/* =============================================================================
   Projekt-Premium
   Eigenständiges Layout für herausgehobene Referenzprojekte.
   Wird ausschließlich auf Projekten mit _ds_premium_layout = 1 geladen.
   ========================================================================== */

.ds-pp {
	/* --- Farben ---------------------------------------------------------- */
	--ds-primary: #0f4ba3;
	--ds-primary-deep: #0a3572;
	--ds-ink: #16181c;
	--ds-text: #4a4a4a;
	--ds-muted: #77736c;

	/* Warme Steintöne, abgenommen vom Jura Gelb der Fotos */
	--ds-stone-50: #faf8f4;
	--ds-stone-100: #f3efe7;
	--ds-stone-200: #e8e1d4;
	--ds-stone-300: #d8cdb9;
	--ds-line: #e4ded3;

	--ds-dark: #16181c;
	--ds-dark-soft: #21252b;
	--ds-white: #ffffff;

	/* --- Maße ------------------------------------------------------------ */
	--ds-shell: 1240px;
	--ds-shell-wide: 1560px;
	--ds-gutter: clamp(1.25rem, 5vw, 4rem);

	--ds-s1: 0.5rem;
	--ds-s2: 1rem;
	--ds-s3: 1.5rem;
	--ds-s4: 2rem;
	--ds-s5: 3rem;
	--ds-s6: 4.5rem;
	--ds-s7: 6.5rem;
	--ds-s8: 9rem;

	--ds-section: clamp(4rem, 9vw, 8.5rem);

	/* --- Typografie ------------------------------------------------------ */
	--ds-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
		"Helvetica Neue", Arial, "Noto Sans", sans-serif;
	--ds-display: "Oswald", "Helvetica Neue", Arial, sans-serif;

	--ds-ease: cubic-bezier(0.22, 0.61, 0.36, 1);

	font-family: var(--ds-sans);
	color: var(--ds-text);
	font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
	line-height: 1.75;
	background: var(--ds-white);
	overflow-x: clip;
}

/* Theme-Vorgaben neutralisieren, ohne globale Selektoren anzufassen.
   :where() hat Spezifität 0, damit gewinnt jede Komponentenklasse weiter unten
   ohne Spezifitätswettlauf und ohne !important. */
.ds-pp * {
	box-sizing: border-box;
}
/* Der eingebundene Beaver-Builder-Kontaktblock ist vom Reset ausgenommen, damit
   er exakt so aussieht wie auf allen anderen Projektseiten. Das :not() steckt in
   einem :where(), sonst würde es die Spezifität anheben. */
.ds-pp :where(h1, h2, h3, h4, h5, h6):where(:not(.ds-bb *)) {
	font-family: var(--ds-sans);
	color: var(--ds-ink);
	letter-spacing: -0.02em;
	text-transform: none;
	margin: 0;
	line-height: 1.12;
	font-weight: 600;
}
.ds-pp :where(p):where(:not(.ds-bb *)) {
	margin: 0 0 1.1em;
}
.ds-pp :where(p:last-child):where(:not(.ds-bb *)) {
	margin-bottom: 0;
}
.ds-pp :where(ul, ol, dl, dd, dt, figure):where(:not(.ds-bb *)) {
	margin: 0;
	padding: 0;
}
.ds-pp :where(li):where(:not(.ds-bb *)) {
	list-style: none;
}
.ds-pp :where(img):where(:not(.ds-bb *)) {
	display: block;
	max-width: 100%;
	height: auto;
}
.ds-pp :where(a):where(:not(.ds-bb *)) {
	color: var(--ds-primary);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
}
.ds-pp :focus-visible {
	outline: 2px solid var(--ds-primary);
	outline-offset: 3px;
	border-radius: 2px;
}

.ds-shell {
	width: 100%;
	max-width: var(--ds-shell);
	margin-inline: auto;
	padding-inline: var(--ds-gutter);
}

.ds-h2 {
	font-size: clamp(1.7rem, 1.1rem + 2.4vw, 3rem);
	max-width: 22ch;
}

.ds-lead {
	font-size: clamp(1.075rem, 1rem + 0.5vw, 1.3rem);
	line-height: 1.6;
	color: var(--ds-muted);
	max-width: 62ch;
}

.ds-section-head {
	margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
	display: grid;
	gap: var(--ds-s3);
}
.ds-section-head--row {
	grid-template-columns: 1fr auto;
	align-items: end;
	gap: var(--ds-s4);
}
@media (max-width: 640px) {
	.ds-section-head--row {
		grid-template-columns: 1fr;
		align-items: start;
	}
}

.ds-link {
	font-weight: 600;
	white-space: nowrap;
	text-decoration: none;
	border-bottom: 1px solid currentColor;
	padding-bottom: 2px;
	transition: color 0.25s var(--ds-ease);
}
.ds-link:hover {
	color: var(--ds-primary-deep);
}

/* =============================================================================
   Hero und Kennzahlen: zusammen genau eine Bildschirmhöhe
   ========================================================================== */

/* Der Hero wächst auf den verbleibenden Platz, die Kennzahlenleiste behält ihre
   natürliche Höhe. So stehen die Zahlen immer ohne Scrollen im Bild, egal wie
   hoch die Leiste durch Umbrüche gerade ist. */
/* --ds-top-offset ist die Höhe dessen, was über dem Block steht (Kontaktleiste,
   Navigation). Wird per JS gemessen, weil sie je nach Viewport variiert.
   Ohne JS bleibt es bei 100svh, dann rutscht die Leiste minimal unter die Kante. */
.ds-top {
	min-height: calc(100svh - var(--ds-top-offset, 0px));
	display: flex;
	flex-direction: column;
}

.ds-hero {
	position: relative;
	flex: 1 1 auto;
	min-height: min(52svh, 620px);
	display: flex;
	align-items: flex-end;
	isolation: isolate;
	background: var(--ds-dark);
	overflow: hidden;
}

.ds-hero__media {
	position: absolute;
	inset: 0;
	z-index: -2;
}

.ds-hero__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Sehr langsamer Zoom, statt background-attachment: fixed.
	   Parallax bricht auf iOS und kostet Scroll-Performance. */
	animation: ds-hero-zoom 24s var(--ds-ease) forwards;
}

@keyframes ds-hero-zoom {
	from {
		transform: scale(1.06);
	}
	to {
		transform: scale(1);
	}
}

/* Verlauf statt flächigem Graufilter: das Foto bleibt sichtbar,
   der Text steht trotzdem sicher lesbar. */
.ds-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background:
		linear-gradient(to top, rgba(10, 12, 15, 0.9) 0%, rgba(10, 12, 15, 0.6) 34%,
			rgba(10, 12, 15, 0.16) 58%, rgba(10, 12, 15, 0.34) 82%,
			rgba(10, 12, 15, 0.68) 100%);
}

.ds-hero__inner {
	/* Gemeinsame Maße von Scroll-Button und Fakten-Karte, damit die Karte
	   zuverlässig oberhalb des Buttons endet. */
	--ds-hero-scroll-bottom: clamp(2.5rem, 4.5vw, 4rem);
	--ds-hero-scroll-size: 2.75rem;
	position: relative;
	width: 100%;
	max-width: var(--ds-shell-wide);
	margin-inline: auto;
	padding: var(--ds-s6) var(--ds-gutter) clamp(2.5rem, 4.5vw, 4rem);
	color: var(--ds-white);
}

.ds-breadcrumb {
	font-size: 0.8125rem;
	letter-spacing: 0.04em;
	margin-bottom: clamp(2rem, 6vw, 5rem);
	color: rgba(255, 255, 255, 0.72);
	display: flex;
	flex-wrap: wrap;
	gap: 0.5em;
}
.ds-breadcrumb a {
	color: inherit;
	text-decoration: none;
	transition: color 0.2s var(--ds-ease);
}
.ds-breadcrumb a:hover {
	color: var(--ds-white);
	text-decoration: underline;
}
.ds-breadcrumb [aria-current] {
	color: var(--ds-white);
}

.ds-hero__eyebrow {
	font-family: var(--ds-display);
	font-weight: 400;
	font-size: clamp(0.875rem, 0.8rem + 0.35vw, 1.0625rem);
	letter-spacing: 0.32em;
	text-transform: uppercase;
	color: var(--ds-stone-300);
	margin: 0 0 var(--ds-s3);
	display: flex;
	align-items: center;
	gap: 1rem;
}
.ds-hero__eyebrow::before {
	content: "";
	width: clamp(2rem, 6vw, 4.5rem);
	height: 1px;
	background: currentColor;
	opacity: 0.75;
	flex: none;
}

.ds-hero__title {
	color: var(--ds-white);
	font-size: clamp(2.5rem, 1.2rem + 5.6vw, 5.75rem);
	font-weight: 300;
	letter-spacing: -0.03em;
	line-height: 1.02;
	max-width: 16ch;
	margin: 0;
	text-wrap: balance;
}

.ds-hero__claim {
	margin: var(--ds-s4) 0 0;
	max-width: 46ch;
	font-size: clamp(1.05rem, 1rem + 0.5vw, 1.35rem);
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.9);
}

.ds-hero__scroll {
	position: absolute;
	right: var(--ds-gutter);
	bottom: var(--ds-hero-scroll-bottom);
	z-index: 2;
	width: var(--ds-hero-scroll-size);
	height: var(--ds-hero-scroll-size);
	display: grid;
	place-items: center;
	border: 1px solid rgba(255, 255, 255, 0.4);
	border-radius: 50%;
	transition: background 0.3s var(--ds-ease), border-color 0.3s var(--ds-ease);
}
.ds-hero__scroll span {
	width: 0.55rem;
	height: 0.55rem;
	border-right: 1.5px solid var(--ds-white);
	border-bottom: 1.5px solid var(--ds-white);
	transform: translateY(-2px) rotate(45deg);
	animation: ds-bounce 2.2s var(--ds-ease) infinite;
}
.ds-hero__scroll:hover {
	background: rgba(255, 255, 255, 0.14);
	border-color: rgba(255, 255, 255, 0.85);
}
@keyframes ds-bounce {
	0%, 100% { transform: translateY(-3px) rotate(45deg); }
	50% { transform: translateY(2px) rotate(45deg); }
}
@media (max-width: 700px) {
	.ds-hero__scroll { display: none; }
}

/* --- Eckdaten als Milchglaskarte im Hero ---------------------------------- */

.ds-hero__facts {
	position: absolute;
	/* Endet oberhalb des Scroll-Buttons. Vorher lagen beide rechts unten
	   übereinander und die Karte hat den Button halb verdeckt. */
	bottom: calc(var(--ds-hero-scroll-bottom) + var(--ds-hero-scroll-size) + 1.15rem);
	right: var(--ds-gutter);
	z-index: 1;
	width: min(21rem, 30vw);
	padding: 1.5rem 1.65rem;
	background: rgba(18, 20, 25, 0.34);
	border: 1px solid rgba(255, 255, 255, 0.24);
	border-radius: 2px;
	box-shadow: 0 20px 54px -26px rgba(0, 0, 0, 0.8);
	-webkit-backdrop-filter: blur(18px) saturate(135%);
	backdrop-filter: blur(18px) saturate(135%);
	color: var(--ds-white);
}

/* Ohne backdrop-filter (ältere Browser) sonst unlesbar */
@supports not (backdrop-filter: blur(1px)) {
	.ds-hero__facts {
		background: rgba(16, 18, 22, 0.72);
	}
}

.ds-hero__facts dl {
	display: grid;
	gap: 0.9rem;
}
.ds-hero__facts div + div {
	padding-top: 0.9rem;
	border-top: 1px solid rgba(255, 255, 255, 0.16);
}
.ds-hero__facts dt {
	font-size: 0.625rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.62);
	margin-bottom: 0.2rem;
}
.ds-hero__facts dd {
	font-size: 0.9375rem;
	line-height: 1.4;
	color: var(--ds-white);
	font-weight: 500;
}

/* Mit Symbol: Icon links, Beschriftung und Wert rechts daneben */
.ds-hero__facts .has-icon {
	display: grid;
	grid-template-columns: 1.35rem minmax(0, 1fr);
	column-gap: 0.85rem;
	align-items: start;
}
.ds-hero__facts-icon {
	grid-row: span 2;
	display: block;
	width: 1.35rem;
	margin-top: 0.15rem;
}
.ds-hero__facts-icon img {
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
	object-fit: contain;
	/* Die Symbole liegen in Blau vor. Auf dem dunklen Bild wären sie kaum zu
	   erkennen, deshalb werden sie hier weiß eingefärbt. */
	filter: brightness(0) invert(1);
	opacity: 0.72;
}

/* Flache Fenster: die Karte endet oberhalb des Scroll-Buttons und wächst
   deshalb nach oben. Damit sie dem Header nicht zu nahe kommt, wird sie hier
   kompakter gesetzt. */
@media (max-height: 860px) {
	.ds-hero__facts {
		padding: 1.15rem 1.35rem;
	}
	.ds-hero__facts dl {
		gap: 0.7rem;
	}
	.ds-hero__facts div + div {
		padding-top: 0.7rem;
	}
}

/* Sehr flache Fenster: für Karte, Scroll-Button und Titel ist kein Platz mehr. */
@media (max-height: 620px) {
	.ds-hero__facts {
		display: none;
	}
}

/* Schmal und flach zugleich: der Hero wird dann so niedrig, dass die Karte
   in den Header läuft. */
@media (max-width: 1250px) and (max-height: 720px) {
	.ds-hero__facts {
		display: none;
	}
}

/* Unterhalb von Desktop überlagert die Karte den Titel. Die Angaben stehen
   ohnehin vollständig in den Projektdetails. */
@media (max-width: 1100px) {
	.ds-hero__facts {
		display: none;
	}
}

/* =============================================================================
   Kennzahlen
   ========================================================================== */

.ds-stats {
	background: var(--ds-dark);
	color: var(--ds-white);
	scroll-margin-top: 6rem;
	flex: 0 0 auto;
}

.ds-stats__list {
	max-width: var(--ds-shell-wide);
	margin-inline: auto;
	padding-inline: var(--ds-gutter);
	display: grid;
	grid-template-columns: repeat(4, 1fr);
}

.ds-stats__item {
	padding: clamp(2.25rem, 4vw, 3.5rem) var(--ds-s3) clamp(2.25rem, 4vw, 3.5rem) 0;
	display: grid;
	gap: 0.35rem;
	align-content: start;
	position: relative;
}
.ds-stats__item + .ds-stats__item {
	padding-left: clamp(1.25rem, 3vw, 2.75rem);
}
.ds-stats__item + .ds-stats__item::before {
	content: "";
	position: absolute;
	left: 0;
	top: clamp(2.25rem, 4vw, 3.5rem);
	bottom: clamp(2.25rem, 4vw, 3.5rem);
	width: 1px;
	background: rgba(255, 255, 255, 0.16);
}

.ds-stats__value {
	font-family: var(--ds-display);
	font-weight: 300;
	font-size: clamp(2.1rem, 1rem + 4vw, 4.25rem);
	line-height: 1;
	letter-spacing: -0.01em;
	font-variant-numeric: tabular-nums;
	color: var(--ds-white);
	white-space: nowrap;
}

.ds-stats__label {
	font-size: 0.8125rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.6);
	line-height: 1.4;
}

@media (max-width: 860px) {
	.ds-stats__list {
		grid-template-columns: repeat(2, 1fr);
	}
	.ds-stats__item:nth-child(odd) + .ds-stats__item::before {
		content: "";
	}
	.ds-stats__item:nth-child(3)::before,
	.ds-stats__item:nth-child(3) {
		border-top: 1px solid rgba(255, 255, 255, 0.16);
	}
	.ds-stats__item:nth-child(3)::before {
		display: none;
	}
	.ds-stats__item:nth-child(4) {
		border-top: 1px solid rgba(255, 255, 255, 0.16);
	}
	.ds-stats__item:nth-child(odd) {
		padding-left: 0;
	}
	.ds-stats__item:nth-child(odd)::before {
		display: none;
	}
}
@media (max-width: 520px) {
	/* Auf schmalen Displays muss die Zahl in eine Zeile passen */
	.ds-stats__value {
		font-size: clamp(1.5rem, 7vw, 2.1rem);
	}
	.ds-stats__label {
		font-size: 0.6875rem;
		letter-spacing: 0.12em;
	}
}

/* =============================================================================
   Einordnung und Projektdaten
   ========================================================================== */

.ds-intro {
	padding-block: var(--ds-section);
}

.ds-intro__grid {
	display: grid;
	gap: clamp(2rem, 5vw, 4.5rem);
	align-items: start;
}

/* Zweite Spalte nur dort, wo die Baustellenszene mitläuft. */
.ds-intro__grid--split {
	grid-template-columns: minmax(0, 1fr) clamp(190px, 24%, 320px);
}
/* Die Szene steht mittig zum Textblock, sonst bleibt rechts unten ein Loch. */
.ds-intro__grid--split .ds-intro__scene {
	align-self: center;
}

.ds-intro__text {
	max-width: 62rem;
}
.ds-intro__text > * + * {
	margin-top: var(--ds-s3);
}
.ds-intro__text .ds-h2 + .ds-lead {
	margin-top: var(--ds-s4);
}
.ds-intro__text .ds-h2 {
	max-width: 26ch;
}

/* =============================================================================
   Projektdetails als Kacheln
   ========================================================================== */

.ds-facts {
	padding-bottom: var(--ds-section);
}

/* 12er-Raster, damit die Kacheln unterschiedlich breit sein können und jede
   Zeile bündig abschließt. Bei sieben Angaben: 4 Kacheln oben, 3 breitere
   unten, zusammen ein geschlossenes Rechteck ohne Lücke. */
.ds-facts__grid {
	display: grid;
	grid-template-columns: repeat(12, 1fr);
	gap: clamp(0.75rem, 1.6vw, 1.25rem);
}

.ds-fact {
	grid-column: span 4;
}

/* 4 + 3 */
.ds-facts__grid[data-count="7"] .ds-fact {
	grid-column: span 3;
}
.ds-facts__grid[data-count="7"] .ds-fact:nth-child(n + 5) {
	grid-column: span 4;
}
/* 3 + 2 */
.ds-facts__grid[data-count="5"] .ds-fact:nth-child(n + 4) {
	grid-column: span 6;
}
/* 2 + 2 */
.ds-facts__grid[data-count="4"] .ds-fact {
	grid-column: span 6;
}
/* 2 + 1 */
.ds-facts__grid[data-count="3"] .ds-fact:nth-child(3) {
	grid-column: span 12;
}

.ds-fact {
	background: var(--ds-stone-50);
	border: 1px solid var(--ds-line);
	padding: clamp(1.4rem, 2.4vw, 2rem) clamp(1.2rem, 2vw, 1.75rem);
	display: grid;
	gap: 0.55rem;
	align-content: start;
	justify-items: center;
	text-align: center;
	transition: border-color 0.3s var(--ds-ease), background 0.3s var(--ds-ease);
}
.ds-fact:hover {
	background: var(--ds-white);
	border-color: var(--ds-stone-300);
}

/* Die Symbole liegen als 512-px-PNG in der Mediathek. Hier werden sie in
   passender Größe ausgeliefert statt unskaliert. */
/* Bewusst ohne feste Höhe am Wrapper: ein Kind mit height:100% in einer
   zentrierten Grid-Area löst sich in Chrome zyklisch auf und wird absurd hoch.
   Die quadratischen Symbole bestimmen die Höhe hier selbst. */
.ds-fact__icon {
	display: block;
	width: 3rem;
	margin-bottom: 0.35rem;
}
.ds-fact__img {
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
	object-fit: contain;
}

.ds-fact__label {
	font-size: 0.6875rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	font-weight: 600;
	color: var(--ds-muted);
}

.ds-fact__value {
	font-size: 0.9375rem;
	line-height: 1.5;
	color: var(--ds-ink);
	margin: 0;
}
.ds-fact__value span {
	display: block;
}
.ds-fact__value span + span {
	margin-top: 0.15em;
}

/* Zwischenstufe: zwei Kacheln je Zeile, eine ungerade letzte füllt die Zeile aus.
   Die Selektoren tragen dieselbe Spezifität wie die Regeln oben, sonst gewinnen
   dort die nth-child-Varianten und die letzte Kachel bliebe zu kurz. */
@media (max-width: 1100px) {
	.ds-facts__grid .ds-fact,
	.ds-facts__grid[data-count="7"] .ds-fact,
	.ds-facts__grid[data-count="7"] .ds-fact:nth-child(n + 5),
	.ds-facts__grid[data-count="5"] .ds-fact:nth-child(n + 4),
	.ds-facts__grid[data-count="4"] .ds-fact,
	.ds-facts__grid[data-count="3"] .ds-fact:nth-child(3) {
		grid-column: span 6;
	}
	.ds-facts__grid[data-count="7"] .ds-fact:nth-child(7),
	.ds-facts__grid[data-count="5"] .ds-fact:nth-child(5),
	.ds-facts__grid[data-count="3"] .ds-fact:nth-child(3) {
		grid-column: span 12;
	}
}
@media (max-width: 620px) {
	.ds-facts__grid .ds-fact,
	.ds-facts__grid[data-count="7"] .ds-fact,
	.ds-facts__grid[data-count="7"] .ds-fact:nth-child(n + 5),
	.ds-facts__grid[data-count="7"] .ds-fact:nth-child(7),
	.ds-facts__grid[data-count="5"] .ds-fact:nth-child(n + 4),
	.ds-facts__grid[data-count="4"] .ds-fact,
	.ds-facts__grid[data-count="3"] .ds-fact:nth-child(3) {
		grid-column: span 12;
	}
}

/* =============================================================================
   Eingebundene Bestandsvorlagen
   ========================================================================== */

/* Die Vorlagen bringen ihr eigenes Layout und ihre eigenen Abstände mit.
   Hier wird nur sichergestellt, dass sie über die volle Breite laufen und
   nicht mit den Abständen der eigenen Abschnitte kollidieren. */
.ds-bb {
	width: 100%;
	position: relative;
}
.ds-bb .fl-row-content-wrap {
	margin: 0;
}

/* Die CTA-Vorlage zieht ihre Karte im Original mit margin-top: -288px in den
   darüberliegenden Abschnitt hinein. Dort steht auf den Bestandsseiten eine
   Bildergalerie mit Platz, hier die Zeitschiene. Ohne diese Korrektur legt sich
   die Karte über den Text. */
.ds-bb--cta .fl-col-content {
	margin-top: 0 !important;
}

/* Der Ablaufblock ist im Original ein kräftiger Blauverlauf. Auf dieser Seite
   nimmt er den dunklen Ton von Hero und Kennzahlenleiste auf, mit nur noch
   einem Hauch Blau, damit er sich einfügt statt herauszustechen. */
.ds-bb--vorgehen .fl-row-content-wrap {
	background-image: linear-gradient(103deg, #15171b 0%, #1b2534 55%, #223250 100%) !important;
}

.ds-specs {
	background: var(--ds-stone-100);
	padding: clamp(1.75rem, 3vw, 2.75rem);
	border-top: 3px solid var(--ds-primary);
	position: sticky;
	top: 6rem;
}

.ds-specs__title {
	font-size: 0.8125rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--ds-muted);
	font-weight: 600;
	margin-bottom: var(--ds-s3);
}

.ds-specs__row {
	display: grid;
	grid-template-columns: 8.5rem minmax(0, 1fr);
	gap: var(--ds-s2);
	padding-block: 0.85rem;
	border-top: 1px solid var(--ds-stone-200);
	font-size: 0.9375rem;
	line-height: 1.5;
}
.ds-specs__row:first-child {
	border-top: 0;
	padding-top: 0;
}

.ds-specs__row dt {
	color: var(--ds-muted);
	font-weight: 500;
}
.ds-specs__row dd span {
	display: block;
	color: var(--ds-ink);
}
.ds-specs__row dd span + span {
	margin-top: 0.15em;
}

@media (max-width: 900px) {
	.ds-intro__grid,
	.ds-intro__grid--split {
		grid-template-columns: 1fr;
	}
	.ds-intro__scene {
		max-width: 280px;
		margin-inline: auto;
	}
	.ds-specs {
		position: static;
	}
}
@media (max-width: 420px) {
	.ds-specs__row {
		grid-template-columns: 1fr;
		gap: 0.2rem;
	}
}

/* =============================================================================
   Bauteile
   ========================================================================== */

.ds-parts {
	padding-block: var(--ds-section);
	background: var(--ds-stone-50);
}

.ds-parts__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: clamp(1.25rem, 2.5vw, 2.25rem);
}

.ds-part {
	background: var(--ds-white);
	display: flex;
	flex-direction: column;
	transition: transform 0.4s var(--ds-ease), box-shadow 0.4s var(--ds-ease);
}
.ds-part:hover {
	transform: translateY(-4px);
	box-shadow: 0 18px 42px -22px rgba(22, 24, 28, 0.4);
}

.ds-part__media {
	overflow: hidden;
	aspect-ratio: 4 / 3;
}
.ds-part__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.7s var(--ds-ease);
}
.ds-part:hover .ds-part__img {
	transform: scale(1.045);
}

.ds-part__body {
	padding: clamp(1.35rem, 2.4vw, 2rem);
	display: flex;
	flex-direction: column;
	gap: var(--ds-s2);
	flex: 1;
}

.ds-part__title {
	font-size: clamp(1.15rem, 1rem + 0.6vw, 1.4rem);
	font-weight: 600;
}

.ds-part__text {
	font-size: 0.9375rem;
	color: var(--ds-muted);
	margin: 0;
}

.ds-part__figures {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--ds-s2);
	margin-top: auto;
	padding-top: var(--ds-s3);
	border-top: 1px solid var(--ds-line);
}
.ds-part__figures dt {
	font-size: 0.6875rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--ds-muted);
	margin-bottom: 0.2rem;
}
.ds-part__figures dd {
	font-family: var(--ds-display);
	font-size: clamp(1.05rem, 0.9rem + 0.55vw, 1.3rem);
	font-weight: 400;
	color: var(--ds-ink);
	font-variant-numeric: tabular-nums;
	line-height: 1.1;
	white-space: nowrap;
}

@media (max-width: 900px) {
	.ds-parts__grid {
		grid-template-columns: 1fr;
		max-width: 34rem;
	}
}

/* =============================================================================
   Material
   ========================================================================== */

.ds-materials {
	padding-block: var(--ds-section);
}

.ds-materials__grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: clamp(1.75rem, 4vw, 3.5rem);
}

.ds-material__media {
	aspect-ratio: 16 / 10;
	overflow: hidden;
	margin-bottom: var(--ds-s4);
}
.ds-material__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.ds-material__title {
	font-size: clamp(1.3rem, 1.1rem + 0.9vw, 1.75rem);
	margin-bottom: var(--ds-s2);
}

.ds-material__body p {
	color: var(--ds-text);
	max-width: 52ch;
}

.ds-material__facts {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-top: var(--ds-s3);
}
.ds-material__facts li {
	font-size: 0.8125rem;
	letter-spacing: 0.03em;
	background: var(--ds-stone-100);
	color: var(--ds-ink);
	padding: 0.4rem 0.85rem;
	border: 1px solid var(--ds-stone-200);
}

@media (max-width: 820px) {
	.ds-materials__grid {
		grid-template-columns: 1fr;
	}
}

/* =============================================================================
   Anklickbare Bilder außerhalb der Galerie (Bauteile, Materialien)
   ========================================================================== */

.ds-pp .ds-zoom {
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
	background: var(--ds-stone-200);
	cursor: pointer;
	position: relative;
	overflow: hidden;
	text-align: left;
	font: inherit;
	color: inherit;
}

.ds-zoom__icon {
	position: absolute;
	inset: 0;
	background: rgba(15, 75, 163, 0);
	transition: background 0.35s var(--ds-ease);
	display: grid;
	place-items: center;
	z-index: 1;
}
.ds-zoom__icon::before,
.ds-zoom__icon::after {
	content: "";
	position: absolute;
	background: var(--ds-white);
	opacity: 0;
	transition: opacity 0.35s var(--ds-ease);
}
.ds-zoom__icon::before {
	width: 1.5rem;
	height: 1.5px;
}
.ds-zoom__icon::after {
	width: 1.5px;
	height: 1.5rem;
}
.ds-zoom:hover .ds-zoom__icon,
.ds-zoom:focus-visible .ds-zoom__icon {
	background: rgba(15, 75, 163, 0.34);
}
.ds-zoom:hover .ds-zoom__icon::before,
.ds-zoom:hover .ds-zoom__icon::after,
.ds-zoom:focus-visible .ds-zoom__icon::before,
.ds-zoom:focus-visible .ds-zoom__icon::after {
	opacity: 1;
}

/* =============================================================================
   Galerie
   ========================================================================== */

.ds-gallery {
	padding-block: var(--ds-section);
	background: var(--ds-stone-50);
}
.ds-gallery .ds-shell {
	max-width: var(--ds-shell-wide);
}

/* Feste Zeilenhöhe statt Seitenverhältnis je Kachel: dadurch bleiben alle
   Reihen bündig, auch wenn eine Kachel zwei Spalten breit ist.
   grid-auto-flow: dense füllt die Lücken, die dabei sonst entstehen. */
.ds-gallery__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	grid-auto-rows: clamp(200px, 21vw, 340px);
	grid-auto-flow: dense;
	gap: clamp(0.75rem, 1.5vw, 1.25rem);
}

.ds-gallery__item--wide {
	grid-column: span 2;
}

.ds-gallery__btn {
	display: block;
	width: 100%;
	height: 100%;
	padding: 0;
	border: 0;
	background: var(--ds-stone-200);
	cursor: pointer;
	position: relative;
	overflow: hidden;
}

.ds-gallery__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Das Seitenverhältnis steuert hier die Kachel, nicht das Bild. */
	aspect-ratio: auto !important;
	transition: transform 0.75s var(--ds-ease), filter 0.4s var(--ds-ease);
}
.ds-gallery__btn:hover .ds-gallery__img,
.ds-gallery__btn:focus-visible .ds-gallery__img {
	transform: scale(1.05);
}

.ds-gallery__zoom {
	position: absolute;
	inset: 0;
	background: rgba(15, 75, 163, 0);
	transition: background 0.35s var(--ds-ease);
	display: grid;
	place-items: center;
}
.ds-gallery__zoom::before,
.ds-gallery__zoom::after {
	content: "";
	position: absolute;
	background: var(--ds-white);
	opacity: 0;
	transition: opacity 0.35s var(--ds-ease);
}
.ds-gallery__zoom::before {
	width: 1.5rem;
	height: 1.5px;
}
.ds-gallery__zoom::after {
	width: 1.5px;
	height: 1.5rem;
}
.ds-gallery__btn:hover .ds-gallery__zoom,
.ds-gallery__btn:focus-visible .ds-gallery__zoom {
	background: rgba(15, 75, 163, 0.34);
}
.ds-gallery__btn:hover .ds-gallery__zoom::before,
.ds-gallery__btn:hover .ds-gallery__zoom::after,
.ds-gallery__btn:focus-visible .ds-gallery__zoom::before,
.ds-gallery__btn:focus-visible .ds-gallery__zoom::after {
	opacity: 1;
}

.ds-gallery__credit {
	margin-top: var(--ds-s4);
	font-size: 0.8125rem;
	color: var(--ds-muted);
	text-align: right;
}

@media (max-width: 900px) {
	.ds-gallery__grid {
		grid-template-columns: repeat(2, 1fr);
		grid-auto-rows: clamp(190px, 30vw, 300px);
	}
	.ds-gallery__item--wide {
		grid-column: span 2;
	}
}
@media (max-width: 560px) {
	.ds-gallery__grid {
		grid-template-columns: 1fr;
		grid-auto-rows: 62vw;
	}
	.ds-gallery__item--wide {
		grid-column: span 1;
	}
}

/* =============================================================================
   Zeitschiene
   ========================================================================== */

.ds-timeline {
	padding-block: var(--ds-section);
}

.ds-timeline__list {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
	gap: clamp(1rem, 2.2vw, 1.85rem);
	position: relative;
}

.ds-timeline__step {
	display: grid;
	gap: 0.4rem;
	padding-top: var(--ds-s4);
	border-top: 1px solid var(--ds-line);
	position: relative;
}

.ds-timeline__marker {
	position: absolute;
	top: -0.3125rem;
	left: 0;
	width: 0.625rem;
	height: 0.625rem;
	background: var(--ds-primary);
	border-radius: 50%;
}

.ds-timeline__date {
	font-family: var(--ds-display);
	font-size: 0.875rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--ds-primary);
}

.ds-timeline__title {
	font-size: 1.0625rem;
	font-weight: 600;
	color: var(--ds-ink);
	line-height: 1.3;
}

.ds-timeline__text {
	font-size: 0.9375rem;
	color: var(--ds-muted);
	line-height: 1.55;
}

/* =============================================================================
   Weitere Projekte
   ========================================================================== */

.ds-more {
	padding-block: var(--ds-section);
	background: var(--ds-stone-50);
}

.ds-more__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: clamp(1.25rem, 2.5vw, 2rem);
}

.ds-more__card {
	display: flex;
	flex-direction: column;
	height: 100%;
	background: var(--ds-white);
	text-decoration: none;
	color: inherit;
	transition: transform 0.35s var(--ds-ease), box-shadow 0.35s var(--ds-ease);
}
.ds-more__card:hover {
	transform: translateY(-4px);
	box-shadow: 0 16px 38px -20px rgba(22, 24, 28, 0.4);
}

.ds-more__media {
	aspect-ratio: 3 / 2;
	overflow: hidden;
	background: var(--ds-stone-200);
}
.ds-more__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s var(--ds-ease);
}
.ds-more__card:hover .ds-more__img {
	transform: scale(1.045);
}

/* Platzhalter statt grauer Leerkachel, wo ein Projekt kein Bild hat */
.ds-more__media--empty {
	background:
		repeating-linear-gradient(
			135deg,
			var(--ds-stone-100) 0 12px,
			var(--ds-stone-200) 12px 24px
		);
	display: grid;
	place-items: center;
}
.ds-more__placeholder {
	width: 2.25rem;
	height: 2.25rem;
	border: 1.5px solid var(--ds-stone-300);
	transform: rotate(45deg);
}

.ds-more__body {
	padding: clamp(1.15rem, 2vw, 1.6rem);
	display: grid;
	gap: 0.4rem;
	align-content: start;
	flex: 1;
}

.ds-more__ort {
	font-size: 0.6875rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ds-primary);
	font-weight: 600;
}

.ds-more__title {
	font-size: 1.0625rem;
	font-weight: 600;
	line-height: 1.35;
}

.ds-more__mat {
	font-size: 0.875rem;
	color: var(--ds-muted);
	line-height: 1.5;
}

@media (max-width: 900px) {
	.ds-more__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}
@media (max-width: 560px) {
	.ds-more__grid {
		grid-template-columns: 1fr;
	}
}

/* =============================================================================
   Kontakt
   ========================================================================== */

.ds-contact {
	padding-block: var(--ds-section);
	background: var(--ds-dark);
	color: rgba(255, 255, 255, 0.82);
	scroll-margin-top: 5rem;
}

.ds-contact__grid {
	display: grid;
	grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
	gap: clamp(2.5rem, 6vw, 5.5rem);
	align-items: start;
}

.ds-contact .ds-h2 {
	color: var(--ds-white);
}
.ds-contact .ds-lead {
	color: rgba(255, 255, 255, 0.68);
	margin-top: var(--ds-s3);
}

.ds-contact__direct {
	margin-top: var(--ds-s5);
	display: grid;
	gap: var(--ds-s3);
}
.ds-contact__direct li {
	display: grid;
	gap: 0.2rem;
	padding-top: var(--ds-s2);
	border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.ds-contact__direct span {
	font-size: 0.6875rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.45);
}
.ds-contact__direct a {
	color: var(--ds-white);
	text-decoration: none;
	font-size: 1.125rem;
	transition: color 0.25s var(--ds-ease);
}
.ds-contact__direct a:hover {
	color: var(--ds-stone-300);
}

/* WPForms in die dunkle Fläche einpassen, ohne das Formular selbst zu ändern */
.ds-contact__form {
	background: var(--ds-dark-soft);
	padding: clamp(1.5rem, 3vw, 2.5rem);
}
.ds-contact__form .wpforms-field-label,
.ds-contact__form .wpforms-field-sublabel {
	color: rgba(255, 255, 255, 0.78) !important;
	font-weight: 500 !important;
}
.ds-contact__form .wpforms-field-description,
.ds-contact__form .wpforms-required-label {
	color: rgba(255, 255, 255, 0.5) !important;
}
.ds-contact__form input[type="text"],
.ds-contact__form input[type="email"],
.ds-contact__form input[type="tel"],
.ds-contact__form input[type="url"],
.ds-contact__form textarea,
.ds-contact__form select {
	background: rgba(255, 255, 255, 0.06) !important;
	border: 1px solid rgba(255, 255, 255, 0.18) !important;
	color: var(--ds-white) !important;
	border-radius: 0 !important;
	transition: border-color 0.25s var(--ds-ease), background 0.25s var(--ds-ease);
}
.ds-contact__form input::placeholder,
.ds-contact__form textarea::placeholder {
	color: rgba(255, 255, 255, 0.38);
}
.ds-contact__form input:focus,
.ds-contact__form textarea:focus,
.ds-contact__form select:focus {
	border-color: rgba(255, 255, 255, 0.55) !important;
	background: rgba(255, 255, 255, 0.1) !important;
	outline: none;
}
.ds-contact__form .wpforms-submit {
	background: var(--ds-primary) !important;
	border: 1px solid var(--ds-primary) !important;
	color: var(--ds-white) !important;
	border-radius: 0 !important;
	padding: 0.9rem 2.25rem !important;
	font-size: 1rem !important;
	font-weight: 600 !important;
	cursor: pointer;
	transition: background 0.25s var(--ds-ease), border-color 0.25s var(--ds-ease);
}
.ds-contact__form .wpforms-submit:hover {
	background: var(--ds-white) !important;
	border-color: var(--ds-white) !important;
	color: var(--ds-dark) !important;
}
.ds-contact__form .wpforms-confirmation-container-full {
	background: rgba(255, 255, 255, 0.08) !important;
	border: 1px solid rgba(255, 255, 255, 0.2) !important;
	color: var(--ds-white) !important;
}

@media (max-width: 900px) {
	.ds-contact__grid {
		grid-template-columns: 1fr;
	}
}

/* =============================================================================
   Zurück-Leiste
   ========================================================================== */

.ds-back {
	padding-block: var(--ds-s5);
	border-bottom: 1px solid var(--ds-line);
}
.ds-back__link {
	text-decoration: none;
	font-weight: 600;
	color: var(--ds-ink);
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	transition: color 0.25s var(--ds-ease), gap 0.25s var(--ds-ease);
}
.ds-back__link:hover {
	color: var(--ds-primary);
	gap: 0.95rem;
}

/* =============================================================================
   Lightbox
   ========================================================================== */

.ds-lb[hidden] {
	display: none !important;
}
.ds-lb {
	position: fixed;
	inset: 0;
	z-index: 99999;
	display: grid;
	place-items: center;
	padding: clamp(1rem, 4vw, 3rem);
	animation: ds-fade 0.28s var(--ds-ease);
}
@keyframes ds-fade {
	from { opacity: 0; }
	to { opacity: 1; }
}

.ds-lb__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(8, 10, 13, 0.94);
	border: 0;
}

.ds-lb__stage {
	position: relative;
	max-width: 100%;
	max-height: 100%;
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	gap: clamp(0.5rem, 2vw, 1.5rem);
}

.ds-lb__figure {
	margin: 0;
	min-width: 0;
	text-align: center;
}
.ds-lb__img {
	max-width: 100%;
	max-height: min(82svh, 1100px);
	width: auto;
	margin-inline: auto;
	object-fit: contain;
}
.ds-lb__caption {
	color: rgba(255, 255, 255, 0.72);
	font-size: 0.875rem;
	margin-top: 1rem;
	min-height: 1.2em;
}

.ds-lb__close,
.ds-lb__nav {
	background: rgba(255, 255, 255, 0.08);
	border: 1px solid rgba(255, 255, 255, 0.2);
	color: #fff;
	cursor: pointer;
	display: grid;
	place-items: center;
	transition: background 0.25s var(--ds-ease), border-color 0.25s var(--ds-ease);
	line-height: 1;
}
.ds-lb__close:hover,
.ds-lb__nav:hover {
	background: rgba(255, 255, 255, 0.2);
	border-color: rgba(255, 255, 255, 0.55);
}

.ds-lb__nav {
	width: clamp(2.5rem, 5vw, 3.25rem);
	height: clamp(2.5rem, 5vw, 3.25rem);
	font-size: 2rem;
	padding-bottom: 0.25rem;
	border-radius: 50%;
}

/* Einzelbild: Pfeile und Zähler wären sinnlos */
.ds-lb--single .ds-lb__nav,
.ds-lb--single .ds-lb__counter {
	display: none;
}
.ds-lb--single .ds-lb__stage {
	grid-template-columns: minmax(0, 1fr);
}

.ds-lb__close {
	position: absolute;
	top: -3.25rem;
	right: 0;
	width: 2.5rem;
	height: 2.5rem;
	font-size: 1.75rem;
	border-radius: 50%;
	z-index: 2;
}

.ds-lb__counter {
	position: absolute;
	top: -3rem;
	left: 0;
	color: rgba(255, 255, 255, 0.6);
	font-family: var(--ds-display);
	font-size: 0.9375rem;
	letter-spacing: 0.12em;
	margin: 0;
}

@media (max-width: 640px) {
	.ds-lb__stage {
		grid-template-columns: 1fr;
	}
	.ds-lb__nav {
		position: absolute;
		bottom: -3.5rem;
	}
	.ds-lb__nav--prev { left: 25%; }
	.ds-lb__nav--next { right: 25%; }
	.ds-lb__close { top: -3rem; }
}

body.ds-lb-open {
	overflow: hidden;
}

/* =============================================================================
   Einblenden beim Scrollen
   ========================================================================== */

.ds-reveal {
	opacity: 0;
	transform: translateY(28px);
	transition: opacity 0.7s var(--ds-ease), transform 0.7s var(--ds-ease);
}
.ds-reveal.is-in {
	opacity: 1;
	transform: none;
}
/* Ohne JS bleibt nichts unsichtbar */
.no-js .ds-reveal {
	opacity: 1;
	transform: none;
}

/* =============================================================================
   Rollo-Effekt im Hero: das Flugzeug zieht den Rohbau ab
   Über dem fertigen Hero liegt das Rohbau-Foto (.ds-flug__rollo). Ein Flugzeug
   fliegt herein, hängt sich per Seil an die Kante und zieht die Bahn nach
   rechts aus dem Bild. Die Bahn wird dabei gegenläufig verschoben, damit das
   Rohbau-Foto an Ort und Stelle bleibt und nur die Kante wandert: zwei
   Transforms statt clip-path, alles läuft auf dem Compositor. JS misst Hero,
   Flugzeug und die freie Flugspur, schreibt die Maße als Variablen und startet
   mit .is-flying. Danach entfernt JS das Element. Ohne JS blendet ein Notaus
   die Bahn nach 14 s aus, damit nie der Rohbau stehen bleibt.
   ========================================================================== */

/* Variablen liegen am Hero, weil Bahn (.ds-flug) und Flugzeug (.ds-flug-sky)
   getrennte Ebenen sind. JS setzt die gemessenen Werte ebenfalls am Hero. */
.ds-hero {
	--ds-flug-dauer: 4.2s;  /* Rückfallwert, JS leitet die Dauer aus der Breite ab */
	--ds-flug-seil-winkel: 0deg; /* Neigung des Seils am Ende des Steigflugs, JS */
	--ds-flug-hw: 1440px;   /* Hero-Breite, setzt JS */
	--ds-flug-pw: 120px;    /* Flugzeug-Breite, setzt JS */
	--ds-flug-seil: 64px;   /* Seil zwischen Rolle und Heck */
	--ds-flug-top: 22%;     /* Oberkante des Flugzeugs, setzt JS */
	--ds-flug-hub: 0px;     /* leichter Steigflug beim Ziehen, setzt JS */
}
.ds-flug {
	position: absolute;
	inset: 0;
	z-index: 0;
	overflow: hidden;
	pointer-events: none;
	animation: ds-flug-notaus 0.8s linear 14s forwards;
}
/* Ebene für das Flugzeug: über der Faktenkarte (z-index 1) und dem
   Scroll-Button (2), unter der Navigation, die als eigener Header darüber liegt. */
.ds-flug-sky {
	position: absolute;
	inset: 0;
	z-index: 3;
	overflow: hidden;
	pointer-events: none;
}

/* --- Bahn mit dem Rohbau-Foto ------------------------------------------- */

.ds-flug__rollo {
	position: absolute;
	inset: 0;
	overflow: hidden;
	transform: translate3d(0, 0, 0);
}
.ds-flug__bahn {
	position: absolute;
	inset: 0;
	transform: translate3d(0, 0, 0);
}
/* Die Bahn biegt sich in die Rolle: dunkler Saum an der ziehenden Kante */
.ds-flug__rollo::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	width: clamp(44px, 6vw, 110px);
	z-index: 1;
	background: linear-gradient(to right, rgba(0, 0, 0, 0.62), rgba(0, 0, 0, 0.28) 42%, rgba(0, 0, 0, 0) 100%);
}
.ds-flug__vorher {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Etwas kühler und ruhiger, damit der Warm-Kalt-Kontrast zum fertigen
	   Terminal stärker trägt und die Deckenstrahler nicht ausbrennen */
	filter: contrast(1.03) saturate(0.88);
}
/* Derselbe Verlauf wie auf dem Hero, damit der Text über dem Rohbau
   genauso lesbar bleibt. */
.ds-flug__bahn::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(to top, rgba(10, 12, 15, 0.9) 0%, rgba(10, 12, 15, 0.6) 34%,
			rgba(10, 12, 15, 0.16) 58%, rgba(10, 12, 15, 0.44) 82%,
			rgba(10, 12, 15, 0.74) 100%);
}

/* Aufgerollte Kante: heller Wulst mit Schatten auf das freigelegte Foto. Liegt
   außerhalb von .ds-flug__rollo, weil dessen overflow den Schatten abschneiden
   würde, und läuft mit denselben Keyframe-Werten mit. */
.ds-flug__rolle {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	width: clamp(28px, 3.2vw, 48px);
	margin-left: calc(clamp(28px, 3.2vw, 48px) / -2);
	border-radius: 999px;
	/* Matte Rolle im Bildton, Glanz gedeckelt, damit weißer Text darüber
	   lesbar bleibt. Dunkle Ränder wie ein Zylinder, Lichtkante in der Mitte. */
	background:
		linear-gradient(to right, rgba(0, 0, 0, 0.62) 0%, rgba(0, 0, 0, 0.22) 24%,
			rgba(255, 255, 255, 0.26) 46%, rgba(255, 255, 255, 0.08) 58%,
			rgba(0, 0, 0, 0.36) 80%, rgba(0, 0, 0, 0.68) 100%),
		#62656a;
	box-shadow: -24px 0 44px rgba(0, 0, 0, 0.5), 8px 0 22px rgba(0, 0, 0, 0.4);
	/* Unter der transparenten Navigation zurückgenommen */
	-webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.3) 0, #000 140px);
	mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.3) 0, #000 140px);
	opacity: 0;
	transform: translate3d(-100%, 0, 0);
}
/* Falz: hier läuft die flache Bahn in die Rolle */
.ds-flug__rolle::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	right: -2px;
	width: 2px;
	background: rgba(0, 0, 0, 0.45);
}

/* --- Flugzeug ------------------------------------------------------------ */

.ds-flug__plane {
	position: absolute;
	left: 0;
	top: var(--ds-flug-top);
	width: clamp(110px, 13vw, 210px);
	/* Prozent bezieht sich auf die eigene Breite: die Nase ist bei jeder
	   Größe draußen, auch bevor JS die Variablen gesetzt hat. */
	transform: translate3d(calc(-100% - 40px), 14px, 0);
	opacity: 0;
}
.ds-flug__svg {
	display: block;
	width: 100%;
	height: auto;
	/* Nase leicht angehoben, statisch, deshalb kein Konflikt mit der Bahn */
	rotate: -2deg;
	/* Feiner dunkler Saum gegen helle Lampen, dazu weicher Höhenschatten */
	filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.6)) drop-shadow(0 14px 22px rgba(0, 0, 0, 0.35));
}
.ds-flug__glas {
	fill: #16181c;
}
/* Seil vom Heck zur Rolle */
.ds-flug__zug {
	position: absolute;
	right: calc(100% - 6px); /* 6 px unter das Heck, sonst bleibt eine Lücke */
	top: calc(54% - 6px);
	width: calc(var(--ds-flug-seil) + 6px);
	height: 12px;
	transform-origin: 100% 50%;
	rotate: 0deg;
}
.ds-flug__seil {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
	overflow: visible;
	filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5));
	transform-origin: 100% 50%;
	transform: scaleX(0);
	opacity: 0;
}
.ds-flug__oese {
	position: absolute;
	left: -4px;
	top: 1px;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	border: 1.5px solid rgba(255, 255, 255, 0.85);
	background: rgba(0, 0, 0, 0.35);
	opacity: 0;
}
/* Positionslicht am Seitenleitwerk */
.ds-flug__beacon {
	opacity: 0.15;
}

/* --- Ablauf ------------------------------------------------------------- */
/* Alle Keyframes teilen sich dieselben Stationen: bis 18 % fliegt das Flugzeug
   herein und hängt sich ein, von 18 % bis 90 % ziehen Flugzeug, Rolle und
   Bahn mit derselben Kurve nach rechts, danach verlässt alles das Bild. */

.ds-hero.is-flying .ds-flug__plane {
	will-change: transform, opacity;
	animation: ds-flug-plane var(--ds-flug-dauer) linear forwards;
}
.ds-hero.is-flying .ds-flug__rollo {
	will-change: transform;
	animation: ds-flug-rollo var(--ds-flug-dauer) linear forwards;
}
.ds-hero.is-flying .ds-flug__bahn {
	will-change: transform;
	animation: ds-flug-bahn var(--ds-flug-dauer) linear forwards;
}
.ds-hero.is-flying .ds-flug__rolle {
	will-change: transform, opacity;
	animation: ds-flug-rolle var(--ds-flug-dauer) linear forwards;
}
.ds-hero.is-flying .ds-flug__seil {
	animation: ds-flug-seil var(--ds-flug-dauer) linear forwards;
}
.ds-hero.is-flying .ds-flug__oese {
	animation: ds-flug-oese var(--ds-flug-dauer) linear forwards;
}
.ds-hero.is-flying .ds-flug__zug {
	animation: ds-flug-zug var(--ds-flug-dauer) linear forwards;
}
.ds-hero.is-flying .ds-flug__beacon {
	animation: ds-flug-beacon 1.1s steps(1, end) infinite;
}
@keyframes ds-flug-oese {
	0%, 11% {
		opacity: 0;
	}
	13%, 100% {
		opacity: 1;
	}
}
@keyframes ds-flug-zug {
	0%, 16% {
		rotate: 0deg;
		animation-timing-function: cubic-bezier(0.55, 0, 0.8, 0.5);
	}
	100% {
		rotate: var(--ds-flug-seil-winkel);
	}
}
@keyframes ds-flug-beacon {
	0%, 88% {
		opacity: 0.15;
	}
	89%, 100% {
		opacity: 1;
	}
}
/* Leises Wippen plus Nicken unter Last: die Bahn zieht am Heck, die Nase geht
   hoch, dann fängt sich das Flugzeug. translate und rotate statt transform,
   damit nichts mit der Bahn kollidiert. */
.ds-hero.is-flying .ds-flug__svg {
	animation:
		ds-flug-wippen 3.2s ease-in-out infinite alternate,
		ds-flug-nicken var(--ds-flug-dauer) linear forwards;
}
@keyframes ds-flug-wippen {
	from {
		translate: 0 -1px;
	}
	to {
		translate: 0 1.5px;
	}
}
@keyframes ds-flug-nicken {
	0%, 10% {
		rotate: -1deg;
	}
	14% {
		rotate: -5deg;
	}
	40% {
		rotate: -3deg;
	}
	100% {
		rotate: -1.5deg;
	}
}

@keyframes ds-flug-plane {
	0% {
		opacity: 0;
		transform: translate3d(calc(-100% - 40px), 14px, 0);
		animation-timing-function: cubic-bezier(0.25, 0.1, 0.5, 1);
	}
	6%, 100% {
		opacity: 1;
	}
	/* Überschwingen: das Seil wird straff, die Last reißt das Flugzeug zurück */
	13% {
		transform: translate3d(calc(var(--ds-flug-seil) + 14px), 2px, 0);
		animation-timing-function: cubic-bezier(0.2, 0.9, 0.3, 1);
	}
	16% {
		transform: translate3d(var(--ds-flug-seil), 0, 0);
		animation-timing-function: cubic-bezier(0.55, 0, 0.8, 0.5);
	}
	100% {
		transform: translate3d(calc(var(--ds-flug-hw) + var(--ds-flug-seil) + var(--ds-flug-pw) + 80px), var(--ds-flug-hub), 0);
	}
}
@keyframes ds-flug-rollo {
	0%, 16% {
		transform: translate3d(0, 0, 0);
		animation-timing-function: cubic-bezier(0.55, 0, 0.8, 0.5);
	}
	100% {
		transform: translate3d(calc(var(--ds-flug-hw) + 120px), 0, 0);
	}
}
@keyframes ds-flug-bahn {
	0%, 16% {
		transform: translate3d(0, 0, 0);
		animation-timing-function: cubic-bezier(0.55, 0, 0.8, 0.5);
	}
	100% {
		transform: translate3d(calc(-1 * var(--ds-flug-hw) - 120px), 0, 0);
	}
}
@keyframes ds-flug-rolle {
	0%, 10% {
		transform: translate3d(-100%, 0, 0);
		opacity: 0;
		animation-timing-function: cubic-bezier(0.2, 0.7, 0.3, 1);
	}
	13% {
		opacity: 1;
	}
	16% {
		transform: translate3d(0, 0, 0);
		animation-timing-function: cubic-bezier(0.55, 0, 0.8, 0.5);
	}
	100% {
		transform: translate3d(calc(var(--ds-flug-hw) + 120px), 0, 0);
		opacity: 1;
	}
}
@keyframes ds-flug-seil {
	0%, 10% {
		transform: scaleX(0);
		opacity: 0;
	}
	13%, 100% {
		transform: scaleX(1);
		opacity: 0.9;
	}
}
/* Notaus ohne JS: nach 14 s ist die Bahn weg, der fertige Hero steht. */
@keyframes ds-flug-notaus {
	to {
		opacity: 0;
		visibility: hidden;
	}
}

@media (max-width: 700px) {
	.ds-flug {
		--ds-flug-seil: 40px;
	}
	.ds-flug__plane {
		width: clamp(96px, 26vw, 140px);
	}
	.ds-flug__rolle {
		width: clamp(16px, 4.5vw, 28px);
		margin-left: calc(clamp(16px, 4.5vw, 28px) / -2);
		box-shadow: -14px 0 28px rgba(0, 0, 0, 0.5), 5px 0 14px rgba(0, 0, 0, 0.4);
	}
}

/* Bei reduzierter Bewegung gibt es weder Rohbau noch Flugzeug. Wichtig, weil
   der globale 0.001ms-Block unten sonst den Notaus sofort greifen ließe und
   die Bahn kurz aufblitzen würde. */
@media (prefers-reduced-motion: reduce) {
	.ds-flug {
		display: none !important;
	}
}
@media print {
	.ds-flug {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ds-pp *,
	.ds-pp *::before,
	.ds-pp *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
	}
	.ds-reveal {
		opacity: 1;
		transform: none;
	}
	.ds-hero__img {
		animation: none;
	}
}

/* =============================================================================
   Sichtbarkeit nur für Screenreader
   ========================================================================== */

.ds-pp .screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* =============================================================================
   Baustellenszene neben dem Einordnungstext

   Inline-SVG aus ds/szene-baustelle.php, animiert ausschließlich hier.
   Koordinaten sind viewBox-Einheiten (340 x 226), deshalb überall
   transform-box: view-box und Ursprünge in User-Units.
   ========================================================================== */

.ds-intro__scene {
	margin-top: 0.35rem;
	width: 100%;
}

.ds-scene {
	display: block;
	width: 100%;
	height: auto;
}

.ds-scene * {
	transform-box: view-box;
}

.ds-scene path,
.ds-scene rect,
.ds-scene circle {
	fill: none;
	stroke: var(--ds-ink);
	stroke-width: 1.6;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ------------------------------------------------------------ Bauwerk */

.ds-scene .ds-scene__ground {
	stroke-width: 1.8;
}
.ds-scene .ds-scene__wall {
	fill: var(--ds-stone-100);
}
.ds-scene .ds-scene__joint {
	stroke: var(--ds-stone-300);
	stroke-width: 1;
}
/* Noch nicht bekleidete Felder. In der Wandfläche mit heller Füllung,
   damit kein Loch in der Silhouette entsteht, frei stehend ohne. */
.ds-scene .ds-scene__open {
	fill: var(--ds-stone-50);
	stroke: var(--ds-stone-300);
	stroke-width: 1.2;
	stroke-dasharray: 3 3;
}
.ds-scene .ds-scene__open--free {
	fill: none;
}
.ds-scene .ds-scene__slab,
.ds-scene .ds-scene__slab-set,
.ds-scene .ds-scene__floor,
.ds-scene .ds-scene__stack rect {
	fill: var(--ds-stone-200);
	stroke-width: 1.4;
}

/* -------------------------------------------------------------- Kran */

.ds-scene .ds-scene__mast,
.ds-scene .ds-scene__jib {
	stroke-width: 1.9;
}
.ds-scene .ds-scene__brace,
.ds-scene .ds-scene__tie {
	stroke: var(--ds-muted);
	stroke-width: 1;
}
.ds-scene .ds-scene__weight,
.ds-scene .ds-scene__cat {
	fill: var(--ds-primary);
	stroke: var(--ds-primary);
}
.ds-scene .ds-scene__hook {
	stroke-width: 1.2;
}
/* Das Seil ist ein Rechteck, dessen Höhe animiert wird. Ein skalierter
   Strich würde durch die runde Linienkappe über den Ausleger hinausragen. */
.ds-scene .ds-scene__rope {
	fill: var(--ds-ink);
	stroke: none;
}
.ds-scene .ds-scene__far path,
.ds-scene .ds-scene__far rect {
	stroke: var(--ds-stone-300);
	stroke-width: 1.2;
}

/* --------------------------------------------------------- Handwerker */

.ds-scene .ds-scene__limb {
	stroke-width: 1.9;
}
.ds-scene .ds-scene__head {
	fill: var(--ds-white);
	stroke-width: 1.4;
}
.ds-scene .ds-scene__helmet {
	fill: var(--ds-primary);
	stroke: var(--ds-primary);
	stroke-width: 1;
}
.ds-scene .ds-scene__helmet-brim {
	stroke: var(--ds-primary);
	stroke-width: 1.6;
}
.ds-scene .ds-scene__hammer {
	fill: var(--ds-primary);
	stroke: var(--ds-primary);
}
.ds-scene .ds-scene__spark {
	stroke: var(--ds-primary);
	stroke-width: 1.4;
	transform-origin: 250px 133px;
	/* Blitzt nur im Takt des Hammers auf, im Stillstand unsichtbar. */
	opacity: 0;
}

/* ---------------------------------------------------------- Bewegung */

/* Ruhelage: Laufkatze auf halber Strecke, Platte hängt am Seil. Ohne
   Animation (reduzierte Bewegung) bleibt das Bild genau so stehen. */
.ds-scene__trolley {
	transform: translateX(40px);
}
.ds-scene__rope {
	height: 60px;
}
.ds-scene__load {
	transform: translateY(60px);
}
.ds-scene__torso--a {
	transform-origin: 122px 203px;
}
.ds-scene__torso--b {
	transform-origin: 70px 203px;
}
.ds-scene__arm-c {
	transform-origin: 272px 124px;
	transform: rotate(-14deg);
}
.ds-scene__far-load {
	transform-origin: 288px 74px;
}

/* Ein Umlauf: Platte am Stapel anschlagen, hochziehen, zur Fassade fahren,
   absetzen, leer zurück. Seil und Last laufen exakt synchron, die Zahlen
   sind Seillänge in User-Units. */
@keyframes ds-scene-trolley {
	0%,
	22% {
		transform: translateX(0);
	}
	38%,
	66% {
		transform: translateX(84px);
	}
	82%,
	100% {
		transform: translateX(0);
	}
}
@keyframes ds-scene-rope {
	0%,
	8% {
		height: 139px;
	}
	22%,
	38% {
		height: 28px;
	}
	50%,
	56% {
		height: 81px;
	}
	66%,
	82% {
		height: 28px;
	}
	94%,
	100% {
		height: 139px;
	}
}
@keyframes ds-scene-load {
	0%,
	8% {
		transform: translateY(139px);
	}
	22%,
	38% {
		transform: translateY(28px);
	}
	50%,
	56% {
		transform: translateY(81px);
	}
	66%,
	82% {
		transform: translateY(28px);
	}
	94%,
	100% {
		transform: translateY(139px);
	}
}
/* Die Platte bleibt beim Absetzen liegen: dort deckt sie sich mit der
   bereits gesetzten Platte der obersten Reihe. */
@keyframes ds-scene-slab {
	0%,
	52% {
		opacity: 1;
	}
	53%,
	94% {
		opacity: 0;
	}
	95%,
	100% {
		opacity: 1;
	}
}
@keyframes ds-scene-bend-a {
	from {
		transform: rotate(3deg);
	}
	to {
		transform: rotate(27deg);
	}
}
@keyframes ds-scene-bend-b {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(19deg);
	}
}
@keyframes ds-scene-hammer {
	from {
		transform: rotate(-34deg);
	}
	to {
		transform: rotate(6deg);
	}
}
@keyframes ds-scene-spark {
	0%,
	46% {
		opacity: 0;
	}
	54% {
		opacity: 1;
	}
	72%,
	100% {
		opacity: 0;
	}
}
@keyframes ds-scene-sway {
	from {
		transform: rotate(-4deg);
	}
	to {
		transform: rotate(4deg);
	}
}

.ds-scene__trolley {
	animation: ds-scene-trolley 11s ease-in-out infinite;
}
.ds-scene__rope {
	animation: ds-scene-rope 11s ease-in-out infinite;
}
.ds-scene__load {
	animation: ds-scene-load 11s ease-in-out infinite;
}
.ds-scene__slab {
	animation: ds-scene-slab 11s linear infinite;
}
.ds-scene__torso--a {
	animation: ds-scene-bend-a 3.4s ease-in-out infinite alternate;
}
.ds-scene__torso--b {
	animation: ds-scene-bend-b 2.6s ease-in-out -1.1s infinite alternate;
}
.ds-scene__arm-c {
	animation: ds-scene-hammer 0.78s ease-in-out infinite alternate;
}
.ds-scene__spark {
	animation: ds-scene-spark 1.56s linear infinite;
}
.ds-scene__far-load {
	animation: ds-scene-sway 6s ease-in-out infinite alternate;
}

/* Erst laufen lassen, wenn der Abschnitt im Bild ist. */
.ds-intro:not(.is-in) .ds-scene * {
	animation-play-state: paused;
}
.no-js .ds-intro .ds-scene * {
	animation-play-state: running;
}

@media (prefers-reduced-motion: reduce) {
	.ds-pp .ds-scene * {
		animation: none !important;
	}
}

/* =============================================================================
   Mobile-Feinschliff, 09.09.2026
   Gemessen mit Playwright auf 320, 360, 375, 390, 414, 430, 768 und 1024px.
   Alle Regeln greifen ausschliesslich am Handy oder auf Touchgeraeten.
   Am Desktop aendert sich nichts.
   ========================================================================== */

/* --- 1. Ankersprung landet nicht mehr unter der Kopfzeile -------------------
   Die Kopfzeile des Themes wird ab dem ersten Scrollen position:fixed und ist
   am Handy 80px hoch. .ds-contact trug bereits scroll-margin-top, gerendert
   wird aber der Beaver-Builder-Block .ds-contact-bb, und der Intro-Anker
   #projekt hatte gar keins. Gemessen: das Sprungziel lag 79 bis 80px unter
   der Kopfzeile, die Ueberschrift war nach dem Sprung nicht zu sehen. */
.ds-pp .ds-contact-bb,
.ds-pp .ds-intro,
.ds-pp .ds-gallery,
.ds-pp .ds-more {
	scroll-margin-top: 5.5rem;
}

/* --- 2. iOS zoomt nicht mehr in die Formularfelder --------------------------
   Safari auf dem iPhone zoomt beim Antippen in jedes Feld unter 16px hinein
   und zoomt danach nicht von selbst zurueck. Die WPForms-Felder im
   Kontaktblock standen auf 12px. 16px ist genau die Schwelle, ab der Safari
   den Zoom unterlaesst. Die Felder werden dadurch etwas hoeher, die Optik
   des Blocks bleibt sonst unveraendert.
   Die Spezifitaet muss ueber der PowerPack-Regel liegen, weil deren
   Stylesheet (fl-builder-layout-368) nach dieser Datei geladen wird. */
@media (max-width: 782px) {

	/* Die :not()-Kette ist aus der PowerPack-Regel gespiegelt und um eine
	   Klasse erweitert. Jedes :not([type=...]) zaehlt wie eine Klasse, die
	   Originalregel kommt damit auf 0-10-1 und wird ausserdem spaeter
	   geladen als diese Datei. Ohne diese Spezifitaet greift der Fix nicht. */
	.ds-pp .ds-bb.ds-contact-bb .pp-wpforms-content .wpforms-container .wpforms-form input:not([type="radio"]):not([type="checkbox"]):not([type="submit"]):not([type="button"]):not([type="image"]):not([type="file"]),
	.ds-pp .ds-bb.ds-contact-bb .pp-wpforms-content .wpforms-container .wpforms-form select,
	.ds-pp .ds-bb.ds-contact-bb .pp-wpforms-content .wpforms-container .wpforms-form textarea {
		font-size: 16px;
	}

	/* Die Pflicht-Checkbox fuer den Datenschutz war 14x14px gross. Das ist
	   deutlich unter jeder Empfehlung fuer Touchbedienung und sie muss
	   zwingend getroffen werden, sonst laesst sich das Formular nicht
	   absenden. */
	.ds-pp .ds-bb.ds-contact-bb .wpforms-container .wpforms-form input[type="checkbox"],
	.ds-pp .ds-bb.ds-contact-bb .wpforms-container .wpforms-form input[type="radio"] {
		width: 22px;
		height: 22px;
	}
}

/* --- 3. Hover-Zustaende bleiben auf Touchgeraeten nicht mehr kleben ---------
   Ohne hover-Guard behaelt eine angetippte Kachel ihren Hover-Zustand, bis
   woanders hingetippt wird. Am Handy sieht das aus, als haenge das Layout.
   Betroffen sind die Karten, die sich um 4px anheben und deren Bild
   leicht zoomt. Der Tastaturfokus (:focus-visible) bleibt unberuehrt. */
@media (hover: none) {

	.ds-pp .ds-part:hover,
	.ds-pp .ds-more__card:hover,
	.ds-pp .ds-fact:hover {
		transform: none;
	}

	.ds-pp .ds-part:hover .ds-part__img,
	.ds-pp .ds-more__card:hover .ds-more__img,
	.ds-pp .ds-gallery__btn:hover .ds-gallery__img {
		transform: none;
	}
}

/* =============================================================================
   Bildnachweis auf den Projektfotos
   Kleine Zeile unten rechts im Bild. pointer-events: none, damit Klick und
   Hover weiter beim Bild landen. Im Hero liegt sie über der Rollo-Bahn
   (z-index 0) und unter dem Flugzeug (3).
   ========================================================================== */

.ds-pp .ds-credit {
	position: absolute;
	right: 0;
	bottom: 0;
	z-index: 2;
	max-width: 100%;
	padding: 0.2rem 0.5rem;
	font-family: var(--ds-sans);
	font-size: 0.6875rem;
	line-height: 1.3;
	letter-spacing: 0.02em;
	color: rgba(255, 255, 255, 0.9);
	background: rgba(10, 12, 15, 0.42);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	pointer-events: none;
}

.ds-lb__credit {
	display: block;
	margin-top: 0.25rem;
	font-size: 0.75rem;
	color: rgba(255, 255, 255, 0.55);
}
