/* Aufbau, Masse UND Handschrift aller fuenf Varianten. Ab Runde 18 ist die
   ganze Seite gesetzt: Schrift, Farbe, jeder Abschnitt. Verschieden ist NUR
   noch das Feld im Hero — jede Variante bringt es in ihrer app.js mit.

   Fest verdrahtet, weil mehrfach gerissen:
   1. Nichts aendert nach dem Laden seine Hoehe (Schrift vorgeladen, Flaechen
      reserviert) — die Seite darf beim Reinladen nicht springen.
   2. Das Feld hat oben KEINE tote Zone: es blasst zum Rand aus, ist aber
      ueberall vorhanden.
   3. Ein Rhythmus fuer alle Abschnitte: --abschnitt.
   4. Das Zeichen steht GANZ im sichtbaren Streifen, die Ansage mittig darin;
      das Feld beruhigt sich hinter der Schrift (Lichtung, siehe kern.js). */

:root {
  /* Eine Spur weiter ins Graue als Runde 12 — derselbe Ton wie das Dashboard
     (#101113/#141619), damit Seite und Produkt aus einer Familie sind. */
  --bg: #0a0a0b;
  --bg2: #101113;
  --fg: #f2f3f5;
  --mid: #c2c4c9;
  --dim: #8b8e95;
  --line: rgba(242, 243, 245, .075);
  --line-2: rgba(242, 243, 245, .15);
  --flaeche: #141518;
  --flaeche-2: #1b1c20;

  /* Bedeutungsfarben wie im Dashboard — und nur dort, wo sie etwas bedeuten. */
  --gruen: #46d68b;
  --amber: #f0b45c;
  --rot: #f97070;

  /* Der eine Farbmoment der Seite — sichtbar nur am hervorgehobenen Plan und
     im Konfetti. Gruen war seine Wahl aus Runde 17. */
  --akzent: #46d68b;

  --r: 16px;
  --r-gross: 22px;
  --breit: 1180px;
  --eng: 1080px;
  --font: "Onest", system-ui, sans-serif;
  --font-h: "Funnel Display", system-ui, sans-serif;
  --mono: "Chivo Mono", ui-monospace, monospace;
  --h-weight: 600;
  --h-space: -.03em;
  --h-hoehe: 1.02;
  --ease: cubic-bezier(.22, 1, .36, 1);
  --glanz: rgba(242, 243, 245, .1);
  --art: #f2f3f5;

  --abschnitt: clamp(76px, 9.5vw, 128px);
  /* Die Kopfleiste liegt ueber allem, was darunter durchscrollt. Wer mittig im
     SICHTBAREN Teil stehen soll, braucht diese Hoehe als Rechenwert. */
  --leiste: 66px;

  /* Der Chat ist ein echtes Kleinanzeigen-Fenster: heller Schirm, gruene Blase. */
  --ka-schirm: #e7e9ec;
  --ka-kopf: #f1f2f4;
  --ka-blase: #cfe8a3;
  --ka-blase-ink: #27370f;
  --ka-ink: #14181c;
}

/* Die Wurzel traegt dieselbe Flaeche wie der Koerper: iOS liest sie aus, um
   seine eigenen Leisten einzufaerben, und faellt bei durchsichtiger Wurzel auf
   Weiss zurueck. */
html { background: var(--bg); color-scheme: dark; }
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.55;
  overflow-x: clip;
}
::selection { background: rgba(255, 255, 255, .16); }
/* Ohne das zoomt iOS beim zweiten schnellen Tippen auf einen Knopf herein —
   das Zoomen mit zwei Fingern bleibt erlaubt. */
a, button, summary, [role="button"] { touch-action: manipulation; }

/* Die Kopfleiste liegt UEBER der Seite: ein Sprung muss darunter landen,
   sonst haengt die Ueberschrift des Ziels dahinter. */
section[id] { scroll-margin-top: var(--leiste); }

.wrap { width: min(100% - 40px, var(--breit)); margin-inline: auto; }
.wrap-eng { width: min(100% - 40px, var(--eng)); margin-inline: auto; }
@media (max-width: 560px) { .wrap, .wrap-eng { width: calc(100% - 30px); } }

h1, h2, h3 { font-family: var(--font-h); font-weight: var(--h-weight); letter-spacing: var(--h-space); line-height: var(--h-hoehe); }
h1 { font-size: clamp(46px, 9.1vw, 95px); }
/* Untergrenze deutlich tiefer statt eines eigenen Handy-Wertes: eine
   Abschnitts-Ueberschrift von 30px nimmt auf einem 390er Schirm zweizeilig den
   halben Bildschirm ein. Dieselbe Formel, nur ohne den zu hohen Boden. */
h2 { font-size: clamp(30px, 5vw, 57px); }
h1 span, h2 span { color: var(--mid); }

/* ── Kopfleiste ───────────────────────────────────────────────────────────
   Rechts steht nur der Login. Die Kante der Leiste geht ueber das GANZE
   Fenster — vorher endete sie mit der Inhaltsspalte, also mitten im Wort. */
/* `viewport-fit=cover` laesst die Seite unter die Statusleiste reichen — ohne
   diesen Abstand sitzt der Menue-Knopf dort, wo iOS die Beruehrung selbst
   nimmt (Tippen auf die Statusleiste springt nach oben). */
.topbar { position: sticky; top: 0; z-index: 40; padding-top: env(safe-area-inset-top, 0px); }
/* Die Platte reicht ein gutes Stueck UNTER die Zeile hinaus: endete sie auf
   Hoehe der Schrift, sass die Kante genau auf den Unterlaengen der Zeile.
   Sie DECKT bis genau zur Unterkante der Leiste und blendet erst darunter aus:
   vorher wurde sie schon 18 px darueber durchsichtig, und was gerade
   durchscrollte, stand dort als Schemen IN der Leiste. */
.topbar::before {
  content: ""; position: absolute; inset: -12px 0 -26px; pointer-events: none;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  mask-image: linear-gradient(180deg, #000 calc(12px + env(safe-area-inset-top, 0px) + var(--leiste)), transparent);
}
/* KEINE harte Kante unter der Leiste. Sie lag als durchgehender Strich ueber
   allem, was darunter durchscrollt — am gehefteten Chatfenster sah das aus wie
   ein Fehler. Die blasse, ausblendende Platte trennt genug. */
.topbar-in {
  position: relative;
  display: flex; align-items: center; gap: 18px;
  width: min(100% - 40px, var(--breit)); margin-inline: auto; height: var(--leiste);
}
/* ── iOS 26: die Leiste bleibt durchsichtig ───────────────────────────────
   Safari (Liquid Glass) tastet 4 px ueber der Unterkante ab, ob dort ein
   festes oder klebendes Element liegt, und fuellt dann den Streifen unter
   seiner Leiste DAUERHAFT mit dessen Farbe - solange das Element existiert,
   auch wenn es laengst weitergescrollt ist (WebKit, LocalFrameView::
   fixedContainerEdges und Page::updateFixedContainerEdges). Der klebende
   Chat-Block loeste genau das aus: ab der Ablauf-Sektion stand ein Balken.
   Dieser Kasten liegt zuoberst genau auf dem Abtastpunkt. Ein Treffer auf
   ein Pseudo-Element landet bei seinem Wirt (HitTestResult), und body ist
   nicht fest: die Suche geht leer aus, bevor sie etwas darunter findet. Er
   braucht einen Hintergrund, sonst gilt er als leer und wird uebersprungen. */
body::after {
  content: ""; position: fixed; z-index: 2147483647; left: 0; right: 0; bottom: 0;
  width: 24px; height: 24px; margin-inline: auto;
  background-image: linear-gradient(transparent, transparent); pointer-events: none;
}
/* Ist das Menue offen, soll Safari den Streifen unter seiner Leiste mit dessen
   Farbe fuellen - unter die Leiste malen kann das Menue selbst nicht, iOS
   schneidet feste Elemente an der Layout-Kante ab. Also tritt das Schild
   solange zurueck; zu heisst `display: none`, damit die Farbe nicht klebt. */
body:has(.menue.is-auf)::after { display: none; }

.mark { display: flex; align-items: center; gap: 9px; font-weight: 620; letter-spacing: -.03em; }
.mark img { border-radius: 7px; }
.nav-mid { display: none; gap: 26px; margin-inline: auto; }
.nav-mid a { color: var(--dim); font-size: 14.5px; transition: color .2s; }
.nav-mid a:hover { color: var(--fg); }
.nav-end { display: flex; align-items: center; gap: 9px; margin-left: auto; }
@media (min-width: 900px) { .nav-mid { display: flex; } .nav-end { margin-left: 0; } }

/* ── Menue ────────────────────────────────────────────────────────────────
   Unter 900 px ist die Zeile mit den Abschnitten ausgeblendet — ohne Ersatz
   fuehrte von dort kein Weg mehr zu den Abschnitten der Seite. Der
   Login zieht mit hinein, damit in der Leiste EIN Bedienteil steht. */
.nav-knopf {
  display: none; place-items: center; width: 46px; height: 46px;
  border: 1px solid var(--line-2); border-radius: 999px; color: var(--fg);
  transition: border-color .2s, color .2s;
}
.nav-knopf:hover { border-color: rgba(242, 243, 245, .34); }
/* Drei Striche, nicht zwei: das ist das Zeichen, nach dem gesucht wird. */
.nav-knopf i, .nav-knopf i::before, .nav-knopf i::after {
  content: ""; display: block; width: 19px; height: 1.6px; border-radius: 2px;
  background: currentColor;
  /* Im Takt der Menue-Blende: der harte Umschlag auf das Kreuz war das letzte,
     was oben noch zuckte. */
  transition: top .24s var(--ease), transform .24s var(--ease), background-color .14s;
}
.nav-knopf i { position: relative; }
.nav-knopf i::before, .nav-knopf i::after { position: absolute; left: 0; }
.nav-knopf i::before { top: -6px; }
.nav-knopf i::after { top: 6px; }
.nav-knopf.is-zu i { background: transparent; }
.nav-knopf.is-zu i::before { top: 0; transform: rotate(45deg); }
.nav-knopf.is-zu i::after { top: 0; transform: rotate(-45deg); }

.menue {
  /* Ausserhalb des klebenden Kopfes: ein festes Element in einem klebenden
     Vorfahren ist auf iOS unzuverlaessig — dort ging das Menue gar nicht auf.
     Deshalb traegt es seine eigene Kopfzeile und liegt UEBER der Leiste. */
  position: fixed; z-index: 60; inset: 0;
  padding-top: env(safe-area-inset-top, 0px);
  /* Eigene Ebene: sonst malt der Browser beim Einblenden die Seite darunter
     Bild fuer Bild mit. */
  transform: translateZ(0);
  /* Unten statt mittig: dort liegt der Daumen, und die leere Flaeche darueber
     laesst die vier Zeilen als Block stehen statt sie im Nichts zu halten.
     Der Platz kommt aus `margin-top: auto` der Liste, nicht aus
     `justify-content`: quer gedreht wuerde der sonst oben abschneiden. */
  flex-direction: column; overflow-y: auto;
  padding-inline: 20px; padding-bottom: calc(30px + env(safe-area-inset-bottom, 0px));
  background: var(--bg);
  /* 🔴 `display: none`, nicht `opacity: 0`: iOS 26 faerbt seine Leiste nach der
     `background-color` fester Elemente an der Bildkante — und zaehlt dabei auch
     unsichtbare mit. Dieses Feld liegt ueber dem GANZEN Bild, faerbte die
     Leiste also dauerhaft ein, obwohl das Menue zu ist. Nur `display: none`
     nimmt es da heraus; `allow-discrete` und `@starting-style` halten die
     Blende trotzdem weich. */
  display: none; opacity: 0;
  transition: opacity .26s var(--ease), display .26s allow-discrete;
}
.menue.is-auf { display: flex; opacity: 1; }
@starting-style { .menue.is-auf { opacity: 0; } }
.menue-kopf { display: flex; align-items: center; justify-content: space-between; height: var(--leiste); }
.menue-kopf .nav-knopf { display: grid; }
.menue-liste { display: grid; margin-top: auto; border-top: 1px solid var(--line); }
.menue-liste a {
  display: grid; grid-template-columns: 32px 1fr 24px; align-items: center; gap: 14px;
  padding: 18px 2px; border-bottom: 1px solid var(--line);
}
.m-zeichen, .m-pfeil { display: block; color: var(--mid); }
.m-zeichen { width: 23px; height: 23px; }
.m-pfeil { width: 18px; height: 18px; justify-self: end; color: var(--dim); }
.m-zeichen svg, .m-pfeil svg {
  width: 100%; height: 100%; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.menue-liste span {
  font-family: var(--font-h); font-weight: var(--h-weight);
  letter-spacing: var(--h-space); line-height: 1.04;
  font-size: clamp(31px, 8.6vw, 40px);
}
.menue-app { width: 100%; margin-top: 26px; }
/* Die Zeilen kommen einzeln nach — dieselbe Handschrift wie der Aufbau im
   letzten Schritt, nur kuerzer. */
.menue-liste a, .menue-app { opacity: 0; }
.menue.is-auf .menue-liste a, .menue.is-auf .menue-app {
  animation: menue-rein .44s var(--ease) both; animation-delay: var(--d, 260ms);
}
@keyframes menue-rein { from { opacity: 0; transform: translateY(15px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .menue.is-auf .menue-liste a, .menue.is-auf .menue-app { animation: none; opacity: 1; }
  .nav-knopf i, .nav-knopf i::before, .nav-knopf i::after { transition: none; }
}
@media (max-width: 899px) { .nav-knopf { display: grid; } .nav-end .btn { display: none; } }
@media (min-width: 900px) { .menue, .nav-knopf { display: none; } }
/* Kein `overflow: hidden` am Koerper: das macht ihn zum Scrollrahmen seiner
   klebenden Kinder, und die Kopfleiste sprang im ersten Bild an den Anfang des
   Dokuments — genau das Zucken beim Aufklappen. Die Platte haelt sich selbst. */
.menue { overscroll-behavior: contain; }


.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 36px; padding: 0 16px; border-radius: 999px;
  font-size: 14px; font-weight: 560; letter-spacing: -.01em; white-space: nowrap;
  transition: background-color .2s, border-color .2s, color .2s, transform .12s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn-solid { background: var(--fg); color: #0b0b0a; }
.btn-solid:hover { background: #fff; }
.btn-ghost { border: 1px solid var(--line-2); color: var(--mid); }
.btn-ghost:hover { border-color: rgba(242, 243, 245, .34); color: var(--fg); }
.btn-lg { height: 50px; padding: 0 26px; font-size: 15.5px; }

/* ── Hero ─────────────────────────────────────────────────────────────────
   Das Feld ist ueberall vorhanden, blasst oben ein und nach unten lange aus,
   sodass es hinter dem Dashboard verschwindet statt an dessen Kante
   abzubrechen. KEIN Schleier mehr hinter der Ansage: wo das Zeichen hinter dem
   Text steht, tritt das FELD dort zurueck (Lichtung, siehe kern.js) — ein
   dunkler Fleck vor dem Zeichen sah aus wie ein Fehler. */
.hero { position: relative; --hero-luft: clamp(84px, 10vw, 148px); }
/* Oben und unten GENAU gleich viel Luft — dadurch steht die Ansage von selbst
   mittig im Streifen, also mittig ueber dem Loch des Zeichens. Und das Feld
   deckt nur noch diesen Streifen ab statt den ganzen Hero: die Flaeche ist ein
   Drittel so gross, was das Scrollen spuerbar glaettet. */
.hero-kopf { position: relative; padding: var(--hero-luft) 0; }
.feld {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  mask-image: linear-gradient(180deg, transparent 0, #000 14%, #000 82%, transparent 100%);
}
.feld canvas { display: block; width: 100%; height: 100%; }
.hero-in { position: relative; z-index: 1; text-align: center; }
.hero-in h1 { font-size: clamp(44px, 10.1vw, 99px); }
.hero-in p {
  max-width: 44ch; margin: 22px auto 0; color: var(--mid);
  font-size: clamp(16px, 2vw, 18.5px); line-height: 1.6;
}
.acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 11px; margin-top: 32px; }

/* Das Dashboard ist das Hauptstueck des Hero. Format eines echten Bildschirms,
   nie angeschnitten — am Handy ein hochkant zugeschnittener Ausschnitt. */
.stage { position: relative; }
.stage::before {
  content: ""; position: absolute; inset: -16% -8% 4%; z-index: -1; pointer-events: none;
  background: radial-gradient(58% 54% at 50% 6%, var(--glanz), transparent 72%);
  filter: blur(38px);
}
.dashframe {
  position: relative; overflow: hidden;
  border: 1px solid var(--line-2); border-radius: var(--r-gross);
  background: #101113;
  box-shadow: 0 40px 110px rgba(0, 0, 0, .62);
}
.dashbar {
  display: flex; align-items: center; gap: 7px; height: 34px; padding: 0 14px;
  border-bottom: 1px solid rgba(255, 255, 255, .06); background: #141619;
}
.dashbar i { width: 9px; height: 9px; border-radius: 50%; }
.dashbar .d1 { background: #f8695f; } .dashbar .d2 { background: #f7bd4f; } .dashbar .d3 { background: #62c554; }
.dashbar span { margin-inline: auto; padding-right: 34px; color: rgba(235, 238, 244, .42); font-family: var(--mono); font-size: 11px; }
/* Die Hoehe steht VOR dem Skript fest — sonst waechst der Rahmen beim Laden
   und schiebt die halbe Seite nach unten. */
.dash { position: relative; overflow: hidden; aspect-ratio: 1180 / 663; }
/* Am Handy dasselbe Format wie der schmale Bau in `mountDash` — sonst springt
   der Rahmen in dem Moment, in dem das Skript die Hoehe setzt. */
@media (max-width: 760px) {
  .dashbar { height: 28px; } .dashbar span { font-size: 10px; padding-right: 24px; }
  .dash { aspect-ratio: 392 / 690; }
}

/* Ein Reiter, der am Fensterrahmen haengt: der Knopf gehoert zum Fenster, er
   liegt nicht daneben. Genau diese Bauart ist gesetzt — nur deutlich
   praesenter, damit man ihm ansieht, dass man ihn druecken kann: hellere
   Flaeche, klarer Rand, Spielzeichen im eigenen Kreis, Schatten. */
.stage-foot { position: relative; display: flex; justify-content: center; padding-top: 26px; }
.dk {
  display: inline-flex; align-items: center; gap: 11px;
  margin-top: -26px; height: 46px; padding: 0 20px 0 9px;
  border: 1px solid var(--line-2); border-top: 0; border-radius: 0 0 17px 17px;
  background: #1e2126; color: var(--fg);
  font-size: 14.5px; font-weight: 560; letter-spacing: -.012em;
  box-shadow: 0 16px 34px rgba(0, 0, 0, .5);
  transition: background-color .2s, border-color .2s;
}
.dk:hover { background: #262931; border-color: rgba(242, 243, 245, .32); }
.dk:active { transform: translateY(1px); }
.dk-sp { display: grid; place-items: center; width: 28px; height: 28px; flex: 0 0 auto; border-radius: 50%; background: var(--fg); }
.dk-sp svg { width: 11px; height: 11px; margin-left: 1.5px; fill: #0a0a0b; }
.dk-pf { width: 15px; height: 15px; flex: 0 0 auto; fill: none; stroke: var(--dim); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; transition: transform .24s var(--ease), stroke .2s; }
.dk:hover .dk-pf { transform: translateX(3px); stroke: var(--fg); }
@media (max-width: 560px) { .dk { height: 42px; font-size: 13.5px; padding-right: 16px; } }

/* ── Zahlen ────────────────────────────────────────────────────────────────
   Aussen eine Linie ueber die volle Fensterbreite, zu den Enden ausblassend.
   Innen VOLLE Trenner ohne Verlauf — von Linie zu Linie durchgezogen. */
.figs { padding: var(--abschnitt) 0 0; }
.figs-in { --figs-luft: clamp(30px, 4vw, 46px); position: relative; display: grid; padding: var(--figs-luft) 0; }
.figs-in::before {
  content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 100vw;
  transform: translateX(-50%); pointer-events: none;
  border-top: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2);
  mask-image: linear-gradient(90deg, transparent, #000 11%, #000 89%, transparent);
}
.fg { position: relative; display: grid; justify-items: center; padding: 22px 4px; text-align: center; }
.fg + .fg::before {
  content: ""; position: absolute; left: 50%; top: 0; width: 100vw; height: 1px;
  transform: translateX(-50%); background: var(--line-2);
}
.fg-art { display: block; height: 56px; margin-bottom: 20px; }
.art { display: block; width: auto; height: 100%; overflow: visible; color: var(--art); }
.fg-v { display: block; font-family: var(--font-h); font-size: clamp(32px, 4.4vw, 46px); font-weight: var(--h-weight); letter-spacing: -.04em; line-height: 1; font-variant-numeric: tabular-nums; }
.fg-l { display: block; margin-top: 12px; font-size: 15.5px; font-weight: 560; color: var(--mid); }
@media (min-width: 820px) {
  .figs-in { grid-template-columns: repeat(3, 1fr); }
  .fg { padding: 0; }
  .fg + .fg::before {
    inset: calc(-1 * var(--figs-luft)) auto calc(-1 * var(--figs-luft)) 0;
    width: 1px; height: auto; transform: none; background: var(--line-2);
  }
}
/* Am Handy tragen die zwei Trenner ZWISCHEN den Zahlen die Gliederung allein:
   Rahmen oben und unten war zu viel Linie fuer drei Zahlen. Sie stehen mittig
   unter der Zahl und blenden nach BEIDEN Seiten gleich aus — nur nach rechts
   auslaufend sassen sie sichtbar schief. */
@media (max-width: 819px) {
  .figs-in::before { display: none; }
  .fg + .fg::before {
    width: 100%;
    background: linear-gradient(90deg, transparent, var(--line-2) 12%, var(--line-2) 88%, transparent);
  }
}

/* Drei Bilder, drei Formen, drei Bewegungen — sie starten gemeinsam und enden
   verschieden lang. Eine Spur langsamer als in Runde 12, damit man zusieht. */
.art-linie {
  fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 1.35s var(--ease);
}
.art-kopf { fill: currentColor; opacity: 0; transition: opacity .3s 1.15s; }
.fg.is-in .art-linie { stroke-dashoffset: 0; }
.fg.is-in .art-kopf { opacity: 1; }
/* „Zeit gespart": die volle Scheibe; ein Schnitt laeuft einmal herum und laesst
   deinen Rest stehen. Als Kegelverlauf, weil ein SVG-Keil ohne Skript nicht
   rundlaeuft. Diese drei Bilder sind gesetzt und in allen Varianten gleich. */
@property --p { syntax: "<angle>"; inherits: false; initial-value: 78deg; }
.art-uhr {
  width: 56px; height: 56px; border-radius: 50%;
  background: conic-gradient(currentColor 0 var(--p), rgba(242, 243, 245, .12) var(--p) 360deg);
  transition: --p 1.25s var(--ease) .2s;
}
.fg .art-uhr { --p: 360deg; }
.fg.is-in .art-uhr { --p: 78deg; }
/* Menge: alle Punkte stehen zuerst hell, dann wandert die Pruefung durch das
   Feld und laesst nur die Treffer hell zurueck. */
.art-punkt {
  fill: currentColor; opacity: 0;
  transition: opacity .32s linear calc(var(--i) * 14ms), fill .55s var(--ease) calc(880ms + var(--i) * 14ms);
}
.fg.is-in .art-punkt { opacity: 1; }
.fg.is-in .art-punkt:not(.an) { fill: var(--line-2); }
@media (prefers-reduced-motion: reduce) {
  .art-linie, .art-kopf, .art-punkt, .art-uhr { transition: none; opacity: 1; }
  .art-linie { stroke-dashoffset: 0; }
  .fg .art-uhr { --p: 78deg; }
  .art-punkt:not(.an) { fill: var(--line-2); }
}

/* ── Abschnittskopf ───────────────────────────────────────────────────────── */
.head { text-align: center; }
.head p { max-width: 54ch; margin: 16px auto 0; color: var(--dim); font-size: 16px; }
.query {
  display: inline-flex; align-items: center; gap: 10px; margin-top: 26px;
  height: 44px; padding: 0 20px; border-radius: 999px;
  background: var(--flaeche-2); font-size: 14.5px;
}
.query svg { width: 16px; height: 16px; fill: none; stroke: var(--dim); stroke-width: 2; stroke-linecap: round; }
.query b { font-weight: 560; }
.query span { color: var(--dim); }

/* ── Anzeigen-Band ──────────────────────────────────────────────────────────
   Kartenbreite, Bildhoehe und Bandhoehe haengen zusammen — am Handy wird alles
   drei kleiner, deshalb steht es als EIN Satz Werte hier oben. */
.detect { padding: var(--abschnitt) 0 0; }
.belts { --karte: 236px; --karte-bild: 152px; --band: 265px; margin-top: clamp(36px, 4.5vw, 58px); display: grid; gap: 16px; }
/* Hoehe steht fest, bevor das Skript die Karten baut. */
.belt { height: var(--band); overflow: hidden; mask-image: linear-gradient(90deg, transparent, #000 13%, #000 87%, transparent); }
.brail { overflow: hidden; }
.btrack { display: flex; gap: 16px; will-change: transform; }
/* Von 64 Karten stehen immer nur zwei bis drei im Bild — die uebrigen laesst
   der Browser aus. Das war die teuerste Stelle beim schnellen Scrollen am
   Handy (schlimmstes Bild 98 → 57 ms bei vierfach gebremster Rechenleistung).
   Die Ersatzmasse ist die ECHTE Kartenhoehe, sonst zoege eine uebersprungene
   Karte die ganze Reihe hoeher. */
.acard {
  position: relative; flex: 0 0 auto; width: var(--karte); overflow: hidden;
  content-visibility: auto; contain-intrinsic-size: auto var(--karte) auto 249px;
  border: 1px solid var(--line); border-radius: var(--r); background: var(--flaeche);
  transition: opacity .45s var(--ease), border-color .45s, box-shadow .45s;
}
.acard img { display: block; width: 100%; height: var(--karte-bild); object-fit: cover; }
.card-b { padding: 12px 12px 14px; }
.card-t { display: flex; justify-content: space-between; font-size: 11px; color: var(--dim); }
.card-h { margin-top: 5px; font-size: 13.5px; font-weight: 560; letter-spacing: -.01em; line-height: 1.3; }
.card-f { display: flex; align-items: center; gap: 8px; margin-top: 11px; font-size: 12px; }
.card-p { flex: 0 0 auto; font-weight: 620; white-space: nowrap; }
.card-s { min-width: 0; overflow: hidden; color: var(--dim); white-space: nowrap; text-overflow: ellipsis; }

/* Das Urteil sitzt MITTIG auf dem Bild, nicht in der Ecke: gruener Haken fuer
   den Treffer, Kreuz fuers Aussortierte. Der Treffer wird auch als Karte
   deutlich gruen — sonst faellt die Entscheidung optisch nicht auf. */
.card-mark {
  position: absolute; left: 0; right: 0; top: 0; height: var(--karte-bild); z-index: 2;
  display: grid; place-items: center; pointer-events: none;
  background: rgba(9, 10, 11, .34); opacity: 0; transition: opacity .34s;
}
.card-mark i {
  grid-area: 1 / 1; display: grid; place-items: center; width: 46px; height: 46px;
  border-radius: 50%; background: rgba(9, 10, 11, .72);
  transform: scale(.6); transition: transform .4s var(--ease), background-color .3s;
}
/* Beide Zeichen liegen AUFEINANDER. Ohne `grid-area` legt das Raster sie
   untereinander — dann sitzt der Haken in der oberen Haelfte statt mittig. */
.card-mark svg {
  grid-area: 1 / 1; width: 21px; height: 21px; fill: none;
  stroke-width: 2.7; stroke-linecap: round; stroke-linejoin: round;
  opacity: 0; transition: opacity .3s;
}
.acard.is-hit .card-mark, .acard.is-miss .card-mark { opacity: 1; }
.acard.is-hit .card-mark i, .acard.is-miss .card-mark i { transform: none; }
.acard.is-hit .card-mark { background: rgba(70, 214, 139, .13); }
.acard.is-hit .card-mark i { background: var(--gruen); }
.acard.is-hit .mk-ja { opacity: 1; stroke: #06240f; }
.acard.is-miss .mk-nein { opacity: 1; stroke: var(--fg); }
.acard.is-hit {
  border-color: rgba(70, 214, 139, .62);
  box-shadow: 0 0 0 1px rgba(70, 214, 139, .34), 0 14px 34px rgba(0, 0, 0, .4);
}
.acard.is-hit .card-p { color: var(--gruen); }
/* Kein Graufilter mehr: bei 16 % Deckkraft war er kaum zu sehen, kostete am
   Handy aber die teuerste Bildlaufzeit der Seite (schlimmstes Bild 111 → 69 ms
   bei vierfach gebremster Rechenleistung). */
.acard.is-miss { opacity: .16; }
/* Am Handy ein knappes Drittel kleiner: die Karten waren dort fast so breit wie
   der halbe Schirm, und dann sieht man vom Band nur noch zwei Bilder. */
@media (max-width: 700px) {
  .belts { --karte: 165px; --karte-bild: 106px; --band: 208px; gap: 12px; }
  .acard { contain-intrinsic-size: auto var(--karte) auto 206px; }
  .btrack { gap: 12px; }
  .card-b { padding: 10px 10px 11px; }
  .card-t { font-size: 10px; }
  .card-h { margin-top: 4px; font-size: 12.5px; }
  .card-f { margin-top: 8px; font-size: 11px; }
  .card-mark i { width: 38px; height: 38px; }
  .card-mark svg { width: 17px; height: 17px; }
}

/* ── Chat + Schrittleiste ──────────────────────────────────────────────────
   1080 breit, Chat ~635, Leiste ~419 — gemessen am Original. Beide Spalten
   haben FESTE Hoehe, deshalb springt beim Eintreffen einer Nachricht nichts. */
/* Am Rechner haftet die Ueberschrift als EIGENE Ebene ueber dem Fenster — sie
   gehoert zum Chat und bleibt dabei. Am Handy scrollt sie weg (sie presste den
   Chat sonst zusammen), das Fenster bekommt den ganzen Schirm. */
/* 🔴 Solange der Chat laeuft, steht der Schirm still. Bei 320vh waren das 10
   Rad-Rasterungen ohne sichtbare Bewegung, und danach lief die Seite wieder
   normal — genau das las sich als „das Scrollen speedet auf". Gemessen ist der
   Weg je Rasterung ueberall gleich (200 px), es ist also der Kontrast. */
/* `section.talk`, nicht `.talk`: die allgemeine Regel oben ist mit
   `section[id]` spezifischer und wuerde sonst gewinnen. Der Sprung auf
   `#ablauf` landet damit genau dort, wo der Block ohnehin kleben wird. */
section.talk {
  /* EIN Wert fuer den Platz ueber dem klebenden Block und fuer das Sprungziel:
     driften die auseinander, landet `#ablauf` neben dem Block. */
  --kopfluft: var(--abschnitt);
  position: relative; min-height: 260vh;
  padding-top: var(--kopfluft); scroll-margin-top: calc(var(--kopfluft) * -1);
}
/* Ueberschrift und Fenster kleben GEMEINSAM: als eigene haftende Ebene lief
   die Ueberschrift frueher ueber das Fenster, in derselben Ebene kann sie das
   nicht. Nur so steht sie dicht am Fenster — liegt sie im Fluss darueber, ist
   ihr Abstand zwangslaeufig so gross wie der Rand des Fensters zum Bildrand. */
.talk-pin {
  position: sticky; top: 0; min-height: 100svh;
  /* `safe center`: passt der Block ausnahmsweise nicht (kurzes Fenster, drei
     Zeilen Ueberschrift), rutscht er nach OBEN statt mittig zu bleiben —
     sonst waere die Ueberschrift ueber dem Bildrand. */
  display: flex; flex-direction: column; justify-content: safe center;
  padding: calc(var(--leiste) + 16px) 0 20px;
}
.talk-head { margin-bottom: clamp(18px, 2vw, 26px); }
.talk-stage { display: grid; gap: 20px; }
@media (min-width: 900px) {
  /* Schmaler als der Abschnitt: das Fenster stand sonst fast randlos breit. */
  .talk-stage { width: min(100%, 980px); margin-inline: auto; grid-template-columns: minmax(0, 1fr) minmax(280px, .66fr); gap: 26px; align-items: stretch; }
}

.chat-win { padding: 9px; border: 1px solid var(--line-2); border-radius: var(--r-gross); background: var(--flaeche-2); }
.chat-screen {
  /* Ueberschrift, Fenster und Schrittliste kleben als EIN Block. Seine Hoehe
     muss unter 100svh bleiben, sonst stuende der Kopf ueber dem Bildrand.
     Deshalb bekommt das Fenster, was uebrig bleibt — nicht einen festen
     Anteil des Schirms. */
  display: flex; flex-direction: column; height: min(620px, calc(100svh - 350px)); overflow: hidden;
  border: 1px solid rgba(0, 0, 0, .18); border-radius: calc(var(--r-gross) - 8px);
  background: var(--ka-schirm); box-shadow: 0 8px 22px rgba(0, 0, 0, .22);
}
.chat-top { display: flex; align-items: center; gap: 11px; padding: 10px 12px; background: var(--ka-kopf); border-bottom: 1px solid rgba(22, 23, 26, .08); }
.chat-th { border-radius: 50%; object-fit: cover; }
.chat-who { display: flex; flex-direction: column; min-width: 0; }
.chat-who strong { color: #16201a; font-size: 14px; font-weight: 700; }
.chat-who small { overflow: hidden; color: rgba(22, 23, 26, .55); font-size: 12px; white-space: nowrap; text-overflow: ellipsis; }
.chat-tag {
  display: flex; align-items: center; gap: 6px; margin-left: auto;
  padding: 4px 11px; border-radius: 999px; background: var(--ka-blase);
  color: var(--ka-blase-ink); font-size: 11px; font-weight: 700;
}
.chat-tag::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: #4d7a12; }
.chat-body {
  position: relative; flex: 1; min-height: 0; overflow: hidden; padding: 0 14px;
  display: flex; flex-direction: column; justify-content: flex-end;
}
/* Oben ausblenden GEMALT statt MASKIERT: eine Maske hebt den ganzen Verlauf
   auf eine eigene Ebene, die bei jedem Scrollbild neu zusammengesetzt wird —
   dort entstehen die dunklen Flecken. Der Schirm ist einfarbig, ein Verlauf
   darueber sieht deshalb genauso aus und kostet nur einen Malzug. */
.chat-body::before {
  content: ""; position: absolute; z-index: 1; left: 0; right: 0; top: 0; height: 12%;
  background: linear-gradient(180deg, var(--ka-schirm), rgba(231, 233, 236, 0));
  pointer-events: none;
}
.chat-track { display: flex; flex-direction: column; align-items: flex-start; gap: 9px; padding: 16px 0 12px; }
.msg { display: none; max-width: min(340px, 86%); padding: 9px 14px; font-size: 13.5px; line-height: 1.5; overflow-wrap: anywhere; }
.msg.is-shown { display: block; animation: sagen .36s var(--ease) both; }
/* Ohne `scale`: eine Blase aus Text, runden Ecken und Schlagschatten wird
   dabei auf krummer Groesse neu gerastert, und genau das setzt die dunklen
   Punkte an die Ecken. Verschieben allein tut das nicht. */
@keyframes sagen { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .msg.is-shown { animation: none; } }
.msg-a { display: block; margin-bottom: 2px; font-size: 10.5px; font-weight: 700; letter-spacing: .02em; }
.msg.is-bot { align-self: flex-end; color: var(--ka-blase-ink); background: var(--ka-blase); border-radius: 17px 17px 5px 17px; box-shadow: 0 8px 20px rgba(120, 150, 40, .14); }
.msg.is-bot .msg-a { color: rgba(40, 55, 15, .6); }
.msg.is-seller { align-self: flex-start; color: var(--ka-ink); background: #fff; border-radius: 17px 17px 17px 5px; box-shadow: 0 8px 20px rgba(22, 23, 26, .1); }
.msg.is-seller .msg-a { color: rgba(22, 23, 26, .5); }
.msg.is-status {
  align-self: center; max-width: none; padding: 7px 15px; border-radius: 999px;
  border: 1px solid rgba(22, 23, 26, .1); background: rgba(22, 23, 26, .045);
  color: rgba(22, 23, 26, .6); font-size: 12px; font-weight: 620;
}
.msg.is-media { align-self: flex-start; max-width: min(300px, 82%); padding: 0; background: none; box-shadow: none; }
.msg-media { display: flex; gap: 6px; }
.msg-media img { width: 92px; height: 92px; border-radius: 15px; object-fit: cover; box-shadow: 0 8px 18px rgba(22, 23, 26, .16); }
.msg.is-media small { display: block; margin-top: 6px; color: rgba(22, 23, 26, .5); font-size: 11.5px; }
.chat-input { display: flex; align-items: center; gap: 10px; min-height: 54px; padding: 8px 12px; border-top: 1px solid rgba(22, 23, 26, .08); background: #fdfcfa; }
.chat-field { display: flex; align-items: center; flex: 1; height: 38px; padding: 0 15px; border: 1px solid rgba(22, 23, 26, .1); border-radius: 999px; background: #f3f1ea; color: rgba(22, 23, 26, .42); font-size: 13px; }
.chat-typing { display: flex; gap: 4px; width: 38px; height: 38px; align-items: center; justify-content: center; border-radius: 50%; background: var(--ka-blase); opacity: 0; transition: opacity .25s; }
.chat-typing.is-on { opacity: 1; }
.chat-typing b { width: 5px; height: 5px; border-radius: 50%; background: rgba(60, 82, 18, .55); animation: tip 1.05s infinite; }
.chat-typing b:nth-child(2) { animation-delay: .14s; }
.chat-typing b:nth-child(3) { animation-delay: .28s; }
@keyframes tip { 0%, 60%, 100% { opacity: .34; transform: none; } 30% { opacity: 1; transform: translateY(-3px); } }

/* Die Leiste: sechs gleich hohe Spuren in einem Kasten fester Hoehe. Die
   Schiene laeuft exakt vom ersten bis zum letzten Knoten (8.333 %/83.333 %). */
.sch { display: flex; flex-direction: column; height: 100%; min-height: 440px; padding: 8px 4px; }
.sch-list { position: relative; flex: 1; min-height: 0; display: grid; grid-template-rows: repeat(6, 1fr); }
.sch-rail { position: absolute; left: 11px; top: 8.333%; height: 83.333%; width: 2px; transform: translateX(-50%); border-radius: 2px; background: var(--line-2); }
.sch-rail i {
  position: absolute; inset: 0; border-radius: 2px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .55), #fff);
  transform: scaleY(var(--lauf, 0)); transform-origin: top center;
}
.sch-row { position: relative; display: grid; grid-template-columns: 22px minmax(0, 1fr); align-items: center; gap: 16px; }
.sch-node {
  position: relative; z-index: 2; justify-self: center;
  display: grid; place-items: center; width: 15px; height: 15px;
  border: 2px solid var(--line-2); border-radius: 50%;
  background: var(--bg); box-shadow: 0 0 0 4px var(--bg);
  transition: border-color .24s, background-color .24s, transform .28s var(--ease);
}
.sch-check { width: 9px; height: 9px; fill: none; stroke: #06240f; stroke-width: 3.6; stroke-linecap: round; stroke-linejoin: round; opacity: 0; transform: scale(.5); transition: opacity .2s, transform .24s var(--ease); }
.sch-row.is-now .sch-node { border-color: var(--fg); background: #171614; transform: scale(1.14); box-shadow: 0 0 0 4px var(--bg), 0 0 0 6px rgba(255, 255, 255, .09); }
/* `is-ok` ist der erledigte Punkt — getrennt von `is-now`. Am Ende klappt
   auch der letzte Schritt zu und steht als gruener Punkt da, wie alle davor. */
.sch-row.is-ok .sch-node { border-color: var(--gruen); background: var(--gruen); }
.sch-row.is-ok .sch-check { opacity: 1; transform: none; }
.sch-body { min-width: 0; }
.sch-head { display: flex; align-items: baseline; gap: 12px; }
.sch-head b { font-size: 15px; font-weight: 560; color: var(--dim); white-space: nowrap; transition: color .3s, font-size .34s var(--ease); }
.sch-row.is-ok .sch-head b { color: var(--mid); }
.sch-row.is-now .sch-head b { font-size: 21px; font-weight: var(--h-weight); font-family: var(--font-h); letter-spacing: -.025em; color: var(--fg); }
/* Der Stand steht NUR am laufenden Schritt. Ist er erledigt, bleibt der Name
   und sonst nichts — sonst haengt an jedem gruenen Punkt noch ein Detail. */
.sch-val { font-family: var(--mono); font-size: 11.5px; font-style: normal; letter-spacing: -.01em; white-space: nowrap; color: var(--fg); opacity: 0; transition: opacity .3s; }
.sch-row.is-now .sch-val { opacity: 1; }
.sch-desc { display: block; overflow: hidden; max-height: 0; opacity: 0; font-size: 13.5px; line-height: 1.45; color: var(--dim); transition: max-height .34s var(--ease), opacity .3s, margin-top .34s var(--ease); }
.sch-row.is-now .sch-desc { max-height: 42px; opacity: 1; margin-top: 5px; }

/* ── Zahlung ──────────────────────────────────────────────────────────────
   Statt drei Absaetzen Text nur noch drei Takte: OutBit — Du — OutBit. Wer
   dran ist, steht als Marke ueber dem Wort; der mittlere Takt ist der einzige
   helle. Man SIEHT die Rollenverteilung, statt sie zu lesen. */
/* Nach unten mehr Luft als nach oben: zum Abschnitt „Historie" soll deutlich
   Abstand sein, sonst laufen Strahl und Kaufliste ineinander. */
.pay { padding: var(--abschnitt) 0 clamp(30px, 4vw, 56px); }
.pay-grid { display: grid; gap: 34px; align-items: center; }
@media (min-width: 900px) { .pay-grid { grid-template-columns: minmax(0, 1fr) minmax(360px, .78fr); gap: 60px; } }
.pay-copy > p { margin-top: 18px; color: var(--dim); font-size: 16px; }

/* ── Letzter Schritt: elf gleiche Bloecke ─────────────────────────────────
   Der Anteil als Bild: zehn Bloecke laufen ohne dich, einer ist deiner. Wer
   dran ist, steht als Marke UEBER seiner Taetigkeit — als ein Satz gelesen
   verschwand „Du" mitten im Text. */
.pay-rail { margin-top: clamp(30px, 4vw, 44px); }
/* Elf Spalten, immer in EINER Reihe — auch am Handy. */
.bahn { display: grid; grid-template-columns: repeat(11, 1fr); gap: 9px; align-items: center; }
/* Die Stuecke sind `<i>`: ohne das stuende Text darin kursiv. */
.seg { height: 12px; border-radius: 4px; background: var(--flaeche-2); font-style: normal; }
.seg.is-du { height: 30px; border-radius: 7px; background: var(--fg); }

.rl-namen { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 22px; }
.rl-namen span { display: grid; gap: 2px; }
.rl-namen b { font-family: var(--font-h); font-size: clamp(13px, 1.25vw, 15px); font-weight: var(--h-weight); letter-spacing: -.025em; color: var(--dim); }
.rl-namen em { font-style: normal; font-size: clamp(12px, 1.15vw, 13.5px); line-height: 1.3; color: var(--dim); text-wrap: balance; }
.rl-namen .is-du { justify-items: center; text-align: center; }
.rl-namen .is-du b { color: var(--fg); }
.rl-namen .is-du em { color: var(--mid); }
.rl-namen .is-nach { justify-items: end; text-align: right; }

/* Der Aufbau in zwei Zuegen: erst stehen elf GLEICHE Bloecke da — die Reihe
   waechst von deiner Stelle nach beiden Seiten hinaus —, dann waechst deiner
   heraus und wird hell. Ein Lauf von links war ein Ladebalken, keine Aussage.
   Jeder Block bringt seine Verzoegerung als `--d` mit. */
.seg { transform: scaleY(.32); opacity: 0; }
.rl.is-an .seg { animation: klotz .34s var(--ease) both; animation-delay: var(--d, 0ms); }
@keyframes klotz { to { transform: scaleY(1); opacity: 1; } }

/* Deiner ist hoeher, sieht anfangs aber genauso flach aus wie die anderen:
   .4 von 30 px sind die 12 px der uebrigen. */
.rl.is-an .seg.is-du { animation: deins .78s var(--ease) both; }
@keyframes deins {
  0%   { opacity: 0; transform: scaleY(.128); background-color: var(--flaeche-2); }
  26%  { opacity: 1; transform: scaleY(.4); background-color: var(--flaeche-2); }
  52%  { transform: scaleY(.4); background-color: var(--flaeche-2); }
  80%  { transform: scaleY(1.04); }
  100% { opacity: 1; transform: scaleY(1); background-color: var(--fg); }
}

/* Ohne Bewegung bleibt sonst stehen, was die Bewegung aufziehen sollte. */
@media (prefers-reduced-motion: reduce) {
  .rl.is-an * { animation: none !important; }
  .seg { transform: none !important; opacity: 1 !important; }
}

.paycard { position: relative; padding: 22px; border: 1px solid var(--line-2); border-radius: var(--r-gross); background: var(--flaeche-2); }
.pc-item { display: flex; align-items: center; gap: 13px; }
.pc-item img { border-radius: 14px; object-fit: cover; }
.pc-item strong { display: block; font-size: 15.5px; font-weight: 600; }
.pc-item small { color: var(--dim); font-size: 12.5px; }
.pc-sum { margin-top: 16px; padding: 14px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); display: grid; gap: 7px; }
.pc-row { display: flex; align-items: baseline; justify-content: space-between; font-size: 14px; }
.pc-row span, .pc-row s { color: var(--dim); }
.pc-row b { font-family: var(--font-h); font-size: 22px; font-weight: var(--h-weight); letter-spacing: -.03em; }
.pc-save em { font-style: normal; font-weight: 560; color: var(--gruen); }
.pc-state { display: grid; margin-top: 15px; font-size: 13px; }
.pc-state span { grid-area: 1 / 1; display: flex; align-items: center; gap: 8px; color: var(--dim); opacity: 0; transition: opacity .28s; }
.pc-state i { width: 7px; height: 7px; border-radius: 50%; background: var(--amber); }
.paycard[data-state="2"] .pc-state i { background: var(--gruen); }
.paycard[data-state="0"] .pc-state .s0,
.paycard[data-state="1"] .pc-state .s1,
.paycard[data-state="2"] .pc-state .s2 { opacity: 1; }
.pc-btn {
  display: grid; width: 100%; height: 50px; margin-top: 13px; border-radius: 999px;
  background: var(--fg); color: #0b0b0a; font-size: 15px; font-weight: 600;
  transition: background-color .2s, transform .12s var(--ease);
}
.pc-btn:active { transform: translateY(1px); }
.pc-btn span { grid-area: 1 / 1; place-self: center; opacity: 0; transition: opacity .22s; }
.paycard[data-state="0"] .pc-btn .s0,
.paycard[data-state="1"] .pc-btn .s1,
.paycard[data-state="2"] .pc-btn .s2 { opacity: 1; }
.paycard[data-state="1"] .pc-btn { background: var(--mid); }
.paycard[data-state="2"] .pc-btn { background: var(--gruen); }
.pc-lock { display: flex; align-items: center; justify-content: center; gap: 7px; margin-top: 13px; font-size: 12.5px; color: var(--dim); }
.pc-lock svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.pc-again { position: absolute; right: 22px; bottom: -30px; font-size: 12.5px; color: var(--dim); opacity: 0; pointer-events: none; transition: opacity .3s; }
.paycard[data-state="2"] .pc-again { opacity: 1; pointer-events: auto; }
.pc-again:hover { color: var(--fg); }

.confetti { position: absolute; z-index: 3; pointer-events: none; }
.confetti i { position: absolute; width: 6px; height: 6px; border-radius: 2px; animation: konf var(--d) var(--ease) var(--delay) forwards; }
@keyframes konf {
  0% { opacity: 1; transform: translate(0, 0) rotate(0); }
  100% { opacity: 0; transform: translate(var(--x), var(--y)) rotate(var(--r)); }
}

/* ── Historie und Export ───────────────────────────────────────────────────
   Was gespeichert wird, steht EINMAL unter der Liste — nicht an einem Kauf und
   am naechsten nicht. Das Menue klappt nach UNTEN auf; der Platz dafuer ist
   reserviert, damit nichts ueber den Inhalt faellt. */
/* Unter dem Knopf steht der reservierte Raum fuers Menue: gerechnet wird der
   Abstand ab dem OFFENEN Menue, denn so sieht man den Abschnitt (der Zeiger
   oeffnet es selbst). */
.arch { padding: var(--abschnitt) 0 clamp(48px, 4vw, 56px); }
/* Das Menue klappt UNTER der Liste auf und darf sie nie verdecken. */
.arch-stage { position: relative; margin-top: clamp(34px, 5vw, 54px); }
.buys-stack { position: relative; width: min(100%, 620px); }
.buys-stack::before, .buys-stack::after {
  content: ""; position: absolute; left: 50%; bottom: -8px; height: 22px;
  border: 1px solid var(--line); border-top: 0; border-radius: 0 0 var(--r-gross) var(--r-gross);
  background: var(--bg2); transform: translateX(-50%);
}
/* Beide Lagen lagen auf 0 — bei Gleichstand gewinnt die spaetere im Markup,
   also ausgerechnet die HINTERSTE, und ihre Flaeche schnitt in die vordere.
   Und der Radius der Karte ist 22 px: schaut eine Lage nur 12 px heraus, ist
   ihre Rundung gekappt und die Seitenkante wirkt schief. */
.buys-stack { isolation: isolate; }
.buys { z-index: 3; }
.buys-stack::before, .buys-stack::after { height: 40px; opacity: 1; border-radius: 0 0 17px 17px; }
.buys-stack::before { z-index: 2; width: calc(100% - 36px); bottom: -14px; background: #111216; border-color: rgba(242, 243, 245, .12); }
.buys-stack::after { z-index: 1; width: calc(100% - 72px); bottom: -28px; background: #0e0f12; border-color: rgba(242, 243, 245, .08); }
.buys { position: relative; padding: 18px; border: 1px solid var(--line-2); border-radius: var(--r-gross); background: var(--flaeche); }
.buys-top { display: flex; align-items: center; justify-content: space-between; padding-bottom: 13px; border-bottom: 1px solid var(--line); font-size: 13.5px; }
.buys-top span:first-child { font-weight: 560; }
.buys-n { display: flex; align-items: center; gap: 7px; color: var(--dim); }
.buys-n i { width: 6px; height: 6px; border-radius: 50%; background: var(--gruen); }
.buy { padding: 14px 0; }
.buy + .buy { border-top: 1px solid var(--line); }
.buy-head { display: flex; align-items: center; gap: 12px; }
.buy-head img { border-radius: 13px; object-fit: cover; }
.buy-t { min-width: 0; }
.buy-t strong { display: block; font-size: 14.5px; font-weight: 560; }
.buy-t small { color: var(--dim); font-size: 12.5px; }
.buy-p { margin-left: auto; font-size: 15px; font-weight: 620; }
.buys-more { padding: 13px 0 0; border-top: 1px solid var(--line); text-align: center; font-size: 13px; color: var(--dim); }


/* Links die Liste, rechts die Belege als Vierfeld, der Knopf mittig unter
   beidem. Zwei je Reihe, gleich breit, gleich hoch: die Haarlinien bilden ein
   Kreuz, weil jede Zelle nur ihre INNERE Kante traegt. */
.ex23 { position: relative; display: grid; gap: 26px; justify-items: center; text-align: center; }
.ex23 .buys-stack { width: 100%; text-align: left; }
.ex23 .expo-fach { display: grid; justify-items: center; gap: 14px; width: 100%; }
.ex23 .expo-raum { justify-items: center; }
.a-sp { width: 100%; }
.a-titel { margin-bottom: 16px; color: var(--mid); font-size: 13px; font-weight: 560; text-align: center; }
.a-feld { display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 1fr; }
.a-zelle {
  display: grid; justify-items: center; align-content: center; gap: 10px;
  padding: 18px 8px; font-size: 12.5px; line-height: 1.3; color: var(--mid); text-align: center;
}
.a-zelle svg { width: 19px; height: 19px; stroke: var(--mid); }
.a-zelle:nth-child(2n) { border-left: 1px solid var(--line); }
.a-zelle:nth-child(n+3) { border-top: 1px solid var(--line); }
@media (min-width: 900px) {
  .ex23 { grid-template-columns: minmax(0, 1.5fr) minmax(232px, .5fr); gap: 30px clamp(28px, 3vw, 46px); align-items: start; justify-items: stretch; text-align: left; }
  /* Rand plus Polster der Karte: so steht der Titel auf einer Linie mit
     „Deine Kaeufe" statt darueber. */
  .a-sp { padding-top: 19px; }
  .ex23 .expo-fach { grid-column: 1 / -1; margin-top: clamp(20px, 2.4vw, 34px); }
}
@media (max-width: 899px) {
  .ex23 { gap: 32px; }
  .a-sp { margin-top: 12px; }
  .a-feld { width: min(100%, 420px); margin-inline: auto; }
}

/* Bausteine der Buehne. */
/* Der Mauszeiger faehrt einmal selbst zum Knopf und drueckt — er ZEIGT die
   Handlung, statt sie zu behaupten. Sein ausdruecklicher Wunsch. */
.expo-cur { position: absolute; left: 0; top: 0; z-index: 6; width: 22px; height: 22px; opacity: 0; pointer-events: none; transform: translate(-40px, 40px); transition: opacity .3s, transform .85s var(--ease); }
.expo-cur svg { width: 100%; height: 100%; fill: #f2f3f5; stroke: #0a0a0b; stroke-width: 1.1; stroke-linejoin: round; }
.is-cursor .expo-cur { opacity: 1; transform: translate(var(--cx), var(--cy)); }
.is-press .expo-cur { transform: translate(var(--cx), var(--cy)) scale(.84); transition: transform .12s; }
.expo-menu { display: grid; gap: 2px; width: 100%; max-width: 320px; padding: 7px; border: 1px solid var(--line-2); border-radius: var(--r); background: var(--bg2); }
.expo-item { position: relative; display: flex; align-items: center; gap: 11px; width: 100%; padding: 10px 11px; border-radius: 12px; text-align: left; transition: background-color .18s, transform .15s; }
.expo-item:hover { background: var(--flaeche-2); }
.expo-item:active { transform: scale(.985); }
.expo-ic { width: 17px; height: 17px; flex: 0 0 auto; fill: none; stroke: var(--dim); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.expo-tx { min-width: 0; }
.expo-tx strong { display: block; font-size: 13.5px; font-weight: 560; }
.expo-tx small { font-size: 11.5px; color: var(--dim); }
/* Der Pfeil erscheint beim Zeigen: er sagt, dass die Zeile ein Knopf ist. */
.expo-pf { width: 15px; height: 15px; flex: 0 0 auto; margin-left: auto; fill: none; stroke: var(--dim); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; opacity: 0; transition: opacity .18s, transform .18s; }
.expo-item:hover .expo-pf { opacity: 1; transform: translateX(2px); }
/* Zeichen links und Winkel rechts sind unterschiedlich breit — als reine Reihe
   sass das Wort dadurch sichtbar neben der Mitte. Gleiche Flanken zentrieren es. */
.expo-knopf {
  display: inline-grid; grid-template-columns: 16px auto 16px; place-items: center;
  gap: 9px; height: 44px; padding: 0 18px;
  border: 1px solid var(--line-2); border-radius: 999px; color: var(--mid);
  font-size: 14px; font-weight: 560; transition: background-color .2s, border-color .2s, color .2s;
}
.expo-knopf svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.expo-knopf:hover { color: var(--fg); border-color: rgba(242, 243, 245, .34); background: var(--flaeche); }
/* Offen heisst „gedrueckt", nicht „wichtigster Knopf der Seite" — voll weiss
   haette er die eigentliche Handlungsaufforderung ueberstrahlt. */
.expo-knopf.is-on { color: var(--fg); background: var(--flaeche-2); border-color: rgba(242, 243, 245, .3); }
.expo-kl { width: 8px; height: 8px; border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform .3s var(--ease); }
.expo-knopf.is-on .expo-kl { transform: translateY(1px) rotate(225deg); }

/* Der Raum fuers Menue steht IMMER — offen wie zu gleich hoch. Deshalb
   verschiebt das Oeffnen nichts und verdeckt nichts. */
.expo-raum { display: grid; justify-items: center; width: 100%; }
.expo-raum > * { opacity: 0; transform: translateY(8px); pointer-events: none; transition: opacity .3s, transform .36s var(--ease); }
.is-open .expo-raum > * { opacity: 1; transform: none; pointer-events: auto; }

.expo-fach { display: grid; justify-items: center; gap: 14px; width: min(100%, 620px); }

/* ── Preise ───────────────────────────────────────────────────────────────
   Der meistgewaehlte Plan hebt sich ueber Flaeche, Rand und Hoehe ab — und
   traegt als einziges Element der Seite den Farbakzent der Variante. */
.price { padding: clamp(44px, 5.4vw, 78px) 0 0; }
.plans { display: grid; gap: 16px; margin-top: clamp(26px, 3.6vw, 44px); }
/* Unter den Plaenen der Weg fuer alle, die erst testen wollen: die Anfrage
   laeuft ueber Discord, dort sitzt das Team. */
/* Die Pflichtangabe laeuft in der Preiszeile mit: als eigener Absatz darunter
   war sie ein Block fuer sich, hier ist sie erkennbar und gehoert zur Zahl. */
.plan-price i { color: var(--dim); font-size: 11.5px; font-style: normal; }
.trial { display: grid; justify-items: center; gap: 14px; margin-top: clamp(28px, 3.6vw, 46px); text-align: center; }
.trial p { color: var(--dim); font-size: 15px; }
.plan { position: relative; display: flex; flex-direction: column; padding: 26px; border: 1px solid var(--line); border-radius: var(--r-gross); background: var(--flaeche); }
.plan-top { display: flex; align-items: center; gap: 10px; width: 100%; }
.plan h3 { font-size: clamp(28px, 3.2vw, 37px); line-height: 1; }
.plan-tag { padding: 5px 11px; border-radius: 999px; background: rgba(242, 243, 245, .1); color: var(--fg); font-size: 10px; font-weight: 620; letter-spacing: .05em; text-transform: uppercase; }
.plan-price { display: flex; align-items: baseline; gap: 7px; margin-top: 15px; }
.plan-price b { font-family: var(--font-h); font-size: 38px; font-weight: var(--h-weight); letter-spacing: -.04em; line-height: 1; }
.plan-price small { color: var(--dim); font-size: 13px; }
.plan-profile { margin-top: 11px; color: var(--dim); font-size: 13.5px; line-height: 1.5; }
.plan .btn { width: 100%; margin-top: 20px; height: 46px; }
.plan-mit { display: flex; align-items: center; gap: 8px; width: 100%; margin-top: auto; padding-top: 15px; border-top: 1px solid var(--line); color: var(--dim); font-size: 13px; }
.pm-ic { width: 15px; height: 15px; flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
/* Konten und Verbrauch sind zwei Zonen unter dem Profiltext, gleich abgesetzt. */
.plan-konten, .plan-balken {
  width: 100%; margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line);
}
/* Die Grenzen als Balken: man SIEHT den Unterschied zwischen den Plaenen,
   statt drei Zahlenreihen zu vergleichen. Bezug ist der groesste Plan, damit
   alle drei Karten dieselbe Skala haben. Diese Ordnung ist gesetzt. */
.plan-balken { display: grid; gap: 15px; }
.pb { display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: 5px 10px; }
.pb em { color: var(--dim); font-size: 12.5px; font-style: normal; }
.pb b { font-family: var(--font-h); font-size: 17px; font-weight: var(--h-weight); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.pb i { grid-column: 1 / -1; height: 4px; border-radius: 3px; background: var(--line-2); overflow: hidden; }
.pb i::before { content: ""; display: block; width: calc(var(--f) * 100%); height: 100%; border-radius: 3px; background: var(--mid); }

/* Die Konten sind eine harte Grenze, die man ZAEHLT, kein Verbrauch, den man
   misst: eine Marke je Konto, keine leeren Plaetze daneben. Wird es eng
   (schmale Geraete, zehn Marken), weicht die Pille in die naechste Zeile —
   sonst zerlegt der Umbruch das Wort „Kleinanzeigen-Konten". */
.pk { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.pk em { flex: 0 0 auto; color: var(--dim); font-size: 12.5px; font-style: normal; white-space: nowrap; }
.pk-chip { display: flex; align-items: center; gap: 5px; padding: 5px 11px 5px 8px; border: 1px solid var(--line-2); border-radius: 999px; }
.pk-chip small { color: var(--dim); font-size: 11.5px; }
.pk-chip b { font-family: var(--font-h); font-size: 15px; font-weight: var(--h-weight); letter-spacing: -.02em; line-height: 1; font-variant-numeric: tabular-nums; }
/* Der Rand hat die Farbe der FLAECHE, auf der die Marken liegen, nicht ihre
   eigene: er schneidet sie frei, sonst werden zehn davon eine Raupe. */
.pk-marken { display: flex; flex: 0 0 auto; margin-right: 3px; }
.pk-marken i { width: 11px; height: 11px; border-radius: 50%; background: var(--fg); border: 2px solid var(--flaeche); margin-left: -4px; }
.pk-marken i:first-child { margin-left: 0; }

/* Der eine Farbmoment der Seite. Eingesetzt an genau drei Stellen und nirgends
   flaechig: Balken, Etikett und ein sehr weicher Schein hinter der
   hervorgehobenen Karte. Schein und Tonung sind gegenueber Runde 17 deutlich
   zurueckgenommen — „weniger Glow und weniger gruen". */
.plan.is-top {
  border-color: color-mix(in srgb, var(--akzent) 22%, transparent);
  background:
    radial-gradient(130% 62% at 50% 0%, color-mix(in srgb, var(--akzent) 5%, transparent), transparent 70%),
    var(--flaeche-2);
  box-shadow: 0 0 30px -16px color-mix(in srgb, var(--akzent) 26%, transparent);
}
.plan.is-top .plan-tag { background: color-mix(in srgb, var(--akzent) 14%, transparent); color: var(--akzent); }
.plan.is-top .pb i::before { background: var(--akzent); }
.plan.is-top .pk-marken i { background: var(--akzent); border-color: var(--flaeche-2); }
.plan.is-top .pm-ic { stroke: var(--akzent); }
@media (min-width: 900px) {
  /* Gleich hohe Karten, damit die drei Knoepfe auf einer Linie stehen. Der
     meistgewaehlte waechst symmetrisch nach oben UND unten heraus — der INHALT
     bleibt dabei auf derselben Hoehe, sonst steht sein Knopf ueber den anderen. */
  .plans { grid-template-columns: repeat(3, 1fr); }
  .plan.is-top {
    margin-block: -20px; padding-block: 46px;
    box-shadow: 0 28px 66px rgba(0, 0, 0, .5), 0 0 34px -16px color-mix(in srgb, var(--akzent) 26%, transparent);
  }
}

/* ── Fragen ───────────────────────────────────────────────────────────────
   Beim Laden ist KEINE offen, hoechstens eine gleichzeitig.

   Der Platz unter der Liste ist der der laengsten Antwort und schrumpft um die
   offene (`--faq-rest`, gesetzt in kern.js) — mit DERSELBEN Kurve wie das
   Aufklappen, deshalb ist die Summe immer gleich und nichts darunter
   verschiebt sich. */
.faq { padding: var(--abschnitt) 0 0; }
.faq-list {
  max-width: 760px; margin: clamp(30px, 4vw, 46px) auto 0;
  padding-bottom: var(--faq-rest, 0px); transition: padding-bottom .36s var(--ease);
}
.faq-i { border-bottom: 1px solid var(--line); }
.faq-q { display: flex; align-items: center; gap: 16px; width: 100%; padding: 19px 2px; text-align: left; font-size: 16px; font-weight: 560; transition: color .2s; }
.faq-q:hover { color: var(--mid); }
.faq-q span { flex: 1; }
/* Ein schlanker Haken, der sich dreht — kein eingepackter Kreis. */
.faq-ic { position: relative; width: 14px; height: 14px; flex: 0 0 auto; transition: transform .34s var(--ease); }
.faq-ic::before, .faq-ic::after { content: ""; position: absolute; top: 6px; width: 9px; height: 1.5px; background: var(--dim); border-radius: 1px; transition: background-color .3s; }
.faq-ic::before { left: -1px; transform: rotate(45deg); }
.faq-ic::after { right: -1px; transform: rotate(-45deg); }
.faq-i.is-open .faq-ic { transform: rotate(180deg); }
.faq-i.is-open .faq-ic::before, .faq-i.is-open .faq-ic::after { background: var(--fg); }
.faq-a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .36s var(--ease); }
.faq-i.is-open .faq-a { grid-template-rows: 1fr; }
.faq-a > div { overflow: hidden; }
.faq-a p { padding: 0 46px 22px 2px; color: var(--dim); font-size: 14.5px; line-height: 1.62; }
.faq-a a { color: var(--fg); text-decoration: underline; text-underline-offset: 3px; }

/* ── Abschluss + Fuss ─────────────────────────────────────────────────────
   Ein eigener, klar begrenzter Streifen: KEIN Ausfaedeln nach oben und keines
   in den Fuss. Oben schliesst ihn die Trennlinie ab, unten die Linie des
   Fusses — das Material laeuft von Kante zu Kante und der Abschluss liest sich
   als das, was er ist: die letzte Section, nicht ein Verlauf ins Nichts.
   Deutlich flacher als in Runde 17, sein ausdruecklicher Wunsch. */
/* Ansage und Knopf stehen als EINE Gruppe mittig im Streifen: gleich viel Luft
   ueber der Zeile wie unter dem Knopf. */
.end {
  position: relative; text-align: center;
  --end-luft: clamp(42px, 4.6vw, 62px);
  /* Bewusst TIEFER als die Mitte: genau mittig sass die Gruppe optisch zu hoch. */
  --end-tief: 14px;
  margin-top: clamp(46px, 5vw, 72px);
  padding: calc(var(--end-luft) + var(--end-tief)) 0 calc(var(--end-luft) - var(--end-tief));
}
.end::before {
  content: ""; position: absolute; left: 50%; top: 0; width: 100vw; height: 1px;
  transform: translateX(-50%); background: var(--line);
}
.end h2 { font-size: clamp(29px, 3.7vw, 42px); }
.end .feld { inset: 1px 0 0; mask-image: none; }
.end-in { position: relative; z-index: 1; }
.end-in .btn { margin-top: 20px; }

/* Der Fuss ist ein Fuss, kein Abschnitt: EINE Zeile, Kleingedrucktes darin.
   Die Luft traegt die Zeile selbst, oben wie unten gleich viel — als Hoehe plus
   Aussenrand stand das Kleingedruckte sichtbar zu hoch. */
.foot { padding: 0; }
/* Unten kommt der sichere Bereich dazu: die Seite reicht bis unter die
   schwebende Leiste des Telefons, die letzte Zeile soll aber frei stehen. */
.foot-in { position: relative; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 20px; padding: 15px 0 calc(15px + env(safe-area-inset-bottom, 0px)); }
.foot-in::before {
  content: ""; position: absolute; left: 50%; top: 0; width: 100vw; height: 1px;
  transform: translateX(-50%); background: var(--line);
}
.foot-mark { display: flex; align-items: center; gap: 9px; color: var(--dim); font-size: 12.5px; }
.foot-mark img { width: 18px; height: 18px; border-radius: 6px; opacity: .8; }
.foot-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 22px; }
.foot-links a { color: var(--dim); font-size: 12.5px; transition: color .2s; }
.foot-links a:hover { color: var(--fg); }
.foot-dc { display: grid; place-items: center; width: 28px; height: 28px; border: 1px solid var(--line); border-radius: 50%; transition: border-color .2s; }
.foot-dc:hover { border-color: var(--line-2); }
.foot-dc svg { width: 15px; height: 15px; fill: var(--dim); transition: fill .2s; }
.foot-dc:hover svg { fill: var(--fg); }
/* Umgebrochen und linksbuendig sieht der Fuss aus wie ein Rest; mittig sieht er
   aus wie ein Abschluss. */
@media (max-width: 700px) {
  .foot-in { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 14px; padding: 20px 0 calc(20px + env(safe-area-inset-bottom, 0px)); }
  .foot-links { justify-content: center; }
}

/* ── Rechtsseiten ────────────────────────────────────────────────────────
   Mittig gesetzt wie der Rest der Seite: Kopf, Reiter, Ueberschriften und
   Absaetze stehen zentriert, die Spalte selbst bleibt schmal genug, dass eine
   Zeile am Stueck lesbar ist. Nur Listen und Tabellen laufen linksbuendig -
   eine zentrierte Aufzaehlung hat keine Kante, an der das Auge zaehlt. */
.legal { width: min(100% - 40px, 720px); margin: 0 auto; padding: clamp(80px, 9vw, 120px) 0 var(--abschnitt); text-align: center; }
.legal h1 { font-size: clamp(34px, 5vw, 48px); }
.legal-stand { margin-top: 12px; color: var(--dim); font-size: 13.5px; font-family: var(--mono); }
.legal-nav { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 28px 0 0; }
.legal-nav a { padding: 9px 18px; border-radius: 999px; background: var(--flaeche); color: var(--dim); font-size: 13.5px; transition: background-color .2s, color .2s; }
.legal-nav a:hover { background: var(--flaeche-2); color: var(--mid); }
.legal-nav a.is-on { background: var(--flaeche-2); color: var(--fg); }

.legal-intro { max-width: 62ch; margin: 44px auto 0; padding: 20px 22px; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--flaeche); color: var(--mid); font-size: 14.5px; line-height: 1.7; }

/* Das Verzeichnis ist eine Landkarte, kein Schmuck: zweispaltig, damit sechzehn
   Abschnitte nicht den halben Bildschirm fuellen, bevor der Text beginnt. */
.legal-toc { margin-top: 32px; padding-top: 26px; border-top: 1px solid var(--line); }
.legal-toc ol { list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px 24px; text-align: left; }
.legal-toc a { display: flex; gap: 10px; padding: 7px 10px; margin-left: -10px; border-radius: 9px;
  color: var(--dim); font-size: 13.5px; line-height: 1.45; transition: background-color .18s, color .18s; }
.legal-toc a:hover { background: var(--flaeche); color: var(--fg); }
/* Mono heisst gleich breite Zeichen: 4ch fasst das laengste Label ("§ 16")
   genau, und damit beginnt jeder Eintragstext auf derselben Kante. */
.legal-toc a span { flex: none; min-width: 4ch; color: var(--dim); font-family: var(--mono); font-size: 12px; }

.legal-doc { margin-top: 12px; }
.legal-sec { margin-top: 40px; padding-top: 34px; border-top: 1px solid var(--line); scroll-margin-top: calc(var(--leiste) + 20px); }
.legal-sec h2 { display: flex; justify-content: center; gap: 12px; font-size: 19px; line-height: 1.35; }
.legal-n { flex: none; color: var(--dim); font-family: var(--mono); font-size: 15px; font-weight: 400; }
.legal-sec p { max-width: 62ch; margin: 14px auto 0; color: var(--mid); font-size: 15px; line-height: 1.72; }
.legal-sec a { color: var(--fg); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line-2); }
.legal-sec a:hover { text-decoration-color: currentColor; }
.legal-vorsatz { color: var(--fg) !important; font-weight: 500; }
.legal-sec strong { color: var(--fg); font-weight: 600; }

/* Aufzaehlungen brauchen eine linke Kante - der Block als Ganzes steht mittig. */
.legal-liste { max-width: 62ch; margin: 16px auto 0; display: grid; gap: 10px; padding-left: 0; list-style: none;
  counter-reset: satz; text-align: left; font-size: 15px; }
.legal-liste li { position: relative; padding-left: 2.1em; color: var(--mid); line-height: 1.66; }
ol.legal-liste li { counter-increment: satz; }
ol.legal-liste li::before { content: "(" counter(satz) ")"; position: absolute; left: 0; top: .05em;
  color: var(--dim); font-family: var(--mono); font-size: 12.5px; }
ul.legal-liste li::before { content: ""; position: absolute; left: .55em; top: .72em;
  width: 4px; height: 4px; border-radius: 50%; background: var(--line-2); }

/* Breite Tabellen scrollen in sich selbst - die Seite selbst darf nie waagerecht laufen. */
.legal-tab-huelle { margin-top: 18px; overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r); text-align: left; }
.legal-tab { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.legal-tab th, .legal-tab td { padding: 12px 16px; text-align: left; vertical-align: top; line-height: 1.55; }
.legal-tab th { background: var(--flaeche); color: var(--fg); font-weight: 600; white-space: nowrap; }
.legal-tab td { color: var(--mid); border-top: 1px solid var(--line); }
.legal-tab td:first-child { color: var(--fg); }

.is-legal .foot { padding-top: clamp(40px, 6vw, 70px); }

@media (max-width: 640px) {
  .legal-toc ol { grid-template-columns: 1fr; }
  .legal-tab th, .legal-tab td { padding: 11px 13px; }
}

/* ── Datenschutz-Hinweis ──────────────────────────────────────────────────
   Unten mittig, eine Karte in der Sprache der Kopfleiste. Zentriert ueber
   `margin-inline` statt `translateX(-50%)`: das `transform` gehoert der
   Einblendung. */
.dsh {
  position: fixed; z-index: 50;
  left: 14px; right: 14px; bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  margin-inline: auto; width: fit-content; max-width: 544px;
  display: flex; align-items: center; gap: 16px;
  padding: 12px 12px 12px 18px;
  border: 1px solid var(--line-2); border-radius: var(--r);
  background: color-mix(in srgb, var(--flaeche) 88%, transparent);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .46);
  /* Erst nach dem Hero: der erste Blick gehoert der Ansage, nicht dem Recht. */
  opacity: 0; transform: translateY(14px);
  animation: dsh-rein .5s var(--ease) 1.2s forwards;
}
.dsh p { margin: 0; color: var(--mid); font-size: 14px; line-height: 1.45; }
.dsh a { color: var(--fg); text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
.dsh a:hover { text-decoration-color: var(--dim); }
.dsh .btn { flex: none; }
@keyframes dsh-rein { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .dsh { animation-delay: 0s; animation-duration: 1ms; } }
/* Am Handy ueber die Breite: `fit-content` zoege die Karte auf die schmalste
   Textbreite zusammen, und zwei kurze Zeilen stuenden als Saeule in der Mitte.
   Die 14px Rand stehen oben, hier aendert sich nur die Breite. */
@media (max-width: 560px) {
  .dsh {
    width: auto;
    bottom: calc(14px + env(safe-area-inset-bottom, 0px));
    gap: 12px; padding: 11px 11px 11px 15px;
  }
  .dsh p { font-size: 13.5px; }
}

/* ── Live-Demo ────────────────────────────────────────────────────────────
   Keine Unterseite der Landing, sondern das Dashboard selbst: kein Kopf, kein
   Fuss, kein Fensterrahmen — man ist DRIN. Oben nur ein Band, das sagt, dass
   es eine Demo ist, und zurueckfuehrt. */

/* ── Handy ───────────────────────────────────────────────────────────────
   Alles mittig — auch die Zahlungs-Spalte, der Kopf und der Fuss. */
@media (max-width: 899px) {
  .hero { --hero-luft: clamp(62px, 14vw, 104px); }
  .acts { margin-top: 26px; }
  /* Eine Spur groesser: am Telefon liest sich der Fliesstext sonst wie
     Kleingedrucktes neben den grossen Ueberschriften. */
  .hero-in p { font-size: 17px; }
  .head p, .pay-copy > p { font-size: 16.5px; }
  .fg-l { font-size: 16px; }

  /* Letzter Schritt: kleiner und enger, mit Rand nach links und rechts. */
  .bahn { gap: 6px; }
  .seg { height: 10px; }
  .seg.is-du { height: 24px; }
  .rl-namen { gap: 8px 10px; margin-top: 16px; padding-inline: 10px; }
  .rl-namen b { font-size: 12.5px; }
  .rl-namen em { font-size: 11.5px; line-height: 1.25; }
  .plan-profile { font-size: 14px; }
  .foot-mark, .foot-links a { font-size: 13px; }

  /* Am Handy klebt NUR das Fenster; die Ueberschrift steht im Fluss darueber.
     Sie kommt mit der Luft des Abschnitts herein, steht dicht am Fenster und
     faehrt beim Einrasten hinter die Leistenplatte — danach gehoert der Schirm
     dem Fenster allein. `--luft` zaehlt ab der LEISTE, nicht ab dem Bildrand. */
  section.talk { --luft: 41px; --spur: 132px; min-height: 230vh; scroll-margin-top: var(--leiste); }
  .talk-pin { display: contents; }
  /* Kein eigener Abstand: naeher als die Luft ueber dem Fenster geht nicht,
     ohne dass die Ueberschrift beim Einrasten unter der Leiste hervorschaut —
     ihre Unterkante landet dann genau auf deren Kante. */
  .talk-head { margin-bottom: 0; }
  /* Der Kasten IST der Schirm unter der Leiste, sein Inhalt sitzt mittig darin:
     das Fenster steht damit genau dort, wo es die Polsterung vorher hielt —
     auch dann, wenn es an seine Hoechsthoehe stoesst. */
  .talk-stage {
    position: sticky; top: var(--leiste); height: calc(100svh - var(--leiste));
    align-content: center; gap: 14px;
  }
  /* Was uebrig bleibt, wenn Leiste, Luft, Spur, Rahmen und Abstand (34 px)
     weg sind — die Hoehe des Fensters bleibt damit dieselbe. */
  .chat-screen { height: min(600px, calc(100svh - var(--leiste) - 2 * var(--luft) - var(--spur) - 34px)); }
  .sch {
    min-height: 0; height: var(--spur); padding: 0; overflow: hidden;
    mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  }
  /* Sechs Spuren zu je 58 %: der erste Knoten sitzt bei 29 %, der letzte bei
     319 %. Alles laeuft ueber DENSELBEN Wert --lauf (0..1) — deshalb steht der
     Punkt immer in der Mitte und kann am Ende nicht mehr aus dem Bild laufen. */
  .sch-list {
    grid-template-rows: none; display: flex; flex-wrap: nowrap; align-items: flex-start; padding-top: 20px;
    transform: translateX(calc(50% - 29% - 290% * var(--lauf, 0)));
  }
  .sch-row { flex: 0 0 58%; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 9px; padding: 0 8px; text-align: center; }
  .sch-rail { left: calc(29% + 290% * var(--lauf, 0)); top: 21.5px; width: 11px; height: 11px; border-radius: 50%; background: var(--fg); box-shadow: 0 0 12px 3px rgba(255, 255, 255, .5); }
  .sch-rail i { display: none; }
  .sch-list::before, .sch-list::after { content: ""; position: absolute; left: 29%; top: 25px; height: 3px; border-radius: 3px; pointer-events: none; }
  .sch-list::before { width: 290%; background: var(--line-2); }
  .sch-list::after { width: calc(290% * var(--lauf, 0)); background: var(--fg); z-index: 1; }
  .sch-body { display: flex; flex-direction: column; align-items: center; opacity: .42; transition: opacity .45s var(--ease); }
  .sch-row.is-ok .sch-body { opacity: .7; }
  .sch-row.is-now .sch-body { opacity: 1; }
  .sch-head { flex-direction: column; align-items: center; gap: 4px; }
  .sch-head b { font-size: 14px; }
  .sch-row.is-now .sch-head b { font-size: 18px; }
  .sch-val { margin-left: 0; }
  .sch-desc { display: none; }

  /* Zahlung: Ueberschrift und Strahl mittig, nicht linksbuendig. */
  .pay-copy { text-align: center; }
  .pay-copy > p { margin-inline: auto; max-width: 34ch; }
  .pay-rail { margin-top: 24px; }

  /* Der Platz rechts neben der Antwort kostet hier Zeilen — und jede Zeile
     kostet doppelt, weil der reservierte Platz an der laengsten Antwort haengt. */
  .faq-q { gap: 12px; padding: 17px 2px; font-size: 16px; }
  .faq-a p { padding-right: 8px; font-size: 14.5px; }
  /* Der reservierte Platz IST der Abstand zum Abschluss — er war zusammen mit
     dem Rand fast ein Viertel Schirm. Kuerzere Antworten oben, halber Rand
     hier. */
  .end { margin-top: 22px; }
}
