/* ============================================================================
 * EverAudit Showcase — FOUNDATION
 * Dark-only premium token layer + reset + aurora + utilities + buttons +
 * header/footer shell + the reveal-on-scroll gate. Section-specific styles are
 * added per section as we build them.
 *
 * Token discipline (project profile: tailwind_mode v3-:root — NO Tailwind/@theme):
 *   - colour lives in OKLch at the token layer; semantic aliases reference the
 *     numeric --violet-* scale. No raw hex in new tokens.
 *   - one scale per axis: type (modular 1.25), spacing (4-pt), radius, elevation,
 *     z-index, motion. Components consume tokens, never ad-hoc values.
 * Knowledge followed: design-system/{typography-scale, spacing-scale(-fluid),
 *   oklch-palette, tokens-overview, elevation-radius-z-index, motion-defaults,
 *   interaction/focus-ring}, accessibility/wcag-aa-checklist.
 * ========================================================================== */

:root {
  color-scheme: dark;

  /* ── Colour · Tier 1: primitive violet scale (OKLch; source of the aliases) ── */
  --violet-50:  oklch(.970 .018 290);
  --violet-100: oklch(.936 .040 290);
  --violet-200: oklch(.880 .075 290);
  --violet-300: oklch(.800 .120 290);
  --violet-400: oklch(.680 .175 290);
  --violet-500: oklch(.560 .205 290);
  --violet-600: oklch(.500 .210 290); /* brand ≈ #683ecf */
  --violet-700: oklch(.440 .190 290);
  --violet-800: oklch(.375 .155 290);
  --violet-900: oklch(.310 .120 290);
  --violet-950: oklch(.230 .085 290);

  /* ── Colour · Tier 2: surfaces (Hue 290, low chroma) ── */
  --ground:    oklch(.170 .020 290); /* ≈ #101019 */
  --surface-1: oklch(.210 .022 290);
  --surface-2: oklch(.245 .024 290);
  --surface-3: oklch(.285 .026 290);

  /* ── Colour · Tier 2: text (AA on --ground — measured 16.6 / 11.3 / 7.2 :1) ── */
  --text-primary:   oklch(.950 .005 290);
  --text-secondary: oklch(.830 .015 290);
  --text-muted:     oklch(.700 .015 290);
  --text-on-accent: oklch(1 0 0); /* white — 6.6:1 on --accent-strong (violet-600) */

  /* ── Colour · Tier 2: borders ── */
  --border-subtle:  oklch(1 0 0 / .08);
  --border-default: oklch(1 0 0 / .12);
  --border-strong:  oklch(1 0 0 / .18);

  /* ── Colour · Tier 3: accent (allowed: primary CTA, links, kicker, focus ring,
        brand-mark, hero-gradient text, active nav indicator — never body text,
        never flat panel fills, never >1 primary CTA per viewport) ── */
  --accent:        var(--violet-500);
  --accent-strong: var(--violet-600);
  --accent-text:   var(--violet-300); /* 9.9:1 on --ground */
  --link:          var(--violet-300);
  --link-hover:    var(--violet-200);
  --focus:         var(--violet-300);

  /* ── Colour · severity / prio (load-bearing) — canonical product anchors in
        OKLch + -soft fill (alpha .15) + -on label. -on = raw role colour:
        measured ≥5:1 on its own -soft over --ground (no L-lift needed). ── */
  --sev-critical:      oklch(.680 .164 28.3);  /* #ec6a5c */
  --sev-critical-soft: oklch(.680 .164 28.3 / .15);
  --sev-critical-on:   oklch(.680 .164 28.3);
  --sev-serious:       oklch(.754 .134 75.4);  /* #e0a23f */
  --sev-serious-soft:  oklch(.754 .134 75.4 / .15);
  --sev-serious-on:    oklch(.754 .134 75.4);
  --sev-moderate:      oklch(.795 .145 96.0);  /* #d8bb3a */
  --sev-moderate-soft: oklch(.795 .145 96.0 / .15);
  --sev-moderate-on:   oklch(.795 .145 96.0);
  --sev-minor:         oklch(.715 .124 254.1); /* #6aa6ef */
  --sev-minor-soft:    oklch(.715 .124 254.1 / .15);
  --sev-minor-on:      oklch(.715 .124 254.1);
  --sev-ok:            oklch(.725 .136 161.1); /* #43c08a */
  --sev-ok-soft:       oklch(.725 .136 161.1 / .15);
  --sev-ok-on:         oklch(.725 .136 161.1);

  /* ── Colour · gradients ──
        --grad-hero-text (3-stop, 500→400→300): for CLIPPED hero TEXT — every stop
          clears WCAG 1.4.3 large-text 3:1 on --ground (worst, leftmost: 3.77:1).
        --grad-hero (3-stop, 600→500→400): FILL only (white text sits on the
          violet-600 anchor at 6.6:1). Not for clipped text — its 600 stop is
          2.89:1 as text. (Split per designer/oklch-palette: scope, don't mutate.)
        --grad-primary (2-stop, 600→500) carries every normal primary button;
        white stays ≥5:1 on both its stops. */
  --grad-hero-text: linear-gradient(100deg, var(--violet-500) 0%, var(--violet-400) 50%, var(--violet-300) 100%);
  --grad-hero:      linear-gradient(100deg, var(--violet-600) 0%, var(--violet-500) 50%, var(--violet-400) 100%);
  --grad-primary:   linear-gradient(180deg, var(--violet-600), var(--violet-500));

  /* ── Type · families ── */
  --font-display: "Space Grotesk", ui-sans-serif, system-ui, sans-serif;
  --font-body:    "Geist", ui-sans-serif, system-ui, sans-serif;
  --font-mono:    "Geist Mono", ui-monospace, "SF Mono", monospace;

  /* ── Type · modular scale (ratio 1.25, anchor 16px). Sizes + line-heights +
        tracking as paired tokens. Weights: Space Grotesk ships 400/500/600/700;
        Geist & Geist Mono ship only 400/500 (self-hosted fonts.css is out of
        this task's scope). h3/h4 declare weight 600 and .priotag declares 700 to
        honour the type spec and stay forward-compatible if those faces are later
        embedded; `font-synthesis: none` (on body) blocks faux-bold, so today they
        render at the nearest real weight (500). ── */
  --text-display:  clamp(2.75rem, 1.1rem + 6.4vw, 4.5rem);
  --text-h2:       clamp(1.9rem, 1.1rem + 3.2vw, 2.75rem);
  --text-h3:       clamp(1.4rem, 1.05rem + 1.4vw, 1.75rem);
  --text-h4:       1.25rem;
  --text-lead:     clamp(1.125rem, 1.05rem + 0.4vw, 1.25rem);
  --text-body:     1.0625rem; /* 17px — body never < 16px */
  --text-ui:       0.875rem;  /* 14px */
  --text-caption:  0.8125rem; /* 13px */
  --text-overline: 0.75rem;   /* 12px */
  --text-micro:    0.6875rem; /* 11px */

  --line-height-display: 1.05;
  --line-height-h2:      1.15;
  --line-height-h3:      1.25;
  --line-height-h4:      1.3;
  --line-height-lead:    1.5;
  --line-height-body:    1.6;
  --line-height-ui:      1.4;

  --tracking-display:  -0.02em;
  --tracking-h2:       -0.015em;
  --tracking-h3:       -0.01em;
  --tracking-overline: 0.1em;
  --tracking-micro:    0.06em;

  /* ── Spacing · 4-pt grid ── */
  --space-1:  0.25rem; /* 4 */
  --space-2:  0.5rem;  /* 8 */
  --space-3:  0.75rem; /* 12 */
  --space-4:  1rem;    /* 16 */
  --space-5:  1.25rem; /* 20 */
  --space-6:  1.5rem;  /* 24 */
  --space-8:  2rem;    /* 32 */
  --space-10: 2.5rem;  /* 40 */
  --space-12: 3rem;    /* 48 */
  --space-16: 4rem;    /* 64 */
  --space-20: 5rem;    /* 80 */
  --space-24: 6rem;    /* 96 */

  /* ── Spacing · fluid layout layer ── */
  --space-section: clamp(4rem, 8vw, 7rem);
  --space-block:   clamp(2rem, 4vw, 3rem);
  --space-card:    var(--space-6);

  /* deterministic seat height of a labeled finding bar (.rt-real): its 2-row body
     (priotag chip row + meta row) renders ~60.8px, which EXCEEDS the old 3.25rem
     floor — so the reserved foot slot (.rt-slot, same token) reserves the landed
     .flow-travel card's TRUE footprint and the .lane-stack gap (--space-2) applies
     evenly ABOVE the landed card too (no 0/negative gap). Pinned, not content-floor,
     so card + slot can never drift apart again. */
  --rt-seat-h: 3.8rem;

  /* ── Layout ── */
  --content-max: 1120px;
  --gutter:      clamp(1.25rem, 4vw, 3rem);
  --header-h:    3.75rem; /* 60px — single source for header height + scroll offset */

  /* ── Radius ── */
  --radius-xs:   6px;
  --radius-sm:   10px;
  --radius-md:   12px;
  --radius-lg:   16px;
  --radius-xl:   20px;
  --radius-pill: 999px;

  /* ── Elevation (two-layer shadows) + edge highlight + accent glow ── */
  --shadow-1: 0 1px 2px oklch(0 0 0 / .20), 0 1px 1px oklch(0 0 0 / .14);
  --shadow-2: 0 4px 8px oklch(0 0 0 / .24), 0 2px 4px oklch(0 0 0 / .16);
  --shadow-3: 0 12px 28px oklch(0 0 0 / .34), 0 6px 12px oklch(0 0 0 / .20);
  --highlight-top: inset 0 1px 0 oklch(1 0 0 / .05);
  --glow-accent:   0 8px 24px -10px oklch(.50 .21 290 / .5); /* primary CTA only */
  --elevation-card:    var(--shadow-1);
  --elevation-raised:  var(--shadow-2);
  --elevation-overlay: var(--shadow-3);

  /* ── Z-index · single source ── */
  --z-base:    0;
  --z-sticky:  100;
  --z-skip:    200;
  --z-overlay: 300;

  /* ── Motion ── */
  --duration-ui:     150ms;
  --duration-medium: 300ms;
  --duration-reveal: 500ms;
  --easing-standard: cubic-bezier(.2, 0, 0, 1);
  --easing-reveal:   cubic-bezier(.16, 1, .3, 1);
}

[data-sev="critical"] { --sev: var(--sev-critical); }
[data-sev="serious"]  { --sev: var(--sev-serious); }
[data-sev="moderate"] { --sev: var(--sev-moderate); }
[data-sev="minor"]    { --sev: var(--sev-minor); }
[data-sev="ok"]       { --sev: var(--sev-ok); }

/* ── reset / base ─────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  /* No CSS scroll-behavior: smooth — Lenis owns smooth scrolling. CSS-smooth
     fights Lenis' rAF (jank / "snap" feel). Anchor smooth is JS: main.js uses
     __lenis.scrollTo(), or scrollIntoView({behavior}) on the no-Lenis floor. */
  scroll-padding-top: var(--header-h);
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0;
  background: var(--ground);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--line-height-body);
  font-synthesis: none; /* no faux-bold/-italic — see weights note above */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
img, svg, canvas { display: block; max-width: 100%; }
.mono { font-family: var(--font-mono); }

/* Headings — real per-element sizes (the old h1,h2,h3{line-height:1.08} blanket
   rule is dissolved). Space Grotesk only on display + h2; Geist from h3 down. */
h1, h2, h3, h4 { margin: 0; }
h1 {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--text-display); line-height: var(--line-height-display);
  letter-spacing: var(--tracking-display);
  text-wrap: balance; max-inline-size: 18ch;
}
h2 {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--text-h2); line-height: var(--line-height-h2);
  letter-spacing: var(--tracking-h2);
  text-wrap: balance; max-inline-size: 24ch;
}
h3 {
  font-family: var(--font-body); font-weight: 600; /* renders 500 today */
  font-size: var(--text-h3); line-height: var(--line-height-h3);
  letter-spacing: var(--tracking-h3);
}
h4 {
  font-family: var(--font-body); font-weight: 600; /* renders 500 today */
  font-size: var(--text-h4); line-height: var(--line-height-h4);
}

/* ── aurora ground — one calm, top-anchored wash (was two saturated orbs) ───── */
.aurora { position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.aurora::before, .aurora::after {
  content: ""; position: absolute; left: 50%; transform: translateX(-50%);
  width: 50vmax; height: 50vmax; border-radius: 50%;
  filter: blur(160px); mix-blend-mode: screen;
}
.aurora::before {
  top: -18vmax; opacity: .22;
  background: radial-gradient(closest-side, oklch(.45 .11 290 / .45), transparent);
}
.aurora::after { /* distant depth anchor, hue shifted to 270 */
  top: -6vmax; opacity: .12;
  background: radial-gradient(closest-side, oklch(.45 .11 270 / .45), transparent);
}

/* ── utilities ────────────────────────────────────────────────────────────── */
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: fixed; top: var(--space-2); left: var(--space-2); z-index: var(--z-skip);
  background: var(--accent-strong); color: var(--text-on-accent); font-weight: 500;
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-sm);
  transform: translateY(-150%);
  transition: transform var(--duration-ui) var(--easing-standard);
}
.skip-link:focus { transform: translateY(0); }
:where(a, button, input, [tabindex]):focus-visible {
  outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--radius-sm);
}
:focus:not(:focus-visible) { outline: none; } /* suppress mouse-click outline */
.icon {
  width: 1.2em; height: 1.2em; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: 0 0 auto;
}

/* ── buttons (base = md/40px; sizes via min-height per WCAG 2.5.8) ──────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: 2.5rem; padding: var(--space-2) var(--space-4);
  font-family: var(--font-body); font-size: var(--text-ui); font-weight: 500;
  line-height: var(--line-height-ui);
  border-radius: var(--radius-sm); border: 1px solid transparent;
  cursor: pointer; white-space: nowrap;
  transition: transform var(--duration-ui) var(--easing-standard),
              filter var(--duration-ui) var(--easing-standard),
              background-color var(--duration-ui) var(--easing-standard),
              border-color var(--duration-ui) var(--easing-standard);
}
.btn-sm { min-height: 2rem; padding: var(--space-1) var(--space-3); }
.btn-lg { min-height: 3rem; padding: var(--space-3) var(--space-5); font-size: var(--text-body); }
.btn .icon { width: 1.05em; height: 1.05em; }

.btn-primary { /* 2-stop gradient; glow reserved to primary CTA */
  background: var(--grad-primary); color: var(--text-on-accent);
  box-shadow: var(--glow-accent), var(--highlight-top);
}
.btn-primary:hover  { filter: brightness(1.07); transform: translateY(-1px); }
.btn-primary:active { transform: translateY(0); }

.btn-ghost { background: var(--surface-1); color: var(--text-primary); border-color: var(--border-strong); }
.btn-ghost:hover { background: var(--surface-2); }

.btn-text { background: transparent; color: var(--link); border-color: transparent; padding-inline: var(--space-2); }
.btn-text:hover { color: var(--link-hover); }

/* ── chips (mono family per the data/kicker/priotag/chip rule; caption size) ── */
.chips { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.chip {
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--text-caption); line-height: var(--line-height-ui);
  color: var(--text-secondary); background: var(--surface-3);
  border: 1px solid var(--border-subtle);
  padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill);
  white-space: nowrap;
}

/* ── priotag (kept primitive; consumes severity roles) ──────────────────────── */
.priotag {
  font-family: var(--font-mono); font-weight: 700; /* renders 500 today */
  font-size: var(--text-micro); line-height: var(--line-height-ui);
  letter-spacing: var(--tracking-micro); text-transform: uppercase;
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-xs);
  white-space: nowrap;
}
.priotag.p1 { background: var(--sev-critical-soft); color: var(--sev-critical-on); }
.priotag.p2 { background: var(--sev-serious-soft);  color: var(--sev-serious-on); }
.priotag.p3 { background: var(--sev-minor-soft);    color: var(--sev-minor-on); }

/* ── header / footer shell ──────────────────────────────────────────────────── */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: var(--z-sticky);
  display: flex; justify-content: center;
  background: color-mix(in oklab, var(--ground) 72%, transparent);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border-subtle);
}
.nav {
  width: 100%; max-width: var(--content-max);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-5);
  min-height: var(--header-h); padding-block: var(--space-2); padding-inline: var(--gutter);
}
.brand { display: flex; align-items: center; gap: var(--space-2); font-weight: 500; }
.brand-mark {
  display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: var(--radius-sm); background: var(--grad-primary);
  color: var(--text-on-accent); box-shadow: var(--glow-accent);
}
.brand-mark .icon { width: 17px; height: 17px; }
.brand-name {
  font-family: var(--font-body); font-weight: 500;
  font-size: var(--text-ui); line-height: var(--line-height-ui);
}

.site-footer {
  border-top: 1px solid var(--border-subtle);
  padding: var(--space-10) var(--gutter); text-align: center; color: var(--text-muted);
}
.footer-tagline {
  font-family: var(--font-display); font-weight: 500;
  font-size: var(--text-lead); line-height: var(--line-height-lead);
  color: var(--text-secondary); margin: 0;
}
.footer-inner {
  width: 100%; max-width: var(--content-max); margin: 0 auto;
  display: flex; flex-direction: column; align-items: center; gap: var(--space-5);
}
.footer-cta { align-self: center; }
.footer-legal {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: var(--space-3) var(--space-5); font-size: var(--text-caption);
}
.footer-legal a { color: var(--link); text-decoration: none; }
.footer-legal a:hover { color: var(--link-hover); text-decoration: underline; }
.footer-copy { margin: 0; font-size: var(--text-caption); color: var(--text-muted); }

/* ── card primitive (foundation pattern for the sections to come) ───────────── */
.card {
  background: var(--surface-1); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg); box-shadow: var(--elevation-card), var(--highlight-top);
}

/* ── generic section helpers (available for new sections) ───────────────────── */
.beat { position: relative; padding-block: var(--space-section); }
.beat-inner { width: 100%; max-width: var(--content-max); margin: 0 auto; padding-inline: var(--gutter); }
.kicker {
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--text-overline); line-height: var(--line-height-ui);
  letter-spacing: var(--tracking-overline); text-transform: uppercase;
  color: var(--accent-text); margin: 0 0 var(--space-3);
}
.lede {
  font-family: var(--font-body); font-weight: 400;
  font-size: var(--text-lead); line-height: var(--line-height-lead);
  color: var(--text-secondary); margin: 0;
}
.accent-gradient {
  background: var(--grad-hero-text); -webkit-background-clip: text; background-clip: text; color: transparent;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .accent-gradient { color: var(--accent-text); }
}

/* ── reveal-on-scroll gate (reusable system) ────────────────────────────────────
   The gate only HIDES while the motion system is in control (html.anim / html.rm,
   set pre-paint by the inline head script). No-JS / libs-blocked → neither class
   is present, OR the inline fail-safe drops the gate → everything is visible. */
html.anim .reveal:not([data-reveal-stagger]) { opacity: 0; transform: translateY(22px); }
html.anim [data-reveal-stagger] > * { opacity: 0; transform: translateY(18px); }
html.rm .reveal:not(.is-in) { opacity: 0; }
html.rm [data-reveal-stagger] > * { opacity: 1; }

/* `.is-in` (reduced-motion IntersectionObserver + the fail-safe) reveals
   regardless of which gate is active — decoupled from .rm on purpose. The
   transition only runs for a motion-OK user in the libs-blocked fail-safe path;
   genuine reduced-motion users get the global transition-kill below (so it is a
   live, intentional fade, not the old dead .28s path). */
.reveal.is-in { opacity: 1 !important; transform: none !important;
  transition: opacity var(--duration-medium) var(--easing-standard); }
[data-reveal-stagger].is-in > * { opacity: 1 !important; transform: none !important; }

/* ── copy-gap surfacing (?copygaps — dev-only) ──────────────────────────────── */
html[data-copygaps] .copy-gap { text-decoration: underline dotted var(--accent-text); text-underline-offset: 3px; }
#copygap-panel {
  position: fixed; right: var(--space-4); bottom: var(--space-4); z-index: var(--z-overlay);
  max-width: 360px; max-height: 60vh; overflow: auto;
  background: var(--surface-2); border: 1px solid var(--accent);
  border-radius: var(--radius-md); padding: var(--space-4);
  font-size: var(--text-caption); box-shadow: var(--elevation-overlay);
}
#copygap-panel h2 { font-size: var(--text-ui); margin: 0 0 var(--space-3); color: var(--accent-text); }
#copygap-panel ol { margin: 0; padding-left: var(--space-5); display: grid; gap: var(--space-2); }
#copygap-panel code { color: var(--accent-text); font-family: var(--font-mono); }
#copygap-panel em { color: var(--text-muted); font-style: normal; margin-left: var(--space-2); }
#copygap-panel span { display: block; color: var(--text-secondary); margin-top: var(--space-1); }

/* ── 1 · HERO ───────────────────────────────────────────────────────────────
   Two-column hero: copy left, a simplified on-brand browser mock right. The mock
   is decorative (aria-hidden); the scanline beam is GSAP-driven (hero.js) and CSS
   only paints its static, centred no-JS / reduced-motion floor. Tokens only — no
   raw hex; the beam's violet comes from --violet-400 / --accent via color-mix.
   Knowledge: delivery/marketing-component-hero, design-system/motion/
   {motion-defaults, gsap-context-matchmedia}, accessibility/wcag-aa-checklist.
   Designer-consult values: beam violet-400/65% core + accent/20% glow, screen
   blend; surfaces step 1→2→3; sweep sine.inOut 4.5s yoyo; reduced-motion rests
   the beam at the viewport-well centre. */
.hero {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  /* clear the fixed header, then breathe; bottom keeps the section rhythm */
  padding-block: calc(var(--header-h) + var(--space-8)) var(--space-section);
}
.hero-inner {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: 1fr; /* mobile-first: single column, copy then mock */
  gap: var(--space-12);
  align-items: center;
}

/* LEFT · copy */
.hero-copy { max-width: 40rem; }
.hero-eyebrow { margin-bottom: var(--space-4); }
/* Hero headline — SCOPED overrides of the global h1 (the --text-display token and
   the global `h1` rule stay untouched: scope, don't mutate). Smaller fluid size
   tuned for the ~57% half-column (32→52px; min 2rem stops single-word fragmenting
   on mobile), 24ch measure overriding the inherited 18ch, and a calmer multi-line
   line-height/tracking. The accent runs INLINE (no display:block) so the whole
   headline balances as one block; .accent-gradient keeps its clip-gradient + the
   @supports --accent-text fallback. h1→lead rhythm = --space-6 (24px). */
.hero-h1 {
  font-size: clamp(2rem, 1.1rem + 3.6vw, 3.25rem);
  line-height: 1.12; letter-spacing: -0.015em;
  max-inline-size: 24ch; text-wrap: balance;
  hyphens: manual; overflow-wrap: normal;
  margin-bottom: var(--space-6);
}
.hero-lead { max-inline-size: 50ch; text-wrap: pretty; margin-bottom: var(--space-8); }
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; }
.hero-scrollcue {
  display: inline-flex; align-items: center; gap: var(--space-2);
  margin: var(--space-10) 0 0;
  font-family: var(--font-mono); font-size: var(--text-caption);
  color: var(--text-muted);
}
.hero-scrollcue .icon { width: 1em; height: 1em; color: var(--accent-text); }

/* RIGHT · simplified browser mock (+ the finding-ticket overlay, positioned
   against this box on desktop) */
.hero-visual { position: relative; justify-self: center; width: 100%; max-width: 32rem; }
.hb { /* the browser window */
  background: var(--surface-1);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--elevation-card), var(--highlight-top);
  overflow: hidden;
}
.hb-chrome {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border-subtle);
}
.hb-dots { display: flex; gap: var(--space-2); flex: 0 0 auto; }
.hb-dots span { width: 8px; height: 8px; border-radius: var(--radius-pill); background: var(--border-strong); }
.hb-url {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-width: 0; max-width: 100%;
  padding: var(--space-1) var(--space-3);
  background: var(--surface-3); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  font-family: var(--font-mono); font-size: var(--text-caption);
  color: var(--text-secondary); white-space: nowrap;
}
.hb-url .icon { width: .85em; height: .85em; color: var(--text-muted); flex: 0 0 auto; }
.hb-url > span { overflow: hidden; text-overflow: ellipsis; }

.hb-viewport {
  position: relative;
  isolation: isolate;       /* contain the beam's screen-blend to the mock */
  overflow: hidden;         /* clip the beam inside the viewport, off the chrome */
  min-height: clamp(17.5rem, 30vw, 23rem);
  padding: var(--space-5);
}
.hb-page { display: flex; flex-direction: column; gap: var(--space-3); }
.hb-block { background: var(--surface-2); border-radius: var(--radius-sm); }
.hb-bar  { height: var(--space-6); }
.hb-hero { height: var(--space-20); background: var(--surface-3); border: 1px solid var(--border-subtle); } /* emphasised, still neutral */
.hb-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.hb-cell { height: var(--space-16); }
.hb-lines { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-1); }
.hb-line { height: var(--space-2); border-radius: var(--radius-pill); background: var(--border-default); }
.hb-line--short { width: 60%; }

/* audit scan checklist — overlays the mock page as the "scanned content". The
   scanline (z-index:1) rides ABOVE it and checks each row off. CSS REST STATE =
   done (all five checked): the no-JS / reduced-motion / mobile floor reads as a
   finished scan. Under html.flow-active (desktop + motion-OK, set pre-paint) the
   rows start UNCHECKED here and routing.js scrubs each to done as the beam
   crosses it — never `.from()` against the CSS-done end. */
.hb-scan {
  position: absolute; inset: 0; z-index: 0;
  display: flex; flex-direction: column; justify-content: center;
  gap: var(--space-3); margin: var(--space-5);
  list-style: none;
  background: var(--surface-1);   /* cover the faint .hb-page behind it */
}
.hb-dim {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-2);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
.hb-dim-ico { width: 1.15em; height: 1.15em; flex: 0 0 auto; color: var(--accent-text); }
.hb-dim-label {
  flex: 1 1 auto; min-width: 0;
  font-size: var(--text-ui); font-weight: 550; color: var(--text-secondary);
}
.hb-dim-st { position: relative; flex: 0 0 auto; width: 1.25em; height: 1.25em; display: grid; place-items: center; }
.hb-dim-dot { width: .5em; height: .5em; border-radius: var(--radius-pill); background: var(--border-strong); }
.hb-dim-check { position: absolute; inset: 0; margin: auto; width: 1.25em; height: 1.25em; color: var(--sev-ok); }

/* REST = done: the dot is gone, the green check shows. */
.hb-dim-dot { opacity: 0; }
.hb-dim-check { opacity: 1; }

/* Desktop flow pin: pre-paint UNCHECKED start (dim row, dot shown, no check) so the
   scrubbed scan has somewhere to animate FROM without a load flash. routing.js then
   sets/animates the inline styles toward the done rest state above. */
html.flow-active .hb-dim { opacity: .5; }
html.flow-active .hb-dim-dot { opacity: 1; }
html.flow-active .hb-dim-check { opacity: 0; }

/* scanline beam — GSAP-driven (hero.js). Default position = vertical centre of
   the well: the static no-JS / reduced-motion floor. hero.js sets top:0 + sweeps
   `y` for motion-OK users, and reverts back to this centre on reduced-motion. */
.hb-scanline {
  position: absolute; left: 0; right: 0; top: 50%; margin-top: -1px;
  height: 2px; z-index: 1; pointer-events: none;
  background: color-mix(in oklab, var(--violet-400) 65%, transparent);
  mix-blend-mode: screen; /* reads as emitted light, like the aurora */
}
.hb-scanline::before { /* soft vertical glow falloff above/below the core */
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: var(--space-16); transform: translateY(-50%);
  background: linear-gradient(to bottom, transparent,
              color-mix(in oklab, var(--accent) 20%, transparent), transparent);
  pointer-events: none;
}

/* The hero's finding-ticket stack used to live here; it is now the shared
   .flow-travel trio in the routing section (see "FLOW STAGE" below) — the SAME
   3 tickets fake this hero-side stack at scrub t=0 and fly down to the bars, so
   there is no separate hero ticket DOM/CSS anymore. */

@media (min-width: 821px) { /* desktop: two columns, copy ~57% (≈560–580px text col) */
  .hero-inner {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: var(--space-12);
  }
  .hero-visual { justify-self: end; }
}

@media (max-width: 820px) { /* mobile: stacked, calmer/smaller mock */
  .hero-visual { max-width: 26rem; }
  .hb-viewport { min-height: clamp(15rem, 48vw, 19rem); }
}

/* ── 2 · ROUTING ──────────────────────────────────────────────────────────────
   Team-routing beat: 3 vertical "diagram bars" (Frontend / Backend / Content),
   each a recessed --ground tube that fills bottom-up with finding tickets. Depth
   model (designer-consult): head --surface-2 · tube --ground (recessed, inset
   shadow) · tickets --surface-1 (raised). Tickets STAY on --surface-1 — the
   critical priotag.p1 measures 4.7:1 there but only 4.3:1 on --surface-2 (fails
   AA), which is the load-bearing reason for the ground-tube. Lanes stay neutral
   violet; severity owns all colour (stripes, priotags, the glow). The whole
   diagram is aria-hidden; the <h2> + .lede carry meaning.

   The natural CSS state below IS the final FILLED bars — the no-JS / libs-blocked
   / reduced-motion floor. routing.js explicitly sets the clustered + hidden START
   state and scrubs it to this natural state (gsap-reveal-from-vs-css-hidden: the
   visible end state stays natural CSS, never driven by .from()). Transform/opacity
   only. Knowledge: design-system/motion/{gsap-scrolltrigger,
   gsap-scrolltrigger-pin-scrolling, gsap-reveal-from-vs-css-hidden,
   gsap-context-matchmedia, gsap-timelines, motion-defaults}. ───────────────── */
.routing { position: relative; padding-block: var(--space-section); }
.routing-inner {
  width: 100%; max-width: var(--content-max); margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex; flex-direction: column; gap: var(--space-block);
}

/* intro — centred explainer above the diagram; the only SR-meaningful content */
.routing-intro { max-width: 44rem; margin-inline: auto; text-align: center; }
.routing-h2 { margin-bottom: var(--space-5); max-inline-size: none; }
.routing-lede { max-inline-size: 52ch; margin-inline: auto; text-wrap: pretty; }

/* the 3-lane diagram (mobile-first: stacked single column) */
.routing-stage { display: grid; grid-template-columns: 1fr; gap: var(--space-6); }

/* .lane is a bare POSITIONING wrapper (no visuals): it hosts the clipped visual
   lane (.lane-clip) AND the single unclipped travelling ticket (.flow-travel),
   so the trio can fly UP-and-OUT of the tube without being clipped while the head
   + tube keep their rounded-corner clip. */
.lane { position: relative; display: flex; flex-direction: column; min-width: 0; }
.lane-clip { /* THE visual lane: rounded, bordered, clipped (was .lane) */
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  overflow: hidden; /* clip head + tube to the lane's rounded corners */
}
.lane-head {
  flex: 0 0 auto;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border-subtle);
}
.lane-name {
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--text-caption); line-height: var(--line-height-ui);
  letter-spacing: var(--tracking-overline); text-transform: uppercase;
  color: var(--text-primary); /* ≈10:1 on --surface-2 */
}

/* the tube — recessed --ground well; tickets pile at the bottom (flex-end) */
.lane-stack {
  position: relative; flex: 1 1 auto;
  min-height: clamp(12rem, 44vw, 15rem); /* mobile; desktop override below */
  display: flex; flex-direction: column; justify-content: flex-end;
  gap: var(--space-2); padding: var(--space-3);
  background: var(--ground);
  box-shadow: inset 0 2px 6px oklch(0 0 0 / .25);
}

/* ticket primitive — full lane width so it reads as a bar, not a chip */
.rt-ticket {
  position: relative;
  display: flex; align-items: stretch; gap: var(--space-2);
  width: 100%; flex: 0 0 auto;
  padding: var(--space-2);
  border-radius: var(--radius-md);
}
.rt-real { /* labeled — raised on --surface-1 (AA-safe for the priotag) */
  min-height: var(--rt-seat-h); /* deterministic seat (== .rt-slot) so the slot reserves the card's true footprint */
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  box-shadow: var(--elevation-raised), var(--highlight-top);
}
.rt-ghost { /* abstract density card — lighter, no invented text */
  min-height: 2.25rem;
  background: var(--surface-1);
  border: 1px solid var(--border-default);
  box-shadow: var(--elevation-card);
}
/* reserved foot slot — an invisible spacer the matching .flow-travel ticket lands
   OVER; the fill stacks above it. SAME height as an .rt-real (--rt-seat-h, the
   landed card's TRUE rendered footprint — not the old 3.25rem floor, which the
   2-row body exceeds): so the absolutely-positioned .flow-travel no longer overflows
   the slot's top edge, and the .lane-stack `gap` (--space-2) above the slot becomes
   the SAME even gap above the landed card. The landed ticket sits flush + the bar
   reads correct on the floor (where .flow-travel rests exactly here) and after fill. */
.rt-slot { flex: 0 0 auto; min-height: var(--rt-seat-h); width: 100%; pointer-events: none; }

/* .flow-travel — the ONE travelling P1 ticket per lane. It is a .lane child that
   sits OUTSIDE .lane-clip, absolutely pinned OVER the lane's foot slot, so its
   resting (floor) position is the landed bar ticket and it is free to fly out of
   the clipped tube. left/right/bottom mirror the tube's --space-3 padding (+1px
   for the .lane-clip border) so it lands flush over .rt-slot. */
.flow-travel {
  position: absolute; z-index: 2; margin: 0;
  /* width:auto (overriding .rt-ticket{width:100%}) so left+right actually size the
     box: the inherited width:100% on an absolute element makes width = 100% of the
     containing .lane and SILENTLY drops `right` (over-constrained), landing the
     card at the full lane width (~325px) overhanging the padded stack cards. With
     width:auto the left/right insets size it to the lane CONTENT width (lane − 2×
     (--space-3 + 1px) = the .lane-stack content box), pixel-flush with the stack
     cards + the .rt-slot it lands over. */
  width: auto;
  left: calc(var(--space-3) + 1px); right: calc(var(--space-3) + 1px);
  bottom: calc(var(--space-3) + 1px);
}

/* .rt-arrange — the priotag-on-top "hero stack" FACE of a travelling trio card
   (designer-consult). It carries a shell BYTE-IDENTICAL to the landed .rt-real
   (same --surface-1, --border-strong, --radius-md, elevation + the 3px --sev
   stripe), so the #flow scrub only ever cross-fades the TEXT LAYOUT between this
   overlay and the inline .rt-body — never the frame (no seam, no double-edge).
   Bottom-anchored to the card box (left/right/bottom:0) so it grows UPWARD into a
   roomy 3-row card while its bottom edge + stripe stay locked on the landing seat:
   as the card flies down the overlay fades and the card "collapses from the top"
   into the compact inline bar. Full-row nowrap title → all three finding titles
   fit with no truncation. display:none on the FLOOR (no-JS / reduced-motion /
   mobile) — it exists only inside the desktop+motion-OK overlay layout; the scrub
   sets opacity. Decorative twin of .rt-body (aria-hidden); the diagram is
   aria-hidden anyway, meaning lives in the h1/h2. */
.rt-arrange {
  position: absolute; z-index: 3;
  left: 0; right: 0; bottom: 0;          /* bottom-anchored → grows up */
  display: none;                          /* floor: never rendered */
  align-items: stretch; gap: var(--space-3);
  padding: var(--space-3);
  background: var(--surface-1);           /* MUST be surface-1: priotag.p1 = 4.7:1 here */
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-raised), var(--highlight-top);
  opacity: 0; pointer-events: none;
}
.rt-arrange-body {
  display: flex; flex-direction: column; justify-content: center;
  gap: var(--space-1); min-width: 0; flex: 1 1 auto;
}
.rt-arrange-body .priotag { align-self: flex-start; margin-bottom: var(--space-1); }
.rt-arrange-title {
  margin: 0; min-width: 0;
  font-family: var(--font-body); font-weight: 600; /* renders 500 today */
  font-size: var(--text-ui); line-height: var(--line-height-ui);
  color: var(--text-primary);            /* ≈12:1 on --surface-1 */
  white-space: nowrap;                   /* full row → no ellipsis (titles fit) */
}
.rt-arrange-meta {
  font-family: var(--font-mono); font-size: var(--text-micro);
  line-height: var(--line-height-ui); color: var(--text-secondary); /* ≈7:1 */
  white-space: nowrap;
}

/* .flow-scatter / .flow-ghost — decorative density cards for the #flow scatter→
   arrange AUFTAKT (the hero opening). They reuse the .rt-ticket.rt-ghost shell but
   are absolutely positioned, centred on the stack region, and live ONLY while the
   intro plays: routing.js fades them in scattered around the browser, then drifts
   them away as the trio sorts into the tidy stack — they never enter a tube or the
   fill, so there is no doubling with the lane ghosts. FLOOR / mobile / reduced-
   motion: display:none (the static design shows only the filled bars + landed
   trio). The static 1px blur is a depth cue (kept static, never tweened — a
   scrubbed filter janks). */
.flow-scatter { display: none; }
.flow-ghost {
  position: absolute; left: 74%; top: 42%;
  width: clamp(14rem, 18vw, 18rem);
  opacity: 0; pointer-events: none;
  filter: blur(1px);
}
.rt-stripe { /* severity hue; non-text → no contrast gate */
  flex: 0 0 auto; align-self: stretch; width: 3px;
  border-radius: var(--radius-pill); background: var(--sev);
}

/* SIGNATURE — prio-coloured glow pulse on the 5 labeled tickets as they land.
   opacity-driven (GPU-composited), colour from the ticket's own --sev. The inset
   left rail lights the stripe column ("along the bar edge"); the outer bloom is
   the snap-in flash. routing.js pulses opacity 0 → .5 → 0 at the landing moment.
   Non-text → no contrast gate. */
.rt-glow {
  position: absolute; inset: -1px; z-index: 0;
  border-radius: var(--radius-md); pointer-events: none; opacity: 0;
  box-shadow:
    0 0 16px -2px color-mix(in oklab, var(--sev) 45%, transparent),
    inset 2px 0 0 0 color-mix(in oklab, var(--sev) 60%, transparent),
    inset 0 0 0 1px color-mix(in oklab, var(--sev) 30%, transparent);
}

.rt-body {
  position: relative; z-index: 1; /* over the glow's inset ring */
  display: flex; flex-direction: column; justify-content: center;
  gap: var(--space-1); min-width: 0; flex: 1 1 auto;
}
.rt-row { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.rt-row .priotag { flex: 0 0 auto; }
.rt-title {
  margin: 0; min-width: 0; flex: 1 1 auto;
  font-family: var(--font-body); font-weight: 600; /* renders 500 today */
  font-size: var(--text-ui); line-height: var(--line-height-ui);
  color: var(--text-primary); /* ≈12:1 on --surface-1 */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rt-meta {
  max-width: 100%;
  font-family: var(--font-mono); font-size: var(--text-micro);
  line-height: var(--line-height-ui); color: var(--text-secondary); /* ≈7:1 */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ghost redacted bars — abstract shapes, never text */
.rt-redact { display: block; border-radius: var(--radius-pill); }
.rt-redact--a { width: 62%; height: 0.55rem; background: var(--border-default); }
.rt-redact--b { width: 42%; height: 0.45rem; background: var(--surface-3); margin-top: var(--space-1); }

@media (max-width: 820px) {
  /* mobile: keep the bars legible — trim the extra ghosts to ~2 per lane */
  .rt-ghost--extra { display: none; }
}

@media (min-width: 821px) {
  /* desktop: 3 lanes side by side; the pinned scrub stage is one viewport tall */
  .routing-stage { grid-template-columns: repeat(3, 1fr); gap: var(--space-6); align-items: stretch; }
  .lane-stack { min-height: clamp(18rem, 42svh, 23rem); }

  /* the routing section is the pinned transition stage → exactly one viewport
     tall, content centred so it sits clear of the fixed header. Applied on
     desktop generally (the reduced-motion floor just renders it static + tall). */
  .routing {
    min-height: 100svh;
    display: flex; align-items: center;
    padding-block: calc(var(--header-h) + var(--space-8)) var(--space-section);
  }
}

/* scope GPU hints to where the scrub actually plays: desktop + motion-OK */
@media (min-width: 821px) and (prefers-reduced-motion: no-preference) {
  .rt-ticket { will-change: transform, opacity; }
  .rt-glow { will-change: opacity; }
}

/* ── FLOW STAGE — the ONE-pin hero→routing transition layout ───────────────────
   FLOOR (NO html.flow-active: no-JS / reduced-motion / mobile / ≤820): #flow is a
   plain block — #hero and #routing stack as two normal full-height sections, the
   approved static design (hero readable + bars filled + the trio resting over its
   foot slot). The whole block below is gated on .flow-active, so the floor is
   untouched.

   ANIMATED (html.flow-active = desktop + motion-OK, set pre-paint by the head
   script): the two sections become absolutely-overlaid LAYERS in one 100svh pin;
   routing.js scrubs the morph + the trio flight. The hidden-START gates give the
   scrub an explicit hidden start AND stop un-morphed content flashing before the
   deferred timeline boots (gsap-reveal-from-vs-css-hidden). All travel is a pure
   transform offset within the ONE pinned #flow — no offsetTop, no cross-pin
   measuring (gsap-scrolltrigger-pin-scrolling). ── */
.flow { position: relative; }

@media (min-width: 821px) and (prefers-reduced-motion: no-preference) {
  /* overlay hero + routing + DETAIL in one viewport-tall pinned stage — ONE scene,
     so the contrast ticket can fly from the Frontend lane straight into the detail
     panel with no section seam. */
  html.flow-active #flow { height: 100svh; overflow: hidden; } /* clips the off-screen .flow-track */
  html.flow-active #flow > #hero,
  html.flow-active #flow > #routing,
  html.flow-active #flow > #detail {
    position: absolute; inset: 0; min-height: 0; margin: 0;
    padding-block: calc(var(--header-h) + var(--space-10)) var(--space-section);
  }
  /* routing above hero; detail above routing (the final scene). pointer-events off
     on the decorative routing layer so the hero CTA stays clickable through it. */
  html.flow-active #flow > #hero    { z-index: 0; padding-block: 0; }
  html.flow-active #flow > #routing { z-index: 1; pointer-events: none; padding-block: 0; }
  html.flow-active #flow > #detail  {
    z-index: 2; opacity: 0; /* hidden START — routing.js's master timeline reveals it
                               at the handoff (FOUC-safe: never flashes over the hero) */
  }
  /* in the merged scene the routing already led in → drop the detail's own intro;
     the panel is top-aligned so the flown-in contrast lands on its header. */
  html.flow-active #flow > #detail .detail-inner { height: 100%; }
  html.flow-active .detail-intro { display: none; }

  /* scatter-intro ghost layer: above the browser (z-auto, after #hero in DOM),
     BELOW the routing trio (#routing z-index:1) so the real P1 tickets read on top
     of the faint density ghosts. Shown only here (floor keeps it display:none). */
  html.flow-active .flow-scatter {
    display: block; position: absolute; inset: 0; pointer-events: none;
  }
  html.flow-active .flow-ghost { will-change: transform, opacity; }

  /* the arrange overlay exists ONLY in the animated overlay layout; the scrub
     shows it at the arrange pose and cross-fades it to the inline bar mid-flight */
  html.flow-active .rt-arrange { display: flex; will-change: opacity; }

  /* hidden START states — the timeline reveals/positions each as the scrub plays */
  html.flow-active .flow-travel        { opacity: 0; } /* lifted to the hero stack + shown at t=0 */
  html.flow-active .routing-intro > *  { opacity: 0; } /* h2 + lede rise in during the morph */
  html.flow-active .lane-clip          { opacity: 0; } /* tubes + heads rise in during the morph */
  html.flow-active .lane-stack .rt-ticket { opacity: 0; } /* fill tickets charge in during phase D */

  /* GPU hints scoped to the morphing layers (.flow-travel is also caught by the
     .rt-ticket will-change above) */
  html.flow-active .lane-clip,
  html.flow-active .hero-visual,
  html.flow-active .hero-copy { will-change: transform, opacity; }
}

/* ── 3 · DETAIL ────────────────────────────────────────────────────────────────
   The Frontend (contrast) finding opened into a full ticket-detail panel that
   mirrors the real EverAudit dashboard ticket view, with the Vorteile beside it.
   The card REUSES the landed-ticket vocabulary (--surface-1 surface, --border-
   strong, the --sev stripe + the --rt-glow settle bloom) so it reads as the SAME
   Frontend ticket, continued. data-sev="critical" on #detail resolves --sev.

   FLOOR = the full panel + Vorteile, static + readable (no-JS / reduced-motion /
   mobile). detail.js adds ONLY the desktop+motion-OK pinned "unfold" scrub; its
   hidden-start states are gated on html.detail-active (set pre-paint, mirroring
   flow-active). Tokens only — the one exception is the decorative evidence mock,
   a faux light "screenshot" panel whose literal greys intentionally demonstrate
   the low-contrast finding (aria-hidden, not part of the token-driven UI).
   Knowledge: design-system/{tokens-overview, elevation-radius-z-index,
   motion-defaults}, delivery/marketing-component-* , accessibility/wcag-aa. ── */
.detail { position: relative; padding-block: var(--space-section); }
.detail-inner {
  position: relative; /* anchor for the absolute intro overlay on the desktop scrub */
  width: 100%; max-width: var(--content-max); margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex; flex-direction: column;
}

/* intro — centred explainer above the opened ticket. In the FLOW on every floor
   (it stacks above the panel). On the desktop scrub it becomes an absolute overlay
   (see the motion media query) so the panel is already top-aligned beneath it — the
   intro can fade as the ticket descends with no layout shift / empty top gap. */
.detail-intro { max-width: 46rem; margin: 0 auto var(--space-block); text-align: center; }
.detail-h2 { margin-bottom: var(--space-5); max-inline-size: 22ch; margin-inline: auto; }
.detail-lede { max-inline-size: 56ch; margin-inline: auto; text-wrap: pretty; }

/* two columns: opened ticket (left) + Vorteile (right). Mobile-first single col. */
.detail-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-8); }

/* ── the opened ticket-detail panel (mirrors the dashboard ticket view) ──────── */
.detail-ticket {
  position: relative; isolation: isolate;
  background: var(--surface-1);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--elevation-raised), var(--highlight-top);
  padding: var(--space-6);
  padding-left: var(--space-8); /* clear the severity stripe */
}
/* severity left stripe — the dashboard's signature card accent (non-text → no gate) */
.detail-stripe {
  position: absolute; left: 0; top: 0; bottom: 0; width: 4px; z-index: 1;
  border-radius: var(--radius-lg) 0 0 var(--radius-lg);
  background: var(--sev);
}
/* settle glow — reuse .rt-glow (inset ring + bloom in --sev); widen to the card radius */
.detail-glow { border-radius: var(--radius-lg); }

.detail-head { display: flex; flex-direction: column; gap: var(--space-3); }
.detail-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.detail-id { color: var(--accent-text); } /* mono id chip (.chip base) */

/* badge — the dashboard's outline-tinted badge geometry (mono micro caps).
   Severity follows --sev; category is violet-soft; bucket is a neutral hairline. */
.badge {
  display: inline-flex; align-items: center;
  font-family: var(--font-mono); font-weight: 700; /* renders 500 today */
  font-size: var(--text-micro); line-height: var(--line-height-ui);
  letter-spacing: var(--tracking-micro); text-transform: uppercase;
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-xs);
  border: 1px solid transparent; white-space: nowrap;
}
.badge-sev {
  color: var(--sev);
  background: color-mix(in oklab, var(--sev) 15%, transparent);
  border-color: color-mix(in oklab, var(--sev) 45%, transparent);
}
.badge-cat {
  color: var(--accent-text);
  background: color-mix(in oklab, var(--accent) 16%, transparent);
  border-color: color-mix(in oklab, var(--accent) 38%, transparent);
}
.badge-bucket { color: var(--text-secondary); border-color: var(--border-strong); }

.detail-title {
  margin: 0;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.3rem, 1.1rem + 0.7vw, 1.6rem);
  line-height: var(--line-height-h4); letter-spacing: var(--tracking-h3);
  color: var(--text-primary);
}
.detail-metaline { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; margin: 0; }
.detail-wcag {
  display: inline-flex; align-items: center; gap: var(--space-1);
  color: var(--link);
  border-color: color-mix(in oklab, var(--accent) 30%, var(--border-subtle));
  transition: color var(--duration-ui) var(--easing-standard),
              border-color var(--duration-ui) var(--easing-standard);
}
.detail-wcag:hover { color: var(--link-hover); border-color: color-mix(in oklab, var(--accent) 55%, transparent); }
.detail-wcag .icon { width: .85em; height: .85em; }

/* body rows — the part that "unfolds". overflow:hidden lets detail.js collapse it to
   height 0 (the compact-ticket start) and open it as a drawer without an empty box. */
.detail-body { display: flex; flex-direction: column; gap: var(--space-4); margin-top: var(--space-5); overflow: hidden; }
.detail-field { display: flex; flex-direction: column; gap: var(--space-1); }
.detail-label {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-mono); font-weight: 500;
  font-size: var(--text-overline); line-height: var(--line-height-ui);
  letter-spacing: var(--tracking-overline); text-transform: uppercase;
  color: var(--text-muted);
}
.detail-label .icon { width: 1em; height: 1em; color: var(--text-muted); }
.detail-value {
  margin: 0; color: var(--text-secondary);
  font-size: var(--text-body); line-height: var(--line-height-body);
}
.detail-standard {
  font-family: var(--font-mono); font-size: var(--text-caption);
  line-height: var(--line-height-lead); color: var(--text-secondary);
}

/* evidence mock — decorative faux "screenshot": a low-contrast text line ringed
   with a dashed --sev outline + the measured ratio. The light panel + grey text
   are intentional literals (a real-website screenshot demonstrating the finding);
   aria-hidden, so its own low contrast is illustrative, not a defect of THIS page. */
.detail-evidence {
  margin: 0; border: 1px solid var(--border-default);
  border-radius: var(--radius-md); overflow: hidden;
  box-shadow: var(--elevation-card);
}
.ev-chrome {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-2); border-bottom: 1px solid var(--border-subtle);
}
.ev-dots { display: flex; gap: var(--space-2); flex: 0 0 auto; }
.ev-dots span { width: 7px; height: 7px; border-radius: var(--radius-pill); background: var(--border-strong); }
.ev-url {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-mono); font-size: var(--text-micro); color: var(--text-muted);
}
.ev-url .icon { width: .8em; height: .8em; }
.ev-viewport {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-5) var(--space-4);
  background: oklch(.96 .004 290); /* decorative light "page" */
}
.ev-line { display: block; height: .6rem; border-radius: var(--radius-pill); background: oklch(.86 .005 290); }
.ev-line--full { width: 100%; }
.ev-line--short { width: 52%; }
.ev-flag {
  position: relative; align-self: flex-start;
  padding: var(--space-1) var(--space-2);
  border: 2px dashed var(--sev); border-radius: var(--radius-sm);
}
.ev-faint {
  font-family: var(--font-body); font-size: var(--text-ui);
  color: oklch(.80 .004 290); /* ~2.1:1 on the light page — the finding, on purpose */
}
.ev-flag::after {
  content: attr(data-ratio);
  position: absolute; top: -10px; right: -8px;
  font-family: var(--font-mono); font-weight: 700; font-size: var(--text-micro);
  line-height: 1; padding: 2px var(--space-1); border-radius: var(--radius-xs);
  color: var(--text-on-accent); background: var(--sev);
  box-shadow: var(--shadow-1);
}

/* Lösung — the green "fixbox" callout (matches the dashboard's suggested-fix box) */
.detail-fix {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--sev-ok-soft);
  border: 1px solid color-mix(in oklab, var(--sev-ok) 40%, transparent);
  border-radius: var(--radius-md);
}
.detail-fix-label {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-mono); font-weight: 700; /* renders 500 today */
  font-size: var(--text-micro); line-height: var(--line-height-ui);
  letter-spacing: var(--tracking-micro); text-transform: uppercase;
  color: var(--sev-ok-on);
}
.detail-fix-label .icon { width: 1em; height: 1em; color: var(--sev-ok-on); }
.detail-fix .detail-value { color: var(--text-primary); }

/* ── Vorteile column ────────────────────────────────────────────────────────── */
.detail-vorteile { align-self: start; }
.detail-vorteile-h {
  margin: 0 0 var(--space-5);
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--text-h3); line-height: var(--line-height-h3);
  letter-spacing: var(--tracking-h3); color: var(--text-primary);
  text-wrap: balance; max-inline-size: 22ch;
}
.vorteile-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-5); }
.vorteil {
  display: flex; align-items: flex-start; gap: var(--space-3);
  color: var(--text-secondary);
  font-size: var(--text-body); line-height: var(--line-height-body);
}
.vorteil-mark {
  flex: 0 0 auto; margin-top: 2px;
  display: grid; place-items: center; width: 1.6rem; height: 1.6rem;
  border-radius: var(--radius-pill);
  background: var(--sev-ok-soft); color: var(--sev-ok-on);
}
.vorteil-mark .icon { width: .95rem; height: .95rem; }

@media (min-width: 821px) {
  /* the detail section is a pinned "unfold" stage → one viewport tall, centred
     clear of the fixed header (the reduced-motion floor just renders it static). */
  .detail {
    min-height: 100svh; display: flex; align-items: flex-start;
    padding-block: calc(var(--header-h) + var(--space-10)) var(--space-section);
  }
  .detail-grid {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.85fr);
    gap: var(--space-12); align-items: start;
  }
  .detail-ticket { padding: var(--space-8); padding-left: var(--space-10); }
}

/* desktop + motion-OK: the pinned scrub layer. Hidden-START states (detail.js
   reveals/positions each as the scrub plays) + GPU hints, gated on detail-active
   so the FLOOR (no class) is untouched — the full panel renders statically. The
   intro is NOT gated here: it uses the foundation reveal system so the section is
   never blank as it scrolls in. */
@media (min-width: 821px) and (prefers-reduced-motion: no-preference) {
  /* In the merged flow scene routing.js drives the whole detail reveal: the #detail
     LAYER starts opacity:0 (above), so the timeline-set start states (card opacity 0,
     body drawer height 0, Vorteile hidden) never flash. Only GPU hints live in CSS. */
  html.flow-active .detail-ticket,
  html.flow-active .detail-body,
  html.flow-active .detail-vorteile-h,
  html.flow-active .vorteil { will-change: transform, opacity; }
}

/* ── §4–6 · FILMSTRIP — der ganze Auditor (horizontal pan) ───────────────────
   FLOOR (mobile ≤820 / reduced-motion / no-JS): the three stages stack vertically
   as normal full-bleed sections, static. Under html.flow-active (desktop+motion-OK)
   .flow-track becomes a 3-wide horizontal row — a LAYER inside the ONE #flow pin that
   routing.js translateX-es after the §3 detail. Per-stage data-sev tints the kicker
   + the thread (cookies critical · architektur minor/depth · export ok). Token-only. */
.flow-track { display: flex; flex-direction: column; } /* floor: stack the stages */
.strip-stage { position: relative; padding-block: var(--space-section); }
.stage-inner {
  width: 100%; max-width: var(--content-max); margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex; flex-direction: column; gap: var(--space-block);
}
.stage-intro { max-width: 46rem; }
.stage-intro .kicker {
  display: inline-flex; align-items: center; gap: var(--space-2);
  color: var(--sev, var(--accent-text));
}
.stage-intro .kicker .icon { width: 1.15em; height: 1.15em; }
.stage-h2 { margin-bottom: var(--space-4); max-inline-size: 20ch; }
.stage-lede { max-inline-size: 56ch; }
.stage-scene { position: relative; }
.strip-thread { display: none; } /* shown only on the desktop horizontal pan */

@media (min-width: 821px) {
  /* desktop floor: each stage one viewport tall (stacked); two-column inner. */
  .strip-stage {
    min-height: 100svh; display: flex; align-items: center;
    padding-block: calc(var(--header-h) + var(--space-8)) var(--space-section);
  }
  .flow-track .stage-inner {
    display: grid; grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
    gap: var(--space-12); align-items: center;
  }
  .flow-track .stage-intro { max-width: none; }
  /* the architektur scene needs room for node-web + sidebar → fixed-width intro,
     the rest to the scene (web left-docked, sidebar right-docked, no overlap). */
  .flow-track #stage-arch .stage-inner { grid-template-columns: 21rem minmax(0, 1fr); }
}

@media (min-width: 821px) and (prefers-reduced-motion: no-preference) {
  /* the horizontal track as a #flow LAYER (one continuous pin): a 3-wide row,
     z-3 above the detail (z-2), parked off-screen right (translateX 100vw) until
     routing.js turns the camera and pans it. #flow clips the overflow. */
  html.flow-active #flow > .flow-track {
    position: absolute; inset: 0; z-index: 3;
    flex-direction: row; width: 300vw; height: 100svh;
    transform: translateX(100vw); will-change: transform;
  }
  html.flow-active .flow-track .strip-stage {
    flex: 0 0 100vw; width: 100vw; height: 100svh; min-height: 0;
    padding-block: calc(var(--header-h) + var(--space-8)) var(--space-section);
  }
  /* the travelling thread — a constant severity baseline across the three scenes
     (the §1–3 red thread, continued horizontally; spans the full 300vw track). */
  html.flow-active .flow-track .strip-thread {
    display: block; position: absolute; left: 0; right: 0; bottom: 20%;
    height: 2px; z-index: 0; pointer-events: none;
    background: linear-gradient(90deg, transparent, var(--sev-critical) 8%, var(--sev-serious) 50%, var(--sev-ok) 92%, transparent);
    opacity: .45;
  }
}

/* ── §4 · COOKIES scene ─────────────────────────────────────────────────────── */
.stage-scene[data-scene="cookies"] { position: relative; }
.cookie-prop {
  position: absolute; top: -2.6rem; right: 6%; z-index: 2;
  display: grid; place-items: center; width: 4.5rem; height: 4.5rem;
  color: var(--sev-serious); filter: drop-shadow(0 10px 22px oklch(0 0 0 / .45));
}
.cookie-prop .icon { width: 4.5rem; height: 4.5rem; stroke-width: 1.5; }
.cov-panel {
  position: relative; background: var(--surface-1);
  border: 1px solid var(--border-strong); border-radius: var(--radius-lg);
  box-shadow: var(--elevation-raised), var(--highlight-top); padding: var(--space-6);
}
.cov-head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-2); }
.cov-icon { width: 1.25em; height: 1.25em; color: var(--sev-serious); flex: 0 0 auto; }
.cov-title { font-family: var(--font-display); font-weight: 600; font-size: var(--text-h4); color: var(--text-primary); }
.cov-badge {
  margin-left: auto; font-family: var(--font-mono); font-weight: 700;
  font-size: var(--text-micro); text-transform: uppercase; letter-spacing: var(--tracking-micro);
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-xs);
  color: var(--sev-critical-on); background: var(--sev-critical-soft);
  border: 1px solid color-mix(in oklab, var(--sev-critical) 40%, transparent);
}
.cov-sub { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--text-muted); margin: 0 0 var(--space-4); }
.cov-list { list-style: none; margin: 0 0 var(--space-4); padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.cov-row {
  position: relative; display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-md);
  background: var(--surface-2); border: 1px solid var(--border-subtle);
}
.cov-mark { flex: 0 0 auto; display: grid; place-items: center; width: 1.4rem; height: 1.4rem; }
.cov-mark .icon { width: 1.4rem; height: 1.4rem; }
.cov-row[data-cov="ok"]  .cov-mark { color: var(--sev-ok); }
.cov-row[data-cov="bad"] .cov-mark { color: var(--sev-critical); }
.cov-row[data-cov="bad"] { border-color: color-mix(in oklab, var(--sev-critical) 30%, transparent); }
.cov-tool { font-weight: 500; color: var(--text-primary); font-size: var(--text-ui); }
.cov-dom { margin-left: auto; font-family: var(--font-mono); font-size: var(--text-micro); color: var(--text-secondary); }
.cov-foot { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-caption); color: var(--text-secondary); margin: 0; }
.cov-foot .icon { width: 1em; height: 1em; color: var(--text-muted); flex: 0 0 auto; }

/* hidden-start states for the scene visuals — gated on flow-active (desktop+motion),
   so the floor renders them statically; routing.js reveals them during the cookies dwell. */
@media (min-width: 821px) and (prefers-reduced-motion: no-preference) {
  html.flow-active .cookie-prop,
  html.flow-active .cov-panel,
  html.flow-active .cov-row { opacity: 0; }
  html.flow-active .cov-panel, html.flow-active .cookie-prop { will-change: transform, opacity; }
}

/* ── §5 · ARCHITEKTUR scene — the crawl graph as a node-web + node-detail sidebar ──
   Nodes sized by inbound links, coloured by depth (violet ramp), noindex = dashed ring
   (non-colour signal). One node focuses → the sidebar slides in (mirrors the real
   ArchitecturePanel sidebar; reuses the mono/chip/severity vocabulary). Token-only. */
.stage-scene[data-scene="architecture"] { position: relative; }
.arch-stage { position: relative; width: 100%; }
/* narrower + left-aligned so the focus node clears the right-docked sidebar. */
.arch-web { display: block; width: min(100%, 36rem); height: auto; max-height: 62svh; overflow: visible; }

.arch-edge { stroke: var(--violet-600); opacity: .45; stroke-dasharray: 1; stroke-linecap: round; }
.arch-edge-cross { opacity: .28; }

.arch-node { transform-box: fill-box; transform-origin: center; }
.arch-node[data-depth="0"] { fill: var(--accent); }
.arch-node[data-depth="1"] { fill: var(--violet-400); }
.arch-node[data-depth="2"] { fill: var(--violet-600); }
.arch-node[data-depth="3"] { fill: var(--violet-700); }
.arch-node.is-focus { fill: var(--accent); }
.arch-node.is-noindex { stroke: var(--text-muted); stroke-width: 1.5; stroke-dasharray: 3 2.5; }
.arch-focus-ring { fill: none; stroke: var(--accent); stroke-width: 2; opacity: 0;
  transform-box: fill-box; transform-origin: center; }

.arch-label { fill: var(--text-secondary); font-family: var(--font-mono); font-size: var(--text-caption); text-anchor: middle; }
.arch-label.is-focus-label { fill: var(--text-primary); }

.arch-summary {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); margin: var(--space-5) 0 0;
  font-family: var(--font-mono); font-size: var(--text-caption); color: var(--text-muted);
}
.arch-summary b { color: var(--text-secondary); font-weight: 600; }

/* the node-detail sidebar — slides in from the right when a node focuses. */
.arch-sidebar {
  position: relative; width: min(17rem, 94%); margin-top: var(--space-5); /* floor: below the web */
  background: var(--surface-1); border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg); box-shadow: var(--elevation-raised), var(--highlight-top);
  padding: var(--space-5);
}
.as-head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); }
.as-head .icon { width: 1.1em; height: 1.1em; color: var(--accent-text); flex: 0 0 auto; }
.as-url { font-family: var(--font-mono); font-size: var(--text-ui); color: var(--text-primary); font-weight: 600; }
.as-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-4); }
.as-chip {
  font-family: var(--font-mono); font-size: var(--text-micro);
  padding: var(--space-1) var(--space-2); border-radius: var(--radius-xs);
  background: var(--surface-3); color: var(--text-secondary); border: 1px solid var(--border-subtle);
}
.as-chip.is-hub { color: var(--accent-text); border-color: color-mix(in oklab, var(--accent) 35%, transparent); }
.as-chip.is-ok { color: var(--sev-ok-on); background: var(--sev-ok-soft); border-color: color-mix(in oklab, var(--sev-ok) 35%, transparent); }
.as-rows { margin: 0 0 var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.as-row { display: flex; align-items: center; justify-content: space-between; font-size: var(--text-caption); }
.as-row dt { color: var(--text-muted); }
.as-row dd { margin: 0; color: var(--text-secondary); font-family: var(--font-mono); display: flex; align-items: center; gap: var(--space-2); }
.as-dot { width: .6rem; height: .6rem; border-radius: var(--radius-pill); background: var(--text-muted); }
.as-dot[data-sev="moderate"] { background: var(--sev-moderate); }
.as-insights { border-top: 1px solid var(--border-subtle); padding-top: var(--space-3); }
.as-ins-h { font-family: var(--font-mono); font-size: var(--text-micro); text-transform: uppercase; letter-spacing: var(--tracking-micro); color: var(--text-muted); margin: 0 0 var(--space-2); }
.as-ins { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-caption); color: var(--text-secondary); margin: 0 0 var(--space-1); }
.as-ins .icon { width: 1em; height: 1em; flex: 0 0 auto; }
.as-ins.is-ok .icon { color: var(--sev-ok); }
.as-ins.is-warn .icon { color: var(--sev-moderate); }

/* hidden-start gates (desktop+motion) — revealed by routing.js during the arch dwell.
   Edges use stroke-dashoffset (set by gsap) to "draw", so they're not opacity-gated. */
@media (min-width: 821px) and (prefers-reduced-motion: no-preference) {
  html.flow-active .arch-node,
  html.flow-active .arch-label,
  html.flow-active .arch-summary,
  html.flow-active .arch-sidebar { opacity: 0; }
  /* desktop+motion: the sidebar docks to the right of the scene (slides in on focus). */
  html.flow-active .arch-sidebar { will-change: transform, opacity; position: absolute; top: 3%; right: 0; margin-top: 0; }
}

/* ── §6 · KUNDENEXPORT scene — curate by tier (WIDE + readable) → the report shrinks
   into an envelope that lifts off → a delivery receipt. Reuses .priotag + card/mono
   vocab. Numbers illustrative. Token-only. ──────────────────────────────────────── */
.stage-scene[data-scene="export"] { position: relative; }
.exp-stage { position: relative; width: 100%; min-height: 24rem; }

.exp-curate {
  width: 100%; background: var(--surface-1); border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg); box-shadow: var(--elevation-raised), var(--highlight-top); padding: var(--space-5);
}
.exp-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); flex-wrap: wrap; }
.exp-count { position: relative; font-size: var(--text-ui); color: var(--text-secondary); }
.exp-count .exp-n { font-family: var(--font-mono); font-weight: 700; color: var(--text-primary); }
.exp-count .exp-n11 { position: absolute; left: 0; top: 0; opacity: 0; } /* cross-fades over 12 on exclude */
.exp-tiers { display: flex; gap: var(--space-1); }
.exp-list { list-style: none; margin: 0; padding: 0; }
.exp-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-1); }
.exp-row + .exp-row { border-top: 1px solid var(--border-subtle); }
.exp-prio { display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--font-mono); font-size: var(--text-micro); color: var(--text-muted); flex: 0 0 4rem; }
.priodot { width: .55rem; height: .55rem; border-radius: var(--radius-pill); flex: 0 0 auto; }
.priodot.p1 { background: var(--sev-critical); } .priodot.p2 { background: var(--sev-serious); } .priodot.p3 { background: var(--sev-minor); }
.exp-cat { font-family: var(--font-mono); font-size: var(--text-micro); color: var(--text-secondary); flex: 0 0 7rem; }
.exp-t { font-size: var(--text-ui); color: var(--text-primary); flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.exp-eye { display: grid; place-items: center; width: 1.4rem; height: 1.4rem; color: var(--text-muted); flex: 0 0 auto; }
.exp-eye .icon { width: 1.05rem; height: 1.05rem; }
.exp-row.exp-drop .exp-eye { color: var(--sev-critical); }
.exp-check { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-4); font-size: var(--text-caption); color: var(--text-secondary); }
.exp-box { display: grid; place-items: center; width: 1.2rem; height: 1.2rem; border-radius: var(--radius-xs); border: 1.5px solid var(--border-strong); color: var(--sev-ok); flex: 0 0 auto; }
.exp-box .icon { width: .9rem; height: .9rem; opacity: 0; }

/* the send — FLOOR: the delivery receipt flows below the curate (static "sent" state);
   the envelope is the desktop send gesture only (hidden on the floor). */
.exp-send { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-3); text-align: center; margin-top: var(--space-7); }
.exp-envelope { display: none; color: var(--accent-text); filter: drop-shadow(0 10px 22px oklch(0 0 0 / .4)); }
.exp-envelope .icon { width: 4.5rem; height: 4.5rem; stroke-width: 1.4; }
.exp-receipt { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); }
.exp-receipt-check { width: 2.4rem; height: 2.4rem; color: var(--sev-ok); }
.exp-receipt-h { font-family: var(--font-display); font-weight: 600; font-size: var(--text-h4); color: var(--text-primary); }
.exp-receipt-meta { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--text-muted); }

@media (min-width: 821px) {
  .flow-track #stage-export .stage-inner { grid-template-columns: 21rem minmax(0, 1fr); }
}

/* hidden-start gates + the send overlay (desktop+motion) — revealed by routing.js. */
@media (min-width: 821px) and (prefers-reduced-motion: no-preference) {
  html.flow-active .exp-row,
  html.flow-active .exp-check,
  html.flow-active .exp-envelope,
  html.flow-active .exp-receipt { opacity: 0; }
  /* the send is the centered inset overlay; envelope + receipt stack at the centre (the
     report shrinks into the envelope, it lifts off, then the receipt rises). */
  html.flow-active .exp-stage { display: grid; place-items: center; } /* centres the curate so it shrinks onto the envelope */
  html.flow-active .exp-send { position: absolute; inset: 0; margin-top: 0; display: grid; place-items: center; }
  html.flow-active .exp-send > * { grid-area: 1 / 1; }
  html.flow-active .exp-envelope { display: grid; place-items: center; }
  html.flow-active .exp-curate, html.flow-active .exp-envelope, html.flow-active .exp-receipt { will-change: transform, opacity; }
}

/* ── §7 · WARUM / VORTEILE ────────────────────────────────────────────────────
   Vertical closing beat after the filmstrip: differentiator cards + a semantic
   comparison table. Reuses .beat/.beat-inner/.card + the standard reveal system. */
.warum-intro { max-width: 48rem; margin: 0 auto var(--space-10); text-align: center; }
.warum-h2 { text-wrap: balance; margin: 0 0 var(--space-5); }
.warum-lede { max-inline-size: 58ch; margin-inline: auto; text-wrap: pretty; }

.warum-cards { display: grid; grid-template-columns: 1fr; gap: var(--space-6); }
.warum-card {
  padding: var(--space-card); display: flex; flex-direction: column; gap: var(--space-3);
  /* no transform here: the reveal system drives transform via GSAP inline styles,
     so hover feedback is elevation + border only (transform would be overridden). */
  transition: border-color var(--duration-ui) var(--easing-standard),
              box-shadow var(--duration-ui) var(--easing-standard);
}
.warum-card:hover { border-color: var(--border-default); box-shadow: var(--elevation-raised), var(--highlight-top); }
.warum-card-ico {
  display: inline-grid; place-items: center;
  width: 2.5rem; height: 2.5rem; border-radius: var(--radius-md);
  background: color-mix(in oklab, var(--accent) 12%, transparent);
  color: var(--accent-text);
  transition: transform var(--duration-medium) var(--easing-reveal);
}
.warum-card:hover .warum-card-ico { transform: scale(1.08) rotate(-3deg); }
.warum-card-ico .icon { width: 1.3rem; height: 1.3rem; }
.warum-card-t { font-size: var(--text-h4); margin: 0; color: var(--text-primary); }
.warum-card-b { font-size: var(--text-body); color: var(--text-secondary); margin: 0; }

/* comparison table — horizontal-scrollable on narrow viewports (min-width forces it).
   `overflow-x: clip` on the section guards the document: a horizontally-scrollable
   child (.cmp-scroll) otherwise leaks its scroll width up to the page (Chromium),
   which would make the whole layout scroll sideways < ~640px. The table still
   scrolls inside .cmp-scroll; the section just can't widen the page. */
.warum { overflow-x: clip; position: relative; isolation: isolate; }
/* ambient drifting accent glow behind the whole closing beat — pure decoration,
   pointer-inert, and frozen for reduced-motion users by the global animation-kill. */
.warum::before {
  content: ""; position: absolute; inset: -10% 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(38rem 26rem at 14% 10%, color-mix(in oklab, var(--accent) 13%, transparent), transparent 70%),
    radial-gradient(34rem 24rem at 88% 82%, color-mix(in oklab, var(--violet-400) 11%, transparent), transparent 70%);
  animation: warum-drift 19s var(--easing-standard) infinite alternate;
}
@keyframes warum-drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(0, -2.5%, 0) scale(1.07); }
}
.cmp { margin-top: var(--space-16); }
/* the scroll wrapper doubles as the table's visible frame (bordered surface). */
.cmp-scroll {
  overflow-x: auto; border-radius: var(--radius-lg);
  border: 1px solid var(--border-subtle); background: var(--surface-1);
  box-shadow: var(--elevation-card), var(--highlight-top);
}
.cmp-scroll:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 2px; }
.cmp-table { width: 100%; border-collapse: collapse; min-width: 40rem; font-size: var(--text-ui); }
.cmp-table th, .cmp-table td {
  padding: var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
  text-align: center; vertical-align: middle;
}
.cmp-table thead th { padding-block: var(--space-3); color: var(--text-secondary); font-weight: 600; }
.cmp-table tbody th[scope="row"], .cmp-feature-h {
  text-align: left; color: var(--text-primary); font-weight: 500;
  white-space: normal; min-width: 14rem;
}
/* EverAudit column emphasis — a tinted, accent-capped column that "floats" above
   the comparators. Cells transition so the row-hover lift below reads smoothly. */
.cmp-table .cmp-ea { background: color-mix(in oklab, var(--accent) 11%, transparent); transition: background var(--duration-ui) var(--easing-standard); }
.cmp-table thead .cmp-ea {
  color: var(--text-primary); font-weight: 700;
  border-bottom: 2px solid var(--accent);
  box-shadow: inset 0 3px 0 color-mix(in oklab, var(--accent) 60%, transparent);
}
.cmp-table tbody th[scope="row"], .cmp-table tbody td { transition: background var(--duration-ui) var(--easing-standard); }
.cmp-table tbody tr:hover th[scope="row"], .cmp-table tbody tr:hover td { background: color-mix(in oklab, var(--surface-3) 55%, transparent); }
.cmp-table tbody tr:hover .cmp-ea { background: color-mix(in oklab, var(--accent) 18%, transparent); }
.cmp-table tbody tr:last-child th, .cmp-table tbody tr:last-child td { border-bottom: 0; }

.cmp-mark { display: inline-grid; place-items: center; width: 1.5rem; height: 1.5rem; }
.cmp-mark .icon { width: 1.15rem; height: 1.15rem; }
.cmp-yes { color: var(--sev-ok); }
.cmp-no { color: var(--text-muted); opacity: .55; }
.cmp-partial { color: var(--text-muted); font-weight: 600; }

.cmp-note { margin: var(--space-5) 0 0; font-size: var(--text-caption); color: var(--text-muted); text-align: center; text-wrap: pretty; }

/* the CTA is the final beat — a hairline rule sets it apart from the table above. */
.warum-cta {
  margin-top: var(--space-16); padding-top: var(--space-12);
  border-top: 1px solid var(--border-subtle);
  display: flex; flex-direction: column; align-items: center; gap: var(--space-3); text-align: center;
}
.warum-cta-sub { font-size: var(--text-body); color: var(--text-muted); margin: 0; }
/* the final Magic-Link button gets a playful breathing halo (pulsing box-shadow —
   NOT clipped by overflow, unlike a pseudo) + a periodic shine sweep (::after,
   clipped to the button via overflow), and a slightly bigger lift on hover. */
.warum-cta .btn-primary { position: relative; overflow: hidden; animation: cta-halo 3s var(--easing-standard) infinite; }
.warum-cta .btn-primary::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 38%, oklch(1 0 0 / .35) 50%, transparent 62%);
  transform: translateX(-130%); animation: cta-shine 4.5s var(--easing-standard) 1s infinite;
}
.warum-cta .btn-primary:hover { transform: translateY(-2px) scale(1.03); }
@keyframes cta-halo {
  0%, 100% { box-shadow: 0 0 0 0 transparent, var(--glow-accent), var(--highlight-top); }
  50%      { box-shadow: 0 0 28px 2px color-mix(in oklab, var(--accent) 55%, transparent), var(--glow-accent), var(--highlight-top); }
}
@keyframes cta-shine { 0% { transform: translateX(-130%); } 45%, 100% { transform: translateX(130%); } }

/* Zeitersparnis — Rechenbeispiel (echte effortTotals aus dem Audit). */
.warum-zeit {
  margin-top: var(--space-16); padding: var(--space-8); position: relative;
  /* reveal drives transform via GSAP inline styles → hover feedback is elevation only. */
  transition: box-shadow var(--duration-ui) var(--easing-standard);
}
.warum-zeit:hover { box-shadow: var(--elevation-raised), var(--highlight-top); }
.warum-zeit-head { margin-bottom: var(--space-6); }
.warum-zeit-badge {
  display: inline-block; margin-bottom: var(--space-3);
  font-size: var(--text-overline); text-transform: uppercase; letter-spacing: .08em; font-weight: 600;
  color: var(--accent-text); padding: .2em .8em; border-radius: var(--radius-pill);
  border: 1px solid color-mix(in oklab, var(--accent) 40%, transparent);
}
.warum-zeit-t { font-size: var(--text-h3); margin: 0 0 var(--space-2); color: var(--text-primary); text-wrap: balance; }
.warum-zeit-run { margin: 0; font-family: var(--font-mono); font-size: var(--text-caption); color: var(--text-muted); }
.warum-zeit-body { display: grid; grid-template-columns: 1fr; gap: var(--space-6); align-items: stretch; }
.warum-zeit-figure {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; flex-direction: column; justify-content: center; gap: var(--space-1);
  padding: var(--space-6); border-radius: var(--radius-md);
  background:
    radial-gradient(120% 120% at 0% 0%, color-mix(in oklab, var(--accent) 20%, transparent), transparent 60%),
    color-mix(in oklab, var(--accent) 9%, transparent);
  border: 1px solid color-mix(in oklab, var(--accent) 28%, transparent);
  box-shadow: inset 0 1px 0 oklch(1 0 0 / .06), 0 0 32px -12px color-mix(in oklab, var(--accent) 45%, transparent);
}
/* slow diagonal light-sweep across the figure — paused for reduced-motion users
   by the global animation-kill below. */
.warum-zeit-figure::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(115deg, transparent 30%, oklch(1 0 0 / .07) 48%, transparent 62%);
  transform: translateX(-110%); animation: zeit-sheen 7s var(--easing-standard) 1.5s infinite;
}
@keyframes zeit-sheen { 0% { transform: translateX(-110%); } 35%, 100% { transform: translateX(110%); } }
.warum-zeit-num {
  font-size: clamp(2.4rem, 1.6rem + 2.6vw, 3.25rem); font-weight: 700; line-height: 1; letter-spacing: -0.01em;
  text-wrap: nowrap;
  background: var(--grad-hero-text); -webkit-background-clip: text; background-clip: text; color: transparent;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .warum-zeit-num { color: var(--text-primary); }
}
.warum-zeit-days { font-size: var(--text-lead); font-weight: 600; color: var(--accent-text); }
.warum-zeit-lbl { margin-top: var(--space-3); font-size: var(--text-ui); line-height: var(--line-height-ui); color: var(--text-secondary); text-wrap: pretty; }
.warum-zeit-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-4); }
.warum-zeit-list li { display: flex; gap: var(--space-3); align-items: flex-start; font-size: var(--text-body); color: var(--text-secondary); }

/* Was wir prüfen — 5 Dimensionen als native <details>-Dropdowns.
   interpolate-size scoped here so the ::details-content height can animate to/from
   the keyword `auto` (Chromium 131+); older engines fall back to the native snap. */
.warum-dims { margin-top: var(--space-16); interpolate-size: allow-keywords; }
.warum-dims-intro { max-width: 46rem; margin: 0 auto var(--space-8); text-align: center; }
.warum-dims-h { font-size: var(--text-h3); margin: 0 0 var(--space-2); text-wrap: balance; }
.warum-dims-sub { margin: 0; font-size: var(--text-body); color: var(--text-muted); }
.warum-dims-list { display: flex; flex-direction: column; gap: var(--space-3); max-width: 56rem; margin: 0 auto; }
.dim {
  background: var(--surface-1); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md); overflow: hidden;
  transition: border-color var(--duration-ui) var(--easing-standard),
              box-shadow var(--duration-ui) var(--easing-standard);
}
.dim:hover { border-color: var(--border-default); }
.dim[open] { border-color: var(--border-default); box-shadow: var(--elevation-card), var(--highlight-top); }
/* smooth open/close — animate the content box height + fade (Chromium 131+). */
.dim::details-content {
  block-size: 0; overflow: clip; opacity: 0;
  transition: block-size var(--duration-medium) var(--easing-reveal),
              opacity var(--duration-medium) var(--easing-standard),
              content-visibility var(--duration-medium) var(--easing-standard) allow-discrete;
}
.dim[open]::details-content { block-size: auto; opacity: 1; }
.dim-sum {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-4) var(--space-5); cursor: pointer; list-style: none; user-select: none;
  transition: background var(--duration-ui) var(--easing-standard);
}
.dim-sum:hover { background: color-mix(in oklab, var(--surface-3) 45%, transparent); }
.dim-sum::-webkit-details-marker { display: none; }
.dim-sum:focus-visible { outline: 2px solid var(--accent-text); outline-offset: -2px; }
.dim-ico {
  flex: 0 0 auto; display: inline-grid; place-items: center; width: 2rem; height: 2rem;
  border-radius: var(--radius-sm); color: var(--accent-text);
  background: color-mix(in oklab, var(--accent) 12%, transparent);
}
.dim-ico .icon { width: 1.1rem; height: 1.1rem; }
.dim-name { font-size: var(--text-h4); font-weight: 600; color: var(--text-primary); }
.dim-count { margin-left: auto; font-size: var(--text-caption); color: var(--text-muted); }
.dim-chev { flex: 0 0 auto; color: var(--text-muted); transition: transform .2s ease; }
.dim-chev .icon { display: block; width: 1.1rem; height: 1.1rem; }
.dim[open] .dim-chev { transform: rotate(180deg); }
.dim-cats {
  list-style: none; margin: 0;
  padding: 0 var(--space-5) var(--space-5) calc(var(--space-5) + 2rem + var(--space-3));
  display: flex; flex-direction: column; gap: var(--space-3);
}
.dim-cats li { display: flex; flex-direction: column; gap: 2px; }
.dim-cat-n { font-size: var(--text-ui); font-weight: 550; color: var(--text-primary); }
.dim-cat-d { font-size: var(--text-caption); color: var(--text-muted); }

@media (min-width: 821px) {
  .warum-cards { grid-template-columns: repeat(4, 1fr); }
  .warum-zeit { padding: var(--space-10); }
  .warum-zeit-body { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); gap: var(--space-10); }
}
@media (min-width: 600px) and (max-width: 820px) { .warum-cards { grid-template-columns: repeat(2, 1fr); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}
