/* =========================================================================
   AIngels — Design System
   Hell & luftig · Off-White als Basis · Tannengrün & Gold als Akzente
   Ruhig, großzügig, zurückhaltend (Referenz-Ästhetik: Clay, invertiert)
   Mobile-first, kein Framework, kein Build-Schritt
   ========================================================================= */

/* ------------------------------------------------------------------ Fonts */

/* Inter Tight — Fließtext. Selbst gehostet als Variable-Font (latin),
   deckt die gesamte Gewichtsachse ab (u. a. 400/500/700/800). Kein externes CDN (DSGVO). */
@font-face {
  font-family: "Inter Tight";
  font-style: normal;
  font-weight: 100 900;   /* Variable-Font: gesamte Achse */
  font-display: swap;
  src: url("assets/fonts/intertight-var.woff2") format("woff2");
}

/* JetBrains Mono — Variable-Font, Achse 300-700 (SIL Open Font License 1.1).
   Rolle: Headlines, Labels, Zahlen, technische Angaben. Niemals Fließtext.
   Selbst gehostet, kein Google-CDN — die Datenschutzerklärung sagt zu, dass
   beim Seitenaufruf keine Verbindung zu Dritten aufgebaut wird.
   Zwei Subsets: latin deckt Umlaute/ß ab, latin-ext u. a. €-nahe Zeichen. */
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("assets/fonts/jetbrainsmono-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("assets/fonts/jetbrainsmono-var-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --------------------------------------------------------------- Tokens */
:root {
  /* ==== PALETTE — Quelle der Wahrheit =================================
     Kontrastwerte geprüft mit WCAG 2.1 (siehe Kommentare). Regel:
     --gold NUR auf dunklem Grund, --gold-dark NUR auf hellem Grund. */
  --void:      #030405;   /* Bühne, Scan-Terrain */
  --paper:     #FAFAF8;   /* heller Grund, Off-White */
  --ink:       #0F1E17;   /* dunkles Tannengrün — Flächen, Buttons */
  --gold:      #C6A15B;   /* Akzent auf DUNKEL — 8.45:1 auf --void  ✓ AA */
  --gold-dark: #8A6F35;   /* Akzent auf HELL   — 4.56:1 auf --paper ✓ AA */
  --ok:        #4E9E72;   /* Status gut     — 6.31:1 auf --void ✓ AA */
  --warn:      #C77A3A;   /* Status Achtung — 6.13:1 auf --void ✓ AA */

  /* Statusfarben für hellen Grund. --ok/--warn reißen dort AA (3.1:1),
     deshalb eigene, abgedunkelte Varianten für Kleintext. */
  --ok-dark:   #3F805C;   /* 4.51:1 auf --paper ✓ AA */
  --warn-dark: #A36430;   /* 4.54:1 auf --paper ✓ AA */

  /* Fehlerfarbe — von der Vorgabe nicht benannt, für Formularmeldungen
     aber unverzichtbar. Nach demselben Muster wie --ok/--warn geprüft. */
  --err:       #E8796C;   /* 7.21:1 auf --void  ✓ AAA */
  --err-dark:  #A32B22;   /* 6.87:1 auf --paper ✓ AA (auch für 10px Mono) */

  /* ==== ROLLEN AUF DUNKLEM GRUND (Stage, Seitenköpfe) ================= */
  --d-txt:    #EDEEEC;                  /* 17.63:1 ✓ AAA */
  --d-txt-2:  #9DA09C;                  /*  7.76:1 ✓ AAA */
  --d-txt-3:  #747773;                  /*  4.52:1 ✓ AA — Kleinstlabels */
  --d-line:   rgba(255, 255, 255, 0.36);
  --d-line-2: rgba(255, 255, 255, 0.12);
  --d-panel:  rgba(3, 4, 5, 0.34);      /* Wireframe-Panel-Füllung */

  /* ==== ROLLEN AUF HELLEM GRUND ======================================= */
  --l-txt:    #12160F;                  /* 17.51:1 ✓ AAA — Headlines */
  --l-txt-2:  #4A524D;                  /*  7.71:1 ✓ AAA — Fließtext */
  --l-txt-3:  #6E7570;                  /*  4.52:1 ✓ AA  — Meta, Ticks */
  --l-line:   rgba(26, 29, 27, 0.15);
  --l-line-2: rgba(26, 29, 27, 0.085);
  --l-panel:  #FFFFFF;
  --grid-line: #E4E6E2;                 /* 1px-Raster zwischen Zellen */

  /* ==== TYPOGRAFIE ====================================================
     Zwei Familien mit strikt getrennten Rollen:
       --font-mono  Headlines, Labels, Zahlen, technische Angaben.
                    Immer uppercase, letter-spacing aus der Tracking-Skala.
       --font-sans  Fließtext. Niemals Mono für Fließtext.             */
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono",
               Menlo, Consolas, "Liberation Mono", monospace;
  --font:       "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;

  /* Tracking-Skala für Mono-Versalien (Vorgabe: .03em bis .24em) */
  /* Ausnahme unterhalb der Skala: Mono in NORMALSCHREIBUNG. Die Skala ist
     für Versalien gerechnet — bei Gemischtschreibung fallen die Wortbilder
     bei positivem Tracking auseinander. */
  --track-0: -0.01em;
  --track-1: 0.03em;   /* große Headlines */
  --track-2: 0.06em;   /* Zwischenheadlines */
  --track-3: 0.10em;   /* Pills, Statuszeilen */
  --track-4: 0.15em;   /* Panel-Köpfe, Zellennummern */
  --track-5: 0.18em;   /* Eckmarken, Ticks */
  --track-6: 0.22em;   /* HUD, Kicker */
  --track-7: 0.24em;   /* Stage-Kicker, weiteste Stufe */

  /* Mono-Größenstufen — bewusst klein, technisch */
  --mono-xs:  0.469rem;  /* 7.5px — Panel-Kopf, Pills */
  --mono-sm:  0.531rem;  /* 8.5px — Panel-Zeilen */
  --mono-md:  0.5625rem; /* 9px   — Ticks, Zellennummern */
  --mono-lg:  0.625rem;  /* 10px  — HUD, Kicker */
  --mono-xl:  0.6875rem; /* 11px  — Buttons */
  --font-sans:  var(--font);

  /* Maße & Rhythmus */
  --container: 1180px;
  --pad-inline: clamp(1.5rem, 5vw, 3rem);
  --header-h: 76px;
  --radius-sm: 4px;   /* nur noch Kleinteile: Nav-Radius, Skip-Link */
  --radius-lg: 22px;  /* große eigenständige Flächen: Abschlussblock */

  /* Abschlussblock — eigene Maße, weil er als einziges Element aus dem
     Container ausbricht und bis dicht an den Viewportrand läuft. */
  --block-inset: 5vw;   /* Abstand des Blocks zum Viewportrand */
  /* Deckel für die Breite: etwas weiter als der Textcontainer (1180px),
     damit der Block über die Konsole hinausgeht — aber nicht randlos. */
  --block-max: 1400px;
  --block-h: 400px;     /* Mindesthöhe Desktop */
  --block-h-sm: 320px;  /* Mindesthöhe Mobile */
  /* Abdunklung zwischen Visual und Text. --ink mit Deckkraft: hält den
     Grundton der Fläche, auch wenn später ein buntes Bild darunterliegt. */
  --scrim: rgba(15, 30, 23, 0.58);

  /* Abstände — Vielfache von 8px */
  --space-1: 0.5rem;    /*  8px */
  --space-2: 1rem;      /* 16px */
  --space-3: 1.5rem;    /* 24px */
  --space-4: 2rem;      /* 32px */
  --space-5: 3rem;      /* 48px */
  --space-6: 4rem;      /* 64px */
  --space-7: 6rem;      /* 96px */
  --space-8: 8rem;      /* 128px */

  /* Vertikaler Grundrhythmus zwischen den Sektionen der hellen Seite. */
  --section-pad: clamp(70px, 11vh, 130px);

  --ease: cubic-bezier(0.4, 0.14, 0.2, 1);
}

/* ------------------------------------------------------------- Reset/Base */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Sprungziele nicht unter den fixierten Header schieben (z. B. Datenschutz-Inhaltsübersicht) */
  scroll-padding-top: calc(var(--header-h) + 1.5rem);
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--l-txt);
  background-color: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* `clip` statt `hidden`: Beides schneidet seitlich ab, aber `hidden` macht
     den Body zu einem Scroll-Container. Damit lösen alle position:sticky
     darin gegen den Body auf statt gegen das Fenster — und kleben nie, weil
     der Body selbst nicht scrollt. Genau daran ist der Sticky-Ablauf in
     SEC_02 zuerst gescheitert. `clip` erzeugt keinen Scroll-Container. */
  overflow-x: clip;
}

img, svg { display: block; max-width: 100%; }
svg { height: auto; }

a { color: inherit; text-decoration: none; }

/* Grundstufe für Überschriften ohne .ds-*-Klasse (kommt regulär nicht vor —
   alle Seiten setzen .ds-h1/-h2/-h3, .footer-h oder die .legal-Regeln). */
h1, h2, h3, h4 {
  font-family: var(--font-sans);
  font-weight: 800;
  color: var(--l-txt);
  line-height: 1.08;
  letter-spacing: -0.03em;
  margin: 0 0 0.4em;
}

p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0; padding: 0; list-style: none; }

strong { color: var(--ink); font-weight: 600; }

::selection { background: var(--gold); color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ------------------------------------------------------------- Utilities */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--pad-inline);
}
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--ink);
  color: var(--paper);
  padding: 0.75rem 1.25rem;
  font-weight: 600;
  border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; }

/* Nur für die Vorlesehilfe. Kein display:none und kein visibility:hidden —
   beide nähmen den Text auch der Vorlesehilfe weg. Die 1px-Box mit
   clip-path ist der Weg, der überall trägt. */
.ds-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------- Header/Nav */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(250, 250, 248, 0.82);
  backdrop-filter: saturate(140%) blur(14px);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  border-bottom: 1px solid var(--l-line);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 76px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-sans);
  font-size: 1.55rem;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0.01em;
}
.brand-mark { width: 26px; height: 26px; flex: none; }
.brand-ai { color: var(--gold); }

.nav { display: flex; align-items: center; }

.nav-menu {
  display: flex;
  align-items: center;
  gap: 0.15rem;
}
.nav-menu a {
  display: inline-block;
  padding: 0.55rem 0.95rem;
  font-size: 0.95rem;
  color: var(--l-txt);
  border-radius: var(--radius-sm);
  transition: color 0.2s var(--ease);
}
.nav-menu a:hover { color: var(--ink); }
.nav-menu a[aria-current="page"] { color: var(--ink); }
.nav-menu a[aria-current="page"]:not(.nav-cta) {
  box-shadow: inset 0 -1px 0 var(--gold);
}

.nav-cta {
  margin-left: 0.65rem;
  padding: 0.65rem 1.35rem !important;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--paper) !important;
  border-radius: var(--radius-sm);
  transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease) !important;
}
/* Hover dunkelt ab — gleiche Richtung wie der Absenden-Button (.ds-submit). */
.nav-cta:hover { background: var(--void); border-color: var(--void); color: var(--paper) !important; }
.nav-cta[aria-current="page"] { box-shadow: none; }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--l-line);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.nav-toggle-bar {
  display: block;
  width: 20px;
  height: 1.5px;
  margin-inline: auto;
  background: var(--ink);
  transition: transform 0.25s var(--ease), opacity 0.2s var(--ease);
}

/* ------------------------------------------------------- Weiches Scrollen */
/* Pflichtregeln für Lenis (js/vendor/lenis.mjs). Lenis setzt die Klassen
   selbst am <html>; ohne diese Regeln bleibt die Seitenhöhe eingefroren und
   angehaltenes Scrollen läuft weiter. Gekürzt auf das, was diese Seite
   braucht — Datenquelle: node_modules/lenis/dist/lenis.css. */
html.lenis,
html.lenis body { height: auto; }
.lenis:not(.lenis-autoToggle).lenis-stopped { overflow: clip; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-smooth iframe { pointer-events: none; }

/* ------------------------------------------------------------- Motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

/* ============================================================== Responsive */

/* Mobile-Navigation (bis 860px) */
@media (max-width: 860px) {
  .nav-toggle { display: flex; }

  .nav-menu {
    position: fixed;
    inset: 76px 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0.25rem;
    padding: 1.25rem var(--pad-inline) 1.75rem;
    background: var(--paper);
    border-bottom: 1px solid var(--l-line);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-12px);
    transition: opacity 0.22s var(--ease), transform 0.22s var(--ease), visibility 0.22s;
  }
  .site-header.is-open .nav-menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
  }
  .nav-menu a { padding: 0.85rem 0.5rem; font-size: 1.05rem; }
  .nav-menu a[aria-current="page"]:not(.nav-cta) { box-shadow: none; color: var(--gold); }
  .nav-cta {
    margin-left: 0;
    margin-top: 0.5rem;
    text-align: center;
    padding: 0.9rem 1.35rem !important;
  }
  .site-header.is-open .nav-toggle-bar:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
  .site-header.is-open .nav-toggle-bar:nth-child(2) { opacity: 0; }
  .site-header.is-open .nav-toggle-bar:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
}

/* =========================================================================
   SCROLL-REVEAL
   Einblendung beim Hereinscrollen — nur aktiv, wenn JS läuft (.js am <html>).
   ========================================================================= */
/* Scroll-Reveal — nur aktiv, wenn JS läuft (.js am <html>) */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.js .reveal.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1 !important; transform: none !important; transition: none; }
}

/* ========================================== Rechtstexte (Impressum, Datenschutz)
   Reine Lesetext-Seiten: eine Spalte, ~70 Zeichen, klare Abschnittsgliederung.
   Keine Karten, keine Akzentflächen — Mono nur für Marken und Nummern,
   der Fließtext bleibt durchgehend Sans.

   Zur Warnfarbe: --warn-dark trägt hier NIE Text auf getöntem Grund
   (dort nur 3.82:1). Sie markiert Rahmen, Balken und Vollton-Chips;
   der Text in diesen Kästen steht in --c-txt und bleibt damit bei ~15:1.
   ============================================================================ */
.legal { max-width: 70ch; }

/* Lesetext-Sektion: knapper Einstieg statt der großen Sektionspolster der
   Marketingseiten — hier soll man sofort im Text sein.
   Doppelte Klasse, damit die Regel unabhängig von der Reihenfolge gewinnt:
   .lite-section steht weiter unten in dieser Datei. */
.lite-section.lite-section--read { padding: var(--space-5) 0 var(--space-7); }

.legal-section {
  padding-top: var(--space-5);
  margin-top: var(--space-5);
  border-top: 1px solid var(--grid-line);
}
/* Der erste Abschnitt folgt je nach Seite auf die Hinweisbox (Impressum)
   oder auf das Inhaltsverzeichnis (Datenschutz). Deshalb keine Trennlinie
   und kein doppeltes Polster, aber sehr wohl ein Abstand — sonst klebt er
   am Vorgänger. */
.legal-section:first-of-type { margin-top: var(--space-4); padding-top: 0; border-top: none; }

.legal-section > h2 {
  margin: 0 0 var(--space-3);
  font-family: var(--font-mono);
  font-size: 1.02rem;
  font-weight: 400;
  letter-spacing: var(--track-2);
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--c-txt);
}
.legal-section > h2 .legal-num {
  display: block;
  margin-bottom: var(--space-1);
  font-size: var(--mono-md);
  letter-spacing: var(--track-4);
  color: var(--c-acc);
}
.legal h3 {
  margin: var(--space-4) 0 var(--space-1);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 400;
  letter-spacing: var(--track-3);
  text-transform: uppercase;
  color: var(--c-txt);
}

.legal p {
  margin: 0 0 var(--space-2);
  font-family: var(--font-sans);
  font-size: 0.95rem;
  line-height: 1.72;
  color: var(--c-txt-2);
}
.legal p:last-child { margin-bottom: 0; }
.legal strong { color: var(--c-txt); font-weight: 600; }

/* Aufzählung mit Mono-Strich statt Punkt — wie .ds-list, aber im Lesefluss. */
.legal ul { list-style: none; margin: 0 0 var(--space-3); padding: 0; }
.legal ul li {
  position: relative;
  padding: 0 0 0 var(--space-3);
  margin-bottom: var(--space-1);
  font-family: var(--font-sans);
  font-size: 0.95rem;
  line-height: 1.72;
  color: var(--c-txt-2);
}
.legal ul li::before {
  content: "—";
  position: absolute;
  left: 0;
  font-family: var(--font-mono);
  color: var(--c-acc);
}

/* Schlüssel/Wert-Paare: Mono-Marke, darunter der Wert, getrennt durch Haarlinien. */
.legal dl { margin: 0 0 var(--space-3); }
.legal dt {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--c-line-2);
  font-family: var(--font-mono);
  font-size: var(--mono-lg);
  letter-spacing: var(--track-4);
  text-transform: uppercase;
  color: var(--c-txt-3);
}
.legal dl > dt:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.legal dd {
  margin: var(--space-1) 0 0;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  line-height: 1.65;
  color: var(--c-txt);
}

.legal a { color: var(--c-acc); text-decoration: underline; text-underline-offset: 2px; }
.legal a:hover { color: var(--c-txt); }

.legal-meta {
  margin-top: var(--space-6);
  padding-top: var(--space-3);
  border-top: 1px solid var(--grid-line);
  font-family: var(--font-mono);
  font-size: var(--mono-md);
  letter-spacing: var(--track-4);
  text-transform: uppercase;
  color: var(--c-txt-3);
}

/* Inhaltsübersicht */
.legal-toc {
  counter-reset: toc;
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
  border-top: 1px solid var(--grid-line);
}
.legal-toc li {
  counter-increment: toc;
  border-bottom: 1px solid var(--grid-line);
}
.legal-toc a {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  font-family: var(--font-sans);
  font-size: 0.92rem;
  color: var(--c-txt-2);
  text-decoration: none;
}
.legal-toc a::before {
  content: counter(toc, decimal-leading-zero);
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: var(--mono-md);
  letter-spacing: var(--track-4);
  color: var(--c-acc);
}
.legal-toc a:hover { color: var(--c-txt); }

/* ---------------------------------------------------------- Platzhalter */
/* Muss beim Durchblättern sofort ins Auge springen: gestrichelter
   Warnrahmen plus Tönung. Der Text selbst steht in --c-txt (14.7:1 auf der
   Tönung) — auffällig heißt hier nicht schlechter lesbar. */
.fill {
  display: inline;
  padding: 0.15em 0.4em;
  border: 1px dashed var(--c-warn);
  background: rgba(163, 100, 48, 0.14);
  color: var(--c-txt);
  font-weight: 600;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/* Hinweisbox „noch nicht freigegeben" — vor dem Go-Live entfernen.
   Bewusst laut: Volltonmarke, Warnrahmen, kräftiger Balken links. */
.legal-notice {
  margin: 0 0 var(--space-4);
  padding: var(--space-3);
  border: 1px solid var(--c-warn);
  border-left: 3px solid var(--c-warn);
  background: rgba(163, 100, 48, 0.07);
}
.legal-notice__label {
  display: inline-block;
  margin-bottom: var(--space-2);
  padding: 3px var(--space-1);
  background: var(--warn-dark);
  color: var(--paper);              /* 4.54:1 ✓ AA */
  font-family: var(--font-mono);
  font-size: var(--mono-lg);
  letter-spacing: var(--track-5);
  text-transform: uppercase;
}
.legal-notice p { margin: 0; color: var(--c-txt); }

/* Knapperer Kopfbereich für die Rechtstexte — sie sind zum Lesen da,
   nicht zum Ankündigen. Die Höhe bestimmt hier der Inhalt, nicht die
   min-height; deshalb muss auch das Polster kleiner werden. */
.pagehead--slim {
  min-height: 26vh;
  padding-top: calc(var(--header-h) + var(--space-3));
  padding-bottom: var(--space-3);
}
.pagehead--slim .ds-lead { margin-top: var(--space-1); }
.pagehead--slim .pagehead__status { margin-top: var(--space-3); }
@media (max-width: 900px) {
  .pagehead--slim { min-height: 22vh; }
}


/* =========================================================================
   DESIGNSYSTEM-PRIMITIVE
   Gemeinsames Vokabular für alle 7 Seiten. Ab hier gilt: keine
   hartcodierten Farben oder Größen — alles über die Tokens oben.
   Aufgebaut in Etappe 1, genutzt ab Etappe 2.
   ========================================================================= */

/* ---------------------------------------------- Kontextflächen (Rollen) */
/* Ein Element bekommt .on-dark oder .on-light und erbt damit die passenden
   Text-, Linien- und Akzentrollen. Kindelemente greifen nur noch auf
   --c-* zu und funktionieren dadurch auf beiden Gründen unverändert. */
.on-dark {
  --c-bg:     var(--void);
  --c-txt:    var(--d-txt);
  --c-txt-2:  var(--d-txt-2);
  --c-txt-3:  var(--d-txt-3);
  --c-line:   var(--d-line);
  --c-line-2: var(--d-line-2);
  --c-panel:  var(--d-panel);
  --c-acc:    var(--gold);
  --c-ok:     var(--ok);
  --c-warn:   var(--warn);
  --c-err:    var(--err);
  background: var(--c-bg);
  color: var(--c-txt);
}
.on-light {
  --c-bg:     var(--paper);
  --c-txt:    var(--l-txt);
  --c-txt-2:  var(--l-txt-2);
  --c-txt-3:  var(--l-txt-3);
  --c-line:   var(--l-line);
  --c-line-2: var(--l-line-2);
  --c-panel:  var(--l-panel);
  --c-acc:    var(--gold-dark);
  --c-ok:     var(--ok-dark);
  --c-warn:   var(--warn-dark);
  --c-err:    var(--err-dark);
  background: var(--c-bg);
  color: var(--c-txt);
}

/* ------------------------------------------------------------- Kicker */
/* Gold-Label mit vorangestellter Haarlinie. */
.ds-kicker {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--mono-lg);
  font-weight: 400;
  letter-spacing: var(--track-6);
  text-transform: uppercase;
  color: var(--c-acc, var(--gold-dark));
}
.ds-kicker::before {
  content: "";
  flex: 0 0 auto;
  width: var(--space-3);
  height: 1px;
  background: currentColor;
}
.ds-kicker--center { justify-content: center; }

/* --------------------------------------------------------- Headlines */
.ds-h1, .ds-h2, .ds-h3 {
  font-family: var(--font-mono);
  text-transform: uppercase;
  color: var(--c-txt, var(--l-txt));
  margin: 0;
}
.ds-h1 {
  font-size: clamp(1.45rem, 2.8vw, 2.3rem);
  font-weight: 300;
  letter-spacing: var(--track-1);
  line-height: 1.2;
}
.ds-h2 {
  font-size: clamp(1.5rem, 2.9vw, 2.2rem);
  font-weight: 400;
  letter-spacing: var(--track-1);
  line-height: 1.24;
  max-width: 22ch;
}
.ds-h3 {
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: var(--track-2);
  line-height: 1.3;
}
.ds-h1 b, .ds-h2 b { font-weight: 500; color: var(--c-acc, var(--gold-dark)); }

/* Fließtext — immer Sans, nie Mono. */
.ds-lead {
  margin-top: var(--space-2);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.7;
  color: var(--c-txt-2, var(--l-txt-2));
  max-width: 56ch;
}
.ds-body {
  font-family: var(--font-sans);
  font-size: 0.9rem;
  line-height: 1.65;
  color: var(--c-txt-2, var(--l-txt-2));
}

/* ------------------------------------------------- 1px-Raster-Grid */
/* Zellen ohne Radius und ohne Schatten — getrennt durch echte Haarlinien,
   erzeugt über die Lücke im Grid-Hintergrund. */
.ds-grid {
  display: grid;
  gap: 1px;
  margin-top: var(--space-5);
  background: var(--grid-line);
  border: 1px solid var(--grid-line);
}
.ds-grid--2 { grid-template-columns: repeat(2, 1fr); }
.ds-grid--3 { grid-template-columns: repeat(3, 1fr); }
.ds-grid--4 { grid-template-columns: repeat(4, 1fr); }
.ds-cell {
  background: var(--c-bg, var(--paper));
  padding: var(--space-4) var(--space-3);
}
.ds-cell__n {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--mono-md);
  letter-spacing: var(--track-4);
  color: var(--c-acc, var(--gold-dark));
}
.ds-cell .ds-h3 { margin-bottom: var(--space-1); }
@media (max-width: 820px) {
  .ds-grid--2, .ds-grid--3, .ds-grid--4 { grid-template-columns: 1fr; }
}

/* -------------------------------------------- Technische Detailzeichen */
/* Eckmarke — kleines offenes Quadrat an Layoutecken. */
.ds-cross {
  position: absolute;
  width: var(--space-1);
  height: var(--space-1);
  border: 1px solid var(--c-line-2, var(--l-line-2));
  pointer-events: none;
}
/* Tick — Revisionsnummer, Prozentstand, Randnotiz. */
.ds-tick {
  font-family: var(--font-mono);
  font-size: var(--mono-md);
  letter-spacing: var(--track-5);
  text-transform: uppercase;
  color: var(--c-txt-3, var(--l-txt-3));
}
/* Statuszeile — Schlüssel/Wert-Paar mit Trennlinie. */
.ds-status {
  display: flex;
  justify-content: space-between;
  gap: var(--space-1);
  padding: var(--space-1) 0;
  font-family: var(--font-mono);
  font-size: var(--mono-sm);
  line-height: 1.35;
  color: var(--c-txt-2, var(--l-txt-2));
}
.ds-status + .ds-status { border-top: 1px solid var(--c-line-2, var(--l-line-2)); }
.ds-status__k { color: var(--c-txt-3, var(--l-txt-3)); }
.ds-status__v { color: var(--c-txt, var(--l-txt)); }
/* Pill — kleiner umrandeter Status. */
.ds-pill {
  display: inline-block;
  padding: 1px var(--space-1);
  border: 1px solid var(--c-line-2, var(--l-line-2));
  font-family: var(--font-mono);
  font-size: var(--mono-xs);
  letter-spacing: var(--track-3);
  text-transform: uppercase;
  color: var(--c-txt-3, var(--l-txt-3));
}
.ds-pill--on { border-color: var(--c-acc); color: var(--c-acc); }
.ds-pill--ok { border-color: var(--c-ok); color: var(--c-ok); }

/* -------------------------------------------------------------- Button */
.ds-go {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--ink);
  background: var(--ink);
  text-decoration: none;
}
.ds-go__bar { width: 7px; background: var(--gold); }
.ds-go__label {
  padding: var(--space-2) var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--mono-xl);
  letter-spacing: var(--track-6);
  text-transform: uppercase;
  color: var(--paper);
}
.ds-go:focus-visible { outline: 2px solid var(--gold-dark); outline-offset: 3px; }


/* =========================================================================
   STARTSEITE — AKT / BÜHNE
   Sticky-Bühne über einer langen Scrollstrecke. Zwei deckungsgleiche Ebenen
   (dunkel + hell); der Sweep gibt die helle von unten nach oben frei.
   Die Rollen-Variablen --c-* stammen aus .on-dark / .on-light.
   ========================================================================= */

.act {
  position: relative;
  z-index: 10;
  height: var(--track, 620vh);   /* js/stage/config.js setzt den Wert je Profil */
  /* Der Header schwebt über der Bühne, statt sie nach unten zu schieben —
     sonst sampelt sein Backdrop-Filter den hellen Body statt das Terrain. */
  margin-top: calc(var(--header-h) * -1);
}
.stage {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  background: var(--void);
}
.stage-layer { position: absolute; inset: 0; }
.stage-layer--light {
  z-index: 20;
  clip-path: inset(100% 0 0 0);   /* wird vom Sweep aufgezogen */
}
/* Auf hellem Grund heben sich die Panels durch einen weichen Schatten ab,
   auf dunklem allein durch die Haarlinie. */
.on-light .pn { box-shadow: 0 18px 44px rgba(15, 30, 23, 0.10); }
.stage-terrain { position: absolute; inset: 0; z-index: 0; }
.stage-flow { position: absolute; inset: 0; z-index: 4; pointer-events: none; }

/* ------------------------------------------------ technische Detailzeichen */
.stage-tick {
  position: absolute;
  z-index: 14;
  bottom: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--mono-md);
  letter-spacing: var(--track-5);
  text-transform: uppercase;
  color: var(--c-txt-3);
}
.stage-tick--left { left: clamp(1rem, 4vw, 2.5rem); }
.stage-tick--right { right: clamp(1rem, 4vw, 2.5rem); font-variant-numeric: tabular-nums; }
.stage-cross {
  position: absolute;
  z-index: 14;
  width: var(--space-1);
  height: var(--space-1);
  border: 1px solid var(--c-line-2);
}
.stage-cross--tl { left: 12px; top: calc(var(--header-h) - 18px); }
.stage-cross--tr { right: 12px; top: calc(var(--header-h) - 18px); }
.stage-cross--bl { left: 12px; bottom: 52px; }
.stage-cross--br { right: 12px; bottom: 52px; }

/* ------------------------------------------------------------ Textphasen */
/* Desktop: Die Konsole steht unverrückbar mittig — der TEXT bewegt sich.
   Basisposition ist die Parkposition (zentriert unterhalb der Konsole,
   über der Statuszeile). Phase 1 wird per JS-Versatz in die Bildmitte
   gehoben und wandert zum Montagebeginn einmalig hierher (index.js).
   Mobile behält das gestapelte Layout (Media-Query unten). */
.stage-say {
  position: absolute;
  z-index: 12;
  left: 50%;
  bottom: 64px;
  max-width: min(640px, 82vw);
  text-align: center;
  transform: translateX(-50%);   /* JS setzt pro Frame translate(-50%, y) */
}
.stage-say--low { bottom: 64px; max-width: min(640px, 82vw); }

/* Ab Phase 2 nur Kicker + Headline — der Fließtext entfällt auf Desktop,
   der vertikale Platz gehört der Konsole. */
@media (min-width: 901px) {
  .stage-say[data-say="2"] .stage-say__p,
  .stage-say[data-say="3"] .stage-say__p { display: none; }
}

/* Die Textphasen liegen über dem Panelfeld. Auf dunklem Grund bekommen sie
   eine weiche Abdunklung, damit Wireframes nicht durch die Schrift laufen —
   das ist Kontrastschutz, keine Dekoration. Der Verlauf muss deutlich vor
   den Rändern seiner Box auf 0 auslaufen, sonst zeichnet er sich als
   Rechteck ab. */
.on-dark .stage-say::before {
  content: "";
  position: absolute;
  inset: -70% -55%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse 58% 55% at 50% 50%,
    rgba(3, 4, 5, 0.72) 0%, rgba(3, 4, 5, 0.45) 45%, rgba(3, 4, 5, 0) 72%);
}
.stage-say__k {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--mono-lg);
  letter-spacing: var(--track-7);
  text-transform: uppercase;
  color: var(--c-acc);
}
.stage-say__h {
  margin: 0;
  font-family: var(--font-mono);
  /* Gilt ab 901px. Darunter setzt die Media-Query am Dateiende einen eigenen
     Grad — schmale Geräte brauchen einen anderen Maßstab, siehe dort. */
  font-size: clamp(1.45rem, 2.8vw, 2.3rem);
  font-weight: 300;
  letter-spacing: var(--track-1);
  line-height: 1.2;
  text-transform: uppercase;
  color: var(--c-txt);
}
.stage-say__h b { font-weight: 500; color: var(--c-acc); }
.stage-say--low .stage-say__h { font-size: clamp(1.1rem, 1.9vw, 1.5rem); }
.stage-say__p {
  margin: var(--space-2) auto 0;
  max-width: 36ch;
  font-family: var(--font-sans);
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--c-txt-2);
}
.stage-say--low .stage-say__p { font-size: 0.85rem; }
.stage-say__go { margin-top: var(--space-3); }
/* Auf der Bühne steht der Button auf dunklem Grund. */
.on-dark .stage-say__go { border-color: var(--gold); background: transparent; }
.on-dark .stage-say__go .ds-go__label { color: var(--d-txt); }

/* ---------------------------------------------------------------- Panels */
.stage-rig {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  z-index: 6;
  perspective: 1700px;
  transform-style: preserve-3d;
}
.pn {
  position: absolute;
  overflow: hidden;
  border: 1px solid var(--c-line);
  background: var(--c-panel);
  font-family: var(--font-mono);
  will-change: transform;
  /* Ohne dies skaliert scale() um die Panel-Mitte; die Layoutkoordinaten
     aus config.js meinen aber die obere linke Ecke. Bei Skalierung nahe 1
     fällt das kaum auf, bei 0,55 auf Mobile verschiebt es die ganze
     Gruppe aus der Mitte. */
  transform-origin: 0 0;
}
.pn-hd {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 7px 9px;
  border-bottom: 1px solid var(--c-line-2);
  font-size: var(--mono-xs);
  letter-spacing: var(--track-4);
  text-transform: uppercase;
  color: var(--c-txt-3);
}
.pn-bd { padding: 9px; }
.pn-bd--feed { padding: 8px 9px; }
.pn-r {
  display: flex;
  justify-content: space-between;
  gap: 6px;
  padding: 4px 0;
  font-size: var(--mono-sm);
  line-height: 1.35;
  color: var(--c-txt-2);
}
.pn-r + .pn-r { border-top: 1px solid var(--c-line-2); }
.pn-lbl { color: var(--c-txt-3); }
.pn-val { color: var(--c-txt); }
.pn-cap {
  margin-top: 4px;
  font-size: var(--mono-xs);
  letter-spacing: var(--track-4);
  text-transform: uppercase;
  color: var(--c-txt-3);
}



/* Montagezustand der Bühnen-Panels: bis kurz vor dem Einrasten nur die
   Kontur — keine Füllung, kein Inhalt. Panels.update setzt die Klassen;
   beim Übergang läuft einmal eine feine Scanlinie über das Panel. */
/* Heller Rand beim Umschalten: js/stage/three-stage.js schreibt --pn-edge
   auf das Panel, sobald die Balkenkante darüber steht. Kein Blitz und kein
   Blinken — der Wert steigt und fällt mit der Kante, die Bewegung kommt
   also allein vom Scrollen. */
.stage-css3d .pn::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--pn-edge, 0);
  border: 1px solid rgb(198 161 91 / 0.85);
  box-shadow: inset 0 0 22px rgb(198 161 91 / 0.28), 0 0 18px rgb(198 161 91 / 0.22);
}
[data-rig] .pn,
.stage-css3d .pn { transition: background-color var(--pn-fade-ms, 300ms) var(--ease); }
[data-rig] .pn > *,
.stage-css3d .pn > * { transition: opacity var(--pn-fade-ms, 300ms) var(--ease); }
/* ---------------------------------------- Stationen der Maschine (dunkel)
   Fünf Panels in Fließrichtung. Sie zeigen einen ABLAUF, kein Ergebnis:
   keine Quote, kein Konfidenzbalken, kein Gesamtzähler. Die Ampelzahlen
   gelten für die eine Anfrage, die gerade durchläuft. */
.pn-step { color: var(--c-txt-3); }

/* 01 Eingang — was hereinkommt, als Kachel mit Formatkürzel. */
.pn-tile {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 6px;
  border: 1px solid var(--c-line-2);
  font-size: var(--mono-sm);
  line-height: 1.3;
  color: var(--c-txt-2);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.pn-tile + .pn-tile { margin-top: 5px; }
.pn-tile__k {
  flex-shrink: 0;
  padding: 1px 4px;
  border: 1px solid var(--c-acc);
  color: var(--c-acc);
  font-size: 8px;
}

/* 02 Extraktion — oben die Rohzeile, darunter, was daraus wird. */
.pn-raw {
  padding: 5px 6px;
  border: 1px dashed var(--c-line-2);
  font-size: var(--mono-sm);
  line-height: 1.35;
  color: var(--c-txt-2);
  text-transform: none;
  letter-spacing: 0;
}
.pn-attrs { margin-top: 7px; }

/* 03 Artikelstamm — das Sieb. Jede Stufe ist enger als die vorige; die
   Balkenbreite ist der Anteil am Katalog, logarithmisch gestaucht
   (feed.js), sonst wäre die letzte Stufe unsichtbar. */
.pn-sieve { margin-top: 7px; display: grid; gap: 7px; }
.pn-sv {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 2px 6px;
  font-size: var(--mono-sm);
  line-height: 1.3;
}
.pn-sv i {
  grid-column: 1 / -1;
  order: 2;
  height: 2px;
  background: var(--c-acc);
  transition: width 0.5s var(--ease);
}
.pn-sv span { color: var(--c-txt-3); }
.pn-sv b { font-weight: 400; color: var(--c-txt); }
.pn-sv.is-empty i { background: var(--c-err); }
.pn-sv.is-empty b { color: var(--c-err); }

/* 04 Zuordnung — die Ampel. Zahl, Farbe UND Wort; die Farbe allein trüge
   die Aussage für Farbfehlsichtige nicht. */
.pn-amp { display: grid; gap: 6px; margin: 7px 0; }
.pn-amp__r {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 6px;
  font-size: var(--mono-sm);
  line-height: 1.3;
  color: var(--c-txt-2);
}
.pn-amp__r span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.pn-amp__r i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c-txt-3);
}
.pn-amp__r b { font-weight: 400; color: var(--c-txt); }
.pn-amp__r--ok i { background: var(--c-ok); }
.pn-amp__r--warn i { background: var(--c-warn); }
.pn-amp__r--err i { background: var(--c-err); }
.pn-r--foot { border-top: 1px solid var(--c-line-2); padding-top: 6px; }

/* 05 Ausgabe — die Zeilen, die der Entwurf bekommt. */
.pn-out {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: 4px 6px;
  padding: 4px 0;
  font-size: var(--mono-sm);
  line-height: 1.3;
  color: var(--c-txt-2);
}
.pn-out span { grid-column: 2; overflow: hidden; }
.pn-out time { grid-column: 2; }
.pn-out + .pn-out { border-top: 1px solid var(--c-line-2); }
.pn-out i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--c-txt-3);
  transform: translateY(-1px);
}
.pn-out--ok i { background: var(--c-ok); }
.pn-out--warn i { background: var(--c-warn); }
.pn-out--err i { background: var(--c-err); }
.pn-out time { color: var(--c-txt-3); }
.pn-out b { font-weight: 400; color: var(--c-txt); }

.pn--bare { background: transparent; }
.pn--bare > * { opacity: 0; }
.pn--scan::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to bottom,
    transparent 42%, rgba(198, 161, 91, 0.6) 50%, transparent 58%);
  animation: pn-scan var(--pn-scan-ms, 500ms) ease-out forwards;
}
@keyframes pn-scan {
  from { transform: translateY(-60%); opacity: 1; }
  to   { transform: translateY(60%); opacity: 0; }
}

/* Pulsierender Statuspunkt — erst wenn das System „lebt“. */
.pn-dot {
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 5px;
  border-radius: 50%;
  background: var(--c-ok);
}
.is-alive .pn-dot { animation: pn-pulse 2.2s infinite; }
@keyframes pn-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(78, 158, 114, 0.45); }
  70%  { box-shadow: 0 0 0 7px rgba(78, 158, 114, 0); }
  100% { box-shadow: 0 0 0 0 rgba(78, 158, 114, 0); }
}

/* =========================================================================
   PRODUKT-EBENE — APP-KONSOLE
   Die helle Ebene der Bühne zeigt nach dem Sweep echte Software. Eigenes,
   funktionales Farbsystem, bewusst getrennt von der Marken-Palette.
   Kontraste (geprüft): #12161A auf Weiß 15,9:1 · #5B6670 auf Weiß 5,5:1 ·
   #2563EB auf Weiß 5,2:1 · Weiß auf #1D4ED8 6,7:1. #8B959E (3,1:1) ist
   nur für Nicht-Text zugelassen. Statusfarben tragen Text ausschließlich
   als dunkle Stufe auf eigener Tönung (Grün #166534 auf #DCF3E3 6,2:1,
   Amber #92400E, Rot #991B1B, Violett #6D28D9 — alle ≥ 6:1). Der gefüllte
   Primärbutton nutzt #1D4ED8, weil Weiß auf #2563EB nur 4,06:1 erreichte;
   #2563EB bleibt Links, aktiven Zuständen und Diagrammen vorbehalten.
   ========================================================================= */
/* Die Farben gehören der KONSOLE, nicht der Ebene — deshalb stehen sie auch
   am Rig selbst. Im Ruhemodus gibt es keine geklonte helle Ebene, die
   Konsole hängt dort direkt in der umgefärbten dunklen; ohne diesen zweiten
   Träger blieben Knöpfe und Statusfarben ungefärbt. */
.stage-layer--light,
.stage-rig--app {
  --app-bg: #F6F7F8;
  --app-panel: #FFFFFF;
  --app-line: #E3E6E8;
  --app-txt: #12161A;
  --app-txt-2: #5B6670;
  --app-txt-3: #8B959E;      /* nur Symbole/Deko, nie Fließtext */
  --app-blue: #2563EB;
  --app-blue-deep: #1D4ED8;
  --app-ok: #16A34A;
  --app-ok-txt: #166534;
  --app-warn: #D97706;
  --app-warn-txt: #92400E;
  --app-err: #DC2626;
  --app-err-txt: #991B1B;
  --app-ai: #7C3AED;
  --app-ai-txt: #6D28D9;
}
/* Der Ebenengrund nur an der Ebene, nicht am Rig. */
.stage-layer--light { background: var(--app-bg); }

.pn--app {
  background: var(--app-panel);
  border: 1px solid var(--app-line);
  border-radius: 8px;
  font-family: var(--font-sans);
  color: var(--app-txt);
  letter-spacing: 0;
  text-transform: none;
}
.on-light .pn--app {
  box-shadow: 0 1px 2px rgba(18, 22, 26, 0.05), 0 10px 28px rgba(18, 22, 26, 0.09);
}
.pn--app.pn--bare { background: transparent; box-shadow: none; }

/* ------------------------------------------------------------ Kopfzeile */
.app-hd {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--app-line);
}
.app-hd__t { font-size: 10px; font-weight: 600; }
.app-hd__v { font-size: 12px; font-weight: 650; font-variant-numeric: tabular-nums; }
.app-pos { color: #15803D; }

/* Reiter — Unterstrich am aktiven Element */

/* ------------------------------------------------------------- Inhalte */
.app-bd { padding: 8px 10px; }
.app-bd--list { padding: 4px 5px; }
.app-bd--chart { padding: 6px 10px 9px; }
.app-r {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  font-size: 10.5px;
  color: var(--app-txt-2);
}
.app-r + .app-r { border-top: 1px solid rgba(227, 230, 232, 0.6); }
.app-r b { font-weight: 600; color: var(--app-txt); font-variant-numeric: tabular-nums; }

/* Statusbadges — gefüllte Pillen mit Hintergrundton */
.app-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2.5px 7px;
  border-radius: 999px;
  background: #EEF0F2;
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #3F4A52;
  white-space: nowrap;
}
.app-badge--ok { background: #DCF3E3; color: var(--app-ok-txt); }
.app-badge--warn { background: #F9EDDC; color: var(--app-warn-txt); }
.app-badge--err { background: #FBE4E4; color: var(--app-err-txt); }
.app-badge--ai { background: #EFE8FD; color: var(--app-ai-txt); }

/* Buttons */
.app-btn {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 6px;
  background: var(--app-blue);
  font-size: 9px;
  font-weight: 600;
  color: #fff;
}

/* Fußzeile eines Panels */
.app-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  padding-top: 7px;
  border-top: 1px solid var(--app-line);
  font-size: 9.5px;
  color: var(--app-txt-2);
}

/* ------------------------------------------------- Herkunft (Panel src)
   Der abfotografierte Zettel. Bewusst KEINE Schreibschrift-Attrappe: Was
   hier steht, ist die abgetippte Rohzeile, nicht ein Foto-Effekt. Der
   leichte Winkel und das getönte Papier genügen als Herkunftshinweis. */
.app-note {
  display: grid;
  gap: 7px;
  padding: 12px 12px 14px;
  border-radius: 4px;
  background: #FBF7EC;
  box-shadow: inset 0 0 0 1px rgba(18, 22, 26, 0.06);
  transform: rotate(-0.6deg);
}
.app-note__h {
  font-size: 9px;
  font-weight: 600;
  color: var(--app-txt-2);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.app-note__l {
  padding-bottom: 6px;
  border-bottom: 1px dashed rgba(18, 22, 26, 0.16);
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1.35;
  color: var(--app-txt);
}
/* Die Zeile, deren Position gerade offen ist, wird mitmarkiert — so ist
   der Weg vom Entwurf zurück auf den Zettel sichtbar. */
.app-note__l.is-lit {
  border-bottom-color: var(--app-blue);
  color: var(--app-blue-deep);
}

/* --------------------------------------------- Angebotsentwurf (doc) */
/* Die Panelhöhe steht fest (config.js), der Inhalt ist je nach aufgeklappter
   Stelle verschieden hoch. Damit die Freigabezeile nicht mitwandert, sitzt
   sie unten am Rand — sonst rutschte sie bei jeder Stelle woandershin. */
.pn--app[data-panel="doc"] { display: flex; flex-direction: column; }
.app-bd--doc {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  padding: 9px 10px 10px;
}
.doc-sign { margin-top: auto; }
.doc-meta {
  display: flex;
  justify-content: space-between;
  padding-bottom: 7px;
  border-bottom: 1px solid var(--app-line);
  font-size: 9px;
  color: var(--app-txt-2);
}

/* Eine Position. Der Punkt links trägt die Ampel — und daneben steht
   immer Text, der dasselbe sagt. Farbe allein trüge die Aussage nicht. */
/* Eine Position — ein echter Knopf. Deshalb hier der übliche Rückbau der
   Browservorgaben; Rolle, Tastaturbedienung und Enter/Space kommen dafür
   umsonst statt nachgebaut. */
.doc-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  width: 100%;
  /* Die Trefferfläche ist der Grund für min-height: Die ganze Konsole wird
     per transform verkleinert (baseScale), aus 60 Layoutpixeln werden auf dem
     Telefon rund 43 echte. Weniger wäre mit dem Finger nicht mehr sicher zu
     treffen. */
  min-height: 60px;
  margin: 0;
  padding: 7px 4px;
  border: 0;
  border-bottom: 1px solid rgba(227, 230, 232, 0.7);
  border-radius: 4px;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
/* Sichtbar UND kräftig: Der Ring liegt innen, weil die Zeile bündig im Panel
   sitzt und ein äußerer Ring vom Panelrand beschnitten würde. */
.doc-row:focus-visible {
  outline: 2px solid var(--app-blue);
  outline-offset: -2px;
}
.doc-row:hover { background: #F7FAFD; }
.doc-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--app-txt-3);
}
.doc-row--ok .doc-dot { background: var(--app-ok); }
.doc-row--warn .doc-dot { background: var(--app-warn); }
.doc-row--err .doc-dot { background: var(--app-err); }
.doc-txt { overflow: hidden; font-size: 10px; line-height: 1.3; }
.doc-txt b { display: block; font-weight: 600; color: var(--app-txt); }
.doc-txt i {
  display: block;
  font-style: normal;
  font-size: 9px;
  color: var(--app-txt-2);
}
/* Das Plus/Minus wird gezeichnet, nicht gesetzt: Als Schriftzeichen säße es
   je nach Schnitt anders in der Zeile, und angesagt werden soll es ohnehin
   nicht — den Zustand trägt aria-expanded. */
.doc-more {
  position: relative;
  width: 17px;
  height: 17px;
  border-radius: 4px;
  background: #EEF2F6;
}
.doc-more::before,
.doc-more::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 9px;
  height: 1.5px;
  background: var(--app-txt-2);
  transform: translate(-50%, -50%);
}
.doc-more::after { transform: translate(-50%, -50%) rotate(90deg); }
.doc-row[aria-expanded="true"] { background: #F4F8FD; }
.doc-row[aria-expanded="true"] .doc-more { background: var(--app-blue); }
.doc-row[aria-expanded="true"] .doc-more::before,
.doc-row[aria-expanded="true"] .doc-more::after { background: #fff; }
/* Aufgeklappt bleibt nur der waagrechte Strich — aus Plus wird Minus. */
.doc-row[aria-expanded="true"] .doc-more::after { opacity: 0; }

/* Die aufgeklappte Erklärung. Geschlossen nimmt sie keinen Platz ein —
   das Dokument soll ein Dokument bleiben und keine Ziehharmonika. */
.doc-panel {
  display: none;
  padding: 8px 10px 9px;
  border-bottom: 1px solid rgba(227, 230, 232, 0.7);
  background: #F8FAFC;
  font-size: 9.5px;
}
.doc-panel.is-open { display: block; }
.doc-attr {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 0;
  color: var(--app-txt-2);
}
.doc-attr b { font-weight: 600; color: var(--app-txt); }
.doc-hit {
  margin-top: 6px;
  padding: 4px 7px;
  border-radius: 4px;
  background: #DCF3E3;
  font-weight: 600;
  color: var(--app-ok-txt);
}
.doc-hit--err { background: #FBE4E4; color: var(--app-err-txt); }
.doc-cand {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 5px 7px;
  border: 1px solid var(--app-line);
  border-radius: 5px;
  background: #fff;
  color: var(--app-txt);
}
.doc-cand + .doc-cand { margin-top: 4px; }
.doc-pick {
  padding: 2px 7px;
  border-radius: 4px;
  background: var(--app-blue);
  font-size: 8.5px;
  font-weight: 600;
  color: #fff;
}
.doc-src {
  padding: 5px 7px;
  border-radius: 4px;
  background: #FBF7EC;
  font-family: var(--font-mono);
  font-size: 9.5px;
  color: var(--app-txt);
}
.doc-hint { margin-top: 5px; color: var(--app-txt-2); }
.doc-sign {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--app-line);
  font-size: 9.5px;
  color: var(--app-txt-2);
}

/* Einschwingen neuer Elemente: gleiten ein, leichtes Überschwingen */
.app-in { animation: app-in 0.38s cubic-bezier(0.2, 1.25, 0.4, 1); }
@keyframes app-in {
  from { opacity: 0; transform: translateY(-7px); }
  70% { opacity: 1; transform: translateY(1.5px); }
  to { opacity: 1; transform: translateY(0); }
}
.app-bump { animation: app-bump 0.55s var(--ease); }
@keyframes app-bump {
  35% { transform: scale(1.07); }
  100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .app-in, .app-bump { animation: none; }
}

/* ----------------------------------------------------------------- Sweep */
.stage-sweep {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 30;
  opacity: 0;
  pointer-events: none;
}
.stage-sweep__glow,
.stage-sweep__edge,
.stage-sweep__line { position: absolute; left: 0; right: 0; display: block; }
/* Höhe und Stärke des Scheins kommen aus js/stage/config.js (REVEAL_FX)
   und werden als Custom Property auf die Bühne geschrieben — damit sind
   sie über die Reglertafel live veränderbar. */
.stage-sweep__glow {
  top: 0;
  height: var(--sweep-glow-h, 180px);
  background: linear-gradient(to bottom,
    rgb(198 161 91 / calc(var(--sweep-glow-a, 0.26))),
    rgb(198 161 91 / calc(var(--sweep-glow-a, 0.26) * 0.27)) 45%, transparent);
}
.stage-sweep__edge {
  top: -24px;
  height: 24px;
  background: linear-gradient(to top, rgba(198, 161, 91, 0.14), transparent);
}
.stage-sweep__line {
  top: 0;
  height: 2px;
  background: var(--gold);
  box-shadow: 0 0 16px rgba(198, 161, 91, 0.6), 0 0 46px rgba(198, 161, 91, 0.3);
}
.stage-sweep__cap {
  position: absolute;
  top: -7px;
  width: 14px;
  height: 14px;
  border: 1px solid var(--gold);
}
.stage-sweep__cap--l { left: 12px; }
.stage-sweep__cap--r { right: 12px; }

/* ------------------------------------------------- Header über der Bühne */
.site-header.is-over-dark {
  background: rgba(3, 4, 5, 0.62);
  border-bottom-color: var(--d-line-2);
  color: var(--d-txt);
}
.site-header.is-over-dark .nav-menu a { color: var(--d-txt); }
.site-header.is-over-dark .brand { color: var(--d-txt); }
.site-header.is-over-dark .nav-cta {
  border-color: var(--gold);
  background: transparent;
  color: var(--d-txt);
}
.site-header.is-over-dark .nav-toggle-bar { background: var(--d-txt); }

/* =========================================================================
   RUHENDE FASSUNG
   Ohne JavaScript und bei prefers-reduced-motion: keine Scrollstrecke,
   keine Bewegung. Die drei Textphasen stehen als normaler Inhalt
   untereinander, die dekorativen Panels entfallen.
   ========================================================================= */
html:not(.js) .act,
html:not(.js) .stage,
html:not(.js) .stage-layer,
html:not(.js) .stage-say { position: static; }
html:not(.js) .act { height: auto; margin-top: 0; }
html:not(.js) .stage { height: auto; padding: var(--space-7) 0; }
html:not(.js) .stage-rig,
html:not(.js) .stage-sweep,
html:not(.js) .stage-terrain,
html:not(.js) .stage-flow { display: none; }
html:not(.js) .stage-say {
  max-width: 56ch;
  margin: 0 auto var(--space-6);
  padding: 0 var(--pad-inline);
  text-align: left;
  transform: none;
}
html:not(.js) .stage-tick,
html:not(.js) .stage-cross { display: none; }

@media (prefers-reduced-motion: reduce) {
  .act { height: auto; margin-top: 0; }
  .stage { position: static; height: auto; padding: var(--space-7) 0; background: var(--paper); }
  .stage-layer { position: static; }
  /* .stage-css3d: falls Bewegungsreduktion erst NACH dem Start der
     3D-Bühne aktiviert wird — beim Laden greift sie gar nicht erst. */
  .stage-rig, .stage-sweep, .stage-terrain, .stage-flow, .stage-css3d { display: none; }
  .stage-say {
    position: static;
    max-width: 56ch;
    margin: 0 auto var(--space-6);
    padding: 0 var(--pad-inline);
    text-align: left;
    opacity: 1 !important;      /* überstimmt Inline-Reste, falls vorhanden */
    transform: none !important;
  }
  .stage-say--low { max-width: 56ch; }
  .stage-tick, .stage-cross { display: none; }

  /* AUSNAHME vom display:none weiter oben: Die App-Konsole bleibt stehen.
     Wer Bewegung abbestellt hat, bekäme sonst weder das Ergebnis der Bühne
     zu sehen noch die vier aufklappbaren Positionen — und die sind das
     inhaltliche Hauptargument, kein Schmuck.
     Gezeigt wird sie ruhend: gestapelt im Textfluss, ohne Montage, ohne
     Flug, ohne Maße aus config.js (panels.layout() läuft hier nicht). */
  .stage-rig--app {
    display: grid;
    position: static;
    gap: var(--space-3);
    /* Die Grundregel setzt width/height auf 0 — als absolut gesetzter Anker
       für die Montage ist das richtig, hier trüge der Block dann aber keinen
       Inhalt. */
    width: 100%;
    height: auto;
    max-width: 34rem;
    margin: 0 auto;
    padding: 0 var(--pad-inline);
    perspective: none;
    transform-style: flat;
  }
  .stage-rig--app .pn {
    position: static;
    width: auto;
    height: auto;
    /* !important, weil panels.js im Normalbetrieb inline schreibt — bei
       einem späteren Wechsel des Bewegungswunsches stünden die Werte sonst
       noch im style-Attribut. */
    transform: none !important;
    opacity: 1 !important;
  }
}

/* ------------------------------------------------------ schmale Geräte */
/* Mobile behält das gestapelte Layout: Text oben links, Konsole darunter.
   Die Desktop-Basis (zentriert, unten geparkt) wird hier zurückgenommen. */
@media (max-width: 900px) {
  .stage-say {
    left: calc(max(0px, (100% - var(--container)) / 2) + var(--pad-inline));
    top: 16%;
    bottom: auto;
    /* 80vw statt vormals 72vw/78vw: Die Headlines sind mit der neuen
       Positionierung länger geworden und rissen sonst in der Wortmitte.
       Beide Phasenarten bekommen dieselbe Breite, damit die linke Kante
       über den Scrollverlauf hinweg steht und nur der Text wechselt. */
    max-width: 80vw;
    text-align: left;
    transform: none;
  }
  .stage-say--low { top: 16%; bottom: 8%; max-width: 80vw; }

  /* Schriftgrad in vw statt in rem. Der Textblock ist selbst vw-breit, also
     hält nur ein vw-Grad das Verhältnis von Zeile zu Block über alle
     Gerätebreiten konstant — die Reserve bleibt bei 360px dieselbe wie bei
     430px. Ein fester rem-Wert passt immer nur für eine Breite: 1.35rem geht
     sich auf 390px knapp aus und reißt auf 360px mitten im Wortbild.
     5.4vw sind auf 390px rund 1,32rem. Die Obergrenze schließt an den
     Desktop-Grad an, der bei 900px bei 2.8vw ≈ 1,58rem steht. */
  .stage-say__h { font-size: clamp(1.05rem, 5.4vw, 1.55rem); }
  /* Phase 3 steht eine Stufe kleiner und trägt zugleich die längste Zeile
     („Das System bestimmt selbst,"), deshalb ein eigener, engerer Grad. */
  .stage-say--low .stage-say__h { font-size: clamp(0.9rem, 4.2vw, 1.05rem); }

  /* Trefferfläche für den Finger. Die Konsole wird auf schmalen Geräten auf
     rund 0,65 verkleinert (baseScale mal Ausweichbewegung) — aus diesen 68
     Layoutpixeln werden dadurch etwa 44 echte, der übliche Richtwert.
     Der Platz dafür kommt aus `mobileSize` des doc-Panels in config.js; wer
     hier dreht, muss dort mitziehen. */
  .doc-row { min-height: 68px; }

  .stage-say__p { margin-inline: 0; }
  .on-dark .stage-say::before {
    inset: -60% -85% -60% -95%;
    background: radial-gradient(ellipse 58% 55% at 34% 50%,
      rgba(3, 4, 5, 0.72) 0%, rgba(3, 4, 5, 0.45) 45%, rgba(3, 4, 5, 0) 72%);
  }
}


/* =========================================================================
   STARTSEITE — HELLE SEKTIONEN
   Liegen über der Sticky-Bühne und führen deren Sprache fort: Mono-Versalien,
   Gold-Label mit Haarlinie, 1px-Raster statt Karten, Abschnittsmarken.
   ========================================================================= */

.lite {
  position: relative;
  z-index: 11;              /* deckt die Sticky-Bühne beim Hochscrollen ab */
  background: var(--c-bg);
}
.lite-wrap {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--pad-inline);
}
.lite-section { padding: var(--section-pad) 0; }
.lite-section + .lite-section { border-top: 1px solid var(--grid-line); }

/* Kopfzeile einer Sektion: Gold-Label links, Abschnittsmarke rechts. */
.lite-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
}
.lite-head .ds-kicker { margin-bottom: var(--space-3); }

/* Textlink im Mono-Duktus, mit nachgestelltem Pfeil statt SVG. */
.lite-link {
  display: inline-block;
  margin-top: var(--space-4);
  padding-bottom: 3px;
  border-bottom: 1px solid var(--c-acc);
  font-family: var(--font-mono);
  font-size: var(--mono-lg);
  letter-spacing: var(--track-6);
  text-transform: uppercase;
  color: var(--c-acc);
}
.lite-link::after { content: " \2192"; }
.lite-link:hover { border-bottom-color: var(--c-txt); color: var(--c-txt); }
.lite-link:focus-visible { outline: 2px solid var(--gold-dark); outline-offset: 3px; }

/* Nummerierte Phasenliste — die Zählung steht sichtbar in .ds-cell__n,
   der Listenpunkt selbst bleibt aus. */
.lite-steps { list-style: none; margin-block: var(--space-5) 0; padding: 0; }

/* Trust-Kennwert: die Angabe trägt das Gewicht, nicht der Fließtext. */
.lite-fact__fig {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-mono);
  font-size: 1.35rem;
  font-weight: 400;
  letter-spacing: var(--track-1);
  text-transform: uppercase;
  line-height: 1.1;
  color: var(--c-txt);
}

/* ------------------------------------------- Rechenprobe (SEC_01) */
/* Die Rechnung steht im normalen Zellenraster, nur die dritte Zelle kehrt
   sich um: Sie ist das Ergebnis, nicht der dritte Fakt. Ohne die Umkehrung
   läse man drei gleichrangige Kennwerte statt einer Rechnung. */
.lite-sum__note {
  margin-top: var(--space-5);
  font-family: var(--font-mono);
  font-size: var(--mono-lg);
  letter-spacing: var(--track-6);
  text-transform: uppercase;
  color: var(--c-txt-3, var(--l-txt-3));
}
/* Die Hinweiszeile hat den Abstand schon gesetzt, das Raster braucht ihn
   deshalb hier nicht noch einmal. */
.lite-sum { margin-top: var(--space-2); }
/* Wie im Abschlussblock: .on-dark liefert die Textrollen, die FLÄCHE bleibt
   Tannengrün statt des Bühnen-Schwarz von --void. */
.lite-sum__out { --c-bg: var(--ink); }

/* ------------------------------------------------------- Merksatz */
/* Ein Satz, der für sich steht: Er schließt eine Sektion ab, statt sie
   fortzusetzen. Deshalb die Haarlinie darüber — dieselbe Linie, die im
   Zellenraster die Felder trennt.
   Mono in Normalschreibung: Die Tracking-Skala ist für Versalien gerechnet,
   bei Gemischtschreibung müssen die Wortbilder unter null (--track-0),
   sonst zerfallen sie. */
.lite-claim {
  max-width: 52ch;
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--grid-line);
  font-family: var(--font-mono);
  font-size: 1.02rem;
  font-weight: 400;
  letter-spacing: var(--track-0);
  line-height: 1.55;
  color: var(--c-txt, var(--l-txt));
}

/* ------------------------------------------------- Ampel (SEC_03) */
/* Die Farbe trägt die Aussage NICHT allein — jede Zelle nennt ihren Status
   auch als Wort. Für Farbfehlsichtige wäre die Ampel sonst stumm.
   Die Werte kommen aus --c-ok/--c-warn/--c-err; auf hellem Grund sind das
   die abgedunkelten Fassungen, die dort AA halten. */
.lite-amp__sig {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-mono);
  font-size: 1.35rem;
  font-weight: 400;
  letter-spacing: var(--track-1);
  text-transform: uppercase;
  line-height: 1.1;
}
.lite-amp__c--ok .lite-amp__sig { color: var(--c-ok, var(--ok-dark)); }
.lite-amp__c--warn .lite-amp__sig { color: var(--c-warn, var(--warn-dark)); }
.lite-amp__c--err .lite-amp__sig { color: var(--c-err, var(--err-dark)); }

/* ------------------------------------ Sticky-Ablauf (Startseite SEC_02) */
/* Links klebt ein Visual, rechts scrollen die vier Schritte durch. Der
   Zweispalter existiert nur ab 901px — darunter steht alles untereinander,
   und zwar in genau der Reihenfolge, in der es im Markup steht (Visual,
   dann Text). Das Umhängen der Visuals in die Bühne macht js/index.html;
   ohne JavaScript bleibt die gestapelte Fassung stehen und ist richtig. */
.proc { margin-top: var(--space-5); }
.proc__stage { display: none; }
.proc__list { list-style: none; margin: 0; padding: 0; }
.proc__item {
  padding: var(--space-4) 0;
  border-top: 1px solid var(--grid-line);
}
.proc__item:last-child { border-bottom: 1px solid var(--grid-line); }
.proc__vis { margin-bottom: var(--space-3); }
.proc__txt .ds-h3 { margin-bottom: var(--space-1); }

@media (min-width: 901px) {
  .proc {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-7);
    /* start, nicht stretch: Ein gedehntes Rasterfeld wäre so hoch wie die
       Liste, und darin klebt nichts. */
    align-items: start;
  }
  .proc__stage {
    display: grid;                 /* alle Visuals im selben Feld */
    position: sticky;
    /* Etwa Bildmitte. Der Kopf der Seite ist 72px hoch; darunter soll das
       Visual auf Augenhöhe mit dem Schritt stehen, der gerade gelesen wird. */
    top: 28vh;
  }
  .proc__stage .proc__vis {
    grid-area: 1 / 1;
    margin: 0;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.45s var(--ease), transform 0.45s var(--ease);
  }
  .proc__stage .proc__vis.is-on { opacity: 1; transform: none; }

  /* Der aktive Schritt trägt die Goldkante und den kräftigeren Text. Die
     übrigen treten zurück, ohne unleserlich zu werden — sie sollen beim
     Überfliegen noch lesbar sein, nur eben nicht im Vordergrund. */
  .proc__list { border-left: 1px solid var(--grid-line); }
  .proc__item {
    position: relative;
    /* Jeder Schritt braucht Scrollweg, sonst klebt die Bühne nur ein paar
       hundert Pixel und der Wechsel ist vorbei, bevor man ihn bemerkt hat.
       44vh je Schritt heißt: Man liest einen Schritt, scrollt, liest den
       nächsten — der Panelwechsel fällt genau dazwischen. Mehr wäre nicht
       besser: Bei 62vh füllte ein Schritt das ganze Bild, die zurückgenommenen
       Nachbarn wären gar nicht mehr zu sehen, und ihre Abstufung liefe ins
       Leere. */
    min-height: 44vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--space-5) 0 var(--space-5) var(--space-4);
    border-top: 0;
    transition: opacity 0.35s var(--ease);
    opacity: 0.45;
  }
  .proc__item:last-child { border-bottom: 0; }
  .proc__item::before {
    content: "";
    position: absolute;
    left: -1px;
    top: var(--space-4);
    bottom: var(--space-4);
    width: 2px;
    background: var(--gold-dark);
    opacity: 0;
    transition: opacity 0.35s var(--ease);
  }
  .proc__item.is-active { opacity: 1; }
  .proc__item.is-active::before { opacity: 1; }
}

/* Das Visual selbst — heller Panelduktus der Seite, kein Bühnen-Schwarz. */
.pv {
  border: 1px solid var(--grid-line);
  background: var(--paper);
  font-family: var(--font-mono);
}
.pv__hd {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 10px 14px;
  border-bottom: 1px solid var(--grid-line);
  font-size: var(--mono-lg);
  letter-spacing: var(--track-4);
  text-transform: uppercase;
  color: var(--c-txt-3);
}
.pv__bd { padding: 14px; }

/* 01 Eingang */
.pv__tile {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border: 1px solid var(--grid-line);
  font-size: 0.8rem;
  color: var(--c-txt-2);
}
.pv__tile + .pv__tile { margin-top: 7px; }
.pv__k {
  flex-shrink: 0;
  padding: 2px 6px;
  border: 1px solid var(--gold-dark);
  font-size: var(--mono-lg);
  letter-spacing: var(--track-3);
  color: var(--gold-dark);
}

/* 02 Extraktion */
.pv__raw {
  padding: 9px 10px;
  margin-bottom: 12px;
  border: 1px dashed var(--grid-line);
  font-size: 0.82rem;
  color: var(--c-txt-2);
}
.pv__attr {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 6px 0;
  font-size: 0.8rem;
  color: var(--c-txt-3);
}
.pv__attr + .pv__attr { border-top: 1px solid var(--grid-line); }
.pv__attr b { font-weight: 400; color: var(--c-txt); }

/* 03 Sieb */
.pv__sv {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 3px var(--space-2);
  font-size: 0.8rem;
  color: var(--c-txt-3);
}
.pv__sv + .pv__sv { margin-top: 12px; }
.pv__sv i {
  grid-column: 1 / -1;
  order: 2;
  height: 2px;
  background: var(--gold-dark);
}
.pv__sv b { font-weight: 400; color: var(--c-txt); }

/* 04 Ausgabe */
.pv__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  font-size: 0.8rem;
  color: var(--c-txt);
}
.pv__row + .pv__row { border-top: 1px solid var(--grid-line); }
.pv__row i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--c-txt-3);
}
.pv__row em { font-style: normal; color: var(--c-txt-3); }
.pv__row--ok i { background: var(--ok-dark); }
.pv__row--warn i { background: var(--warn-dark); }
.pv__row--err i { background: var(--err-dark); }
.pv__row--ok em { color: var(--ok-dark); }
.pv__row--warn em { color: var(--warn-dark); }
.pv__row--err em { color: var(--err-dark); }

/* --------------------------------------------- Wort der Gründer (Haltung) */
/* Ohne Kicker und ohne Abschnittsmarke: Hier spricht ein Mensch, kein
   Kapitel. Die Sektion ist absichtlich schmal und mittig — sie soll gelesen
   und nicht überflogen werden. */
.lite-word { text-align: center; }
.word__text {
  max-width: 46ch;
  margin: 0 auto;
  font-family: var(--font-sans);
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  line-height: 1.72;
  color: var(--c-txt);
  text-wrap: pretty;
}
.word__who {
  margin: var(--space-5) 0 0;
  font-family: var(--font-mono);
  font-size: var(--mono-lg);
  letter-spacing: var(--track-6);
  text-transform: uppercase;
  color: var(--c-txt-3);
}
.word__who span { color: var(--gold-dark); }
.word__sign {
  display: block;
  width: clamp(190px, 22vw, 260px);
  height: auto;
  margin: var(--space-2) auto 0;
  color: var(--gold-dark);
}

/* Abschluss: mittig gesetzt, mit Eckmarken als technische Klammer.
   Diese Fassung tragen die Unterseiten; die Startseite nutzt darunter
   die Blockfassung (.lite-final--block). */
.lite-final { text-align: center; }
.lite-final .lite-wrap { position: relative; }
.lite-final .ds-h2 { max-width: 18ch; margin-inline: auto; }
.lite-final .ds-lead { margin-inline: auto; }
.lite-final .lite-wrap .ds-go { margin-top: var(--space-4); }
.lite-final__mark { top: 0; }
.lite-final__mark--l { left: var(--pad-inline); }
.lite-final__mark--r { right: var(--pad-inline); }

/* ------------------------------------------- Abschlussblock (Erstgespräch) */
/* Anders als jede andere Sektion trägt dieser Abschluss keine Textspalte auf
   dem Seitengrund, sondern eine eigene gerundete Fläche. Deshalb bricht er
   aus dem Container aus (--block-inset statt .lite-wrap) und bekommt keine
   Trennlinie: Eine randlose Haarlinie über einem eingerückten Block läse
   sich als zweite, konkurrierende Kante. */
/* GLEICHER ABSTAND OBEN WIE UNTEN. Zwei gleiche Polsterwerte ergäben hier
   gerade KEINEN gleichen Abstand: Oben liefert die Sektion darüber bereits
   ihr volles --section-pad, unten liegt die Footer-Haarlinie unmittelbar am
   Polster dieser Sektion. Also oben nichts dazugeben und unten das volle
   --section-pad setzen — dann steht über wie unter dem Block derselbe
   Weißraum, bei jeder Fensterhöhe. */
.lite-final--block {
  padding-top: 0;
  padding-bottom: var(--section-pad);
  padding-inline: var(--block-inset);
}
.lite-section + .lite-section.lite-final--block { border-top: 0; }

.final-block {
  /* .on-dark liefert die Textrollen für dunklen Grund; die FLÄCHE soll
     aber Tannengrün sein, nicht das Bühnen-Schwarz von --void. */
  --c-bg: var(--ink);
  position: relative;
  isolation: isolate;          /* hält die drei Ebenen in eigenem Kontext */
  overflow: hidden;            /* der Radius beschneidet das spätere Visual */
  display: grid;
  place-items: center;
  /* Zwei Grenzen zugleich: --block-inset hält Abstand zum Viewportrand,
     --block-max deckelt die Breite auf breiten Schirmen. */
  max-width: var(--block-max);
  margin-inline: auto;
  min-height: var(--block-h);
  /* Knapp gehalten: Der Inhalt soll die Fläche tragen, nicht darin
     schwimmen. Die Mindesthöhe bleibt der Boden, das Polster nicht. */
  padding: var(--space-4) var(--pad-inline);
  border-radius: var(--radius-lg);
}

/* EBENE 1 — VISUAL. Vorerst nur eine Fläche in --ink. Siehe den Hinweis
   im Markup: Zum Austauschen wird ausschließlich dieses Element gefüllt. */
.final-block__visual {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--ink);
}
/* Was später hineinkommt, füllt die Fläche formatfüllend aus. */
.final-block__visual > img,
.final-block__visual > video,
.final-block__visual > canvas {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* EBENE 2 — ABDUNKLUNG. Liegt über dem Visual, unter dem Inhalt. Solange
   das Visual eine einfarbige --ink-Fläche ist, wäre sie wirkungslos und
   steht deshalb auf 0; mit .final-block--scrim am Block wird sie aktiv. */
.final-block__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0;
  background: var(--scrim);
  pointer-events: none;
  transition: opacity 0.3s var(--ease);
}
.final-block--scrim .final-block__scrim { opacity: 1; }

/* EBENE 3 — INHALT. */
.final-block__inner {
  position: relative;
  z-index: 2;
  max-width: var(--container);
}
/* Zweizeilig gesetzt soll die Headline zwei ähnlich lange Zeilen ergeben.
   Ohne das reißt die Normalschreibung „Problem“ als Waise in Zeile zwei. */
.final-block .ds-h2 { text-wrap: balance; }

/* Zwei Wege nebeneinander. */
.final-block__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

/* EIN Bauprinzip für beide Knöpfe: gleiche Höhe, gleiche Polsterung,
   gleicher Radius, kein Goldbalken. Nur die Füllung unterscheidet primär
   von sekundär — sonst lesen sich zwei Wege als zwei Bauteile. */
.final-block__actions .ds-go {
  justify-content: center;
  min-width: 15rem;
  border-radius: var(--radius-sm);
}
.final-block__actions .ds-go__label { padding: var(--space-2) var(--space-3); }

/* Gefüllt. Auf dunklem Grund kehrt sich .ds-go um — helle Fläche, dunkle
   Schrift. Der Block trägt genau einen Weg; die Zentrierung kommt aus
   .final-block__actions und gilt für ein Kind genauso wie für mehrere. */
.ds-go--solid { border-color: var(--paper); background: var(--paper); }
.ds-go--solid .ds-go__label { color: var(--ink); }
.ds-go--solid:hover { border-color: var(--d-txt); background: var(--d-txt); }

/* HEADLINE — VARIANTE B: Normalschreibung statt Versalien.
   Die Tracking-Skala ist für Versalien gerechnet; in Gemischtschreibung
   muss sie unter null (--track-0), sonst zerfallen die Wortbilder. Etwas
   größer, weil Kleinbuchstaben optisch kleiner bauen als Versalien.
   Umgeschaltet wird im Markup, siehe den Kommentar an der Headline. */
.ds-h2--plain {
  text-transform: none;
  font-size: clamp(1.75rem, 3.4vw, 2.75rem);
  letter-spacing: var(--track-0);
  line-height: 1.16;
}
.lite-final .ds-h2--plain { max-width: 20ch; }

@media (max-width: 720px) {
  .final-block {
    min-height: var(--block-h-sm);
    padding: var(--space-6) var(--space-3);
  }
  /* Untereinander und auf volle Breite: nebeneinander bleibt auf 390px
     kein Mono-Label mehr in einer Zeile. */
  .final-block__actions { flex-direction: column; align-items: stretch; }
  .final-block__actions .ds-go { min-width: 0; }
}

/* ------------------------------------------------------------- Footer */
/* Überschreibt den früheren dunkelgrünen Footer. */
.site-footer {
  position: relative;
  z-index: 11;
  padding: var(--space-6) 0 var(--space-4);
  border-top: 1px solid var(--grid-line);
  background: var(--c-bg);
  color: var(--c-txt-2);
}
.site-footer .brand { color: var(--c-txt); }
.site-footer .brand-mark { color: var(--gold-dark); }
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: var(--space-5) var(--space-4);
  /* Luft vor der Schlusszeile — stammte früher aus dem alten Footer-Block. */
  padding-bottom: var(--space-5);
}
.footer-brand .brand { margin-bottom: var(--space-2); }
.footer-tag {
  max-width: 34ch;
  margin: 0;
  font-family: var(--font-sans);
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--c-txt-2);
}
.footer-loc {
  margin: var(--space-1) 0 0;
  font-family: var(--font-mono);
  font-size: var(--mono-md);
  letter-spacing: var(--track-4);
  text-transform: uppercase;
  color: var(--c-txt-3);
}
.footer-h {
  margin: 0 0 var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--mono-lg);
  font-weight: 400;
  letter-spacing: var(--track-6);
  text-transform: uppercase;
  color: var(--c-txt-3);
}
.footer-col ul { display: grid; gap: var(--space-1); margin: 0; padding: 0; list-style: none; }
.footer-col a {
  font-family: var(--font-mono);
  font-size: var(--mono-lg);
  letter-spacing: var(--track-3);
  text-transform: uppercase;
  color: var(--c-txt-2);
  transition: color 0.2s var(--ease);
}
.footer-col a:hover { color: var(--c-acc); }
.footer-col a:focus-visible { outline: 2px solid var(--gold-dark); outline-offset: 3px; }
.footer-bottom {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-5);
  padding-top: var(--space-3);
  border-top: 1px solid var(--grid-line);
  font-family: var(--font-mono);
  font-size: var(--mono-md);
  letter-spacing: var(--track-4);
  text-transform: uppercase;
  color: var(--c-txt-3);
}

@media (max-width: 820px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 520px) {
  .lite-head { flex-direction: column; align-items: flex-start; gap: var(--space-1); }
  .lite-head .ds-tick { order: -1; }
}


/* =========================================================================
   UNTERSEITEN — KOMPAKTER DUNKLER KOPFBEREICH
   Rund 40vh mit statischem, ausgedünntem Scan-Terrain. Kein Scroll-Akt.
   ========================================================================= */

.pagehead {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 40vh;
  overflow: hidden;
  /* Der Header schwebt darüber — wie auf der Startseite die Bühne. */
  margin-top: calc(var(--header-h) * -1);
  padding: calc(var(--header-h) + var(--space-5)) 0 var(--space-5);
}
.pagehead__terrain { position: absolute; inset: 0; z-index: 0; }
.pagehead__inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--pad-inline);
}
.pagehead .ds-h1 { max-width: 20ch; }
.pagehead .ds-lead { max-width: 52ch; color: var(--c-txt-2); }

/* Statuszeile am Fuß des Kopfbereichs — Revisionsnummer links,
   Kennwert rechts, getrennt durch eine Haarlinie. */
.pagehead__status {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding-top: var(--space-2);
  border-top: 1px solid var(--c-line-2);
  font-family: var(--font-mono);
  font-size: var(--mono-md);
  letter-spacing: var(--track-5);
  text-transform: uppercase;
  color: var(--c-txt-3);
}
.pagehead__mark { position: absolute; z-index: 2; }
.pagehead__mark--tl { left: 12px; top: calc(var(--header-h) + 12px); }
.pagehead__mark--tr { right: 12px; top: calc(var(--header-h) + 12px); }
.pagehead__mark--bl { left: 12px; bottom: 12px; }
.pagehead__mark--br { right: 12px; bottom: 12px; }

/* Ohne JavaScript überlappt nichts: der Kopf beginnt unter dem Header,
   der damit in seiner hellen Fassung lesbar bleibt. */
html:not(.js) .pagehead {
  margin-top: 0;
  padding-top: var(--space-5);
}

/* ------------------------------------------------- Unterseiten-Inhalte */

/* Leistungsblock: Kennung und Titel links, Ausführung rechts. */
.svc { padding: clamp(56px, 8vh, 96px) 0; }
.svc + .svc { border-top: 1px solid var(--grid-line); }
.svc__grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--space-5);
  align-items: start;
}
.svc__n {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-mono);
  font-size: 1.6rem;
  font-weight: 300;
  letter-spacing: var(--track-1);
  color: var(--c-acc);
}
.svc__tag {
  margin: var(--space-2) 0 0;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--c-txt-2);
  max-width: 34ch;
}
.svc__lead { margin: 0 0 var(--space-4); }

/* Aufzählung mit Mono-Marke statt Punkt. */
.ds-list { margin: var(--space-3) 0 0; padding: 0; list-style: none; }
.ds-list li {
  position: relative;
  padding: var(--space-1) 0 var(--space-1) var(--space-4);
  font-family: var(--font-sans);
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--c-txt-2);
}
.ds-list li + li { border-top: 1px solid var(--c-line-2); }
.ds-list li::before {
  content: "—";
  position: absolute;
  left: 0;
  font-family: var(--font-mono);
  color: var(--c-acc);
}

/* Zweispaltiger Textblock mit Beistellkasten. */
.split-2 {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--space-5);
  align-items: start;
  margin-top: var(--space-5);
}
.split-2 p + p { margin-top: var(--space-2); }
.side-panel {
  border: 1px solid var(--grid-line);
  padding: var(--space-4) var(--space-3);
  background: var(--c-bg);
}
.side-panel .ds-h3 { margin-bottom: var(--space-2); }

@media (max-width: 900px) {
  .svc__grid, .split-2 { grid-template-columns: 1fr; gap: var(--space-3); }
  .pagehead { min-height: 34vh; }
}

/* Kennung und Titel bleiben beim Lesen der Facetten stehen. */
@media (min-width: 901px) {
  .svc__grid > :first-child {
    position: sticky;
    top: calc(var(--header-h) + var(--space-4));
  }
}

/* Facetten eines Leistungsblocks — durch Haarlinien getrennt, nicht durch Karten. */
.svc__facet + .svc__facet {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--grid-line);
}
.svc__facet .ds-h3 { margin-bottom: var(--space-1); color: var(--c-txt); }

/* Markenzeichen folgt der Ebene: Gold-Dunkel auf hell, helles Gold auf dunkel.
   Das SVG zeichnet mit stroke="currentColor". */
.brand-mark { color: var(--gold-dark); }
.site-header.is-over-dark .brand-mark,
.on-dark .brand-mark { color: var(--gold); }

/* Lesbarkeitsschutz im Kopfbereich: das Terrain darf nicht durch den
   Fließtext laufen. Verlauf von unten, wo der Text steht. */
.pagehead::after {
  content: "";
  position: absolute;
  inset: 30% 0 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(3, 4, 5, 0) 0%, rgba(3, 4, 5, 0.86) 62%, rgba(3, 4, 5, 0.94) 100%);
}

/* Hinweiskasten — Gold-Haarlinie links, keine Fläche. */
.note {
  margin-top: var(--space-5);
  padding: var(--space-3) 0 var(--space-3) var(--space-3);
  border-left: 2px solid var(--c-acc);
}
.note__label { display: block; margin-bottom: var(--space-1); color: var(--c-acc); }
.note p { margin: 0; max-width: 62ch; }

/* =========================================================================
   KONTAKT — FORMULAR
   Dieselbe Sprache wie der Rest: Mono-Versalien als Feldmarken, 1px-Rahmen
   ohne Radius, Gold nur als Akzent. Alle Haken, an denen main.js hängt
   (#contact-form, .field, .error-text, .field-error, .hp, .form-status,
   [data-required]), bleiben unverändert erhalten.
   ========================================================================= */

.form-layout {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--space-6);
  align-items: start;
  margin-top: var(--space-5);
}

#contact-form { display: grid; gap: var(--space-3); }

/* Zwei Felder nebeneinander, sobald Platz ist. */
.form-row { display: grid; gap: var(--space-3); }
@media (min-width: 560px) {
  .form-row { grid-template-columns: 1fr 1fr; }
}

/* --------------------------------------------------------------- Feld */
.field { display: grid; gap: var(--space-1); }
.field label {
  font-family: var(--font-mono);
  font-size: var(--mono-lg);
  font-weight: 400;
  letter-spacing: var(--track-4);
  text-transform: uppercase;
  color: var(--c-txt);
}
.field label .req { color: var(--c-acc); }
.field .hint {
  letter-spacing: var(--track-3);
  color: var(--c-txt-3);
}

.input, .textarea, .select {
  width: 100%;
  padding: var(--space-2);
  font-family: var(--font-sans);
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--c-txt);
  background: var(--c-panel);
  border: 1px solid var(--grid-line);
  border-radius: 0;
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.input::placeholder, .textarea::placeholder { color: var(--c-txt-3); }

/* Fokus als doppelte Haarlinie statt weichem Schein — passt zum Raster. */
.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--c-acc);
  box-shadow: inset 0 0 0 1px var(--c-acc);
}
.textarea { resize: vertical; min-height: 168px; }

.select {
  appearance: none;
  padding-right: var(--space-5);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238A6F35' stroke-width='2'%3E%3Cpath d='M5 9l7 7 7-7'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-2) center;
}

/* Honeypot — für Menschen unsichtbar, für Bots ein sichtbares Feld.
   main.js findet ihn über „.hp input"; diese Klasse muss bleiben. */
.hp {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* -------------------------------------------------------- Fehlerbild */
.field-error { border-color: var(--c-err) !important; }
.field-error:focus { box-shadow: inset 0 0 0 1px var(--c-err) !important; }
.error-text {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--mono-lg);
  letter-spacing: var(--track-3);
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--c-err);
}
.error-text:empty { display: none; }

/* ------------------------------------------------------- Einwilligung */
.field-consent { margin-top: var(--space-1); }
.field-consent .consent {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}
.field-consent input[type="checkbox"] {
  flex: none;
  width: 17px;
  height: 17px;
  margin: 3px 0 0;
  accent-color: var(--ink);
  cursor: pointer;
}
.field-consent label {
  font-family: var(--font-sans);
  font-size: 0.86rem;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  line-height: 1.6;
  color: var(--c-txt-2);
}
.field-consent a {
  color: var(--c-acc);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.field-consent input.field-error {
  outline: 2px solid var(--c-err);
  outline-offset: 3px;
}

/* ----------------------------------------------------- Statusmeldung */
/* Haarlinie links statt Fläche — wie .note. */
.form-status {
  display: none;
  padding: var(--space-2) 0 var(--space-2) var(--space-3);
  border-left: 2px solid var(--c-line);
  font-family: var(--font-sans);
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--c-txt-2);
}
.form-status.is-visible { display: block; }
.form-status.is-success { border-color: var(--c-ok); color: var(--c-txt); }
.form-status.is-error { border-color: var(--c-err); color: var(--c-txt); }

/* ---------------------------------------------------------- Absenden */
/* Der Goldbalken liegt bewusst in ::before: main.js tauscht während des
   Sendens den textContent des Buttons aus — echte Kindelemente wären
   danach weg, ein Pseudoelement überlebt. */
.ds-submit {
  position: relative;
  display: block;
  width: 100%;
  margin-top: var(--space-2);
  padding: var(--space-3) var(--space-4);
  padding-left: calc(var(--space-4) + 7px);
  font-family: var(--font-mono);
  font-size: var(--mono-xl);
  letter-spacing: var(--track-6);
  text-transform: uppercase;
  text-align: left;
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 0;
  cursor: pointer;
  transition: background-color 0.18s var(--ease);
}
.ds-submit::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 7px;
  background: var(--gold);
}
.ds-submit:hover { background: var(--void); border-color: var(--void); }
.ds-submit:focus-visible { outline: 2px solid var(--gold-dark); outline-offset: 3px; }
.ds-submit:disabled { cursor: progress; opacity: 0.62; }

.form-foot {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--space-1);
}

/* ------------------------------------------------- Beistellspalte */
.aside-block + .aside-block {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--grid-line);
}
.aside-block .ds-h3 { margin-bottom: var(--space-2); color: var(--c-txt); }

/* Nummerierte Liste mit Mono-Marke — Ablaufschritte, Reihenfolgen. */
.num-list {
  counter-reset: nl;
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
}
.num-list li {
  position: relative;
  counter-increment: nl;
  padding: var(--space-2) 0 var(--space-2) var(--space-5);
  font-family: var(--font-sans);
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--c-txt-2);
}
.num-list li + li { border-top: 1px solid var(--c-line-2); }
.num-list li::before {
  content: "0" counter(nl);
  position: absolute;
  left: 0;
  top: calc(var(--space-2) + 0.15em);
  font-family: var(--font-mono);
  font-size: var(--mono-md);
  letter-spacing: var(--track-4);
  color: var(--c-acc);
}

/* Mailadresse in Mono — sie ist eine technische Angabe, kein Fließtext. */
.ds-mail {
  display: inline-block;
  margin-top: var(--space-2);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: var(--track-2);
  color: var(--c-acc);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}
.ds-mail:hover { color: var(--c-txt); }

@media (max-width: 900px) {
  .form-layout {
    grid-template-columns: 1fr;
    gap: var(--space-6);
  }
}

/* Auf schmalen Schirmen ist die Einrückung der Ziffer zu teuer — sie kostet
   Zeilenlänge, ohne die Lesbarkeit zu verbessern. */
@media (max-width: 560px) {
  .num-list li { padding-left: var(--space-4); }
}
