/* leXpro Media — Startseite V2, „Sichtbarkeit".
   ---------------------------------------------------------------------------
   Ein Konzept, kein Effekt-Katalog: die Seite beginnt dunkel und schlecht lesbar
   und wird beim Scrollen hell. Das ist genau die Behauptung des Eingangstextes
   („weil sie mehr Sichtbarkeit hat als du"), nur als Layout ausgeführt.

   Lädt NACH tokens.css, components.css und lexpro-motion.css.
   Alle Klassen sind mit `v2-` präfixiert; wiederverwendet werden nur `.lx-btn`,
   `.lx-label` und `.lx-grain` aus dem Marken-CSS.

   Bewegungsregel wie in V1 dreistufig: OS-Präferenz, eigener Schalter
   (`data-motion` am <html>), und jeder versteckte Zustand steht INNERHALB des
   `@supports`-Blocks — ein Browser ohne Scroll-Timelines liefert die Seite
   statisch, aber vollständig aus.
   ========================================================================== */

/* ==========================================================================
   0 · Grundlagen
   ========================================================================== */

.v2 {
	--v2-pad: clamp(1.25rem, 5vw, 5rem);
	--v2-y: clamp(5rem, 13vw, 12rem);
	--v2-max: 1560px;

	background: var(--ink-1000);
	color: var(--text-primary);
	/* clip statt hidden: hidden auf einem Element mit sticky-Kindern erzeugt einen
	   Scroll-Container und tötet jedes `position: sticky` darin. */
	overflow-x: clip;
}

.v2 :where(h1, h2, h3) {
	font-family: var(--font-display);
	font-weight: var(--fw-ultra);
	letter-spacing: var(--ls-tight);
	text-wrap: balance;
	margin: 0;
}

.v2 :where(p) {
	margin: 0;
}

.v2 section {
	position: relative;
}

.v2-h2 {
	font-size: clamp(2.25rem, 6.2vw, 5.25rem);
	line-height: 0.94;
	max-width: 18ch;
}

.v2-h2--mega {
	font-size: clamp(2.5rem, 7.5vw, 7rem);
	max-width: 15ch;
}

.v2-h2--stack {
	max-width: none;
}

/* Überschriften kommen unter einer Kante hervor statt einzublenden.
   `clip-path` statt `opacity`, weil ein Element mit `opacity: 0` kein
   LCP-Kandidat ist — die Regel gilt hier zwar nur fürs Hero-H1, aber ein
   zweiter Mechanismus für denselben Effekt wäre unnötiger Ballast.
   Der versteckte Zustand steht INNERHALB von @supports: ohne Scroll-Timelines
   ist die Überschrift von Anfang an vollständig sichtbar. */
/* Zwei Bezugsquellen, ein Mechanismus — wie beim Lichtsatz in design.js.
   Das Attribut ist die ursprüngliche Auszeichnung; die Klasse gibt es dazu, weil in
   Elementor gebaute Seiten Klassen vergeben und ein eigenes Attribut beim Bearbeiten
   im Editor verlorengeht. Genau deshalb stand auf der V3-Startseite monatelang
   `v3-lines` im Markup, wofür es NIRGENDS eine Regel gab: die Enthüllung lief auf
   der ganzen Seite nicht, ohne dass irgendetwas auffiel. */
@supports (animation-timeline: view()) {
	[data-v2-lines],
	.v2-lines {
		animation: v2-rise linear both;
		animation-timeline: view();
		/* Endpunkt bei cover 45%, nicht bei entry 100%: sonst ist die Bewegung
		   vorbei, bevor das Auge die Überschrift erreicht hat, und die Seite
		   wirkt statisch, obwohl sie animiert ist. */
		animation-range: entry 12% cover 42%;
	}
}

@keyframes v2-rise {
	from { clip-path: inset(0 0 108% 0); translate: 0 0.35em; }
	to   { clip-path: inset(0 0 -20% 0); translate: 0 0; }
}

.v2-lead {
	font-family: var(--font-text);
	font-size: clamp(1.0625rem, 1.5vw, 1.3125rem);
	line-height: var(--lh-body);
	color: var(--text-secondary);
	max-width: 54ch;
}

/* Gold-Gradient auf Text. Muss im Kontrastmodus zurückgenommen werden — dort
   verwirft der Browser den Verlauf, `-webkit-text-fill-color: transparent`
   bleibt aber stehen, und die Überschrift wäre schlicht unsichtbar. */
.v2-gold {
	background: var(--grad-gold);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

@media (forced-colors: active) {
	.v2-gold,
	.v2-hero__mega,
	.v2-fig__num {
		background: none;
		color: CanvasText;
		-webkit-text-fill-color: CanvasText;
	}
}

/* ==========================================================================
   1 · Fortschritt — der „Sichtbarkeits-Index"
   Reine CSS-Scroll-Timeline. Die Prozentzahl kommt aus einem registrierten
   Integer über counter() — dafür braucht es kein Javascript.
   ========================================================================== */

@property --v2-progress {
	syntax: "<integer>";
	initial-value: 0;
	inherits: false;
}

.v2-progress {
	position: fixed;
	inset: 0 0 auto 0;
	height: 2px;
	z-index: 60;
	pointer-events: none;
	background: rgb(212 175 55 / 0.12);
}

.v2-progress i {
	display: block;
	height: 100%;
	background: var(--grad-gold);
	transform-origin: 0 50%;
	scale: 0 1;
}

.v2-hud {
	position: fixed;
	right: clamp(1rem, 2.5vw, 2.5rem);
	bottom: clamp(1rem, 2.5vw, 2.5rem);
	z-index: 55;
	display: none;
	align-items: center;
	gap: 0.75rem;
	padding: 0.55rem 0.9rem;
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	letter-spacing: var(--ls-overline);
	text-transform: uppercase;
	color: var(--text-muted);
	background: rgb(11 10 9 / 0.72);
	border: var(--hairline-gold);
	backdrop-filter: blur(8px);
	pointer-events: none;
}

@media (min-width: 1024px) {
	.v2-hud { display: flex; }
}

.v2-hud__bar {
	display: block;
	width: 72px;
	height: 3px;
	background: rgb(212 175 55 / 0.16);
}

.v2-hud__bar i {
	display: block;
	height: 100%;
	background: var(--au-mid);
	transform-origin: 0 50%;
	scale: 0 1;
}

.v2-hud__num {
	min-width: 3.5em;
	text-align: right;
	color: var(--au-light);
	font-variant-numeric: tabular-nums;
	/* counter-reset MUSS auf dem Element liegen: --v2-progress ist mit
	   inherits: false registriert, das ::after sähe sonst ewig den
	   Initialwert 0. Das ::after liest den Counter nur noch aus. */
	counter-reset: v2n var(--v2-progress);
}

.v2-hud__num::after {
	content: counter(v2n) "%";
}

@supports (animation-timeline: scroll()) {
	.v2-progress i,
	.v2-hud__bar i {
		animation: v2-fill linear both;
		animation-timeline: scroll(root block);
	}

	.v2-hud__num {
		animation: v2-count linear both;
		animation-timeline: scroll(root block);
	}

	/* Am Seitenende räumt das HUD das Feld: es stand sonst auf der Impressum-Zeile
	   des Footers (klickbar blieb sie — pointer-events: none —, aber lesbar nicht).
	   Erst ab 98,5 %, damit der Moment „Sichtbarkeit 100 %" beim Ankommen noch
	   stattfindet; die letzten anderthalb Prozent sind genau die Footer-Zeile. */
	.v2-hud {
		animation: v2-hud-weg linear both;
		animation-timeline: scroll(root block);
	}
}

@keyframes v2-fill { to { scale: 1 1; } }
@keyframes v2-count { to { --v2-progress: 100; } }
@keyframes v2-hud-weg {
	0%, 98.5% { opacity: 1; }
	100% { opacity: 0; }
}

/* ==========================================================================
   2 · Hero — ein typografischer Auftritt, kein Fließtext
   Regel aus V1 bleibt: das LCP-Element bekommt NIE eine Opacity-Animation.
   ========================================================================== */

.v2-hero {
	min-height: calc(100svh - var(--lx-header-h, 105px));
	display: grid;
	grid-template-rows: 1fr auto;
	align-content: end;
	padding: clamp(3rem, 9vw, 8rem) var(--v2-pad) clamp(2rem, 4vw, 3.5rem);
	isolation: isolate;
	overflow: clip;
}

/* Die Lichtszene. Liegt ganz unten und bleibt bewusst gedämpft — sie ist
   Atmosphäre, keine Aussage. Bei voller Deckkraft würde sie das H1 bedrängen,
   und das H1 ist der Grund, warum es diese Seite gibt.
   Der Verlauf darüber zieht die untere Hälfte ins Schwarz, damit die
   Unterzeile und die Knöpfe auf ruhigem Grund stehen. */
.v2-hero__film {
	position: absolute;
	inset: 0;
	z-index: -3;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0.42;
	filter: saturate(0.85) contrast(1.05);
	pointer-events: none;
}

.v2-hero:has(.v2-hero__film)::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -3;
	pointer-events: none;
	background: linear-gradient(180deg,
		rgb(11 10 9 / 0.35) 0%,
		rgb(11 10 9 / 0.55) 45%,
		rgb(11 10 9 / 0.92) 100%);
}

/* Der Pausenknopf sitzt unten rechts im Hero, nicht am Seitenrand — sonst
   sucht man ihn bei dem Element, zu dem er gehört, und findet ihn woanders. */
.v2-pause--hero {
	position: absolute;
	right: var(--v2-pad);
	bottom: clamp(1rem, 2vw, 1.75rem);
	margin: 0;
	z-index: 2;
	background: rgb(11 10 9 / 0.6);
	backdrop-filter: blur(6px);
}

/* Lichtquelle. Folgt auf dem Desktop dem Zeiger (--mx/--my werden in v2.js
   gesetzt), sonst steht sie fest. Zwei Quellen, damit das Gold nicht wie ein
   aufgeklebter Kreis wirkt. */
.v2-hero__bloom {
	position: absolute;
	inset: -20%;
	z-index: -2;
	pointer-events: none;
	background:
		radial-gradient(38rem 30rem at var(--mx, 50%) var(--my, 28%), rgb(212 175 55 / 0.20), transparent 62%),
		radial-gradient(70rem 46rem at 82% 8%, rgb(156 124 30 / 0.14), transparent 70%);
	transition: background-position 400ms linear;
}

/* Riesenwort im Hintergrund. Es ist Dekoration und darf nicht vorgelesen
   werden — deshalb aria-hidden im Markup. */
.v2-hero__ghost {
	position: absolute;
	inset: auto 0 8% 0;
	z-index: -1;
	pointer-events: none;
	overflow: clip;
	mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.v2-ghost__row {
	display: flex;
	gap: 4vw;
	width: max-content;
	font-family: var(--font-display);
	font-weight: var(--fw-ultra);
	font-size: clamp(6rem, 22vw, 22rem);
	line-height: 0.8;
	color: transparent;
	-webkit-text-stroke: 1px rgb(212 175 55 / 0.10);
	white-space: nowrap;
}

.v2-hero__inner {
	display: grid;
	gap: clamp(2rem, 5vw, 4rem);
	width: 100%;
	max-width: var(--v2-max);
	margin-inline: auto;
	align-self: end;
}

.v2-hero__h1 {
	display: grid;
	gap: 0.15em;
}

.v2-hero__lead {
	font-family: var(--font-mono);
	font-weight: 400;
	font-size: clamp(0.875rem, 1.35vw, 1.125rem);
	/* KEINE Versalien: der Markenname wird „leXpro Media" geschrieben, mit
	   kleinem l und grossem X. `text-transform: uppercase` machte daraus
	   „LEXPRO MEDIA" und damit eine andere Schreibweise als ueberall sonst.
	   Sperrung entsprechend zurueckgenommen — bei Gemischtschreibung wirkt
	   die Laufweite eines Mikrolabels zu locker. */
	letter-spacing: 0.06em;
	color: var(--au-mid);
}

.v2-hero__mega {
	display: block;
	/* Auch an der HÖHE begrenzt, nicht nur an der Breite: auf einem flachen
	   Notebook-Display schiebt eine rein breitenbasierte Größe den Hero unter
	   die Falz, und der Auftritt ist genau dann kaputt, wenn er zählt. */
	font-size: clamp(3.75rem, min(17vw, 27svh), 16rem);
	line-height: 0.8;
	letter-spacing: -0.035em;
	background: var(--grad-gold);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

.v2-hero__tail {
	display: block;
	font-size: clamp(1.5rem, 4.6vw, 4rem);
	line-height: 0.95;
	color: var(--text-primary);
}

.v2-hero__foot {
	display: flex;
	flex-wrap: wrap;
	align-items: end;
	justify-content: space-between;
	gap: clamp(1.5rem, 4vw, 3rem);
	padding-top: clamp(1.5rem, 3vw, 2.5rem);
	border-top: var(--hairline-gold);
}

.v2-hero__tags {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
	font-family: var(--font-mono);
	font-size: 0.75rem;
	letter-spacing: var(--ls-overline);
	text-transform: uppercase;
	color: var(--text-muted);
}

.v2-hero__tags li::before {
	content: "→ ";
	color: var(--au-mid);
}

.v2-hero__cta {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
}

.v2-hero__scroll {
	position: absolute;
	left: var(--v2-pad);
	bottom: clamp(2rem, 4vw, 3.5rem);
	font-family: var(--font-mono);
	font-size: 0.625rem;
	letter-spacing: var(--ls-overline);
	text-transform: uppercase;
	color: var(--text-muted);
	writing-mode: vertical-rl;
	display: none;
}

@media (min-width: 1280px) {
	.v2-hero__scroll { display: block; }
	.v2-hero { padding-left: calc(var(--v2-pad) + 2.5rem); }
}

@supports (animation-timeline: view()) {
	.v2-ghost__row {
		animation: v2-ghost linear both;
		animation-timeline: scroll(root block);
	}

	.v2-hero__scroll {
		animation: v2-bob 2.4s var(--ease-in-out) infinite alternate;
	}
}

@keyframes v2-ghost { to { translate: -34% 0; } }
@keyframes v2-bob { to { translate: 0 0.75rem; } }

/* ==========================================================================
   3 · Der Satz, der hell wird
   Jedes Wort bekommt in v2.js ein `--p` von 0 bis 1 und wird an genau seiner
   Stelle im Scrollfortschritt sichtbar. Ohne Scroll-Timelines steht der Absatz
   sofort voll lesbar da — der gedimmte Zustand existiert nur innerhalb
   des @supports-Blocks.
   ========================================================================== */

.v2-lit {
	padding: var(--v2-y) var(--v2-pad);
	display: grid;
	place-items: center;
	min-height: 70svh;
}

.v2-lit__text {
	font-family: var(--font-text);
	font-weight: 500;
	font-size: clamp(1.25rem, 3.3vw, 2.6rem);
	line-height: 1.34;
	max-width: 20em;
	text-wrap: pretty;
}

.v2-w {
	display: inline-block;
	white-space: pre-wrap;
}

@supports (animation-timeline: view()) {
	.v2-w {
		color: rgb(147 144 137 / 0.28);
		animation: v2-light linear both;
		animation-timeline: view();
		animation-range:
			cover calc(14% + var(--p, 0) * 46%)
			cover calc(26% + var(--p, 0) * 46%);
	}
}

@keyframes v2-light {
	to { color: var(--text-primary); }
}

/* ==========================================================================
   4 · Beweis
   ========================================================================== */

.v2-proof {
	padding: var(--v2-y) var(--v2-pad);
	max-width: var(--v2-max);
	margin-inline: auto;
	display: grid;
	gap: clamp(3rem, 7vw, 6rem);
}

.v2-proof__head {
	display: grid;
	gap: 1.5rem;
	justify-items: start;
	max-width: 70ch;
}

.v2-figures {
	list-style: none;
	margin: 0;
	padding: clamp(2rem, 4vw, 3rem) 0;
	display: grid;
	gap: clamp(2rem, 4vw, 3rem);
	grid-template-columns: 1fr;
	border-top: var(--hairline-gold);
	border-bottom: var(--hairline-gold);
}

@media (min-width: 760px) {
	.v2-figures { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1160px) {
	.v2-figures { grid-template-columns: repeat(4, 1fr); }
}

.v2-fig {
	display: grid;
	gap: 0.5rem;
	align-content: start;
	container-type: inline-size;
}

.v2-fig__num {
	font-family: var(--font-display);
	font-weight: var(--fw-ultra);
	/* cqw statt vw: die Zahl muss in IHRE Spalte passen, nicht ins Fenster.
	   +45.475% ist die längste und bestimmt die Skalierung. */
	font-size: clamp(2.25rem, 19cqw, 4.5rem);
	line-height: 0.9;
	letter-spacing: -0.03em;
	font-variant-numeric: tabular-nums;
	background: var(--grad-gold);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

.v2-fig__num em {
	font-style: normal;
	font-size: 0.55em;
}

.v2-fig__unit {
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	letter-spacing: var(--ls-overline);
	text-transform: uppercase;
	color: var(--au-mid);
}

.v2-fig__note {
	font-family: var(--font-text);
	font-size: 0.9375rem;
	line-height: var(--lh-snug);
	color: var(--text-muted);
	max-width: 34ch;
}

.v2-proof__awards {
	display: grid;
	gap: clamp(2rem, 5vw, 4rem);
	align-items: center;
}

@media (min-width: 900px) {
	.v2-proof__awards { grid-template-columns: 1.05fr 0.95fr; }
}

.v2-proof__shot {
	margin: 0;
	overflow: clip;
	border: var(--hairline-ink);
}

.v2-proof__shot img {
	display: block;
	width: 100%;
	height: auto;
	filter: saturate(0.75) contrast(1.05);
}

.v2-awards {
	list-style: none;
	margin: 1rem 0 0;
	padding: 0;
	display: grid;
}

.v2-awards li {
	display: grid;
	grid-template-columns: 4.5rem 1fr;
	gap: 1rem;
	align-items: baseline;
	padding: 0.9rem 0;
	border-top: var(--hairline-ink);
	font-family: var(--font-text);
	font-size: clamp(1rem, 1.5vw, 1.1875rem);
	color: var(--text-primary);
}

.v2-awards li:last-child { border-bottom: var(--hairline-ink); }

.v2-awards__year {
	font-family: var(--font-mono);
	font-size: 0.8125rem;
	color: var(--au-mid);
	font-variant-numeric: tabular-nums;
}

.v2-awards em {
	display: block;
	font-style: normal;
	font-size: 0.8125rem;
	color: var(--text-muted);
	margin-top: 0.15rem;
}

/* --------------------------------------------------------------------------
   Die Beweis-Sektion verdichten

   Vorher stand die Überschrift links in ihrer Textbreite, die rechte Hälfte
   blieb leer, und die Kennzahlen lagen als Band darunter — ein L-förmiges Loch
   über die halbe Sektion.

   Jetzt stehen die Kennzahlen NEBEN der Behauptung, die sie belegen, getrennt
   durch eine senkrechte Goldlinie. Das ist nicht nur dichter, es ist auch das
   glaubwürdigere Muster: Aussage und Zahl sind dasselbe Objekt, nicht zwei
   Dinge untereinander.
   -------------------------------------------------------------------------- */
@media (min-width: 1100px) {
	.v2-proof {
		grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
		column-gap: clamp(2.5rem, 5vw, 5rem);
		align-items: start;
	}

	.v2-proof__head {
		grid-column: 1;
		grid-row: 1;
	}

	.v2-figures {
		grid-column: 2;
		grid-row: 1;
		/* Gegen die Textspalte zentriert. Oben ausgerichtet standen die vier
		   Zahlen im oberen Drittel und darunter war wieder Luft — genau das
		   Loch, das die Sektion vorher schon hatte, nur kleiner. */
		align-self: center;
		/* Zwei mal zwei statt einer Viererreihe — in halber Breite hätte eine
		   Reihe aus vier Zahlen keine Luft mehr. */
		grid-template-columns: repeat(2, 1fr);
		row-gap: clamp(2.25rem, 4vw, 3.25rem);
		border-top: 0;
		border-bottom: 0;
		border-left: var(--hairline-gold);
		padding: 0.5rem 0 0.5rem clamp(2rem, 4vw, 3.5rem);
	}

	.v2-proof__awards {
		grid-column: 1 / -1;
		grid-row: 2;
	}
}

/* Das Pokalfoto lag im Hochformat und türmte sich neben einer kurzen Liste.
   Ein Querschnitt bringt beide Spalten auf vergleichbare Höhe — und das Motiv
   verliert dabei nichts, die Pokale stehen mittig. */
.v2-proof__shot {
	aspect-ratio: 4 / 3;
}

.v2-proof__shot img {
	height: 100%;
	object-fit: cover;
	object-position: 50% 45%;
}

/* ==========================================================================
   5 · Leistungen, quer gescrollt
   Der Kern des Scrollytellings. Der Weg ist 1:1 gekoppelt — v2.js misst die
   Breite der Bahn und setzt daraus die Höhe der Schiene, damit sich der
   Seitwärtsweg genau so schnell anfühlt wie normales Scrollen.
   Unter 900px und ohne Scroll-Timelines wird daraus eine ganz normale
   vertikale Abfolge; nichts geht verloren.
   ========================================================================== */

.v2-track {
	background:
		radial-gradient(60rem 40rem at 15% 0%, rgb(212 175 55 / 0.07), transparent 60%),
		var(--ink-950);
	border-block: var(--hairline-ink);
}

.v2-track__inner {
	display: grid;
	gap: clamp(1.5rem, 3vw, 3rem);
	padding: var(--v2-y) var(--v2-pad);
}

.v2-panel {
	display: grid;
	align-content: center;
	gap: 1rem;
	padding: clamp(1.75rem, 3vw, 2.75rem);
	border: var(--hairline-ink);
	background: linear-gradient(155deg, rgb(27 24 21 / 0.9), rgb(14 13 11 / 0.9));
}

.v2-panel--intro,
.v2-panel--outro {
	border-color: transparent;
	background: none;
	padding-inline: 0;
}

.v2-panel__num {
	font-family: var(--font-mono);
	font-size: 0.75rem;
	letter-spacing: var(--ls-overline);
	color: var(--au-mid);
}

.v2-panel h3 {
	font-size: clamp(1.75rem, 4vw, 3.25rem);
	line-height: 0.95;
	color: var(--text-primary);
}

.v2-panel p {
	font-family: var(--font-text);
	font-size: clamp(1rem, 1.4vw, 1.1875rem);
	line-height: var(--lh-body);
	color: var(--text-secondary);
	max-width: 32ch;
}

.v2-panel .lx-btn { justify-self: start; }

.v2-panel__hint,
.v2-panel__claim {
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	letter-spacing: var(--ls-overline);
	text-transform: uppercase;
	color: var(--text-muted);
}

.v2-panel__claim {
	font-family: var(--font-text);
	font-size: clamp(1.125rem, 2.4vw, 1.875rem);
	letter-spacing: var(--ls-normal);
	text-transform: none;
	line-height: var(--lh-snug);
	color: var(--text-primary);
	max-width: 24ch;
}

@media (min-width: 900px) {
	.v2-track__rail {
		height: calc(100svh + var(--travel, 120vw));
	}

	.v2-track__stage {
		position: sticky;
		top: 0;
		height: 100svh;
		overflow: clip;
		display: flex;
		/* stretch statt center: nur so reicht die Bahn über die volle Höhe der
		   Stufe, und die Karten füllen den Bildschirm statt in der Mitte zu
		   schweben. Mit `center` bestimmt der Inhalt die Höhe — die Karten
		   waren dadurch rund 390 px hoch bei 720 px Fensterhöhe. */
		align-items: stretch;
	}

	.v2-track__inner {
		display: flex;
		align-items: stretch;
		gap: clamp(1.5rem, 2.5vw, 2.5rem);
		width: max-content;
		/* Ohne `flex-shrink: 0` drueckt die Stufe die Bahn auf Fensterbreite
		   zusammen — sie ist deren Flex-Element. `width: max-content` ist dann
		   nur noch die BEVORZUGTE Breite und wird ueberstimmt.
		   Die Folge ist heimtueckisch: `scrollWidth` bleibt korrekt (3864 px),
		   nur die tatsaechliche Breite schrumpft (2545 px). Und weil die
		   Prozentangabe in `translate: calc(-100% + 100vw)` sich auf die EIGENE
		   Breite bezieht, heben sich beide Terme dann exakt auf — die Bahn
		   laeuft, bewegt sich aber nicht. Gemessen im echten Browser. */
		flex: 0 0 auto;
		padding: var(--lx-header-h, 105px) var(--v2-pad) clamp(2rem, 4vw, 4rem);
	}

	.v2-panel {
		width: min(36rem, 68vw);
		flex: 0 0 auto;
	}

	.v2-panel--intro { width: min(46rem, 78vw); }
	.v2-panel--outro { width: min(34rem, 68vw); }

	/* Größere Fläche verlangt größere Schrift, sonst schwimmt der Text in der
	   Karte. */
	.v2-panel--service h3 { font-size: clamp(2rem, 4.6vw, 4rem); }
	.v2-panel--service p { font-size: clamp(1.0625rem, 1.5vw, 1.3125rem); max-width: 34ch; }
}

/* Gemessen: „Online Marketing" lief in der Bahn 65 px über die Panel-Kante hinaus.
   Die Stufe hat `overflow: clip`, es wäre also nichts nach außen gelaufen — dafür
   wäre es ins nächste Panel gestoßen. Die Überschrift bekommt hier ihre eigene,
   engere Skala statt der globalen `.v2-h2`. */
.v2-panel--intro .v2-h2 > span { display: block; }

.v2-panel--intro .v2-h2 {
	font-size: clamp(2rem, 4.6vw, 4.25rem);
}

/* --------------------------------------------------------------------------
   Die Karten leuchten auf, wenn sie dran sind — dieselbe Mechanik wie der
   Eingangssatz, nur auf Karten statt auf Wörtern. Ohne das ist die Bahn ein
   Fließband: alle vier Karten gleich hell, keine sagt, dass sie gemeint ist.

   `view()` funktioniert hier NICHT. Die Karten bewegen sich per `translate`,
   nicht durch Scrollen, und die Stufe ist wegen `overflow: clip` gar kein
   Scroll-Container — eine View-Timeline sähe die Bewegung nie. Stattdessen
   hängen die Karten an DERSELBEN Schienen-Timeline wie die Bahn und bekommen
   ihren eigenen Ausschnitt daraus: `--c` ist der Fortschritt, bei dem die
   Karte mittig steht, und wird in v2.js aus der gemessenen Geometrie gesetzt.

   `--lit` startet bei 1, nicht bei 0. Ohne Scroll-Timelines, unter 900px und
   bei zurückgenommener Bewegung sind damit alle Karten hell — der gedimmte
   Zustand existiert nur dort, wo er auch wieder aufgehoben wird.
   -------------------------------------------------------------------------- */

@property --lit {
	syntax: "<number>";
	initial-value: 1;
	inherits: true;
}

.v2-panel--service {
	position: relative;
	isolation: isolate;
	/* Der goldene Rahmen zeichnet sich selbst, wenn die Karte in die Mitte fährt,
	   und zieht sich beim Verlassen wieder zurück. Vier Linien-Ebenen über dem
	   Karten-Verlauf, jede wächst mit --lit aus ihrer Ecke: oben aus links, rechts
	   aus oben, unten aus rechts, links aus unten — der Rahmen läuft im
	   Uhrzeigersinn um die Karte. background-origin ist padding-box, die Linien
	   liegen also 1px INNERHALB der --hairline-ink-Kontur, nichts verdeckt sich.
	   Er ersetzt den früheren border-top-color-Ramp (nur Oberkante).
	   In den Rückfallebenen (--lit: 1) steht der Rahmen fertig da — der halbe
	   Zustand existiert nur, wo die Timeline ihn auch wieder auflöst. */
	--rahmen: linear-gradient(rgb(212 175 55 / 0.55), rgb(212 175 55 / 0.55));
	background-image:
		var(--rahmen),
		var(--rahmen),
		var(--rahmen),
		var(--rahmen),
		linear-gradient(155deg, rgb(27 24 21 / 0.9), rgb(14 13 11 / 0.9));
	background-repeat: no-repeat;
	background-size:
		calc(var(--lit) * 100%) 1px,
		1px calc(var(--lit) * 100%),
		calc(var(--lit) * 100%) 1px,
		1px calc(var(--lit) * 100%),
		100% 100%;
	background-position: top left, top right, bottom right, bottom left, 0 0;
	/* Gedimmte Karten sitzen tiefer. Andersherum gerechnet wäre der Ruhezustand
	   ein dauerhaft angehobener Kasten. */
	translate: 0 calc((1 - var(--lit)) * 0.7rem);
}

.v2-panel--service > * {
	opacity: calc(0.4 + var(--lit) * 0.6);
}

.v2-panel--service .v2-panel__num {
	color: rgb(212 175 55 / calc(0.45 + var(--lit) * 0.55));
}

/* --------------------------------------------------------------------------
   Das Motiv hinter der Karte.
   Vier abstrakte Messbilder — Kurve, Raster, Fadenkreuz, Wellen —, je eines pro
   Leistung. Sie liegen als Datei IM Plugin, nicht in der Mediathek: sie gehören
   zur Gestaltung wie das Korn, nicht zum Inhalt. Damit sind die Pfade relativ
   zum Stylesheet und überleben den Umzug auf die Live-Domain ohne einen einzigen
   Eintrag.

   `::after` mit z-index -2 liegt ÜBER dem Verlauf der Karte (den malt das Element
   selbst) und UNTER dem Schein aus `::before` (-1) sowie dem Inhalt. Genau die
   Reihenfolge, die es braucht.

   Die Motive tragen ihre Zeichnung in der unteren Hälfte; oben stehen Ziffer,
   Überschrift und Text. Die Maske blendet das Bild unter der Schrift aus, damit
   kein Buchstabe auf Struktur sitzt.

   Die Deckkraft hängt an `--lit`: eine gedimmte Karte muss auch ein gedimmtes
   Bild haben, sonst leuchtet sie hinten weiter, während sie vorne zurücktritt.
   -------------------------------------------------------------------------- */

/* `--motiv-kraft` gleicht aus, dass die vier Bilder unterschiedlich viel Zeichnung
   tragen. GEMESSEN als Anteil der Pixel heller als 60 von 255 in der unteren
   Bildhälfte — der Mittelwert allein taugt nicht, den heben schwache Streupunkte
   ebenso wie eine kräftige Linie:

     Webdesign 1,652 %   ·   Social 0,669 %   ·   SEO 0,325 %   ·   Recruiting 0,231 %

   Webdesign trägt damit das Fünffache von SEO und wirkt als einziges Panel wie ein
   Bild statt wie ein Untergrund. Es wird zurückgenommen.
   SEO bleibt bei 1, obwohl der Messwert niedrig ist: eine durchgehende Linie über die
   ganze Karte liest sich deutlich, auch wenn sie wenig Fläche belegt. Fläche und
   Lesbarkeit sind hier nicht dasselbe — die Zahl ist ein Hinweis, kein Urteil. */

.v2-panel--seo        { --motiv: url("../img/leistung-seo.webp");        --motiv-kraft: 1; }
.v2-panel--webdesign  { --motiv: url("../img/leistung-webdesign.webp");  --motiv-kraft: 0.72; }
.v2-panel--recruiting { --motiv: url("../img/leistung-recruiting.webp"); --motiv-kraft: 1; }
.v2-panel--social     { --motiv: url("../img/leistung-social.webp");     --motiv-kraft: 0.92; }

.v2-panel--service::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -2;
	pointer-events: none;
	background-image: var(--motiv, none);
	background-size: cover;
	background-position: center bottom;
	background-repeat: no-repeat;
	/* GEMESSEN an allen vier Karten: der Inhalt läuft von 36,2 % (Ziffer) bis 63,8 %
	   (Unterkante des Buttons im ungünstigsten Fall). Die Maske stand vorher auf
	   `transparent 20%, #000 64%` — hinter dem Button war das Bild damit schon zu
	   über 80 % da, und weil der Geist-Button gar keinen Hintergrund hat, stand seine
	   Beschriftung direkt auf der Zeichnung. Bei Webdesign war sie nicht mehr lesbar.
	   Jetzt beginnt das Motiv erst unterhalb des Inhalts. */
	-webkit-mask-image: linear-gradient(180deg, transparent 58%, #000 78%);
	mask-image: linear-gradient(180deg, transparent 58%, #000 78%);
	opacity: calc((0.35 + var(--lit) * 0.5) * var(--motiv-kraft, 1));
}

/* Der Geist-Button steht auf einem Bild und braucht deshalb eine Fläche. Ohne sie
   ist seine Lesbarkeit eine Funktion des Zufalls — je nachdem, was hinter ihm liegt.
   Nur innerhalb der Bahn, damit der Knopf überall sonst der bleibt, der er ist.

   ACHTUNG, gemessen: das führende `.v2` ist kein Zierrat. seiten.css setzt
   `.v2 .lx-btn-ghost .elementor-button { background-color: transparent !important }`
   — dieselbe Spezifität (0-3-1) wie die naheliegende Fassung hier, und weil seiten.css
   NACH design.css lädt, gewinnt sie. Das `!important` auf dieser Seite half deshalb
   gar nichts: die Gegenseite hat es auch. Erst die vierte Klasse (0-4-1) entscheidet.
   Wer hier eine Klasse streicht, macht den Button wieder unlesbar — ohne Fehlermeldung. */
.v2 .v2-panel--service .lx-btn-ghost .elementor-button,
.v2 .v2-panel--service .lx-btn--ghost {
	background-color: rgb(11 10 9 / 0.66) !important;
}

/* Der Schein hinter der aktiven Karte. Gleiche Lichtquelle wie im Hero, nur
   kleiner — deshalb liegt er hinter dem Inhalt und nicht darüber. */
.v2-panel--service::before {
	content: "";
	position: absolute;
	inset: -1px;
	z-index: -1;
	pointer-events: none;
	opacity: 0;
	background: radial-gradient(130% 95% at 50% 0%, rgb(212 175 55 / 0.17), transparent 64%);
}

@supports (animation-timeline: view()) {
	@media (min-width: 900px) {
		.v2-track__rail { view-timeline-name: --v2rail; }

		.v2-track__inner {
			animation: v2-hslide linear both;
			animation-timeline: --v2rail;
			animation-range: contain 0% contain 100%;
		}

		.v2-panel--service {
			animation: v2-panel-lit linear both;
			animation-timeline: --v2rail;
			/* ±24 % um die Mittenposition: schmaler und die Karte blitzt nur auf,
			   breiter und alle vier leuchten gleichzeitig. */
			animation-range:
				contain calc(var(--c, 0.5) * 100% - 24%)
				contain calc(var(--c, 0.5) * 100% + 24%);
		}

		.v2-panel--service::before { opacity: var(--lit); }
	}
}

@keyframes v2-hslide {
	to { translate: calc(-100% + 100vw) 0; }
}

/* Der Halteabschnitt zwischen 44 % und 56 % ist wichtig: ohne ihn ist der
   hellste Punkt ein einziger Frame, und die Karte wirkt, als würde sie
   flackern statt zu stehen. */
@keyframes v2-panel-lit {
	0%, 100%  { --lit: 0; }
	44%, 56%  { --lit: 1; }
}

/* ==========================================================================
   6 · Kinetisches Band
   Zwei gegenläufige Zeilen, oben Kontur, unten gefüllt. Der Wortlaut steht
   einmal echt im Dokument, die Wiederholungen sind aria-hidden.
   ========================================================================== */

.v2-kinetic {
	padding: clamp(3rem, 8vw, 7rem) 0;
	overflow: clip;
	border-block: var(--hairline-gold);
	background: var(--ink-1000);
}

.v2-kin__row {
	overflow: clip;
}

.v2-kin__track {
	display: flex;
	gap: 3vw;
	width: max-content;
	white-space: nowrap;
}

.v2-kin__word {
	font-family: var(--font-display);
	font-weight: var(--fw-ultra);
	font-size: clamp(2.75rem, 9.5vw, 9rem);
	line-height: 1.02;
	letter-spacing: -0.025em;
	color: transparent;
	-webkit-text-stroke: 1px rgb(242 239 233 / 0.34);
}

.v2-kin__word--fill {
	-webkit-text-stroke: 0;
	background: var(--grad-gold);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

@media (forced-colors: active) {
	.v2-kin__word {
		color: CanvasText;
		-webkit-text-fill-color: CanvasText;
		background: none;
		-webkit-text-stroke: 0;
	}
}

.v2-kin__row--a .v2-kin__track { animation: v2-slide-l 38s linear infinite; }
.v2-kin__row--b .v2-kin__track { animation: v2-slide-r 32s linear infinite; }

@keyframes v2-slide-l { to { translate: -33.333% 0; } }
@keyframes v2-slide-r { from { translate: -33.333% 0; } to { translate: 0 0; } }

/* ==========================================================================
   7 · Vorteile als Stapel
   Jede Karte bleibt stehen, die nächste schiebt sich darüber. Der wachsende
   `top`-Versatz lässt die Kanten der darunterliegenden Karten sichtbar — sonst
   sähe man nur die oberste und der Stapel wäre nicht als Stapel erkennbar.
   ========================================================================== */

.v2-stack-sec {
	padding: var(--v2-y) var(--v2-pad);
	max-width: var(--v2-max);
	margin-inline: auto;
}

.v2-stack-sec__head {
	display: grid;
	gap: 1rem;
	margin-bottom: clamp(2rem, 5vw, 4rem);
}

.v2-stack {
	list-style: none;
	margin: 0;
	padding: 0;
}

.v2-stack__slot {
	position: sticky;
	top: calc(var(--lx-header-h, 105px) + 1.5rem + var(--i) * 0.85rem);
	padding-bottom: clamp(1rem, 2vw, 1.75rem);
}

.v2-stack__card {
	position: relative;
	isolation: isolate;
	/* clip, damit die große Schattenziffer unten sauber an der Kante abreißt —
	   genau dieser Anschnitt lässt sie wie Druck wirken und nicht wie ein
	   hineingelegtes Bild. */
	overflow: clip;
	display: grid;
	gap: 0.85rem;
	padding: clamp(1.75rem, 4vw, 3.25rem);
	border: var(--hairline-ink);
	border-top: 0;
	background:
		radial-gradient(75% 100% at 0% 0%, rgb(212 175 55 / 0.075), transparent 58%),
		linear-gradient(160deg, #1c1916, #0e0d0b 72%);
	box-shadow: 0 -20px 54px rgb(0 0 0 / 0.6);
	/* Vorher 14–20rem bei rund 110px Inhalt — die untere Hälfte war schlicht
	   leer. Jetzt knapper, und was übrig bleibt, trägt die Ziffer. */
	min-height: clamp(11rem, 24vh, 16rem);
	align-content: center;
}

/* Die Oberkante ist das Einzige, was man von den darunterliegenden Karten
   sieht. Ein gleichmäßiger Goldstrich wirkt dort wie ein Trennstrich; ein
   auslaufender Verlauf lässt den Stapel nach Schichtung aussehen. */
.v2-stack__card::before {
	content: "";
	position: absolute;
	inset: 0 0 auto 0;
	height: 1px;
	background: linear-gradient(90deg,
		var(--au-light) 0%,
		var(--au-mid) 14%,
		rgb(212 175 55 / 0.14) 52%,
		transparent 88%);
}

/* Schattenziffer. Füllt die untere Hälfte, ohne etwas zu behaupten —
   Kontur statt Fläche, damit sie den Text nicht bedrängt. */
.v2-stack__card::after {
	content: attr(data-n);
	position: absolute;
	left: clamp(1.75rem, 4vw, 3.25rem);
	bottom: -0.3em;
	z-index: -1;
	font-family: var(--font-display);
	font-weight: var(--fw-ultra);
	/* Größe ist gerechnet, nicht geschätzt: sichtbare Höhe der Ziffer ist
	   `1,1 × Schriftgröße` (Zeilenhöhe 0,8 plus 0,3em Anschnitt). Bei der
	   flachsten Karte (218 px) endet die Überschrift bei 104 px — also muss
	   1,1 × Schriftgröße ≤ 114 px bleiben. Mit 96 px Deckel passt es auf
	   jeder der sechs Karten, gemessen und nachgerechnet. */
	font-size: clamp(3.5rem, 8vw, 6rem);
	line-height: 0.8;
	letter-spacing: -0.04em;
	color: transparent;
	-webkit-text-stroke: 1px rgb(212 175 55 / 0.16);
	pointer-events: none;
}

/* Unter 900px steht alles einspaltig untereinander — dort läge die Ziffer
   hinter dem Fließtext. */
@media (max-width: 899px) {
	.v2-stack__card::after { content: none; }
}

.v2-stack__num {
	position: relative;
	font-family: var(--font-mono);
	font-size: 0.75rem;
	letter-spacing: var(--ls-overline);
	color: var(--au-mid);
	font-variant-numeric: tabular-nums;
}

/* Kurzer Goldstrich über der Ziffer. Ohne ihn steht sie allein in einer 4rem
   breiten Spalte und liest sich wie ein vergessener Rest; mit ihm ist sie eine
   Marke am Anfang der Zeile. */
@media (min-width: 900px) {
	.v2-stack__num {
		padding-top: 0.9em;
	}

	.v2-stack__num::before {
		content: "";
		position: absolute;
		inset: 0 auto auto 0;
		width: 1.75rem;
		height: 1px;
		background: var(--au-mid);
	}
}

/* Zeigt an, dass die Karte gemeint ist — dieselbe Sprache wie die Karten in
   der horizontalen Bahn, nur hier vom Zeiger ausgelöst statt vom Scrollen. */
.v2-stack__card::before,
.v2-stack__card::after {
	transition: opacity var(--dur-base) var(--ease-out);
}

.v2-stack__card:hover::after { -webkit-text-stroke-color: rgb(212 175 55 / 0.26); }

.v2-stack__card h3 {
	font-size: clamp(1.75rem, 4.5vw, 3.5rem);
	line-height: 0.95;
}

.v2-stack__card p {
	font-family: var(--font-text);
	font-size: clamp(1rem, 1.4vw, 1.125rem);
	line-height: var(--lh-body);
	color: var(--text-secondary);
	max-width: 62ch;
}

@media (min-width: 900px) {
	.v2-stack__card {
		grid-template-columns: 4rem minmax(0, 1fr) minmax(0, 1.15fr);
		gap: clamp(1.5rem, 3vw, 3rem);
		align-items: start;
	}

	.v2-stack__num { grid-row: 1; }
	.v2-stack__card h3 { grid-row: 1; }

	/* Senkrechte Haarlinie zwischen Titel- und Textspalte. Macht die
	   dreispaltige Struktur sichtbar, die sonst nur aus Abständen besteht —
	   und es ist dieselbe Hairline-Sprache wie im Rest der Seite. */
	.v2-stack__card p {
		grid-row: 1;
		border-left: var(--hairline-gold);
		padding-left: clamp(1.25rem, 2.5vw, 2.25rem);
	}
}

/* ==========================================================================
   8 · Stimmen
   ========================================================================== */

.v2-voices {
	padding: var(--v2-y) var(--v2-pad);
	max-width: var(--v2-max);
	margin-inline: auto;
	display: grid;
	gap: clamp(2.5rem, 6vw, 5rem);
}

.v2-voices__head { display: grid; gap: 1rem; }

.v2-voices__films {
	display: grid;
	gap: clamp(1rem, 2.5vw, 2rem);
	grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
}

.v2-film { margin: 0; display: grid; gap: 0.75rem; }

.v2-film__video {
	display: block;
	width: 100%;
	aspect-ratio: 9 / 16;
	object-fit: cover;
	background: var(--ink-900);
	border: var(--hairline-ink);
}

.v2-film figcaption {
	display: grid;
	font-family: var(--font-text);
	font-size: 0.9375rem;
	color: var(--text-muted);
}

.v2-film figcaption strong { color: var(--text-primary); font-weight: 500; }

/* --------------------------------------------------------------------------
   Bento — aber die Groesse folgt der Substanz, nicht der Laune.

   Vorher standen 14 Zitate als gleich grosse Kaesten nebeneinander. Bei
   identischem Gewicht fuehrt nichts, also wird nichts gelesen. Jetzt bekommen
   ausfuehrliche Stimmen Breite und kurze grosse Schrift — eine kurze Stimme in
   grosser Type ist ein Ausrufezeichen, eine kurze Stimme in einer breiten
   Kachel ist ein Loch.

   Kacheln in derselben Reihe strecken sich auf gleiche Hoehe. Das ist der
   Unterschied zwischen einem Bento und einem Mauerwerk mit Luecken.
   -------------------------------------------------------------------------- */
.v2-quotes {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: 1fr;
	gap: clamp(0.75rem, 1.6vw, 1.25rem);
	/* `dense` fuellt Luecken mit spaeteren, schmaleren Kacheln auf. */
	grid-auto-flow: dense;
}

@media (min-width: 760px) {
	.v2-quotes { grid-template-columns: repeat(4, 1fr); }
	.v2-quote { grid-column: span 2; }
	.v2-quote--xl { grid-column: span 4; }
}

@media (min-width: 1200px) {
	.v2-quotes { grid-template-columns: repeat(6, 1fr); }
	.v2-quote { grid-column: span 2; }
	.v2-quote--xl { grid-column: span 3; }
}

.v2-quote {
	display: grid;
	/* Firmenname an die Unterkante. Bei `start` sammelte sich der freie Platz
	   unter dem Namen, und kurze Stimmen sahen nach halbleerer Kachel aus. */
	align-content: space-between;
	gap: 0.9rem;
	padding: clamp(1.25rem, 2.2vw, 1.9rem);
	/* Kein Vollrahmen. Gold nur an der Oberkante — dieselbe Sprache wie die
	   Stapel-Karten, und das Design System sagt: Tiefe kommt aus Raendern. */
	border: var(--hairline-ink);
	border-top: 1px solid rgb(212 175 55 / 0.28);
	background:
		radial-gradient(80% 100% at 0% 0%, rgb(212 175 55 / 0.05), transparent 60%),
		linear-gradient(160deg, rgb(27 24 21 / 0.7), rgb(14 13 11 / 0.7));
	transition: border-top-color var(--dur-base) var(--ease-out);
}

.v2-quote:hover { border-top-color: var(--au-mid); }

.v2-quote blockquote {
	margin: 0;
	font-family: var(--font-text);
	font-size: 0.9375rem;
	line-height: var(--lh-body);
	color: var(--text-secondary);
	text-wrap: pretty;
}

/* EINE Schriftgroesse fuer alle Kacheln.
   Der erste Anlauf gab kurzen Zitaten grosse Type — die Idee war, dass sie den
   Platz haben. In der Ansicht war das ein Fehler: nebeneinander liegende
   Kacheln GLEICHER Breite mit deutlich verschiedener Schriftgroesse lesen sich
   nicht als Hierarchie, sondern als Versehen. Groessenunterschied funktioniert
   nur, wenn auch die Flaeche mitwaechst.

   Unterschieden wird deshalb nur noch ueber die Kachelbreite. Die breite
   xl-Kachel setzt zweispaltig, damit die Zeilen nicht ueberlang werden —
   das ist Lesbarkeit, keine Betonung. */
.v2-quote--xl blockquote {
	columns: 2;
	column-gap: clamp(1.5rem, 3vw, 2.5rem);
	/* Die Trennlinie ist das Zeitungssignal: EIN Text, der in der zweiten Spalte
	   weiterläuft. Ohne sie lasen sich die zwei Spalten als zwei Zitate — und die
	   zweite begann mitten im Satz. */
	column-rule: var(--hairline-ink);
}

@media (max-width: 759px) {
	.v2-quote--xl blockquote { columns: 1; }
}

/* --------------------------------------------------------------------------
   Die Kundenstimmen-Bühne: drei Leitstimmen, eine zur Zeit, gross und still.
   Bewusst das GEGENTEIL der übrigen Startseiten-Choreografien (Bahn, Stapel,
   Bänder): der einzige ruhige, grosse Lese-Moment der Seite. Scroll-gesteuert
   über die eigene Schiene; die Taktleiste unten füllt sich über die gesamte
   Strecke und kündigt den Wechsel an.

   Ausfallmodus ist SICHTBAR: ohne Scroll-Timelines, unter 900px und bei
   reduzierter Bewegung stehen die drei Stimmen einfach untereinander —
   ein vollständiges, lineares Dokument, keine leere Bühne.

   Die erste Stimme hat bewusst KEINE Ein-Animation: `both` würde sie vor
   Beginn ihres Bereichs auf den 0%-Zustand setzen, und die Bühne käme leer
   ins Bild. Sie steht, und bekommt nur den Abgang. Die letzte bekommt nur
   den Auftritt und bleibt stehen, bis die Bühne entklebt.
   -------------------------------------------------------------------------- */

.v2-buehne__stage {
	display: grid;
	gap: clamp(2.5rem, 5vw, 4rem);
	max-width: var(--v2-max);
	margin-inline: auto;
	padding: clamp(2rem, 4vw, 4rem) var(--v2-pad);
}

.v2-buehne__voice { margin: 0; }

.v2-buehne__voice blockquote {
	margin: 0;
	font-family: var(--font-text);
	font-weight: 500;
	font-size: clamp(1.375rem, 2.4vw, 2.375rem);
	line-height: 1.4;
	color: var(--text-primary);
	max-width: 30ch;
	text-wrap: pretty;
}

.v2-buehne__voice blockquote p { margin: 0; }

.v2-buehne__voice figcaption {
	margin-top: 1.25rem;
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	letter-spacing: var(--ls-overline);
	text-transform: uppercase;
	color: var(--au-mid);
}

.v2-buehne__takt { display: none; }

@supports (animation-timeline: view()) {
	@media (min-width: 900px) {
		html:not([data-motion="reduced"]) .v2-buehne {
			height: 320svh;
			view-timeline-name: --v2buehne;
		}

		html:not([data-motion="reduced"]) .v2-buehne__stage {
			position: sticky;
			top: 0;
			height: 100svh;
			overflow: clip;
			align-content: center;
			gap: 0;
		}

		html:not([data-motion="reduced"]) .v2-buehne__voice {
			grid-area: 1 / 1;
			align-self: center;
		}

		html:not([data-motion="reduced"]) .v2-buehne__voice:nth-child(1) {
			animation: v2-b-aus linear both;
			animation-timeline: --v2buehne;
			animation-range: contain 27% contain 33%;
		}

		html:not([data-motion="reduced"]) .v2-buehne__voice:nth-child(2) {
			animation: v2-b-einaus linear both;
			animation-timeline: --v2buehne;
			animation-range: contain 33% contain 66%;
		}

		html:not([data-motion="reduced"]) .v2-buehne__voice:nth-child(3) {
			animation: v2-b-ein linear both;
			animation-timeline: --v2buehne;
			animation-range: contain 66% contain 73%;
		}

		html:not([data-motion="reduced"]) .v2-buehne__takt {
			display: block;
			position: absolute;
			left: var(--v2-pad);
			right: var(--v2-pad);
			bottom: clamp(1.5rem, 3vw, 2.5rem);
			height: 2px;
			background: rgb(212 175 55 / 0.16);
		}

		html:not([data-motion="reduced"]) .v2-buehne__takt i {
			display: block;
			height: 100%;
			background: var(--au-mid);
			transform-origin: 0 50%;
			scale: 0 1;
			animation: v2-fill linear both;
			animation-timeline: --v2buehne;
			animation-range: contain 0% contain 100%;
		}
	}
}

@keyframes v2-b-aus {
	0%   { opacity: 1; translate: 0 0; }
	100% { opacity: 0; translate: 0 -1.25rem; }
}

@keyframes v2-b-ein {
	0%   { opacity: 0; translate: 0 1.75rem; }
	100% { opacity: 1; translate: 0 0; }
}

@keyframes v2-b-einaus {
	0%   { opacity: 0; translate: 0 1.75rem; }
	18%, 82% { opacity: 1; translate: 0 0; }
	100% { opacity: 0; translate: 0 -1.25rem; }
}

@media (prefers-reduced-motion: reduce) {
	html:not([data-motion="full"]) .v2-buehne { height: auto; view-timeline-name: none; }
	html:not([data-motion="full"]) .v2-buehne__stage { position: static; height: auto; overflow: visible; align-content: start; gap: clamp(2.5rem, 5vw, 4rem); }
	html:not([data-motion="full"]) .v2-buehne__voice { animation: none !important; opacity: 1; translate: none; grid-area: auto; }
	html:not([data-motion="full"]) .v2-buehne__takt { display: none; }
}

.v2-quote cite {
	font-family: var(--font-mono);
	font-style: normal;
	font-size: 0.6875rem;
	letter-spacing: var(--ls-overline);
	text-transform: uppercase;
	color: var(--au-mid);
}

/* ==========================================================================
   9 · Logos, schräg
   Die Schräglage ist der einzige Bruch der 4px-Geometrie auf der Seite und
   deshalb genau einmal erlaubt.
   ========================================================================== */

.v2-logos {
	padding: clamp(4rem, 9vw, 8rem) 0;
	overflow: clip;
}

.v2-logos__bands {
	display: grid;
	gap: clamp(0.75rem, 1.5vw, 1.25rem);
	rotate: -2.5deg;
	scale: 1.06;
	mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

/* Eigener Hintergrund und `isolation` sind hier keine Kosmetik, sondern die
   Voraussetzung für den Trick weiter unten: `mix-blend-mode` mischt nur
   innerhalb der nächsten isolierten Gruppe, und die muss den Grundton
   tatsächlich gemalt haben. Ohne beides mischt sich das Logo gegen
   Transparenz — also gegen nichts. */
.v2-band {
	overflow: clip;
	background: var(--ink-1000);
	isolation: isolate;
}

.v2-band__track {
	display: flex;
	align-items: center;
	gap: clamp(2rem, 4vw, 3.5rem);
	width: max-content;
	padding-block: 0.5rem;
	animation: v2-slide-l 68s linear infinite;
}

.v2-band--1 .v2-band__track { animation-name: v2-slide-r; animation-duration: 80s; }

.v2-band__item { display: block; flex: 0 0 auto; }

.v2-band__item img {
	display: block;
	height: clamp(46px, 4.6vw, 62px);
	width: auto;
	object-fit: contain;
	filter: grayscale(1) brightness(1.9) contrast(0.85);
	opacity: 0.62;
	transition: opacity var(--dur-base) var(--ease-out), filter var(--dur-base) var(--ease-out);
}

.v2-band__item img:hover {
	opacity: 1;
	filter: grayscale(0) brightness(1) contrast(1);
}

/* --------------------------------------------------------------------------
   Die 21 Logos mit weißem Kasten.
   Gemessen: 47 der 68 Logos sind freigestellt, 21 sind JPEGs mit deckend
   weißem Hintergrund und standen auf dem dunklen Grund als helle Rechtecke da.

   `invert(1)` dreht den weißen Hintergrund nach Schwarz und die dunkle
   Zeichnung nach Hell. `mix-blend-mode: screen` lässt Schwarz dann vollständig
   im Untergrund verschwinden — screen(Grund, Schwarz) ist exakt der Grund —
   während die helle Zeichnung stehen bleibt. Ergebnis: derselbe freigestellte
   Eindruck wie bei den anderen 47, ohne eine einzige Datei anzufassen.

   Kein Farb-Hover für diese Gruppe: dafür müsste die Invertierung zurück, und
   damit käme der weiße Kasten wieder. Sie werden nur heller.
   -------------------------------------------------------------------------- */
.v2-band__item--box img {
	filter: invert(1) grayscale(1) contrast(1.08);
	mix-blend-mode: screen;
	opacity: 0.72;
}

.v2-band__item--box img:hover {
	filter: invert(1) grayscale(1) contrast(1.08);
	opacity: 1;
}

/* Im Kontrastmodus verwirft der Browser Filter und Blend-Modi. Dann wäre die
   Invertierung weg, der weiße Kasten aber da — also lieber unbehandelt. */
@media (forced-colors: active) {
	.v2-band__item img,
	.v2-band__item--box img {
		filter: none;
		mix-blend-mode: normal;
		opacity: 1;
	}
}

/* ==========================================================================
   10 · Editorial — hier geht das Licht an
   Der Kreis wächst mit dem Scrollen. Ohne Scroll-Timelines steht die Sektion
   sofort komplett hell da, ohne Clip.
   ========================================================================== */

.v2-paper {
	background: var(--paper);
	color: var(--ink-1000);
	padding: clamp(5rem, 12vw, 11rem) var(--v2-pad);
}

.v2-paper__inner {
	max-width: 1180px;
	margin-inline: auto;
	display: grid;
	gap: clamp(1.5rem, 3vw, 2.5rem);
	justify-items: start;
}

.v2-paper .lx-label { color: var(--gold-700); }
.v2-paper .v2-h2 { color: var(--ink-1000); }

.v2-paper__cols {
	display: grid;
	gap: 1.25rem;
	font-family: var(--font-text);
	font-size: clamp(1rem, 1.25vw, 1.125rem);
	line-height: 1.72;
	color: var(--ink-700);
	max-width: 68ch;
}

@media (min-width: 1000px) {
	.v2-paper__cols {
		grid-template-columns: 1fr 1fr;
		column-gap: clamp(2rem, 4vw, 4rem);
		max-width: none;
	}
}

.v2-paper__cols a {
	color: var(--ink-1000);
	text-decoration: underline;
	text-decoration-color: var(--gold-500);
	text-underline-offset: 3px;
	text-decoration-thickness: 2px;
}

.v2-paper__cols a:hover { text-decoration-color: var(--ink-1000); }

/* GEMESSEN am 05.08.2026: seiten.css loest Widget-Huellen in __inner per
   `display: contents` auf (0-2-0, laedt SPAETER als diese Datei) — damit hatte
   die __cols-Huelle nie eine Box, ihr Grid war toter Code, und nur die
   vererbbare Typografie kam an den Absaetzen an. Die Absaetze liefen deshalb
   ueberall einspaltig ueber die volle Innenbreite. Die dritte Klasse holt die
   Box zurueck: 0-3-0 gewinnt unabhaengig von der Ladereihenfolge, und das
   `stretch` verhindert, dass `justify-items: start` des Elternteils die
   wiederhergestellte Box auf Inhaltsbreite schrumpft. */
.v2-paper__inner > .elementor-element.v2-paper__cols {
	display: grid;
	justify-self: stretch;
}

@supports (animation-timeline: view()) {
	.v2-paper {
		animation: v2-wipe linear both;
		animation-timeline: view();
		animation-range: entry 0% entry 85%;
	}
}

/* Der Kreis wächst aus der OBERKANTE, nicht aus der Unterkante. Von unten wäre
   der Ursprung beim Eintritt weit unterhalb der Falz — man sähe eine Jalousie
   statt eines Lichtkegels. Oben ist genau die Kante, an der die Sektion ins
   Bild kommt. */
@keyframes v2-wipe {
	from { clip-path: circle(0% at 50% 0%); }
	to   { clip-path: circle(150% at 50% 0%); }
}

/* ==========================================================================
   11 · FAQ
   `<details name>` schließt die Geschwister automatisch — ein Akkordeon ohne
   eine Zeile Javascript.
   ========================================================================== */

.v2-faq {
	padding: var(--v2-y) var(--v2-pad);
	max-width: 1180px;
	margin-inline: auto;
	display: grid;
	gap: clamp(2rem, 5vw, 4rem);
}

.v2-faq__head { display: grid; gap: 1rem; }

.v2-faq__item { border-top: var(--hairline-ink); }
.v2-faq__item:last-child { border-bottom: var(--hairline-ink); }

.v2-faq__item summary {
	display: grid;
	grid-template-columns: 3.5rem 1fr 2rem;
	align-items: center;
	gap: 1rem;
	padding: clamp(1.25rem, 2.5vw, 1.85rem) 0;
	cursor: pointer;
	list-style: none;
}

.v2-faq__item summary::-webkit-details-marker { display: none; }

.v2-faq__n {
	font-family: var(--font-mono);
	font-size: 0.75rem;
	color: var(--au-mid);
}

.v2-faq__q {
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: clamp(1.125rem, 2.6vw, 2rem);
	line-height: 1.1;
	color: var(--text-primary);
	transition: color var(--dur-fast) var(--ease-out);
}

.v2-faq__item summary:hover .v2-faq__q { color: var(--au-light); }

.v2-faq__ic {
	position: relative;
	width: 1.25rem;
	height: 1.25rem;
	justify-self: end;
}

.v2-faq__ic::before,
.v2-faq__ic::after {
	content: "";
	position: absolute;
	inset: 50% 0 auto 0;
	height: 1px;
	background: var(--au-mid);
}

.v2-faq__ic::after {
	rotate: 90deg;
	transition: rotate var(--dur-base) var(--ease-out);
}

.v2-faq__item[open] .v2-faq__ic::after { rotate: 0deg; }

/* --------------------------------------------------------------------------
   Das Aufklappen animieren.

   NICHT über `::details-content`. Gemessen: `CSS.supports('selector(::details-content)')`
   meldet in diesem Browser `true`, und `block-size: 0` darauf wirkt auch —
   aber die Rücknahme über `[open]` greift nicht, selbst mit `!important`.
   Ergebnis war eine FAQ, die sich überhaupt nicht mehr öffnen ließ.
   Gegenprobe, die es entschieden hat: ein blankes `<details>` ohne meine
   Klassen öffnete (26 → 146 px), dasselbe Markup mit meiner Klasse nicht
   (96 → 96 px).

   Stattdessen der Weg über `grid-template-rows: 0fr → 1fr`. Das ist eine
   gewöhnliche, überall unterstützte Interpolation zwischen zwei Zahlen — und
   sie kann den Inhalt nicht verschwinden lassen, weil `1fr` nichts anderes
   heißt als „so hoch wie der Inhalt".

   `min-height: 0` ist Pflicht: Grid-Elemente haben eine automatische
   Mindestgröße in Höhe ihres Inhalts, und die würde 0fr wirkungslos machen.
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Auf- und Zuklappen der Antwort.

   Die Höhe wird in v2.js GEMESSEN und als Pixelwert gesetzt, nicht per
   Schlüsselwort animiert. Der elegantere Weg über `max-height: max-content`
   plus `interpolate-size: allow-keywords` ist hier gescheitert: bleibt der
   Übergang stehen — kein Neuzeichnen, Hintergrund-Tab —, friert der Browser
   den Zwischenwert ein. Gemessen stand dort dauerhaft
   `calc-size(max-content, 0px + (0 * size))`, also 0 px, und die Antwort war
   unsichtbar, obwohl `open` gesetzt war.

   Deshalb hier KEIN eingeklappter Grundzustand. Ohne Javascript und bei
   zurückgenommener Bewegung ist die geöffnete Antwort einfach da. Alles
   andere setzt das Skript als Inline-Wert und räumt es hinterher wieder weg.
   -------------------------------------------------------------------------- */
.v2-faq__wrap {
	overflow: hidden;
	transition: max-height 420ms var(--ease-emphasis);
}

.v2-faq__a {
	padding: 0 0 clamp(1.5rem, 3vw, 2.25rem) 3.5rem;
	max-width: 68ch;
	font-family: var(--font-text);
	font-size: 1rem;
	line-height: var(--lh-body);
	color: var(--text-secondary);
	display: grid;
	gap: 1rem;
}

.v2-faq__a p { margin: 0; }

/* ==========================================================================
   12 · Kontakt
   ========================================================================== */

.v2-contact {
	padding: var(--v2-y) var(--v2-pad) clamp(4rem, 8vw, 7rem);
	max-width: var(--v2-max);
	margin-inline: auto;
	display: grid;
	gap: clamp(2.5rem, 6vw, 5rem);
	scroll-margin-top: calc(var(--lx-header-h, 105px) + 1rem);
}

.v2-contact__head { display: grid; gap: 1rem; }

/* --------------------------------------------------------------------------
   Adresse, Karte und Formular als EIN Objekt

   Vorher waren es drei Blöcke untereinander: Adresse links, Formular rechts,
   Karte als eigenes Band über die volle Breite darunter. Die Karte hatte damit
   zu nichts eine Beziehung — dabei erklärt sie genau eine Sache, nämlich die
   Anschrift. Sie gehört deshalb IN die Adressspalte, nicht unter die Sektion.

   Zusammengehalten wird das Ganze von einem Hairline-Rahmen mit einer
   senkrechten Linie in der Mitte. Kein Kasten im Kasten: das Formular bringt
   deshalb keinen eigenen Rahmen mehr mit.
   -------------------------------------------------------------------------- */
.v2-contact__grid {
	display: grid;
	gap: 0;
	border: var(--hairline-gold);
	background:
		radial-gradient(70% 90% at 0% 0%, rgb(212 175 55 / 0.05), transparent 62%),
		rgb(18 16 14 / 0.5);
}

@media (min-width: 980px) {
	/* Links steht jetzt auch die Karte, die Spalte braucht also mehr Breite als
	   die früheren 0,62. Das Formular behält genug für zwei Feldspalten. */
	.v2-contact__grid { grid-template-columns: minmax(20rem, 0.85fr) 1.15fr; }

	/* Die senkrechte Haarlinie IST die Trennung — kein Abstand, keine zweite
	   Kante. Sie sitzt am Rand der linken Spalte, nicht als eigenes Element. */
	.v2-contact__meta { border-right: var(--hairline-gold); }
}

@media (max-width: 979px) {
	.v2-contact__meta { border-bottom: var(--hairline-gold); }
}

/* Die Beschriftung gehoert ueber die Angabe, nicht davor. Ohne `display: block`
   liest sich das als „ADRESSEleXpro Media GmbH". */
.v2-contact__meta .lx-label {
	display: block;
	margin-bottom: 0.35rem;
}

.v2-contact__meta {
	display: grid;
	gap: 1.5rem;
	align-content: start;
	padding: clamp(1.5rem, 3.5vw, 2.75rem);
	font-family: var(--font-text);
	font-size: 1.0625rem;
	line-height: var(--lh-snug);
	color: var(--text-secondary);
}

.v2-contact__meta a { color: var(--au-light); }

/* --------------------------------------------------------------------------
   Eingebettetes Elementor-Formular.

   ACHTUNG Ladereihenfolge: `widget-form.min.css` wird erst eingebunden, wenn
   das Widget rendert — also NACH `wp_enqueue_scripts` und damit nach v2.css.
   Gemessen: der Senden-Button war deshalb Elementor-Grau (#69727D), obwohl
   die Marken-Regel `.lx-btn-primary .elementor-button` korrekt geschrieben
   war und in der Datei stand. Gegen später geladenes CSS hilft keine
   Reihenfolge, nur Spezifität — daher die dreiteiligen Selektoren unten.
   -------------------------------------------------------------------------- */

.v2-contact__form {
	padding: clamp(1.5rem, 3.5vw, 2.75rem);
	/* Kein eigener Rahmen und kein eigener Grund mehr — beides kommt vom
	   umgebenden Panel. Sonst stünde hier ein Kasten im Kasten. */
}

/* Elementor legt die Felder als Flex-Zeile mit `col-100` aus, also eine
   Spalte. Zweispaltig gesetzt liest sich das Formular kürzer, als es ist —
   und ein kurz wirkendes Formular wird häufiger ausgefüllt. */
.v2-contact__form .elementor-form-fields-wrapper {
	display: grid;
	grid-template-columns: 1fr;
	gap: clamp(1.25rem, 2.5vw, 1.75rem);
}

@media (min-width: 620px) {
	.v2-contact__form .elementor-form-fields-wrapper {
		grid-template-columns: 1fr 1fr;
	}

	.v2-contact__form .elementor-field-group-message,
	.v2-contact__form .elementor-field-group-consent,
	.v2-contact__form .e-form__buttons {
		grid-column: 1 / -1;
	}
}

.v2-contact__form .elementor-field-group {
	width: auto;
	max-width: none;
	padding: 0;
	display: grid;
	align-content: start;
	gap: 0.35rem;
}

.v2-contact__form .elementor-field-group > label {
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	letter-spacing: var(--ls-overline);
	text-transform: uppercase;
	color: var(--text-muted);
	transition: color var(--dur-fast) var(--ease-out);
}

.v2-contact__form .elementor-field-group:focus-within > label { color: var(--au-mid); }

/* Felder ohne Kasten, nur eine Linie darunter. Kästen wären auf dieser Seite
   das einzige weiche Element — die gesamte Geometrie ist 4px oder gar nichts. */
.v2-contact__form .elementor-field-textual {
	width: 100%;
	font-family: var(--font-text);
	font-size: 1.125rem;
	line-height: 1.4;
	color: var(--text-primary);
	/* `!important` ist hier gemessen, nicht geraten — dasselbe Verhalten wie beim
	   Absende-Button: Rahmen und Schriftfarbe aus dieser Regel kommen an, der
	   HINTERGRUND nicht. Gegenprobe im Browser: eine Regel gleicher Spezifitaet
	   verliert, eine hoehere ebenfalls, nur `!important` gewinnt. Ohne diese
	   Zeile stehen weisse Kaesten auf dunklem Grund. */
	background-color: transparent !important;
	background-image: none !important;
	border: 0;
	border-bottom: 1px solid var(--ink-600);
	border-radius: 0;
	padding: 0.7rem 0;
	box-shadow: none;
	transition: border-color var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}

.v2-contact__form .elementor-field-textual::placeholder { color: var(--ink-500); }

/* Zweite Linie per box-shadow statt dickerem Rahmen: ein wachsender Rahmen
   verschiebt das Feld um einen Pixel, und dieses Zucken sieht man. */
.v2-contact__form .elementor-field-textual:focus {
	outline: none;
	border-bottom-color: var(--au-mid);
	box-shadow: 0 1px 0 0 var(--au-mid);
}

.v2-contact__form .elementor-field-textual:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 4px;
}

.v2-contact__form textarea.elementor-field-textual {
	min-height: 7.5rem;
	resize: vertical;
}

/* Zustimmung: eigenes Kästchen, weil das native auf dunklem Grund als weißer
   Fleck sitzt und sich nicht einfärben lässt. */
.v2-contact__form .elementor-field-type-acceptance {
	grid-template-columns: auto 1fr;
	align-items: start;
	gap: 0.75rem;
	font-family: var(--font-text);
	font-size: 0.875rem;
	line-height: var(--lh-snug);
	color: var(--text-muted);
	padding-top: 0.5rem;
}

.v2-contact__form .elementor-field-type-acceptance input[type="checkbox"] {
	appearance: none;
	width: 1.15rem;
	height: 1.15rem;
	margin: 0.1rem 0 0;
	flex: 0 0 auto;
	border: 1px solid var(--ink-500);
	/* Dritter Fall derselben Sache: Rahmen kommt an, Hintergrund nicht.
	   Ohne `!important` steht hier ein weisses Kaestchen auf dunklem Grund. */
	background-color: transparent !important;
	background-image: none !important;
	display: grid;
	place-content: center;
	cursor: pointer;
	transition: border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}

.v2-contact__form .elementor-field-type-acceptance input[type="checkbox"]::before {
	content: "";
	width: 0.55rem;
	height: 0.3rem;
	border-left: 2px solid var(--ink-1000);
	border-bottom: 2px solid var(--ink-1000);
	rotate: -45deg;
	translate: 0 -0.06rem;
	scale: 0;
	transition: scale var(--dur-fast) var(--ease-out);
}

.v2-contact__form .elementor-field-type-acceptance input[type="checkbox"]:checked {
	background-color: var(--au-mid) !important;
	border-color: var(--au-mid);
}

.v2-contact__form .elementor-field-type-acceptance input[type="checkbox"]:checked::before { scale: 1; }

.v2-contact__form .elementor-field-type-acceptance input[type="checkbox"]:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 3px;
}

.v2-contact__form .elementor-field-type-acceptance label {
	font-family: inherit;
	font-size: inherit;
	letter-spacing: normal;
	text-transform: none;
	color: inherit;
}

.v2-contact__form .elementor-field-type-acceptance a {
	color: var(--au-light);
	text-underline-offset: 3px;
}

/* Der Button. Dreiteiliger Selektor gegen das später geladene Widget-CSS. */
.v2-contact__form .elementor-form .elementor-button,
.v2-contact__form .elementor-form button[type="submit"] {
	width: 100%;
	min-height: var(--control-h-lg);
	padding-inline: 2rem;
	font-family: var(--font-text);
	font-weight: 600;
	font-size: 1rem;
	letter-spacing: 0.02em;
	/* Das einzige `!important` in dieser Datei, und es ist gemessen, nicht geraten:
	   Elementor setzt die Schriftfarbe des Formular-Buttons selbst mit `!important`.
	   Gegenprobe im Browser — eine Regel mit gleicher Spezifität später im Dokument
	   verlor, eine mit HÖHERER Spezifität ebenfalls, nur `!important` gewann. Der
	   Hintergrund braucht es nicht, der Verlauf greift ohne. Ohne diese Zeile steht
	   weiße Schrift auf Gold. */
	color: var(--ink-1000) !important;
	background: var(--grad-gold-surface);
	border: 0;
	border-radius: var(--radius-sm);
	cursor: pointer;
	transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}

.v2-contact__form .elementor-form .elementor-button:hover,
.v2-contact__form .elementor-form button[type="submit"]:hover {
	transform: translateY(-1px);
	box-shadow: var(--glow-gold-md);
}

.v2-contact__form .elementor-form .elementor-button:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 3px;
}

@media (min-width: 620px) {
	.v2-contact__form .elementor-form .elementor-button,
	.v2-contact__form .elementor-form button[type="submit"] {
		width: auto;
		justify-self: start;
	}

	.v2-contact__form .e-form__buttons { justify-content: start; }
}

/* Meldungen nach dem Absenden — ohne diese Regel erbt der Erfolgstext
   Elementors Grün auf dunklem Grund und ist kaum zu lesen. */
.v2-contact__form .elementor-message {
	font-family: var(--font-text);
	font-size: 0.9375rem;
	margin-top: 0.5rem;
}

.v2-contact__form .elementor-message-success { color: var(--success); }
.v2-contact__form .elementor-message-danger { color: var(--danger); }

/* Rückversicherung unter dem Formular (Review P3): wer absendet, will wissen,
   was danach passiert. Gleiche Sprache wie die kleinen Mono-Labels. */
.lx-form-note {
	margin: 0.9rem 0 0;
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	letter-spacing: var(--ls-overline);
	text-transform: uppercase;
	color: var(--text-muted);
}

.v2-contact__fallback {
	font-family: var(--font-text);
	font-size: 1.125rem;
}

.v2-contact__fallback {
	font-family: var(--font-text);
	font-size: 1.125rem;
}

/* ==========================================================================
   13 · Pause-Steuerung für die laufenden Bänder (WCAG 2.2.2)
   Der Knopf steht als Geschwister NEBEN dem Band, nicht darin: die Bänder
   tragen `mask-image`, und alles innerhalb einer Maske wird von ihr
   angeschnitten — in V1 waren die Knöpfe deshalb halb unsichtbar.
   ========================================================================== */

.v2-pause {
	display: block;
	margin: 1.25rem var(--v2-pad) 0 auto;
	padding: 0.45rem 0.9rem;
	font-family: var(--font-mono);
	font-size: 0.625rem;
	letter-spacing: var(--ls-overline);
	text-transform: uppercase;
	color: var(--text-muted);
	background: transparent;
	border: var(--hairline-ink);
	cursor: pointer;
}

.v2-pause:hover { color: var(--text-primary); border-color: var(--au-mid); }

[data-v2-paused] .v2-kin__track,
[data-v2-paused] .v2-band__track {
	animation-play-state: paused;
}

/* ==========================================================================
   14 · Bewegung zurücknehmen
   Dreistufig: OS-Präferenz, eigener Schalter, und `data-motion="full"` als
   ausdrückliches Übersteuern. Reduzieren heißt reduzieren, nicht entfernen —
   die Seite bleibt vollständig, nur ohne Dauerbewegung.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
	html:not([data-motion="full"]) .v2-kin__track,
	html:not([data-motion="full"]) .v2-band__track,
	html:not([data-motion="full"]) .v2-ghost__row,
	html:not([data-motion="full"]) .v2-hero__scroll {
		animation: none !important;
		translate: none !important;
	}

	html:not([data-motion="full"]) .v2-w { color: var(--text-primary); }

	/* Der Überschriften-Reveal arbeitet mit `clip-path` und Fill-Mode `both`:
	   vor seinem Bereich ist die Überschrift vollständig weggeschnitten. Bei
	   zurückgenommener Bewegung wird er ganz abgeschaltet, statt sich auf einen
	   funktionierenden Scroll-Bereich zu verlassen — eine unsichtbare
	   Überschrift ist der teuerste denkbare Ausfall. */
	html:not([data-motion="full"]) [data-v2-lines],
	html:not([data-motion="full"]) .v2-lines { animation: none !important; clip-path: none !important; }

	html:not([data-motion="full"]) .v2-paper { clip-path: none !important; animation: none !important; }

	html:not([data-motion="full"]) .v2-track__rail { height: auto; }
	html:not([data-motion="full"]) .v2-track__stage { position: static; height: auto; overflow: visible; }
	html:not([data-motion="full"]) .v2-track__inner { animation: none; translate: none; display: grid; width: auto; }
	html:not([data-motion="full"]) .v2-panel { width: auto; }
	html:not([data-motion="full"]) .v2-panel--service { animation: none !important; --lit: 1; }

	/* Ohne Übergang aufklappen, aber nicht ohne Inhalt: `block-size` bleibt auto. */
	html:not([data-motion="full"]) .v2-faq__wrap { transition: none; }
}

html[data-motion="reduced"] .v2-kin__track,
html[data-motion="reduced"] .v2-band__track,
html[data-motion="reduced"] .v2-ghost__row,
html[data-motion="reduced"] .v2-hero__scroll {
	animation: none !important;
	translate: none !important;
}

html[data-motion="reduced"] .v2-w { color: var(--text-primary); }
html[data-motion="reduced"] [data-v2-lines],
html[data-motion="reduced"] .v2-lines { animation: none !important; clip-path: none !important; }
html[data-motion="reduced"] .v2-paper { clip-path: none !important; animation: none !important; }
html[data-motion="reduced"] .v2-track__rail { height: auto; }
html[data-motion="reduced"] .v2-track__stage { position: static; height: auto; overflow: visible; }
html[data-motion="reduced"] .v2-track__inner { animation: none; translate: none; display: grid; width: auto; }
html[data-motion="reduced"] .v2-panel { width: auto; }
html[data-motion="reduced"] .v2-panel--service { animation: none !important; --lit: 1; }
html[data-motion="reduced"] .v2-faq__wrap { transition: none; }

/* ==========================================================================
   15 · Karte — Klick zum Laden
   Bis zum Klick geht kein einziger Request an Google. Der Platzhalter ist
   deshalb kein Bild, sondern gezeichnet: ein Raster aus zwei wiederholten
   Verläufen plus ein Goldpunkt für den Standort. Das kostet null Bytes und
   verrät niemanden.
   ========================================================================== */

.v2-map {
	margin: 0;
	position: relative;
	/* In der Adressspalte statt über die volle Breite: aus 21/9 wird ein
	   Format, das in eine Spalte passt, ohne zum Streifen zu werden. */
	aspect-ratio: 5 / 4;
	min-height: 15rem;
	overflow: clip;
	border: var(--hairline-ink);
	background:
		radial-gradient(60% 70% at 50% 50%, rgb(212 175 55 / 0.07), transparent 65%),
		repeating-linear-gradient(0deg, rgb(147 144 137 / 0.055) 0 1px, transparent 1px 64px),
		repeating-linear-gradient(90deg, rgb(147 144 137 / 0.055) 0 1px, transparent 1px 64px),
		var(--ink-950);
}

@media (max-width: 719px) {
	.v2-map { aspect-ratio: 4 / 3; min-height: 13rem; }
}

.v2-map__ph {
	position: absolute;
	inset: 0;
	display: grid;
	align-content: center;
	justify-items: center;
	gap: 0.85rem;
	padding: clamp(1.5rem, 4vw, 3rem);
	text-align: center;
}

/* Der Standortpunkt. Reine Dekoration, deshalb ein Pseudo-Element. */
.v2-map__ph::before {
	content: "";
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: var(--au-mid);
	box-shadow: 0 0 0 6px rgb(212 175 55 / 0.14), 0 0 0 14px rgb(212 175 55 / 0.07);
	margin-bottom: 0.5rem;
}

.v2-map__adr {
	font-family: var(--font-display);
	font-weight: var(--fw-extrabold);
	font-size: clamp(1.25rem, 2.6vw, 2rem);
	line-height: 1.1;
	color: var(--text-primary);
}

.v2-map__note {
	font-family: var(--font-text);
	font-size: 0.8125rem;
	line-height: var(--lh-snug);
	color: var(--text-muted);
	max-width: 42ch;
}

.v2-map__note a { color: var(--au-light); text-underline-offset: 3px; }

.v2-map__ext {
	font-family: var(--font-mono);
	font-size: 0.6875rem;
	letter-spacing: var(--ls-overline);
	text-transform: uppercase;
	color: var(--text-muted);
}

.v2-map__ext::after { content: " 97"; }
.v2-map__ext:hover { color: var(--au-light); }

/* Nach dem Laden füllt der Frame die Fläche. `border: 0` ist nötig, weil
   Browser iframes standardmäßig einen Rahmen geben. */
.v2-map iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	filter: grayscale(1) invert(0.92) contrast(0.86) hue-rotate(180deg);
}
