/* ============================================================================
   WAGNER DIGITAL - gemeinsames Stylesheet aller 11 Seiten
   Quelle: landing/css/wd-base.css  ->  /wp-content/uploads/css/wd-base.css

   Warum extern: der Block lag bisher als render-blockierendes Inline-CSS in JEDER
   Seite - 36,7 KB auf der Startseite, ~54,7 KB auf den Unterseiten, byteidentisch
   und damit nicht cachebar. Als eine Datei wird er einmal geladen und gilt fuer
   alle elf Seiten und alle Folgebesuche. Das Inline-CSS in den Seiten ist nur noch
   der kritische Teil (Kopf, Hero, Tokens) aus css/wd-critical.css.
   ============================================================================ */

/* ---- 1) Basis (Quelle: wp-page-content.html) ---- */

/* self-hosted Fonts (DSGVO: 0 externe Calls) — /wp-content/uploads/fonts/ */
@font-face{font-family:'Montserrat';font-style:normal;font-weight:700;font-display:swap;src:url('https://digital.hans-wagner.de/wp-content/uploads/fonts/montserrat-700.woff2') format('woff2')}
@font-face{font-family:'Montserrat';font-style:normal;font-weight:800;font-display:swap;src:url('https://digital.hans-wagner.de/wp-content/uploads/fonts/montserrat-800.woff2') format('woff2')}
@font-face{font-family:'Source Sans 3';font-style:normal;font-weight:400;font-display:swap;src:url('https://digital.hans-wagner.de/wp-content/uploads/fonts/source-sans-3-400.woff2') format('woff2')}
@font-face{font-family:'Source Sans 3';font-style:normal;font-weight:600;font-display:swap;src:url('https://digital.hans-wagner.de/wp-content/uploads/fonts/source-sans-3-600.woff2') format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url('https://digital.hans-wagner.de/wp-content/uploads/fonts/jetbrains-mono-400.woff2') format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;src:url('https://digital.hans-wagner.de/wp-content/uploads/fonts/jetbrains-mono-500.woff2') format('woff2')}
:root{
  --wd-night:#0B0B0C; --wd-anthracite:#16181B; --wd-surface-1:#1C1F22; --wd-surface-2:#232629;
  --wd-hairline:rgba(245,245,243,.08); --wd-signal:#19E68A; --wd-signal-deep:#0FB870; --wd-fresh:#049B4E;
  --wd-warmwhite:#F5F5F3; --wd-grey:#8B9197;
  --wd-display:'Montserrat','Segoe UI',sans-serif; --wd-body:'Source Sans 3',sans-serif;
  --wd-mono:'JetBrains Mono','Courier New',monospace; --wd-radius:10px; --wd-radius-sm:6px; --wd-maxw:1180px;
  --wd-gutter:32px;
  /* EINE Quelle fuer die Kopfhoehe. Vorher stand 68px an drei Stellen und 80px an einer vierten
     (scroll-padding) — der mobile Header brach zweizeilig aus einem 68px-Band heraus, weil
     niemand die Hoehe mit der Wortmarke zusammen gedacht hat. */
  --wd-header-h:68px;
}
/* kill theme chrome / light bg */
html,body{background:var(--wd-night)!important;}
html{scroll-behavior:smooth;scroll-padding-top:calc(var(--wd-header-h) + 12px)}
/* Ehrlicher Guard statt `@media not all{}`: die Regel greift wirklich, wird aber von der
   Inhaber-Entscheidung (.wd-motion-forced, gesetzt aus WD_FORCE_MOTION) uebersteuert.
   WD_FORCE_MOTION=false stellt damit in EINEM Schritt CSS und JS auf WCAG 2.3.3 zurueck. */
@media (prefers-reduced-motion: reduce){html:not(.wd-motion-forced){scroll-behavior:auto}}
body{margin:0;}
.wd-canvas,.wp-block-post-content{margin:0!important;max-width:none!important;}
#wd-root *{box-sizing:border-box;}
/* clip, nie hidden — Begruendung ausfuehrlich in css/wd-critical.css. */
#wd-root{background:var(--wd-night);color:var(--wd-warmwhite);font-family:var(--wd-body);font-size:17px;line-height:1.6;-webkit-font-smoothing:antialiased;position:relative;overflow-x:clip;}
#wd-root > *:not(.wd-cine){overflow-x:clip}
#wd-root::after{content:"";position:fixed;inset:0;pointer-events:none;z-index:200;opacity:.05;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");}
#wd-root a{color:inherit;text-decoration:none}
.wd-wrap{max-width:var(--wd-maxw);margin:0 auto;padding:0 var(--wd-gutter)}
.wd-eyebrow{font-family:var(--wd-mono);font-weight:500;font-size:13px;letter-spacing:.18em;text-transform:uppercase;color:var(--wd-signal)}
.wd-title{font-family:var(--wd-display);font-weight:800;letter-spacing:-.025em;line-height:1.02;font-size:clamp(1.9rem,4vw,3rem);margin:14px 0 0}
.wd-lead{color:rgba(245,245,243,.72);font-size:1.2rem;max-width:620px;margin-top:16px}
@keyframes wd-blink{0%,45%{opacity:1}50%,95%{opacity:0}100%{opacity:1}}
/* WCAG 2.2.2 „Pause, Stop, Hide" (Level A) gilt unabhaengig von prefers-reduced-motion:
   automatisch startende Bewegung darf nicht laenger als 5s ohne Stopp-Mechanismus laufen.
   Der Caret blinkt jetzt 4x (das „Terminal wacht auf") und bleibt dann stehen; auf Hover
   ueber dem Kopf blinkt er weiter — nutzerinitiiert und damit erlaubt. */
.wd-blink{animation:wd-blink 1s steps(1,end) 4}
#wd-header:hover .wd-blink,#wd-header:focus-within .wd-blink{animation:wd-blink 1s steps(1,end) infinite}
.wd-c{color:var(--wd-signal)}
/* HEADER */
/* Historie: .72 war zu duenn (durchscrollender Text lag sichtbar auf der Wortmarke, gemessen
   bei 390px), also .92 — und ein @supports-Rueckfall auf Vollton fuer Browser ohne
   backdrop-filter. Seit 02.08.2026 ist der Vollton der Normalfall, s. Begruendung und
   Messwerte im gleichlautenden Block in css/wd-critical.css. Kurz: die verbliebenen 8 %
   waren der Ghosting-Befund (+7 Stufen bei weisser H2, +17 ueber der hellen Sektion), und
   die Gegenprobe zeigt, dass die Durchlaessigkeit nichts einbringt, was nicht derselbe
   Fehler waere. Beide Dateien muessen hier IDENTISCH sein — die kritische steht inline,
   diese kommt per <link> nach; wichen sie voneinander ab, kippte der Kopf beim Laden. */
#wd-header{position:sticky;top:0;z-index:100;background:var(--wd-night);border-bottom:1px solid var(--wd-hairline)}
.wd-nav{display:flex;align-items:center;justify-content:space-between;height:var(--wd-header-h);gap:12px}
/* nowrap + flex:0 0 auto: die Wortmarke ist der Fixpunkt des Kopfes, sie schrumpft nicht und
   bricht nicht. Was nicht passt, weicht rechts (CTA-Text, s. Breakpoints). */
.wd-brand{font-family:var(--wd-display);font-weight:800;font-size:22px;letter-spacing:-.02em;white-space:nowrap;flex:0 0 auto}
.wd-menu{display:flex;gap:30px;font-family:var(--wd-mono);font-size:13px;letter-spacing:.04em;color:var(--wd-grey);text-transform:uppercase}
.wd-menu a:hover{color:var(--wd-warmwhite)}
.wd-btn{font-family:var(--wd-display);font-weight:800;font-size:14px;letter-spacing:.02em;text-transform:uppercase;border-radius:var(--wd-radius);padding:11px 20px;display:inline-flex;align-items:center;gap:8px;transition:.18s;cursor:pointer;border:1px solid transparent}
.wd-btn-primary{background:var(--wd-signal);color:var(--wd-night)}
.wd-btn-primary:hover{background:#28f29a;transform:translateY(-1px)}
.wd-btn-ghost{background:transparent;color:var(--wd-warmwhite);border-color:var(--wd-hairline)}
.wd-btn-ghost:hover{border-color:var(--wd-signal);color:var(--wd-signal)}
.wd-btn-lg{padding:16px 30px;font-size:15px}
/* HERO */
/* HERO — Tier-2 „Werkstatt im Caret" (Konzept C). Layer 0 immer sichtbar; Layer 1 = Caret-Portal-Intro (hero-caret.js) */
.wd-hero{position:relative;min-height:100vh;display:flex;align-items:center;overflow:clip;border-bottom:1px solid var(--wd-hairline);background:var(--wd-night)}
.hero-room{position:absolute;inset:0;z-index:0}
.hero-room-media{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.5;filter:saturate(.95)}
.hero-room::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(11,11,12,.95) 28%,rgba(11,11,12,.58) 70%,rgba(11,11,12,.85)),linear-gradient(0deg,var(--wd-night),transparent 55%)}
.hero-portal{position:absolute;inset:0;z-index:3;display:none;align-items:center;justify-content:center;background:var(--wd-night);pointer-events:none}
.js-hero .hero-portal{display:flex}
.hero-wordmark{position:relative;font-family:var(--wd-display);font-weight:800;font-size:clamp(2rem,6.2vw,4.6rem);letter-spacing:-.03em;color:var(--wd-warmwhite);will-change:transform,opacity}
.hero-wordmark .hero-caret{color:var(--wd-signal);margin-left:.04em}
/* Glueh-Radius 01.08.2026 erhoeht — Begruendung s. wd-critical.css (beide Dateien muessen
   hier identisch bleiben, sonst springt der Spalt beim Wechsel inline -> extern). */
.hero-slit{position:absolute;top:50%;left:50%;width:3px;height:0;background:var(--wd-signal);border-radius:2px;transform:translate(-50%,-50%);box-shadow:0 0 26px 3px var(--wd-signal),0 0 96px 14px rgba(25,230,138,.55);opacity:0;will-change:height,width,opacity}
.hero-bloom{position:absolute;inset:0;background:radial-gradient(circle at center,rgba(25,230,138,.95),rgba(25,230,138,.42) 32%,transparent 68%);opacity:0;transform:scale(.2);will-change:opacity,transform}
.wd-hero-inner{position:relative;z-index:2;width:100%;padding:90px var(--wd-gutter)}
.wd-hero h1{font-family:var(--wd-display);font-weight:800;letter-spacing:-.035em;line-height:.94;font-size:clamp(3rem,6.8vw,6rem);margin:18px 0 0}
.wd-hero .wd-lead{font-size:1.35rem;max-width:600px}
.wd-hero-cta{display:flex;gap:14px;margin-top:34px;flex-wrap:wrap}
/* Hier stand `.js-hero.hero-intro-armed .hero-inner{opacity:0}` — der Selektor verlangte BEIDE
   Klassen auf EINEM Element, `js-hero` sitzt aber auf <html> und `hero-intro-armed` auf der
   <section>. Die Regel hat nie gegriffen (tote CSS), die Blindzeit kam aus dem GSAP-opacity:0
   und aus dem deckenden Portal. Der Hero-Inhalt bleibt jetzt bewusst sichtbar und wird nur
   ueberblendet — damit ist die H1 ab dem ersten Paint LCP-faehig.
   Der `@media not all{}`-Guard daneben war entkernt (feuert per Definition nie) und weckte
   den falschen Eindruck, es gaebe einen reduced-motion-Pfad. */
/* Skip-Knopf im Portal — vorher gab es keine Abbruchmoeglichkeit. */
.hero-skip{position:absolute;right:max(16px,var(--wd-gutter));bottom:24px;z-index:4;pointer-events:auto;background:transparent;border:1px solid var(--wd-hairline);border-radius:var(--wd-radius);color:var(--wd-grey);font-family:var(--wd-mono);font-size:12px;letter-spacing:.06em;text-transform:uppercase;padding:0 16px;min-height:44px;cursor:pointer;transition:color .18s,border-color .18s}
.hero-skip:hover,.hero-skip:focus-visible{color:var(--wd-signal);border-color:var(--wd-signal);outline:none}
html:not(.js-hero) .hero-skip{display:none}
.wd-trust{display:flex;gap:26px;margin-top:38px;font-family:var(--wd-mono);font-size:12px;letter-spacing:.06em;color:var(--wd-grey);text-transform:uppercase;flex-wrap:wrap}
.wd-trust span{display:flex;align-items:center;gap:8px}
.wd-section{padding:96px 0}
.wd-section-tight{padding:72px 0}
/* PAIN */
.wd-pain{background:var(--wd-anthracite);border-bottom:1px solid var(--wd-hairline)}
.wd-pain p{font-family:var(--wd-display);font-weight:700;letter-spacing:-.02em;line-height:1.25;font-size:clamp(1.5rem,3.2vw,2.4rem);max-width:880px;color:var(--wd-warmwhite)}
.wd-pain p .wd-de-emph{color:var(--wd-grey)}
/* GRID / CARDS */
.wd-grid{display:grid;gap:18px}
.wd-g3{grid-template-columns:repeat(3,1fr)}
.wd-g2{grid-template-columns:repeat(2,1fr)}
.wd-card{background:var(--wd-surface-1);border:1px solid var(--wd-hairline);border-radius:var(--wd-radius);padding:28px;transition:.18s}
.wd-card:hover{background:var(--wd-surface-2);transform:translateY(-2px)}
.wd-card .wd-k{font-family:var(--wd-mono);font-size:12px;color:var(--wd-signal);letter-spacing:.1em}
.wd-card h3{font-family:var(--wd-display);font-weight:800;font-size:1.4rem;letter-spacing:-.02em;margin:12px 0 8px}
.wd-card p{color:rgba(245,245,243,.68);font-size:1rem}
.wd-card-cta{display:flex;align-items:center;justify-content:space-between;gap:18px;background:var(--wd-anthracite)}
a.wd-card{cursor:pointer}
.wd-card .wd-go{display:inline-block;margin-top:14px;font-family:var(--wd-mono);font-size:12px;letter-spacing:.06em;color:var(--wd-signal)}
.wd-card:hover .wd-go{color:#28f29a}
/* ABLAUF */
.wd-ablauf{background:var(--wd-anthracite);border-top:1px solid var(--wd-hairline);border-bottom:1px solid var(--wd-hairline)}
.wd-steps{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;margin-top:40px}
/* min-width:0 ist an einem Fixed-Track-Grid (repeat(4,1fr)) Pflicht, nicht Kosmetik: ohne
   sie sprengt ein langes Kompositum die 1fr-Spur und zieht die Raender asymmetrisch.
   Gleiche Formulierung wie .wd-flist li / .wd-wer-fakt dd. */
.wd-step{position:relative;padding-top:26px;border-top:2px solid var(--wd-signal);min-width:0}
.wd-step .wd-n{font-family:var(--wd-mono);font-size:13px;color:var(--wd-signal);letter-spacing:.1em}
.wd-step h4{font-family:var(--wd-display);font-weight:800;font-size:1.25rem;letter-spacing:-.01em;margin:10px 0 8px}
.wd-step p{color:rgba(245,245,243,.66);font-size:.98rem;min-width:0;overflow-wrap:anywhere;hyphens:auto}
/* WARUM */
.wd-why{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;margin-top:40px}
.wd-why .wd-b{position:relative;padding:26px 24px 24px;border:1px solid var(--wd-hairline);border-radius:var(--wd-radius);background:var(--wd-surface-1)}
.wd-why .wd-b .wd-big{font-family:var(--wd-display);font-weight:800;font-size:clamp(1.6rem,4.3vw,1.72rem);letter-spacing:-.025em;line-height:1.05;white-space:nowrap}
.wd-why .wd-b p{color:rgba(245,245,243,.66);font-size:.96rem;margin-top:8px}
/* Zähler-Lauf: Mono-Index + drawing Hairline + Wort-Maske (Default = sichtbar, no-JS/reduced-motion-safe) */
.wd-count .wd-count-k{font-family:var(--wd-mono);font-size:13px;letter-spacing:.1em;color:var(--wd-signal);margin-bottom:12px}
.wd-count .wd-count-rule{position:absolute;top:0;left:24px;right:24px;height:2px;background:var(--wd-signal);transform-origin:left}
.wd-count .wd-mask{display:inline-block;overflow:hidden;vertical-align:bottom;padding-bottom:.08em}
.wd-count .wd-word{display:inline-block}
.wd-honesty{margin-top:34px;background:var(--wd-surface-1);border:1px solid var(--wd-hairline);border-left:2px solid var(--wd-signal);border-radius:var(--wd-radius);padding:26px 28px}
.wd-honesty .wd-q{font-family:var(--wd-display);font-weight:800;font-size:clamp(1.25rem,2.4vw,1.7rem);letter-spacing:-.02em;line-height:1.3}
.wd-honesty .wd-s{color:var(--wd-grey);font-family:var(--wd-mono);font-size:12px;letter-spacing:.08em;text-transform:uppercase;margin-top:12px}
/* PAKETE */
.wd-pakete{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:40px;align-items:stretch}
/* Zwei Pakete in drei Spuren lassen rechts ein volles, leeres Kartenfeld stehen — genau
   der „leere Streifen", der die Seite billig aussehen laesst (Landingpage, 30.07.2026).
   Spurenzahl kommt aus der Anzahl, wie schon bei .wd-g2/.wd-g3. */
.wd-pakete.wd-pak2{grid-template-columns:repeat(2,1fr)}
.wd-pak{background:var(--wd-surface-1);border:1px solid var(--wd-hairline);border-radius:var(--wd-radius);padding:30px;display:flex;flex-direction:column;min-width:0}
.wd-pak.wd-feat{border-color:var(--wd-signal);box-shadow:0 0 0 1px var(--wd-signal) inset}
.wd-pak .wd-badge{font-family:var(--wd-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--wd-signal);min-height:18px}
.wd-pak:not(.wd-feat) h3{margin-top:24px}
.wd-pak h3{font-family:var(--wd-display);font-weight:800;font-size:1.5rem;letter-spacing:-.02em;margin:6px 0 4px}
.wd-pak .wd-price{font-family:var(--wd-display);font-weight:800;font-size:2rem;letter-spacing:-.02em;margin:10px 0}
/* Preiszeile ist eine Ueberschrift in Zweitgestalt und braucht denselben Umbruchschutz wie
   h1-h4: „Buendelpreis" bei 2rem lief auf Handy-quer (844px, 3 Spuren) um 10px aus der
   Spur — gemessen 01.08.2026 auf /leistungen/ki-ci/. Bewusst ohne Klassen-Praefix, damit
   auch die Preiszeilen ausserhalb von .wd-pak gedeckt sind. */
#wd-root .wd-price{min-width:0;overflow-wrap:anywhere;hyphens:auto}
.wd-pak .wd-price small{font-family:var(--wd-body);font-weight:400;font-size:.9rem;color:var(--wd-grey)}
.wd-pak ul{list-style:none;margin:14px 0 22px;padding:0;display:flex;flex-direction:column;gap:9px}
.wd-pak li{font-size:.98rem;color:rgba(245,245,243,.74);padding-left:22px;position:relative;min-width:0;overflow-wrap:anywhere}
.wd-pak li::before{content:"_";position:absolute;left:0;color:var(--wd-signal);font-family:var(--wd-mono)}
.wd-pak .wd-btn{justify-content:center;margin-top:auto}
/* ENDORSEMENT */
.wd-endorse{background:var(--wd-anthracite);border-top:1px solid var(--wd-hairline);border-bottom:1px solid var(--wd-hairline);text-align:center}
.wd-endorse .wd-e{font-family:var(--wd-mono);font-size:13px;letter-spacing:.12em;text-transform:uppercase;color:var(--wd-grey)}
.wd-endorse .wd-e b{color:var(--wd-fresh)}
.wd-endorse h2{font-family:var(--wd-display);font-weight:800;font-size:clamp(1.6rem,3.4vw,2.6rem);letter-spacing:-.025em;margin-top:14px;max-width:760px;margin-inline:auto}
/* KONTAKT */
.wd-contact{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center}
.wd-form{background:var(--wd-surface-1);border:1px solid var(--wd-hairline);border-radius:var(--wd-radius);padding:30px}
.wd-form .wd-row{margin-bottom:14px}
.wd-form label{font-family:var(--wd-mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--wd-grey);display:block;margin-bottom:6px}
/* min-height:44px — das Auswahlfeld kam mit 12px Padding auf 42px und riss die
   Touch-Target-Vorgabe um 2px (gemessen live 390px, 01.08.2026). */
.wd-form input,.wd-form textarea,.wd-form select{width:100%;background:var(--wd-night);border:1px solid var(--wd-hairline);border-radius:var(--wd-radius-sm);padding:12px 14px;color:var(--wd-warmwhite);font-family:var(--wd-body);font-size:1rem;min-height:44px}
.wd-form input:focus,.wd-form textarea:focus,.wd-form select:focus{outline:2px solid var(--wd-signal);border-color:transparent}
.wd-form .wd-btn{width:100%;justify-content:center;margin-top:6px}
/* FOOTER */
#wd-footer{border-top:1px solid var(--wd-hairline);padding:46px 0 60px}
.wd-foot{display:flex;justify-content:space-between;align-items:flex-start;gap:30px;flex-wrap:wrap}
.wd-foot .wd-brand{font-size:26px}
.wd-foot .wd-cols{display:flex;gap:60px;font-size:.95rem;color:var(--wd-grey)}
.wd-foot .wd-cols a{display:block;margin-top:8px}
.wd-foot .wd-cols a:hover{color:var(--wd-warmwhite)}
.wd-foot .wd-legal{margin-top:30px;font-family:var(--wd-mono);font-size:11px;color:var(--wd-grey);letter-spacing:.04em}
.wd-foot .wd-legal a{color:var(--wd-grey)}
.wd-foot .wd-legal a:hover{color:var(--wd-warmwhite)}
.wd-foot .wd-legal b{color:var(--wd-fresh)}
/* .wd-badge-draft entfernt — das Vorschau-Badge lag position:fixed mit z-index:300 UEBER dem
   Fliesstext, war nicht schliessbar und hatte kein aria-hidden. Preise sind final (Set A). */
/* MOTION — „Komposition aus Ruhe": IO-Reveals (cross-browser) + Hero-Parallax.
   Default sichtbar (no-JS); Hide nur unter .js-motion. Der reduced-motion-Rueckfall steht
   als eigener Block unter diesem und greift, sobald .wd-motion-forced fehlt.
   (Der alte Kommentar behauptete „reduced-motion safe" — das war zu dem Zeitpunkt falsch.) */
.wd-reveal{opacity:1;transform:none}
@media all{
  .js-motion .wd-reveal{opacity:0;transform:translateY(26px) scale(.99);
    transition:opacity .8s cubic-bezier(.22,.61,.36,1),transform .8s cubic-bezier(.22,.61,.36,1);will-change:opacity,transform}
  .js-motion .wd-reveal.is-in{opacity:1;transform:none}
  /* Zähler-Lauf — Karte selbst ruhig (kein Block-Slide); nur Index, Hairline, Wort, Text animieren */
  .js-motion .wd-count{opacity:1;transform:none}
  .js-motion .wd-count .wd-count-rule{transform:scaleX(0);transition:transform .9s cubic-bezier(.22,.61,.36,1)}
  .js-motion .wd-count.is-in .wd-count-rule{transform:scaleX(1)}
  .js-motion .wd-count .wd-count-k{opacity:0;transform:translateY(-4px);transition:opacity .6s ease .28s,transform .6s ease .28s}
  .js-motion .wd-count.is-in .wd-count-k{opacity:1;transform:none}
  .js-motion .wd-count .wd-word{transform:translateY(118%);transition:transform .75s cubic-bezier(.22,.61,.36,1) .12s}
  .js-motion .wd-count.is-in .wd-word{transform:translateY(0)}
  .js-motion .wd-count p{opacity:0;transform:translateY(10px);transition:opacity .6s ease .34s,transform .6s ease .34s}
  .js-motion .wd-count.is-in p{opacity:1;transform:none}
  @supports (animation-timeline:view()){
    .wd-hero-bg img{animation:wd-drift linear both;animation-timeline:view();animation-range:entry 0% exit 100%}
    @keyframes wd-drift{from{transform:scale(1.06) translateY(0)}to{transform:scale(1.12) translateY(4%)}}
  }
}
/* Reduced-Motion — TRANSPORT faellt weg, der Rest laeuft weiter.
   Frueher stand hier `opacity:1;transform:none;transition:none` auf allem: das war die
   tote Standbild-Version, und genau daran ist die Bewegungsreduktion hier immer gescheitert
   („dann lieber gar kein reduced-motion"). Der Split loest das statt es zu ueberfahren:
     Transport      = Translate, Scale, Parallaxe, Scrub -> aus (loest die Beschwerden aus)
     Nicht-Transport= Opacity, Farbe, clip-path, Draw-on -> laeuft in voller Staerke weiter
   Greift nur ohne .wd-motion-forced; solange die Inhaber-Entscheidung steht, ist der
   Block inaktiv — aber vorhanden und korrekt, nicht entkernt. */
@media (prefers-reduced-motion: reduce){
  html:not(.wd-motion-forced) .js-motion .wd-reveal{transform:none}
  html:not(.wd-motion-forced) .js-motion .wd-count .wd-count-k{transform:none}
  html:not(.wd-motion-forced) .js-motion .wd-count .wd-word{transform:none}
  html:not(.wd-motion-forced) .js-motion .wd-count p{transform:none}
  /* RAIL-LAUF (Block ⑤ weiter unten), Transport/Nicht-Transport getrennt:
     AUS    — Fall des Index, Hub der Ueberschrift, Versatz des Textes und der laufende
              Caret (ein Objekt, das sich durch die Sektion bewegt).
     BLEIBT — der Draw-on des Schienensegments (scaleX) und jede Opacity in voller
              Staerke; gleiche Einordnung wie .wd-count-rule drei Zeilen darueber.
     Der Caret wird ausgeblendet statt eingefroren: `transform:none` parkte ihn am
     Streckenanfang, wo er dauerhaft und sichtbar falsch stuende.
     .wd-lift bekommt hier — und NUR hier — eine Opacity: mit Hub waere eine zusaetzliche
     Blende matschig, ohne Hub ist sie das, was den Takt ueberhaupt noch traegt. */
  html:not(.wd-motion-forced) .js-motion .wd-rail .wd-step::after{display:none}
  html:not(.wd-motion-forced) .js-motion .wd-rail .wd-n{transform:none}
  html:not(.wd-motion-forced) .js-motion .wd-rail .wd-lift{transform:none;opacity:var(--wd-e-h)}
  html:not(.wd-motion-forced) .js-motion .wd-rail .wd-step p{transform:none}
  /* LEDGER-LISTE, gleiche Trennung:
     AUS    — Fall des Numerals, Hub des Namens, der Prompt-Einzug und der Chevron-Versatz
     BLEIBT — jede Opacity, der Draw-on der gruenen Kante (scaleX) und das Einwischen des
              Motivs; clip-path ist Nicht-Transport, gleiche Einordnung wie .wd-count-rule.
     .wd-lift bekommt hier — und NUR hier — eine Opacity: ohne Hub traegt sonst nichts
     mehr den Takt der Zeile. */
  html:not(.wd-motion-forced) .js-motion .wd-lst .wd-lst-n{transform:none}
  html:not(.wd-motion-forced) .js-motion .wd-lst .wd-lift{transform:none;opacity:var(--wd-lp-h)}
  html:not(.wd-motion-forced) .js-motion .wd-lst-a:hover .wd-lst-t,
  html:not(.wd-motion-forced) .js-motion .wd-lst-a:focus-visible .wd-lst-t,
  html:not(.wd-motion-forced) .js-motion .wd-lst-a:hover .wd-lst-d,
  html:not(.wd-motion-forced) .js-motion .wd-lst-a:focus-visible .wd-lst-d,
  html:not(.wd-motion-forced) .js-motion .wd-lst-a:hover .wd-lst-go,
  html:not(.wd-motion-forced) .js-motion .wd-lst-a:focus-visible .wd-lst-go{transform:none}
  /* BUEHNE, gleiche Trennung:
     AUS    — der Zoom-Ausschwung der einfahrenden Ebene (Scale = Transport).
     BLEIBT — der Stapel-Wechsel selbst (Deckkraft), die gruene Kante, die Farbfuehrung
              und die Fortschrittsschiene. Wer Bewegungsreduktion einschaltet, will kein
              Standbild, sondern keinen Transport. */
  html:not(.wd-motion-forced) .js-motion .wd-bue-l{transform:none}
  html:not(.wd-motion-forced) .wd-hero-bg img{animation:none}
  html:not(.wd-motion-forced) .wd-pak.wd-feat{animation:none}
  html:not(.wd-motion-forced) #wd-scrollbar{animation:none}
  html:not(.wd-motion-forced) .wd-title{animation:none}
  html:not(.wd-motion-forced) .hero-portal{display:none!important}
}

/* _MOTION AUS — der sichtbare Schalter im Footer (wd-motion.js haengt ihn ein).
   WCAG 2.2.2 „Pause, Stop, Hide", Level A: alles anhalten, nichts verstecken. Das ist der
   einzige Ort mit einem Rundumschlag — hier ist er die Zusage, nicht die Bequemlichkeit. */
html.wd-motion-off #wd-root *,
html.wd-motion-off #wd-root *::before,
html.wd-motion-off #wd-root *::after{animation:none!important;transition:none!important}
html.wd-motion-off #wd-root .wd-reveal{opacity:1!important;transform:none!important}
html.wd-motion-off #wd-root .wd-cine [data-s]{--l:1!important}
/* RAIL-LAUF haengt wie das Cine-Band an einer Custom Property, nicht an einer Klasse —
   `animation:none;transition:none` allein liesse den deklarierten --wd-sp:0 stehen und
   bliese die Sektion leer. Diese eine Zeile setzt alles: Segment scaleX(1), alle
   Translates auf 0, alle Opacity auf 1, und die Caret-Formel min(9, (1-1)*9) liefert
   exakt 0 — kein verwaister Caret bleibt irgendwo auf der Strecke stehen. */
html.wd-motion-off #wd-root .wd-rail .wd-step{--wd-sp:1!important}
/* Dieselbe Ursache bei der Ledger-Liste: sie haengt an --wd-lp, nicht an einer Klasse.
   Ohne diese Zeile bliebe der deklarierte --wd-lp:0 stehen und die sechs Zeilen waeren
   bis auf die Haarlinien leer. */
html.wd-motion-off #wd-root .wd-lst .wd-lst-row{--wd-lp:1!important;--wd-lz:0!important}
/* Und dieselbe Ursache bei der Buehne: sie haengt an --wd-bp/--wd-hov, nicht an einer
   Klasse. `animation:none` allein wuerde den Treiber zwar auf seinem Initialwert 0
   stehen lassen (Motiv 1 steht, korrekt) — aber genau diese Annahme hat sich am 02.08.
   schon einmal als falsch erwiesen. Explizit gesetzt kann sie nicht kippen: Buehne zeigt
   Motiv 1, Schiene auf 1/6, kein Zwischenzustand friert irgendwo ein. */
html.wd-motion-off #wd-root .wd-lst-split{--wd-bp:0!important;--wd-hov:0!important}
html.wd-motion-off #wd-root .wd-cine-vid{transform:none!important}
html.wd-motion-off .hero-portal{display:none!important}
html.wd-motion-off{scroll-behavior:auto}
.wd-motion-btn{font-family:var(--wd-mono);font-size:12px;letter-spacing:.08em;
  background:none;border:1px solid var(--wd-hairline);border-radius:var(--wd-radius);
  color:var(--wd-grey);padding:8px 12px;margin-left:14px;cursor:pointer;min-height:44px;
  display:inline-flex;align-items:center;transition:.18s}
.wd-motion-btn:hover,.wd-motion-btn:focus-visible{color:var(--wd-signal);border-color:var(--wd-signal)}
/* Lenis ist raus (Hausdoktrin: nativ scrollen). Sein einziger reale Aufgabe hier war der
   Ankerversatz via `lenis.scrollTo(el,{offset:-68})` — und der galt nur fuer Maus-Klicks auf
   Desktop. `scroll-margin-top` am Ziel gilt fuer ALLE Wege: Klick, Tastatur, Deep-Link,
   Zurueck-Navigation, `scrollIntoView` aus fremdem JS. Deckt auch die 84 H2-Anker der
   Unterseiten ab, weil der Selektor auf jedem [id] unter #wd-root sitzt. */
#wd-root [id]{scroll-margin-top:calc(var(--wd-header-h) + 12px)}
/* FLUENT FORMS — auf CI getrimmt (Wrapper = .frm-fluent-form) */
.wd-form .frm-fluent-form .ff-el-group{margin-bottom:14px}
.wd-form .frm-fluent-form .ff-el-input--label label,.wd-form .frm-fluent-form label{font-family:var(--wd-mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--wd-grey);margin-bottom:6px}
.wd-form .frm-fluent-form .ff-el-is-required,.wd-form .frm-fluent-form .ff_t_asterisk{color:var(--wd-signal)}
.wd-form .frm-fluent-form input[type=text].ff-el-form-control,.wd-form .frm-fluent-form input[type=email].ff-el-form-control,.wd-form .frm-fluent-form input.ff-el-form-control,.wd-form .frm-fluent-form textarea.ff-el-form-control,.wd-form .frm-fluent-form select.ff-el-form-control{width:100%;background:var(--wd-night);border:1px solid var(--wd-hairline);border-radius:var(--wd-radius-sm);padding:12px 14px;color:var(--wd-warmwhite);font-family:var(--wd-body);font-size:1rem;box-shadow:none;min-height:44px}
.wd-form .frm-fluent-form .ff-el-form-control:focus{outline:2px solid var(--wd-signal);border-color:transparent;background:var(--wd-night)}
.wd-form .frm-fluent-form .ff-el-form-control::placeholder{color:var(--wd-grey)}
.wd-form .frm-fluent-form .ff-btn-submit,.wd-form .frm-fluent-form button[type=submit]{background:var(--wd-signal)!important;color:var(--wd-night)!important;font-family:var(--wd-display);font-weight:800;font-size:14px;letter-spacing:.02em;text-transform:uppercase;border:none;border-radius:var(--wd-radius);padding:14px 22px;cursor:pointer;width:100%;transition:.18s}
.wd-form .frm-fluent-form .ff-btn-submit:hover{background:#28f29a!important;transform:translateY(-1px)}
.wd-form .frm-fluent-form .ff-message-success{color:var(--wd-signal);font-family:var(--wd-mono);font-size:.95rem}
.wd-form .frm-fluent-form .text-danger,.wd-form .frm-fluent-form .error{color:#ff6b6b;font-family:var(--wd-mono);font-size:.8rem}
/* Datenschutz-Einwilligung (Art. 13 DSGVO) — Pflichtfeld, Touch-Target >=44px */
.wd-form .frm-fluent-form .ff-el-tc{display:flex;align-items:flex-start;gap:10px}
.wd-form .frm-fluent-form .ff_tc_label{display:flex;align-items:flex-start;gap:10px;min-height:44px;padding:6px 0;cursor:pointer;text-transform:none;letter-spacing:normal;font-family:var(--wd-body);margin:0}
.wd-form .frm-fluent-form .ff_tc_checkbox{display:flex;align-items:center;min-height:32px;flex:0 0 auto}
.wd-form .frm-fluent-form .ff_tc_checkbox input[type=checkbox]{width:20px;height:20px;min-width:20px;accent-color:var(--wd-signal);background:var(--wd-night);border:1px solid var(--wd-hairline);border-radius:3px;padding:0;margin:0;cursor:pointer}
.wd-form .frm-fluent-form .ff_t_c{color:rgba(245,245,243,.74);font-size:.92rem;line-height:1.5}
.wd-form .frm-fluent-form .ff_t_c a{color:var(--wd-signal);text-decoration:underline;text-underline-offset:2px}
/* Kurzhinweis unter dem Formular */
.wd-form-note{margin-top:14px;color:var(--wd-grey);font-size:.85rem;line-height:1.55}
.wd-form-note a{color:var(--wd-signal);text-decoration:underline;text-underline-offset:2px}
/* ===== CINE — Sticky-Pin Video-Band „Werkstatt bei Nacht" (full-bleed) ===== */
.wd-cine{position:relative;height:200vh;background:var(--wd-night)}
.wd-cine-stage{position:sticky;top:0;height:100vh;min-height:560px;width:100%;overflow:hidden;display:flex;align-items:flex-end;border-top:1px solid var(--wd-hairline);border-bottom:1px solid var(--wd-hairline)}
.wd-cine-vid{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:58% 42%;transform:scale(var(--cine-scale,1.05));transform-origin:62% 42%;will-change:transform;background:var(--wd-night)}
.wd-cine-veil{position:absolute;inset:0;z-index:1;background:linear-gradient(0deg,rgba(11,11,12,.94) 1%,rgba(11,11,12,.45) 30%,rgba(11,11,12,.18) 56%,rgba(11,11,12,.5) 100%)}
.wd-cine-copy{position:relative;z-index:2;width:100%;padding-bottom:clamp(40px,8vh,92px);padding-top:48px;transform:translateY(var(--cine-copy-par,0));will-change:transform}
.wd-cine-eyebrow{display:flex;align-items:center;gap:14px;margin-bottom:12px}
.wd-cine-rule{display:block;flex:0 0 auto;width:46px;height:2px;background:var(--wd-signal);transform:scaleX(var(--l,1));transform-origin:left;will-change:transform}
.wd-cine-eyebrow-t{display:inline-block;opacity:var(--l,1);transform:translateY(calc((1 - var(--l,1)) * 12px));will-change:opacity,transform}
.wd-cine-h{font-family:var(--wd-display);font-weight:800;letter-spacing:-.035em;line-height:.95;font-size:clamp(2.4rem,6.2vw,5.2rem);margin:10px 0 0}
.wd-cine-h .wd-w{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.12em;margin-bottom:-.12em}
.wd-cine-h .wd-lift{display:inline-block;transform:translateY(calc((1 - var(--l,1)) * 120%));will-change:transform}
.wd-cine-sub{color:rgba(245,245,243,.74);font-size:1.15rem;max-width:560px;margin-top:18px;opacity:var(--l,1);transform:translateY(calc((1 - var(--l,1)) * 16px));will-change:opacity,transform}
@property --l{syntax:'<number>';inherits:false;initial-value:1}
@media all{
  .js-motion .wd-cine [data-s]{--l:0}
}
@media (prefers-reduced-motion: reduce){
  html:not(.wd-motion-forced) .wd-cine{height:auto}
  html:not(.wd-motion-forced) .wd-cine-stage{position:relative;height:auto;min-height:70vh}
  html:not(.wd-motion-forced) .wd-cine-vid{transform:none}
}
@media(max-width:1024px){ .wd-cine{height:175vh} }
@media(max-width:600px){
  .wd-cine{height:auto}
  .wd-cine-stage{position:relative;height:auto;min-height:82vh}
  .wd-cine-vid{transform:none}
  .wd-cine-copy{padding-bottom:clamp(30px,6vh,60px);padding-top:38px}
  .wd-cine-h{font-size:clamp(2.2rem,9.4vw,3.3rem)}
  .wd-cine-sub{font-size:1.02rem;margin-top:14px}
}
/* flaches Querformat (z.B. Handy quer): Pin kollabieren, kompakt füllen, Text muss in die niedrige Höhe passen */
@media (max-height:620px) and (orientation:landscape){
  .wd-cine{height:auto}
  .wd-cine-stage{position:relative;height:auto;min-height:96vh}
  .wd-cine-vid{transform:none}
  .wd-cine-copy{padding-bottom:22px;padding-top:26px}
  .wd-cine-eyebrow{margin-bottom:8px}
  .wd-cine-h{font-size:clamp(1.7rem,5.6vw,2.4rem)}
  .wd-cine-sub{font-size:.98rem;margin-top:10px;max-width:560px}
}
/* ===== RESPONSIVE — Seitenrand global via --wd-gutter (überall identisch) ===== */
/* Tablet quer / kleiner Desktop (≤1024) → 2-spaltige Grids */
@media(max-width:1024px){
  :root{--wd-gutter:28px}
  .wd-g3,.wd-steps,.wd-why{grid-template-columns:repeat(2,1fr)}
  .wd-hero h1{font-size:clamp(2.8rem,8vw,5rem)}
  .wd-section{padding:84px 0}
  .wd-section-tight{padding:60px 0}
}
/* Tablet hoch (≤834) → Pakete/Kontakt 1-spaltig, Menü weg */
@media(max-width:834px){
  .wd-menu{display:none}
  /* .wd-pak2 mitschreiben: `.wd-pakete.wd-pak2` ist spezifischer und wuerde den
     Einspalter sonst schlagen — die zwei Karten blieben auf 390px nebeneinander. */
  .wd-pakete,.wd-pakete.wd-pak2{grid-template-columns:1fr}
  .wd-contact{grid-template-columns:1fr;gap:30px}
  /* Ab hier kommt der Hamburger dazu — der CTA gibt sein Verb ab, damit Marke + CTA + Burger
     nebeneinander passen. Gerechnet bei 390px: Marke ~190 + CTA ~190 + Burger 52 = 432 > 350. */
  .wd-nav-cta-x{display:none}
  .wd-nav-cta{padding:11px 14px}
}
/* Handy hoch (≤600) → alles 1-spaltig, kompakter */
@media(max-width:600px){
  :root{--wd-gutter:20px;--wd-header-h:56px}
  .wd-brand{font-size:17px}
  /* Der Kopf-CTA weicht ganz — er lebt jetzt als erste Zeile im Hamburger-Panel weiter. */
  .wd-nav-cta{display:none}
  .wd-g3,.wd-g2,.wd-steps,.wd-why{grid-template-columns:1fr}
  .wd-section{padding:60px 0}
  .wd-section-tight{padding:44px 0}
  .wd-hero-inner{padding:64px var(--wd-gutter)}
  .wd-hero h1{font-size:clamp(2.6rem,11vw,3.4rem)}
  .wd-trust{gap:14px}
  /* Buttons sauber: voll-breit gestapelt, Label zentriert */
  .wd-hero-cta{flex-direction:column;align-items:stretch}
  .wd-card-cta{flex-direction:column;align-items:stretch}
  .wd-hero-cta .wd-btn,.wd-card-cta .wd-btn{width:100%;justify-content:center}
  /* Preiskarten + Ablauf-Schritte hatten als einzige Bloecke der Seite keine eigene
     Mobile-Regel: 30px Padding blieben bei 390px stehen, was 288px Textbreite laesst —
     die engste Karte der Seite. .wd-card bekommt hier seit jeher eine Feinjustierung,
     .wd-pak wurde beim Zuruecknehmen der Preis-Langsektion (01.08.2026) mitvergessen. */
  .wd-pak{padding:22px}
  .wd-pak .wd-price{font-size:1.6rem}
  .wd-pak ul{margin:12px 0 18px}
  .wd-step{padding-top:22px}
}
/* sehr schmale Handys (≤380) */
@media(max-width:380px){ :root{--wd-gutter:16px} }
/* Handy quer (niedrige Höhe): Hero + Sektionen flacher, Höhe nicht erzwingen */
@media(max-height:620px) and (orientation:landscape){
  .wd-hero{min-height:auto}
  /* Kurzer Landscape-Fold (Handy quer): Hero straffen, damit der Primär-CTA voll in den Fold passt */
  .wd-hero-inner{padding:22px var(--wd-gutter) 28px}
  .wd-hero h1{font-size:clamp(2rem,5.4vw,3rem);line-height:.98;margin-top:10px}
  .wd-hero .wd-lead{font-size:1.1rem;margin-top:10px}
  .wd-hero-cta{margin-top:18px}
  .wd-trust{margin-top:18px}
  .wd-section{padding:54px 0}
  .wd-section-tight{padding:40px 0}
}
/* === LEISTUNGEN — Hauptleistungen visuell hervorheben === */
a.wd-card.wd-card-main{border-color:var(--wd-signal);box-shadow:0 0 0 1px var(--wd-signal) inset;background:var(--wd-surface-2)}
a.wd-card.wd-card-main h3{font-size:1.65rem}
a.wd-card.wd-card-main p{font-size:1.04rem}
.wd-card-tag{font-family:var(--wd-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--wd-signal);margin-bottom:10px}
/* === HAMBURGER MOBILE NAV === */
.wd-ham{display:none;flex-direction:column;justify-content:center;gap:5px;cursor:pointer;background:transparent;border:none;padding:8px 6px;margin-left:8px;min-height:44px;min-width:44px;align-items:center;flex:0 0 auto}
.wd-ham span{display:block;width:22px;height:2px;background:var(--wd-warmwhite);transition:transform .22s cubic-bezier(.22,.61,.36,1),opacity .18s}
.wd-ham.open span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.wd-ham.open span:nth-child(2){opacity:0;transform:scaleX(0)}
.wd-ham.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
@media(max-width:834px){.wd-ham{display:flex}}
.wd-mob-menu{position:fixed;top:var(--wd-header-h);right:-270px;width:260px;bottom:0;background:var(--wd-anthracite);border-left:1px solid var(--wd-hairline);transition:right .28s cubic-bezier(.22,.61,.36,1);z-index:99;padding:20px;display:flex;flex-direction:column;gap:0;overflow-y:auto}
/* Primaer-CTA im Panel. Unter 601px verschwindet der Kopf-CTA (die Wortmarke braucht die
   Breite) — ohne diesen Knopf gaebe es dann oberhalb des Folds keinen Weg zum Kontakt. */
.wd-mob-menu .wd-mob-cta{background:var(--wd-signal);color:var(--wd-night);font-family:var(--wd-display);font-weight:800;font-size:14px;letter-spacing:.02em;text-transform:uppercase;border-radius:var(--wd-radius);padding:0 18px;min-height:48px;display:flex;align-items:center;justify-content:center;gap:8px;border-bottom:none;margin-bottom:14px}
.wd-mob-menu .wd-mob-cta .wd-c{color:var(--wd-night)}
.wd-mob-menu .wd-mob-cta:hover,.wd-mob-menu .wd-mob-cta:focus{color:var(--wd-night);background:#28f29a}
.wd-mob-menu a{padding:15px 6px;font-family:var(--wd-mono);font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:var(--wd-grey);border-bottom:1px solid var(--wd-hairline);display:block;transition:color .18s}
.wd-mob-menu a:last-child{border-bottom:none}
.wd-mob-menu a:hover,.wd-mob-menu a:focus{color:var(--wd-warmwhite);outline:none}
.wd-mob-overlay{position:fixed;inset:0;background:rgba(11,11,12,.72);z-index:98;opacity:0;pointer-events:none;transition:opacity .25s}
.wd-mob-menu.open{right:0}
.wd-mob-overlay.open{opacity:1;pointer-events:auto}
/* Ueber 834px gibt es den Hamburger nicht — dann hat auch das geparkte Panel nichts im
   Dokument zu suchen. Es war die einzige Quelle der 58px Ueberstand bei 1440px, die
   `#wd-root{overflow-x:clip}` bisher wegschneiden musste, und stand als Tastatur-Ziel
   im Fokus-Fluss. */
@media(min-width:835px){.wd-mob-menu,.wd-mob-overlay{display:none}}
/* === DIREKTKONTAKT-LINKS === */
.wd-contact-direct{display:flex;gap:18px;flex-wrap:wrap;margin-top:16px}
.wd-contact-link{font-family:var(--wd-mono);font-size:12px;letter-spacing:.06em;color:var(--wd-grey);display:inline-flex;align-items:center;gap:6px;transition:color .18s}
.wd-contact-link:hover{color:var(--wd-warmwhite)}
.wd-foot-contact{margin-top:10px;display:flex;flex-direction:column;gap:5px}
.wd-foot-contact a{font-family:var(--wd-mono);font-size:11px;letter-spacing:.04em;color:var(--wd-grey);transition:color .18s}
.wd-foot-contact a:hover{color:var(--wd-warmwhite)}
/* === ELEGANTE WOW-TOUCHES === */
/* ① Scroll-Caret-Fortschrittsleiste (CSS scroll-timeline; unsupported → unsichtbar) */
#wd-scrollbar{position:fixed;top:0;left:0;height:2px;width:100%;transform:scaleX(0);transform-origin:0 50%;background:var(--wd-signal);box-shadow:0 0 8px rgba(25,230,138,.6);z-index:300;pointer-events:none}
@supports (animation-timeline: scroll()){@media all{
  #wd-scrollbar{animation:wd-scrollprog linear both;animation-timeline:scroll(root)}
}}
@keyframes wd-scrollprog{from{transform:scaleX(0)}to{transform:scaleX(1)}}
/* ① Nav-Caret: getipptes gruenes _ vor dem Link bei hover/focus (kein Layout-Shift) */
/* Touch-Targets auch im Handy-Querformat (844x390): dort ist .wd-menu sichtbar und
   die Links waren 21px hoch, die Wortmarke 35px. Das Kopfband ist ohnehin hoeher —
   die Hoehe kostet kein Layout. */
.wd-menu a{position:relative;min-height:44px;display:inline-flex;align-items:center}
.wd-brand{min-height:44px;display:inline-flex;align-items:center}
.wd-menu a::before{content:"_";position:absolute;left:-9px;top:50%;margin-top:-.62em;color:var(--wd-signal);opacity:0;transform:translateX(3px);transition:opacity .2s,transform .2s;font-family:var(--wd-mono)}
.wd-menu a:hover::before,.wd-menu a:focus-visible::before{opacity:1;transform:translateX(0)}
/* ② Card Terminal-Focus: gruene Oberkante zeichnet sich ein */
.wd-card{position:relative}
.wd-card::after{content:"";position:absolute;left:0;top:0;height:2px;width:100%;background:var(--wd-signal);transform:scaleX(0);transform-origin:0 50%;transition:transform .32s cubic-bezier(.22,.61,.36,1);border-radius:var(--wd-radius) var(--wd-radius) 0 0;pointer-events:none}
.wd-card:hover::after{transform:scaleX(1)}
/* ② Paket-Glow: die EINE beliebte Karte atmet einen dezenten Gruen-Glow.
   Ein Atemzug beim Ankommen (4,2s < 5s), danach Ruhe — Endlosschleife war WCAG 2.2.2.
   Auf Hover atmet sie weiter, weil der Nutzer sie dann selbst gestartet hat. */
@media all{.wd-pak.wd-feat{animation:wd-pak-breathe 4.2s ease-in-out 1}}
@media all{.wd-pak.wd-feat:hover{animation:wd-pak-breathe 4.2s ease-in-out infinite}}
@keyframes wd-pak-breathe{0%,100%{box-shadow:0 0 0 1px var(--wd-signal) inset,0 0 0 0 rgba(25,230,138,0)}50%{box-shadow:0 0 0 1px var(--wd-signal) inset,0 0 26px 2px rgba(25,230,138,.22)}}
/* ③ Caret-Puls: das _ im Primary-Button pulsiert bei hover (Magnetic = wd-touches.js) */
.wd-btn-primary:hover span{animation:wd-caret-pulse .9s ease-in-out infinite}
@keyframes wd-caret-pulse{0%,100%{opacity:1}50%{opacity:.35}}
/* ④ Title-Wipe: H2 wischt beim Eintreten hinter Maske hoch (CSS view-timeline) */
@supports (animation-timeline: view()){@media all{
  .wd-title{animation:wd-wipe linear both;animation-timeline:view();animation-range:entry 5% entry 55%}
}}
@keyframes wd-wipe{from{clip-path:inset(0 0 100% 0);opacity:0}to{clip-path:inset(0 0 0 0);opacity:1}}
/* ===== ⑤ ABLAUF „RAIL-LAUF" mit Terminal-Kopf ========================================
   Warum: `.wd-step{border-top:2px solid}` malte vier getrennte Striche, und der ganze
   Vierer blendete als EIN .wd-reveal ein. Vier Striche sind vier Kacheln; eine Schiene
   ist ein Ablauf. Die Sektion behauptete „so laeuft's" und stand dabei still.

   GELTUNGSBEREICH `.wd-rail` — steht ausschliesslich im Markup der Startseite. Die
   Klassen .wd-steps/.wd-step/.wd-n erzeugt build_leistungen.py::steps() auch auf sechs
   Unterseiten; die tragen .js-motion, laden aber weder anime.min.js noch wd-motion.js.
   Eine Versteck-Regel an `.js-motion .wd-steps` haette deren Prozess-Sektion dauerhaft
   ausgeblendet. `.wd-ablauf` teilt sich #ablauf mit #pakete, `.wd-steps` nicht — #pakete
   bleibt konstruktionsbedingt aussen vor.

   EIN TREIBER JE SCHRITT, ZWEI QUELLEN: --wd-sp laeuft 0 -> 1.
     Ebene 1 (ueberall):   transition, gehaengt an den vorhandenen .is-in-Haken
     Ebene 2 (progressiv): dieselbe Variable per animation-timeline:view()
   Animation schlaegt author-normal in der Kaskade, die Ebenen ueberlagern sich also
   sauber statt zu konkurrieren. --wd-sp ist bewusst `inherits:false` und sitzt je
   Schritt: eine vererbte Property auf dem Container rechnete je Frame den ganzen
   Teilbaum neu (13 Elemente) — der klassische style-recalc-storm.

   VIER SEGMENTE STATT EINER DURCHGEHENDEN SCHIENE: ::before und ::after haengen an
   .wd-step (schon position:relative). Damit stimmt die Geometrie bei 4, bei 2 und bei
   1 Spalte OHNE eine einzige Breakpoint-Regel fuer die Schiene. Der 18px-gap wird zum
   Merkmal — der Caret springt zur naechsten Prompt-Zeile.
   ==================================================================================== */
/* VERERBUNGSRICHTUNG — hier steckte der erste Fehlschlag (02.08.2026, live gemessen):
   --wd-sp und die abgeleiteten Werte standen zuerst alle auf `inherits:false`. Gelesen
   werden sie aber von NACHFAHREN — ::before, ::after, .wd-n, .wd-lift, p — und dort
   fiel eine nicht vererbende Property auf ihren Initialwert 1 zurueck. Der Schritt selbst
   rampte sauber von 0 auf 1, alles daran haengende stand permanent auf „fertig": Schiene
   voll, Caret unsichtbar, Ueberschrift ungehoben. Die Sektion sah exakt so aus wie vorher.
   Deshalb: --wd-sp und --wd-e-rule vererben (ein Treiber plus der Wert, den BEIDE
   Pseudo-Elemente brauchen), die drei uebrigen Kurven werden am verbrauchenden Element
   selbst gerechnet und muessen dort nicht vererben. */
@property --wd-sp{syntax:'<number>';inherits:true;initial-value:1}
@property --wd-e-rule{syntax:'<number>';inherits:true;initial-value:1}
@property --wd-e-n{syntax:'<number>';inherits:false;initial-value:1}
@property --wd-e-h{syntax:'<number>';inherits:false;initial-value:1}
@property --wd-e-p{syntax:'<number>';inherits:false;initial-value:1}

/* Grundzustand IST der Endzustand. initial-value:1 traegt no-JS, Druck, _MOTION AUS und
   jeden Browser ohne @property/pow(): dort faellt eine ungueltige Rechnung auf den
   Initialwert zurueck und die Sektion steht vollstaendig da. Nie ein leeres Band. */
.wd-rail .wd-step{border-top-color:transparent;
  /* Lokale Staffel INNERHALB eines Schritts. Die Schiene laeuft in den ersten 36 % des
     Wegs, danach zuenden Index, Ueberschrift und Text nacheinander. easeOutCubic
     (1-(1-p)^3) ist praktisch deckungsgleich mit der Hauskurve .22,.61,.36,1 und
     dieselbe Formel, die der Cine-Scrub schon benutzt. */
  /* Die Schiene zieht in den ersten 55 % des Schrittwegs. Erster Wurf waren 36 % — bei
     einer Spanne von 15 % cover sind das 5,4 % Scrollweg, also rund 57px bzw. gut ein
     Zehntelsekunde bei normalem Scrolltempo. Der Zeichenvorgang war damit zu kurz, um
     ueberhaupt als Bewegung gelesen zu werden; sichtbar waren fast nur Endzustaende.
     55 % ergeben 8,25 % Scrollweg und bleiben unter dem 9-%-Versatz zum naechsten
     Schritt — die Bedingung „nie zwei Carets gleichzeitig" haelt also weiter. */
  --wd-e-rule:clamp(0,var(--wd-sp)/.55,1)}
/* Schienensegment. Draw-on, nicht Transport — laeuft deshalb auch unter Bewegungsreduktion,
   gleiche Einordnung wie .wd-count-rule. top:-2px legt es in die (transparent gemachte)
   Border-Zone, die 2px-Metrik der Kachel bleibt damit unveraendert. */
.wd-rail .wd-step::before{content:"";position:absolute;left:0;right:0;top:-2px;height:2px;
  background:var(--wd-signal);transform:scaleX(var(--wd-e-rule));transform-origin:0 50%;
  pointer-events:none}
/* Der Terminal-Kopf. Die Spur ist genau so breit wie der Schritt, das Zeichen sitzt an
   ihrem RECHTEN Rand — `translateX((e - 1) * 100%)` bildet den Fortschritt damit 1:1 auf
   die Streckenlaenge ab, ohne eine einzige gemessene Koordinate.
   Das `- 1` ist Pflicht, nicht Geschmack: es kippt den Ueberstand der Spur nach
   inline-start, und links liegender Ueberstand zaehlt in LTR nicht in scrollWidth.
   Mit `translateX(e * 100%)` ragte die Spur bei e=1 um eine volle Spaltenbreite nach
   rechts, und die Sonde in preview_check.py meldete gemessen auf ALLEN fuenf Viewports
   „div.wd-step +265..475px Element-Ueberstand" — eine Klammer am Container half nicht,
   weil die Sonde den scrollWidth des SCHRITTS misst, nicht den des Containers.
   Die Sichtbarkeitsformel haelt genau EINEN Caret auf dem Schirm: das Fenster ist
   36 % des Schrittwegs, der Versatz zum naechsten Schritt ist ebenso gross. */
/* Groesse, Fettung und Glow sind gemessen nachgezogen (02.08.2026): mit 16px/400 und
   schwachem Schatten kam der Caret bei 8x2px und einem Gruenwert von 160 heraus, waehrend
   die Schiene dahinter auf 230 stand — die fuehrende Kante war dunkler als ihre eigene
   Spur, und der Glow hob den Hintergrund um ganze 4 %. Er las sich als Strich-Artefakt,
   nicht als Terminal-Zeiger. Jetzt 22px/700 mit dreistufigem Schatten. */
.wd-rail .wd-step::after{content:"_";position:absolute;left:0;top:-4px;width:100%;
  font-family:var(--wd-mono);font-size:22px;font-weight:700;line-height:0;
  color:#7BFFC4;text-align:right;
  transform:translateX(calc((var(--wd-e-rule) - 1) * 100%));
  opacity:clamp(0,min(var(--wd-e-rule) * 9,(1 - var(--wd-e-rule)) * 9),1);
  text-shadow:0 0 6px rgba(25,230,138,1),0 0 16px rgba(25,230,138,.85),0 0 34px rgba(25,230,138,.5);
  pointer-events:none;will-change:transform,opacity}
/* Maske fuer die Ueberschrift. BLOCK, nicht inline-block: #wd-root h4 traegt
   overflow-wrap:anywhere, weil deutsche Komposita die 1fr-Spur sprengen — eine
   inline-block-Maske naehme dem h4 genau diese Umbruchfreiheit. `clip` statt `hidden`:
   kein Scroll-Container, kein Fokussprung. padding/margin heben sich auf, damit die
   Unterlaengen nicht abgeschnitten werden UND die Kachelhoehe sich nicht aendert. */
.wd-rail .wd-w{display:block;overflow:clip;padding-bottom:.14em;margin-bottom:-.14em}
.wd-rail .wd-lift{display:block}
/* Der Aufloese-Effekt am Mono-Label (wd-motion.js::terminalKopf). `is-scram` haengt NUR
   solange am Schritt, wie die Kopie tatsaechlich existiert — kein JS, kein Ghost, kein
   transparenter Text. white-space:pre haelt die Leerzeichen der Kopie exakt auf der Spur
   des Originals; die Kopie erbt die Gruppen-Opacity von .wd-n und ist damit von selbst
   dann unsichtbar, wenn das Label es ist. */
.wd-rail .wd-n{position:relative}
/* `right:0` + `overflow:clip` sind die Bremse, nicht die Optik: die Kopie ist absolut
   positioniert und wuerde bei jeder Laengenabweichung den scrollWidth des Schritts
   aufziehen. Genau das ist am 02.08.2026 passiert (doppelter Text, 43px Ueberstand auf
   `_04 — FEINSCHLIFF`). Die Ursache ist im Skript behoben; diese Zeile sorgt dafuer,
   dass ein kuenftiger Laengenfehler geklemmt wird statt das Raster zu verziehen. */
.wd-rail .wd-n-ghost{position:absolute;left:0;right:0;top:0;white-space:pre;overflow:clip;
  color:var(--wd-signal)}
.wd-rail .wd-step.is-scram .wd-n{color:transparent}

@media all{
  /* Die Kachel selbst steht still — Vorbild „Zaehler-Lauf" (Zeile 212). Sonst bewegen
     sich zwei Dinge gegeneinander und die Schiene verliert ihre Autoritaet.
     Spezifitaet (0,3,0) schlaegt `.js-motion .wd-reveal` (0,2,0). */
  .js-motion .wd-reveal.wd-rail{opacity:1;transform:none}

  /* --- EBENE 1: Basis, laeuft ueberall ------------------------------------------------
     linear auf dem TREIBER, und das ist begruendet: die Schiene ist ein Fahrzeug, kein
     ankommendes Element. Die Hauskurve sitzt eine Ebene tiefer, auf --wd-e-*.
     520ms Lauf + 3x190ms Versatz = 1.090ms gegen das 1.200ms-Fenster, das
     preview_check.py nach dem Forcieren abwartet. */
  .js-motion .wd-rail .wd-step{--wd-sp:0;transition:--wd-sp 520ms linear}
  .js-motion .wd-rail.is-in .wd-step{--wd-sp:1}
  /* :nth-child ist mit .wd-step qualifiziert: ein fuenfter Schritt oder umsortiertes
     Markup degradiert zu „zuendet mit Schritt 1", nie zum falschen Schritt. */
  .js-motion .wd-rail .wd-step:nth-child(2){transition-delay:190ms}
  .js-motion .wd-rail .wd-step:nth-child(3){transition-delay:380ms}
  .js-motion .wd-rail .wd-step:nth-child(4){transition-delay:570ms}

  /* --- EBENE 2: der Besucher FAEHRT die Schiene ---------------------------------------
     `cover` statt `entry`: entry umfasst nur die Eigenhoehe des Elements (bei 4 Spalten
     163px), das waere ein Wimpernschlag. cover spannt Viewport + Eigenhoehe.
     Bei 4 Spalten stehen alle vier Schritte auf derselben Hoehe — die Staffel MUSS dort
     aus dem Range-Versatz kommen. Bei 1 Spalte staffelt view() ohnehin von selbst und
     der Versatz faellt daneben nicht ins Gewicht.
     Versatz 10 % == Caret-Fenster (36 % von 26 %): nie zwei Carets gleichzeitig. */
  @supports (animation-timeline:view()){
    /* BEREICHSENDE = „steht ganz im Fenster". Ein Element ist bei
       cover = Eigenhoehe/(Fensterhoehe + Eigenhoehe) vollstaendig sichtbar — hier rund
       16 %. Der erste Wurf lief bis cover 42 %, und damit stand beim Deep-Link auf
       /#ablauf ein Schritt vollstaendig im Fold und trotzdem bei 11 % seines Wegs, also
       mit unsichtbarem Text. Ende jetzt bei 19 %: gezuendet ist, was man ganz sieht;
       gescrubbt wird, waehrend der Schritt von unten hereinkommt. */
    .js-motion .wd-rail .wd-step{animation:wd-sp-run linear both;animation-timeline:view();
      animation-range:cover 4% cover 19%}
    /* DER VERSATZ GILT NUR, WO SCHRITTE SICH EINE REIHE TEILEN. view() misst die Lage
       JEDES Schrittes einzeln — einspaltig staffelt es also von selbst, und ein
       zusaetzlicher nth-child-Versatz addiert sich obendrauf. Gemessen am 02.08.2026:
       mit dem Versatz auf allen Breiten stand beim Deep-Link auf /#ablauf bei 390px
       Schritt 2 auf 0,46 und die Schritte 3 und 4 auf 0 — wer genau auf diese Sektion
       verlinkt kam, sah drei leere Bloecke und musste erst weiterscrollen.
       Deshalb: einspaltig kein Versatz, zweispaltig zwei Takte (die zwei Reihen
       staffeln sich schon selbst), vierspaltig vier. */
    /* Versatz 6 %: das Caret-Fenster ist 36 % der 15-%-Spanne, also 5,4 % — der Versatz
       liegt darueber, damit nie zwei Carets gleichzeitig auf dem Schirm sind. */
    @media(min-width:601px){
      .js-motion .wd-rail .wd-step:nth-child(2),
      .js-motion .wd-rail .wd-step:nth-child(4){animation-range:cover 13% cover 28%}
    }
    @media(min-width:1025px){
      .js-motion .wd-rail .wd-step:nth-child(3){animation-range:cover 22% cover 37%}
      .js-motion .wd-rail .wd-step:nth-child(4){animation-range:cover 31% cover 46%}
    }
  }

  /* Jede Kurve wird am verbrauchenden Element gerechnet, aus dem geerbten --wd-sp.
     easeOutCubic (1-(1-p)^3) ist praktisch deckungsgleich mit der Hauskurve
     .22,.61,.36,1 und dieselbe Formel, die der Cine-Scrub schon benutzt. */
  .js-motion .wd-rail .wd-n{
    --wd-e-n:calc(1 - pow(1 - clamp(0,(var(--wd-sp) - .18)/.42,1),3));
    opacity:var(--wd-e-n);transform:translateY(calc((1 - var(--wd-e-n)) * -7px))}
  .js-motion .wd-rail .wd-lift{
    --wd-e-h:calc(1 - pow(1 - clamp(0,(var(--wd-sp) - .30)/.55,1),3));
    transform:translateY(calc((1 - var(--wd-e-h)) * 110%))}
  .js-motion .wd-rail .wd-step p{
    --wd-e-p:calc(1 - pow(1 - clamp(0,(var(--wd-sp) - .46)/.54,1),3));
    opacity:var(--wd-e-p);transform:translateY(calc((1 - var(--wd-e-p)) * 12px))}
}
@keyframes wd-sp-run{from{--wd-sp:0}to{--wd-sp:1}}
/* ④ Header bleibt sichtbar. Vorher blendete `html:has(…hero-intro-armed) #wd-header{opacity:0}`
   ihn samt Navigation und Kontakt-CTA fuer die Dauer des Vorspanns aus — das war die einzige
   Interaktionsmoeglichkeit auf dem ersten Screen. Der Durchflug bleibt fokussiert, weil das
   deckende Portal darueber liegt; der Header taucht auf, sobald das Portal wegblendet. */
#wd-header{transition:opacity .55s ease}
/* Touch-Targets >=44px: Footer- und Rechtslinks waren mit 12-16 Treffern je Seite unter 44px
   die am schwersten treffbaren Elemente — ausgerechnet Impressum, Datenschutz und AGB.
   Vertikales Padding auf inline-Links vergroessert die Trefferflaeche ohne Layout-Shift. */
/* `.wd-legal` ist Geschwister von `.wd-foot`, nicht Kind — der Selektor `.wd-foot .wd-legal a`
   aus dem Basis-CSS greift deshalb NICHT. Ueber #wd-footer angebunden. */
#wd-footer .wd-cols a{min-height:44px;display:flex;align-items:center;margin-top:0}
/* min-WIDTH ist kein Zusatz, sondern die zweite Kante von WCAG 2.5.8. Bis 01.08.2026 stand
   hier nur min-height — „AGB" mass damit 37x50px und bestand, weil der Pruefer nur die Hoehe
   las. Das kuerzeste Wort ist immer das erste Opfer. */
#wd-footer .wd-legal a{display:inline-flex;align-items:center;justify-content:center;min-height:44px;min-width:44px;padding:0 6px}
.wd-foot-contact a{display:inline-flex;align-items:center;min-height:44px}
.wd-contact-link{display:inline-flex;align-items:center;min-height:44px}
/* Sekundaerer Hero-/Kontakt-Knopf war 42px hoch */
#wd-root .wd-btn{min-height:44px}
/* Ueberschriften: langes Kompositum sprengte die H1 (gemessen bei 390px) */
#wd-root h1,#wd-root h2,#wd-root h3,#wd-root h4{overflow-wrap:anywhere;hyphens:auto;min-width:0}
/* Drucken: die Reveals stehen auf opacity:0, bis der IntersectionObserver feuert — beim Druck
   feuert er nie, ungescrollte Sektionen kamen leer aus dem Drucker. */
@media print{
  #wd-root .wd-reveal{opacity:1!important;transform:none!important}
  /* Das Cine-Band haengt nicht an .wd-reveal, sondern an --l, das der Scroll-Handler setzt.
     Beim Druck laeuft kein Scroll → Eyebrow, Headline und Subline kamen leer aus dem Drucker. */
  #wd-root .wd-cine [data-s]{--l:1!important}
  /* Gleiche Ursache beim Ablauf-Band: die Schiene haengt an --wd-sp, und
     `@media print{.wd-reveal{opacity:1}}` erreicht keine Custom Property. */
  #wd-root .wd-rail .wd-step{--wd-sp:1!important}
  /* Und dieselbe bei der Ledger-Liste — `.wd-reveal{opacity:1}` erreicht keine Custom
     Property, die sechs Leistungen kaemen sonst leer aus dem Drucker. */
  #wd-root .wd-lst .wd-lst-row{--wd-lp:1!important;--wd-lz:0!important}
  /* Die Motiv-Flaeche der schmalen Ansicht ist auf Papier nur Farbauftrag hinter Text —
     Schleier und Bild fliegen raus, die Zeile druckt als reine Tabelle. */
  #wd-root .wd-lst-img{display:none!important}
  #wd-root .wd-lst-a::after{display:none!important}
  /* Die Buehne ist auf Papier nur Farbauftrag — ein 470px-Motiv, das keine Zeile mehr
     auswaehlt, weil es beim Druck kein Scrollen und keinen Zeiger gibt. Die Liste
     druckt als Tabelle. */
  #wd-root .wd-buehne{display:none!important}
  #wd-root .wd-lst-split{display:block!important}
  #wd-root .wd-cine{height:auto!important}
  #wd-root .wd-cine-stage{position:relative!important;height:auto!important;min-height:0!important}
  #wd-header,#wd-mob-menu,.wd-mob-overlay,.wd-ham,#wd-scrollbar,.hero-portal,.hero-room,.wd-form{display:none!important}
  .wd-hero{min-height:auto}
}

/* ---- 2) Leistungs-/Rechtsseiten (Quelle: build_leistungen.py EXTRA_CSS) ---- */

/* ===== Leistungs-Unterseiten — Ergaenzungen ===== */
.wd-subhero{padding:62px 0 10px;border-bottom:1px solid var(--wd-hairline)}
.wd-crumb{font-family:var(--wd-mono);font-size:12px;letter-spacing:.06em;color:var(--wd-grey);display:inline-block}
.wd-crumb:hover{color:var(--wd-signal)}
/* Lange deutsche Komposita sprengen grosse Ueberschriften: „Leistungsbedingungen" ragte
   bei 390px um 84px aus dem Container. hyphens:auto trennt sauber (lang=de-DE steht am
   <html>), overflow-wrap:anywhere ist das Netz darunter. Gilt fuer ALLE Ueberschriften,
   nicht nur diese eine — der naechste lange Begriff kommt bestimmt. */
#wd-root h1,#wd-root h2,#wd-root h3,#wd-root h4{overflow-wrap:anywhere;hyphens:auto;min-width:0}
.wd-subhero h1{font-family:var(--wd-display);font-weight:800;letter-spacing:-.03em;line-height:1;font-size:clamp(2.3rem,6vw,4rem);margin:14px 0 0}
.wd-subhero .wd-lead{font-size:1.25rem;max-width:700px;margin-top:18px}
.wd-rich{max-width:840px;color:rgba(245,245,243,.82);font-size:1.08rem;line-height:1.72}
.wd-rich p{margin:0 0 15px}
.wd-rich strong{color:var(--wd-warmwhite)}
.wd-flist{list-style:none;margin:14px 0 0;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:10px 30px}
.wd-flist li{position:relative;padding-left:24px;color:rgba(245,245,243,.78);font-size:1.02rem;min-width:0;overflow-wrap:anywhere}
.wd-flist li::before{content:"_";position:absolute;left:0;color:var(--wd-signal);font-family:var(--wd-mono)}
/* Rahmenbedingungen: Honesty-Box als Faktentafel (Titel + Text) */
.wd-honesty .wd-h-t{font-family:var(--wd-mono);font-weight:500;font-size:12px;line-height:1.4;letter-spacing:.08em;text-transform:uppercase;color:var(--wd-signal);margin:0 0 8px}
.wd-honesty p{color:rgba(245,245,243,.8);font-size:1.02rem;margin:0;line-height:1.62}
.wd-honesty + .wd-honesty{margin-top:14px}
/* CTA-Band am Seitenende */
.wd-ctaband{background:var(--wd-surface-1);border:1px solid var(--wd-hairline);border-left:2px solid var(--wd-signal);border-radius:var(--wd-radius);padding:30px 32px;display:flex;justify-content:space-between;align-items:center;gap:24px;flex-wrap:wrap}
.wd-ctaband h3{font-family:var(--wd-display);font-weight:800;font-size:clamp(1.3rem,2.6vw,1.8rem);letter-spacing:-.02em;margin:0}
.wd-ctaband p{color:var(--wd-grey);margin:7px 0 0;font-size:1rem;max-width:520px}
/* Klickbare Karten (Hub + Startseite): Mehr-erfahren-Hinweis */
.wd-card .wd-go{display:inline-block;margin-top:14px;font-family:var(--wd-mono);font-size:12px;letter-spacing:.06em;color:var(--wd-signal)}
.wd-card:hover .wd-go{color:#28f29a}
@media(max-width:600px){
  .wd-flist{grid-template-columns:1fr}
  .wd-ctaband{flex-direction:column;align-items:stretch}
  .wd-ctaband .wd-btn{width:100%;justify-content:center}
  .wd-subhero{padding:46px 0 8px}
}
/* Legal-/AGB-Prosa (wie Impressum/Datenschutz) */
/* Lesespalte in ch kalibriert, nicht in px — 840px ergaben bis zu 112 Zeichen je Zeile.
   Rechtsseiten sind die ausdrueckliche Ausnahme von der Content==Header-Breite-Regel. */
.wd-prose{max-width:68ch;color:rgba(245,245,243,.82);font-size:1.04rem;line-height:1.72}
/* Inhaltsverzeichnis der AGB */
.wd-toc{background:var(--wd-surface-1);border:1px solid var(--wd-hairline);border-left:2px solid var(--wd-signal);border-radius:var(--wd-radius);padding:20px 24px;margin:0 0 34px}
.wd-toc h2{font-family:var(--wd-mono)!important;font-weight:500!important;font-size:12px!important;letter-spacing:.08em;text-transform:uppercase;color:var(--wd-signal)!important;margin:0 0 10px!important}
.wd-toc ol{margin:0;padding-left:18px;color:var(--wd-grey)}
.wd-toc li{margin:0}
.wd-toc a{display:inline-flex;align-items:center;min-height:44px;color:var(--wd-grey);text-decoration:none}
.wd-toc a:hover{color:var(--wd-signal);text-decoration:underline}
.wd-prose h2{font-family:var(--wd-display);font-weight:800;font-size:1.4rem;letter-spacing:-.02em;color:var(--wd-warmwhite);margin:38px 0 10px}
.wd-prose h3{font-family:var(--wd-mono);font-weight:500;text-transform:uppercase;letter-spacing:.08em;font-size:13px;color:var(--wd-signal);margin:24px 0 6px}
.wd-prose p{margin:0 0 14px}
.wd-prose a{color:var(--wd-signal);text-decoration:underline;text-underline-offset:2px}
.wd-prose ul{margin:0 0 16px;padding-left:20px}
.wd-prose li{margin:5px 0}
.wd-prose strong{color:var(--wd-warmwhite)}
.wd-prose .wd-note{color:var(--wd-grey);font-size:.95rem;background:var(--wd-surface-1);border:1px solid var(--wd-hairline);border-left:2px solid var(--wd-signal);border-radius:var(--wd-radius);padding:14px 16px}
.wd-prose .wd-legal-meta{font-family:var(--wd-mono);font-size:12px;color:var(--wd-grey);letter-spacing:.04em;margin-top:36px;border-top:1px solid var(--wd-hairline);padding-top:18px}
/* FAQ — native details/summary, kein JS */
.wd-faq{margin-top:34px;display:flex;flex-direction:column;gap:12px;max-width:880px}
.wd-faq details{background:var(--wd-surface-1);border:1px solid var(--wd-hairline);border-radius:var(--wd-radius);overflow:hidden}
.wd-faq summary{cursor:pointer;list-style:none;padding:18px 22px;font-family:var(--wd-display);font-weight:800;font-size:1.08rem;letter-spacing:-.01em;color:var(--wd-warmwhite);display:flex;justify-content:space-between;align-items:center;gap:14px}
.wd-faq summary::-webkit-details-marker{display:none}
.wd-faq summary::after{content:"+";font-family:var(--wd-mono);color:var(--wd-signal);font-size:1.3rem;transition:.18s}
.wd-faq details[open] summary::after{transform:rotate(45deg)}
.wd-faq details[open] summary{color:var(--wd-signal)}
.wd-faq p{margin:0;padding:0 22px 20px;color:rgba(245,245,243,.74);font-size:1.02rem;line-height:1.6}
/* Rechtszeile im Footer — liegt hier als Geschwister von .wd-foot, der Basis-Selektor
   `.wd-foot .wd-legal` aus der Startseite greift deshalb NICHT. */
#wd-footer .wd-legal{margin-top:30px;font-family:var(--wd-mono);font-size:11px;color:var(--wd-grey);letter-spacing:.04em}
#wd-footer .wd-legal b{color:var(--wd-fresh)}
/* Touch-Targets >=44px. Impressum/Datenschutz/AGB waren auf dem Handy die am schwersten
   treffbaren Elemente der Seite — ausgerechnet die Vertrauensbelege.
   Vertikales Padding auf inline-Links vergroessert die Trefferflaeche ohne Layout-Shift. */
/* Zweite Kante (01.08.2026): ohne min-width mass „AGB" 37x50px und bestand, weil der
   Pruefer nur die Hoehe las. Das kuerzeste Wort ist immer das erste Opfer. */
#wd-footer .wd-legal a{color:var(--wd-grey);padding:16px 8px;display:inline-flex;align-items:center;justify-content:center;min-height:44px;min-width:44px}
#wd-footer .wd-legal a:hover{color:var(--wd-warmwhite)}
#wd-footer .wd-cols a{min-height:44px;display:flex;align-items:center;margin-top:0}
.wd-crumb{display:inline-flex;align-items:center;min-height:44px}
/* Drucken: die Reveals stehen auf opacity:0, bis der IntersectionObserver feuert — beim
   Druck feuert er nie. Ohne diese Regel druckt jede ungescrollte Sektion leer, inklusive
   des kompletten AGB-Klauseltexts. */
@media print{
  #wd-root .wd-reveal{opacity:1!important;transform:none!important}
  #wd-header,#wd-mob-menu,.wd-mob-overlay,.wd-ham,.wd-ctaband,#wd-scrollbar{display:none!important}
  .wd-prose,.wd-rich,.wd-honesty p{color:#000}
  a[href^="/"]::after{content:" (https://digital.hans-wagner.de" attr(href) ")";font-size:.8em}
}

/* ---- 3) Nur-Legal-Regeln (Quelle: build_legal.py, entdoppelt) ---- */

/* self-hosted Fonts (DSGVO: 0 externe Calls) */
@font-face{font-family:'Montserrat';font-style:normal;font-weight:700;font-display:swap;src:url('https://digital.hans-wagner.de/wp-content/uploads/fonts/montserrat-700.woff2') format('woff2')}
@font-face{font-family:'Montserrat';font-style:normal;font-weight:800;font-display:swap;src:url('https://digital.hans-wagner.de/wp-content/uploads/fonts/montserrat-800.woff2') format('woff2')}
@font-face{font-family:'Source Sans 3';font-style:normal;font-weight:400;font-display:swap;src:url('https://digital.hans-wagner.de/wp-content/uploads/fonts/source-sans-3-400.woff2') format('woff2')}
@font-face{font-family:'Source Sans 3';font-style:normal;font-weight:600;font-display:swap;src:url('https://digital.hans-wagner.de/wp-content/uploads/fonts/source-sans-3-600.woff2') format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;src:url('https://digital.hans-wagner.de/wp-content/uploads/fonts/jetbrains-mono-500.woff2') format('woff2')}
:root{
  --wd-night:#0B0B0C; --wd-anthracite:#16181B; --wd-surface-1:#1C1F22;
  --wd-hairline:rgba(245,245,243,.08); --wd-signal:#19E68A; --wd-fresh:#049B4E;
  --wd-warmwhite:#F5F5F3; --wd-grey:#8B9197;
  --wd-display:'Montserrat','Segoe UI',sans-serif; --wd-body:'Source Sans 3',sans-serif;
  --wd-mono:'JetBrains Mono','Courier New',monospace; --wd-radius:10px; --wd-maxw:1180px;
  --wd-gutter:32px;
  --wd-header-h:68px;
}
html,body{background:var(--wd-night)!important}
html{scroll-behavior:smooth;scroll-padding-top:calc(var(--wd-header-h) + 12px)}
#wd-root [id]{scroll-margin-top:calc(var(--wd-header-h) + 12px)}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0}
.wd-canvas,.wp-block-post-content{margin:0!important;max-width:none!important}
#wd-root *{box-sizing:border-box}
/* `overflow-x:hidden` hier entfernt (28.07.2026). Diese zweite #wd-root-Deklaration ist ein
   Rest aus der Zusammenlegung der drei fruueheren CSS-Quellen; sie steht spaeter in der Datei
   und hat die erste ueberschrieben. `hidden` auf einer Achse rechnet die andere auf `auto`
   hoch — #wd-root wurde damit zum Scroll-Container, und `position:sticky` am Kopfband klebte
   an ihm statt am Viewport. Gemessen: bei scrollY 900 stand der Header auf top -861.
   Die Klammer gegen den 58-px-Overscan der Hero-Parallaxe macht `clip` weiter oben —
   `clip` erzeugt keinen Scroll-Container und laesst sticky in Ruhe. */
#wd-root{background:var(--wd-night);color:var(--wd-warmwhite);font-family:var(--wd-body);font-size:17px;line-height:1.6;-webkit-font-smoothing:antialiased;position:relative}
#wd-root a{color:inherit;text-decoration:none}
.wd-wrap{max-width:var(--wd-maxw);margin:0 auto;padding:0 var(--wd-gutter)}
.wd-eyebrow{font-family:var(--wd-mono);font-weight:500;font-size:13px;letter-spacing:.18em;text-transform:uppercase;color:var(--wd-signal)}
@keyframes wd-blink{0%,45%{opacity:1}50%,95%{opacity:0}100%{opacity:1}}
/* WCAG 2.2.2 (Level A): automatisch startende Bewegung braucht nach 5s einen Stopp.
   4 Blinks beim Ankommen, danach Ruhe; auf Hover ueber dem Kopf laeuft es weiter. */
.wd-blink{animation:wd-blink 1s steps(1,end) 4}
#wd-header:hover .wd-blink,#wd-header:focus-within .wd-blink{animation:wd-blink 1s steps(1,end) infinite}
.wd-c{color:var(--wd-signal)}
/* HEADER — zweite, aeltere Kopie desselben Blocks. Sie muss mitgezogen werden: stuende hier
   noch rgba(...,.92), gaebe die spaetere Regel das Glas zurueck und der Fix waere wirkungslos. */
#wd-header{position:sticky;top:0;z-index:100;background:var(--wd-night);border-bottom:1px solid var(--wd-hairline)}
.wd-nav{display:flex;align-items:center;justify-content:space-between;height:var(--wd-header-h);gap:12px}
/* Touch-Targets auch im Handy-Querformat (844x390): dort ist .wd-menu sichtbar und die
   Links waren 21px hoch. Das Kopfband ist ohnehin hoeher — kostet kein Layout. */
.wd-brand{font-family:var(--wd-display);font-weight:800;font-size:22px;letter-spacing:-.02em;min-height:44px;display:inline-flex;align-items:center;white-space:nowrap;flex:0 0 auto}
.wd-menu{display:flex;gap:30px;font-family:var(--wd-mono);font-size:13px;letter-spacing:.04em;color:var(--wd-grey);text-transform:uppercase}
.wd-menu a{min-height:44px;display:inline-flex;align-items:center}
.wd-menu a:hover{color:var(--wd-warmwhite)}
.wd-btn{font-family:var(--wd-display);font-weight:800;font-size:14px;letter-spacing:.02em;text-transform:uppercase;border-radius:var(--wd-radius);padding:11px 20px;display:inline-flex;align-items:center;gap:8px;transition:.18s;cursor:pointer;border:1px solid transparent}
.wd-btn-primary{background:var(--wd-signal);color:var(--wd-night)}
.wd-btn-primary:hover{background:#28f29a;transform:translateY(-1px)}
/* LEGAL PROSE */
.wd-legal{padding:64px 0 90px;min-height:62vh}
.wd-legal-head{margin-bottom:38px}
/* Lange deutsche Komposita sprengen grosse Ueberschriften (bei 390px gemessen).
   hyphens:auto trennt sauber (lang=de-DE am <html>), overflow-wrap:anywhere ist das Netz. */
#wd-root h1,#wd-root h2,#wd-root h3,#wd-root h4{overflow-wrap:anywhere;hyphens:auto;min-width:0}
.wd-legal-title{font-family:var(--wd-display);font-weight:800;letter-spacing:-.03em;line-height:1;font-size:clamp(2.4rem,6vw,3.6rem);margin:12px 0 0}
/* Lesespalte in ch statt px — 780px ergaben bis zu 112 Zeichen je Zeile.
   Rechtsseiten sind die ausdrueckliche Ausnahme von der Content==Header-Breite-Regel. */
.wd-prose{max-width:68ch;color:rgba(245,245,243,.82);font-size:1.02rem;line-height:1.72}
.wd-prose h2{font-family:var(--wd-display);font-weight:800;font-size:1.4rem;letter-spacing:-.02em;color:var(--wd-warmwhite);margin:40px 0 10px}
.wd-prose h3{font-family:var(--wd-mono);font-weight:500;text-transform:uppercase;letter-spacing:.08em;font-size:13px;color:var(--wd-signal);margin:26px 0 6px}
.wd-prose p{margin:0 0 14px}
.wd-prose a{color:var(--wd-signal);text-decoration:underline;text-underline-offset:2px}
.wd-prose a:hover{color:#28f29a}
.wd-prose ul{margin:0 0 16px;padding-left:20px}
.wd-prose li{margin:5px 0}
.wd-prose strong{color:var(--wd-warmwhite)}
.wd-prose .wd-addr{font-style:normal;background:var(--wd-surface-1);border:1px solid var(--wd-hairline);border-left:2px solid var(--wd-signal);border-radius:var(--wd-radius);padding:16px 18px;margin:0 0 18px}
.wd-prose .wd-note{color:var(--wd-grey);font-size:.95rem}
.wd-legal-meta{font-family:var(--wd-mono);font-size:12px;color:var(--wd-grey);letter-spacing:.04em;margin-top:40px;border-top:1px solid var(--wd-hairline);padding-top:18px}
/* FOOTER */
#wd-footer{border-top:1px solid var(--wd-hairline);padding:46px 0 60px}
.wd-foot{display:flex;justify-content:space-between;align-items:flex-start;gap:30px;flex-wrap:wrap}
.wd-foot .wd-brand{font-size:26px}
.wd-foot .wd-cols{display:flex;gap:60px;font-size:.95rem;color:var(--wd-grey)}
.wd-foot .wd-cols a{display:block;margin-top:8px}
.wd-foot .wd-cols a:hover{color:var(--wd-warmwhite)}
.wd-foot .wd-legal{margin-top:30px;font-family:var(--wd-mono);font-size:11px;color:var(--wd-grey);letter-spacing:.04em}
.wd-foot .wd-legal a{color:var(--wd-grey)}
.wd-foot .wd-legal a:hover{color:var(--wd-warmwhite)}
.wd-foot .wd-legal b{color:var(--wd-fresh)}
/* Rechtszeile liegt als Geschwister von .wd-foot — `.wd-foot .wd-legal` greift hier NICHT. */
#wd-footer .wd-legal{margin-top:30px;font-family:var(--wd-mono);font-size:11px;color:var(--wd-grey);letter-spacing:.04em}
#wd-footer .wd-legal b{color:var(--wd-fresh)}
/* Touch-Targets >=44px — Impressum/Datenschutz/AGB waren auf dem Handy die am schwersten
   treffbaren Elemente. Vertikales Padding vergroessert die Trefferflaeche ohne Layout-Shift. */
/* Zweite Kante (01.08.2026): ohne min-width mass „AGB" 37x50px und bestand, weil der
   Pruefer nur die Hoehe las. Das kuerzeste Wort ist immer das erste Opfer. */
#wd-footer .wd-legal a{color:var(--wd-grey);padding:16px 8px;display:inline-flex;align-items:center;justify-content:center;min-height:44px;min-width:44px}
#wd-footer .wd-legal a:hover{color:var(--wd-warmwhite)}
#wd-footer .wd-cols a{min-height:44px;display:flex;align-items:center;margin-top:0}
/* HAMBURGER MOBILE NAV — unter 834px ist .wd-menu aus; ohne dieses Markup fuehrt aus einem
   langen Rechtstext kein Weg zurueck ausser Footer-Links unter 44px. */
.wd-ham{display:none;flex-direction:column;justify-content:center;gap:5px;cursor:pointer;background:transparent;border:none;padding:8px 6px;margin-left:8px;min-height:44px;min-width:44px;align-items:center}
.wd-ham span{display:block;width:22px;height:2px;background:var(--wd-warmwhite);transition:transform .22s cubic-bezier(.22,.61,.36,1),opacity .18s}
.wd-ham.open span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.wd-ham.open span:nth-child(2){opacity:0;transform:scaleX(0)}
.wd-ham.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
.wd-mob-menu{position:fixed;top:var(--wd-header-h);right:-270px;width:260px;bottom:0;background:var(--wd-anthracite);border-left:1px solid var(--wd-hairline);transition:right .28s cubic-bezier(.22,.61,.36,1);z-index:99;padding:20px;display:flex;flex-direction:column;overflow-y:auto}
.wd-mob-menu .wd-mob-cta{background:var(--wd-signal);color:var(--wd-night);font-family:var(--wd-display);font-weight:800;font-size:14px;letter-spacing:.02em;text-transform:uppercase;border-radius:var(--wd-radius);padding:0 18px;min-height:48px;display:flex;align-items:center;justify-content:center;gap:8px;border-bottom:none;margin-bottom:14px}
.wd-mob-menu .wd-mob-cta .wd-c{color:var(--wd-night)}
.wd-mob-menu .wd-mob-cta:hover,.wd-mob-menu .wd-mob-cta:focus{color:var(--wd-night);background:#28f29a}
.wd-mob-menu a{padding:15px 6px;min-height:44px;display:flex;align-items:center;font-family:var(--wd-mono);font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:var(--wd-grey);border-bottom:1px solid var(--wd-hairline);transition:color .18s}
.wd-mob-menu a:last-child{border-bottom:none}
.wd-mob-menu a:hover,.wd-mob-menu a:focus{color:var(--wd-warmwhite);outline:none}
.wd-mob-overlay{position:fixed;inset:0;background:rgba(11,11,12,.72);z-index:98;opacity:0;pointer-events:none;transition:opacity .25s}
.wd-mob-menu.open{right:0}
.wd-mob-overlay.open{opacity:1;pointer-events:auto}
/* Ueber 834px gibt es den Hamburger nicht — dann hat auch das geparkte Panel nichts im
   Dokument zu suchen (Ueberstand + Fokus-Ziel). */
@media(min-width:835px){.wd-mob-menu,.wd-mob-overlay{display:none}}
/* Inhaltsverzeichnis */
.wd-toc{background:var(--wd-surface-1);border:1px solid var(--wd-hairline);border-left:2px solid var(--wd-signal);border-radius:var(--wd-radius);padding:20px 24px;margin:0 0 34px}
.wd-toc h2{font-family:var(--wd-mono)!important;font-weight:500!important;font-size:12px!important;letter-spacing:.08em;text-transform:uppercase;color:var(--wd-signal)!important;margin:0 0 10px!important;border:none!important;padding:0!important}
.wd-toc ol{margin:0;padding-left:18px;color:var(--wd-grey)}
.wd-toc li{margin:0}
.wd-toc a{display:inline-flex;align-items:center;min-height:44px;color:var(--wd-grey);text-decoration:none}
.wd-toc a:hover{color:var(--wd-signal);text-decoration:underline}
/* Liste, deren Eintraege ihre Nummer schon im Text tragen (AGB-Klauseln). */
.wd-toc ol.wd-toc-self{list-style:none;padding-left:0}
/* RESPONSIVE — Seitenrand global via --wd-gutter (identisch zur Landing) */
@media(max-width:1024px){:root{--wd-gutter:28px}.wd-legal{padding:56px 0 80px}}
@media(max-width:834px){.wd-menu{display:none}.wd-ham{display:flex}.wd-nav-cta-x{display:none}.wd-nav-cta{padding:11px 14px}}
@media(max-width:600px){:root{--wd-gutter:20px;--wd-header-h:56px}.wd-legal{padding:44px 0 70px}.wd-legal-title{font-size:clamp(2rem,9vw,2.8rem)}.wd-brand{font-size:17px}.wd-nav-cta{display:none}}
@media(max-width:380px){:root{--wd-gutter:16px}}
/* Drucken: Chrome raus, Rechtstext lesbar. Auf diesen Seiten gibt es keine Reveals, die
   Regel haelt den Druck aber mit den uebrigen Seiten konsistent. */
@media print{
  #wd-header,#wd-mob-menu,.wd-mob-overlay,.wd-ham,.wd-toc{display:none!important}
  .wd-prose{max-width:none;color:#000}
  #wd-root .wd-reveal{opacity:1!important;transform:none!important}
}

/* ============================================================================
   4) REDESIGN 28.07.2026 — Layout-Familien, erweiterte Typo-Skala, helles Band

   Gegen den Befund "ein Raster, ein Kartentyp, ein Taktwechsel auf 7.800 px":
   acht Sektionen liefen nach demselben Schema, einziger Unterschied war die
   Spaltenzahl. Sechs Familien loesen das strukturell.

   Regel beim Setzen der Sektionen: nie zwei benachbarte Sektionen derselben
   Familie, nie zwei benachbarte mit derselben vertikalen Polsterung.

     STAGE      full-bleed, das Medium ist der Grund      Padding 0
     STATEMENT  ein grosser Satz, keine Karte             clamp(120px,18vh,200px)
     CATALOG    das Kartenraster, genau 2x je Seite       96px
     INDEX      asymmetrischer Split, Sticky-Numeral      96px
     LEDGER     tabellarisch, Hairlines statt Karten      112px
     FORM       ruhig, Tier 0, kein Effekt                96px
   ============================================================================ */

/* ---- Typo-Stufen (CI-LOCK §2, Amendment 28.07.2026) ---- */
/* D0 steht im kritischen CSS (Hero, genau einmal je Seite). Hier D1 und das Numeral. */
.wd-d1{font-family:var(--wd-display);font-weight:800;letter-spacing:-.03em;line-height:.98;
  font-size:clamp(2.2rem,5.6vw,4.25rem);margin:0}
/* N Index-Numeral: Strukturelement, nicht Dekoration. tabular-nums ist Pflicht,
   sonst tanzen die Ziffern in der Sticky-Spalte beim Scrollen. */
.wd-num{font-family:var(--wd-mono);font-weight:500;font-variant-numeric:tabular-nums;
  font-size:clamp(2.5rem,7vw,5rem);line-height:1;letter-spacing:0;color:var(--wd-signal);display:block}

/* ---- STATEMENT ---- */
.wd-statement{padding:clamp(120px,18vh,200px) 0;background:var(--wd-anthracite);
  border-top:1px solid var(--wd-hairline);border-bottom:1px solid var(--wd-hairline)}
/* max-width in ch UND der Haus-Blowout-Schutz. 16ch waren zu eng: "Abstimmungsschleifen"
   ist laenger als die Spalte und ragte je nach Breite 25-45px heraus. Lange deutsche
   Komposita sind hier der Normalfall, nicht der Sonderfall. */
.wd-statement p{font-family:var(--wd-display);font-weight:800;letter-spacing:-.03em;line-height:1.08;
  font-size:clamp(1.9rem,4.6vw,3.4rem);max-width:20ch;color:var(--wd-warmwhite);margin:0;
  min-width:0;overflow-wrap:anywhere;hyphens:auto}
.wd-statement .wd-de-emph{color:var(--wd-grey)}
.wd-statement .wd-statement-sub{font-family:var(--wd-body);font-weight:400;font-size:1.15rem;
  line-height:1.6;color:rgba(245,245,243,.72);max-width:52ch;margin-top:32px;letter-spacing:0}

/* ---- LEDGER (dunkel) — Zeilen durch Hairlines, keine Karten ---- */
.wd-ledger{padding:112px 0}
/* Ohne border-bottom: die Linie traegt jetzt die Mono-Spaltenkopfzeile darunter
   (.wd-lst-kopf). Zwei Haarlinien uebereinander waren es sonst. */
.wd-ledger-head{display:flex;align-items:baseline;justify-content:space-between;gap:24px;flex-wrap:wrap;
  padding-bottom:14px}
.wd-ledger-note{font-family:var(--wd-mono);font-size:12px;letter-spacing:.06em;color:var(--wd-grey);
  max-width:46ch;line-height:1.6}
/* Der Zahlen-Riegel (.wd-zahlen/.wd-zahl*) und .wd-fussnote standen bis hier — beide ohne
   einen einzigen Markup-Treffer im Repo, seit `#zahlen` am 01.08.2026 rausflog. Ersetzt
   (nicht ergaenzt) durch die Ledger-Liste, die die Familie jetzt tatsaechlich benutzt. */

/* ---- LEDGER-Liste — die sechs Leistungen als Terminal-Listing (02.08.2026) ----
   Loest das Kartenraster in #leistungen ab. Zwei Gruende, beide aus der Doktrin:
   CI-LOCK deckelt CATALOG auf 2x/Seite und #pakete braucht den zweiten Slot; und der
   Block war die einzige Sektion der Seite ohne eigene Choreografie (Befund des
   UX-Audits vom 27.07.: „acht Sektionen, einziger Unterschied die Spaltenzahl").

   NULL Javascript. Die ganze Bewegung haengt an .wd-reveal/.is-in plus CSS. Genau
   deshalb laeuft sie auf /leistungen/ unveraendert mit: der Hub bringt zwar einen
   eigenen IntersectionObserver mit (build_leistungen.py::MOTION_JS), laedt aber weder
   anime.min.js noch wd-motion.js. Ein JS-Konzept haette dort einen zweiten Code-Pfad
   gebraucht — und das ist die Bauform, die am 30.07. die halbe Seite geleert hat. */
@property --wd-lp{syntax:'<number>';inherits:true;initial-value:1}
@property --wd-lp-n{syntax:'<number>';inherits:false;initial-value:1}
@property --wd-lp-h{syntax:'<number>';inherits:false;initial-value:1}
@property --wd-lp-p{syntax:'<number>';inherits:false;initial-value:1}
/* Vererbungsrichtung wie beim Rail-Lauf: --wd-lp lesen NACHFAHREN (::before, Numeral,
   .wd-lift, Preis, Text), also muss es vererben. Die drei Kurven werden am
   verbrauchenden Element selbst gerechnet und duerfen es nicht.
   initial-value:1 = Grundzustand IST Endzustand: no-JS, Druck, _MOTION AUS und jeder
   Browser ohne @property/pow() zeigen die volle Liste. Nie ein leeres Band. */

/* Spaltenkopf. Er ist der Grund, warum der Ruhezustand ein LEDGER ist und nicht eine
   Preisliste: er benennt die rechte Haelfte, die sonst zwischen Textende und Preis
   ueber ~500px leer laeuft. aria-hidden, weil er rein optisch gliedert — die Zeilen
   tragen ihre Bedeutung im Linktext. */
/* EINE Spaltendefinition fuer Kopf UND Zeile. Vorher war der Kopf ein flex mit
   space-between ueber die volle Breite — „AB · NETTO" endete dadurch 52px rechts vom
   letzten Preis, naemlich ueber der Chevron-Spalte. Ein Spaltenkopf, der auf eine
   Spalte ohne Zahlen zeigt, verfehlt genau seinen Zweck. Als geteilte Variable kann
   das nicht wieder auseinanderlaufen. */
.wd-lst-kopf,.wd-lst-a{--wd-lst-cols:[n] 4.5rem [t] minmax(0,1fr) [p] auto [go] 1.75rem}

.wd-lst-kopf{display:grid;grid-template-columns:var(--wd-lst-cols);column-gap:24px;
  align-items:baseline;
  font-family:var(--wd-mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(245,245,243,.34);padding-bottom:10px;border-bottom:1px solid var(--wd-hairline)}
.wd-lst-kopf span:first-child{grid-column:n/span 2}
.wd-lst-kopf span:last-child{grid-column:p;justify-self:end}

.wd-lst{list-style:none;margin:0;padding:0}
.wd-lst-row{margin:0}
/* Unten 20 statt 24: die letzte Beschreibungszeile bringt ihre eigene Leading mit,
   symmetrisch gesetzt klebt jede Zeile optisch an ihrer Trennlinie. */
.wd-lst-a{position:relative;display:grid;
  grid-template-columns:var(--wd-lst-cols);
  grid-template-rows:auto auto;column-gap:24px;align-items:baseline;
  padding:26px 0 20px;border-top:1px solid var(--wd-hairline);
  text-decoration:none;color:inherit;transition:opacity .2s ease}
.wd-lst-row:last-child .wd-lst-a{border-bottom:1px solid var(--wd-hairline)}
/* Die Kopfzeile bringt schon eine border-bottom mit — ohne das hier stuenden dort zwei
   Haarlinien uebereinander. */
.wd-lst-row:first-child .wd-lst-a{border-top:none}
/* Die gruene Kante zeichnet NUR bei Hover/Focus, nicht beim Reveal. Sechs gleichzeitig
   zeichnende Signalgruen-Linien waeren die Glow-Soup aus CI-LOCK §0 R2. Die Haarlinien
   stehen deshalb von Anfang an da — das leere Ledger-Blatt — und die EINTRAEGE
   schreiben sich hinein. So bleibt genau ein gruener Akzent pro Blick. */
.wd-lst-a::before{content:"";position:absolute;left:0;right:0;top:-1px;height:2px;
  background:var(--wd-signal);transform:scaleX(0);transform-origin:0 50%;
  transition:transform .32s cubic-bezier(.22,.61,.36,1);pointer-events:none}

.wd-lst-n{grid-column:n;grid-row:1;font-family:var(--wd-mono);font-weight:500;font-size:13px;
  letter-spacing:.1em;color:var(--wd-grey);font-variant-numeric:tabular-nums;
  transition:color .16s ease}
/* flex statt block, damit das BELIEBT-Signal NEBEN dem Namen sitzt statt darunter — und
   zwar ausserhalb der Maske. Innerhalb von .wd-w (overflow:clip) haette der Rahmen des
   Badges am Zeilenkasten beschnitten werden koennen. */
.wd-lst-t{grid-column:t;grid-row:1;display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;
  font-family:var(--wd-display);font-weight:800;
  font-size:clamp(1.25rem,2.4vw,1.75rem);letter-spacing:-.02em;line-height:1.15;
  color:var(--wd-warmwhite);min-width:0;
  transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.wd-lst-t .wd-w{min-width:0}
.wd-lst-tag{font-family:var(--wd-mono);font-weight:500;font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;font-style:normal;color:var(--wd-signal);
  border:1px solid var(--wd-signal);border-radius:var(--wd-radius-sm);
  padding:3px 7px;white-space:nowrap;flex:none;
  /* Baseline-Ausrichtung setzt den Textgrund buendig, durch Polsterung und Rahmen sitzt
     der Kasten dadurch optisch unter der x-Hoehe des Namens. Ein Pixel zurueck. */
  transform:translateY(-1px)}
/* Maske wie in #ablauf, aber eigens gescopet: .wd-w/.wd-lift sind im Haus NICHT global,
   sondern je Sektion definiert (.wd-rail, .wd-cine-h). Ohne diese zwei Zeilen gibt es
   nichts zu heben. overflow:clip klemmt, .wd-lift faehrt darin hoch. */
.wd-lst .wd-w{display:block;overflow:clip;padding-bottom:.14em;margin-bottom:-.14em}
.wd-lst .wd-lift{display:block}
/* tabular-nums ist Pflicht: ohne sie tanzt die Preisspalte beim Farbwechsel im Hover,
   und eine wandernde Zahl liest sich als Fehler. */
/* Preis in Mono, nicht in Montserrat: CI-LOCK §2 weist JetBrains Mono „Labels, DATEN" zu,
   und ein Preis in einem Ledger ist Datum, nicht Ueberschrift. Erst dadurch sieht man
   tabular-nums ueberhaupt — in einer Proportionalschrift verpufft der Effekt. */
.wd-lst-p{grid-column:p;grid-row:1;font-family:var(--wd-mono);font-weight:500;
  font-size:clamp(1.02rem,1.3vw,1.18rem);letter-spacing:.01em;color:rgba(245,245,243,.92);
  font-variant-numeric:tabular-nums;white-space:nowrap;transition:color .16s ease}
/* Ruhefarbe NEUTRAL. Sechs signalgruene Chevrons waren die Glow-Soup aus CI-LOCK §0 R2 —
   und sie tragen null Information, weil ohnehin jede Zeile ein Link ist. Gruen wird der
   Pfeil erst, wenn die Zeile aktiv ist. */
.wd-lst-go{grid-column:go;grid-row:1;justify-self:end;font-family:var(--wd-mono);
  font-size:15px;color:rgba(245,245,243,.30);
  transition:transform .22s cubic-bezier(.22,.61,.36,1),color .16s ease}
/* Beschreibung bleibt IMMER sichtbar. Ein Aufklapp-Akkordeon (grid-template-rows 0fr->1fr)
   waere die naheliegende Geste, animiert aber eine Layout-Eigenschaft pro Frame und
   versteckt Text vor Suchmaschinen und vor jedem Geraet ohne Hover. Das „Oeffnen"
   leistet stattdessen das Motiv — ohne einen einzigen Reflow. */
/* Ruecken beim Hover MIT dem Namen ein (gleiche Kurve, gleiche Distanz). Rueckte nur die
   Ueberschrift ein, brach die linke Kante des Textblocks mitten in der Zeile. */
/* Die Endlinie der Textspalte wird je Bauform gesetzt, NICHT hier allgemein: `t/go`
   umfasst dort, wo es eine Bildspalte gibt, auch diese — die Beschreibung lief dann unter
   dem Motiv durch und wurde bei 768px mitten im Wort verdeckt. Ein Zeilenfall schneidet nie
   mitten im Wort; das war Verdeckung, kein Umbruch. Auf dem Desktop blieb es unsichtbar,
   weil max-width:56ch den Text dort nie bis an die Spalte laufen laesst. */
.wd-lst-d{grid-row:2;font-size:1rem;line-height:1.6;max-width:56ch;
  color:rgba(245,245,243,.64);margin:8px 0 0;
  transition:color .2s ease,transform .22s cubic-bezier(.22,.61,.36,1)}

/* Motiv: eigene Rasterspalte statt position:absolute. Absolut positioniert haette es
   entweder den Preis verdeckt oder in die Nachbarzeile geragt; als reservierte Spalte
   kollidiert nichts, und weil sie immer da ist, gibt es beim Einwischen keinen
   Layout-Shift. Erst ab 1025px — darunter faellt auch der Hover-Block weg. */
.wd-lst-img{display:none}
@media(min-width:1025px){
  .wd-lst-kopf,.wd-lst-a{--wd-lst-cols:[n] 4.5rem [t] minmax(0,1fr) [img] 220px [p] auto [go] 1.75rem}
  .wd-lst-img{display:block;grid-column:img;grid-row:1/-1;align-self:center;justify-self:end;
    width:220px;aspect-ratio:16/9;border-radius:var(--wd-radius-sm);overflow:hidden;
    border:1px solid var(--wd-hairline);background:var(--wd-surface-1);
    clip-path:inset(0 100% 0 0);
    transition:clip-path .42s cubic-bezier(.22,.61,.36,1);pointer-events:none}
  .wd-lst-img img{width:100%;height:100%;object-fit:cover;display:block}
  .wd-lst-d{grid-column:t/img}
}

/* Hover-Zustand hinter (hover:hover) and (pointer:fine) — auf Touch gibt es keinen
   Schwebezustand, dort waere die Regel eine Falle statt einer Verbesserung.
   :focus-visible loest ueberall denselben Zustand aus; das Geschwister-Dimmen braucht
   deshalb ZWEI Selektoren, sonst waere die Tastatur zweite Klasse. */
@media (hover:hover) and (pointer:fine){
  .wd-lst-a:hover::before,.wd-lst-a:focus-visible::before{transform:scaleX(1)}
  .wd-lst-a:hover .wd-lst-n,.wd-lst-a:focus-visible .wd-lst-n{color:var(--wd-signal)}
  .wd-lst-a:hover .wd-lst-t,.wd-lst-a:focus-visible .wd-lst-t,
  .wd-lst-a:hover .wd-lst-d,.wd-lst-a:focus-visible .wd-lst-d{transform:translateX(10px)}
  .wd-lst-a:hover .wd-lst-p,.wd-lst-a:focus-visible .wd-lst-p{color:var(--wd-signal)}
  .wd-lst-a:hover .wd-lst-d,.wd-lst-a:focus-visible .wd-lst-d{color:rgba(245,245,243,.86)}
  .wd-lst-a:hover .wd-lst-go,.wd-lst-a:focus-visible .wd-lst-go{transform:translateX(5px);color:var(--wd-signal)}
  .wd-lst-a:hover .wd-lst-img,.wd-lst-a:focus-visible .wd-lst-img{clip-path:inset(0)}
  .wd-lst:hover .wd-lst-row:not(:hover) .wd-lst-a,
  .wd-lst:focus-within .wd-lst-row:not(:focus-within) .wd-lst-a{opacity:.45}
  /* Das BELIEBT-Badge dimmt ueber die Elterndeckkraft korrekt mit (gemessen: effektiv
     0,450 wie alles andere in der Zeile). Trotzdem zieht es den Blick: gesaettigtes
     Gruen ueberlebt eine Dimmung deutlich besser als graue Schrift, und dann sitzt der
     einzige Farbpunkt der Sektion in einer STILLGELEGTEN Zeile statt in der aktiven.
     Deshalb nimmt es zusaetzlich die Farbe zurueck — Gestaltung, nicht Fehlerbehebung. */
  .wd-lst:hover .wd-lst-row:not(:hover) .wd-lst-tag,
  .wd-lst:focus-within .wd-lst-row:not(:focus-within) .wd-lst-tag{
    color:rgba(245,245,243,.7);border-color:rgba(245,245,243,.22)}
}
@media(max-width:1024px){
  .wd-lst-d{color:rgba(245,245,243,.72)}
}
/* Einspaltig: Numeral vor den Namen, Preis unter den Namen. Die Zeile bleibt eine Zeile,
   sie faltet sich nur. */
@media(max-width:600px){
  /* Der Spaltenkopf verliert einspaltig seine Entsprechung — die rechte Beschriftung
     faellt weg statt ins Leere zu zeigen, und das Raster wird wieder Fluss. */
  .wd-lst-kopf{display:block}
  .wd-lst-kopf span:last-child{display:none}
  /* Der Preis bleibt auf Namenshoehe statt unter die Beschreibung zu rutschen. Zuletzt
     gelesen zu werden ist fuer die zentrale Zahl einer Preisliste die schwaechere
     Reihenfolge — auf Desktop steht er ja auch neben dem Namen. */
  /* Randlos + zurueckgegebenes padding-inline stehen im 1024er-Block; hier nur noch das
     einspaltige Raster und die Bandhoehe. */
  .wd-lst-a{grid-template-columns:[t] minmax(0,1fr) [p] auto [go] 1.5rem;
    grid-template-rows:auto auto auto;column-gap:14px;
    padding-block:30px 26px;min-height:152px;align-content:center}
  .wd-lst-n{grid-column:t/-1;grid-row:1;margin-bottom:8px}
  /* Groesser: der Name ist der Held der Zeile, 1.25rem war auf einem Foto zu zaghaft. */
  .wd-lst-t{grid-column:t;grid-row:2;font-size:clamp(1.35rem,5.4vw,1.7rem)}
  .wd-lst-p{grid-column:p;grid-row:2;justify-self:end;white-space:nowrap;
    font-size:1.02rem;color:var(--wd-warmwhite)}
  .wd-lst-go{grid-column:go;grid-row:2}
  .wd-lst-d{grid-column:t/go;grid-row:3}
}

/* ---- Ledger-Liste: Reveal, zwei Quellen ein Treiber ----
   Dasselbe Muster wie der Rail-Lauf, aber BEWUSST OHNE wanderndes Caret: das Device
   gehoert #ablauf, und CI-LOCK §4 laesst nie mehr als einen blinkenden Caret pro Screen.
   Die Haarlinien zeichnen hier auch nicht mit — sie stehen schon. Animiert wird nur,
   was in das leere Blatt hineingeschrieben wird. */
@media all{
  /* Die Liste selbst steht still, sonst faehrt der Sammel-Reveal ueber die Staffel drueber.
     Hoehere Spezifitaet als `.js-motion .wd-reveal` — gleiche Technik wie bei .wd-rail. */
  .js-motion .wd-reveal.wd-lst{opacity:1;transform:none}

  /* --- Ebene 1: Basis, laeuft ueberall --- */
  .js-motion .wd-lst .wd-lst-row{--wd-lp:0;transition:--wd-lp 460ms linear}
  .js-motion .wd-lst.is-in .wd-lst-row{--wd-lp:1}
  /* Versatz erst ab 601px. Einspaltig addiert er sich auf die natuerliche
     view()-Staffelung — beim Deep-Link auf /#leistungen stuenden sonst Zeilen leer.
     Gemessener Fehler 3 aus der #ablauf-Runde, hier vorweggenommen. */
  @media(min-width:601px){
    .js-motion .wd-lst .wd-lst-row:nth-child(2){transition-delay:70ms}
    .js-motion .wd-lst .wd-lst-row:nth-child(3){transition-delay:140ms}
    .js-motion .wd-lst .wd-lst-row:nth-child(4){transition-delay:210ms}
    .js-motion .wd-lst .wd-lst-row:nth-child(5){transition-delay:280ms}
    .js-motion .wd-lst .wd-lst-row:nth-child(6){transition-delay:350ms}
  }

  /* --- Ebene 2: der Besucher schreibt die Liste mit dem Scrollrad --- */
  @supports (animation-timeline:view()){
    .js-motion .wd-lst .wd-lst-row{animation:wd-lp-run linear both;
      animation-timeline:view();animation-range:cover 5% cover 22%}
  }

  /* Kurven am verbrauchenden Element, easeOutCubic aus dem geerbten --wd-lp.
     Reihenfolge im Takt: Numeral zuerst (die Zeile meldet sich), dann hebt der Name
     hinter der Maske, zuletzt blenden Preis und Beschreibung nach. */
  .js-motion .wd-lst .wd-lst-n{
    --wd-lp-n:calc(1 - pow(1 - clamp(0,var(--wd-lp)/.45,1),3));
    opacity:var(--wd-lp-n);transform:translateY(calc((1 - var(--wd-lp-n)) * -7px))}
  .js-motion .wd-lst .wd-lift{
    --wd-lp-h:calc(1 - pow(1 - clamp(0,(var(--wd-lp) - .12)/.6,1),3));
    transform:translateY(calc((1 - var(--wd-lp-h)) * 110%))}
  /* Chevron und BELIEBT-Badge MUESSEN hier mit drin stehen. Standen sie draussen, trugen
     sie ihre eigene Deckkraft 1 und blieben sichtbar, waehrend die Zeile noch leer war —
     gemessen: sechs freischwebende Signalgruen-Pfeile vor ungeschriebenen Zeilen. Ein
     Element ausserhalb der Reveal-Kurve ist nicht „unanimiert", es ist VORZEITIG da. */
  .js-motion .wd-lst .wd-lst-p,
  .js-motion .wd-lst .wd-lst-d,
  .js-motion .wd-lst .wd-lst-go,
  .js-motion .wd-lst .wd-lst-tag{
    --wd-lp-p:calc(1 - pow(1 - clamp(0,(var(--wd-lp) - .35)/.65,1),3));
    opacity:var(--wd-lp-p)}
}
@keyframes wd-lp-run{from{--wd-lp:0}to{--wd-lp:1}}

/* ---- Ledger unter 1025px: der Daumen zeigt statt der Maus (02.08.2026) ----
   Bis hierher war die Liste auf dem Handy eine reine Textliste: die Motiv-Spalte greift
   erst ab 1025px, Hover gibt es auf Touch nicht, der Versatz ist einspaltig aus. Damit
   verletzte ausgerechnet die meistbesuchte Ansicht CI-LOCK §0 R1 — „Foto ist der Held,
   nicht das Dunkel. Ohne Foto wirkt Dark-First steril."

   Die Uebersetzung ist nicht „Hover nachbauen", sondern das Zeigegeraet wechseln: was am
   Desktop der Mauszeiger auswaehlt, waehlt hier die SCROLLPOSITION. Die Zeile in der
   Bildschirmmitte ist die aktive — Motiv hellt auf, gruene Kante zeichnet, Index und Preis
   ziehen ins Signalgruen. Zweiter Treiber --wd-lz, 0 -> 1 -> 0 ueber die Sichtstrecke,
   Spitze exakt in der Mitte. Weiterhin 0 KB Javascript. */
@property --wd-lz{syntax:'<number>';inherits:true;initial-value:0}
/* EIN Treiber, DREI Kurven. Die erste Fassung haengte Kante und Farbe linear an --wd-lz —
   und weil ein stetiger Treiber immer mehrere Zeilen gleichzeitig teilweise aktiviert,
   standen vier verschieden lange gruene Halblinien uebereinander. Das ist die Bildsprache
   von „laedt noch", nicht von Gestaltung; am Desktop faellt es nicht auf, weil Hover binaer
   ist. Und ein Hue-Flip nach Gruen wird schon ab ~40 % Mischung als „gruen" gelesen, also
   trugen drei Zeilen gleichzeitig den Akzent.
     --wd-lzr  Schwelle ab 55 %  -> genau EINE Zeile zeichnet ihre Kante
     --wd-lzc  kubisch           -> Farbe konzentriert sich auf die Spitze
     --wd-lz   linear            -> nur noch Bildhelligkeit, die darf weich verlaufen */
@property --wd-lzr{syntax:'<number>';inherits:true;initial-value:0}
@property --wd-lzc{syntax:'<number>';inherits:true;initial-value:0}
@property --wd-lp-b{syntax:'<number>';inherits:false;initial-value:1}
@keyframes wd-lz-run{0%{--wd-lz:0}50%{--wd-lz:1}100%{--wd-lz:0}}

@media(max-width:1024px){
  /* Schwelle .70, nicht .55: auf dem Tablet sind die Zeilen niedriger, es liegen also mehr
     gleichzeitig im Sichtfenster und drei Kanten zeichneten parallel — dieselbe
     Ladebalken-Optik, nur eine Bildschirmgroesse weiter. Gemessen bei 768px: mit .55 waren
     es 3 zeichnende Kanten, mit .70 genau eine. */
  /* Schwelle .70 UND potenziert. Die Schwelle allein reichte nicht: im Uebergabemoment
     von einer Zeile zur naechsten lagen auf 768px zwei Kanten bei 0,57 und 0,50 — zwei
     gleich starke gruene Linien. Die dritte Potenz drueckt genau diesen Moment (0,50 -> 0,13)
     und laesst die Spitze stehen; der Faktor 1,4 holt die Spitze auf volle Staerke zurueck.
     Gemessen mobil: zweitstaerkste Kante faellt von 0,29 auf 0,04. */
  .wd-lst-row{
    --wd-lzr:clamp(0,calc(pow(clamp(0,calc((var(--wd-lz) - .70) / .28),1),3) * 1.4),1);
    --wd-lzc:calc(var(--wd-lz) * var(--wd-lz) * var(--wd-lz))}
  .wd-lst-img img{width:100%;height:100%;object-fit:cover;object-position:50% 45%}
  /* Kante an der Naehe zur Mitte statt am Zeiger, aber ueber die SCHWELLE — sonst
     Ladebalken-Optik (s.o.). transition:none, weil eine Uebergangszeit auf einem
     scroll-getriebenen Wert nur Nachlauf erzeugt: genau das Traege, wegen dem Lenis rausflog. */
  /* Volle Breite, Deckkraft statt scaleX. Mit scaleX blieb bei einer Nachbarzeile knapp
     ueber der Schwelle ein ~20px langer gruener Stummel am linken Rand stehen — als
     angefangene zweite Kante lesbar. Als Deckkraft ist derselbe Wert (0,03) schlicht
     unsichtbar, statt eine kurze Linie zu zeichnen. */
  .wd-lst-a::before{transform:scaleX(1);opacity:var(--wd-lzr);transition:none}
  .wd-lst-d{color:rgba(245,245,243,.80)}
  /* Das BELIEBT-Badge nimmt sonst Gruen fuer eine INAKTIVE Zeile in Anspruch: die
     Entgruenungs-Regel haengt am Hover, und den gibt es hier nicht. */
  .wd-lst-tag{color:color-mix(in oklab,var(--wd-signal) calc(var(--wd-lzc) * 100%),rgba(245,245,243,.62));
    border-color:color-mix(in oklab,var(--wd-signal) calc(var(--wd-lzc) * 100%),rgba(245,245,243,.20))}

  /* Das Motiv haengt AUCH an der Reveal-Kurve. Sonst steht es auf .20 da, waehrend Numeral,
     Name und Preis der Zeile noch unsichtbar sind — derselbe Fehler wie beim Chevron,
     siehe feedback_kind_ohne_kurve_erscheint_vorzeitig. */
  .js-motion .wd-lst .wd-lst-img{
    --wd-lp-b:calc(1 - pow(1 - clamp(0,(var(--wd-lp) - .2)/.8,1),3))}
  /* Die erste Zeile hat einen Boden. --wd-lz hat sein Maximum in der Bildschirmmitte —
     beim Ankommen in der Sektion steht die Flaggschiff-Zeile aber OBEN und zeigte deshalb
     kein Motiv. Der erste Eindruck war damit weiterhin „Textliste", also genau das, was
     der Umbau beseitigen sollte. */
  .wd-lst-row:first-child{--wd-lz-boden:.36}

  @supports (animation-timeline:view()){
    .js-motion .wd-lst .wd-lst-row{
      animation:wd-lp-run linear both,wd-lz-run linear both;
      animation-timeline:view(),view();
      animation-range:cover 5% cover 22%,cover 8% cover 92%}
  }
  /* Farbe folgt der Naehe. Faellt color-mix aus, bleiben die Ruhefarben stehen — die
     Sektion verliert dann Nuance, nie Lesbarkeit. */
  /* Farbe folgt der KUBISCHEN Kurve, damit der Akzent auf der Spitze bleibt statt sich auf
     drei Nachbarzeilen zu verteilen. Gezaehlt vor dieser Aenderung: 17 gruene Punkte in
     einem Blick — Eimer, nicht Skalpell (CI-LOCK §0 R2).
     Der CHEVRON bleibt dauerhaft neutral: er ist sechsmal da und trug damit allein sechs
     der 17 Punkte, ohne je Information zu tragen — dass die Zeile ein Link ist, sagt schon
     die ganze Zeile. Faellt color-mix aus, bleiben die Ruhefarben stehen; die Sektion
     verliert dann Nuance, nie Lesbarkeit. */
  @supports (color:color-mix(in oklab,red 50%,blue)){
    .wd-lst-n{color:color-mix(in oklab,var(--wd-signal) calc(var(--wd-lzc) * 100%),var(--wd-grey))}
    .wd-lst-p{color:color-mix(in oklab,var(--wd-signal) calc(var(--wd-lzc) * 66%),rgba(245,245,243,.92))}
  }
}

/* ---- 601..1024: Bildspalte wie am Desktop, aber vom Daumen getrieben ----
   Erster Wurf gab dem Tablet dieselbe Bildflaeche wie dem Handy. Das ging schief, und
   zwar strukturell: der Schleier „links dicht, rechts offen" ist fuer eine SCHMALE Zeile
   gerechnet. Auf 768px liegt der offene Teil ~570px vom Text entfernt — die dunkle linke
   Haelfte dominiert, das Motiv kommt nie an. Gemessen war die AKTIVE Tablet-Zeile dunkler
   als jede inaktive Zeile auf 390px; der Helligkeits-Cue trug also gar nichts, und der
   ganze Mechanismus haette allein am Gruen gehangen.
   Ab 601px ist Platz fuer eine eigene Spalte — also dieselbe Bauform wie am Desktop.
   Getrieben wird sie hier aber von der Naehe zur Bildschirmmitte statt vom Zeiger: auf
   einem Tablet gibt es keinen Hover, der sie je oeffnen wuerde. */
@media(min-width:601px) and (max-width:1024px){
  /* Schmaler als am Desktop, sonst frisst die Bildspalte die Namensspalte auf: bei 768px
     bleiben nach Index, Bild, Preis und Chevron sonst nur ~226px fuer den Namen. */
  .wd-lst-kopf,.wd-lst-a{--wd-lst-cols:[n] 3.5rem [t] minmax(0,1fr) [img] 160px [p] auto [go] 1.75rem;
    column-gap:18px}
  .wd-lst-img{display:block;grid-column:img;grid-row:1/-1;align-self:center;justify-self:end;
    width:160px;aspect-ratio:16/9;border-radius:var(--wd-radius-sm);overflow:hidden;
    border:1px solid var(--wd-hairline);background:var(--wd-surface-1);
    transition:none;opacity:1;
    clip-path:inset(0 calc((1 - var(--wd-lzr)) * 100%) 0 0)}
  /* Textspalte endet HART vor dem Bildkasten — echte Rasterspur statt Ueberlagerung. */
  .wd-lst-d{grid-column:t/img}
}

/* ---- bis 600: das Motiv IST die Zeile ---- */
@media(max-width:600px){
  /* RANDLOS. Auf 390px waere eine in den Satzspiegel eingerueckte Bildflaeche eine
     Briefmarke — hier ist der Bildschirmrand der Rahmen. */
  .wd-lst-a{margin-inline:calc(var(--wd-gutter) * -1);padding-inline:var(--wd-gutter)}
  .wd-lst-img{display:block;position:absolute;inset:0;z-index:0;
    width:auto;aspect-ratio:auto;border:0;border-radius:0;clip-path:none;background:none;
    transition:none}
  /* Der Schleier haelt links dicht (dort steht der Text) und oeffnet nach rechts, wo im
     Motiv der gruene Lichtpunkt sitzt.
     Seine Deckkraft LAEUFT MIT: vorher wurde das Bild heller, der Schleier blieb konstant —
     der Kontrast war damit ausgerechnet auf der AKTIVEN Zeile am schlechtesten. Getrieben
     wird die Deckkraft des Pseudo-Elements, nicht die Alphawerte der Farbstopps: sonst
     rechnet der Browser den Verlauf je Frame neu, statt nur eine Ebene zu komponieren. */
  .wd-lst-a::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
    background:linear-gradient(100deg,rgba(11,11,12,.99) 0%,rgba(11,11,12,.95) 42%,
      rgba(11,11,12,.82) 76%,rgba(11,11,12,.60) 100%);
    opacity:calc(.84 + var(--wd-lz) * .16)}
  .wd-lst-n,.wd-lst-t,.wd-lst-p,.wd-lst-go,.wd-lst-d{position:relative;z-index:2}
  /* Bildhelligkeit haengt AUCH an der Reveal-Kurve — sonst steht das Motiv da, waehrend die
     Zeile selbst noch ungeschrieben ist (feedback_kind_ohne_kurve_erscheint_vorzeitig). */
  .js-motion .wd-lst .wd-lst-img{
    opacity:calc((.26 + max(var(--wd-lz),var(--wd-lz-boden,0)) * .56) * var(--wd-lp-b))}
  /* Abschlusskante: ohne sie endet die Bildband-Kette unten hart auf Schwarz. */
  .wd-lst-row:last-child .wd-lst-a{border-bottom-color:rgba(245,245,243,.14)}
}

/* ================================================================================
   BUEHNE — die tote rechte Haelfte wird ein Schaufenster (>=1025px, 02.08.2026)
   ================================================================================
   Befund, der den Umbau traegt (live gemessen 1440x900, Ruhezustand):
   die 220px-Motivspalte stand auf `clip-path: inset(0 100% 0 0)` und oeffnete NUR bei
   Hover — ohne Maus zeigte der Desktop sechs Textzeilen und null Bilder. Damit verletzte
   ausgerechnet die Desktop-Ansicht CI-LOCK §0 R1 („Foto ist der Held"), also derselbe
   Fehler, der einen Tag vorher fuer Mobil behoben wurde. Dazu ~430px Totflaeche zwischen
   Textende und Preisspalte, ueber 1.570px Sektionshoehe.

   Der Hebel ist deshalb NICHT mehr Bewegung, sondern eine andere Bauform: die Liste
   behaelt ihre Hoehe, rechts klebt eine Buehne mit sechs gestapelten Motiven. Was am
   Desktop der Mauszeiger auswaehlt, waehlt ohne Maus die Scrollposition — dieselbe
   Uebersetzung wie mobil, nur ein Zeigegeraet weiter.

   WEITERHIN 0 BYTES JAVASCRIPT. Das ist die Bedingung dafuer, dass /leistungen/ mitkommt:
   der Hub bringt einen eigenen IntersectionObserver mit, laedt aber weder anime.min.js
   noch wd-motion.js. Ein JS-Konzept waere dort ein zweiter Code-Pfad — genau die Bauform,
   die am 30.07.2026 die halbe Seite geleert hat.

   Bildlast bleibt EIN Satz pro Viewport: ab 1025px faellt .wd-lst-img weg (display:none
   + loading="lazy" ⇒ kein Abruf), darunter faellt die Buehne weg. Nie beide. */

@property --wd-bp{syntax:'<number>';inherits:true;initial-value:0}
@property --wd-t{syntax:'<number>';inherits:true;initial-value:0}
@property --wd-hov{syntax:'<number>';inherits:true;initial-value:0}
@property --wd-hi{syntax:'<number>';inherits:true;initial-value:0}
@property --wd-ri{syntax:'<number>';inherits:true;initial-value:0}
@property --wd-bi{syntax:'<number>';inherits:true;initial-value:0}
@property --wd-bo{syntax:'<number>';inherits:true;initial-value:0}
@property --wd-act{syntax:'<number>';inherits:true;initial-value:0}
@property --wd-actr{syntax:'<number>';inherits:true;initial-value:0}
@property --wd-actc{syntax:'<number>';inherits:true;initial-value:0}
/* Alle inherits:true. Der Fehler vom 02.08. — `inherits:false` auf einer Treiber-Property,
   worauf Nachfahren und Pseudo-Elemente still den Initialwert lasen und die Sektion nach
   dem Deploy exakt aussah wie vorher — wird hier nicht wiederholt. --wd-act wird auf der
   ZEILE gerechnet und von .wd-lst-a::before gelesen; das ist ein Enkel. */
@keyframes wd-bp-run{from{--wd-bp:0}to{--wd-bp:1}}

/* Unter 1025px sind beide Huellen reine Block-Container ohne eigene Wirkung — die
   bestehende, am 02.08. ueber 45 Scrollpositionen verifizierte Mobil-/Tablet-Bauform
   bleibt damit unberuehrt. Sie anzufassen waere Risiko ohne Auftrag gewesen. */
.wd-lst-split,.wd-lst-col{display:block;min-width:0}
.wd-buehne{display:none}

@media(min-width:1025px){
  .wd-lst-split{display:grid;grid-template-columns:minmax(0,1fr) 41%;gap:44px;align-items:start;
    /* EIN Treiber fuer Liste UND Buehne. --wd-hov schaltet die Quelle um: 0 = die
       Scrollposition fuehrt, 1 = der Zeigefinger fuehrt. Weil beide in dieselbe Groesse
       muenden, koennen Zeilen-Hervorhebung und Buehne gar nicht auseinanderlaufen. */
    --wd-t:calc(var(--wd-hov) * var(--wd-hi) + (1 - var(--wd-hov)) * var(--wd-bp) * 5)}

  /* Die Motivspalte IN der Zeile faellt weg — die Buehne hat ihre Aufgabe uebernommen.
     Damit gewinnt die Textspalte den Platz zurueck, und die linke Indexspalte schrumpft
     von 4,5rem auf 3,25rem: 120px fuer drei Zeichen war der Befund des letzten Pruefers. */
  .wd-lst-kopf,.wd-lst-a{--wd-lst-cols:[n] 3.25rem [t] minmax(0,1fr) [p] auto [go] 1.5rem;
    column-gap:20px}
  .wd-lst-img{display:none}
  /* Der Name wird eine Nummer kleiner als in der vollbreiten Zeile. Das ist keine
     Geschmacksfrage: gemessen standen 314px Name + 12px Abstand + 66px BELIEBT-Badge in
     einer 338px-Spalte, das Badge fiel unter den Namen und machte Zeile 1 mit 169px zu
     der einzigen aus der Reihe (alle anderen 141px). Eine Ledger-Liste lebt vom
     gleichmaessigen Takt — eine Zeile, die aus dem Raster faellt, liest sich als Fehler.
     1,55rem in einer 630px-Spalte ist ausserdem die typografisch richtige Groesse; die
     1,75rem waren fuer die volle Seitenbreite gesetzt. */
  .wd-lst-t{font-size:clamp(1.05rem,1.7vw,1.5rem)}
  /* `t/go` ist hier gefahrlos: es gibt keine Bildspur mehr, unter der die Beschreibung
     durchlaufen koennte (der Verdeckungsfehler vom 02.08. entstand genau daran). Preis
     sitzt in Zeile 1, Beschreibung in Zeile 2 — sie ueberlagern sich nie. */
  .wd-lst-d{grid-column:t/go;max-width:46ch}

  /* ---- Die Buehne ---- */
  .wd-buehne{display:block;position:sticky;
    /* Mittig im Sichtfenster, aber nie unter den Header gerutscht. */
    top:max(calc(var(--wd-header-h) + 28px),calc(50vh - 200px))}
  .wd-bue-frame{position:relative;aspect-ratio:16/9;overflow:hidden;
    border-radius:var(--wd-radius);border:1px solid var(--wd-hairline);
    background:var(--wd-surface-1)}
  /* STAPEL statt Kreuzblende. Jede Ebene bleibt voll deckend, sobald sie erreicht ist;
     nur die EINFAHRENDE blendet auf. Eine symmetrische Kreuzblende ueber Schwarz macht
     in der Mitte des Uebergangs zwangslaeufig einen Helligkeits-Einbruch (beide bei 0,5
     uebereinander = 75 % statt 100 %) — hier gibt es ihn nie.
       Ebene i:  opacity = clamp(0, t - i + 1, 1)
       t=0 -> nur Ebene 0 steht.  t=2,5 -> Ebenen 0-2 voll, Ebene 3 bei 0,5 darueber. */
  .wd-bue-l{position:absolute;inset:0;
    --wd-bo:clamp(0,calc(var(--wd-t) - var(--wd-bi) + 1),1);
    opacity:var(--wd-bo);
    /* Zoom-Ausschwung nur auf der einfahrenden Ebene — die darunter stehen auf --wd-bo:1
       und damit exakt auf scale(1). Kein Dauerzoom, kein Flimmern im Stapel. */
    transform:scale(calc(1 + (1 - var(--wd-bo)) * .07))}
  .wd-bue-l:nth-child(1){--wd-bi:0} .wd-bue-l:nth-child(2){--wd-bi:1}
  .wd-bue-l:nth-child(3){--wd-bi:2} .wd-bue-l:nth-child(4){--wd-bi:3}
  .wd-bue-l:nth-child(5){--wd-bi:4} .wd-bue-l:nth-child(6){--wd-bi:5}
  .wd-bue-l img{width:100%;height:100%;object-fit:cover;display:block}

  /* Sucher-Ecken: zwei Winkel in Signalgruen, oben links und unten rechts. Ein ruhiges
     Formmotiv, das den Kasten als BUEHNE liest statt als Bild — und genau ein Akzent,
     keine sechs (CI-LOCK §0 R2). */
  .wd-bue-frame::before,.wd-bue-frame::after{content:"";position:absolute;width:22px;height:22px;
    pointer-events:none;z-index:3;opacity:.75}
  .wd-bue-frame::before{top:12px;left:12px;
    border-top:2px solid var(--wd-signal);border-left:2px solid var(--wd-signal)}
  .wd-bue-frame::after{bottom:12px;right:12px;
    border-bottom:2px solid var(--wd-signal);border-right:2px solid var(--wd-signal)}

  /* Fuss: Zaehler + Fortschrittsschiene. Die Schiene ist die einzige Stelle, die die
     Sechser-Teilung ueberhaupt sichtbar macht. */
  .wd-bue-fuss{display:flex;align-items:center;gap:16px;margin-top:18px}
  .wd-bue-schiene{position:relative;flex:1;height:2px;background:var(--wd-hairline);
    border-radius:2px;overflow:hidden}
  .wd-bue-schiene i{position:absolute;inset:0;background:var(--wd-signal);
    transform-origin:0 50%;transform:scaleX(calc((var(--wd-t) + 1) / 6))}
  .wd-bue-zaehler{font-family:var(--wd-mono);font-weight:500;font-size:12px;
    letter-spacing:.14em;color:rgba(245,245,243,.42);font-variant-numeric:tabular-nums;
    display:none}
  /* Der Live-Zaehler „_03 / 06" ist reines CSS: der Treiber wird auf eine ganze Zahl
     gerundet und als counter() ausgegeben. Er haengt an @supports(round()) und ist sonst
     GAR NICHT da — ein Browser ohne round() soll kein „_00" schreiben. Das ist der
     Unterschied zwischen einem Fallback und einem sichtbaren Defekt. */
  @supports (width: round(1.4px, 1px)){
    .wd-bue-zaehler{display:inline-block;
      counter-reset:wdbue calc(round(down, var(--wd-t), 1) + 1)}
    .wd-bue-zaehler::before{content:"_" counter(wdbue,decimal-leading-zero) " / 06"}
  }

  /* ---- Die Zeile antwortet auf denselben Treiber ----
     EIN Treiber, DREI Kurven — die Lehre der Vorrunde, hier von Anfang an eingebaut.
     Ein stetiger Treiber aktiviert immer mehrere Nachbarn teilweise, also braucht jeder
     Konsument seine eigene Schaerfe:
       --wd-act   Dreieck, Breite +-1   -> Rohwert
       --wd-actr  Schwelle + 3. Potenz  -> genau EINE gruene Kante, nie zwei
       --wd-actc  kubisch               -> Farbe bleibt auf der Spitze statt sich auf
                                           drei Nachbarzeilen zu verteilen */
  .wd-lst-row:nth-child(1){--wd-ri:0} .wd-lst-row:nth-child(2){--wd-ri:1}
  .wd-lst-row:nth-child(3){--wd-ri:2} .wd-lst-row:nth-child(4){--wd-ri:3}
  .wd-lst-row:nth-child(5){--wd-ri:4} .wd-lst-row:nth-child(6){--wd-ri:5}
  .wd-lst-split .wd-lst-row{
    --wd-act:clamp(0,calc(1 - abs(var(--wd-t) - var(--wd-ri))),1);
    --wd-actr:clamp(0,calc((var(--wd-act) - .5) / .16),1);
    --wd-actc:pow(clamp(0,calc((var(--wd-act) - .3) / .55),1),2)}
  /* Warum die Kante an einer SCHWELLE bei .5 haengt und nicht an einer Potenzkurve:
     Weil das Dreieck Breite +-1 hat, gilt zwischen zwei Nachbarzeilen immer act1+act2 = 1.
     Genau eine Zeile liegt also ueber .5 — die Schwelle macht „nie zwei gruene Kanten" zur
     ARITHMETISCHEN Eigenschaft statt zu einer, die man nachmessen und nachjustieren muss.
     Die erste Fassung nahm hier Schwelle .35 + dritte Potenz (aus dem Mobil-Umbau
     uebernommen) — gemessen ueber 23 Scrollpositionen sprang die staerkste Kante damit
     zwischen 0,07 und 0,73: sie BLINKTE, statt zu wandern. Mit der Schwelle steht sie ueber
     rund zwei Dritteln des Zeilenwegs voll und geht im Uebergabemoment kurz ganz aus —
     ein sauberer Schnitt statt eines Pulsierens.
     Die Farbe braucht die andere Form: dort ist nicht „genau eine" das Ziel, sondern „der
     Akzent bleibt auf der Spitze". Plateau ab act .85, quadratischer Abfall — bei act .5
     stehen noch 0,14, das liest niemand als gruen (die Lehre gegen die 17 gruenen Punkte
     im Blick bleibt damit gewahrt). */
  /* Kante ueber DECKKRAFT, nicht ueber scaleX. Als scaleX blieb bei Nachbarzeilen knapp
     ueber der Schwelle ein kurzer gruener Stummel stehen, der als angefangene zweite
     Kante las; als Deckkraft ist derselbe Wert schlicht unsichtbar. Gelernt am
     Mobil-Umbau, hier direkt uebernommen. transition:none, weil eine Uebergangszeit auf
     einem scroll-getriebenen Wert nur Nachlauf erzeugt. */
  .wd-lst-split .wd-lst-a::before{transform:scaleX(1);opacity:var(--wd-actr);transition:none}
  @supports (color:color-mix(in oklab,red 50%,blue)){
    .wd-lst-split .wd-lst-n{
      color:color-mix(in oklab,var(--wd-signal) calc(var(--wd-actc) * 100%),var(--wd-grey))}
    .wd-lst-split .wd-lst-p{
      color:color-mix(in oklab,var(--wd-signal) calc(var(--wd-actc) * 66%),rgba(245,245,243,.92))}
    /* Das BELIEBT-Badge nimmt sonst Gruen fuer eine INAKTIVE Zeile in Anspruch. */
    .wd-lst-split .wd-lst-tag{
      color:color-mix(in oklab,var(--wd-signal) calc(var(--wd-actc) * 100%),rgba(245,245,243,.62));
      border-color:color-mix(in oklab,var(--wd-signal) calc(var(--wd-actc) * 100%),rgba(245,245,243,.20))}
  }

  /* ---- Ebene 2: das Scrollrad liefert die Uhr ----
     Die benannte View-Timeline sitzt auf der <ol>; timeline-scope auf der SEKTION macht
     sie fuer die klebende Buehne sichtbar, die kein Nachfahre der Liste ist.
     Faellt timeline-scope aus (aelterer Browser), bleibt --wd-bp auf seinem Initialwert 0
     — und 0 heisst „Motiv 1 steht". Nie ein leerer Kasten, der auf eine Maus wartet. */
  @supports (timeline-scope: --wd-x){
    /* Der Scope haengt an .wd-lst-split, NICHT an .wd-ledger.
       Erster Wurf nahm .wd-ledger — und genau daran ist der Hub gescheitert: dessen
       Abschnitt heisst `.wd-section`, die Klasse gibt es dort gar nicht. Der Name war
       damit nicht aufloesbar, die Timeline inaktiv, und `animation-fill-mode: both`
       friert eine Animation mit inaktiver Timeline auf ihrem ENDWERT ein: --wd-bp = 1,
       t = 5. Gemessen auf dem Hub: Zaehler „_06 / 06" und volle Schiene, waehrend die
       Liste oben stand. Nichts warf einen Fehler, nichts sah kaputt aus — es zeigte
       dauerhaft den falschen Eintrag.
       .wd-lst-split ist die richtige Aufhaengung, weil sie STRUKTURELL ist: dieselbe
       Huelle erzeugt beide Seiten, sie ist der gemeinsame Vorfahre von Liste und Buehne,
       und sie kann nicht versehentlich fehlen — ohne sie gibt es die Sektion nicht. */
    .wd-lst-split{timeline-scope:--wd-lstline}
    .wd-lst{view-timeline-name:--wd-lstline;view-timeline-axis:block}
    .js-motion .wd-lst-split{animation:wd-bp-run linear both;
      animation-timeline:--wd-lstline;animation-range:cover 25% cover 80%}
  }
}

/* Schmale Desktops: die Buehne nimmt sich weniger, damit die Namensspalte reicht.
   Gemessen bei exakt 1025px mit den 41 % von oben: Namensspalte 279px, Bedarf aus Name
   (212) + Abstand (12) + BELIEBT-Badge (66) = 290px — das Badge fiel unter den Namen und
   Zeile 1 wurde 29px hoeher als die uebrigen fuenf. Mit 36 % stehen dort 329px zur
   Verfuegung. Ab 1180px greift wieder der volle Anteil; die Huelle ist ohnehin auf
   --wd-maxw gedeckelt, breiter wird die Buehne also nicht mehr. */
@media(min-width:1025px) and (max-width:1179px){
  .wd-lst-split{grid-template-columns:minmax(0,1fr) 36%;gap:36px}
}

/* ---- Die Maus uebernimmt (nur wo es einen Schwebezustand gibt) ----
   :has() setzt den gehoverten Index; --wd-t schaltet damit von der Scrollposition auf
   den Zeigefinger. Die Zeilen-Hervorhebung folgt automatisch mit, weil sie an DEMSELBEN
   Treiber haengt — Buehne und Liste koennen nicht auseinanderlaufen. */
@media(min-width:1025px) and (hover:hover) and (pointer:fine){
  .wd-lst-split:has(.wd-lst-a:hover){--wd-hov:1}
  .wd-lst-split:has(.wd-lst-row:nth-child(1) .wd-lst-a:hover){--wd-hi:0}
  .wd-lst-split:has(.wd-lst-row:nth-child(2) .wd-lst-a:hover){--wd-hi:1}
  .wd-lst-split:has(.wd-lst-row:nth-child(3) .wd-lst-a:hover){--wd-hi:2}
  .wd-lst-split:has(.wd-lst-row:nth-child(4) .wd-lst-a:hover){--wd-hi:3}
  .wd-lst-split:has(.wd-lst-row:nth-child(5) .wd-lst-a:hover){--wd-hi:4}
  .wd-lst-split:has(.wd-lst-row:nth-child(6) .wd-lst-a:hover){--wd-hi:5}
  /* Die Blende gilt NUR im Hover-Zustand. Beim Scrollen bleibt der Pfad ohne transition,
     sonst baut man genau den Nachlauf wieder ein, wegen dem Lenis rausgeflogen ist.
     Verlaesst die Maus die Liste, rastet die Buehne uebergangslos auf die
     scroll-richtige Ebene zurueck — das ist gewollt, nicht vergessen. */
  .wd-lst-split:has(.wd-lst-a:hover) .wd-bue-l{transition:opacity .26s ease}
}
/* Tastatur ist nicht zweite Klasse: identischer Zustand ohne (hover:hover)-Bedingung. */
@media(min-width:1025px){
  .wd-lst-split:has(.wd-lst-a:focus-visible){--wd-hov:1}
  .wd-lst-split:has(.wd-lst-row:nth-child(1) .wd-lst-a:focus-visible){--wd-hi:0}
  .wd-lst-split:has(.wd-lst-row:nth-child(2) .wd-lst-a:focus-visible){--wd-hi:1}
  .wd-lst-split:has(.wd-lst-row:nth-child(3) .wd-lst-a:focus-visible){--wd-hi:2}
  .wd-lst-split:has(.wd-lst-row:nth-child(4) .wd-lst-a:focus-visible){--wd-hi:3}
  .wd-lst-split:has(.wd-lst-row:nth-child(5) .wd-lst-a:focus-visible){--wd-hi:4}
  .wd-lst-split:has(.wd-lst-row:nth-child(6) .wd-lst-a:focus-visible){--wd-hi:5}
}

/* ---- INDEX — asymmetrischer Split, links haelt das Numeral die Stellung ---- */
.wd-index{padding:96px 0}
.wd-index-grid{display:grid;grid-template-columns:4fr 8fr;gap:56px;align-items:start}
.wd-index-rail{position:sticky;top:calc(var(--wd-header-h) + 40px)}
.wd-index-rail .wd-eyebrow{display:block;margin-bottom:18px}
.wd-index-rail p{color:rgba(245,245,243,.66);font-size:1rem;line-height:1.6;margin-top:18px;max-width:34ch}
.wd-index-items{display:flex;flex-direction:column;gap:0}
.wd-index-item{display:grid;grid-template-columns:auto 1fr;gap:28px;align-items:start;
  padding:34px 0;border-top:1px solid var(--wd-hairline)}
.wd-index-item:last-child{border-bottom:1px solid var(--wd-hairline)}
.wd-index-item h3{font-family:var(--wd-display);font-weight:800;font-size:1.375rem;letter-spacing:-.01em;margin:0}
.wd-index-item p{color:rgba(245,245,243,.68);font-size:1rem;line-height:1.6;margin:8px 0 0;max-width:54ch}
.wd-index-media{margin-top:18px;border-radius:var(--wd-radius);overflow:hidden;
  border:1px solid var(--wd-hairline);background:var(--wd-surface-1);aspect-ratio:16/9}
.wd-index-media img{width:100%;height:100%;object-fit:cover;display:block}

/* ---- CATALOG — Kartenmedium (die Seite hatte bisher 0 Bilder) ---- */
/* Randlos in die Karte gesetzt: -28px = Kartenpolsterung. aspect-ratio 16/9, weil die
   Quellen 900x502 liefern — bei 16/10 wuerde object-fit:cover oben und unten je ~25px
   wegschneiden, und genau dort sitzt bei beiden Motiven der gruene Lichtpunkt. */
.wd-card-media{margin:-28px -28px 20px;border-radius:var(--wd-radius) var(--wd-radius) 0 0;
  overflow:hidden;aspect-ratio:16/9;background:var(--wd-surface-2)}
.wd-card-media img{width:100%;height:100%;object-fit:cover;display:block}

/* ---- LEDGER hell — die zweite gestalterische Ebene (CI-LOCK §1a) ---- */
/* Bewusst KEINE Neuzuweisung der globalen Tokens: --wd-hairline ist rgba(weiss),
   das kippt auf hell ins Unsichtbare. Eigene Werte, alle nachgerechnet
   (tooling/wd_kontrast.py). Grau #8B9197 kommt hier NICHT vor — 2,92:1. */
/* Frischegruen ist auf Warmweiss 3,31:1 — das reicht fuer Large Text (>=24px oder
   >=18,66px bold), fuer Flaechen und fuer Linien, NICHT fuer Kleintext. Die 13-px-Eyebrows
   und die 12-px-Kartenkoepfe standen genau darin und sind live durchgefallen
   (`python tooling/wd_kontrast.py --live`, 28.07.2026: 6 Verstoesse bei 43 Textknoten).
   Deshalb zwei Rollen statt einer: --wd-hell-accent traegt weiter Flaechen, Linien und die
   grossen Numerale, --wd-hell-accent-txt traegt alles, was als Text gelesen wird. */
.wd-hell{background:var(--wd-warmwhite);color:var(--wd-anthracite);padding:112px 0;
  --wd-hell-muted:#5D5F60;
  --wd-hell-line:#D9DBD8;
  --wd-hell-accent:var(--wd-fresh);
  --wd-hell-accent-txt:var(--wd-anthracite)}
.wd-hell + .wd-hell{padding-top:0}
.wd-hell .wd-eyebrow{color:var(--wd-hell-accent-txt)}
.wd-hell .wd-title,.wd-hell .wd-d1{color:var(--wd-anthracite)}
.wd-hell .wd-lead,.wd-hell p{color:var(--wd-hell-muted)}
.wd-hell .wd-c{color:var(--wd-hell-accent-txt)}
.wd-hell a{color:var(--wd-anthracite)}
.wd-hell .wd-hell-line{border:0;border-top:1px solid var(--wd-hell-line);margin:0}
/* Preistafel: drei Toepfe, tabellarisch statt als Kachelreihe */
.wd-topf{padding:38px 0;border-top:1px solid var(--wd-hell-line)}
.wd-topf:first-of-type{border-top:none}
.wd-topf-kopf{display:grid;grid-template-columns:auto 1fr;gap:22px;align-items:baseline}
.wd-topf .wd-num{color:var(--wd-hell-accent);font-size:clamp(1.6rem,3vw,2.4rem)}
.wd-topf h3{font-family:var(--wd-display);font-weight:800;font-size:clamp(1.3rem,2.6vw,1.9rem);
  letter-spacing:-.02em;margin:0;color:var(--wd-anthracite)}
.wd-topf .wd-topf-text{margin-top:14px;font-size:1.02rem;line-height:1.65;max-width:62ch;color:var(--wd-hell-muted)}
/* Ein Link, der ALLEIN in einem Absatz steht, ist ein Tap-Ziel und keine Fliesstext-Stelle —
   die Ausnahme fuer „Link mitten im Satz" (WCAG 2.5.8) greift dort nicht. Gemessen 24 px,
   verlangt sind 44. Betrifft den Verweis auf die vollstaendige Preisrechnung im hellen Band. */
.wd-topf .wd-topf-link{display:inline-flex;align-items:center;min-height:44px;
  color:var(--wd-anthracite);font-weight:600;text-decoration:underline;text-underline-offset:3px}
.wd-topf .wd-topf-link:hover{color:var(--wd-hell-accent)}
.wd-preise{display:flex;flex-wrap:wrap;gap:10px;margin-top:22px}
.wd-preis{border:1px solid var(--wd-hell-line);border-radius:var(--wd-radius);padding:12px 16px;
  background:#FFFFFF;min-width:0}
.wd-preis .wd-preis-was{font-family:var(--wd-mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--wd-hell-muted)}
.wd-preis .wd-preis-wert{font-family:var(--wd-display);font-weight:800;font-size:1.15rem;letter-spacing:-.02em;
  margin-top:4px;color:var(--wd-anthracite);white-space:nowrap}
/* Die eine hervorgehobene Zeile: Night-Text auf Frischegruen-Flaeche = 5,44:1.
   Weiss auf Frischegruen waere 3,62:1 und faellt fuer Fliesstext durch. */
.wd-preis.wd-preis-feat{background:var(--wd-hell-accent);border-color:var(--wd-hell-accent)}
/* Voll deckend, nicht rgba(11,11,12,.78): halbtransparent mischt sich die Flaeche ein und
   flacht auf #092B1B ab — gemessen 4,23:1 und damit durchgefallen. Deckend sind es 5,44. */
.wd-preis.wd-preis-feat .wd-preis-was{color:var(--wd-night)}
.wd-preis.wd-preis-feat .wd-preis-wert{color:var(--wd-night)}
.wd-nicht-drin{margin-top:30px;padding:26px 28px;background:#FFFFFF;border:1px solid var(--wd-hell-line);
  border-left:2px solid var(--wd-hell-accent);border-radius:var(--wd-radius)}
/* 12px = Kleintext, also die Text-Rolle des Akzents; die gruene Kante links traegt das
   Signal weiter (Linie, kein Text — dort ist Frischegruen erlaubt). */
.wd-nicht-drin h4{font-family:var(--wd-mono);font-weight:500;font-size:12px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--wd-hell-accent-txt);margin:0 0 12px}
.wd-nicht-drin ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.wd-nicht-drin li{position:relative;padding-left:22px;font-size:1rem;line-height:1.55;color:var(--wd-hell-muted)}
.wd-nicht-drin li::before{content:"_";position:absolute;left:0;color:var(--wd-hell-accent-txt);font-family:var(--wd-mono)}
/* Endorsement in derselben hellen Passage — §7 verortet Frischegruen genau hier. */
.wd-hell .wd-endorse-h{font-family:var(--wd-display);font-weight:800;letter-spacing:-.025em;line-height:1.12;
  font-size:clamp(1.6rem,3.4vw,2.6rem);max-width:20ch;margin:14px 0 0;color:var(--wd-anthracite)}
.wd-hell .wd-endorse-sub{margin-top:20px;max-width:60ch;font-size:1.05rem;line-height:1.65;color:var(--wd-hell-muted)}

/* ---- "Wer das baut" — Ort und Mensch ---- */
.wd-wer{display:grid;grid-template-columns:5fr 7fr;gap:48px;align-items:center}
.wd-wer-fakten{display:flex;flex-direction:column;gap:0;margin-top:26px}
.wd-wer-fakt{display:grid;grid-template-columns:auto 1fr;gap:18px;padding:14px 0;
  border-top:1px solid var(--wd-hairline);font-size:1rem}
.wd-wer-fakt:last-child{border-bottom:1px solid var(--wd-hairline)}
.wd-wer-fakt dt{font-family:var(--wd-mono);font-size:12px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--wd-grey);min-width:11ch}
.wd-wer-fakt dd{margin:0;color:rgba(245,245,243,.82);min-width:0;overflow-wrap:anywhere}
/* Die Durchwahl ist ein eigenstaendiges Ziel in einer Definitionsliste, kein Link im
   Fliesstext — die WCAG-2.5.8-Inline-Ausnahme greift hier nicht. */
.wd-wer-fakt dd a{display:inline-flex;align-items:center;min-height:44px}

/* ---- RESPONSIVE fuer die neuen Familien ---- */
@media(max-width:1024px){
  .wd-index-grid{grid-template-columns:1fr;gap:34px}
  .wd-index-rail{position:static}
  .wd-wer{grid-template-columns:1fr;gap:30px}
  .wd-ledger,.wd-hell{padding:84px 0}
}
@media(max-width:600px){
  .wd-index-item{grid-template-columns:1fr;gap:14px}
  .wd-statement{padding:76px 0}
  .wd-ledger,.wd-hell{padding:64px 0}
  .wd-topf-kopf{grid-template-columns:1fr;gap:8px}
  .wd-card-media{margin:-28px -28px 18px}
  .wd-preise{flex-direction:column}
  .wd-preis{width:100%}
}

/* Preis auf der Leistungskarte — der Preis stand bisher erst 3.000 px weiter unten. */
.wd-card-preis{font-family:var(--wd-display);font-weight:800;font-size:1.15rem;letter-spacing:-.02em;
  color:var(--wd-warmwhite);margin-top:16px;padding-top:14px;border-top:1px solid var(--wd-hairline)}
.wd-card-preis span{font-family:var(--wd-body);font-weight:400;font-size:.82rem;color:var(--wd-grey);
  letter-spacing:0;display:block;margin-top:2px}
a.wd-card.wd-card-main .wd-card-preis{color:var(--wd-signal)}
