/* Mia Fabula — Gestaltungssystem der nutzerseitigen Seiten.
 *
 * Die Farb- und Schrift-Token stammen unveraendert aus Website/memoria-landing.html. Wer von
 * der Landingpage in die Anwendung wechselt, soll keinen Bruch sehen.
 *
 * Abgrenzung zu style.css: dort liegt das Werkzeug-Dunkelblau der internen Seiten
 * (Foto-Tagging, Review, Interview). Beide Systeme laufen nebeneinander, weil die internen
 * Seiten fuer laengeres, konzentriertes Arbeiten am Bildschirm gebaut sind und die
 * nutzerseitigen fuer gelegentliche Besuche von Menschen, die oft ueber 70 sind.
 *
 * Daher hier bewusst: 18px/17px Fliesstext-Untergrenze, hohe Kontraste, grosse Klickflaechen.
 * Grundschrift ist Inter (Fliesstext, Labels, Buttons, Formulare). Ueberschriften, Zitate und
 * Preise laufen in Newsreader -- warm und erzaehlerisch, aber mit Gewichten 300/400 und 500 nur
 * fuer Auszeichnungen, nie fett ueber 600. Die Landingpage-Skala (Groessen je Rolle, Desktop und
 * Mobil) steht gesammelt weiter unten bei "Schriftgroessen-Skala".
 */

:root {
  --graphit:     #202524;
  --papier:      #f6f2ea;
  --terrakotta:  #b65f47;
  --messing:     #c39a53;
  --rauchblau:   #647985;

  --bg:          #f6f2ea;
  --surface:     #fcfaf6;
  --surface-alt: #efe9dd;
  --border:      #ded6c6;
  --border-soft: #e8e1d4;

  --fg:          #202524;
  --fg-muted:    #55605b;
  --fg-faint:    #7d867f;

  --band-bg:     #173f3a;
  --band-fg:     #f3efe6;
  --band-muted:  #a8bcb5;
  --band-border: #2b544e;

  --accent:      #a9543d;
  --accent-soft: #f0e2dc;
  --brass-line:  #c39a53;
  --brass-ink:   #8a6b2f;
  --smoke-ink:   #4f626d;
  --focus:       #c39a53;

  /* Tannengruen fuer Zeichnungen auf hellem Grund. Nicht --band-bg wiederverwendet: das ist die
     Flaechenfarbe der Baender und bleibt im dunklen Schema dunkel -- eine Zeichnung darin waere
     dort unsichtbar. Dieses Token hellt stattdessen auf. */
  --zeichen:     #173f3a;

  --ok:          #2f6b4f;
  --ok-bg:       #e4efe6;
  --warn:        #8a6b2f;
  --warn-bg:     #f2e9d5;
  --stop:        #9b3a33;
  --stop-bg:     #f4e2df;

  --serif: "Newsreader", "Iowan Old Style", Georgia, serif;
  --sans:  "Inter", "Segoe UI", system-ui, sans-serif;
  --mono:  "IBM Plex Mono", "Cascadia Mono", Consolas, monospace;

  --content: 1080px;
  --prose: 64ch;
  --radius: 4px;
  --shadow: 0 1px 2px rgba(32, 37, 36, .04), 0 12px 32px -20px rgba(23, 63, 58, .35);

  /* Nur auf der Landingpage genutzt (body.landing), siehe "Liquid Glass" weiter unten. */
  --glass-bg:        rgba(255, 255, 255, .55);
  --glass-border:    rgba(255, 255, 255, .65);
  --glass-highlight: rgba(255, 255, 255, .85);

  /* Abstands-Skala -- ausschliesslich diese sechs Werte fuer vertikale Abstaende zwischen
     Elementen auf der Landingpage. Zwischen zwei Hauptsektionen immer --space-6 (96px Desktop,
     ueber die Media Query unten 64px Mobil), siehe .lp-section. */
  --space-1: .5rem;    /* 8px */
  --space-2: 1rem;     /* 16px */
  --space-3: 1.5rem;   /* 24px */
  --space-4: 2.5rem;   /* 40px */
  --space-5: 4rem;     /* 64px */
  --space-6: 6rem;     /* 96px */

  /* Bewegung: "Seiteumblättern in einem hochwertigen Buch" -- weich auslaufend, nie abrupt.
     Gilt fuer jede Übergangs-/Animationsdauer auf der Landingpage. */
  --ease-book: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-slow:  .9s;
  --dur-mid:   .6s;
  --dur-fast:  .4s;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --zeichen:     #a8bcb5;
    --bg:          #101e1b;
    --surface:     #17302b;
    --surface-alt: #143029;
    --border:      #2b4741;
    --border-soft: #223a35;

    --fg:          #ece7dc;
    --fg-muted:    #a5b1aa;
    --fg-faint:    #7f8c85;

    --band-bg:     #1d3b36;
    --band-fg:     #f1ede4;
    --band-border: #2f5751;

    --accent:      #dc8f74;
    --accent-soft: #33221d;
    --brass-ink:   #d6b273;
    --smoke-ink:   #92a6b1;

    --ok:      #7cc79b;  --ok-bg:   #1a3a2c;
    --warn:    #d6b273;  --warn-bg: #3a3020;
    --stop:    #e79086;  --stop-bg: #3d2320;

    --glass-bg:        rgba(23, 48, 43, .55);
    --glass-border:    rgba(255, 255, 255, .10);
    --glass-highlight: rgba(255, 255, 255, .14);
  }
}

:root[data-theme="dark"] {
  --zeichen:     #a8bcb5;
  --bg:          #101e1b;
  --surface:     #17302b;
  --surface-alt: #143029;
  --border:      #2b4741;
  --border-soft: #223a35;

  --fg:          #ece7dc;
  --fg-muted:    #a5b1aa;
  --fg-faint:    #7f8c85;

  --band-bg:     #1d3b36;
  --band-fg:     #f1ede4;
  --band-border: #2f5751;

  --accent:      #dc8f74;
  --accent-soft: #33221d;
  --brass-ink:   #d6b273;
  --smoke-ink:   #92a6b1;

  --ok:      #7cc79b;  --ok-bg:   #1a3a2c;
  --warn:    #d6b273;  --warn-bg: #3a3020;
  --stop:    #e79086;  --stop-bg: #3d2320;

  --glass-bg:        rgba(23, 48, 43, .55);
  --glass-border:    rgba(255, 255, 255, .10);
  --glass-highlight: rgba(255, 255, 255, .14);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body.memoria {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: 18px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

body.memoria img, body.memoria svg { max-width: 100%; display: block; }

/* Fliesstext-Links tragen sonst Browser-Blau. Bewusst als blankes Element-Selektor (0,0,1) --
   die niedrigste moegliche Spezifitaet, damit jede bestehende Klasse mit eigener Linkfarbe
   (.memnav-step, .entry-menu-trigger, .memfoot-col a, .band--quiet a, .btn, ...) weiterhin
   gewinnt. Das hier ist nur die Grundregel fuer sonst ungestylte Links im Fliesstext
   (Preishinweis, "Verschenken"/"Gutschein einloesen", Rechtstexte). */
a {
  color: var(--accent); text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent);
  text-underline-offset: .15em;
}
a:hover { text-decoration-color: var(--accent); }

/* Browser-eigene Flaechen, die sonst niemand gestaltet, tragen hier bewusst die Markenfarbe statt
   des Browser-Blaus -- ein billiger, aber verlaesslicher Beweis, dass die Seite gebaut wurde. */
::selection { background: var(--accent); color: #fdf7f4; }

:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 2px; }

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--band-bg); color: var(--band-fg); padding: .7rem 1.1rem; z-index: 100;
}
.skip:focus { left: .5rem; top: .5rem; }

/* ---------- Kopfleiste ---------- */

.memnav {
  background: var(--band-bg); color: var(--band-fg);
  border-bottom: 1px solid var(--band-border);
  flex: none;
}
.memnav-inner {
  max-width: var(--content); margin: 0 auto;
  padding: .55rem 1.4rem;
  display: flex; align-items: center; gap: .5rem 1.3rem; flex-wrap: wrap;
}
.memnav-brand {
  font-size: 1rem;
  color: var(--band-fg); text-decoration: none;
  display: flex; align-items: center; gap: .6rem;
}
/* Wortmarke und Untertitel teilen sich eine Grundlinie, das Paar als Ganzes steht mittig zum
   Ringzeichen. Ohne diese eigene Zeile richtete .memnav-brand alles auf baseline aus -- und weil
   das Zeichen hoeher ist als die Schrift, klebte die Wortmarke an der Oberkante des Zeichens
   statt auf der Hoehe der uebrigen Leistenschrift (.memnav-steps, .memnav-who), die mittig steht. */
.memnav-wortmarke { display: flex; align-items: baseline; gap: .6rem; }
.memnav-brand small {
  font-family: var(--mono); font-size: .62rem; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--messing);
}

/* ---------- Wortzeichen: Jahresringe ----------

   Die Ringe stehen in Creme (--band-fg) mit einem einzelnen Messingring, also fest und nicht
   ueber currentColor: das Zeichen erscheint ausschliesslich auf --band-bg (Kopfleiste und Fuss),
   und diese Flaeche bleibt in beiden Farbschemata dunkelgruen. Eine erbende Farbe haette hier
   nichts zu erben, aber eine Datei statt eines eingebetteten SVG spart die ~12 KB auf jeder
   einzelnen Seite.

   align-self: center haelt das Zeichen mittig, wo eine Zeile auf baseline ausgerichtet ist --
   ein Bild hat keine sinnvolle Grundlinie und haengt sonst unter der Schrift. */
.marke-ringe { flex: none; align-self: center; }
.memnav-brand .marke-ringe { width: 36px; height: 36px; }
/* Der Fuss stapelt statt nebeneinanderzustellen: ein 72px-Zeichen neben 1.42rem Schrift saehe
   aus wie ein Bild mit Bildunterschrift, nicht wie eine Marke. */
.memfoot-brand { display: flex; flex-direction: column; align-items: flex-start; gap: .75rem; }
.memfoot-brand .marke-ringe { width: 72px; height: 72px; align-self: flex-start; }
@media (max-width: 640px) {
  .memnav-brand .marke-ringe { width: 30px; height: 30px; }
  .memfoot-brand .marke-ringe { width: 56px; height: 56px; }
}
.memnav-steps { display: flex; gap: .2rem; flex-wrap: wrap; margin-right: auto; }
.memnav-step {
  display: inline-flex; align-items: center; gap: .42rem;
  padding: .3rem .68rem; border-radius: 999px;
  font-size: .82rem; text-decoration: none;
  color: var(--band-muted); border: 1px solid transparent;
}
.memnav-step:hover { color: var(--band-fg); border-color: var(--band-border); }
.memnav-step .n {
  width: 19px; height: 19px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: .66rem;
  border: 1px solid var(--band-border); background: rgba(255,255,255,.05);
}
.memnav-step[aria-current="page"] {
  color: var(--band-fg); border-color: var(--messing); background: rgba(195,154,83,.13);
}
.memnav-step[aria-current="page"] .n { background: var(--messing); border-color: var(--messing); color: #22303a; }
.memnav-step.done { color: var(--band-fg); }
.memnav-step.done .n { background: #2f6b4f; border-color: #2f6b4f; color: #eaf6ee; }
.memnav-step.locked { opacity: .45; pointer-events: none; }
.memnav-who { font-size: .78rem; color: var(--band-muted); display: flex; align-items: center; gap: .7rem; }
.memnav-who a { color: var(--messing); }

/* ---------- Einstiegs-Navigation (Landingpage, in der Kopfleiste) ----------

   Besetzt denselben Platz wie .memnav-steps (layout.py::nav_html, header_extra). Der
   Auslöser bleibt ein normaler Link (direktes Ziel, funktioniert ohne JS und ohne :hover).
   Das Panel klappt zusätzlich auf über :hover (Maus) und :focus-within (Tastatur, Tab auf
   Auslöser oder Panel-Link) -- beides ganz ohne JS. Auf Touch-Geräten greift weder :hover
   noch :focus-within, deshalb kommt pro Menü ein eigener .entry-menu-toggle-Button dazu
   (memoria.js): er navigiert nicht, sondern schaltet nur .entry-menu.is-open um, mit
   aria-expanded/aria-haspopup für Screenreader. Fällt JS aus, bleibt der Auslöser-Link
   trotzdem ein sinnvolles Ziel; das Panel ist dann per Tastatur weiterhin erreichbar, auf
   Touch aber nur über den Auslöser selbst -- kein Rückschritt gegenüber vorher, nur kein
   zusätzlicher Gewinn ohne JS.

   Bewusst zurückhaltender gestaltet als .memnav-brand: das sind Alternativpfade zum
   eigentlichen Weg (Überschrift → Formular), keine gleichrangige Kopfzeile. */

/* Ein Eintrag ist "Wort + Pfeil", nicht "Wort" und daneben ein Knopf. Deshalb traegt die
   Einheit (.entry-menu bzw. der blanke Auslaeser ohne Untermenue) die Polsterung, die Rundung
   und die Hervorhebung -- ihre Teile sind aussen abstandslos. Nur so sind die vier Eintraege
   gleich weit voneinander getrennt: die Luecke kommt allein aus dem gap der Leiste, nicht
   zusaetzlich aus toter Flaeche neben einem Pfeil. */
.entry-nav { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; margin-right: auto; }
.entry-menu { position: relative; display: inline-flex; align-items: center; border-radius: 999px; }
.entry-menu-trigger {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .38rem .7rem; border-radius: 999px;
  font-family: var(--sans); font-size: .86rem; font-weight: 600;
  color: var(--band-muted); text-decoration: none; white-space: nowrap;
}
/* Gleiche Hoehe fuer alle vier Einheiten: die Pfeil-Eintraege sind durch das 44px-Touchziel
   so hoch, der pfeillose Link muss mitziehen -- sonst waeren die Hervorhebungen der vier
   Felder unterschiedlich gross. */
.entry-nav > .entry-menu,
.entry-nav > .entry-menu-trigger { min-height: 44px; }
/* Im Verbund gibt der Text seine rechte Polsterung an den Pfeil ab -- sonst stuende zwischen
   beiden die Summe zweier Innenabstaende. */
.entry-menu > .entry-menu-trigger { padding-right: .18rem; }
.entry-menu-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 .7rem 0 0;   /* rechts das Gegenstueck zur linken Polsterung */
  font-size: .7rem; color: var(--band-muted);
  background: transparent; border: 0; cursor: pointer;
}
.entry-menu-toggle::before { content: "▾"; }
/* Hervorhebung: beim blanken Link auf ihm selbst, beim Verbund auf der ganzen Einheit. */
a.entry-menu-trigger:hover { color: var(--band-fg); background: rgba(195,154,83,.16); }
.entry-menu:hover,
.entry-menu:focus-within,
.entry-menu.is-open { background: rgba(195,154,83,.16); }
.entry-menu:hover > .entry-menu-trigger,
.entry-menu:focus-within > .entry-menu-trigger,
.entry-menu.is-open > .entry-menu-trigger,
.entry-menu:hover > .entry-menu-toggle,
.entry-menu.is-open > .entry-menu-toggle { color: var(--band-fg); background: transparent; }
.entry-menu-panel {
  display: none; flex-direction: column;
  position: absolute; top: 100%; left: 0; margin-top: .3rem; z-index: 20;
  min-width: 230px; padding: .35rem;
  background: var(--glass-bg); color: var(--fg);
  border: 1px solid var(--glass-border); border-radius: var(--radius);
  box-shadow: inset 0 1px 0 var(--glass-highlight), var(--shadow);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
}
/* Hover-Bruecke: ohne sie liegt zwischen Ausloeser und Panel eine Luecke von .3rem, in der der
   Mauszeiger weder ueber .entry-menu (nur so hoch wie der Ausloeser) noch ueber dem Panel steht
   -- :hover faellt in diesem schmalen Streifen weg und das Panel schliesst sich, bevor die
   zweite Ebene erreicht ist. Diese unsichtbare Flaeche gehoert zum Panel (also zu .entry-menu),
   deckt exakt die Luecke ab und haelt :hover beim Uebergang aufrecht. */
.entry-menu-panel::before {
  content: ""; position: absolute; left: 0; right: 0; top: -.3rem; height: .3rem;
}
.entry-menu:hover .entry-menu-panel,
.entry-menu:focus-within .entry-menu-panel,
.entry-menu.is-open .entry-menu-panel { display: flex; }
.entry-menu-panel a {
  padding: .55rem .7rem; border-radius: var(--radius);
  color: inherit; text-decoration: none; font-size: .92rem;
}
.entry-menu-panel a:hover { background: var(--accent-soft); color: var(--accent); }
@media (max-width: 720px) {
  .entry-nav { flex-basis: 100%; order: 3; margin: .3rem 0 0; }
}

/* ---------- Ruhige Fläche + Scroll-Reveal (nur body.landing) ----------

   Vorher lag hier eine mitscrollende "Liquid Glass"-Dekoration (zwei verschwommene Farbflecken,
   die sich beim Scrollen leicht verschoben) -- genau das ist die Ursache des "schmutzigen"
   Verlaufs, den das Redesign beheben soll. Ersetzt durch eine einzige ruhige Cremefläche.
   Sektionswechsel entstehen seitdem durch .lp-section (siehe unten), nicht durch Verlauf.

   Bewegung: ein einziges Muster (Aufblenden + 30px nach oben) für jede Sektion, ausgelöst per
   IntersectionObserver (memoria.js), nie per scroll-Event, und nie zweimal für dasselbe Element.
   Läuft mit --ease-book/--dur-mid ("Buch, das sich umblättert" -- weich auslaufend, 500-900ms).
   prefers-reduced-motion schaltet jede Bewegung ab; die Inhalte bleiben dabei vollständig
   sichtbar (kein "unsichtbar, weil nie ausgelöst"), siehe Media Query unten. */

body.landing { position: relative; background: var(--bg); }

.reveal {
  opacity: 0; transform: translateY(30px);
  transition: opacity var(--dur-mid) var(--ease-book), transform var(--dur-mid) var(--ease-book);
}
.reveal.is-visible { opacity: 1; transform: translateY(0); }

/* Leserichtung links -> rechts bei den vier Prozess-Karten: 100ms Versatz je Karte. Die Karten
   werden gemeinsam sichtbar (eine Zeile), der Versatz kommt daher aus transition-delay, nicht
   aus dem Beobachter selbst. */
.cards-grid .reveal:nth-child(1) { transition-delay: 0ms; }
.cards-grid .reveal:nth-child(2) { transition-delay: 100ms; }
.cards-grid .reveal:nth-child(3) { transition-delay: 200ms; }
.cards-grid .reveal:nth-child(4) { transition-delay: 300ms; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .cards-grid .reveal { opacity: 1; transform: none; transition: none; transition-delay: 0s; }
}

/* ---------- "So funktioniert es"-Karten (Landingpage) ----------

   Terracotta ist Akzentfarbe, keine Flächenfarbe (siehe Farbregel): die Karten sind darum hell
   (--surface) mit dunklem Text, nur der kleine Icon-Kreis trägt noch die Akzentfarbe -- als
   heller Terracotta-Ton mit dunklem Icon, nicht als satte Fläche. Nicht verwechseln mit den
   echten Schritt-Karten im Hub (webui/pages.py::hub) -- die bleiben unveraendert.

   Linksbündig statt zentriert (besser lesbar), alle vier gleichwertig (keine Hervorhebung mehr
   der ersten Karte -- las wie ein hängengebliebener Hover-Zustand), Icon oben links. Die
   Unterkanten stehen jetzt gleich, weil .cards-grid align-items: stretch setzt und die Karte
   selbst height: 100% traegt statt sich an ihrem eigenen Inhalt zu bemessen. */
.step-card--pitch {
  position: relative; z-index: 1; height: 100%;
  background: var(--surface); border: 1px solid var(--border);
  border-top: 1px solid var(--border);
  box-shadow: var(--shadow);
  text-align: left; align-items: flex-start; gap: var(--space-1);
  transition: transform var(--dur-fast) var(--ease-book), border-color var(--dur-fast) var(--ease-book),
              box-shadow var(--dur-fast) var(--ease-book);
}
.step-card--pitch:hover {
  transform: translateY(-4px); border-color: var(--accent);
  box-shadow: 0 8px 20px -14px rgba(23, 63, 58, .35);
}
.step-card--pitch h3 { color: var(--fg); min-width: 0; margin-top: var(--space-1); }
.step-card--pitch p { color: var(--fg-muted); min-width: 0; }
.step-number { color: var(--accent); }
/* Ein duenner, akzentgetoenter Rand haelt den Kreis auch dort sichtbar, wo --accent-soft dem
   Sektionshintergrund optisch zu nahe kommt (--bg und --accent-soft liegen beide sehr hell und
   warmneutral -- ohne Rand ging der Kreis auf Creme fast unter). */
.step-card-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 3rem; height: 3rem; border-radius: 50%;
  background: var(--accent-soft); color: var(--fg);
  border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
  box-shadow: 0 1px 2px rgba(23, 63, 58, .07);
}
.step-card-icon svg { width: 1.6rem; height: 1.6rem; }

/* Die Verbindungslinie zwischen den vier Karten gehoert allein der Landingpage: dort laeuft
   sie durch die Mitte der Icon-Kreise und zeigt den Ablauf als Weg. Im Hub (webui/pages.py::hub)
   teilen die Schrittkarten dasselbe .cards-grid, haben aber keine Kreise -- die Linie zog dort
   quer durch die Kartenkoepfe. Darum haengt sie am Modifier und nicht am Raster. */
@media (min-width: 1001px) {
  .cards-grid--pitch { position: relative; }
  .cards-grid--pitch::before {
    content: ""; position: absolute; z-index: 0;
    left: 12.5%; right: 12.5%; top: 2.85rem; height: 1px;
    background: var(--accent);
  }
}

/* Ueberschrift + Unterzeile vor einem Abschnitt (Landingpage) -- zentriert, damit sie ueber
   einem Raster (Karten) oder einer schmalen Liste (Preise) gleichermassen funktioniert. */
.section-head { text-align: center; max-width: 640px; margin: 0 auto var(--space-5); }
.section-head h2 { margin-bottom: var(--space-1); }
.section-head .lead,
.section-head .price-from { margin: 0 auto; }

/* ---------- "Was uns ausmacht" (Landingpage) ----------

   Bewusst keine Karten: die Prozess-Schritte oben tragen schon die Karten-Form, eine zweite
   Wand aus gleich grossen Boxen waere die naechste "Karten als Seitenstruktur"-Falle. Hier
   traegt die Typografie, das Icon sitzt neben statt ueber der Ueberschrift. */
/* Zeilen richten sich automatisch am jeweils höchsten Element aus (Grid-Standardverhalten);
   der Zeilenabstand ist bewusst deutlich kleiner als der Spaltenabstand. Icon sitzt über statt
   neben der Überschrift, damit Überschrift und Text dieselbe linke Achse teilen. */
.feature-grid {
  display: grid; gap: var(--space-3); grid-template-columns: repeat(2, 1fr);
}
@media (max-width: 720px) { .feature-grid { grid-template-columns: 1fr; } }
/* Leichte Box statt reiner Typografie: die vier Bloecke standen bisher ohne jede Kante frei auf
   der Cremeflaeche und liefen optisch ineinander. Bewusst ruhiger als die Prozess-Karten oben
   (kein Schatten, kein Hover-Lift, kein Schritt-Steg) -- eigener Charakter, nicht dieselbe
   Komponente zweimal. */
.feature {
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--space-3);
  box-shadow: var(--shadow);
}
.feature-icon {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 2.25rem; height: 2.25rem; border-radius: 50%;
  background: var(--accent-soft); color: var(--fg);
  border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
  box-shadow: 0 1px 2px rgba(23, 63, 58, .07);
  margin-bottom: var(--space-2);
}
.feature-icon svg { width: 1.2rem; height: 1.2rem; }
.feature h3 { margin: 0 0 var(--space-1); }
.feature p { margin: 0; color: var(--fg-muted); }

/* ---------- Preiskarten (Landingpage) ----------

   Vier Karten statt einer schmalen Liste: Titel, kurze Zeile, groBe Zahl mit kleinem
   Abrechnungs-Zusatz in Mono, Haekchenliste, ein Knopf. Die empfohlene Stufe
   (.pricing-card--recommended) traegt einen Messing-Rand und ein ueberstehendes Etikett statt
   nur eines helleren Cremetons -- deutlicher sichtbar als vorher, ohne eine zweite Farbe
   einzufuehren. Alle Knoepfe fuehren auf dasselbe Anfrageformular: Mia Fabula verkauft auf dieser
   Seite nichts direkt, die Stufe wird erst bei der Bestellung nach dem Gespraech gewaehlt --
   siehe webui/pages.py::landing, webui/gifts.py fuer den eigentlichen Kaufweg. */
.pricing-grid {
  display: grid; gap: var(--space-3); grid-template-columns: repeat(4, 1fr);
  margin-top: var(--space-5);
}
@media (max-width: 1000px) { .pricing-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px)  { .pricing-grid { grid-template-columns: 1fr; } }
/* Zwei Karten statt vier (siehe pages.py::mehrstimmig). Nicht einfach zwei Zellen des
   Vierer-Rasters leer lassen: zwei Karten auf voller Breite werden so breit, dass die grosse
   Preiszahl im leeren Feld schwimmt. Begrenzte Breite, mittig. */
.pricing-grid--zwei { grid-template-columns: repeat(2, 1fr); max-width: 46rem; margin-inline: auto; }
@media (max-width: 560px) { .pricing-grid--zwei { grid-template-columns: 1fr; } }
/* Der Umfangstext der Stufe, wo die Startseite ihre handgeschriebene Haekchenliste hat.
   flex:1 aus demselben Grund wie dort: sonst sitzen die Knoepfe zweier Karten auf
   verschiedener Hoehe. */
.pricing-card-scope { margin: 0; flex: 1; font-size: .93rem; line-height: 1.5; color: var(--fg-muted); }
.pricing-card {
  position: relative; height: 100%;
  display: flex; flex-direction: column; gap: var(--space-2);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--space-3); box-shadow: var(--shadow);
}
.pricing-card--recommended { border: 2px solid var(--messing); }
.pricing-badge {
  position: absolute; top: -.85rem; left: 50%; transform: translateX(-50%);
  background: var(--graphit); color: var(--papier);
  font-family: var(--sans); font-weight: 600; font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; white-space: nowrap;
  padding: .4em .9em; border-radius: 999px;
}
.pricing-card h3 { margin: var(--space-1) 0 0; }
.pricing-card-desc { margin: 0; color: var(--fg-muted); font-size: .93rem; min-height: 2.6em; }
.pricing-price { margin: 0; display: flex; align-items: baseline; gap: .4rem; }
.pricing-price-num { font-family: var(--serif); font-weight: 500; font-size: 2rem; color: var(--accent); }
.pricing-price-unit { font-family: var(--mono); font-size: .75rem; color: var(--fg-muted); }
.pricing-checklist { list-style: none; margin: 0; padding: 0; flex: 1; display: flex; flex-direction: column; gap: .55rem; }
.pricing-checklist li {
  position: relative; padding-left: 1.6rem;
  font-size: .93rem; line-height: 1.4;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%232f6b4f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 10.5l3.8 3.8L16 6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: 0 .1em; background-size: 1.15rem;
}
.pricing-card .btn { margin-top: var(--space-1); width: 100%; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .pricing-checklist li {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%237cc79b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 10.5l3.8 3.8L16 6'/%3E%3C/svg%3E");
  }
}
:root[data-theme="dark"] .pricing-checklist li {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%237cc79b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 10.5l3.8 3.8L16 6'/%3E%3C/svg%3E");
}

/* ---------- Der andere Weg (Verweisfeld unter dem Preisraster) ----------

   Ein Feld, keine fuenfte Karte: der mehrstimmige Weg unterscheidet sich nicht im Umfang von
   den vier Stufen darueber, sondern darin, wer erzaehlt -- und was anders ist, darf nicht
   aussehen wie mehr vom Gleichen. Vorher war das eine zentrierte Link-Zeile (.pricing-link),
   die unter vier Karten mit Schatten schlicht untergegangen ist.

   Warum diese Mittel und nicht die naechststaerkeren: kein dunkles Band, weil die unmittelbar
   folgende Sektion bereits eines traegt und zwei dunkle Flaechen hintereinander beiden die
   Zaesurwirkung nehmen. Messing statt Terrakotta an der Kante, weil Terrakotta laut DESIGN.md
   nur als Linie Flaeche werden darf und Messing im System ohnehin die Auszeichnungsfarbe ist --
   dieselbe Farbe traegt schon den Rand der empfohlenen Preisstufe. Kein neuer Farbwert, kein
   zweiter Schatten, kein zweiter Radius: alles aus vorhandenen Marken, damit auch nichts an der
   Zwei-Schemata-Regel nachzupflegen ist. */
.path-teaser {
  display: grid; grid-template-columns: 1fr auto; gap: var(--space-3); align-items: center;
  margin-top: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--messing);
  /* Angeschnittene Seite bleibt eckig, damit Linie und Rundung nicht gegeneinander laufen --
     dieselbe Loesung wie bei .note. */
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--space-3);
  box-shadow: var(--shadow);
}
.path-teaser h3 { margin: 0 0 var(--space-2); }
/* Fliesstextgroesse, nicht die .93rem der Kartentexte: das hier ist die Erklaerung des Wegs und
   keine Randnotiz -- 18px-Untergrenze. */
.path-teaser p { margin: 0; max-width: var(--prose); }
.path-teaser .path-teaser-anlaesse { margin-top: var(--space-2); color: var(--fg-muted); }
.path-teaser-aside {
  display: flex; flex-direction: column; gap: var(--space-2); align-items: center;
}
/* Mittig ueber dem Knopf und knapp unter den 2rem der Preiskarten: gross genug, um die Zahl
   aus zwei Metern zu lesen, klein genug, dass das Feld nicht doch als fuenfte Stufe gelesen
   wird. Tabellenziffern wie bei jedem Preis im System. */
.path-teaser-price {
  font-family: var(--serif); font-weight: 500; font-size: 1.75rem;
  color: var(--accent); font-variant-numeric: tabular-nums; white-space: nowrap;
  text-align: center;
}
.path-teaser-aside .btn { white-space: nowrap; }
/* Untereinander, sobald der Text neben dem Knopf zu schmal wuerde. Der Knopf nimmt dann die
   volle Breite -- er ist auf dem Telefon das Bedienelement der ganzen Flaeche. */
@media (max-width: 720px) {
  .path-teaser { grid-template-columns: 1fr; align-items: start; }
  .path-teaser-aside { align-items: stretch; }
  .path-teaser-aside .btn { width: 100%; text-align: center; }
}

/* ---------- Produktseite: Format-Diagramm ----------

   Vier Formate, die in einer Erinnerung zusammenlaufen (siehe pages.py::_format_diagram_html).
   Eingebettetes SVG statt eines Fotos: das ist ein Sachverhalt, keine Szene. Die vier Knoten
   sitzen prozentual in den Ecken, die verbindenden Linien laufen als ein einziges SVG mit
   viewBox 0..100 und preserveAspectRatio="none" darunter -- so bleiben die Linienenden an den
   Knoten, auch wenn der Rahmen nicht quadratisch ist. */
.format-diagram {
  position: relative; aspect-ratio: 16 / 10; max-width: 640px; margin: 0 auto;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius);
}
.format-diagram-lines {
  position: absolute; inset: 0; width: 100%; height: 100%;
  stroke: var(--border); stroke-width: 1;
}
.format-diagram-node {
  position: absolute; z-index: 1;
  display: flex; flex-direction: column; align-items: center; gap: .35rem;
  width: 5.5rem; text-align: center;
  font-family: var(--sans); font-weight: 500; font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--fg-muted);
}
.format-diagram-node--text  { top: 8%;  left: 6%; }
.format-diagram-node--bild  { top: 8%;  right: 6%; }
.format-diagram-node--video { bottom: 8%; left: 6%; }
.format-diagram-node--audio { bottom: 8%; right: 6%; }
.format-diagram-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 3rem; height: 3rem; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);
  color: var(--accent);
}
.format-diagram-icon svg { width: 1.5rem; height: 1.5rem; }
.format-diagram-center {
  position: absolute; z-index: 1; top: 50%; left: 50%; transform: translate(-50%, -50%);
  display: flex; align-items: center; justify-content: center;
  width: 3.6rem; height: 3.6rem; border-radius: 50%;
  background: var(--graphit); color: var(--messing);
  box-shadow: var(--shadow);
}
.format-diagram-center svg { width: 1.6rem; height: 1.6rem; }
.format-diagram-caption { margin: var(--space-3) 0 0; text-align: center; }
.format-diagram-caption strong { display: block; font-family: var(--serif); font-weight: 500; font-size: 1.15rem; color: var(--fg); }
.format-diagram-caption span {
  display: block; margin-top: .3rem;
  font-family: var(--sans); font-weight: 500; font-size: 11px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--fg-faint);
}
@media (max-width: 640px) {
  .format-diagram { aspect-ratio: 3 / 4; }
  .format-diagram-node { width: 4.4rem; font-size: 10px; }
  .format-diagram-icon { width: 2.5rem; height: 2.5rem; }
  .format-diagram-icon svg { width: 1.25rem; height: 1.25rem; }
}

/* ---------- Produktseite: Video-Platzhalter ----------

   Kein Poster-Bild, weil noch keine echte Aufnahme existiert -- ein dunkler Verlauf in
   --band-bg statt eines erfundenen Vorschaubilds, das eine Aufnahme vortaeuschen wuerde, die es
   noch nicht gibt. Die Bildunterschrift sagt das auch in Worten (siehe pages.py::produkt). */
.product-video-frame {
  position: relative; aspect-ratio: 16 / 9; border-radius: var(--radius); overflow: hidden;
  background: linear-gradient(135deg, var(--band-bg), color-mix(in srgb, var(--band-bg) 65%, black));
  box-shadow: var(--shadow);
  display: flex; align-items: center; justify-content: center;
}
.product-video-play {
  display: inline-flex; align-items: center; justify-content: center;
  width: 4.5rem; height: 4.5rem; border-radius: 50%;
  background: var(--accent); color: #fdf7f4;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .25);
}
.product-video-play svg { width: 1.8rem; height: 1.8rem; margin-left: .15rem; }
.product-video-caption { margin-top: var(--space-2); text-align: center; color: var(--fg-muted); font-size: 14px; }

/* ---------- Produktseite: Buch-Doppelseite ----------

   Zwei "Seiten" nebeneinander wie ein aufgeschlagenes Buch, ein 2px-Spalt in --border als
   Buchruecken. Fotoseite mit Streifenmuster statt eines erfundenen Fotos -- klar als
   Platzhalter erkennbar, nicht als vorgetaeuschte Kundenaufnahme. */
.book-demo {
  display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
  max-width: 920px; margin: 0 auto;
  border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow); background: var(--border);
}
@media (max-width: 720px) { .book-demo { grid-template-columns: 1fr; } }
.book-demo-page { background: var(--surface); padding: var(--space-4); display: flex; flex-direction: column; }
.book-demo-page--photo { align-items: center; justify-content: center; gap: var(--space-2); }
.book-demo-photo-placeholder {
  width: 100%; aspect-ratio: 4 / 3; border-radius: calc(var(--radius) - 1px);
  background: repeating-linear-gradient(
    45deg, var(--border-soft), var(--border-soft) 10px, var(--surface-alt) 10px, var(--surface-alt) 20px
  );
}
.book-demo-caption { color: var(--fg-faint); font-size: 14px; }
.book-demo-page--text { justify-content: center; gap: var(--space-2); }
.book-demo-text { font-family: var(--serif); font-style: italic; font-size: 19px; line-height: 1.65; color: var(--fg); }
.book-demo-attrib { color: var(--fg-faint); font-size: 14px; }
.book-demo-qr { align-self: flex-end; color: var(--fg-faint); }
.book-demo-qr svg { width: 2rem; height: 2rem; }

/* ---------- Sektions-Rhythmus (Landingpage) ----------

   Ein Wert für den Abstand zwischen allen Hauptsektionen (--space-6 = 64px), als padding-top
   auf jede Sektion -- so entsteht zwischen je zwei Sektionen immer genau derselbe Zwischenraum,
   unabhängig davon, ob Fragment-Grenze (webui/content/*.html) oder Formular (webui/pages.py)
   dazwischenliegt. Die Hintergrundfarbe wechselt dabei zwischen Creme und Weiß, nie als
   Verlauf, siehe Farbregel. */
/* Sehr feines Papierkorn statt reiner Flat-Farbe -- ein einzelnes, winziges Rauschmuster als
   Hintergrundbild, kachelnd wiederholt. Bewusst kaum wahrnehmbar (Alpha .045): fuer Waerme und
   Tiefe gedacht, nicht als sichtbares Muster. Auf .lp-section statt auf body.landing, damit es
   ueber jeder Sektionsfarbe (Creme oder Weiss) gleich liegt, nicht nur auf einer davon. */
.lp-section {
  padding-top: var(--space-6);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0.114 0 0 0 0 0.086 0 0 0 0 0.055 0 0 0 0.045 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.lp-section--white { background-color: var(--surface); }
.lp-section--cream  { background-color: var(--bg); }

/* ---------- Signatur-Wasserzeichen und Grafiken im Text ----------

   Ein wiederkehrendes Zeichen, das gross und sehr leise im Kopf einer Sektion liegt. Es kommt
   als CSS-Maske aus einer Datei und wird mit currentColor eingefaerbt: eine einzige Datei fuer
   beliebig viele Stellen, ohne Markup zu wiederholen, und im dunklen Schema faerbt sie sich
   von selbst mit. .signatur--gespiegelt und eine andere Breite genuegen fuer eine zweite
   Verwendung -- im Fuss steht dieselbe Datei kleiner und seitenverkehrt.

   z-index: -1 legt das Zeichen hinter die Ueberschrift. isolation: isolate auf der Sektion
   macht daraus einen eigenen Stapelkontext, damit es nicht zusaetzlich hinter dem
   Sektionshintergrund verschwindet. overflow: hidden schneidet es am rechten Rand an -- das
   ist der editoriale Zug und kein Versehen.

   Deckkraft .1: die Ueberschrift (--fg auf --bg) behaelt damit 11.7:1 im hellen und 12.7:1 im
   dunklen Schema -- gerechnet ueber der vollgedeckten Flaeche des Zeichens, also im
   unguenstigsten Fall. WCAG AA verlangt 4.5:1, AAA 7:1; beides bleibt eingehalten. */
.lp-section--signatur { position: relative; isolation: isolate; overflow: hidden; }
.signatur {
  position: absolute; z-index: -1; pointer-events: none;
  background-color: var(--zeichen); opacity: .1;
  -webkit-mask: url("/static/img/zwiegespraech.svg") no-repeat center / contain;
  mask: url("/static/img/zwiegespraech.svg") no-repeat center / contain;
}
.signatur--kopf {
  top: calc(var(--space-4) * -1); right: -3.5rem;
  width: clamp(220px, 26vw, 320px); aspect-ratio: 120 / 100;
}
.signatur--gespiegelt { transform: scaleX(-1); }
/* Dieselbe Datei im Fuss: kleiner, seitenverkehrt und links angeschnitten. Auf dem dunkelgruenen
   Band traegt sie --band-fg statt --zeichen, sonst verschwaende sie darin. */
.signatur--fuss {
  bottom: calc(var(--space-4) * -1); left: -2.5rem;
  width: clamp(180px, 20vw, 260px); aspect-ratio: 120 / 100;
  background-color: var(--band-fg); opacity: .07;
}

/* Grafiken im Fliesstext: grosszuegiger Weissraum ringsum, moderate Groesse. Die Zeichnungen
   stehen dort inline im HTML und nicht als <img>, weil sie zwei Farben tragen und die gruene
   davon aus currentColor kommt -- eine ueber <img> geladene Datei kaeme nicht an die
   CSS-Variablen der Seite und stuende im dunklen Schema falsch. */
.lp-figur { margin: 0; color: var(--zeichen); }
.lp-figur svg { display: block; width: 100%; height: auto; }
.lp-figur--trenner {
  width: min(100%, 320px); margin: var(--space-6) auto;
}
.lp-figur--umflossen {
  float: right; width: clamp(120px, 18vw, 180px);
  margin: 0 0 var(--space-3) var(--space-4);
}

@media (max-width: 720px) {
  /* Auf schmalen Schirmen wuerde das Wasserzeichen unter der Ueberschrift stehen statt hinter
     ihr, und die umflossene Grafik liesse dem Text eine Spalte von wenigen Zeichen. Beide
     treten zurueck: das Zeichen ganz, die Grafik in die volle Breite ohne Umfluss. */
  .signatur--kopf { display: none; }
  .lp-figur--umflossen {
    float: none; width: min(100%, 150px);
    margin: 0 auto var(--space-3);
  }
}
.lp-section--last   { padding-bottom: var(--space-6); }
/* Kapitel-Marke: ein schmaler Akzentstrich statt eines harten Farbschnitts an jeder
   Sektionsgrenze -- die einzige erlaubte Terracotta-Fläche bleibt eine Linie, nicht eine Box. */
.lp-section::before {
  content: ""; display: block; width: 2.75rem; height: 2px;
  background: var(--accent); margin: 0 auto var(--space-4);
}
@media (max-width: 640px) {
  .lp-section { padding-top: var(--space-5); }
  .lp-section--last { padding-bottom: var(--space-5); }
}

/* ---------- Bildpause (Landingpage) ----------

   Bricht die Folge aus drei reinen Textsektionen (Karten, Was uns ausmacht, Preise) mit einem
   stillen Bildmoment auf -- bewusst ohne Text: hier soll das Bild stehen, nicht wieder eine
   Botschaft. Eine eigene Illustration (inline-SVG, siehe webui/content/landing_top.html) statt
   eines zweiten Fotos -- sie nutzt dieselben CSS-Variablen wie der Rest der Seite und bleibt
   deshalb auch im dunklen Farbschema stimmig, ohne ein zweites Bild pflegen zu muessen. */
.lp-photo-break {
  position: relative; overflow: hidden; height: min(52vh, 440px);
  box-shadow: 0 18px 34px -28px rgba(23, 63, 58, .45), 0 -18px 34px -28px rgba(23, 63, 58, .45);
}
.lp-photo-break img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 28%;
}
.lp-photo-break svg { display: block; width: 100%; height: 100%; }
/* Farbton statt rohem Stockfoto, wie beim Hero: ein leichter Multiply-Zug in --band-bg bindet
   das Foto an die Markenfarbe, statt es unbearbeitet zwischen die Sektionen zu setzen. */
.lp-photo-break::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: var(--band-bg); mix-blend-mode: multiply; opacity: .1;
}
@media (max-width: 640px) { .lp-photo-break { height: min(38vh, 300px); } }

/* ---------- Grundraster ---------- */

.wrap { max-width: var(--content); margin: 0 auto; padding: 0 1.4rem; }
.wrap--narrow { max-width: 760px; }

.page-head { padding: 3rem 0 1.6rem; }

/* ---------- Hero (Landingpage): volles Bild, dunkler Verlauf von links, Text linksbündig ----------

   Kein Kreis mehr (schnitt Gesichter an, wirkte wie ein Platzhalter) und kein Parallax mehr
   (siehe Grenzen des Redesigns) -- das Bild steht still. Lesbarkeit kommt stattdessen aus einem
   Verlauf in --band-bg (dasselbe Dunkelgrün wie die Navigation) von links nach transparent.

   Ladesequenz: Bild zoomt sehr langsam (105% -> 100%, ~1.5s), danach erscheinen Wortmarke,
   Headline (zeilenweise), Fließtext und Button gestaffelt mit ~120ms Versatz -- reine
   CSS-Keyframes mit animation-delay, kein JS: das haelt "sofort sichtbar bei reduced-motion"
   trivial richtig (Media Query unten setzt nur animation:none, nichts kann "vergessen" werden,
   im Gegensatz zu einer JS-Klasse, die nie gesetzt wird). */

.hero--full {
  position: relative; isolation: isolate; overflow: hidden;
  min-height: min(82vh, 700px);
  display: flex; align-items: center;
  padding: var(--space-6) 1.4rem;
}
.hero-bg { position: absolute; inset: 0; overflow: hidden; z-index: -1; }
.hero-bg-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 25%;
  transform-origin: 50% 35%;
  animation: hero-img-in 1.5s var(--ease-book) both;
}
/* Farbton statt rohem Stockfoto: ein sehr leichter Multiply-Zug in --band-bg legt sich über das
   ganze Bild (nicht nur die Leseecke) und bindet das Foto an die Markenfarbe, bevor der eigentliche
   Lese-Verlauf darüber kommt. */
.hero-bg::before {
  content: ""; position: absolute; inset: 0;
  background: var(--band-bg); mix-blend-mode: multiply; opacity: .22;
}
.hero-bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(
    100deg,
    color-mix(in srgb, var(--band-bg) 86%, transparent) 0%,
    color-mix(in srgb, var(--band-bg) 58%, transparent) 34%,
    transparent 64%
  );
}
.hero-content {
  position: relative; z-index: 1;
  max-width: 680px;
}
/* Das Ringzeichen liegt als Wasserzeichen hinter dem Hero-Text: gross genug, dass die
   Jahresringe als Jahresringe zu erkennen sind und nicht als Zielscheibe, und weit genug
   zurueckgenommen, dass die Schrift davor nichts verliert.

   position: absolute nimmt es aus dem Fluss -- in der Zeile stehend haette es bei dieser Groesse
   Eyebrow und Ueberschrift aus dem Bild geschoben. z-index: -1 wirkt innerhalb von .hero-content:
   das ist wegen position: relative + z-index: 1 ein eigener Stapelkontext, das Zeichen liegt also
   hinter der Schrift, aber vor dem Hintergrundbild und kann nicht dahinter verschwinden.

   Es reiht sich weiter vor dem Eyebrow in die gestaffelte Ladesequenz ein (.08s vor dessen .2s).
   Die Ruhe-Deckkraft steht deshalb im to-Zustand von hero-marke-in und nicht als eigene
   Deklaration: eine Animation mit fill both haelt ihren Endzustand fest und wuerde ein hier
   gesetztes opacity ueberschreiben. */
.hero-marke {
  position: absolute; z-index: -1; pointer-events: none;
  left: -1.5rem; top: -2.5rem;
  width: clamp(220px, 32vw, 420px); height: auto; aspect-ratio: 1;
  margin: 0;
  animation: hero-marke-in .9s var(--ease-book) both; animation-delay: .08s;
}
@keyframes hero-marke-in {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: .18; transform: translateY(0); }
}
/* Ohne Bewegung bleibt das Zeichen sichtbar statt unsichtbar: derselbe Endzustand, nur sofort. */
@media (prefers-reduced-motion: reduce) {
  .hero-marke { animation: none; opacity: .18; }
}
.hero-content .eyebrow,
.hero-content .wortmarke { color: var(--band-fg); opacity: .85; animation: hero-rise .7s var(--ease-book) both; animation-delay: .2s; }
/* Buendig mit Ueberschrift und Fliesstext darunter: alle drei sind Bloecke im selben
   Inhaltskasten und beginnen an derselben Kante. Ein Einzug waere hier ein Fehler, deshalb
   steht die Null ausdruecklich da -- geerbte text-indent-Werte gaebe es sonst lautlos. */
.hero-content .wortmarke { margin-left: 0; padding-left: 0; text-indent: 0; }
.hero-content h1 { color: var(--band-fg); overflow: hidden; }
.hero-content h1 .line {
  display: block; opacity: 0; transform: translateY(100%);
  animation: hero-line-in .7s var(--ease-book) both;
}
.hero-content h1 .line:nth-child(1) { animation-delay: .35s; }
.hero-content h1 .line:nth-child(2) { animation-delay: .5s; }
.hero-content .lead { color: var(--band-fg); opacity: .92; max-width: 46ch; animation: hero-rise .7s var(--ease-book) both; animation-delay: .68s; }
.hero-content .btn { animation: hero-rise .7s var(--ease-book) both; animation-delay: .8s; }

@keyframes hero-img-in {
  from { transform: scale(1.05); }
  to   { transform: scale(1); }
}
@keyframes hero-rise {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes hero-line-in {
  from { opacity: 0; transform: translateY(100%); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (max-width: 640px) {
  .hero--full { min-height: min(78vh, 560px); padding: var(--space-5) 1rem; }
  .hero-bg::after {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--band-bg) 30%, transparent) 0%,
      color-mix(in srgb, var(--band-bg) 88%, transparent) 78%
    );
  }
  .hero-content { max-width: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-bg-img, .hero-marke, .hero-content .eyebrow, .hero-content .wortmarke, .hero-content h1 .line, .hero-content .lead, .hero-content .btn {
    animation: none; opacity: 1; transform: none;
  }
}
.eyebrow {
  font-family: var(--mono); font-size: .68rem; font-weight: 500;
  letter-spacing: .17em; text-transform: uppercase; color: var(--brass-ink);
  margin: 0 0 .9rem;
}

/* ---------- Wortmarke ----------

   "MIA FABULA" steht ueberall in derselben Schreibweise: Serifenschrift (Newsreader) im
   halbfetten Schnitt, in Versalien, massvoll gesperrt. Die Groesse darf der Ort bestimmen --
   Kopfleiste 1rem, Fuss 1.2rem, ueber einer Ueberschrift .95rem --, der Schnitt nie.

   Vorher gab es sie zweimal: Kopfleiste und Fuss schrieben "Mia Fabula" in der Serifenschrift,
   der Hero und fuenf weitere Seiten liehen sich .eyebrow und setzten daraus "MIA FABULA" in der
   Monoschrift. Der Schnitt kommt jetzt aus der Kopfleiste, die Versalien aus dem Eyebrow, und
   beides steht genau hier und nirgends sonst; .memnav-brand und .memfoot-brand setzen nur noch
   ihre Groesse. Ausdruecklich nicht die Monoschrift: die gehoert den Kopfzeilen ueber
   Ueberschriften, nicht der Marke.

   .08em statt der .17em des Eyebrows: Versalien brauchen mehr Luft als gemischter Satz, aber
   eine Serifenschrift traegt die weite Sperrung der Monoschrift nicht -- der Name zerfiele in
   Einzelbuchstaben. */
.wortmarke {
  font-family: var(--serif); font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
}
/* Die Marke als eigene Zeile ueber einer Ueberschrift. Sie traegt .eyebrow ausdruecklich
   NICHT mehr: jene Klasse wird fuer body.landing auf var(--sans)/11px/.2em umgeschaltet und hat
   die Marke damit im Hero zweimal ueberschrieben, obwohl .wortmarke danach steht -- ein
   Selektor mit zwei Klassen schlaegt einen mit einer. Ein Markenzeichen darf nicht an der
   Klasse einer beliebigen Kopfzeile haengen, also haengt es nicht mehr daran.

   Grad 1rem, also derselbe wie .memnav-brand: "derselbe Schnitt wie in der Navi" heisst
   dieselbe Schrift, dasselbes Gewicht, dieselbe Sperrung UND derselbe Grad. Abstand und Farbe
   kommen aus dieser Regel, weil sie frueher von .eyebrow kamen.

   Die Zeile ist ein div und kein p. Das ist der Kern: body.landing p setzt Inter 300/18px und
   schlaegt mit (0,1,2) jede Klassenregel der Marke -- erst .eyebrow, dann das p selbst haben
   die Marke nacheinander ueberschrieben. Ein anderes Element beendet das, ohne dass irgendwo
   Spezifitaet hochgezogen oder !important gesetzt werden muss. */
.wortmarke--zeile {
  display: block; margin: 0 0 .9rem; font-size: 1rem; color: var(--brass-ink);
}
/* Im Fliesstext erbt die Marke den Grad des Absatzes. Versalien bauen bei gleicher Punktzahl
   optisch groesser als gemischter Satz, deshalb hier ein Hauch weniger -- sonst stuende der
   Name als Block in der Zeile statt darin. */
p .wortmarke, li .wortmarke { font-size: .94em; }
body.memoria h1 {
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(2rem, 4.4vw, 2.9rem); line-height: 1.08;
  letter-spacing: -.015em; text-wrap: balance; margin: 0 0 1rem;
}
body.memoria h2 {
  font-family: var(--serif); font-weight: 600; font-size: 1.42rem;
  line-height: 1.24; text-wrap: balance; margin: 0 0 .7rem;
}
body.memoria h3 { font-family: var(--serif); font-weight: 600; font-size: 1.25rem; margin: 0 0 .5rem; }
.lead { font-size: 1.1rem; color: var(--fg-muted); max-width: var(--prose); margin: 0 0 1.2rem; }
body.memoria p { max-width: var(--prose); margin: 0 0 1rem; }
.muted { color: var(--fg-muted); }
.faint { color: var(--fg-faint); font-size: .88rem; }

/* ---------- Schriftgrößen-Skala der Landingpage ----------

   Eine feste Tabelle, ausschließlich diese Werte, Desktop und Mobil (≤640px). Alles hier nur
   body.landing, damit die übrigen Seiten (Hub, Bestellung, Rechtstexte) ihre bestehende
   Typografie behalten -- diese Skala gilt nur für die Landingpage-Rollen unten.

   Rolle                  Desktop  Mobil   Schrift     Gewicht  Zeilenhöhe
   Hero-Headline           64px    40px    Newsreader  300      1.05
   Sektions-Überschrift    40px    30px    Newsreader  400      1.15
   Karten-Titel            22px    20px    Newsreader  400      1.3
   Fließtext                18px    17px    Inter       300      1.65
   Kleintext / Hinweise    14px    14px    Inter       400      1.5
   Eyebrow / Label         11px    11px    Inter       500      1.4, tracking .2em, GROSS */

body.landing .hero-content h1 {
  font-family: var(--serif); font-weight: 300; font-size: 64px; line-height: 1.05;
  letter-spacing: -.01em; margin: 0 0 var(--space-3);
}
body.landing h2 {
  font-family: var(--serif); font-weight: 400; font-size: 40px; line-height: 1.15;
  letter-spacing: normal; margin: 0 0 var(--space-2);
}
body.landing h3 {
  font-family: var(--serif); font-weight: 400; font-size: 22px; line-height: 1.3;
  margin: 0 0 var(--space-1);
}
body.landing p,
body.landing .lead,
body.landing li,
body.landing .btn {
  font-family: var(--sans); font-weight: 300; font-size: 18px; line-height: 1.65;
}
/* Farbe/max-width fuer .lead kommen bewusst weiter unten aus der bestehenden .lead-Regel bzw.
   aus .hero-content .lead -- hier nochmal color zu setzen hatte zuvor mit body.landing .lead
   (0,2,1) die kontextuelle Hero-Farbe .hero-content .lead (0,2,0) ueberstimmt: der Fliesstext
   im Hero wurde dunkel auf dem dunklen Foto gerendert statt hell, praktisch unlesbar. */
/* :not(.band--quiet), sonst gewinnt diese Regel (0,2,1) gegen .band--quiet p (0,1,1) und die
   helle Fliesstextfarbe fuer dunkle Baender ueberschreibt den dunklen Text auf der hellen
   Karte -- exakt derselbe Ueberschreibungs-Fehler wie beim Hero oben, hier fuer Fliesstext
   statt Ueberschrift. */
body.landing .band:not(.band--quiet) p { color: var(--band-muted); }
/* Kartentexte sind Lesestoff, keine Randnotiz -- die Fliesstext-Untergrenze gilt auch hier,
   nur echte Hinweise/Meta-Zeilen fallen auf Kleintext. */
body.landing .faint,
body.landing .field .help,
body.landing .status-line {
  font-family: var(--sans); font-weight: 400; font-size: 14px; line-height: 1.5;
}
/* :not(.wortmarke) nimmt die Marke aus dieser Regel heraus. Sie ist ein Kicker unter vielen,
   die Marke ist es nicht: sie traegt ihren eigenen Schnitt (siehe .wortmarke) und wuerde hier
   sonst in var(--sans) mit 11px landen -- die Regel schlaegt mit (0,2,0) jede Klasse allein.
   Genau daran ist die Marke im Hero vorher in Inter statt in Newsreader gelaufen. */
body.landing .eyebrow:not(.wortmarke),
body.landing .field label,
body.landing .step-number {
  font-family: var(--sans); font-weight: 500; font-size: 11px; line-height: 1.4;
  letter-spacing: .2em; text-transform: uppercase;
}
/* Newsreader 500 nur fuer Auszeichnungen: die Preiszahlen selbst (siehe "Neu fuer ...Preise:
   Newsreader" im Auftrag), nicht ihre Beschreibungstexte -- die bleiben Fliesstext/Kleintext. */
body.landing .price-from {
  font-family: var(--serif); font-weight: 500; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
body.landing .price-from { font-size: 18px; }
@media (max-width: 640px) { body.landing .price-from { font-size: 17px; } }
body.landing .btn { line-height: 1.2; font-weight: 500; }
@media (max-width: 640px) {
  body.landing .hero-content h1 { font-size: 40px; }
  body.landing h2 { font-size: 30px; }
  body.landing h3 { font-size: 20px; }
  body.landing p, body.landing .lead, body.landing li, body.landing .btn { font-size: 17px; }
}

/* ---------- Schrittkarten (Hub) ---------- */

/* Vier Schritte sind eine Abfolge, keine Sammlung: sie gehoeren nebeneinander, damit der
   Weg als Weg lesbar bleibt. Erst wenn das zu eng wird, zwei- und einspaltig. */
.cards-grid {
  display: grid; align-items: stretch;
  gap: var(--space-3); padding-bottom: 0; grid-template-columns: repeat(4, 1fr);
}
@media (max-width: 1000px) { .cards-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px)  { .cards-grid { grid-template-columns: 1fr; } }
.step-card {
  background: var(--surface); border: 1px solid var(--border);
  border-top: 3px solid var(--border); border-radius: var(--radius);
  padding: 1.3rem 1.35rem 1.2rem;
  display: flex; flex-direction: column; gap: .55rem;
  text-decoration: none; color: inherit;
  box-shadow: var(--shadow);
}
a.step-card:hover { border-color: var(--accent); border-top-color: var(--accent); }
.step-card--open   { border-top-color: var(--messing); }
.step-card--done   { border-top-color: var(--ok); }
.step-card--locked { opacity: .62; box-shadow: none; }
.step-card-n {
  font-family: var(--mono); font-size: .68rem; letter-spacing: .15em;
  text-transform: uppercase; color: var(--brass-ink);
}
.step-card h2 { margin: 0; font-size: 1.24rem; }
.step-card p { margin: 0; font-size: .93rem; color: var(--fg-muted); max-width: none; }
/* flex-end statt center: Karten mit Kennzahl haben einen mehrzeiligen Fuss, Karten ohne nur
   eine Zeile. Zentriert schwebte die Pille dort in der Mitte eines hohen Blocks und stand
   damit auf einer anderen Hoehe als bei den uebrigen Schritten. Unten ausgerichtet schliesst
   sie ueberall buendig mit der letzten Textzeile ab -- und die Kartenfuesse stehen
   untereinander auf einer Linie. */
.step-card-foot {
  margin-top: auto; padding-top: .8rem;
  display: flex; align-items: flex-end; justify-content: space-between; gap: .6rem;
}

.pill {
  display: inline-flex; align-items: center; gap: .35rem;
  font-family: var(--mono); font-size: .68rem; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase;
  padding: .16rem .5rem; border-radius: 2px; border: 1px solid; white-space: nowrap;
}
.pill--ok   { color: var(--ok);   background: var(--ok-bg);   border-color: var(--ok); }
.pill--warn { color: var(--warn); background: var(--warn-bg); border-color: var(--warn); }
.pill--stop { color: var(--stop); background: var(--stop-bg); border-color: var(--stop); }
.pill--idle { color: var(--fg-faint); background: transparent; border-color: var(--border); }

/* ---------- Knoepfe ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font: inherit; font-size: 1rem; line-height: 1.2; min-height: 48px;
  padding: .78rem 1.4rem; border-radius: var(--radius);
  border: 1px solid var(--border); background: var(--surface); color: var(--fg);
  text-decoration: none; cursor: pointer; text-align: center;
  transition: border-color var(--dur-fast) var(--ease-book), background var(--dur-fast) var(--ease-book),
              transform .15s var(--ease-book), filter var(--dur-fast) var(--ease-book);
}
.btn:hover { border-color: var(--accent); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
.btn--primary { background: var(--accent); border-color: var(--accent); color: #fdf7f4; font-weight: 700; }
/* Beim Überfahren geringfügig dunkler und angehoben, beim Klicken senkt er sich wieder ab --
   ein echtes Druckgefühl statt eines reinen Farbwechsels. */
.btn--primary:hover { filter: brightness(.93); border-color: var(--accent); transform: translateY(-2px); }
.btn--primary:active { filter: brightness(.86); transform: translateY(0); transition-duration: .1s; }
.btn--band { background: var(--band-bg); border-color: var(--band-bg); color: var(--band-fg); }
.btn--quiet { background: transparent; border-color: var(--fg); color: var(--fg); }
.btn--quiet:hover { border-color: var(--accent); color: var(--accent); }
/* .btn--quiet ist fuer helle Flaechen gebaut (Rahmen/Text in --fg) -- auf .band (dunkelgruen)
   wurde daraus dunkler Rahmen und dunkler Text auf dunklem Grund, praktisch unlesbar. Innerhalb
   von .band auf die helle Randfarbe umschalten. */
.band .btn--quiet { border-color: var(--band-fg); color: var(--band-fg); }
.band .btn--quiet:hover { border-color: var(--accent); color: var(--accent); }
.btn--lg { font-size: 1.08rem; padding: .95rem 1.7rem; }
.btn--sm { font-size: .88rem; padding: .45rem .85rem; min-height: 40px; }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; margin: var(--space-3) 0; }
@media (prefers-reduced-motion: reduce) {
  .btn { transition: none; }
  .btn--primary:hover, .btn--primary:active { transform: none; }
}

/* ---------- Formulare ---------- */

.form { display: flex; flex-direction: column; gap: var(--space-3); max-width: 560px; }
/* Formular und der gruene Kasten darueber (.band) sitzen auf .wrap--narrow, also schon auf
   derselben Achse/Breite -- .form selbst darf sie hier nur nicht per eigenem max-width wieder
   verengen. Kein eigener Sektionswechsel mehr (siehe webui/pages.py::landing): nur ein kleiner
   Abstand zum Kasten, kein Kapitel-Strich, keine 96px-Luecke fuer zwei Teile derselben Aussage. */
body.landing .lp-form-wrap { max-width: 760px; margin: var(--space-4) auto 0; }
body.landing .lp-form-wrap .form { max-width: none; }
.field { display: flex; flex-direction: column; gap: .4rem; }
.field label { font-size: .93rem; font-weight: 700; }
.field .help { font-size: .84rem; color: var(--fg-muted); }
.field input, .field select, .field textarea {
  font: inherit; font-size: 1rem; min-height: 48px;
  padding: .68rem .9rem; border-radius: var(--radius);
  border: 1px solid var(--border); background: var(--surface); color: var(--fg);
  width: 100%;
  transition: border-color var(--dur-fast) var(--ease-book), box-shadow var(--dur-fast) var(--ease-book);
}
.field textarea { min-height: 7rem; }
/* Weich aufblendender Fokusrahmen statt hartem Umschalten: Rahmenfarbe UND ein schmaler
   Terracotta-Schein laufen über dieselbe Übergangsdauer ein. */
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--accent); outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
.field select {
  appearance: none; -webkit-appearance: none;
  padding-right: 2.6rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%2355605b' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 8l4.5 4.5L14.5 8'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .85rem center; background-size: 1.1rem;
}
.field-row { display: grid; gap: var(--space-3); grid-template-columns: 1fr 1fr; }

/* Zustimmungszeile: Kasten und Text nebeneinander, Text umbricht unter sich selbst und
   nicht unter den Kasten. Stand bisher nur in style.css und fehlte damit hier. */
.checkline {
  display: flex; align-items: flex-start; gap: .55rem;
  margin: 0 0 .9rem; max-width: 560px; line-height: 1.45;
}
.checkline input { margin-top: .3rem; flex: none; }
.checkline label { font-size: .92rem; color: var(--fg); }
/* Die Verweise auf die Rechtstexte (pages.py::_verlinke) stehen in kleinerer Schrift mitten
   im Fliesstext einer Pflichtbestaetigung. Der globale Unterstrich bei 45 % Deckung ist dort
   zu leise: wer bestaetigen soll, etwas gelesen zu haben, muss sehen, wo es steht. */
.checkline label a { text-decoration-color: currentColor; }
@media (max-width: 620px) { .field-row { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) {
  .field input, .field select, .field textarea { transition: none; }
}

/* ---------- Anmelde-Karte (webui/pages.py::_signup_card) ----------

   Vorher ein freistehendes Formular ohne Rahmen oder Schatten -- neben den uebrigen, klar
   umrissenen Flaechen der Seite wirkte es wie ein Fremdkoerper. Jetzt eine einzige Karte: der
   gruene Kopf (dieselbe Farbe wie .band) geht ohne Fuge in die helle Formularflaeche ueber,
   ein gemeinsamer Schatten traegt beides als eine Einheit statt zweier gestapelter Bloecke. */
.signup-card { border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); background: var(--surface); }
.signup-card-head { padding: var(--space-4) var(--space-4) var(--space-3); background: var(--band-bg); }
.signup-card-head h2 { color: var(--band-fg); margin: 0 0 .5rem; }
.signup-card-head p { color: var(--band-muted); margin: 0; }
.signup-card .form { max-width: none; padding: var(--space-4); gap: var(--space-4); }
/* Ohne Meldung nimmt die leere .status-line sonst trotzdem einen vollen Gap-Abstand ein --
   zusammen mit dem Formular-Innenabstand darunter entstand eine auffaellige Leerstelle vor der
   Vertrauenszeile. :empty greift nur, solange kein Text gesetzt ist (memoria.js setzt ihn per
   textContent); sobald eine Meldung erscheint, ist die Zeile nicht mehr leer und wird normal
   sichtbar. */
.signup-card .status-line:empty { display: none; }
/* Serifenschrift der Ueberschriften auch in den Feldbeschriftungen: mono-artige Versalien
   passen zum uebrigen Formularsystem (siehe body.landing .field label), aber innerhalb dieser
   Karte soll die Anmeldung wie ein Teil der ruhigen, warmen Seite wirken, nicht wie ein
   Formular aus einem anderen System. body.landing-Praefix noetig, sonst gewinnt die
   allgemeine Regel per hoeherer Spezifitaet. */
body.landing .signup-card .field label {
  font-family: var(--serif); font-size: 1.02rem; font-weight: 500;
  letter-spacing: 0; text-transform: none;
}
.signup-card .field input, .signup-card .field select {
  min-height: 54px; padding: .85rem 1rem; font-size: 1.05rem;
}
.signup-card .field input:focus, .signup-card .field select:focus {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 26%, transparent);
}
/* Primaerknopf traegt die Entscheidung, der zweite ist nur die Ausweichoption fuer jemanden,
   der schon angefangen hat -- als blanker Text statt als zweiter, fast gleich schwerer Knopf. */
.signup-card .btn-row { align-items: center; }
.signup-card .btn--primary { flex: 1 1 auto; }
.signup-card .btn--quiet {
  background: none; border-color: transparent; min-height: auto; padding: .5rem .3rem;
  color: var(--fg-muted); font-weight: 400;
}
.signup-card .btn--quiet:hover { background: none; border-color: transparent; color: var(--accent); text-decoration: underline; }
.signup-card-trust { margin: 0; padding: 0 var(--space-4) var(--space-4); font-size: .85rem; color: var(--fg-muted); }
@media (max-width: 640px) {
  .signup-card-head, .signup-card .form, .signup-card-trust { padding-left: var(--space-3); padding-right: var(--space-3); }
}
/* Der Chevron ist als Daten-URI eingebettet und kann darum keine CSS-Variable lesen -- im
   Dunkelmodus deshalb eine zweite, helle Fassung derselben Form. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .field select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23a5b1aa' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 8l4.5 4.5L14.5 8'/%3E%3C/svg%3E");
  }
}
:root[data-theme="dark"] .field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23a5b1aa' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 8l4.5 4.5L14.5 8'/%3E%3C/svg%3E");
}

.status-line { font-size: .93rem; color: var(--fg-muted); min-height: 1.4em; }
.status-line.ok { color: var(--ok); }
.status-line.error { color: var(--stop); }

/* ---------- Kaesten ---------- */

.panel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1.3rem 1.4rem; margin: 0 0 1.4rem;
}
.note {
  border-left: 3px solid var(--accent); background: var(--surface);
  padding: .95rem 1.15rem; margin: 1.2rem 0; border-radius: 0 var(--radius) var(--radius) 0;
  max-width: var(--prose); font-size: .95rem;
}
.note--brass { border-left-color: var(--messing); }
.note--stop  { border-left-color: var(--stop); }
.note-label {
  display: block; margin-bottom: .35rem;
  font-family: var(--mono); font-size: .65rem; font-weight: 600;
  letter-spacing: .13em; text-transform: uppercase; color: var(--accent);
}
.note--brass .note-label { color: var(--brass-ink); }
.note--stop  .note-label { color: var(--stop); }
/* .note ist ein geteiltes Bauteil (auch auf den Werkzeugseiten mit style.css), darum hier nur
   fuer body.landing umgeschaltet: Kicker auf dieselbe gesperrte Versalien-Schrift wie .eyebrow/
   .field label, Fliesstext auf dieselbe Schrift/Groesse/Zeilenhoehe wie der uebrige Body-Text.
   Die farbige Randlinie (.note--brass/--stop) bleibt unangetastet. */
body.landing .note-label {
  font-family: var(--sans); font-weight: 500; font-size: 11px; line-height: 1.4;
  letter-spacing: .2em; text-transform: uppercase;
}
body.landing .note p { font-family: var(--sans); font-weight: 300; font-size: 18px; line-height: 1.65; }

.band {
  background: var(--band-bg); color: var(--band-fg);
  border-radius: var(--radius); padding: var(--space-4) var(--space-4); margin: 0;
  box-shadow: var(--shadow);
}
.band h2, .band h3 { color: var(--band-fg); }
.band p { color: var(--band-muted); }
.band strong { color: var(--band-fg); }

/* ---------- Preisstufen ---------- */

.tiers { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
/* Der Stufenblock auf /produkt-waehlen. .tiers hat keinen Aussenabstand -- ohne diese Regel
   klebten die Karten buendig unter dem gruenen Band. Derselbe Wert wie der Innenabstand des
   Bands, damit die Seite einen Rhythmus behaelt. */
.produktgruppe { margin-top: var(--space-4); }
.tier {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); padding: 1.2rem 1.25rem;
  display: flex; flex-direction: column; gap: .5rem; cursor: pointer;
}
.tier:hover { border-color: var(--accent); }
.tier.selected { border-color: var(--accent); border-width: 2px; background: var(--accent-soft); }
.tier-name { font-family: var(--serif); font-size: 1.16rem; font-weight: 600; }
.tier-price {
  font-family: var(--mono); font-size: 1.35rem; font-weight: 500;
  font-variant-numeric: tabular-nums; color: var(--accent);
}
.tier-scope { font-size: .88rem; color: var(--fg-muted); }
/* Die eine empfohlene Stufe. Bewusst nur Rahmen und Schildchen statt einer Farbflaeche:
   .tier.selected benutzt bereits den weichen Akzenthintergrund fuer "ausgewaehlt", und beides
   zugleich waere an der Kasse nicht mehr auseinanderzuhalten. position: relative traegt das
   Schildchen, das oben auf dem Rahmen sitzt. */
.tier--empfohlen { position: relative; border-color: var(--accent); border-width: 2px; }
.tier-badge {
  position: absolute; top: 0; left: 1.25rem; transform: translateY(-50%);
  background: var(--accent); color: var(--surface);
  border-radius: 999px; padding: .15rem .7rem;
  font-size: .75rem; font-weight: 600; letter-spacing: .02em;
}
.tier input { position: absolute; opacity: 0; pointer-events: none; }
/* Auf /produkt-waehlen ist die Karte selbst der Link -- ohne Radioknopf, weil die Wahl
   dort sofort zur Kasse fuehrt und nichts abzuschicken ist. */
a.tier { text-decoration: none; color: inherit; }

/* Anlassseiten (siehe pages.py::verschenken, _GIFT_OCCASION_INTROS) zeigen keine Preise mehr,
   nur einen Verweis auf die eine Stelle, an der Preise gepflegt werden. */
.pricing-link { font-size: .95rem; }
.pricing-link a { color: var(--accent); font-weight: 500; }
.pricing-link a:hover { text-decoration: underline; }

/* ---------- Tabellen / Listen ---------- */

.tablewrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); margin: 1.2rem 0; }
table { border-collapse: collapse; width: 100%; font-size: .93rem; background: var(--surface); }
thead th {
  background: var(--surface-alt); text-align: left; padding: .65rem .85rem;
  font-family: var(--mono); font-size: .66rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--fg-muted); border-bottom: 1px solid var(--border); white-space: nowrap;
}
tbody td { padding: .62rem .85rem; border-bottom: 1px solid var(--border-soft); vertical-align: top; }
tbody tr:last-child td { border-bottom: 0; }
td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Der Steuerausweis unter dem Gesamtbetrag. Zurueckgenommen, weil der ausgewiesene Anteil
   *im* Betrag darueber steckt und nicht dazukommt -- gleich kraeftig gesetzt laese er sich
   als weitere Forderung lesen. */
tbody tr.row--quiet td { color: var(--fg-muted); font-size: .9em; border-bottom: 0; padding-top: .2rem; padding-bottom: .2rem; }
tbody tr.row--quiet + tr.row--quiet td { padding-top: 0; }

.stack { display: flex; flex-direction: column; gap: .75rem; }
.rowitem {
  display: flex; align-items: center; gap: .8rem; flex-wrap: wrap;
  padding: .8rem .95rem; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--surface);
}
.rowitem .grow { flex: 1; min-width: 12ch; }
.rowitem .who { font-weight: 700; }
.rowitem .meta { font-size: .84rem; color: var(--fg-muted); }

/* ---------- Prueffassung ---------- */

.reader {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 2.2rem 2.4rem; margin: 1.3rem 0;
  max-height: 68vh; overflow-y: auto;
}
.reader h2 { font-size: 1.3rem; margin: 1.9rem 0 .7rem; }
.reader h2:first-child { margin-top: 0; }
.reader p { font-family: var(--serif); font-size: 1.06rem; line-height: 1.72; max-width: 62ch; }
/* Der Belegvermerk unter einem Absatz. Kein Monospace mehr und kein "Quelle: " davor: hier
   stand bis dahin die rohe SEG-Kennung, fuer die beides passte. Jetzt steht dort ein Satz,
   den man lesen kann ("2 Belege aus dem Gespraech"), und der soll wie eine Randnotiz
   aussehen und nicht wie eine Fehlermeldung. Die Kennungen selbst haengen als data-seg am
   Element -- fuer die Redaktion, nicht fuer die erzaehlende Person. */
.reader .seg {
  display: block; margin-top: -.5rem; margin-bottom: 1rem;
  font-size: .72rem; letter-spacing: .02em; color: var(--fg-faint);
}
@media (max-width: 620px) { .reader { padding: 1.3rem 1.2rem; } }

.watermark {
  font-family: var(--mono); font-size: .68rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--warn); border: 1px dashed var(--warn); border-radius: 2px;
  padding: .3rem .6rem; display: inline-block; margin-bottom: 1rem;
}

/* ---------- Auftragsanzeige ---------- */

.job {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  font-size: .9rem; color: var(--fg-muted); margin: .6rem 0;
}
.spinner {
  width: 14px; height: 14px; flex: none; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--accent);
  animation: spin .9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 4s; } }

/* ---------- Fuss ----------

   Dunkelgruen wie die Kopfleiste (--band-bg), nicht mehr eine einzelne graue Zeile auf grauem
   Grund: links das Wortzeichen, daneben die Links in Spalten, darunter eine duenne Trennlinie
   und die Rechtszeile. layout.py::page() baut das fuer alle nutzerseitigen Seiten (nicht nur
   die Landingpage) -- der alte Fuss war ueberall gleich schwach, die neue Fassung darum auch
   ueberall neu. */
footer.memfoot {
  background: var(--band-bg); color: var(--band-muted);
  margin-top: var(--space-6); padding: var(--space-6) 0;
}
.memfoot-top {
  display: flex; flex-wrap: wrap; justify-content: space-between;
  gap: var(--space-5) var(--space-6);
}
.memfoot-brand {
  font-size: 1.2rem; color: var(--band-fg);
}
.memfoot-cols { display: flex; flex-wrap: wrap; gap: var(--space-5) var(--space-6); }
.memfoot-col { display: flex; flex-direction: column; gap: .65rem; min-width: 10rem; }
.memfoot-col a {
  color: var(--band-fg); text-decoration: none; font-size: .95rem;
  transition: color var(--dur-fast) var(--ease-book);
}
.memfoot-col a:hover { color: var(--accent); text-decoration: underline; }
@media (prefers-reduced-motion: reduce) { .memfoot-col a { transition: none; } }

/* ---- Stand auf einen Blick (webui/meter.py) --------------------------------------------- */

.meter {
  display: grid;
  gap: 0;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  border-top: 1px solid var(--border-soft);
}
.meter-row {
  display: block;
  padding: 0.9rem 1rem 1rem 0;
  border-bottom: 1px solid var(--border-soft);
  color: inherit;
  text-decoration: none;
}
a.meter-row:hover { background: var(--surface-alt); }
.meter-label {
  display: block;
  font-size: 0.85rem;
  color: var(--fg-faint);
}
.meter-value {
  display: block;
  font-family: "Newsreader", Georgia, serif;
  font-size: 1.15rem;
  line-height: 1.2;
  margin: 0.2rem 0 0.15rem;
  overflow-wrap: break-word;
}
.meter-detail { display: block; font-size: 0.9rem; }
.meter-row--warn .meter-value { color: var(--accent); }

/* Dieselbe Kennzahl, jetzt im Fuss einer Schrittkarte -- Karten und Bestellstatus sollen wie
   ein System wirken, nicht wie zwei Bauteile. */
.step-card-kpi { display: block; }
.step-card-kpi + .step-card-kpi { margin-top: 0.6rem; }

/* ---- Kostprobe: das kostenlose fertige Ergebnis ------------------------------------------- */

.panel--kostprobe { border-left: 3px solid var(--brass-line); }

/* ---- Offene Kapitel als Platzhalter (statt einer Aufforderung zum Kaufen) ------------------ */

.slots {
  display: grid;
  gap: 0.5rem;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  margin: 1rem 0;
}
.slot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.7rem 0.9rem;
  border: 1px dashed var(--border);
  border-radius: 6px;
  background: transparent;
}
.slot--done { border-style: solid; background: var(--surface); }
.slot-title { font-family: "Newsreader", Georgia, serif; font-size: 1.02rem; }

/* ---- Ruhiges Band (Hinweis auf der Startseite, nicht die Hauptaussage) ---------------------- */

.band--quiet {
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}
.band--quiet h2, .band--quiet h3 { color: var(--fg); }
.band--quiet p { color: var(--fg-muted); }
.band--quiet a { color: var(--accent); }

/* ---- Vertrauens-Zeile (ueber dem Fuss der Landingpage) ----

   Drei nebeneinanderliegende Punkte mit Icon statt einer grauen Liste, die unter dem
   vorangehenden Kasten untergeht. */
.trust-row {
  display: grid; gap: var(--space-4); grid-template-columns: repeat(3, 1fr);
  list-style: none; margin: var(--space-5) 0 0; padding: 0;
}
@media (max-width: 720px) { .trust-row { grid-template-columns: 1fr; gap: var(--space-3); } }
.trust-item {
  display: flex; align-items: flex-start; gap: var(--space-2);
}
.trust-item svg {
  flex: none; width: 1.5rem; height: 1.5rem; margin-top: .1rem; color: var(--accent);
}
.trust-item p { margin: 0; color: var(--fg); font-size: .9rem; min-width: 0; }

/* ---------- Rechtstexte (Datenschutz, Impressum, AGB) ----------

   Ein Rechtstext ist kein Fliesstext: er wird ueberflogen, ueber ein Inhaltsverzeichnis
   angesprungen und abschnittsweise gelesen. Deshalb sichtbare Abschnittsgrenzen, ein
   klebendes Inhaltsverzeichnis auf breiten Schirmen und Listen, die ueberhaupt eine
   Einrueckung haben -- memoria.css setzt sonst nirgends ul/ol. */

.rechtstext { padding-bottom: 3.5rem; }
.rechtstext section { margin: 0 0 2.6rem; scroll-margin-top: 4.5rem; }
.rechtstext section + section { border-top: 1px solid var(--border-soft); padding-top: 2.2rem; }
.rechtstext h2 { margin: 0 0 1rem; }
.rechtstext h3 { margin: 1.8rem 0 .6rem; }
.rechtstext ul, .rechtstext ol {
  max-width: var(--prose); margin: 0 0 1.1rem; padding-left: 1.35rem;
}
.rechtstext li { margin: 0 0 .45rem; }
.rechtstext li > strong { color: var(--fg); }
.rechtstext table th:first-child { width: 30%; }

.ds-toc {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); padding: 1.1rem 1.3rem; margin: 0 0 2.6rem;
}
.ds-toc h2 { font-family: var(--sans); font-size: .95rem; margin: 0 0 .7rem; }
.ds-toc ol {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .25rem .9rem; grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: none; font-size: .92rem;
}
@media (max-width: 620px) { .ds-toc ol { grid-template-columns: 1fr; } }

/* Noch nicht eingetragene Pflichtangaben. Sichtbar markiert statt still im Text versteckt:
   ein Platzhalter, den man beim Ueberfliegen uebersieht, geht mit online. */
.offen {
  font-family: var(--mono); font-size: .8em;
  color: var(--warn); background: var(--warn-bg);
  border: 1px dashed var(--warn); border-radius: 4px; padding: .05em .35em;
}

/* ---------- Stimmentafel auf der Übersicht ----------

   Zwei Spalten, weil eine Feierchronik schnell zwanzig Eingeladene hat: einspaltig schöbe die
   Liste die Bestellstatus-Karte und den Freigabe-Hinweis unter den Bildschirmrand, und man
   müsste an der Übersicht scrollen, um zu sehen, was es zu tun gibt. Die Umbruchschwelle ist
   dieselbe wie bei .cards-grid -- zwei Raster mit verschiedenen Schwellen springen beim
   Verkleinern des Fensters versetzt um und wirken wie ein Fehler. */
.stimmen-grid {
  display: grid; gap: var(--space-2); grid-template-columns: 1fr 1fr;
}
@media (max-width: 560px) { .stimmen-grid { grid-template-columns: 1fr; } }

/* ---------- Kamerapruefung im Gespraech ---------- */
/* Steht vor der ersten Aufnahme eines gefilmten Kapitels (Videoportraet). Die Vorschau ist
   gespiegelt, weil ein ungespiegeltes Selbstbild irritiert -- aufgezeichnet wird ungespiegelt. */
.kamera-vorschau {
  width: 100%; max-width: 34rem; aspect-ratio: 16 / 9;
  border-radius: var(--radius); background: #12110f; object-fit: cover;
  transform: scaleX(-1);
}
.kamera-ampel { font-weight: 600; margin: var(--space-2) 0 .3rem; }
.kamera-ampel--gruen { color: var(--accent); }
.kamera-ampel--gelb { color: var(--fg); }
.kamera-ampel--rot { color: #a8322b; }
.kamera-gruende { margin: 0 auto var(--space-2); padding-left: 1.2rem; max-width: 34rem; text-align: left; }
.kamera-gruende li { margin: .25rem 0; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .kamera-ampel--rot { color: #e0837c; }
}
:root[data-theme="dark"] .kamera-ampel--rot { color: #e0837c; }

/* ---------- Nur fuer Screenreader ----------

   Ein Beschriftungstext, der am Bildschirm nichts zu suchen hat, aber vorgelesen werden muss.
   Bewusst nicht display:none und nicht visibility:hidden -- beides nimmt das Element auch aus
   der Vorlese-Reihenfolge, und dann fehlt die Beschriftung genau dort, wo sie gebraucht wird. */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- Der Begleiter auf der Uebersicht ----------

   Ein Fenster unten rechts, das beim Scrollen stehen bleibt. Das leistet allein
   `position: fixed` -- kein Scroll-Listener, keine Rechnerei, und damit auch nichts, was auf
   einem langsamen Geraet ruckeln koennte.

   z-index 200 liegt ueber allem sonst Vergebenen; der bisherige Hoechstwert war .skip mit 100.
   Der Sprunglink muss aber weiterhin *ueber* dem Fenster liegen, wenn er sichtbar wird --
   sonst verdeckt der Begleiter die erste Station der Tastaturbedienung. Deshalb bekommt .skip
   unten einen hoeheren Wert.

   Die Groessen folgen DESIGN.md: 48px Mindestflaeche fuer alles Anklickbare, 18px Untergrenze
   fuer Text. Die Leserin ist oft ueber siebzig; ein zierliches Sprechblasen-Symbol waere hier
   die falsche Sparsamkeit, deshalb traegt der Knopf ausgeschriebenen Text. */
.mf-chat {
  position: fixed;
  right: var(--space-3);
  bottom: var(--space-3);
  z-index: 200;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
  font-family: var(--sans);
}
.mf-chat[hidden] { display: none; }

.mf-chat-toggle {
  font-family: var(--sans); font-size: 1rem; font-weight: 600;
  min-height: 52px; padding: .8rem 1.4rem;
  border: 1px solid var(--band-bg); border-radius: 26px;
  background: var(--band-bg); color: var(--band-fg);
  cursor: pointer;
  box-shadow: var(--shadow);
}
.mf-chat-toggle:hover { filter: brightness(1.12); }
.mf-chat-toggle-kurz { display: none; }

/* Aufgeklappt bleibt der Knopf als Anker stehen, wird aber schmal: das Fenster hat eine
   eigene Schliessen-Schaltflaeche, und zwei gleich grosse Bedienelemente uebereinander
   erzeugten sonst die Frage, welches davon das Fenster schliesst. */
.mf-chat-toggle[aria-expanded="true"] { min-height: 44px; padding: .55rem 1.1rem; }
.mf-chat-toggle[aria-expanded="true"] .mf-chat-toggle-lang { display: none; }
.mf-chat-toggle[aria-expanded="true"] .mf-chat-toggle-kurz { display: inline; }

.mf-chat-panel {
  display: flex; flex-direction: column; gap: var(--space-1);
  width: min(380px, calc(100vw - 2 * var(--space-3)));
  height: min(560px, calc(100vh - 9rem));
  padding: var(--space-2);
  background: var(--surface); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.mf-chat-panel[hidden] { display: none; }

.mf-chat-kopf { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.mf-chat-kopf h2 { font-family: var(--serif); font-size: 1.15rem; font-weight: 500; margin: 0; }
.mf-chat-zu {
  min-width: 48px; min-height: 48px;
  border: 0; background: transparent; color: var(--fg-muted);
  font-size: 1.6rem; line-height: 1; cursor: pointer;
}
.mf-chat-zu:hover { color: var(--accent); }

/* Der Verlauf ist der einzige Teil, der scrollt -- die Eingabe soll nie aus dem Bild wandern. */
.mf-chat-log {
  flex: 1 1 auto; overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--space-2);
  padding-right: .25rem;
  font-size: 1rem; line-height: 1.5;
}
.mf-chat-gruss { color: var(--fg-muted); margin: 0; }
.mf-chat-zug { margin: 0; padding: .6rem .8rem; border-radius: var(--radius); }
.mf-chat-zug--frage {
  align-self: flex-end; max-width: 85%;
  background: var(--accent-soft); border: 1px solid var(--accent-soft);
}
.mf-chat-zug--antwort {
  background: var(--surface-alt); border: 1px solid var(--border-soft);
}

.mf-chat-status { margin: 0; }

.mf-chat-form { display: flex; gap: .5rem; align-items: flex-end; }
.mf-chat-form textarea {
  flex: 1 1 auto; resize: none;
  font-family: var(--sans); font-size: 1rem; line-height: 1.4;
  padding: .6rem .7rem;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg); color: var(--fg);
}
.mf-chat-form button { flex: none; }

.mf-chat-fuss { margin: 0; font-size: .82rem; color: var(--fg-faint); }

/* Auf schmalen Schirmen als Blatt ueber die volle Breite. Ein 380px-Fenster mit Rand daneben
   laesst auf einem Telefon fuer den Verlauf zu wenig uebrig, und der Rand traegt dort nichts. */
@media (max-width: 640px) {
  .mf-chat { right: 0; bottom: 0; left: 0; align-items: stretch; gap: 0; }
  .mf-chat-toggle { align-self: flex-end; margin: 0 var(--space-2) var(--space-2) 0; }
  .mf-chat-toggle[aria-expanded="true"] { margin-bottom: .4rem; }
  .mf-chat-panel {
    width: 100%; height: min(70vh, 520px);
    border-radius: var(--radius) var(--radius) 0 0;
    border-bottom: 0;
  }
}

/* Der Sprunglink bleibt die erste Station der Tastaturbedienung und muss deshalb ueber dem
   Begleiter liegen, sobald er den Fokus hat. */
.skip:focus { z-index: 300; }

/* -- Kontrollzentrum (Adminansicht) --------------------------------------------------------- */
/* Die Tabelle traegt zwei Zeilen je Schraube: Werte oben, der Zweck darunter ueber die volle
   Breite. Der Zweck ist ein ganzer Satz und in einer schmalen Spalte unlesbar -- und ohne ihn
   ist eine Zahl wie "2700" nicht zu beurteilen. */
.kz-tabelle th[scope="row"] { text-align: left; font-weight: 600; white-space: nowrap; }
.kz-tabelle th[scope="row"] .faint { display: block; font-family: var(--mono); font-size: .66rem; }
.kz-tabelle td { vertical-align: top; }
.kz-tabelle input[type="text"], .kz-tabelle select { width: 100%; min-width: 9rem; }
.kz-tabelle .kz-tat { white-space: nowrap; }
.kz-tabelle .kz-tat .btn { margin-right: .3rem; }
.kz-tabelle .kz-fest { display: block; font-weight: 600; }
.kz-zweck td {
  padding-top: 0; color: var(--fg-muted); font-size: .86rem;
  border-bottom: 1px solid var(--border);
}
