/* EVMAN — die öffentliche Seite.
   Handgeschriebenes CSS mit Absicht: Diese Seite geht an Fremde, auf Handys,
   über Schul-WLAN — also ohne Framework, ohne Bauschritt und ohne fremde
   Schrift. Die Palette ist die Akzentrampe der Anwendung
   (apps/web/src/styles.css), unverändert übernommen.

   Alles Maßhafte steht im :root darunter: Abstände, Radien, Schatten, Zeiten,
   Schriftgrade. Wer hier etwas ergänzt, nimmt einen Wert von dort — ein neuer
   Zahlenwert in einer Regel braucht einen Grund, und der Grund gehört als Satz
   daneben. */

:root {
  /* Ohne diese Zeile darf Chrome auf Android die Seite selbst umfärben
     (Auto-Dark) — und trifft dabei weder die Rampe noch die Kontraste. */
  color-scheme: light;

  --accent-50: #f1f9fe;
  --accent-100: #d2edfe;
  --accent-200: #b1dffc;
  --accent-300: #80caf8;
  --accent-500: #1194e7;
  --accent-600: #0972b4; /* primary — 5.15:1 on white, AA as text */
  --accent-700: #0a5d91;
  --accent-900: #113d59;

  --gray-50: #f9fafb;
  --gray-100: #f3f4f6;
  --gray-200: #e5e7eb;
  /* 300 und 700 fehlten in der Rampe, wurden aber benutzt — teils mit einem
     Literal als zweitem Argument, teils ohne. Ohne Deklaration UND ohne
     Rückfallwert ist die Eigenschaft ungültig und fällt auf `currentColor`
     zurück: Der Rahmen des Sekundärknopfs wurde dadurch fast schwarz. */
  --gray-300: #d1d5db;
  --gray-400: #9ca3af;
  --gray-500: #6b7280;
  --gray-600: #4b5563;
  --gray-700: #374151;
  --gray-800: #1f2937;
  --gray-900: #111827;

  /* Eine warme Gegenlage zum Bedien-Blau (SITE-41). Blau bleibt die Farbe der
     Bedienung — Knöpfe, Links, Fokus, Player, Tour-Verweise. Messing markiert
     Herkunft: Augenbrauen, Zeitleiste, Ornamente, Preis-Fläche. Berechnete
     Kontraste:
       brass-700 #b45309 auf #fff      5,02:1  (AA als Text)
       brass-800 #92400e auf #fff      7,09:1  (AA/AAA als Text)
       brass-800 #92400e auf #fffbeb   6,84:1  (Text auf warmer Fläche)
       gray-800  #1f2937 auf #fffbeb  14,16:1  (Fließtext auf warmer Fläche)
     brass-600 ist Ornamentfarbe (Punkte, Linien, Striche) und nie Text. */
  --brass-50: #fffbeb;
  --brass-100: #fdf3d8;
  --brass-200: #f3e3c2;
  --brass-600: #d97706;
  --brass-700: #b45309;
  --brass-800: #92400e;

  /* Die Bedienfarbe unter eigenem Namen: Fläche, Balkenfüllung und Filter der
     Vorführung zeigen auf „das Blau, mit dem man arbeitet" — nicht auf eine
     Stufe der Rampe. Wird die Bedienung einmal umgefärbt, ist das hier eine
     Zeile. */
  --accent: var(--accent-600);

  /* Tinte für alles mit Durchsicht — Schatten, Auflagen, Ringe. Als Kanäle
     notiert, damit rgb(var(--ink) / x) den Alphawert an Ort und Stelle setzt. */
  --ink: 17 24 39; /* = gray-900 */
  --accent-ink: 10 93 145; /* = accent-700 */

  /* Warnfläche der Rechtsseiten und der Fehlerton im Kontaktformular — die
     beiden einzigen Farben außerhalb der drei Rampen. */
  --warn-bg: #fef3c7;
  --warn-border: #fcd34d;
  --warn-ink: #78350f;
  --error-ink: #fecaca;

  /* --- Abstände ------------------------------------------------------------
     Ein 4-px-Raster; die Ziffer im Namen ist die Zahl der Einheiten
     (--space-3 = 3 × 4 px = 0.75rem). Wer eine Sektion ergänzt, wählt aus
     dieser Liste, statt den Wert der Nachbarregel abzuschreiben.
     Zwei Sorten Maß stehen bewusst nicht hier:
       · fließende — die clamp()-Rampen der Sektionen und Überschriften folgen
         der Fensterbreite, nicht dem Raster;
       · geometrische — Tap-Flächen (44 px), Schrittmarken (24 px), Blende,
         Textbreiten, Überlappungen. Sie erfüllen eine Anforderung und werden
         dort erklärt, wo sie steht. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-7: 1.75rem;
  --space-8: 2rem;
  --space-9: 2.25rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-13: 3.25rem;
  --space-18: 4.5rem;

  /* Radien: vier Stufen und die Pille. Alles Rundere ist Gerätegeometrie und
     steht weiter unten. */
  --radius-xs: 0.125rem;
  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
  --radius-full: 999px;

  /* Schatten als Rampe: je höher etwas liegt, desto weiter und weicher fällt
     er. --shadow-accent ist der einzige farbige — der Hauptknopf wirft ihn in
     seinem eigenen Blau, ein grauer Rand um eine blaue Fläche sähe schmutzig
     aus. */
  --shadow-sm: 0 2px 8px -2px rgb(var(--ink) / 0.3);
  --shadow-md: 0 1px 2px rgb(var(--ink) / 0.04), 0 8px 24px -12px rgb(var(--ink) / 0.12);
  --shadow-lg: 0 18px 30px -22px rgb(var(--ink) / 0.5);
  --shadow-xl: 0 24px 48px -24px rgb(var(--ink) / 0.55);
  --shadow-2xl: 0 1px 2px rgb(var(--ink) / 0.05), 0 30px 60px -30px rgb(var(--ink) / 0.35);
  --shadow-accent: 0 1px 2px rgb(var(--accent-ink) / 0.3), 0 8px 20px -10px rgb(var(--accent-ink) / 0.6);

  /* Schriftgrade. 16 px ist der Fließtext; darunter liegen die Stufen dichter,
     weil Bildunterschrift, Randnotiz und Kürzel sich unterscheiden müssen,
     ohne unlesbar zu werden. Überschriften wachsen fließend (clamp) und stehen
     deshalb nicht in der Liste. */
  --text-3xs: 0.625rem;
  --text-2xs: 0.75rem;
  --text-xs: 0.8125rem;
  --text-sm: 0.875rem;
  --text-md: 0.9375rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.375rem;
  --text-3xl: 1.5rem;

  /* Zeiten. --dur-slow ist zugleich die Blendzeit der Vorführung und muss mit
     FADE_MS in demo.js übereinstimmen. */
  --dur-fast: 120ms;
  --dur-base: 160ms;
  --dur-slow: 220ms;
  --dur-press: 420ms;

  /* Symbole, die an mehr als einer Stelle stehen: einmal in der Leiste unter
     der Aufnahme (dunkel auf Weiß), einmal als Auflage auf ihr (weiß auf
     Grau). Deshalb je zwei Fassungen — ein Data-URI erbt kein currentColor. */
  --icon-play: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white"><path d="M8 5l11 7-11 7z"/></svg>');
  --icon-pause: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white"><rect x="6" y="4" width="4" height="16" rx="1"/><rect x="14" y="4" width="4" height="16" rx="1"/></svg>');
  --icon-back: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 6l-6 6 6 6" fill="none" stroke="%234b5563" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg>');
  --icon-fwd: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 6l6 6-6 6" fill="none" stroke="%234b5563" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg>');
  --icon-back-light: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 6l-6 6 6 6" fill="none" stroke="white" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg>');
  --icon-fwd-light: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 6l6 6-6 6" fill="none" stroke="white" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg>');

  /* Gerätegeometrie der Handy-Attrappe. Vier Maße, die zusammengehören: Blende,
     Außenrundung, Bildschirmrundung, Tastenbreite. Der Zoom (SITE-29) skaliert
     alle vier mit demselben Faktor. */
  --phone-bezel: 0.6rem;
  --phone-radius: 2.2rem;
  --phone-screen-radius: 1.6rem;
  --phone-key: 0.16rem;

  /* Satzspiegel und Kopfzeilenhöhe. Letztere kennt auch das Sprungziel
     (scroll-padding-top), sonst verschwände jeder Anker unter der Leiste. */
  /* SITE-51: die Rollen, die eine Umkehrung nicht mitmachen. canvas ist der
     Grund der Seite, surface die erhobene Fläche (Karte, Kopf, Feld) — im
     Hellen ist surface heller als canvas, im Dunkeln ebenfalls, also kann
     keine Graustufe beides sein. Der Fuß und das Kontaktband sind in beiden
     Moden dunkle Bahnen: Was auf ihnen liegt, folgt der Rampe nicht, sonst
     stünde im Dunkeln dunkelblaue Schrift auf dunkelblauem Grund. */
  --canvas: #fff;
  --surface: #fff;
  --surface-translucent: rgb(255 255 255 / 0.9);
  --primary-hover: var(--accent-700);
  --footer-bg: var(--gray-900);
  --footer-fg: var(--gray-400);
  --footer-link: var(--gray-200);
  --contact-from: var(--accent-900);
  --contact-to: var(--accent-700);
  --on-contact: var(--accent-100);
  --on-contact-btn: var(--accent-700);
  --on-contact-btn-hover: var(--accent-50);

  --wrap: 68rem;
  --header-height: 4rem;
}

/* --- SITE-51: Dunkelmodus ---------------------------------------------------
   Die Rampe ist der ganze Trick: Was hier neu belegt wird, wirkt überall, wo
   die Seite `var(--gray-…)` schreibt — und das tut sie an neunzig Stellen.
   Zwei Enden mit verschiedenen Aufgaben:

     50–300   Flächen und Linien  → im Dunkeln dunkel (gekippt)
     400–900  Schrift und Symbole → im Dunkeln hell   (gekippt)

   accent-500/600 bleiben: Füllung, Fokusring und `accent-color` tragen in
   beiden Moden, und ein aufgehelltes accent-600 würde die weiße Schrift auf
   dem Knopf unter 4,5:1 drücken.

   `data-theme` setzt theme.js, im Kopf der Seite und ohne `defer` — die
   Entscheidung muss vor dem ersten Bild stehen, sonst blitzt die weiße Seite
   auf. Das Skript löst „auto" selbst auf, deshalb kennt das Stylesheet nur
   hell und dunkel und keine Medienabfrage: eine zweite Belegung derselben
   drei Dutzend Farben wäre die Stelle, an der beide auseinanderlaufen. Ohne
   Skript bleibt die Seite hell — der Umschalter, der ohnehin Speicher
   braucht, wäre dann auch nur eine tote Schaltfläche. */
:root[data-theme='dark'] {
  color-scheme: dark;

  --canvas: #1a1f26;
  --surface: #232931;
  --surface-translucent: rgb(35 41 49 / 0.9);
  --primary-hover: var(--accent-500);
  --footer-bg: #12161b;
  --footer-fg: #aeb7c3;
  --footer-link: #e9eef4;
  /* Das Kontaktband bleibt ein dunkelblauer Block — die Rampe kippt unter ihm
     weg, seine Töne dürfen es nicht. */
  --contact-from: #12293b;
  --contact-to: #14567f;
  --on-contact: #cfe6f7;
  --on-contact-btn: #0a5d91;
  --on-contact-btn-hover: #e8f2fa;

  --gray-50: #2b323b;
  --gray-100: #333b45;
  --gray-200: #3d4652;
  /* 300 trägt Ränder von Bedienelementen (Sekundärknopf), nicht nur Linien —
     WCAG 1.4.11 verlangt dort 3:1. Gekippt lag der Ton bei 1,91:1 auf surface
     und 1,68:1 auf gray-50, dem Grund desselben Knopfs im Überfahren; die
     Rampe war auf Schrift gerechnet (1.4.3) und hat die Nicht-Text-Paare
     ausgelassen. 3,35:1 auf gray-50, 3,80:1 auf surface, 4,29:1 auf canvas. */
  --gray-300: #78838f;
  --gray-400: #949eab;
  --gray-500: #aeb7c3; /* 7,2:1 auf surface */
  --gray-600: #c4cbd5;
  --gray-700: #d8dee5;
  --gray-800: #e9eef4; /* Fließtext */
  --gray-900: #f7f9fc;

  --accent-50: #16293a;
  --accent-100: #1c3950;
  --accent-200: #234a67;
  --accent-300: #2b5d7e;
  --accent-700: #7cc6f6; /* Linkfarbe — 8,1:1 auf accent-50 */
  --accent-900: #cfeafd;

  --brass-50: #2e2210;
  --brass-100: #3a2c14;
  --brass-200: #48381a;
  --brass-700: #fbbf24;
  --brass-800: #fcd34d;

  /* Die Warnfläche der Rechtsseiten kippt als Ganzes: dunkler Grund, heller
     Text — ein hellgelber Kasten wäre auf der dunklen Seite ein Loch. */
  --warn-bg: #3a2c14;
  --warn-border: #5c4a1e;
  --warn-ink: #fde68a;

  /* Tinte für alles mit Durchsicht: Auf dunklem Grund trägt ein Schatten aus
     gray-900 nichts mehr, die Tiefe muss aus Schwarz kommen — und stärker. */
  --ink: 0 0 0;
  --shadow-md: 0 1px 2px rgb(0 0 0 / 0.5), 0 10px 26px -12px rgb(0 0 0 / 0.75);
  --shadow-2xl: 0 1px 2px rgb(0 0 0 / 0.5), 0 30px 60px -30px rgb(0 0 0 / 0.8);

  /* Die beiden Pfeile der Leiste sind Bilder: Ihre Strichfarbe steckt im
     Datenblock und kippt mit keiner Rampe mit. gray-600 auf dunklem Knopf
     wäre ein schwarzer Pfeil auf Schwarz. */
  --icon-back: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14 6l-6 6 6 6" fill="none" stroke="%23c4cbd5" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg>');
  --icon-fwd: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 6l6 6-6 6" fill="none" stroke="%23c4cbd5" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg>');
}

/* Stapelordnung, von unten nach oben:
     Seite: Inhalt 0 · Kopfzeile 20 · Sprungmarke 100
     in einer Aufnahme (.demo-screen ist ein eigener Stapel, siehe dort):
     Standbild 0/1 · Band 1 · Clip 2 · Zeiger und Titelkarte 3 · Schalter 4 ·
     Schrittknöpfe 5 */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Ein Anker darf nicht unter der klebenden Kopfzeile landen. */
  scroll-padding-top: calc(var(--header-height) + var(--space-4));
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--gray-800);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
}

img,
svg {
  max-width: 100%;
}

a {
  color: var(--accent-700);
  text-underline-offset: 0.2em;
}

:where(a, button, summary, input):focus-visible {
  outline: 2px solid var(--accent-600);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* accent-600 bleibt im Dunkeln stehen (die Füllung braucht es), aber als Ring
   liegt es dann dunkelblau auf dunklem Grund: 2,85:1 auf surface, 2,51:1 auf
   gray-50 (Karten, FAQ-Zeilen), 3,22:1 auf canvas — 1.4.11 verlangt 3:1. Der
   Fokus ist die einzige Anzeige, die die Tastatur hat. accent-700 ist im
   Dunkeln die helle Linkfarbe und trägt auf allen drei Flächen (6,9–8,9:1).
   `:where` um die Wurzel hält die Spezifität bei 0-1-0: Die Regel schlägt die
   allgemeine oben durch die Reihenfolge, verliert aber gegen `.contact`
   (0-2-0) — dort bleibt der weiße Ring von SITE-46. */
:where(:root[data-theme='dark']) :where(a, button, summary, input):focus-visible {
  outline-color: var(--accent-700);
}

h1,
h2,
h3 {
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--gray-900);
  text-wrap: balance;
}

h1 {
  font-size: clamp(1.875rem, 1.3rem + 2.4vw, 2.875rem);
  margin: 0 0 var(--space-3);
}

h2 {
  font-size: clamp(1.375rem, 1.15rem + 1.1vw, 1.875rem);
  margin: 0 0 var(--space-3);
}

h3 {
  /* 17 px standen genau 1 px über dem Fließtext — die Kartenüberschriften
     trugen die Hierarchie allein über Fett. Eine Stufe der Rampe höher ist
     es wieder eine Stufe. */
  font-size: var(--text-xl);
  margin: 0 0 var(--space-1);
}

p {
  text-wrap: pretty;
}

.wrap {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

.narrow {
  max-width: 44rem;
}

section {
  padding-block: clamp(3rem, 7vw, 5.5rem);
}

.lead {
  font-size: clamp(1rem, 0.96rem + 0.25vw, 1.125rem);
  color: var(--gray-600);
  margin: 0 0 var(--space-8);
}

.eyebrow {
  display: inline-block;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--brass-800); /* 7,09:1 auf Weiß */
  margin: 0 0 var(--space-2);
}

/* Der Strich davor ist eine Notenlinie aus dem Logo — das Zeichen besteht aus
   vier davon. Dekorativ, deshalb ::before und kein Zeichen im Text. */
.eyebrow::before {
  content: "";
  display: inline-block;
  width: 1.5rem;
  height: 2px;
  border-radius: var(--radius-full);
  background: var(--brass-600);
  vertical-align: 0.22em;
  margin-right: var(--space-2);
}

/* --- Für das Auge weg, für die Tastatur da ---
   Vier Stellen brauchen dasselbe: ein Element, das im Baum steht und Fokus
   nehmen kann, aber keinen Platz einnimmt — die Sprungmarke (SITE-35), der
   Honigtopf des Formulars (SITE-39), die noch leere Statuszeile (SITE-47) und
   die Ansage der Vorführung (SITE-54), die nie zu sehen, aber immer zu hören
   ist. Weder `display: none` (nähme es der Tastatur und dem Vorleseprogramm)
   noch ein Negativ-Einzug (erzeugte waagrechtes Scrollen, SITE-9): auf einen
   Punkt geclippt bleibt es beides. */
.skip-link,
.contact-form .hp,
.contact-form .form-status:empty,
.demo-live {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Die Sprungmarke ist der erste Tabstopp der Seite und klappt bei Fokus zur
   Marke auf. Sie hängt am Fenster, ist aber nicht über dessen oberen Rand
   geschoben: Beim Überziehen nach oben (Rubber-Band auf iOS, Overscroll auf
   Android) wandert die Seite samt `fixed`-Elementen mit — und genau dann
   stünde die Marke sichtbar über dem Kopf. Geclippt bleibt sie in jeder
   Scrollposition weg. */
.skip-link {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100;
  padding: 0;
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  background: var(--accent-600);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
  box-shadow: var(--shadow-md);
}

.skip-link:focus-visible {
  left: 50%;
  transform: translateX(-50%);
  width: auto;
  height: auto;
  padding: var(--space-3) var(--space-5);
  overflow: visible;
  clip-path: none;
  white-space: nowrap;
}

/* --- Kopfzeile --- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--surface-translucent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--gray-200);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  min-height: var(--header-height);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 700;
  font-size: var(--text-lg);
  letter-spacing: 0.02em;
  color: var(--gray-900);
  text-decoration: none;
}

.brand img {
  width: 1.9rem;
  height: 1.9rem;
  flex: none;
}

.site-nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.site-nav a {
  color: var(--gray-600);
  text-decoration: none;
  font-size: var(--text-md);
  font-weight: 500;
}

.site-nav a:hover {
  color: var(--accent-700);
}

/* Ohne diese Regel schlägt `.site-nav a` den `.btn-primary` und schriebe die
   Aufschrift des Hauptknopfs grau auf blau. */
.site-nav a.btn-primary {
  color: #fff;
}

/* --- Menü am Handy --- */

.nav-toggle {
  /* Der Abstand der drei Balken: er steht in vier Regeln (zwei Kanten, zwei
     Drehungen) und muss überall derselbe sein, sonst schließt das Kreuz nicht. */
  --bar-gap: 0.375rem;
  display: none;
  margin-left: auto;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--gray-200);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--gray-800);
  cursor: pointer;
}

/* Drei Balken aus einem Element: der mittlere ist das Element selbst. */
.nav-toggle .bars,
.nav-toggle .bars::before,
.nav-toggle .bars::after {
  display: block;
  width: 1.15rem;
  height: 2px;
  border-radius: var(--radius-full);
  background: currentColor;
  transition: transform var(--dur-base) ease, opacity var(--dur-fast) ease;
}

.nav-toggle .bars {
  position: relative;
}

.nav-toggle .bars::before,
.nav-toggle .bars::after {
  content: "";
  position: absolute;
  left: 0;
}

.nav-toggle .bars::before {
  top: calc(var(--bar-gap) * -1);
}

.nav-toggle .bars::after {
  top: var(--bar-gap);
}

.nav-toggle[aria-expanded="true"] .bars {
  background: transparent;
}

.nav-toggle[aria-expanded="true"] .bars::before {
  transform: translateY(var(--bar-gap)) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .bars::after {
  transform: translateY(calc(var(--bar-gap) * -1)) rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
  .nav-toggle .bars,
  .nav-toggle .bars::before,
  .nav-toggle .bars::after {
    transition: none;
  }
}

/* Unter 768px passen Marke, fünf Links und der CTA nicht in eine Zeile — die
   Navigation wird zum Panel unter dem Header, der CTA wandert an dessen Ende
   (im Hero steht er ohnehin schon). */
@media (max-width: 47.99rem) {
  .nav-toggle {
    display: inline-flex;
  }

  .site-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin: 0;
    padding: var(--space-1) var(--space-5) var(--space-4);
    background: var(--surface);
    border-bottom: 1px solid var(--gray-200);
    box-shadow: var(--shadow-lg);
  }

  .site-nav[data-open] {
    display: flex;
  }

  .site-nav a:not(.btn) {
    padding: var(--space-3) 0;
    font-size: var(--text-base);
    color: var(--gray-800);
    border-bottom: 1px solid var(--gray-100);
  }

  .site-nav a.btn {
    margin-top: var(--space-4);
    padding: var(--space-3) var(--space-5);
    font-size: var(--text-md);
  }
}

/* --- Knöpfe --- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-lg);
  font-size: var(--text-md);
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background-color var(--dur-base), border-color var(--dur-base), color var(--dur-base);
}

/* Die Elevation lag verkehrt herum: Der schwächere Knopf hatte den Schatten
   und schwebte über dem stärkeren. Dazu fehlte jeder Druckpunkt — auf dem
   erklärten Hauptgerät der Zielgruppe der Unterschied zwischen „hat's
   reagiert?" und „hat reagiert". */
.btn-primary {
  background: var(--accent-600);
  color: #fff;
  box-shadow: var(--shadow-accent);
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary:hover {
  background: var(--primary-hover);
}

.btn-secondary {
  background: var(--surface);
  color: var(--gray-800);
  border-color: var(--gray-300);
  box-shadow: none;
}

.btn-secondary:hover {
  background: var(--gray-50);
}

.btn-sm {
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* --- Auftakt --- */

/* Luft, aber nicht die ganze Bildschirmhöhe (SITE-41).
   Die Abstände sind hier bewusst großzügiger als im Rest der Seite: Der Hero
   ist der einzige Ort, an dem jemand zum ersten Mal steht, und gedrängte Zeilen
   lesen sich dort als Hast. Die Rechnung dahinter — bei 1280×900 beginnt der
   Browser-Rahmen um y 570, es bleiben also gut 330 px Produkt sichtbar. Das ist
   Absicht: Ein angeschnittener Rahmen lädt zum Weiterrollen ein, ein
   vollständig sichtbarer ist ein Bild, das man abhakt. */
.hero {
  position: relative;
  overflow: hidden;
  background: linear-gradient(var(--canvas), var(--gray-50));
  border-bottom: 1px solid var(--gray-200);
  padding-block: clamp(2.5rem, 4.5vw, 3.75rem) clamp(3rem, 6vw, 4.5rem);
}

/* Notenlinien als Flächenornament, oben rechts ausklingend — dieselben vier
   Linien, aus denen das Logo den Schlüssel stanzt. Ersetzt den früheren
   radialen Farbschleier, der nur Blau auf Blau war. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 24rem;
  background: repeating-linear-gradient(
    to bottom,
    rgb(9 114 180 / 0.09) 0 2px,
    transparent 2px 14px
  );
  --fade: radial-gradient(52rem 22rem at 88% -4rem, #000 25%, transparent 72%);
  mask-image: var(--fade);
  -webkit-mask-image: var(--fade);
  pointer-events: none;
}

.hero .wrap {
  position: relative;
}

/* Die Marke als Schulter der Überschrift: Zeichen, Wortmarke und Einordnung in
   einer Zeile. Sie ersetzt die frühere Augenbraue, kostet also kaum Höhe. */
.hero-brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin: 0 0 var(--space-7);
}

.hero-brand img {
  width: 2.5rem;
  height: 2.5rem;
  flex: none;
}

.hero-wordmark {
  font-size: var(--text-3xl);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--gray-900);
}

.hero-kicker {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding-left: var(--space-3);
  border-left: 2px solid var(--brass-600);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--brass-800);
}

@media (max-width: 30rem) {
  .hero-brand img {
    width: 2.1rem;
    height: 2.1rem;
  }

  .hero-wordmark {
    font-size: var(--text-xl);
  }

  /* Auf schmalen Geräten bricht die Einordnung unter die Marke — dort wäre der
     senkrechte Strich die falsche Trennung. */
  .hero-kicker {
    padding-left: 0;
    border-left: 0;
    flex-basis: 100%;
  }
}

/* Dieselbe Textbreite wie der Lead darunter. Vorher lief die Überschrift über
   die ganze Sektionsbreite und war damit breiter als ihr eigener
   Einleitungssatz — der Block wirkte oben auseinandergezogen und unten schmal.
   Auf 34 rem bricht sie in zwei Zeilen und die Kante stimmt. */
.hero h1 {
  max-width: 34rem;
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.5rem);
  line-height: 1.15;
  margin-bottom: var(--space-5);
}

.hero-copy .lead {
  max-width: 34rem; /* 55–75 Zeichen je Zeile */
  line-height: 1.65;
  margin-bottom: var(--space-8);
}

/* Der größte Abstand der Seite steht hier: zwischen dem, was versprochen wird,
   und dem, was es beweist. */
.hero-demo {
  margin-top: var(--space-13);
  min-width: 0;
}

.hero-demo .demo-head,
.hero-demo .shots {
  margin-top: 0;
}

.hero .note {
  margin-top: var(--space-5);
  font-size: var(--text-sm);
  color: var(--gray-500);
}

/* --- Raster und Kacheln --- */

.grid {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}

.card {
  background: var(--surface);
  border: 1px solid var(--gray-200);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-md);
}

.card p {
  margin: 0;
  color: var(--gray-600);
  font-size: var(--text-md);
}

.card .icon {
  display: grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: var(--radius-md);
  background: var(--accent-50);
  color: var(--accent-700);
  margin-bottom: var(--space-4);
}

.card .icon svg {
  width: 1.35rem;
  height: 1.35rem;
}

/* SITE-44 — die Export-Kachel zeigt, was sie verspricht.
   Sie ist die einzige Kachel, die ein Ergebnis beschreibt statt einer
   Tätigkeit, und sie war im dreispaltigen Raster die Waise der letzten Zeile.
   Beides löst dieselbe Setzung: zwei Spalten breit, Text links, das fertige
   Blatt rechts. */
.card-wide {
  position: relative;
  overflow: hidden;
}

/* Das Blatt wird angeschnitten, statt ganz zu stehen: Ein Programm dieser
   Länge lässt das untere Drittel der Seite weiß, und weißes Papier auf weißer
   Kachel ist kein Bild. Angeschnitten liest es sich als Dokument, das
   weitergeht — und die Kachel behält die Höhe ihrer Zeile. */
.card-sheet {
  margin: var(--space-5) 0 0;
  max-height: 13rem;
  overflow: hidden;
  border-radius: var(--radius-sm);
  /* Der Papierrand: eine Haarlinie und ein Schatten, der das Blatt von der
     weißen Kachel abhebt — ohne ihn verschwämme Papier in Papier. */
  box-shadow:
    0 0 0 1px var(--gray-200),
    0 10px 24px rgb(var(--ink) / 0.12);
}

.card-sheet img {
  display: block;
  width: 100%;
  height: auto;
}

/* Erst spannen, wenn es etwas zu spannen gibt: `span 2` in einem
   auto-fit-Raster erzwingt eine zweite Spalte, auch wenn sie nicht
   hineinpasst — die ganze Sektion liefe dann waagrecht über. Das Raster bricht
   bei 620px auf zwei Spalten um; ab 40rem ist es also sicher, und ab da steht
   das Blatt neben dem Text statt darunter. */
@media (min-width: 40rem) {
  .card-wide {
    grid-column: span 2;
    /* Platz für das Blatt: seine Breite plus der Abstand zu beiden Kanten. */
    padding-right: calc(13.5rem + var(--space-6) * 2);
  }

  .card-sheet {
    position: absolute;
    top: var(--space-6);
    right: var(--space-6);
    width: 13.5rem;
    margin: 0;
    max-height: none;
  }
}

.alt {
  background: var(--gray-50);
  border-block: 1px solid var(--gray-200);
}

/* --- Produktaufnahmen --- */

.shots {
  --bezel: var(--phone-bezel);
  position: relative;
  margin-top: var(--space-12);
}

.shots figure {
  margin: 0;
}

.shot-browser {
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--gray-200);
  box-shadow: var(--shadow-2xl);
}

.shot-browser .chrome {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--gray-100);
  border-bottom: 1px solid var(--gray-200);
}

.shot-browser .chrome span {
  width: 0.6rem;
  height: 0.6rem;
  border-radius: var(--radius-full);
  background: var(--gray-200);
}

.shot-browser .chrome .url {
  flex: 1;
  margin-left: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background: var(--surface);
  border: 1px solid var(--gray-200);
  font-size: var(--text-2xs);
  color: var(--gray-500);
  text-align: center;
}

.shot-browser img,
.shot-phone img {
  display: block;
  width: 100%;
  height: auto;
}

/* `.shots figure` schlüge diese Regel sonst und nähme ihr das `auto` in der
   Mitte. Unterhalb der Überlappungsgrenze stehen die beiden Rahmen einfach
   übereinander — überlappt begrub das Handy die Tabelle. */
.shots .shot-phone {
  position: relative;
  margin: var(--space-7) auto 0;
  width: min(15rem, 62%);
  border: var(--bezel) solid var(--gray-900);
  border-radius: var(--phone-radius);
  overflow: visible;
  background: var(--gray-900);
  box-shadow: var(--shadow-xl);
}

.shot-phone img {
  border-radius: var(--phone-screen-radius);
}

/* Die Seitentasten — ohne sie liest sich die Blende als Bilderrahmen und
   nicht als Gerät. */
.shot-phone .key {
  position: absolute;
  width: 0.16rem;
  background: var(--gray-800);
  border-radius: var(--radius-xs);
}

.shot-phone .key-action,
.shot-phone .key-vol-up,
.shot-phone .key-vol-down {
  left: calc(-1 * var(--bezel) - 0.14rem);
  border-radius: var(--radius-xs) 0 0 var(--radius-xs);
}

.shot-phone .key-power {
  right: calc(-1 * var(--bezel) - 0.14rem);
  border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
  top: 30%;
  height: 13%;
}

.shot-phone .key-action {
  top: 19%;
  height: 5%;
}
.shot-phone .key-vol-up {
  top: 27%;
  height: 7%;
}
.shot-phone .key-vol-down {
  top: 36%;
  height: 7%;
}

/* Breit genug, dass das Handy den Browser-Rahmen überlappt, ohne die Tabelle
   zu verdecken. */
@media (min-width: 56rem) {
  .shots {
    padding-right: 12rem;
  }

  .shots .shot-phone {
    position: absolute;
    right: 0;
    bottom: -2rem;
    margin: 0;
    width: 15rem;
  }
}

/* --- Die Vorführung (SITE-16 ff.) -------------------------------------------
   Alles ab hier greift erst, wenn demo.js die beiden Standbilder durch einen
   Ablauf ersetzt hat. Ohne das Skript gibt es keine dieser Klassen, und die
   Sektion bleibt genau das, was SITE-9 verlangt: zwei Bilder und eine Zeile
   Text. ---------------------------------------------------------------------- */

/* Jeder Rahmen ist ein eigener Stapel.
   `position: relative` allein legt keinen an — ohne `isolation` gelten die
   z-index von Band (1), Clip (2) und Zeiger (3) im Stapel der ganzen Sektion,
   und weil der Handy-Rahmen dort nur bei `auto` liegt, malte der Zeiger des
   Browser-Rahmens über das ganze Handy. */
.demo-screen {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  /* Bezugsgröße für die Titelkarte: Sie soll sich nach dem Rahmen richten, in
     dem sie liegt, nicht nach dem Fenster. */
  container-type: inline-size;
}

/* Und die Reihenfolge der beiden Rahmen wird gesagt, nicht dem Zufall der
   Quelltextreihenfolge überlassen: Das Handy liegt vorn. */
.shots .shot-browser {
  position: relative;
  z-index: 0;
}

.shots .shot-phone {
  z-index: 1;
}

/* Zwei deckungsgleiche Standbilder, von denen immer genau eines sichtbar ist.
   Erst wenn das nächste geladen ist, tauschen sie — dazwischen gibt es keinen
   Frame ohne Bild. Die Höhe gibt das `aspect-ratio` vor, das demo.js aus den
   Maßen der Aufnahme setzt. */
/* Der Bildwechsel läuft in einer Richtung: Das neue Bild kommt oben auf, das
   alte bleibt darunter voll deckend liegen, bis das neue steht. Zwei Bilder,
   die gleichzeitig durch 50 % gehen, lassen den Hintergrund zwischen sich
   durchscheinen — auf dunklen Flächen als sichtbares Aufhellen. */
.demo-screen.is-live .demo-shot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  z-index: 0;
}

/* Das abgelöste Bild: bleibt deckend, blendet nicht, verschwindet erst danach. */
.demo-screen.is-live .demo-shot.is-under {
  opacity: 1;
  transition: none;
}

/* Das neue Bild: liegt oben und zieht von 0 auf 1. */
.demo-screen.is-live .demo-shot.is-current {
  opacity: 1;
  z-index: 1;
  transition: opacity var(--dur-slow) ease-out;
}

.shot-phone .demo-screen {
  border-radius: var(--phone-screen-radius);
}

/* `.shot-browser img` weiter oben setzt `display: block` und ist spezifischer
   als das `[hidden]` des Browsers — ohne diese Regel bleibt das Scrollband des
   vorigen Schritts über dem neuen Standbild liegen, quer über die Vorführung.
   Deshalb hier ausdrücklich, mit genug Spezifität, wieder ausgeblendet. */
.shot-browser img[hidden],
.shot-phone img[hidden],
.demo-window[hidden],
.demo-clip[hidden] {
  display: none;
}

/* Das Fenster schneidet hart ab — was das Band darüber hinaus tut, ist von
   außen nicht zu sehen. */
.demo-window {
  position: absolute;
  z-index: 1;
  overflow: hidden;
}

.demo-band {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: auto;
  transform-origin: top left;
}

.demo-clip {
  position: absolute;
  z-index: 2;
  height: auto;
}

/* Äußeres Element: nur die Bewegung. */
.demo-cursor {
  position: absolute;
  z-index: 3;
  left: 0;
  top: 0;
  width: 1.35rem;
  height: 1.35rem;
  margin: -0.2rem 0 0 -0.2rem;
  pointer-events: none;
}

/* Inneres Element: das Sichtbare — und der Klick. */
.demo-cursor-body {
  position: absolute;
  inset: 0;
  transform-origin: 22% 18%;
  /* Zeiger als Grafik statt als Bild: bleibt bei jeder Rahmenbreite scharf. */
  background: no-repeat center/contain
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28"><path d="M4 2 L4 22 L9 17 L13 26 L17 24 L13 15 L20 15 Z" fill="white" stroke="%23111827" stroke-width="2" stroke-linejoin="round"/></svg>');
  filter: drop-shadow(0 1px 2px rgb(var(--ink) / 0.4));
}

.shot-phone .demo-cursor {
  width: 1.7rem;
  height: 1.7rem;
  margin: -0.85rem 0 0 -0.85rem;
}

.shot-phone .demo-cursor-body {
  transform-origin: 50% 50%;
  background-image: none;
  border-radius: var(--radius-full);
  background-color: rgb(var(--ink) / 0.32);
  box-shadow: inset 0 0 0 2px #fff;
}

/* Der Klick: der Zeiger geht kurz auf und wieder zu, dazu ein Ring, der
   aufgeht und verschwindet. Ohne die Skalierung sieht man auf einem
   Standbild-Wechsel nicht, dass überhaupt geklickt wurde. */
.demo-cursor.is-click .demo-cursor-body {
  animation: demo-press var(--dur-press) cubic-bezier(.34, 1.3, .64, 1);
}

@keyframes demo-press {
  0% { transform: scale(1); }
  35% { transform: scale(1.45); }
  100% { transform: scale(1); }
}

.demo-cursor::after {
  content: '';
  position: absolute;
  inset: -0.55rem;
  border-radius: var(--radius-full);
  background: var(--accent);
  opacity: 0;
  transform: scale(0.4);
}

.demo-cursor.is-click::after {
  animation: demo-pulse var(--dur-press) ease-out;
}

@keyframes demo-pulse {
  0% { opacity: 0.5; transform: scale(0.4); }
  100% { opacity: 0; transform: scale(1.3); }
}

/* --- die Titelkarte (SITE-27) ---
   Vor jedem Ablauf steht eine weiße Fläche mit seinem Namen. Sie liegt über
   Band, Clip und Zeiger (die alle in ihrem Schritt stehen bleiben), aber unter
   dem Schalter — anhalten muss auch auf der Karte gehen.

   Ein- und Ausblenden statt harter Schnitt: dieselben 220 ms wie beim
   Bildwechsel, damit die Karte zur Vorführung gehört und nicht dazwischenfährt.
   `visibility` wird verzögert mitgeschaltet, sonst bliebe der Text auch
   unsichtbar noch vorlesbar. */
.demo-title {
  position: absolute;
  z-index: 3;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8%;
  background: var(--surface);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--dur-slow) ease-out, visibility 0s var(--dur-slow);
}

.demo-title.is-on {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--dur-slow) ease-out;
}

/* Die Schrift wächst mit dem Rahmen, nicht mit dem Fenster: Browser- und
   Handy-Rahmen stehen nebeneinander auf derselben Seite, und eine Größe in
   Fenstereinheiten machte den Titel im Handy riesig und im Browser klein. */
/* SITE-27: Der Name bricht um, statt aus der Karte zu laufen. Die Untergrenze
   des `clamp` ist eine Lesbarkeitsgrenze und darf nicht fallen — im
   Handy-Rahmen neben dem Browser ist die Karte aber nur ~136 px breit, und
   „Benachrichtigungen" misst dort 165 px. Ein deutsches Kompositum hat keine
   Leerstelle, an der `balance` umbrechen könnte; es lief 29 px über den Rahmen
   hinaus. `hyphens` trennt es an seinen echten Stellen (das Dokument sagt
   `lang="de"`), `overflow-wrap` fängt ab, was das Wörterbuch nicht kennt.
   Senkrecht kostet das nichts: Die Karte füllt den ganzen Rahmen. */
.demo-title p {
  margin: 0;
  text-align: center;
  text-wrap: balance;
  hyphens: auto;
  overflow-wrap: break-word;
  font-size: clamp(1.1rem, 7cqi, 2.6rem);
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--gray-900);
}

/* --- Bedienelemente --- */

/* Die Kopfzeile (SITE-28): Titel links, Bedienung rechts. Sie existiert nur,
   wenn demo.js sie füllt — ohne Skript bleibt sie leer und [hidden].
   `space-between` statt `margin-left: auto` an der Bedienung: Passen beide
   nebeneinander, steht sie genauso rechts. Passen sie nicht (zwischen 56 und
   gut 62 rem trägt die Kopfzeile alles, nebeneinander wird es aber zu breit —
   und schmal ebenso), bricht sie um; ein automatischer Rand hielte sie dann
   auch in der eigenen Zeile rechts, als schwebende Insel neben leerem Raum.
   So beginnt die umgebrochene Zeile an derselben Kante wie der Titel. */
.demo-head {
  margin-top: var(--space-12);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3) var(--space-6);
  flex-wrap: wrap;
}

.demo-head-text {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.demo-head-text h2 {
  margin: 0;
  font-size: var(--text-2xl);
}

.demo-head-text p {
  margin: 0;
  font-size: var(--text-md);
  color: var(--gray-500);
}

.demo-head-controls {
  display: flex;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* Läuft die Vorführung, übernimmt die Kopfzeile — der große Abstand über den
   Rahmen gehört zum Standbild-Zustand (SITE-9).

   Der Abstand hängt an `has-demo-js`, nicht am `hidden` der Kopfzeile (SITE-64):
   Sonst stand er erst, wenn `demo.js` die Kopfzeile eingeblendet hat, und der
   ganze Bilderblock rutschte in diesem Moment um zwanzig Pixel nach unten —
   mitten im ersten Bildschirm. Die Klasse setzt `theme.js` synchron im Kopf,
   der Abstand steht also von der ersten Zeichnung an. Wo keine Vorführung
   zustande kommt, nimmt `demo.js` die Klasse im Fehlerzweig wieder weg. */
.has-demo-js .demo-head + .shots,
.demo-head:not([hidden]) + .shots {
  margin-top: var(--space-5);
}

/* Der Zoom-Regler (SITE-29): skaliert die Aufnahme-Gruppe, nie die Leiste. */
.demo-zoom {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--gray-50);
  border: 1px solid var(--gray-200);
  border-radius: var(--radius-full);
  padding: var(--space-1) var(--space-3);
}

.demo-zoom span {
  font-size: var(--text-sm);
  line-height: 1;
  color: var(--gray-500);
}

.demo-zoom input {
  width: 7rem;
  margin: 0;
  accent-color: var(--accent-600);
}

/* Unter der Leiste: die Zeile, in die schmale Fenster Rolle und Zoom stellen
   (SITE-30). Auf breiten Fenstern bleibt sie leer und [hidden]. */
.demo-tools {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3) var(--space-4);
  flex-wrap: wrap;
}

.demo-controls {
  margin-top: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  align-items: center;
}

/* --- die Rolle ---
   Ein Streifen aus Abschnitten, einer je Funktion, der sich nach links schiebt.
   Die Marke steht fest in der Mitte; was gerade läuft, liegt darunter. */

.demo-reel {
  position: relative;
  width: 100%;
  overflow: hidden;
  padding: var(--space-1) 0;
  cursor: grab;
  touch-action: pan-y;
  /* Ränder ausblenden, damit der Streifen nicht abgeschnitten wirkt. */
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.demo-reel.is-dragging {
  cursor: grabbing;
}

/* Beim Ziehen darf kein Titel oder Schritt als Text markiert werden. */
.demo-reel.is-dragging * {
  user-select: none;
}

.demo-reel-track {
  display: flex;
  /* Kein Abstand: die Balken der Abläufe bilden eine durchgehende Zeitleiste,
     keine Reihe einzelner Kacheln. */
  column-gap: 0;
  will-change: transform;
}

.demo-seg {
  --played: 0%;
  position: relative;
  flex: 0 0 auto;
  width: 13rem;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Wo ein Ablauf endet und der nächste beginnt: ein Strich zwischen den
   Titeln, der auf dem Balken aufsetzt statt ihn zu durchschneiden — mit den
   mittigen Titeln liest sich die Zeile als „Titel | Titel | Titel". Er steht
   am Abschnitt statt im Balken, weil dessen `overflow: hidden` alles kappte,
   was über die Balkenhöhe hinausragt. */
.demo-seg::before {
  content: '';
  position: absolute;
  left: -1px;
  top: 0.1rem;
  bottom: var(--space-2);
  width: 2px;
  background: var(--gray-300);
  pointer-events: none;
}

.demo-seg-title {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  width: 100%;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: var(--text-xs);
  color: var(--gray-500);
  cursor: pointer;
  transition: color var(--dur-slow);
}

/* Gekürzt wird nur der Name — das Rollen-Kürzel darunter bleibt ganz. */
.demo-seg-name {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Hervorgehoben wird der Abschnitt unter der Marke — nicht jede Kopie des
   laufenden Ablaufs. Bei wenigen Abläufen stehen mehrere Kopien gleichzeitig
   im Bild, und dann wären zwei Titel fett. */
.demo-seg[data-at='now'] .demo-seg-title {
  color: var(--gray-900);
  font-weight: 600;
}

/* Wessen Ablauf: das Rollen-Kürzel am Titel (SITE-24). Sichtbar nur in
   „Alle" — in einer gefilterten Rolle stünde an jedem Abschnitt dasselbe. */
/* Eigene Zeile, bewusst winzig: eine Randnotiz unterm Titel, kein zweiter
   Titel daneben. */
/* Winzig bleibt es — 9 px in gray-400 waren aber 2,54:1 auf Weiß und damit
   nicht klein, sondern unlesbar (WCAG 1.4.3 verlangt 4,5:1). gray-600 auf Weiß
   sind 7,5:1, und 10 px tragen die Randnotiz immer noch als Randnotiz. */
.demo-seg-role {
  flex: none;
  font-size: var(--text-3xs);
  line-height: 1.1;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--gray-600);
}

.demo-controls:not([data-demo-persona='all']) .demo-seg-role {
  display: none;
}

.demo-seg-track {
  position: relative;
  display: block;
  height: 0.3rem;
  background: var(--gray-200);
  /* Kein `overflow: hidden`: der erste Punkt eines Ablaufs sitzt genau auf der
     Nahtstelle und würde sonst halbiert. */
}

.demo-seg-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--played);
  background: var(--accent);
}

/* Schrittmarken — sichtbar, wie viele Stationen eine Funktion hat, und
   anklickbar, um dorthin zu springen. Der Knopf ist deutlich größer als sein
   Punkt: vier Pixel lassen sich nicht treffen (SITE-21). 24 px sind das Maß,
   unter das WCAG 2.5.8 nicht mehr geht — 1,1 rem waren 17,6 px. Dass sich die
   Flächen dichter Abschnitte dabei an den Rändern überlappen, ist der bessere
   Tausch: In der Mitte trifft jetzt jeder Finger, am Saum landet ein Fehlgriff
   beim Nachbarschritt, und der ist einen Knopfdruck weit weg. */
.demo-seg-tick {
  position: absolute;
  /* `left` setzt demo.js in Prozent; die Verschiebung um die halbe eigene
     Größe rückt die Fläche darauf mittig — ohne dass hier die Hälfte von
     1.5rem als Zahl steht. */
  top: 50%;
  transform: translate(-50%, -50%);
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.demo-seg-tick::before {
  content: '';
  position: absolute;
  /* Mittig in der Tastfläche — `transform` bleibt so für das Aufgehen bei
     Zeiger und aktivem Schritt frei. */
  inset: 0;
  margin: auto;
  width: 0.25rem;
  height: 0.25rem;
  border-radius: var(--radius-full);
  background: #fff;
  /* Der Punkt liegt auf zwei Untergründen: auf dem abgespielten Teil des
     Balkens (Akzent) und auf dem offenen (gray-200). Weiß allein trug nur den
     ersten — auf gray-200 waren es 1,24:1 (WCAG 1.4.11 verlangt 3:1). Der
     dunkle Ring übernimmt dort (4,8:1) und verschwindet auf dem Akzent, wo der
     weiße Punkt selbst 5,2:1 hat. */
  box-shadow: 0 0 0 1px rgb(var(--ink) / 0.55);
  transition: transform var(--dur-fast), opacity var(--dur-fast);
}

.demo-seg-tick:hover::before {
  opacity: 1;
  transform: scale(1.8);
}

.demo-seg-tick[aria-current='true']::before {
  opacity: 1;
  transform: scale(1.6);
}

/* Zurück · Anhalten/Abspielen · Weiter — die dauerhafte Steuerung (SITE-31).
   Sie gehört zur Leiste (in jeder Ansicht dieselbe Stelle), wird aber per
   negativem Abstand nach oben gezogen, bis sie auf der Unterkante der
   Aufnahme reitet — die Knöpfe kosten so keine eigene Zeile, die Leiste
   rückt um denselben Betrag hinauf. In der „Beides"-Ansicht sitzt sie damit
   im Überhang-Raum unterm Browser-Rahmen, neben dem hängenden Handy. */
.demo-transport {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: -2.375rem;
  /* Enger an die Leiste als der Spalten-Abstand der Bedienleiste (1rem). */
  margin-bottom: calc(var(--space-2) * -1);
}

.demo-transport button {
  padding: 0;
  border: 1px solid var(--gray-200);
  border-radius: var(--radius-full);
  background: var(--surface) no-repeat center / 52% 52%;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
}

.demo-transport .t-back,
.demo-transport .t-fwd {
  width: 1.875rem;
  height: 1.875rem;
}

.demo-transport button:hover {
  border-color: var(--accent-600);
}

.demo-transport .t-back {
  background-image: var(--icon-back);
}

.demo-transport .t-fwd {
  background-image: var(--icon-fwd);
}

.demo-transport .t-toggle {
  width: 2.25rem;
  height: 2.25rem;
  border-color: var(--accent-600);
  background-color: var(--accent-600);
  background-image: var(--icon-play);
  background-size: 46% 46%;
}

.demo-transport .t-toggle:hover {
  background-color: var(--accent-700);
}

.demo-controls[data-demo-playing='true'] .t-toggle {
  background-image: var(--icon-pause);
}

/* Die Marke: fest in der Mitte, der Streifen läuft darunter durch. */
.demo-playhead {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  transform: translateX(-50%);
  width: 2px;
  border-radius: var(--radius-full);
  background: var(--gray-900);
  pointer-events: none;
}

/* An der Zeitleiste sitzt kein Knopf — Anhalten und Weiterlaufen gehören auf
   die Aufnahme (.demo-toggle weiter unten). */

/* Zwei Filter nebeneinander: aus wessen Sicht, und auf welchem Gerät. */

.demo-views {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
}

.demo-views button {
  border: 1px solid var(--gray-200);
  background: var(--surface);
  color: var(--gray-500);
  border-radius: var(--radius-full);
  padding: var(--space-1) var(--space-3);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
}

.demo-views button:hover {
  border-color: var(--gray-300);
}

.demo-views button[aria-pressed='true'] {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* --- Anhalten auf der Aufnahme ---
   Das Symbol richtet sich nach dem Zustand — und der Zustand entscheidet auch,
   ob es dasteht: Eine angehaltene Aufnahme trägt das Play-Symbol dauerhaft in
   der Mitte (auf jedem sichtbaren Rahmen, in der „Beides"-Ansicht also auf
   beiden), weil ein Standbild ohne Knopf wie ein Bild aussieht und nicht wie
   eine Vorführung, die auf einen Druck wartet. Erst das laufende Abspielen
   räumt es weg und holt es beim Überfahren zurück. */

/* Die ganze Aufnahme ist der Schalter — nicht nur das Symbol darauf. Wer eine
   laufende Vorführung anhalten will, klickt auf das, was er ansieht. */
.demo-toggle {
  position: absolute;
  z-index: 4;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.demo-toggle::before {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-full);
  background: rgb(var(--ink) / 0.55) no-repeat center / 40% 40%;
  backdrop-filter: blur(2px);
  /* Angehalten ist der Grundfall — auch bevor `index.json` da ist und der
     Rahmen noch gar kein `data-demo-playing` trägt. */
  background-image: var(--icon-play);
  opacity: 1;
  transition: opacity var(--dur-base);
}

/* Läuft die Vorführung, weicht das Symbol dem, was zu sehen ist — und kommt
   beim Überfahren als Anhalten-Knopf zurück. */
[data-demo-playing='true'] .demo-toggle::before {
  background-image: var(--icon-pause);
  opacity: 0;
}

[data-demo-playing='true'] .demo-screen:hover .demo-toggle::before,
[data-demo-playing='true'] .demo-toggle:focus-visible::before {
  opacity: 1;
}

/* Der Knopf liegt als unsichtbare Fläche über der ganzen Aufnahme (inset: 0),
   und der Rahmen darüber schneidet ab (overflow: hidden) — der übliche
   Fokusrahmen läge damit vollständig hinter der Kante. Im Halt half auch die
   Regel darüber nicht: Dort steht das Symbol ohnehin schon voll da, ein
   Fokuswechsel änderte also gar nichts, und wer sich mit der Tastatur zum
   wichtigsten Knopf der Vorführung bewegte, bekam keinerlei Rückmeldung
   (WCAG 2.4.7). Der Ring sitzt deshalb am Symbolkreis statt am Rahmen — und
   zweifarbig, weil darunter ein beliebiges Standbild liegt: Der helle Ring
   trägt auf dunklem Grund, der dunkle auf hellem. */
.demo-toggle:focus-visible {
  outline: none;
}

.demo-toggle:focus-visible::before {
  opacity: 1;
  box-shadow:
    0 0 0 2px #fff,
    0 0 0 4px rgb(var(--ink) / 0.85);
}

/* Ohne Mauszeiger gibt es kein Überfahren — dort steht das Anhalten-Symbol
   während des Abspielens dezent an. Das Play-Symbol der angehaltenen Aufnahme
   steht auch hier voll da. */
@media (hover: none) {
  .demo-toggle::before {
    width: 2.5rem;
    height: 2.5rem;
  }

  [data-demo-playing='true'] .demo-toggle::before {
    opacity: 0.55;
  }
}

/* Schritt für Schritt auf der Aufnahme (SITE-31): die Chevrons links und
   rechts neben dem Play-Knopf — kleiner als er und mit Strich statt gefüllter
   Fläche, damit sie nicht wie ein zweites Play aussehen. Sie sitzen in der
   Mitte, nicht am Rahmenrand, wo in der „Beides"-Ansicht das Handy über dem
   Browser liegt — und erscheinen wie das Play-Symbol erst beim Überfahren;
   die dauerhafte Steuerung ist die an der Leiste. */
.demo-step {
  position: absolute;
  z-index: 5;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 1.9rem;
  height: 1.9rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: rgb(var(--ink) / 0.55) no-repeat center / 55% 55%;
  backdrop-filter: blur(2px);
  cursor: pointer;
  /* SITE-79: unsichtbar über die Deckkraft, nicht über `visibility`. Ein
     Element mit `visibility: hidden` ist gar nicht fokussierbar — die
     Fokus-Regel weiter unten war damit toter Code, und die Tabulatortaste
     sprang von „Browser-Demo anhalten" direkt zur Handy-Demo (2.1.1). Dass der
     Mauszeiger nicht ins Leere klickt, besorgt jetzt `pointer-events`. */
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base);
}

/* Beide Chevrons stehen 2.8rem von der Mitte weg — links und rechts vom
   3-rem-Knopf, mit einer Handbreit Luft dazwischen. */
.demo-step-back {
  margin-left: -2.8rem;
  background-image: var(--icon-back-light);
}

.demo-step-fwd {
  margin-left: 2.8rem;
  background-image: var(--icon-fwd-light);
}

.demo-screen:hover .demo-step,
.demo-step:focus-visible {
  opacity: 1;
  pointer-events: auto;
}

.demo-step:hover {
  background-color: rgb(var(--ink) / 0.75);
}

/* Ohne Mauszeiger stehen sie dezent an — wie das Play-Symbol. */
@media (hover: none) {
  .demo-step {
    opacity: 0.55;
    pointer-events: auto;
  }
}

@media (max-width: 30rem) {
  .demo-seg {
    width: 10rem;
  }
}

/* Eine Ansicht ausblenden — das Layout fällt dann auf die einspaltige Form
   zurück, damit der Browser-Rahmen die frei gewordene Breite bekommt. */
[data-demo-view='desktop'] .shot-phone,
[data-demo-view='phone'] .shot-browser {
  display: none;
}

/* Der Zoom (SITE-29): `--demo-zoom` ist eine einheitenlose Prozentzahl, die
   demo.js am Wurzelelement setzt. Daraus wird hier ein Faktor — und die vier
   Maße der Attrappe hängen alle an ihm. Ohne das sähe eine klein gezoomte
   Aufnahme aus wie ein Bilderrahmen: 0,6 rem Blende und 2,2 rem Rundung um ein
   halb so großes Gerät sind kein Handy mehr.
   Der Bezugswert unterscheidet sich nach Breite (unten der sichtbare Rahmen,
   über der Stapelgrenze die ganze Gruppe), der Rest der Rechnung nicht — er
   steht deshalb genau einmal. Und nur am laufenden Player
   ([data-demo-feature]): ohne Skript bleibt alles, wie es war. */
.shots[data-demo-feature] {
  --zoom: calc(var(--demo-zoom, 62) / 65);
  --bezel: calc(var(--phone-bezel) * var(--zoom));
}

.shots[data-demo-feature] .shot-phone {
  border-radius: calc(var(--phone-radius) * var(--zoom));
}

/* Auch der Bildschirm-Stapel: er beschneidet Titelkarte und Auflagen — mit
   fixem Radius stünde seine Rundung bei kleinem Zoom von der Blende ab. */
.shots[data-demo-feature] .shot-phone img,
.shots[data-demo-feature] .shot-phone .demo-screen {
  border-radius: calc(var(--phone-screen-radius) * var(--zoom));
}

.shots[data-demo-feature] .shot-phone .key {
  width: calc(var(--phone-key) * var(--zoom));
}

@media (min-width: 56rem) {
  [data-demo-view='desktop'].shots,
  [data-demo-view='phone'].shots {
    padding-right: 0;
  }

  /* `relative`, nicht `static`: die Seitentasten hängen als absolute Elemente
     am Rahmen. Ohne positionierten Vorfahren wandern sie an den Rand der
     Seite und stehen als vier Striche neben dem Handy. */
  [data-demo-view='phone'] .shot-phone {
    position: relative;
    right: auto;
    bottom: auto;
    margin: 0 auto;
    width: 17rem;
  }

  /* Über der Stapelgrenze bezieht sich der Zoom nicht auf die Textspalte,
     sondern auf das Fenster (SITE-77). Vorher war die Bezugsgröße die 68 rem
     breite `.wrap` — auf einem 30-Zoll-Schirm schmaler als die Aufnahme selbst:
     100 % zeigte einen 1440 px breiten Desktop-Mitschnitt auf gut 1000 px, also
     kleiner als aufgenommen, mit dem halben Fenster daneben leer.

     Die Bezugsgröße ist die **Fensterbreite**, schlicht `100vw`: 100 % heißt
     randlos, und der Regler geht bis 110 % — zehn Prozent über das Fenster
     hinaus, die die Hero-Sektion abschneidet (`overflow: hidden`). Das ist
     Absicht: Wer die Tabelle im Rahmen lesen will, darf über den Rand hinaus
     vergrößern, wie man in ein Bild hineinzoomt.

     Eine Höhenschranke stand hier zuerst mit — sie war der Grund, warum auf
     einem breiten Fenster nie etwas Sichtbares passierte: bei gewöhnlichem
     Seitenverhältnis griff sie lange vor der Breite und hielt die Gruppe auf
     der alten Größe fest. Die Höhe begrenzt jetzt nichts mehr; zu hoch heißt
     scrollen, und die Vorführung steht ohnehin im Fluss der Seite.

     Die Maße stehen hier, das Wachsen tut nur die Gruppe: `.hero-demo` behält
     seine Breite aus der Textspalte, damit Kopfzeile und Leiste vom Regler
     unberührt bleiben (SITE-29). Vergrößert wird die Aufnahme, nicht ihre
     Bedienung. */
  .hero-demo:has(> .shots[data-demo-feature]) {
    --demo-avail: 100vw;
    --demo-span: calc(var(--demo-avail) * var(--demo-zoom, 100) / 100);
  }

  .shots[data-demo-feature] {
    /* Der Faktor für die rem-Maße der Attrappe folgt jetzt der Breite, die die
       Gruppe wirklich bekommt, nicht mehr der Reglerzahl: 65 rem ist die Breite,
       für die Blende, Rundung, Handy und Überlapp gewählt wurden. Bei der alten
       Bezugsgröße war beides dasselbe — bei der neuen wäre das Handy sonst ein
       Streichholz neben einem Kinoschirm. */
    --zoom: calc(var(--demo-span) / 65rem);
    width: var(--demo-span);
    /* Zentriert, und zwar auch dann, wenn die Gruppe breiter ist als die
       Spalte, in der sie steht: `auto` würde in dem Fall zu 0 und schöbe alles
       nach rechts. Beide Prozentwerte messen dieselbe Bezugsbreite, der Ausbruch
       ist also links und rechts gleich groß. */
    margin-inline: calc((100% - var(--demo-span)) / 2);
    padding-right: calc(12rem * var(--zoom));
    /* Der Handy-Überhang gehört in die Gruppe: als Innenabstand statt als
       negativer Versatz ragt er nie in die Leiste darunter. */
    padding-bottom: var(--space-8);
  }

  .shots[data-demo-feature] .shot-phone {
    bottom: 0;
    width: calc(15rem * var(--zoom));
  }

  [data-demo-view='phone'].shots[data-demo-feature] .shot-phone {
    width: calc(17rem * var(--zoom));
  }

  /* Ohne zweiten Rahmen gibt es nichts zu überlappen — wie oben, nur gegen die
     skalierte Polsterung durchgesetzt. */
  [data-demo-view='desktop'].shots[data-demo-feature],
  [data-demo-view='phone'].shots[data-demo-feature] {
    padding-right: 0;
    padding-bottom: 0;
  }
}

/* Unter der Stapelgrenze skaliert der Zoom den jeweils sichtbaren Rahmen —
   der Faktor dafür steht oben. */
@media (max-width: 55.9375rem) {
  .shots[data-demo-feature] .shot-phone {
    width: min(24rem, calc(var(--demo-zoom, 62) * 1%));
  }

  .shots[data-demo-feature] .shot-browser {
    width: calc(var(--demo-zoom, 100) * 1%);
    margin-inline: auto;
  }

  /* „Beides" gibt es hier nicht — zwei gestapelte Rahmen sprengen die
     Bildschirmhöhe, die Ansicht wählt genau einen (SITE-30). */
  .demo-views [data-view='both'] {
    display: none;
  }
}

/* Kein `prefers-reduced-motion`-Ausstieg: Die Vorführung bleibt überall
   dieselbe — bei reduzierter Bewegung startet sie nur angehalten auf dem
   ersten Bild, statt zu verschwinden (SITE-20, gesetzt in `demo.js`). Losgehen
   und Anhalten geht über die Knöpfe an der Leiste und auf der Aufnahme. */

/* --- Preis --- */

.center {
  text-align: center;
}

.center .lead,
.center .narrow {
  margin-inline: auto;
}

/* Der Konversionsblock bekommt eine eigene Fläche. Vorher standen Datenschutz
   und Preis beide auf Weiß — die Alternation der Sektionen brach ausgerechnet
   am Preis, und er sah aus wie das untere Ende des Abschnitts darüber. */
#preis {
  background: linear-gradient(var(--canvas), var(--brass-50));
  border-top: 1px solid var(--brass-200);
}

#preis h2 {
  font-size: clamp(1.75rem, 1.3rem + 2vw, 2.5rem);
  color: var(--accent-700);
}

.price-note {
  margin: var(--space-4) 0 0;
  font-size: var(--text-sm);
  color: var(--gray-500);
}

/* --- Herkunft (SITE-41) ---
   Ersetzt das frühere Zahlenband: dieselben drei Tatsachen, aber als
   Geschichte statt als drei Kacheln. Der Violinschlüssel des Logos liegt groß
   und angeschnitten dahinter — die Marke kam bisher genau einmal in 30 px vor.
   Die warme Fläche trennt die Sektion vom Hero darüber, ohne eine weitere
   graue Bahn zu sein. */

.origin {
  position: relative;
  overflow: hidden;
  background: linear-gradient(var(--canvas), var(--brass-50));
  border-bottom: 1px solid var(--gray-200);
}

.origin-clef {
  position: absolute;
  top: 50%;
  right: clamp(-7rem, -4vw, -2rem);
  height: 160%;
  transform: translateY(-46%) rotate(6deg);
  color: var(--brass-600);
  opacity: 0.1;
  pointer-events: none;
}

.origin-clef svg {
  height: 100%;
  width: auto;
  max-width: none;
}

.origin-copy {
  position: relative;
  max-width: 40rem;
}

.origin-copy p {
  color: var(--gray-600);
  font-size: var(--text-lg);
}

.origin-copy strong {
  color: var(--gray-900);
}

.origin-who {
  margin-top: var(--space-9);
}

.origin-who p {
  font-size: var(--text-md);
}

/* Die Pointe schließt die Zeitleiste ab und trägt deshalb mehr Gewicht als die
   Zeile über den Betreiber darunter. Als Überschrift funktionierte derselbe
   Gedanke nicht: „nie beworben" eröffnet mit einer Abwesenheit — am Ende der
   Zeitleiste ist es ein Beleg. */
.origin-who .origin-pointe {
  font-size: var(--text-xl);
  line-height: 1.55;
  color: var(--gray-800);
  border-left: 3px solid var(--brass-700);
  padding-left: var(--space-4);
  margin-bottom: var(--space-6);
}

/* Die Zeitleiste: eine Messing-Linie mit vier Stationen, auf schmalen Fenstern
   senkrecht, ab 56rem waagrecht. */

.timeline {
  /* Vier Maße, die voneinander abhängen: Der Punkt sitzt mittig auf der Linie,
     und die Linie reicht genau bis zur nächsten Station — also so weit, wie
     die Lücke des Rasters breit ist. Als Zahlen nebeneinander stimmten sie nur
     zufällig; hier rechnen sie auseinander hervor. */
  --tl-gap: var(--space-6);
  --tl-dot: 0.75rem;
  --tl-line: 2px;
  --tl-top: var(--space-1); /* Höhe der Station neben der Jahreszahl */
  position: relative;
  list-style: none;
  margin: var(--space-9) 0 0;
  padding: 0;
  display: grid;
  gap: var(--tl-gap);
}

.timeline li {
  position: relative;
  padding-left: var(--space-8);
}

/* Linie … */
.timeline li::before {
  content: "";
  position: absolute;
  left: var(--space-2);
  top: var(--tl-top);
  bottom: calc(var(--tl-gap) * -1);
  width: var(--tl-line);
  background: var(--brass-200);
}

.timeline li:last-child::before {
  display: none;
}

/* … und Station. */
.timeline li::after {
  content: "";
  position: absolute;
  left: var(--space-2);
  top: var(--tl-top);
  width: var(--tl-dot);
  height: var(--tl-dot);
  margin-left: calc(var(--tl-line) / 2 - var(--tl-dot) / 2);
  border-radius: var(--radius-full);
  background: var(--brass-600);
  box-shadow: 0 0 0 3px var(--brass-100);
}

.tl-year {
  display: block;
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: var(--brass-800);
}

.timeline p {
  margin: var(--space-1) 0 0;
  font-size: var(--text-md);
  color: var(--gray-600);
  max-width: 34rem;
}

/* Ab 56rem waagrecht: Der Verlauf wird zur Bewegung von links nach rechts statt
   zu einer Liste. Bedingung dafür ist die Textlänge — in ~15rem Spaltenbreite
   trägt eine Station höchstens zwei bis drei Zeilen. */
@media (min-width: 56rem) {
  .timeline {
    --tl-gap: var(--space-8);
    grid-template-columns: repeat(4, 1fr);
    gap: var(--tl-gap);
    max-width: 62rem;
  }

  .timeline li {
    padding-left: 0;
    padding-top: var(--space-5);
  }

  .timeline li::before {
    left: var(--tl-top);
    right: calc(var(--tl-gap) * -1);
    top: var(--tl-top);
    bottom: auto;
    width: auto;
    height: var(--tl-line);
  }

  /* Auch die letzte Station bekommt ihr Stück Linie — sonst bricht die Reihe
     optisch beim dritten Punkt ab. Sie endet am Spaltenrand, nicht im Nichts. */
  .timeline li:last-child::before {
    display: block;
    right: 0;
  }

  .timeline li::after {
    left: var(--tl-top);
    top: var(--tl-top);
    margin-left: 0;
    margin-top: calc(var(--tl-line) / 2 - var(--tl-dot) / 2);
  }

  .timeline p {
    font-size: var(--text-sm);
  }
}

/* --- Verweis von der Funktionskachel in die Vorführung (SITE-42) ---
   Bedienung, also Blau — und bewusst leiser als ein Knopf. Kein Abspiel-Symbol:
   Ein Kreis mit Dreieck sähe aus wie ein Videoknopf und machte aus der
   Kachel-Fußzeile einen zweiten Aufruf zur Handlung. */

.tour-link {
  display: inline-block;
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--accent-700);
  text-decoration: none;
}

.tour-link::after {
  content: " ›";
}

.tour-link:hover {
  text-decoration: underline;
}

/* --- Ablauf --- */

.steps {
  counter-reset: step;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

.steps li {
  counter-increment: step;
  position: relative;
  padding-top: var(--space-12);
}

.steps li::before {
  content: counter(step);
  position: absolute;
  top: 0;
  left: 0;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-full);
  background: var(--accent-600);
  color: #fff;
  font-weight: 700;
  font-size: var(--text-base);
}

.steps p {
  margin: 0;
  color: var(--gray-600);
  font-size: var(--text-md);
}

/* --- Zusicherungen --- */

.checks {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-2);
}

.checks li {
  font-size: var(--text-md);
  display: grid;
  grid-template-columns: 1.4rem 1fr;
  gap: var(--space-2);
  align-items: start;
  color: var(--gray-600);
}

/* Ein hohler Ring liest sich als NICHT ausgewählter Radioknopf — an einer
   Stelle, an der jede Zeile eine Zusicherung ist, sagt er das Gegenteil. */
.checks li::before {
  content: "";
  margin-top: var(--space-1);
  width: 1.05rem;
  height: 1.05rem;
  background: no-repeat center / contain
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="11" fill="%230972b4"/><path d="M7 12.5l3.2 3.2L17 9" fill="none" stroke="white" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg>');
}

/* Nachsatz unter einer Zusicherungsliste (SITE-45): zeigt auf das Dokument,
   das die Zusicherungen darüber verbindlich macht. Kein Häkchen davor — es ist
   keine weitere Zusage, sondern der Weg zu ihrer Quelle. */
.checks-note {
  margin: var(--space-5) 0 0;
  font-size: var(--text-md);
  color: var(--gray-600);
}

/* --- Fragen --- */

.faq details {
  border-bottom: 1px solid var(--gray-200);
  padding: var(--space-4) 0;
}

.faq summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--gray-900);
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: "+";
  color: var(--accent-600);
  font-weight: 700;
  flex: none;
}

.faq details[open] summary::after {
  content: "–";
}

.faq details p {
  margin: var(--space-3) 0 0;
  color: var(--gray-600);
  font-size: var(--text-md);
}

/* --- Kontaktband --- */

.contact {
  background: linear-gradient(160deg, var(--contact-from), var(--contact-to));
  color: #fff;
}

.contact h2 {
  color: #fff;
}

.contact p {
  color: var(--on-contact);
}

.contact .btn-primary {
  background: #fff;
  color: var(--on-contact-btn);
}

.contact .btn-primary:hover {
  background: var(--on-contact-btn-hover);
}

.contact a:not(.btn) {
  color: #fff;
}

/* SITE-38: Aus der Textzeile ist ein eigener Block geworden. Die Linie setzt
   ihn vom Formular ab, damit der zweite Weg sichtbar ist, ohne mit dem
   Absendeknopf um dieselbe Handlung zu streiten — deshalb auch der Umriss-
   knopf statt eines zweiten weißen. */
.contact-alt {
  margin-top: var(--space-7);
  padding-top: var(--space-6);
  border-top: 1px solid rgb(255 255 255 / 0.25);
  display: grid;
  gap: var(--space-3);
  justify-items: center;
  text-align: center;
  font-size: var(--text-sm);
}

.contact-alt h3 {
  margin: 0;
  color: #fff;
  font-size: var(--text-lg);
}

.contact-alt p {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--on-contact);
}

/* Weiß zu 70 % gegen den Verlauf: 4,4:1 bis 8:1 — ein Knopfrand ist ein
   Bedienelement und braucht 3:1 (1.4.11), wie die Feldränder darüber. */
.contact-alt .btn-mail {
  width: 100%;
  min-height: 44px;
  background: transparent;
  color: #fff;
  border-color: rgb(255 255 255 / 0.7);
}

.contact-alt .btn-mail:hover {
  background: rgb(255 255 255 / 0.12);
}

/* SITE-46: Der globale Ring ist accent-600 (#0972b4) — auf dem Kontaktband liegt
   damit Blau auf Blau: 2,22:1 gegen accent-900, 1,35:1 gegen accent-700, WCAG
   1.4.11 verlangt 3:1. Ausgerechnet an der einzigen Handlung der Seite wüsste die
   Tastatur nicht mehr, wo sie steht. Weiß trägt auf dem ganzen Verlauf. */
.contact :focus-visible {
  outline-color: #fff;
}

/* --- Kontaktformular (SITE-37) --- */

.contact-form {
  margin-top: var(--space-7);
  display: grid;
  gap: var(--space-4);
  text-align: left;
}

.contact-form .field {
  display: grid;
  gap: var(--space-1);
}

/* Nach dem Absenden blendet form.js Felder und Knopf per hidden-Attribut aus —
   das UA-Stylesheet verliert gegen die display-Regeln oben, deshalb explizit. */
.contact-form [hidden] {
  display: none !important;
}

.contact-form label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--on-contact);
}

.contact-form input {
  width: 100%;
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-lg);
  /* Weiß zu 35 % war auf dem helleren Ende des Verlaufs (contact-to) 2,33:1
     im Dunkeln und 2,18:1 im Hellen — ein Feldrand ist ein Bedienelement und
     braucht 3:1 (1.4.11). Nicht der Dunkelmodus hat das gebrochen, er hat es
     nur sichtbar gemacht; deshalb steht die Korrektur für beide Moden hier.
     55 % blieben am hellen Ende bei 3,28:1 hängen, 60 % trägt überall: 3,82:1
     bis 6,81:1 gegen den Verlauf, 3,19:1 gegen die eigene Füllung. */
  border: 1px solid rgb(255 255 255 / 0.6);
  background: rgb(255 255 255 / 0.08);
  color: #fff;
  font: inherit;
}

.contact-form input::placeholder {
  color: var(--on-contact);
}

/* Die Ringfarbe kommt jetzt für den ganzen Abschnitt aus der Regel oben (SITE-46). */
.contact-form input:focus-visible {
  background: rgb(255 255 255 / 0.14);
}

.contact-form .form-status {
  margin: 0;
  font-size: var(--text-md);
  color: #fff;
  font-weight: 600;
}

/* Nach dem Absenden bekommt sie den Fokus (SITE-47) und damit einen Ring — die
   globale Regel deckt nur a/button/summary/input ab, ein <p> nicht. */
.contact-form .form-status:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.contact-form .form-status[data-tone='error'] {
  color: var(--error-ink);
}

.contact-form .form-note {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--on-contact);
}

/* --- Fußzeile --- */

.site-footer {
  background: var(--footer-bg);
  color: var(--footer-fg);
  font-size: var(--text-sm);
  padding-block: var(--space-10);
}

.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  align-items: center;
}

.site-footer a {
  color: var(--footer-link);
  text-decoration: none;
}

.site-footer a:hover {
  text-decoration: underline;
}

/* --- SITE-51: Darstellungsschalter ---
   Steht im Fuß, hinter den Rechtslinks. Er muss nicht oben stehen: Wer nachts
   ankommt, bekommt die dunkle Seite ohnehin von selbst (Auto folgt dem Gerät)
   — der Schalter ist die Ausnahme davon und nicht der Regelfall, und eine
   Ausnahme gehört nicht in die Kopfzeile neben den einen Knopf, auf den die
   Seite hinarbeitet.
   Der Fuß ist in beiden Moden ein dunkles Band, also nimmt der Schalter dort
   seine Farben aus dem Band und nicht aus der Rampe. Gebaut wird er von
   theme.js — ohne Skript gäbe es nichts zu speichern und der Schalter wäre
   eine tote Schaltfläche.
   Kein eigenes `margin-left: auto`: Das hat die Rechtsnavigation davor schon,
   und zwei davon teilen den freien Platz, statt beide nach rechts zu schieben. */
.site-footer .theme-switch {
  display: flex;
  gap: var(--space-1);
  padding: var(--space-1);
  border: 1px solid rgb(255 255 255 / 0.18);
  border-radius: var(--radius-full);
  background: rgb(255 255 255 / 0.06);
}

.site-footer .theme-switch button {
  display: grid;
  place-items: center;
  width: 1.85rem;
  height: 1.85rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: none;
  color: var(--footer-fg);
  cursor: pointer;
}

.site-footer .theme-switch button:hover {
  color: var(--footer-link);
}

.site-footer .theme-switch button[aria-pressed='true'] {
  background: rgb(255 255 255 / 0.16);
  color: #fff;
}

.site-footer .theme-switch svg {
  width: 1rem;
  height: 1rem;
}

/* Für Namen, die nur die Vorlesehilfe braucht. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.site-footer nav {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
}

/* --- Rechtsseiten --- */

.legal {
  padding-block: clamp(2.5rem, 6vw, 4rem);
}

.legal h1 {
  font-size: clamp(1.625rem, 1.35rem + 1.2vw, 2.125rem);
}

.legal h2 {
  font-size: var(--text-lg);
  margin-top: var(--space-9);
}

.legal dl {
  margin: 0 0 var(--space-6);
}

.legal dt {
  font-weight: 600;
  color: var(--gray-900);
  margin-top: var(--space-3);
}

.legal dd {
  margin: 0;
  color: var(--gray-600);
}

.legal .todo {
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  color: var(--warn-ink);
  font-size: var(--text-sm);
}

/* ==========================================================================
   Kontrastmodus des Betriebssystems (SITE-63, WCAG 1.4.11)
   ==========================================================================
   Anders als oft angenommen entfernt der Browser hier keine Hintergrundbilder
   aus `url()` — er forciert die Hintergrund*farbe* darunter. Die weißen
   Glyphen der Vorführung standen damit weiß auf weiß: Der Play-Knopf war ein
   leerer Kreis, während die Chevrons daneben stehen blieben. Als Maske nimmt
   ein Symbol die Systemfarbe an und folgt dem Thema, das der Mensch gewählt
   hat — statt einer festen Farbe in einem Modus, dessen ganzer Zweck es ist,
   Farben zu ersetzen. Mauszeiger und Häkchen bleiben unangetastet: Sie sind
   dekorativ und behalten ihre Farben ohnehin. */
@media (forced-colors: active) {
  /* Die dauerhafte Steuerung an der Leiste. Die zweite Zeile ist kein
     Überfluss: Die Zustandsregel des Abspielens ist spezifischer als die erste
     und behielte ihr Bild sonst — Symbol und Maske lägen übereinander. */
  .demo-transport button,
  .demo-controls[data-demo-playing='true'] .demo-transport button {
    position: relative;
    background-image: none;
  }

  .demo-transport button::before {
    content: '';
    position: absolute;
    inset: 24%;
    background-color: ButtonText;
    -webkit-mask: var(--icon) no-repeat center / contain;
    mask: var(--icon) no-repeat center / contain;
  }

  .demo-transport .t-back {
    --icon: var(--icon-back);
  }

  .demo-transport .t-fwd {
    --icon: var(--icon-fwd);
  }

  .demo-transport .t-toggle {
    --icon: var(--icon-play);
  }

  .demo-controls[data-demo-playing='true'] .t-toggle {
    --icon: var(--icon-pause);
  }

  /* Auf der Aufnahme bleibt der Kreis ein Kreis, das Symbol zieht auf ::after
     um — ein Pseudoelement kann nicht Fläche und Maske zugleich sein. */
  .demo-toggle::before {
    background-image: none;
    background-color: Canvas;
    border: 1px solid CanvasText;
    backdrop-filter: none;
  }

  .demo-toggle::after {
    content: '';
    position: absolute;
    inset: 0;
    margin: auto;
    width: 1.2rem;
    height: 1.2rem;
    background-color: CanvasText;
    -webkit-mask: var(--icon-play) no-repeat center / contain;
    mask: var(--icon-play) no-repeat center / contain;
    opacity: inherit;
  }

  [data-demo-playing='true'] .demo-toggle::after {
    -webkit-mask-image: var(--icon-pause);
    mask-image: var(--icon-pause);
  }

  .demo-step {
    background-image: none;
    background-color: Canvas;
    border: 1px solid CanvasText;
    backdrop-filter: none;
  }

  .demo-step::before {
    content: '';
    position: absolute;
    inset: 26%;
    background-color: CanvasText;
    -webkit-mask: var(--icon) no-repeat center / contain;
    mask: var(--icon) no-repeat center / contain;
  }

  .demo-step-back {
    --icon: var(--icon-back-light);
  }

  .demo-step-fwd {
    --icon: var(--icon-fwd-light);
  }

  /* Gedrückt heißt gedrückt, auch ohne eigene Farben. */
  .demo-views button[aria-pressed='true'],
  .site-footer .theme-switch button[aria-pressed='true'] {
    background-color: Highlight;
    border-color: Highlight;
    color: HighlightText;
  }
}

/* ==========================================================================
   Druck (SITE-62)
   ==========================================================================
   Die Seite wird gedruckt, und zwar von genau der Person, die entscheidet: Eine
   Leitung legt den Ausdruck der Trägersitzung vor, eine Gemeinde heftet AGB und
   Auftragsverarbeitungsvertrag ab. Ohne diese Regeln stellt der Ausdruck elf
   Fragen und beantwortet keine — und wer sein Betriebssystem dunkel gestellt
   hat, druckt einen blassgrauen Zettel. */
@media print {
  /* 1 — Dunkelmodus zurücknehmen. `theme.js` löst „auto" immer auf und schreibt
     `data-theme` hart ins <html>; es gibt also keine Medienabfrage, an der der
     Druck vorbeikäme. Ungefixt druckt die Überschrift in #a5a6a8: 2,44:1 auf
     Weiß, AA verfehlt — auf der Startseite wie im Vertrag. */
  :root,
  :root[data-theme='dark'] {
    color-scheme: light !important;

    --canvas: #fff;
    --surface: #fff;
    --surface-translucent: #fff;

    --gray-50: #f9fafb;
    --gray-100: #f3f4f6;
    --gray-200: #e5e7eb;
    --gray-300: #d1d5db;
    --gray-400: #9ca3af;
    --gray-500: #6b7280;
    --gray-600: #4b5563;
    --gray-700: #374151;
    --gray-800: #1f2937;
    --gray-900: #111827;

    --accent-50: #f1f9fe;
    --accent-100: #d2edfe;
    --accent-200: #b1dffc;
    --accent-300: #80caf8;
    --accent-500: #1194e7;
    --accent-600: #0972b4;
    --accent-700: #0a5d91;
    --accent-900: #113d59;

    --brass-50: #fffbeb;
    --brass-100: #fdf3d8;
    --brass-200: #f3e3c2;
    --brass-600: #d97706;
    --brass-700: #b45309;
    --brass-800: #92400e;

    --footer-bg: #fff;
    --footer-fg: #374151;
    --footer-link: #111827;
  }

  /* 2 — Grundfläche und Grundschrift. Punkt statt rem: Papier hat eine
     physische Größe. Weiß erzwingen, damit ein gesetzter Haken bei
     „Hintergründe drucken" keine dunkle Fläche über das Blatt legt. */
  html,
  body {
    background: #fff !important;
    color: #1f2937 !important;
    font-size: 11pt;
    line-height: 1.45;
  }

  /* 3 — Was auf Papier nicht existiert: Bedienung, Navigation, Ornament. Die
     Tour-Steuerung restlos — ein Zoomregler auf Papier ist eine Lüge über das
     Medium, und die Schrittmarken drucken als zerschnittene Wortfragmente, die
     wie ein Druckfehler aussehen. `.demo-clip` ist meist ohnehin verborgen,
     bei laufender Tour aber nicht: deshalb ausdrücklich. */
  .site-header,
  .nav-toggle,
  .site-nav,
  .skip-link,
  .theme-switch,
  .demo-head,
  .demo-controls,
  .demo-transport,
  .demo-reel,
  .demo-reel-track,
  .demo-playhead,
  .demo-seg-tick,
  .demo-tools,
  .demo-zoom,
  .demo-toggle,
  .demo-step,
  .demo-cursor,
  .demo-clip,
  .demo-band,
  .demo-live,
  .tour-link,
  .contact-form,
  .contact-alt .btn,
  .site-footer nav,
  .hero .cta-row,
  /* SITE-74: dieselbe Kachel, zwei Kennungen — die englische Seite nennt den
     Abschnitt `#price`. */
  #preis .btn,
  #price .btn,
  .origin-clef {
    display: none !important;
  }

  /* Ein Standbild genügt. Der Handy-Rahmen ist mit seinen gezeichneten
     Gehäusetasten das bildschirmigste Element der Seite und zeigt dasselbe
     wie der Browser-Rahmen daneben. */
  .shot-phone {
    display: none !important;
  }

  /* 4 — Die FAQ aufklappen. Der entscheidende Block, und der naheliegende Weg
     führt daran vorbei: `details > * { display: block }` wirkt nicht, weil der
     geschlossene Zustand an `content-visibility` des UA-Slots hängt, nicht am
     `display` der Kinder. Ohne diese Regel druckt die Seite elf Fragen und
     keine Antwort. Das „+" ist eine Aufklapp-Geste, keine Information. */
  details::details-content {
    content-visibility: visible !important;
  }

  details > summary {
    list-style: none;
    font-weight: 600;
  }

  details > summary::marker,
  details > summary::-webkit-details-marker {
    content: '';
    display: none;
  }

  /* 5 — Seitenumbrüche. Eine Kachel, ein FAQ-Eintrag, ein Jahr der Zeitleiste
     sind Sinneinheiten; mitten durchgeschnitten kosten sie den Faden. */
  details,
  .card,
  .steps li,
  .timeline li,
  .origin-copy,
  .contact-alt,
  .price-note {
    break-inside: avoid;
  }

  h1,
  h2,
  h3 {
    break-after: avoid;
  }

  /* 6 — Tinte. Schatten und Verläufe sind Bildschirmtiefe und werden auf
     Papier zu grauem Nebel. Die farbigen Flächen bleiben: Sie gliedern das
     Dokument, und Browser drucken Hintergründe ohnehin nur auf Wunsch. */
  * {
    box-shadow: none !important;
    text-shadow: none !important;
  }

  .hero,
  .contact,
  .site-footer {
    background-image: none !important;
  }

  /* 7 — Bilder */
  img {
    max-width: 100% !important;
    height: auto;
    break-inside: avoid;
  }

  /* 8 — Verweise ausschreiben. Auf Papier ist ein Link ohne Ziel eine
     Sackgasse; im Auftragsverarbeitungsvertrag zeigt „siehe AGB" sonst ins
     Leere. Nicht in Navigationslisten, dort stört die URL mehr als sie nützt. */
  a[href^='http']::after,
  a[href^='mailto:']::after {
    content: ' (' attr(href) ')';
    font-size: 9pt;
    font-weight: 400;
    word-break: break-all;
  }

  nav a::after,
  .btn::after {
    content: '' !important;
  }

  /* 9 — Rechtsseiten. Genau diese vier werden abgeheftet. Der Stand steht
     bereits im Fließtext; was fehlt, ist die Herkunft — ein abgehefteter
     Vertrag ohne Quelle ist im Streitfall schwer zuzuordnen. */
  .legal {
    font-size: 10.5pt;
  }

  .legal h1::after {
    display: block;
    margin-top: 0.35rem;
    content: 'evman.flof.codes';
    font-size: 9pt;
    font-weight: 400;
    color: #4b5563;
  }

  .legal h2 {
    break-after: avoid;
    font-size: 12pt;
  }

  .legal p,
  .legal li {
    orphans: 3;
    widows: 3;
  }
}

@page {
  size: A4;
  margin: 18mm 16mm;
}
