/* ═══════════════════════════════════════════════════════════════════════════
   LBW digital — Stilblatt
   Weiß überwiegt · Nacht ist die Zäsur · Werkgrün ist der einzige Akzent

   ═══ MITTELWEG, 26.08. ════════════════════════════════════════════════════
   Ansage: „die farben vom grünen, aber die eleganz und eckige vom anderen."
   Geblieben ist deshalb die FORM der schwarz-orangen Runde — `border-radius:0`
   ausser bei Punkten und Pillen, kein `box-shadow`, dieselbe Schriftleiter,
   dieselben drei Abstandsstufen, dieselben Scroll-Beobachter in main.js.
   Zurueckgekommen sind die FARBWERTE der gruenen Marke. Keiner davon ist hier
   gemischt worden; jeder steht in 01-marke/MARKENHANDBUCH.html, in
   07-marketing/print/broschuere/ALT-broschuere-vorlage.html oder in der
   Werkgruen-/Tinte-Leiter von 06-software/app/ui-bausteine/ci/tokens.css.

   Gemessen (WCAG 2.1, sRGB, Python; im Browser mit pruefe-kontrast.js belegt):
     #3BA064 auf Weiss       3,28 : 1   Flaechen, Linien, Balken. NIE Text auf Hell.
     #3BA064 auf #F4F6F4     3,02 : 1   ✔ knapp ueber 3 — die Grenze, s. u.
     #3BA064 auf #020C09     6,04 : 1   ✔ derselbe Wert traegt im dunklen Block ALS TEXT
     #007032 auf Weiss       6,24 : 1   ✔ die Textfassung fuer Verweise im Fliesstext
     Weiss auf #005A20       8,46 : 1   ✔ so und nicht anders wird der Knopf gebaut
     #101C15 auf Weiss      17,52 : 1   ✔ Fliesstext
     #4A6153 auf Weiss       6,72 : 1   ✔ Nebentext
     #4A6153 auf #F4F6F4     6,19 : 1   ✔ derselbe Nebentext auf Papier
     #DCE7DE auf #020C09    15,61 : 1   ✔ Text im dunklen Block
     #98AB9F auf #020C09     8,18 : 1   ✔ Nebentext im dunklen Block

   WER HIER EINE FARBE AENDERT, RECHNET SIE NACH. Und misst im Browser erst,
   nachdem `transition: none` gesetzt ist — sonst liest man Zwischenfarben
   (reproduzierbar 1.00, 1.03, 1.05, 1.78; alles Messfehler).

   ═══ EIN AKZENT FUER BEIDE GRUENDE — DAS IST DER TRICK ════════════════════
   Gruen auf Weiss ist tueckisch: der Markenwert Werkgruen #008A4B sieht als
   Flaeche gut aus, traegt aber im dunklen Block als Text nur 4,47 : 1 und
   faellt damit knapp durch AA. #3BA064 (Werk-500 derselben Leiter) liegt
   genau im Fenster, das BEIDE Bedingungen erfuellt: hell genug fuer 3 : 1
   gegen Weiss, dunkel genug fuer 4,5 : 1 gegen Nacht. Deshalb braucht der
   dunkle Block KEINEN eigenen Akzentwert — eine Variable, ein Ton, ueberall.

   ═══ DAS ORANGE DER MARKE BLEIBT DEM ZEICHEN ══════════════════════════════
   #E07C1E gehoert dem Punkt in „digital." und wird hier NICHT als Bedienfarbe
   nachgebaut — die Logodateien entstehen aus 01-marke/corporate-design/
   werkzeug/. Zwei Stellen im Blatt fuehren es trotzdem als KATEGORIE-Farbe
   (Aufmass-Hauptflaeche, GBU-Ampel „mittleres Risiko"): dort ist Gruen keine
   Option, weil daneben schon ein Gruen mit anderer Bedeutung steht. Beide
   Stellen sind unten einzeln begruendet.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* Grundfarben — hell. Jeder Wert steht so im Markenhandbuch („Papier",
     „Tinte", „Grau") oder auf einer Sprosse der Tinte-Leiter aus
     app/ui-bausteine/ci/tokens.css — die Neutralen der gruenen Marke sind
     nicht kaltgrau, sondern minimal gruenstichig (Farbton 158,3°). */
  --w:#FFFFFF;                /* Markenhandbuch „Papier" */
  /* Zurueckgenommen, aber lesbar: 5,18 : 1 auf Weiss, 4,77 : 1 auf Papier.
     Fuer Zustaende, die „geht nicht" sagen sollen, ohne unleserlich zu
     werden (gesperrte Tage im Kalender). Markenhandbuch „Grau". */
  --grau-leise:#63706A;
  --papier:#F4F6F4;           /* Tinte-Leiter ti-50 */
  --linie:#D3DCD6;            /* Tinte-Leiter ti-200 */
  --linie-stark:#B7C6BD;      /* Tinte-Leiter ti-300 — 1,78 : 1, dekorativ */
  --tinte:#101C15;            /* Markenhandbuch „Tinte" — 17,52 : 1 auf Weiss */
  --grau:#4A6153;             /* Tinte-Leiter ti-700 — 6,72 : 1 / 6,19 : 1 */

  /* Zäsur — dunkel. Markenhandbuch „Nacht" und „Panel"; der Textwert ist
     --nebel aus der Broschuerenvorlage, die Linie deren --randlind. */
  --schwarz:#020C09;
  --schwarz-2:#08201A;
  --d-text:#DCE7DE;                    /* 15,61 : 1 auf Nacht */
  --d-grau:#98AB9F;                    /* Tinte-Leiter ti-400 — 8,18 : 1 */
  --d-linie:rgba(143,233,168,.30);     /* Mint 30 % — Broschuere --randlind */

  /* ═══ AKZENT — ZWEI WERTE, UND DER UNTERSCHIED IST EINE REGEL ══════════
     Alle vier Akzentwerte sind Sprossen EINER Leiter, der Werkgruen-Leiter
     aus app/ui-bausteine/ci/tokens.css (Farbton 154,0°, Markenwert #008A4B):
       werk-500 #3BA064  Flaeche
       werk-700 #007032  Text auf Hell
       werk-800 #005A20  Knopf
       werk-900 #004714  gedrueckter Knopf
     Gemessen: #3BA064 auf Weiss 3,28 : 1, auf Papier 3,02 : 1 (reicht fuer
     Flaechen und Linien, NICHT fuer Text auf Hell), auf #020C09 6,04 : 1 —
     im dunklen Block traegt derselbe Wert also auch als Schrift.

     GRUEN IST AUF HELL EINE FLAECHENFARBE, KEINE SCHRIFTFARBE. Knoepfe,
     Striche, Balken, Punkte, Kartenkanten — ja. Ueberschriften, Etiketten,
     Zahlen im Fliesstext — nein. --akzent-text bleibt fuer die wenigen
     Stellen, an denen ein Verweis wirklich Farbe braucht.

     GRENZE, offen benannt: 3,02 : 1 auf --papier ist die knappste Zahl im
     Blatt. Wer --papier je dunkler zieht, prueft diese Paarung zuerst. */
  --akzent:#3BA064;        /* Flächen, Linien, Balken, Punkte, Grafik */
  --akzent-text:#007032;   /* Verweise und Auszeichnung auf Hell — 6,24 : 1 */

  /* ═══ WARUM DER KNOPF EIN EIGENES GRUEN HAT ═════════════════════════════
     Ansage von damals, unveraendert gueltig: „wenn button farbig dann
     schrift weiß". Mit --akzent ist das nicht zu haben — Weiss auf #3BA064
     sind 3,28 : 1, und die Knopfschrift ist 16 px bei Schnitt 600, gilt
     also nicht als gross. Gefordert wären 4,5.

     Zwei Wege gäbe es: die Schrift grösser und fetter machen, bis die
     Ausnahme für grosse Schrift greift (3,0) — dann stünde die Lesbarkeit
     auf „gerade eben zulässig". Oder die FLÄCHE dunkler nehmen.

     Hier die Fläche: #005A20 (werk-800, dieselbe Leiter, derselbe Farbton),
     Weiss darauf 8,46 : 1. ✔ AA mit Luft.

     Die helle Flächenfarbe bleibt unangetastet: Linien, Balken, das Netz im
     Hero und die Markierung im Luftbild tragen weiter --akzent. Ein Knopf
     ist der einzige Ort, an dem Schrift AUF dem Gruen steht. */
  --akzent-knopf:#005A20;
  --akzent-tief:#004714;   /* gedrückter/überfahrener Knopf — werk-900 */
  --akzent-lasur:rgba(59,160,100,.28); /* Textmarker-Streifen unter Wörtern */
  /* Hauchflaeche hinter Hinweisen und belegten Tagen. War als Literal
     #FFEFE8 an sechs Stellen eingestreut, jetzt hier: werk-50 der gruenen
     Leiter. Tinte darauf 16,15 : 1, --akzent-tief darauf 10,13 : 1. */
  --akzent-hauch:#EFF8F1;

  /* Warnfarbe. Bleibt Warnfarbe, wird nie zur Bedienfarbe. */
  --rot:#C0392B;

  /* Schrift — zwei, mehr nicht. Ubuntu ausschliesslich in der Wortmarke. */
  --f:"Geist","Helvetica Neue",Arial,sans-serif;
  --fu:"Ubuntu",var(--f);

  /* ═══ DIE SCHRIFTLEITER — ACHT STUFEN, MEHR GIBT ES NICHT ═══════════════
     Geprüft von `pruefe-schriftleiter.py`: jede `font-size` im Blatt muss
     eine dieser Variablen benutzen. Ein fester Wert daneben ist ein Fehler,
     kein Sonderfall. --fs-zahl liegt bewusst DEUTLICH unter --fs-h2 (nicht
     drei Pixel; das liest niemand als zwei Stufen).
       riese    nur die eine Kennzahl im Hero
       display  nur die h1
       h2       Abschnittsüberschrift — genau eine je Abschnitt
       zahl     Ziffern über kleiner Unterschrift, Schrittnummern
       lead     Lead-Absatz, Zitat, Kartenüberschrift
       body     Fliesstext
       klein    Bildunterschrift, Fussnote, Attrappen-Innenleben
       label    Etikett/Kicker, versal, gesperrt */
  --fs-riese:clamp(2.8rem,5.4vw,4.6rem);
  --fs-display:clamp(2.3rem,4.6vw,4.1rem);
  --fs-h2:clamp(1.7rem,2.9vw,2.55rem);
  --fs-zahl:clamp(1.3rem,1.9vw,1.65rem);
  --fs-lead:clamp(1.06rem,1.3vw,1.28rem);
  --fs-body:1rem;
  --fs-klein:.8125rem;
  --fs-label:.6875rem;

  /* ═══ DREI ABSTANDSSTUFEN, MEHR NICHT ═══════════════════════════════════
     Die alte Seite hatte vierzehn verschiedene senkrechte Abstaende zwischen
     11 und 48 px. Das war die Beanstandung „keine gigantische abstände".
     Hier gibt es drei, und sie heissen nach ihrer Rolle. */
  --a-gross:44px;   /* zwischen Bloecken innerhalb eines Abschnitts */
  --a-mittel:32px;  /* zwischen Ueberschrift und Text, zwischen Karten */
  --a-klein:16px;   /* innerhalb eines Blocks */

  /* Raster */
  --rand:clamp(20px,5vw,72px);
  --mass:1240px;    /* aeussere Breite */
  --text:720px;     /* DIE Textachse. Jeder Fliesstext haengt hier. */
  --sekt:clamp(72px,8.5vw,132px);   /* Abschnittsluft oben und unten */
}

/* ── Grundlage ────────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
}
body{
  margin:0;background:var(--w);color:var(--tinte);
  font-family:var(--f);font-size:var(--fs-body);font-weight:400;
  line-height:1.65;letter-spacing:-.005em;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
img,svg{max-width:100%}
/* height:auto ist Pflicht, sobald ein <img> width/height traegt — sonst
   streckt der Browser das Bild auf die Attributhoehe. Einmal gemessen:
   210 x 896 statt 210 x 183. */
img{height:auto;display:block}
h1,h2,h3,h4{margin:0;font-weight:600;letter-spacing:-.025em;line-height:1.1}
p{margin:0}
ul,ol{margin:0;padding:0;list-style:none}
a{color:inherit}

/* Sprungmarke fuer die Tastatur */
.skip{position:absolute;left:-9999px;top:0;z-index:200}
.skip:focus{left:var(--rand);top:12px;background:var(--akzent-knopf);color:#fff;
  padding:10px 16px;border-radius:0;font-size:var(--fs-klein);font-weight:600}

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

/* ── Breiten ──────────────────────────────────────────────────────────────── */
.wrap{max-width:var(--mass);margin-inline:auto;padding-inline:var(--rand)}
/* EINE Textachse. Die alte Seite hatte drei Bloecke in drei Breiten — die
   Beanstandung „der text links bündig" war in Wahrheit eine Achsenfrage. */
.schmal{max-width:var(--text)}

/* ── Abschnittsbänder ─────────────────────────────────────────────────────── */
.band{padding-block:var(--sekt);position:relative}
.band--papier{background:var(--papier)}
.band--dunkel{background:var(--schwarz);color:var(--d-text)}

/* ═══ DAS TOPO-MUSTER ══════════════════════════════════════════════════════
   EINE Datei für beide Richtungen: `assets/img/topo.webp` ist eine
   Graustufen-Zeichnung — weisse Höhenlinien auf schwarzem Grund, aus der
   Marken-Textur (01-marke/muster/textur-topo.jpg) erzeugt und entfärbt.

   Auf DUNKEL wird sie mit `screen` aufgelegt: Schwarz bleibt schwarz, die
   Linien hellen auf.
   Auf HELL wird sie erst invertiert und dann mit `multiply` aufgelegt:
   Weiss bleibt weiss, die Linien dunkeln ab.
   Deshalb genügt eine Datei. Zwei wären zwei Wahrheiten — und eine davon
   wäre irgendwann falsch eingefärbt.

   Ohne Alphakanal, weil der bei WebP teuer ist: die Graustufenfassung wiegt
   60 KB, dieselbe Zeichnung mit Alpha wog 120 KB bei gleicher Kantenlänge.

   `pointer-events:none` ist Pflicht — die Ebene liegt über dem Grund, aber
   der Inhalt darüber (`> .wrap { position:relative }`), sonst frisst sie
   jeden Klick. */
/* `footer.fuss`, NICHT `footer`. GEMESSEN am 26.08.: das Kundenzitat in
   #referenz trägt ein <footer> für die Namenszeile. Es erbte dieses
   Pseudoelement, war selbst nicht positioniert — und `inset:0` fand als
   nächsten positionierten Vorfahren `.band > .wrap`. Ergebnis: eine
   Topo-Fläche von 1240 x 1585 px über dem halben Abschnitt, die mitten im
   Inhalt aufhörte. Beanstandet als „grauer kasten, 0 ordnung fürs auge".
   Die Falle steht 700 Zeilen weiter unten schon beschrieben — dort wurde
   nur `background` qualifiziert, dieses Muster nicht. */
.band--dunkel::before,.band--papier::before,footer.fuss::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:url("../img/topo.webp") center/560px repeat;
}
/* ═══ DIE DECKKRAFT IST GEMESSEN, NICHT GESCHAETZT ════════════════════════
   Bei .30 lief das Muster IM BILD quer durch den Fliesstext — der Abschnitt
   war lesbar, aber unruhig, und die orange Flaeche bekam Hoehenlinien.
   Ein Rechner findet das nicht: jede Kontrastmessung liest
   `backgroundColor` und sieht ein Muster ueberhaupt nicht.
   Deshalb hier klein: .09 auf Dunkel, .14 auf Papier (invertiert und
   multipliziert traegt schwaecher). Wer hochsetzt, sieht im Bild nach. */
.band--dunkel::before,footer.fuss::before{mix-blend-mode:screen;opacity:.09}
.band--papier::before{filter:invert(1);mix-blend-mode:multiply;opacity:.14}
/* ═══ `isolation` IST HIER KEIN FEINSCHLIFF ════════════════════════════════
   `mix-blend-mode` mischt gegen den Hintergrund des naechsten
   Stapelkontexts — NICHT gegen das eigene Band. Ohne diese Zeile
   entscheidet also irgendein Vorfahre darueber, wogegen gemischt wird.
   Gemessen: im Standbild-Modus (`?shot=`) legt main.js ein `transform` auf
   <body>, das damit selbst zum Stapelkontext wird — und die Mischung lief
   danach ueber die GANZE Seite. Im Bild war der weisse Hero grau
   ueberzogen. Mit `isolation:isolate` bleibt jede Mischung in ihrem Band. */
.band--dunkel,.band--papier,footer.fuss{isolation:isolate}
.band > .wrap,footer.fuss > .wrap{position:relative}
/* Im Druck ist ein Muster nur Toner. */
@media print{.band--dunkel::before,.band--papier::before,footer.fuss::before{display:none}}
.band--dunkel h1,.band--dunkel h2,.band--dunkel h3{color:var(--d-text)}
.band--eng{padding-block:calc(var(--sekt) * .62)}
/* Trennlinie nur zwischen zwei HELLEN Baendern. Zwischen hell und dunkel
   trennt der Farbwechsel selbst — eine Linie darauf waere Zierrat. */
.band--linie{border-top:1px solid var(--linie)}

/* ── Etikett · Überschrift · Lead ─────────────────────────────────────────── */
.etikett{
  display:block;font-size:var(--fs-label);font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--grau);
  margin-bottom:var(--a-klein);
}
/* Auf Dunkel bleibt das Etikett GRAU. Orange war hier Schriftfarbe —
   genau das, was nicht mehr sein soll. Den Akzent tragen der Strich
   darüber und die Flächen darunter. */
.band--dunkel .etikett{color:var(--d-grau)}
/* stillgelegt: Etiketten sind grau, Punkt. Wer die Klasse wieder ins
   Markup schreibt, sieht dieselbe Farbe wie ohne sie. */
.etikett--akzent{color:var(--grau)}

h2,.h2{font-size:var(--fs-h2)}
.display{font-size:var(--fs-display);font-weight:600;letter-spacing:-.032em;line-height:1.04}
.riese{font-size:var(--fs-riese);font-weight:600;letter-spacing:-.035em;line-height:1}

.lead{font-size:var(--fs-lead);line-height:1.55;color:var(--grau);max-width:var(--text)}
.band--dunkel .lead{color:var(--d-grau)}
.fliess{max-width:var(--text)}
.fliess p + p{margin-top:var(--a-klein)}
.fliess strong{font-weight:600;color:var(--tinte)}
.band--dunkel .fliess strong{color:var(--w)}

/* Der Strich ueber der Ueberschrift. 40 px, 3 px stark, Akzent.
   Das ist der einzige Zierrat auf der ganzen Seite. */
.regel{width:40px;height:3px;background:var(--akzent);margin-bottom:var(--a-mittel);border-radius:0}

.klein{font-size:var(--fs-klein);color:var(--grau);line-height:1.5}
/* NICHT in den hellen Inseln: ein Beleg im dunklen Band ist ein weisses
   Blatt, und hellgrauer Kleintext darauf mass 2,61 : 1. */
.band--dunkel .klein:not(.beleg *):not(.blatt *):not(.vfg-screen *):not(.vfp-screen *):not(.vfm-phone *){color:var(--d-grau)}

/* Auszeichnung im Fliesstext: ein TEXTMARKER, keine farbige Schrift.
   Die Schrift bleibt schwarz (19,03 : 1), der Akzent liegt als Lasur
   darunter. Damit trägt die Farbe die Betonung, ohne die Lesbarkeit
   anzufassen — und die Kontrastfrage stellt sich gar nicht erst. */
.mark{
  font-weight:600;color:var(--tinte);
  background:linear-gradient(transparent 62%,var(--akzent-lasur) 62%);
  padding-bottom:1px;
}
.band--dunkel .mark{color:var(--w);background:linear-gradient(transparent 62%,rgba(59,160,100,.34) 62%)}

/* ── Knöpfe ───────────────────────────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  min-height:48px;padding:12px 26px;border-radius:0;border:1px solid transparent;
  font-family:inherit;font-size:var(--fs-body);font-weight:600;letter-spacing:-.01em;
  text-decoration:none;cursor:pointer;background:none;color:inherit;
  transition:background-color .16s ease,color .16s ease,border-color .16s ease,transform .06s ease;
}
.btn:active{transform:translateY(1px)}
/* WEISS auf dem dunkleren Knopf-Orange: 4,60 : 1. Nicht auf --akzent —
   dort wären es 3,12 : 1 (Begründung oben bei --akzent-knopf). */
.btn--voll{background:var(--akzent-knopf);color:#fff;border-color:var(--akzent-knopf)}
.btn--voll:hover{background:var(--akzent-tief);border-color:var(--akzent-tief);color:#fff}
.btn--linie{border-color:var(--linie-stark);color:var(--tinte)}
.btn--linie:hover{border-color:var(--tinte);background:var(--tinte);color:var(--w)}
.band--dunkel .btn--linie{border-color:rgba(255,255,255,.28);color:var(--d-text)}
.band--dunkel .btn--linie:hover{background:var(--w);color:var(--schwarz);border-color:var(--w)}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
/* `laeuft` sperrt bewusst NICHT — der zweite Klick soll ins selbe Ziel laufen,
   nicht ins Leere. Der Kringel haengt an aria-busy, nicht an einer Klasse,
   die der Knopf gar nicht traegt. */
.btn[aria-busy="true"]::before{
  content:"";width:15px;height:15px;border-radius:50%;
  border:2px solid currentColor;border-top-color:transparent;
  animation:kringel .7s linear infinite;
}
@keyframes kringel{to{transform:rotate(360deg)}}

.rufe{display:flex;flex-wrap:wrap;gap:12px;margin-top:var(--a-mittel)}
/* ── DER RUF MIT LICHTHOF UMSCHLIESST SEINE KNOEPFE ──────────────────────
   GEMESSEN am 29.08.2026, im Bild beanstandet: „glow kaputt random im
   nirgendwo". Der Hof lag als waagerechter Schmier NEBEN dem Knopf.

   Ursache: `.rufe` ist ein Block und damit so breit wie das Band — bei
   1280 px rund 1150 px. Der Hof (`.lichthof::before`) deckt diesen Kasten
   ab, und sein Verlauf sitzt auf `50%` DIESER Breite. Der Knopf steht aber
   links und ist 300 px breit. Also leuchtete die Mitte des Bandes, nicht
   der Knopf. Bei einer Kastenhoehe von 52 px und einer Breite von 1150 px
   ist ein Radialverlauf kein Hof mehr, sondern ein Streifen.

   Behoben nicht am Verlauf, sondern am Kasten: `width:fit-content` laesst
   die Zeile nur so breit werden wie ihre Knoepfe. Damit sitzt der Verlauf
   wieder ueber dem, was leuchten soll. `max-width:100%` haelt ihn auf dem
   Telefon in der Spur, wo zwei Knoepfe umbrechen.

   Wer zentriert stehen soll, bekommt `.rufe--mitte` — mit `fit-content`
   richtet `justify-content` nichts mehr aus, es gibt ja keinen Freiraum
   mehr in der Zeile. */
.rufe.lichthof{width:fit-content;max-width:100%}
.rufe--mitte{margin-inline:auto}

/* ── DER HOF HINTER EINER KNOPFREIHE RECHNET ANDERS ──────────────────────
   GEMESSEN am 29.08.2026 an allen sieben Lichthöfen der Startseite:

     Bauteil                 Höhe    Hof-Box   Verlaufsmitte   auf dem Teil?
     Puzzle / Beleg / Prot   556-574  645-664   -133 bis -139     ja
     die vier Rufe            52      141          -32            NEIN

   Die Grundgeometrie ist für HOHE Bauteile gemacht: 48,6 px fester Überstand
   nach oben und die Verlaufsmitte auf 30 % der Box. Auf einer 574-px-Karte
   landet sie im oberen Drittel — gewollt, Licht kommt von oben. Auf einer
   52 px hohen Knopfreihe besteht die Box fast nur aus Überstand: 52 + 48,6 +
   40,5 = 141 px, und 30 % davon liegen 6 px ÜBER der Oberkante der Knöpfe.
   Der Schein stand dadurch als waagerechtes Band zwischen Vorspann und
   Knöpfen statt dahinter — im Bild beanstandet.

   Hier also symmetrisch und mittig: gleicher Überstand oben wie unten, Mitte
   auf 50 %. Damit ist der hellste Punkt der Knopf selbst.
   Nachgerechnet, damit der Verlauf INNERHALB der Box auf null fällt und
   keine Kante entsteht: Box 52 + 2·44 = 140 px, Radius senkrecht 46 %,
   Null bei 0,82 · 46 % = 37,7 % — der Schein endet also bei 12,3 % und
   87,7 % der Box (17 px / 123 px), die Knöpfe liegen bei 44…96 px. Er deckt
   sie voll und läuft vorher aus.
   Seitlich weiter an `--rand` gebunden, aus demselben Grund wie oben: sonst
   schiebt er das Dokument. */
.rufe.lichthof::before{
  inset:-44px calc(-1 * min(40.5px, var(--rand)));
  background:radial-gradient(62% 46% at 50% 50%,
    rgba(143,233,168,.55) 0%, rgba(143,233,168,.22) 42%,
    rgba(143,233,168,0) 82%);
}

/* Textverweis mit Pfeil — der leise Ruf zwischen den Abschnitten */
.pfeil{
  display:inline-flex;align-items:center;gap:8px;
  font-weight:600;color:var(--tinte);text-decoration:none;
  border-bottom:2px solid var(--akzent);padding-bottom:2px;
}
/* Der Pfeil trägt die Farbe, nicht das Wort. */
.pfeil::after{content:"→";color:var(--akzent-text);transition:transform .16s ease}
.pfeil:hover::after{transform:translateX(3px)}
.band--dunkel .pfeil{color:var(--d-text)}
.band--dunkel .pfeil::after{color:var(--akzent)}

/* ═══════════════════════════════════════════════════════════════════════════
   KOPF
   ═══════════════════════════════════════════════════════════════════════════ */
.kopf{
  position:sticky;top:0;z-index:60;background:var(--w);
  border-bottom:1px solid transparent;transition:border-color .2s ease,box-shadow .2s ease;
}
.kopf.fest{border-bottom-color:var(--linie);}
.kopf__innen{
  max-width:var(--mass);margin-inline:auto;padding:12px var(--rand);
  display:flex;align-items:center;gap:var(--a-mittel);
}
.lockup{display:flex;align-items:center;gap:9px;text-decoration:none;flex:0 0 auto}
/* Groesser auf Ansage. Die Wortmarke waechst mit, damit das Verhaeltnis
   bleibt — sie wird nie einzeln skaliert. */
.lockup img{width:44px;height:auto}
/* Die Wortmarke — Ubuntu, und nur hier. Sie weicht nie: wenn der Platz eng
   wird, weicht der Knopf oder die Bildmarke schrumpft. */
.lockup span{
  font-family:var(--fu);font-size:var(--fs-lead);font-weight:500;
  letter-spacing:-.02em;color:var(--tinte);
}
/* Der Punkt in „digital." — die MARKE, kein Fliesstext.
   3,30 : 1 gegen Weiss. Das ist zulaessig: WCAG 1.4.3 nimmt Text aus, der
   Teil eines Logos oder Markennamens ist, und der Punkt traegt keine
   Information (im Markup steht er als aria-hidden). Wer ihn trotzdem
   dunkler will, faerbt NICHT hier nach, sondern laesst die Logodateien in
   01-marke/corporate-design/werkzeug/ neu erzeugen. */
.lockup i{color:var(--akzent);font-style:normal;font-weight:700}

.kopf nav{margin-left:auto;display:flex;align-items:center;gap:var(--a-mittel)}
.kopf__links{display:flex;gap:26px}
.kopf__links a{
  font-size:var(--fs-klein);font-weight:500;color:var(--grau);text-decoration:none;
  padding:6px 0;border-bottom:2px solid transparent;transition:color .15s ease,border-color .15s ease;
}
.kopf__links a:hover{color:var(--tinte);border-bottom-color:var(--akzent)}
/* 44 px ist der Boden, und er gilt UEBERALL — nicht nur in
   `@media (pointer: coarse)`. Genau dort stand er einmal, und damit galt er
   am Schreibtisch nie: auf einer Seite lagen 23 von 31 Bedienelementen
   darunter. Im Browser nachgemessen: 42 px waren es hier, jetzt 44. */
.kopf .btn{min-height:44px;padding:10px 20px;font-size:var(--fs-klein)}
@media (max-width:900px){.kopf__links{display:none}}
@media (max-width:400px){
  /* Wenn es eng wird, weicht der Knopf — nie die Wortmarke. */
  .kopf .btn{padding:9px 14px}
}

/* ═══════════════════════════════════════════════════════════════════════════
   HERO
   ═══════════════════════════════════════════════════════════════════════════ */
/* Weniger Luft als vorher: die Ueberschrift ist kurz, und ein halber
   Bildschirm Weiss ueber zwei Zeilen las sich als Leere, nicht als Ruhe.
   Beanstandet: „viel zu viel platz". */
#hero{padding-block:clamp(36px,4.5vw,64px) clamp(24px,3vw,40px)}
.hero__gitter{display:grid;grid-template-columns:.86fr 1.14fr;gap:clamp(28px,4vw,56px);align-items:center}
.hero__text{max-width:560px}
/* ═══ AUF DEM TELEFON UNTEREINANDER ═════════════════════════════════════
   Ohne diese Regel blieb das Raster auch bei 393 px zweispaltig: 160 px
   für die Überschrift (Wort-für-Wort-Umbruch) und 85 px für die Grafik.
   Gemessen auf einem echten Gerät, nicht geschätzt. */
@media (max-width:900px){
  .hero__gitter{grid-template-columns:1fr;gap:var(--a-gross)}
  .hero__text{max-width:none}
  .hero__gitter .netz{max-width:420px;margin-inline:auto}
}
.hero h1{margin-bottom:var(--a-mittel)}

/* ═══ ZWEI TOENE IN DER UEBERSCHRIFT ══════════════════════════════════════
   Beanstandet: „farbige unterschiede machen". Die erste Zeile bleibt
   schwarz (19,03 : 1), die zweite traegt die dunkle Fassung des Akzents.
   Gemessen: #007032 auf Weiss = 6,24 : 1 — das reicht auch fuer Fliesstext
   und erst recht fuer eine Ueberschrift. --akzent waere mit 3,12 : 1 nur
   fuer grosse Schrift zulaessig gewesen, und „gerade eben zulaessig" ist
   bei der ersten Zeile der Seite der falsche Ort. */
.h1-akzent{color:var(--akzent-text)}
.band--dunkel .h1-akzent{color:var(--akzent)}

/* ═══════════════════════════════════════════════════════════════════════════
   DAS NETZ, ZWEITER ANLAUF — ein Bus, keine Speichen

   Der erste war ein Rad aus Kreisen mit schraegen Speichen. Beanstandet:
   „grafik immer noch scheiße". Zu Recht — Kreise und Diagonalen sind das
   Vokabular jeder Mindmap-Vorlage.

   Jetzt eine senkrechte Leitung durch die Mitte, der Kern sitzt darauf, die
   Module haengen links und rechts mit rechtwinkligen Stichleitungen daran.
   Querverbindungen laufen aussen herum, ebenfalls im rechten Winkel. Das ist
   die Sprache technischer Zeichnungen.

   ═══ DIE BEWEGUNG VERSTECKT NICHTS ═══════════════════════════════════════
   Grundzustand: Leitungen gezeichnet (`stroke-dashoffset: 0`), Bloecke
   deckend. Die Animation setzt den Anfangszustand nur ueber `both` INNERHALB
   ihrer Laufzeit. Laeuft sie nicht — altes Geraet, abgeschaltete Bewegung,
   Standbild —, steht das Bild einfach da.
   ═══════════════════════════════════════════════════════════════════════════ */
.netz{width:100%;height:auto;display:block;overflow:visible}

/* ═══════════════════════════════════════════════════════════════════════════
   DAS NETZ — sechs Modulkästen an einem Kern

   Dritter Anlauf. Der erste war ein Rad aus Kreisen („grafik immer noch
   scheisse"), der zweite Namen mit Unterstrichen an einer senkrechten Achse
   („0 clean, richtig trocken, nix verknuepft"). Der Fehler war beide Male
   derselbe: die Namen hatten keinen Körper. Ohne Kasten gibt es nichts, was
   verbunden aussieht — eine Linie zwischen zwei Wörtern ist nur eine Linie.

   Jetzt trägt jedes Modul einen Kasten, jeder Kasten hängt an einer
   orthogonalen Leitung, und drei Leitungen laufen aussen herum und
   verbinden Module direkt miteinander. Der orange Kasten ist der Teil, den
   es nur beim jeweiligen Betrieb gibt.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Kästen: weiss mit feiner Kante. Gefüllt sind nur zwei — der Kern (das
   ist der Betrieb) und der Zuschnitt (das ist das Angebot). Wäre alles
   gefüllt, hiesse Füllung nichts mehr. */
.nb-block rect{fill:var(--w);stroke:var(--linie-stark);stroke-width:1}
.nb-kante{stroke:var(--tinte);stroke-width:3;fill:none}
.nb-block--kern rect{fill:var(--tinte);stroke:var(--tinte)}
.nb-block--zuschnitt rect{fill:var(--akzent);stroke:var(--akzent)}
.nb-block--zuschnitt .nb-kante{stroke:var(--akzent-tief)}

.nb-leitung{stroke:var(--linie-stark);stroke-width:1.5;fill:none;
  stroke-dasharray:var(--l);stroke-dashoffset:0}
.nb-leitung--quer{stroke-dasharray:5 4;stroke-width:1.25}
.nb-leitung--zuschnitt{stroke:var(--akzent);stroke-width:2}
.nb-punkt{fill:var(--tinte)}

/* Der Impuls: ein kurzer Strich, der über die Leitung läuft. Reine Zierde —
   er liegt ÜBER der fertigen Leitung und nimmt ihr nichts. */
.nb-puls{stroke:var(--akzent);stroke-width:3;stroke-linecap:square;fill:none;
  stroke-dasharray:18 9999;stroke-dashoffset:0;opacity:0}
.nb-puls--quer{stroke-width:2.5}

.netz text{font-family:var(--f);letter-spacing:-.015em}
.nb-eins{font-size:calc(var(--fs-klein) * 1.35);font-weight:600;fill:var(--tinte)}
.nb-zwei{font-size:calc(var(--fs-label) * 1.45);font-weight:500;fill:var(--grau)}
.nb-block--zuschnitt .nb-eins,.nb-block--zuschnitt .nb-zwei{fill:#fff}
.nb-kern-1{font-size:calc(var(--fs-klein) * 1.5);font-weight:700;fill:#fff;
  letter-spacing:.16em;text-anchor:middle}
.nb-kern-2{font-size:calc(var(--fs-label) * 1.45);font-weight:500;fill:#C9C9C6;
  letter-spacing:.02em;text-anchor:middle}
.nb-quer-t{font-size:calc(var(--fs-label) * 1.35);font-weight:600;
  fill:var(--grau);letter-spacing:.06em;text-anchor:middle}

/* WAS IM MARKUP STEHT, IST DER ENDZUSTAND. Ohne erlaubte Bewegung läuft
   keine dieser Regeln, und die Zeichnung steht vollständig da. */
@media (prefers-reduced-motion:no-preference){
  .nb-leitung{animation:nb-mal .75s cubic-bezier(.22,.61,.36,1) var(--verz,0s) both}
  .nb-block{animation:nb-auf .5s cubic-bezier(.22,.61,.36,1) var(--verz,0s) both}
  .nb-punkt{animation:nb-auf .4s linear .8s both}
  .nb-puls{animation:nb-puls 4.6s linear var(--verz,0s) infinite}
}
@keyframes nb-mal{from{stroke-dashoffset:calc(var(--l) * 1px)}to{stroke-dashoffset:0}}
@keyframes nb-auf{from{opacity:0}to{opacity:1}}
@keyframes nb-puls{
  0%{stroke-dashoffset:18;opacity:0}
  6%{opacity:1}
  40%{stroke-dashoffset:calc(var(--l) * -1px);opacity:1}
  46%{opacity:0}
  100%{stroke-dashoffset:calc(var(--l) * -1px);opacity:0}
}

@media (max-width:880px){.netz{max-width:460px;margin-inline:auto}}

/* ═══════════════════════════════════════════════════════════════════════════
   KARTEN — das eine Kartenmuster fuer die ganze Seite
   ═══════════════════════════════════════════════════════════════════════════ */
.karten{display:grid;gap:var(--a-mittel);margin-top:var(--a-gross)}
.karten--3{grid-template-columns:repeat(3,1fr)}
/* Vier Kacheln in einem Dreierraster lassen die vierte allein in der
   nächsten Zeile stehen — beanstandet als „das eine Ding auf einmal
   darunter, richtig random platziert". `auto-fit` mit Mindestbreite füllt
   die Zeile stattdessen aus: vier nebeneinander, wo Platz ist, sonst zwei
   und zwei. Nie eine allein. */
.karten--4{grid-template-columns:repeat(auto-fit,minmax(232px,1fr))}
@media (max-width:1100px){.karten--4{grid-template-columns:1fr 1fr}}
@media (max-width:640px){.karten--4{grid-template-columns:1fr}}
.karten--2{grid-template-columns:repeat(2,1fr)}
@media (max-width:900px){.karten--3{grid-template-columns:1fr}.karten--2{grid-template-columns:1fr}}

/* ═══ KEINE KARTE, SONDERN EIN BLOCK ══════════════════════════════════════
   Eine umrandete Box mit Radius und Schatten steht auf jeder zweiten Seite
   im Netz — beanstandet als „wirkt noch stark kopiert". Hier stattdessen:
   eine kraeftige OBERkante, sonst nichts. Kein Rahmen ringsum, kein
   Schatten, kein Radius. Das liest sich wie ein Datenblatt, nicht wie ein
   Template.

   Der Grund bleibt weiss — auf Papier hebt sich der Block dadurch ab, ohne
   dass eine Linie darum gezogen werden muss. */
/* ═══ DIE KACHEL ══════════════════════════════════════════════════════════
   Vorher trug jede Karte zwei waagerechte Striche übereinander — einen
   schwarzen und einen orangen — plus die Nummer darunter. Beanstandet als
   „viel zu viele random Linien": drei Karten nebeneinander ergaben sechs
   Striche, die nichts trennten, was nicht ohnehin getrennt war.

   Jetzt eine feine orange Umrandung, die sich zeichnet, sobald die Kachel
   ins Bild kommt, und die Nummer GROSS im Hintergrund. Der Rahmen ist ein
   SVG-Pfad und läuft über dasselbe `.malt`/`.gemalt`-System wie jeder
   andere gezeichnete Strich der Seite — ohne Skript steht er einfach da. */
.karte{
  position:relative;background:none;border:0;
  padding:var(--a-mittel);isolation:isolate;
}
.karte__rahmen{position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;z-index:0}
.karte__rahmen path{fill:none;stroke:var(--akzent);stroke-width:1}
.karte > *:not(.karte__rahmen){position:relative;z-index:1}

.karten{gap:var(--a-mittel)}
.karte h3,.karte h4{font-size:var(--fs-lead);margin-bottom:var(--a-klein);
  letter-spacing:-.02em}
.karte p{color:var(--grau);font-size:var(--fs-body)}
.band--dunkel .karte p{color:var(--d-grau)}
.band--dunkel .karte__rahmen path{stroke:var(--akzent)}

/* Die Nummer liegt HINTER dem Text und ist gross. Sie ist Zierrat und kein
   Text mehr — deshalb `aria-hidden` im Markup und ein Ton, der sich nicht
   vordrängt. Auf Kontrast wird sie nicht geprüft, weil sie nichts sagt,
   was nicht die Reihenfolge schon sagt. */
.karte__nr{
  position:absolute;right:10px;top:0;z-index:0;
  font-size:calc(var(--fs-zahl) * 2.6);font-weight:700;line-height:.8;
  letter-spacing:-.05em;color:var(--akzent);opacity:.13;pointer-events:none;
}
.band--dunkel .karte__nr{opacity:.22}

.karte--akzent .karte__rahmen path{stroke-width:2}

/* Häkchen-Liste */
.haken li{position:relative;padding-left:26px;color:var(--grau);line-height:1.55}
.haken li + li{margin-top:10px}
/* Ein Haken ist HOEHER als breit — quadratisch gedreht ergibt er einen
   Winkel, der wie ein Aufklapp-Pfeil aussieht. Im Bild gesehen, nicht am
   Quelltext: 9 x 9 las sich als „⌄". */
.haken li::before{
  content:"";position:absolute;left:2px;top:.5em;width:6px;height:11px;
  border-right:2px solid var(--akzent);border-bottom:2px solid var(--akzent);
  transform:rotate(42deg);
}
.band--dunkel .haken li{color:var(--d-grau)}

/* ═══════════════════════════════════════════════════════════════════════════
   MODULE — je Modul EIN Abschnitt, im Wechsel links/rechts
   Keine Unterseiten. Kein Reiterwerk. Eine Seite, ein Lauf.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Der Wechsel hell/dunkel trägt die Gliederung — die Liste selbst braucht
   oben keine Linie mehr. Getrennt wird nur INNERHALB eines Bandes. */
.module{}
.band--dunkel .modul{border-bottom-color:var(--d-linie)}
.band--dunkel .modul__text p{color:var(--d-grau)}
.band--dunkel .modul__text h2,.band--dunkel .modul__text h3{color:var(--d-text)}
.modul{
  display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(28px,4vw,64px);align-items:center;
  padding-block:clamp(44px,5.2vw,72px);
  border-bottom:1px solid var(--linie);
}
.modul:last-child{border-bottom:0}
/* Grid-Items schrumpfen ohne min-width:0 nicht unter ihren Inhalt — bei der
   Gefährdungsbeurteilung (`.vfg-*`-Tabelle) riss das `.modul__beleg` bei
   375px rechts aus dem Kasten (Kasten 335px, Karte erzwang 400px). Betraf
   nur dieses eine Modul, weil nur seine Vorführung so viele feste
   Spalten hat; die anderen Vorführungen (vfa-/vfm-/vfp-) waren schon
   schmal genug. */
.modul__text,.modul__beleg{min-width:0}
/* Die Vorfuehrung laeuft mit, statt in der Mitte von Leerraum zu haengen.
   Gemessen: Textspalte 1870px, Karte 546px, zentriert — 660px Luft oben
   und unten. Der Beleg-Kasten wird auf volle Hoehe gezogen (`stretch`),
   die Karte darin klebt oben. */
.modul{align-items:start}
.modul__beleg{align-self:stretch}
.modul__beleg>*{position:sticky;top:80px}
/* Ungerade Module drehen die Seiten. `order` statt zweier Markup-Fassungen. */
.modul:nth-child(even) .modul__beleg{order:-1}
/* Steht ein Modul allein in seinem Band, greift `nth-child(even)` nie — es
   ist immer das erste Kind. `modul--gedreht` dreht es von Hand. Die Klasse
   stand seit dem 24.08. im Markup der Gefaehrdungsbeurteilung und hatte im
   Stilblatt keine Entsprechung; sie tat also nichts. Jetzt tut sie, was ihr
   Name sagt, und traegt den Seitenwechsel zwischen Planung und Arbeitszeit. */
.modul--gedreht .modul__beleg{order:-1}
.modul__text h2,.modul__text h3{font-size:var(--fs-h2);letter-spacing:-.028em;margin-bottom:var(--a-klein)}
.modul__text p{color:var(--grau);margin-bottom:var(--a-mittel)}
.modul__text .haken{margin-bottom:0}
@media (max-width:900px){
  .modul{grid-template-columns:1fr;gap:var(--a-gross)}
  .modul:nth-child(even) .modul__beleg{order:0}
  /* Einspaltig gibt es nichts zum Mitlaufen — die Karte wuerde ueber dem
     eigenen Text kleben. */
  .modul__beleg>*{position:static}
}

/* ═══════════════════════════════════════════════════════════════════════════
   ZWEI GESICHTER — der Ueber-uns-Abschnitt

   Er stand ganz unten und war eine Aufzaehlung. Wer eine Software kaufen
   soll, die IHM gehoert, will frueh wissen, von wem sie kommt — deshalb
   steht er jetzt an dritter Stelle, direkt nach dem Kurzprofil.

   Bild und Text NEBENeinander, nicht untereinander: zwei hohe Portraets
   uebereinander schoben den Abschnitt auf drei Bildschirmhoehen.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ═══ ZWEI GESICHTER, GROSS GENUG ════════════════════════════════════════
   Die Bilder standen auf 132 px — zweimal beanstandet („zu klein"). Bei der
   Breite ist ein Gesicht briefmarkengross und trägt nichts. Jetzt eine
   eigene Spalte statt einer Randspalte: das Bild ist so breit wie der Text
   daneben hoch. Der Abschnitt ist der Vertrauensbeweis der Seite — dafür
   sind zwei Portraits genau das richtige Mittel, aber nur in Grösse. */
.leute{display:grid;grid-template-columns:1fr 1fr;gap:var(--a-gross);
  margin-top:var(--a-gross)}
@media (max-width:900px){.leute{grid-template-columns:1fr;gap:var(--a-gross)}}
.person{display:grid;grid-template-columns:220px 1fr;gap:var(--a-mittel);
  align-items:start}
.person img{width:220px;aspect-ratio:4/5;object-fit:cover;object-position:50% 18%;
  display:block;border-radius:0}
.person figcaption b{display:block;font-size:var(--fs-lead);font-weight:600;
  letter-spacing:-.02em;color:var(--tinte)}
.person figcaption > span{display:block;font-size:var(--fs-klein);font-weight:600;
  color:var(--akzent-text);margin-top:2px}
.person figcaption p{margin-top:10px;font-size:var(--fs-klein);color:var(--grau);
  line-height:1.6}
@media (max-width:1100px){
  .person{grid-template-columns:1fr}
  .person img{width:100%;max-width:320px;aspect-ratio:4/5}
}
@media (max-width:520px){
  .person{grid-template-columns:96px 1fr;gap:var(--a-klein)}
  .person img{width:96px}
}

/* Der Satz mit Kante — eine Aussage, kein Absatz. */
.kante{margin-top:var(--a-gross);max-width:var(--text);
  border-left:3px solid var(--akzent);padding-left:20px;
  font-size:var(--fs-lead);line-height:1.5;letter-spacing:-.015em;
  font-weight:500;color:var(--tinte)}
.band--dunkel .kante{color:var(--d-text)}

/* ═══════════════════════════════════════════════════════════════════════════
   ZAHLEN, DIE WIRKEN — statt eines weiteren Absatzes

   Beanstandet: „zu viel text, spektakulaerer machen". Drei Zahlen sagen in
   einer Zeile, was drei Absaetze umschreiben.
   ═══════════════════════════════════════════════════════════════════════════ */
.zahlen{display:grid;grid-template-columns:repeat(3,auto);gap:var(--a-gross);
  margin:var(--a-mittel) 0;justify-content:start}
.zahlen li b{display:block;font-size:var(--fs-zahl);font-weight:600;
  letter-spacing:-.02em;line-height:1.1;color:var(--tinte)}
.zahlen li span{display:block;font-size:var(--fs-label);letter-spacing:.08em;
  text-transform:uppercase;color:var(--grau);margin-top:4px}
.zahlen li:first-child b{color:var(--akzent-text)}
@media (max-width:560px){.zahlen{grid-template-columns:1fr 1fr;gap:var(--a-mittel)}}

/* ═══ DIE NUMMERNFOLGE ALS STREIFEN ═══════════════════════════════════════
   47 Blaetter, eines fehlt. In einer Liste sieht man das nie, in einer Reihe
   sofort — die Luecke ist eine helle Stelle zwischen lauter dunklen.
   Die Kaestchen sind `aria-hidden` ueber das `role="img"` am Elternteil;
   der Vorleser bekommt den Satz, nicht 47 leere Spannen. */
.folge{display:flex;flex-wrap:wrap;gap:3px;padding:12px;border-radius:0;
  background:var(--papier);border:1px solid var(--linie)}
.fg{width:10px;height:16px;border-radius:0;display:inline-block;flex:0 0 auto}
.fg--ok{background:#2F7345}
.fg--lauf{background:var(--akzent)}
/* Die Luecke ist KEIN gefuelltes Kaestchen — sie ist ein Loch. Ein rotes
   Kaestchen laese sich als „Blatt mit Fehler", und das ist etwas anderes
   als „Blatt fehlt". */
.fg--luecke{background:repeating-linear-gradient(45deg,#FBECE9 0 3px,#F4D3CC 3px 6px);
  border:1px solid var(--rot)}
.folge__bei{display:flex;flex-wrap:wrap;gap:16px;margin-top:8px;
  font-size:var(--fs-label);color:var(--grau)}
.folge__bei span{display:inline-flex;align-items:center;gap:6px}
.folge__bei i{width:9px;height:13px}

/* Ein Beleg, der mehr traegt als die anderen, darf breiter atmen. */
.beleg--gross .beleg__inhalt{padding:18px}
.b-feld--zahl b{font-size:var(--fs-zahl);letter-spacing:-.02em;line-height:1.1}
.b-feld--warn{border-color:var(--rot)}
.b-feld--warn b{color:var(--rot)}

/* ═══════════════════════════════════════════════════════════════════════════
   BELEG — EIN Attrappen-Bauplan fuer alle Module
   Standbild. Kein Tippen, kein Ablauf, keine Vorfuehrung.

   Damit faellt der gesamte Sichtbarkeits-Apparat der alten Seite weg — dort
   standen 58 Bloecke auf `opacity:0` und wurden erst durch einen
   IntersectionObserver sichtbar. Meldete der nicht (Safari, Rueckkehr aus
   dem Verlaufsspeicher), blieb die halbe Seite leer. Hier gibt es nichts,
   was melden koennte: was im HTML steht, ist zu sehen.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ═══ `color` MUSS HIER STEHEN ════════════════════════════════════════════
   Ein Beleg ist eine WEISSE Karte — auch mitten in einem schwarzen Band.
   Alles darin, was keine eigene Farbe setzt (`.b-kopf b`, `.b-zeile__wert`,
   `.b-feld b`), erbt sonst die Farbe des Bandes. Im dunklen Band war das
   #F2F2F2 auf Weiss: gemessen 1,12 : 1 an 16 Stellen — Zahlen wie
   „50 658,60 €" standen weiss auf weiss und waren schlicht nicht da.
   Gefunden hat das die Kontrastmessung, nicht das Auge. */
.beleg{
  background:var(--w);color:var(--tinte);
  border:1px solid var(--linie);border-radius:0;
  overflow:hidden;font-size:var(--fs-klein);
}
/* Im dunklen Band traegt die Karte einen Lichtsaum statt eines Schattens —
   ein Schatten auf Schwarz ist nichts. */
.band--dunkel .beleg{border-color:rgba(255,255,255,.16);
  }
.band--papier .beleg{}
.beleg__leiste{
  display:flex;align-items:center;gap:10px;
  padding:10px 14px;border-bottom:1px solid var(--linie);background:var(--papier);
}
.beleg__punkte{display:flex;gap:5px}
.beleg__punkte i{width:8px;height:8px;border-radius:50%;background:var(--linie-stark);display:block}
.beleg__titel{font-size:var(--fs-label);font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--grau)}
.beleg__inhalt{padding:16px}

/* Bausteine im Beleg — dieselben elf Mal, verschieden gefuellt */
.b-kopf{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:12px}
.b-kopf b{font-size:var(--fs-body);font-weight:600;letter-spacing:-.02em}
.b-kopf span{font-size:var(--fs-klein);color:var(--grau)}

.b-zeile{
  display:flex;align-items:center;gap:10px;
  padding:9px 0;border-top:1px solid var(--linie);
}
.b-zeile:first-child{border-top:0}
.b-zeile__haupt{flex:1;min-width:0}
.b-zeile__haupt b{display:block;font-weight:500;color:var(--tinte);
  font-size:var(--fs-klein);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.b-zeile__haupt span{display:block;color:var(--grau);font-size:var(--fs-label)}
.b-zeile__wert{font-weight:600;font-size:var(--fs-klein);white-space:nowrap;letter-spacing:-.01em}
.b-zeile__wert--akzent{color:var(--akzent-text)}

.b-marke{
  display:inline-flex;align-items:center;gap:6px;flex:0 0 auto;
  padding:3px 9px;border-radius:99px;font-size:var(--fs-label);font-weight:600;
  letter-spacing:.02em;background:var(--papier);color:var(--grau);
}
.b-marke--an{background:rgba(59,160,100,.12);color:var(--akzent-text)}
.b-marke--fertig{background:#E8F0E9;color:#256B36}
.b-marke--warn{background:#FBECE9;color:var(--rot)}

.b-punkt{width:7px;height:7px;border-radius:50%;background:var(--linie-stark);flex:0 0 auto}
.b-punkt--an{background:var(--akzent)}
.b-punkt--fertig{background:#2F7345}

.b-fort{height:6px;border-radius:99px;background:var(--linie);overflow:hidden;margin-top:6px}
.b-fort i{display:block;height:100%;background:var(--akzent);border-radius:99px}

.b-gitter{display:grid;gap:8px}
.b-gitter--2{grid-template-columns:1fr 1fr}
.b-gitter--3{grid-template-columns:repeat(3,1fr)}
.b-feld{
  border:1px solid var(--linie);border-radius:0;padding:10px;background:var(--w);
}
.b-feld b{display:block;font-size:var(--fs-klein);font-weight:600;letter-spacing:-.01em}
.b-feld span{display:block;font-size:var(--fs-label);color:var(--grau);
  letter-spacing:.08em;text-transform:uppercase;margin-bottom:3px}
.b-feld--akzent b{color:var(--akzent-text)}

.b-reiter{display:flex;gap:4px;margin-bottom:12px;border-bottom:1px solid var(--linie)}
/* padding-inline war 10px: bei "Aufmaßblätter" (leistung.html, 375px) reichte
   das nicht, die drei Reiter liefen 8px über die Kartenkante. 8px passt bei
   allen bisherigen Beschriftungen auf allen drei Seiten. */
.b-reiter span{
  font-size:var(--fs-label);font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--grau);padding:6px 8px;border-bottom:2px solid transparent;margin-bottom:-1px;
}
.b-reiter span.an{color:var(--tinte);border-bottom-color:var(--akzent)}

.b-notiz{
  background:var(--papier);border-radius:0;padding:10px 12px;
  font-size:var(--fs-klein);color:var(--grau);line-height:1.5;
}
.b-notiz b{color:var(--tinte);font-weight:600}

.b-warn{
  display:flex;gap:9px;align-items:flex-start;
  background:#FBECE9;border-left:3px solid var(--rot);border-radius:0;
  padding:10px 12px;font-size:var(--fs-klein);color:#7A2318;line-height:1.45;
}
.b-warn b{font-weight:600}

/* ── Der Jahresplan im Pflege-Beleg ──────────────────────────────────────
   Zwoelf Monate, vier Aufgaben, ein Punkt je Termin. Kein Diagramm und
   keine Zahlenreihe: man SIEHT, wo im Jahr etwas passiert und wo nicht —
   und dass der Gehoelzschnitt die Schonzeit meidet. */
.jahresplan{border:1px solid var(--linie);border-radius:0;padding:10px 12px;background:var(--w)}
.jp-zeile{display:grid;grid-template-columns:104px 1fr;gap:10px;align-items:center;
  padding:6px 0;border-top:1px solid var(--linie)}
.jp-zeile--kopf{border-top:0;padding-top:0}
.jp-name b{display:block;font-size:var(--fs-klein);font-weight:600;letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jp-name span{display:block;font-size:var(--fs-label);color:var(--grau)}
.jp-band{display:grid;grid-template-columns:repeat(12,1fr);gap:3px;align-items:center}
.jp-monat{font-size:var(--fs-label);color:var(--grau);text-align:center;font-weight:600}
.jp-punkt{height:9px;border-radius:0;background:var(--linie)}
.jp-punkt--an{background:var(--akzent)}
@media (max-width:400px){.jp-zeile{grid-template-columns:84px 1fr;gap:6px}}

/* Luftbild-Andeutung fuer das Aufmass. Reine CSS-Flaeche, kein Fremdmaterial:
   ein amtliches Orthofoto braeuchte die Namensnennung „© GeoBasis-DE/LGB
   (DOP20), dl-de/by-2-0", und dafuer ist eine Attrappe der falsche Ort. */
.b-luft{
  position:relative;border-radius:0;overflow:hidden;aspect-ratio:16/9;
  background:
    repeating-linear-gradient(58deg,#DFDCD4 0 14px,#D7D3CA 14px 28px),
    linear-gradient(160deg,#E6E3DB,#CFCBC1);
  border:1px solid var(--linie);
}
.b-luft::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(200deg,rgba(255,255,255,.28),transparent 60%);
}
.b-flaeche{
  position:absolute;border:2px solid var(--akzent);
  background:rgba(59,160,100,.2);border-radius:0;z-index:1;
}
.b-mass{
  position:absolute;z-index:2;background:var(--schwarz);color:var(--d-text);
  font-size:var(--fs-label);font-weight:600;padding:2px 6px;border-radius:0;
  letter-spacing:.02em;white-space:nowrap;
}

/* Telefon-Attrappe fuer die Feld-Module. Ein Seitenverhaeltnis, eine Breite. */
.b-telefon{
  width:100%;max-width:280px;margin-inline:auto;
  border:8px solid var(--schwarz);border-radius:0;overflow:hidden;
  /* wie beim Beleg: eigene Textfarbe, sonst erbt der Inhalt die des Bandes */
  background:var(--w);color:var(--tinte);
}
.b-telefon__kopf{
  background:var(--schwarz);color:var(--d-text);padding:5px 14px 9px;
  display:flex;justify-content:space-between;font-size:var(--fs-label);font-weight:600;
}
.b-telefon__inhalt{padding:12px}
/* `background-color` steht AUSDRUECKLICH neben dem Verlauf, und die Schrift
   ist deckend. Grund: ein Verlauf ist fuer jedes Messwerkzeug unsichtbar —
   es liest `backgroundColor: transparent`, geht den Baum hinauf und rechnet
   gegen WEISS. Gemessen wurde so 1,00 : 1 fuer eine Schrift, die in Wahrheit
   6,42 : 1 hat. Der Wert unten ist gegen #55554F gerechnet: 6,40 : 1. */
.b-foto{
  aspect-ratio:4/3;border-radius:0;margin-bottom:10px;
  background-color:#55554F;
  background-image:linear-gradient(150deg,#8C8C86,#5F5F5A 60%,#4A4A46);
  display:grid;place-items:center;color:#EDEDEA;
  font-size:var(--fs-label);letter-spacing:.1em;text-transform:uppercase;
}

/* ═══════════════════════════════════════════════════════════════════════════
   REFERENZ
   ═══════════════════════════════════════════════════════════════════════════ */
.ref__gitter{display:grid;grid-template-columns:1fr 1fr;gap:clamp(32px,4.5vw,64px);align-items:center}
@media (max-width:900px){.ref__gitter{grid-template-columns:1fr;gap:var(--a-gross)}}

/* ═══════════════════════════════════════════════════════════════════════════
   NUR FUER VORLESEPROGRAMME
   Eine Ueberschrift, die die Gliederung braucht, im Bild aber nichts zu
   suchen hat. NICHT `display:none` — das nimmt sie den Vorleseprogrammen
   mit heraus, und genau die sollen sie hoeren.

   Stand hier bis 27.08.2026 unter der Ueberschrift des Vergleichs, obwohl
   sie mit ihm nie etwas zu tun hatte: sie wird auf funnel.html, index.html
   und termin.html an sechs Stellen benutzt.
   ═══════════════════════════════════════════════════════════════════════════ */
.sr-nur{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ═══════════════════════════════════════════════════════════════════════════
   LINIEN, DIE SICH BEIM SCROLLEN MALEN

   ═══ DIE REGEL, DIE HIER NICHT GEBROCHEN WIRD ════════════════════════════
   Die Vorgängerfassung dieser Website stellte 58 INHALTSBLÖCKE auf
   `opacity:0` und liess sie von einem IntersectionObserver sichtbar machen.
   Meldete der nicht — Safari meldet nach der Rückkehr aus dem
   Verlaufsspeicher gar nicht mehr —, war die halbe Seite leer. Gemessen:
   0 von 58 sichtbar.

   Hier bewegt sich AUSSCHLIESSLICH ein Strich. Kein Text, kein Bild, kein
   Block hängt an einer Meldung. Und der Grundzustand ist FERTIG GEZEICHNET:
   ohne JavaScript, bei abgeschalteter Bewegung und im Standbild-Modus steht
   die Linie einfach da. Erst wenn `main.js` `<html>` die Klasse `js-malt`
   gibt, wird überhaupt etwas versteckt — und nur ein Strich.

   `--laenge` ist die Pfadlänge und steht am Element (`style="--laenge:420"`).
   ═══════════════════════════════════════════════════════════════════════ */
.malt{stroke-dasharray:var(--laenge);stroke-dashoffset:0}
.js-malt .malt{stroke-dashoffset:var(--laenge)}
.js-malt .malt.gemalt{stroke-dashoffset:0;transition:stroke-dashoffset 1.1s cubic-bezier(.22,.61,.36,1)}
.js-malt .malt--spaet.gemalt{transition-delay:.22s}
.js-malt .malt--spaeter.gemalt{transition-delay:.44s}

/* Derselbe Gedanke für den Akzentstrich über jeder Überschrift: er wächst
   von 0 auf 40 px. Fällt das Skript aus, steht er auf 40 — wie immer. */
.js-malt .regel{transform:scaleX(0);transform-origin:left center}
.js-malt .regel.gemalt{transform:scaleX(1);transition:transform .55s cubic-bezier(.22,.61,.36,1)}

@media (prefers-reduced-motion:reduce){
  .js-malt .malt{stroke-dashoffset:0}
  .js-malt .regel{transform:none}
}

/* ═══════════════════════════════════════════════════════════════════════════
   DIE AUFMASS-VORFÜHRUNG — Luftbild links, Eingabe rechts

   Vorher stand hier ein Querschnitt mit einem Regler darunter. Beanstandet:
   „was soll das für ne böschungsaufmaß sein?" — zu Recht: ein Querschnitt
   ist eine Zeichnung aus dem Lehrbuch, kein Aufmass. Ein Aufmass sieht man
   von oben.

   Ein echtes Kartenbild geht nicht: eine Google-Kachel ist fremdes Material,
   ein amtliches Orthofoto traegt die Namensnennungspflicht. Deshalb eine
   GEZEICHNETE Draufsicht — und die Bildunterschrift sagt das.
   ═══════════════════════════════════════════════════════════════════════════ */
.bo-raster{display:grid;grid-template-columns:1.35fr 1fr;gap:16px;align-items:start}
@media (max-width:1080px){.bo-raster{grid-template-columns:1fr}}

.bo-bild{min-width:0}
.lb{width:100%;height:auto;display:block;border-radius:0;
  border:1px solid var(--linie)}
.bo-quelle{margin-top:8px;font-size:var(--fs-label);color:var(--grau);line-height:1.45}

/* Die Markierung */
.lb-flaeche{fill:rgba(59,160,100,.34);stroke:none}
.lb-kante{fill:none;stroke:var(--akzent);stroke-width:2.5}
.lb-kante--oben{stroke-dasharray:8 5}
.lb-griffe circle{fill:var(--w);stroke:var(--akzent);stroke-width:2.5}
.lb-masslinie{stroke:var(--w);stroke-width:1.6;fill:none;opacity:.9}

/* Beschriftungstafeln: dunkle Plaketten, damit die Schrift auf jedem
   Untergrund liest — auf Asphalt, Acker und Wiese gleichermassen. */
.lb-tafel{fill:rgba(11,11,11,.82)}
.lb-tafel--leise{fill:rgba(11,11,11,.66)}
.lb-schrift text{text-anchor:middle;font-family:var(--f)}
.lb-wert{font-size:var(--fs-klein);font-weight:700;fill:#fff;letter-spacing:-.01em}
.lb-leise{font-size:var(--fs-label);font-weight:600;fill:#EDEDEA;letter-spacing:.02em}
.lb-nord{font-size:var(--fs-label);font-weight:700;fill:#fff;opacity:.9}
.lb-nordpfeil{stroke:#fff;stroke-width:1.6;fill:none;opacity:.9}

/* ── Das Eingabefeld daneben ────────────────────────────────────────────── */
.bo-panel{border:1px solid var(--linie);border-radius:0;padding:14px;
  background:var(--papier);min-width:0}
.bo-panel__kopf{display:block;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grau);
  padding-bottom:10px;margin-bottom:12px;border-bottom:1px solid var(--linie)}

.bo-feld{display:block;cursor:pointer}
.bo-feld__kopf{display:flex;justify-content:space-between;align-items:baseline;
  gap:8px;margin-bottom:2px}
.bo-feld__kopf span{font-size:var(--fs-label);font-weight:600;letter-spacing:.08em;
  text-transform:uppercase;color:var(--grau)}
.bo-feld__kopf b{font-size:var(--fs-klein);font-weight:700;color:var(--tinte);
  font-variant-numeric:tabular-nums}
/* 44 px Anfassflaeche, auch am Schreibtisch. `accent-color` faerbt Bahn und
   Griff in einem Wert. */
.bo-feld input[type="range"]{width:100%;height:44px;accent-color:var(--akzent);
  cursor:pointer;margin:0}
.bo-feld input[type="range"]:focus-visible{outline:2px solid var(--akzent);outline-offset:3px}

.bo-zwei{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:6px}
.bo-zahl span{display:block;font-size:var(--fs-label);font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--grau);margin-bottom:4px}
.bo-zahl input{width:100%;min-height:44px;padding:8px 10px;border-radius:0;
  border:1px solid var(--linie-stark);background:var(--w);color:var(--tinte);
  font-family:inherit;font-size:var(--fs-body);font-weight:600;
  font-variant-numeric:tabular-nums}
.bo-zahl input:focus{outline:none;border-color:var(--akzent);
  }

.bo-werte{margin:14px 0 0;display:grid;gap:0}
.bo-werte > div{display:flex;justify-content:space-between;align-items:baseline;
  gap:10px;padding:8px 0;border-top:1px solid var(--linie)}
.bo-werte dt{font-size:var(--fs-label);letter-spacing:.06em;text-transform:uppercase;
  color:var(--grau)}
.bo-werte dd{margin:0;font-size:var(--fs-klein);font-weight:600;color:var(--tinte);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.bo-werte__gross{border-top-width:2px!important;border-top-color:var(--akzent)!important}
.bo-werte__gross dt{color:var(--tinte);font-weight:700}
.bo-werte__gross dd{font-size:var(--fs-lead);letter-spacing:-.02em}

.bo-diff{margin-top:8px;font-size:var(--fs-label);color:var(--grau)}
.bo-diff b{color:var(--akzent-text);font-weight:700}

/* Was das Modul aus der Flaeche noch macht — der eigentliche Zuschnitt. */
.bo-folge{margin-top:14px;padding-top:12px;border-top:1px dashed var(--linie-stark)}
.bo-folge__kopf{display:block;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--akzent-text);margin-bottom:8px}
.bo-folge > div{display:flex;justify-content:space-between;align-items:baseline;
  gap:10px;padding:5px 0}
.bo-folge span{font-size:var(--fs-label);color:var(--grau)}
.bo-folge b{font-size:var(--fs-klein);font-weight:700;color:var(--tinte);
  font-variant-numeric:tabular-nums;white-space:nowrap}

/* ═══════════════════════════════════════════════════════════════════════════
   DER ABLAUF ALS STRECKE

   Vier gleich breite Spalten mit 01–04 darueber sind der Standardweg — und
   sie sagen nichts darueber, dass die Etappen unterschiedlich lang sind und
   dass es GENAU EINE gibt, an der der Kunde etwas entscheiden muss.

   Hier eine durchgehende Linie mit vier Marken. Die Marke, an der Geld ins
   Spiel kommt, ist orange und gefuellt; die anderen sind offen. Das ist der
   ganze Unterschied — und er ist die wichtigste Information des Abschnitts.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════════════════════
   DER ABLAUF — vier Kacheln an einer Leitung

   Keine Kachel klappt auf, keine verdeckt etwas („nicht wieder mit Öffnung
   etc"). Was verbindet, ist eine Leitung dahinter: sie zieht sich beim
   Hinscrollen von links nach rechts und setzt an jeder Kachel einen Punkt.
   ═══════════════════════════════════════════════════════════════════════════ */
.strecke{position:relative;margin-top:var(--a-gross);list-style:none;padding:0;
  display:grid;grid-template-columns:repeat(4,1fr);gap:var(--a-mittel)}
@media (max-width:900px){.strecke{grid-template-columns:1fr 1fr}}
@media (max-width:560px){.strecke{grid-template-columns:1fr}}

/* Die Leitung liegt hinter den Kacheln, auf Höhe der Anschlusspunkte, und
   läuft von der ersten zur letzten — nicht über die ganze Breite. */
.strecke__leitung{position:absolute;left:12%;right:12%;top:7px;height:2px;
  background:var(--linie-stark);transform-origin:left center}
@media (max-width:900px){.strecke__leitung{display:none}}

.etappe{position:relative;padding:26px var(--a-klein) var(--a-klein);
  border:1px solid var(--linie);background:var(--w)}
.etappe__punkt{position:absolute;top:-8px;left:var(--a-klein);
  width:16px;height:16px;background:var(--w);border:3px solid var(--linie-stark)}
.etappe--geld{border-color:var(--akzent);border-width:2px;padding-top:25px}
.etappe--geld .etappe__punkt{background:var(--akzent);border-color:var(--akzent)}
.etappe:last-child .etappe__punkt{background:var(--tinte);border-color:var(--tinte)}

.etappe__nr{display:block;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.14em;color:var(--grau)}
.etappe b{display:block;margin-top:6px;font-size:var(--fs-lead);font-weight:600;
  letter-spacing:-.02em;color:var(--tinte)}
.etappe__dauer{display:inline-block;margin-top:4px;font-size:var(--fs-label);
  font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--grau)}
.etappe p{margin-top:var(--a-klein);font-size:var(--fs-klein);color:var(--grau);
  line-height:1.55}
.etappe strong{color:var(--tinte);font-weight:600}
/* Der einzige Punkt, an dem der Kunde etwas tun muss — er darf auffallen. */
.etappe__hier{display:inline-block;margin-top:var(--a-klein);padding:4px 9px;
  font-size:var(--fs-label);font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;background:var(--akzent-knopf);color:#fff}

/* ═══ DIE LEITUNG ZIEHT SICH, DIE KACHELN FOLGEN ════════════════════════
   Zerlegt wird nur unter der Klasse `zerlegt`, die `main.js` selbst setzt
   und beim Hinscrollen wieder entfernt — ohne Skript und ohne erlaubte
   Bewegung steht alles fertig da. */
@media (prefers-reduced-motion:no-preference){
  .strecke__leitung{transition:transform .9s cubic-bezier(.22,.61,.36,1)}
  .strecke .etappe{transition:opacity .5s ease var(--verz,0s),
                              transform .5s cubic-bezier(.22,.61,.36,1) var(--verz,0s)}
  .strecke.zerlegt .strecke__leitung{transform:scaleX(0)}
  .strecke.zerlegt .etappe{opacity:0;transform:translateY(10px)}
}

/* ═══════════════════════════════════════════════════════════════════════════
   FRAGEN — <details>, damit es ohne Skript funktioniert
   ═══════════════════════════════════════════════════════════════════════════ */
.fragen{margin-top:var(--a-gross);max-width:860px;border-top:1px solid var(--linie)}
.frage{border-bottom:1px solid var(--linie)}
.frage summary{
  list-style:none;cursor:pointer;padding:20px 40px 20px 0;position:relative;
  font-size:var(--fs-lead);font-weight:600;letter-spacing:-.02em;line-height:1.35;
}
.frage summary::-webkit-details-marker{display:none}
.frage summary::after{
  content:"";position:absolute;right:6px;top:calc(50% - 1px);
  width:14px;height:2px;background:var(--akzent);
}
.frage summary::before{
  content:"";position:absolute;right:12px;top:calc(50% - 7px);
  width:2px;height:14px;background:var(--akzent);transition:transform .18s ease;
}
.frage[open] summary::before{transform:scaleY(0)}
.frage__text{padding:0 0 22px;color:var(--grau);max-width:var(--text)}
.frage__text p + p{margin-top:var(--a-klein)}

/* ═══════════════════════════════════════════════════════════════════════════
   BUCHUNG — FORMULAR UND MELDUNGEN

   Die Kalender- und Slot-Regeln, die hier einmal standen, sind ERSATZLOS
   weg (24.08.2026). Sie waren für ein dunkles Band gebaut; die
   Buchungsstrecke steht seit dem Umbau auf hellem Grund, und zwei Fassungen
   desselben Kalenders wären zwei Wahrheiten. Die gültige steht weiter unten
   unter „DIE BUCHUNGSSTRECKE".
   ═══════════════════════════════════════════════════════════════════════════ */

.feldsatz{border:0;padding:0;margin:0}
.feld{margin-bottom:var(--a-klein)}
.feld label{display:block;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--grau);margin-bottom:6px}
.feld input,.feld textarea,.feld select{
  width:100%;min-height:48px;padding:12px 14px;border-radius:0;
  border:1px solid var(--linie-stark);background:var(--w);
  color:var(--tinte);font-family:inherit;font-size:var(--fs-body);
}
.feld textarea{min-height:96px;resize:vertical;line-height:1.5}
.feld input::placeholder,.feld textarea::placeholder{color:var(--grau)}
.feld input:focus,.feld textarea:focus{border-color:var(--akzent);outline:none;
  box-shadow:inset 0 0 0 1px var(--akzent)}
.feld--zwei{display:grid;grid-template-columns:1fr 1fr;gap:var(--a-klein)}
@media (max-width:520px){.feld--zwei{grid-template-columns:1fr}}

/* Auf HELLEM Grund die dunkle Fassung — --akzent hat dort 3,12 : 1 und ist
   fuer ein Zeichen in Textgroesse zu wenig. Im dunklen Band ist es
   umgekehrt: dort traegt --akzent 6,30 : 1. */
.pflicht{color:var(--akzent-text)}
.band--dunkel .pflicht{color:var(--akzent)}
.band--dunkel .feld label{color:var(--d-grau)}
.band--dunkel .feld input,.band--dunkel .feld textarea{
  border-color:var(--d-linie);background:rgba(255,255,255,.04);color:var(--d-text)}

.meldung{border-radius:0;padding:14px 16px;font-size:var(--fs-klein);
  line-height:1.5;margin-top:var(--a-klein)}
.meldung--gut{background:#EAF5EC;color:#1D6633;border:1px solid #B9DCC3}
.meldung--schlecht{background:#FBEAE8;color:#9E2B1F;border:1px solid #EFC2BC}
.meldung[hidden]{display:none}

/* Der Rueckfall, wenn es (noch) keinen Kalender gibt.
   EHRLICH: kein leeres Gitter, das so tut, als waere alles ausgebucht. */
.direkt{
  border:1px solid var(--d-linie);border-radius:0;padding:clamp(20px,2.4vw,28px);
  background:var(--schwarz-2);
}
.direkt dl{margin:var(--a-mittel) 0 0;display:grid;gap:var(--a-klein)}
.direkt dt{font-size:var(--fs-label);letter-spacing:.1em;text-transform:uppercase;color:var(--d-grau)}
.direkt dd{margin:4px 0 0;font-size:var(--fs-lead);font-weight:600}
.direkt dd a{color:var(--akzent);text-decoration:none}
.direkt dd a:hover{text-decoration:underline}

/* ═══════════════════════════════════════════════════════════════════════════
   FUSS
   ═══════════════════════════════════════════════════════════════════════════ */
/* GENAU EIN <footer> je Seite. Ein zweiter mitten im Dokument erbt diese
   Regeln — einmal gemessen: 128 px hoch fuer eine Textzeile. */
/* `position:relative` ist hier KEINE Zierde, sondern der Anker fuer
   `footer::before` (das Topo-Muster). Ohne ihn hat das absolut gesetzte
   Pseudoelement keinen positionierten Vorfahren und bezieht `inset:0` auf
   den ANFAENGLICHEN Umriss — also auf ein bildschirmgrosses Rechteck am
   Dokumentanfang. Im Bild: der weisse Hero lag unter dem Muster des
   Seitenfusses, 800 Pixel weiter unten. Zwanzig Minuten gesucht. */
/* NUR die Seitenfusszeile, nicht jedes <footer>. GEMESSEN: die Zeile
   unter dem Kundenzitat steht in einem <footer> und bekam den schwarzen
   Grund der Seitenfusszeile ab — dunkler Text auf dunklem Grund,
   1,03 : 1. Ein Elementselektor fuer ein Bauteil ist die Falle. */
footer.fuss{position:relative;background:var(--schwarz);color:var(--d-grau);
  padding-block:var(--a-gross)}
.fuss__oben{display:flex;flex-wrap:wrap;gap:var(--a-gross);align-items:flex-start;
  justify-content:space-between;padding-bottom:var(--a-gross);
  border-bottom:1px solid var(--d-linie)}
.fuss .lockup span{color:var(--d-text)}
.fuss__links{display:flex;flex-wrap:wrap;gap:22px}
.fuss__links a{font-size:var(--fs-klein);color:var(--d-grau);text-decoration:none}
.fuss__links a:hover{color:var(--akzent)}
.fuss__unten{padding-top:var(--a-gross);display:grid;gap:var(--a-klein);font-size:var(--fs-klein);line-height:1.55}
.fuss__unten p{max-width:760px}

/* ═══════════════════════════════════════════════════════════════════════════
   UNTERSEITEN (Impressum, Datenschutz)
   ═══════════════════════════════════════════════════════════════════════════ */
.rechtstext{max-width:var(--text);padding-block:var(--sekt)}
.rechtstext h1{font-size:var(--fs-h2);margin-bottom:var(--a-mittel)}
.rechtstext h2{font-size:var(--fs-lead);margin:var(--a-gross) 0 var(--a-klein)}
.rechtstext p,.rechtstext li{color:var(--grau)}
.rechtstext p + p{margin-top:var(--a-klein)}
.rechtstext ul{list-style:disc;padding-left:22px;margin-top:var(--a-klein)}
.rechtstext li + li{margin-top:8px}
.rechtstext a{color:var(--akzent-text);font-weight:500}
.rechtstext .platzhalter{color:var(--rot);font-weight:600}

/* ═══ TABELLEN IN DEN RECHTSTEXTEN ═══════════════════════════════════════
   Acht davon stehen in `agb.html` und `auftragsverarbeitung.html`. Bis zum
   28.08.2026 trug jede einen eigenen `<div style="overflow-x:auto">` um
   eine `<table style="min-width:520px">` — und weil die Angaben Pflicht
   sind (Art. 28 Abs. 3 DSGVO fuer die Anlagen, Reaktionszeiten fuer die
   Servicezusage), war das der schlimmste Ort fuer einen Rollkasten.
   GEMESSEN bei 393 px, vorher: 520 px Tabelle in 353 px Kasten; die
   Reaktionszeiten-Tabelle in agb.html zeigte die Spalte „Reaktionszeit"
   gar nicht mehr, und „Beschreibung" brach mitten im Wort ab.

   Die Anordnung lautet „nirgends, wirklich nirgends horizontal scrolls".
   Umgebaut, nicht abgeschaltet: unterhalb von 640 px wird jede ZEILE eine
   KARTE, in der jeder Wert seine Spaltenueberschrift aus `data-spalte`
   mittraegt. Keine Spalte faellt weg. Dieselbe Machart wie
   `.lbw-karten-tabelle` in der App (`06-software/app/src/app/globals.css`).

   Die Stile stehen ab jetzt HIER statt achtmal inline im Quelltext —
   sonst laesst sich die Kartenfassung nicht durchsetzen, weil ein inline
   `border-bottom` an jeder Zelle in der Karte eine Linie je Wert zoege. */
.rechtstext .rtab{margin-top:var(--a-klein)}
.rechtstext .rtab table{border-collapse:collapse;width:100%;text-align:left}
.rechtstext .rtab th{border-bottom:2px solid var(--linie-stark);padding:10px 12px;
  vertical-align:top;font-weight:600;color:var(--tinte)}
.rechtstext .rtab td{border-bottom:1px solid var(--linie);padding:10px 12px;
  vertical-align:top;color:var(--grau)}

/* GEMESSEN am 29.08.2026 bei 768 px an auftragsverarbeitung.html:
   Dokument 821 px gegen 768 px Fenster — 53 px waagerechter Rollbalken,
   Verursacher `thead`/`tbody`/`tr` der Rechtstabellen (20 Elemente ueber der
   Kante). Die Tabelle hat drei Spalten dichten Rechtstexts; ihre
   Mindestbreite betraegt 783 px, verfuegbar sind bei 768 px aber nur
   768 − 2·38,4 = 691 px. `width:100%` hilft dagegen nicht: eine Tabelle
   faellt nicht unter ihre Mindestbreite, sie schiebt.

   Die Hausantwort darauf steht seit jeher hier — Umklappen in Bloecke, mit
   der Spaltenueberschrift aus `data-spalte` vor jedem Wert. Sie griff nur
   zu spaet: unter 640 px. Zwischen 641 px und rund 870 px (dort erst ist
   `Breite − 2·--rand` ≥ 783 px) stand die Tabelle unveraendert und schob.
   Genau in diese Luecke faellt das gaengige Tablet-Mass 768.

   Die Grenze steht jetzt auf 980 px: eine Stufe, die dieses Blatt schon
   benutzt (`.prot`), und sie liegt mit Luft ueber der gerechneten Schwelle.
   Der Auftrag dazu ist unmissverstaendlich und zweimal gestellt:
   „nirgends, wirklich nirgends horizontal scrolls" (27.08. 19:37) und
   „Keine waagerechten Rollbalken. … das hasst jeder."
   Drei Spalten Rechtstext auf einem Tablet zu stapeln liest sich ohnehin
   besser als drei gequetschte Spalten. */
@media (max-width:980px){
  .rechtstext .rtab table,.rechtstext .rtab tbody,
  .rechtstext .rtab tr,.rechtstext .rtab td{display:block}
  .rechtstext .rtab thead{display:none}
  .rechtstext .rtab tr{border-bottom:2px solid var(--linie-stark);padding:10px 0}
  .rechtstext .rtab tr:last-child{border-bottom:0}
  .rechtstext .rtab td{border-bottom:0;padding:2px 0}
  .rechtstext .rtab td::before{content:attr(data-spalte);display:block;
    font-size:var(--fs-label);font-weight:700;letter-spacing:.05em;
    text-transform:uppercase;color:var(--tinte)}
  .rechtstext .rtab td + td{margin-top:6px}
}

/* ── Handy ────────────────────────────────────────────────────────────────── */
@media (max-width:560px){
  .b-gitter--3{grid-template-columns:1fr 1fr}
  .rufe .btn{width:100%}
}

/* ── Druck ────────────────────────────────────────────────────────────────── */
@media print{
  .kopf,.ck-hinter,.buchung__gitter{display:none}
  body{color:#000;background:#fff}
  .band--dunkel{background:#fff;color:#000}
}

/* ═══════════════════════════════════════════════════════════════════════════
   DIE TERMINSEITE — `termin.html`

   Das Formular stand bis zum 24.08. mitten in der Startseite. Es hat jetzt
   eine eigene Seite, und zwar aus einem Grund, der beide Seiten besser
   macht: wer bucht, soll nicht scrollen; wer liest, soll nicht an einem
   Formular vorbei muessen.

   Drei Pflichtangaben, mehr nicht — Name samt Betrieb, Mail, Anliegen.
   Telefon bleibt freiwillig: wer nicht angerufen werden will, soll es nicht
   eintragen muessen.
   ═══════════════════════════════════════════════════════════════════════════ */
.takt{display:grid;grid-template-columns:repeat(3,auto);gap:var(--a-gross);
  margin-top:var(--a-gross);justify-content:start}
.takt li{padding-top:var(--a-klein);border-top:2px solid var(--akzent)}
.takt b{display:block;font-size:var(--fs-body);font-weight:600;letter-spacing:-.015em}
.takt span{display:block;font-size:var(--fs-klein);color:var(--d-grau);margin-top:2px}
@media (max-width:760px){.takt{grid-template-columns:1fr;gap:var(--a-mittel)}}

/* Die Schrittmarke ueber jeder Spalte — sie ersetzt eine Ueberschrift, die
   sonst zweimal dasselbe saegte. */
.schritt{display:block;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--akzent-text);
  padding-bottom:10px;margin-bottom:var(--a-mittel);
  border-bottom:2px solid var(--linie-stark)}

/* Auf der hellen Terminseite steht das Formular NICHT im dunklen Kasten —
   `.direkt` traegt dort seine dunklen Farben. Hier hell und eckig. */
#buchen .direkt{background:none;border:0;padding:0}
#buchen .feld label,#buchen .feld > span{color:var(--grau)}
#buchen .feld input,#buchen .feld textarea{
  background:var(--w);border-color:var(--linie-stark);color:var(--tinte)}
#buchen .feld input::placeholder,#buchen .feld textarea::placeholder{color:#8A8A8A}
#buchen .feld input:focus,#buchen .feld textarea:focus{
  border-color:var(--akzent);box-shadow:0 0 0 3px rgba(59,160,100,.2)}
#buchen .meldung--gut{background:#EAF3EC;color:#245C33;border-color:#B6D6BF}
#buchen .meldung--schlecht{background:#FBECE9;color:#7A2318;border-color:#E6BDB4}

.wunsch{margin-top:var(--a-mittel);padding-top:var(--a-mittel);
  border-top:1px solid var(--linie)}
.wunsch .feld > span{display:block;font-size:var(--fs-label);font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--grau);margin-bottom:6px}

/* ═══════════════════════════════════════════════════════════════════════════
   DAS RECHENBEISPIEL — der Schmerz in Zahlen

   § 5 UWG: hier wird NICHT behauptet, wie viel ein Betrieb verliert. Das
   weiss niemand, und eine erfundene Zahl waere irrefuehrende Werbung. Was
   dasteht, ist eine Rechnung mit SICHTBAREN Eingaben — der Leser setzt seine
   eigenen ein, und die Beschriftung sagt genau das.

   Gestaltung wie ein Rechnungsblatt: Zeilen mit Fuehrungspunkten, darunter
   ein Strich und die Summe. Kein Kasten, keine Karte.
   ═══════════════════════════════════════════════════════════════════════════ */
.rechnung{margin-top:var(--a-gross);max-width:var(--text)}

/* Der Anlauf. Stand vorher als Kleingedrucktes GANZ UNTEN — es war der
   beste Satz des Abschnitts und wurde als letztes gelesen. Jetzt faengt
   er die Rechnung an, und die Kopfzeile („RECHENBEISPIEL — SETZEN SIE
   IHRE ZAHLEN EIN") ist ersatzlos weg: der Text macht ihre Arbeit. */
.rechnung__auf{font-size:var(--fs-body);color:var(--grau);line-height:1.6}
.rechnung__auf strong{font-weight:600;color:var(--tinte)}

/* DIE DREI GROESSEN NEBENEINANDER, mit dem Mal-Zeichen dazwischen — eine
   Rechnung, keine Tabelle und kein Formular. `align-items:baseline` legt
   das × auf die Grundlinie der Zahlen; weil alle drei Zellen dieselbe
   erste Zeile haben, stehen ihre Oberkanten damit ebenfalls auf einer
   Linie, ohne dass irgendwo eine feste Hoehe steht. */
.rechnung__formel{display:flex;align-items:baseline;gap:clamp(10px,3vw,28px);
  margin-top:var(--a-mittel);max-width:var(--text)}
.rechnung__groesse{flex:1;border-top:2px solid var(--linie-stark);padding-top:10px}
.rechnung__groesse b{display:block;font-size:var(--fs-zahl);font-weight:700;
  letter-spacing:-.02em;line-height:1.1;color:var(--tinte);
  font-variant-numeric:tabular-nums}
.rechnung__groesse span{display:block;margin-top:5px;font-size:var(--fs-label);
  font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--grau)}
.rechnung__op{font-size:var(--fs-zahl);line-height:1.1;color:var(--akzent-text)}

/* Die drei Linien laufen sichtbar auf EIN Ergebnis zu. `non-scaling-stroke`,
   weil `preserveAspectRatio:none` sonst die senkrechten Striche breiter
   zoege als den waagerechten — derselbe Kniff wie beim Kartenrahmen. */
.rechnung__lauf{display:block;width:100%;height:44px;margin-top:14px;
  max-width:var(--text);fill:none;stroke:var(--akzent);stroke-width:2}

/* Der Hoehepunkt. Zaehlt beim Hereinscrollen hoch (`data-zaehl` in
   main.js) — deshalb Tabellenziffern, sonst wackelt die Breite bei jedem
   Schritt. OHNE Skript und bei abgeschalteter Bewegung steht der Endwert
   sofort da; im Markup steht nichts anderes als 7 920 €. */
.rechnung__erg{margin-top:8px;text-align:center}
.rechnung__zahl{display:block;font-size:var(--fs-display);font-weight:600;
  letter-spacing:-.035em;line-height:1;color:var(--akzent-text);
  font-variant-numeric:tabular-nums}
.rechnung__erg span{display:block;margin-top:12px;font-size:var(--fs-label);
  font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--tinte)}

/* § 5 UWG im Klartext, direkt unter der Zahl — nicht als Fussnote am
   Blattende. */
.rechnung__bei{margin-top:var(--a-mittel);padding-top:var(--a-klein);
  border-top:1px solid var(--linie);font-size:var(--fs-klein);
  line-height:1.55;color:var(--grau);max-width:var(--text)}
.rechnung__bei b{font-weight:700;color:var(--tinte)}

/* Schmal: die Rechnung bleibt waagerecht — sie IST eine Zeile. Nur die
   Zulauf-Linie wird flacher, damit sie nicht zum Loch wird. */
@media (max-width:560px){
  .rechnung__lauf{height:30px}
  .rechnung__groesse span{letter-spacing:.05em}
}

/* Zwischenueberschrift innerhalb eines Abschnitts. Sie benutzt die
   vorhandene Stufe --fs-lead, keine neue. */
.teil-h{margin-top:var(--a-gross);font-size:var(--fs-lead);letter-spacing:-.02em;
  padding-top:var(--a-klein);border-top:2px solid var(--akzent);display:inline-block}
.karte h4{font-size:var(--fs-body);font-weight:600;letter-spacing:-.015em;
  margin-bottom:var(--a-klein)}

/* ═══════════════════════════════════════════════════════════════════════════
   DIE BELEGE BEWEGEN SICH — aber verstecken nichts

   Ansage, dreimal: „alle demos animieren", „die demo geiler machen".

   ═══ DIE REGEL, DIE HIER NICHT GEBROCHEN WIRD ════════════════════════════
   Jeder Grundzustand ist der FERTIGE. Die Animation setzt den Anfangswert
   ausschliesslich ueber `both` INNERHALB ihrer Laufzeit, und sie laeuft nur
   unter `prefers-reduced-motion: no-preference`. Faellt sie aus — altes
   Geraet, abgeschaltete Bewegung, Standbild-Modus, verborgenes Fenster —,
   steht jeder Beleg vollstaendig da.

   Das ist der Unterschied zur Vorgaengerfassung dieser Website, in der 58
   Bloecke auf `opacity: 0` standen und nur sichtbar wurden, WENN ein
   IntersectionObserver meldete. Gemessen: 0 von 58 sichtbar, sobald er
   schwieg.

   Und: KEINE Endlosschleife auf einem Inhalt. Was laeuft, laeuft einmal.
   Endlos laufen nur zwei Dinge, und beide sind Zierrat: der Impuls im Netz
   und der Fortschrittsbalken-Schimmer.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion:no-preference){

  /* ── Der Fortschrittsbalken waechst auf seinen Wert ──────────────────────
     `transform: scaleX` statt `width`: eine Breitenaenderung rechnet das
     Layout neu, eine Verschiebung nicht. Bei sechs Balken auf einer Seite
     ist das der Unterschied zwischen fluessig und ruckelig. */
  .b-fort i{transform-origin:left center;
    animation:bl-fort .9s cubic-bezier(.22,.61,.36,1) .25s both}

  /* ── Die Punkte des Jahresplans erscheinen monatsweise ───────────────────
     Zwoelf Spalten, jede 40 ms spaeter. Der Blick laeuft dadurch von Januar
     nach Dezember — genau die Richtung, in der man den Plan liest.
     `nth-child` statt einer Variablen je Punkt: 48 Inline-Stile im Markup
     waeren dieselbe Aussage, nur unwartbar. */
  .jp-band .jp-punkt{animation:bl-tupfen .34s ease both}
  .jp-band .jp-punkt:nth-child(1){animation-delay:.10s}
  .jp-band .jp-punkt:nth-child(2){animation-delay:.14s}
  .jp-band .jp-punkt:nth-child(3){animation-delay:.18s}
  .jp-band .jp-punkt:nth-child(4){animation-delay:.22s}
  .jp-band .jp-punkt:nth-child(5){animation-delay:.26s}
  .jp-band .jp-punkt:nth-child(6){animation-delay:.30s}
  .jp-band .jp-punkt:nth-child(7){animation-delay:.34s}
  .jp-band .jp-punkt:nth-child(8){animation-delay:.38s}
  .jp-band .jp-punkt:nth-child(9){animation-delay:.42s}
  .jp-band .jp-punkt:nth-child(10){animation-delay:.46s}
  .jp-band .jp-punkt:nth-child(11){animation-delay:.50s}
  .jp-band .jp-punkt:nth-child(12){animation-delay:.54s}

  /* ── Die Nummernfolge der Protokolle baut sich auf ───────────────────────
     47 Kaestchen, jedes 12 ms spaeter — knapp 0,6 s fuer den ganzen
     Abschnitt. Die Luecke bleibt dabei die einzige Stelle, an der nichts
     erscheint, und genau darum geht es. */
  .folge .fg{animation:bl-tupfen .28s ease both;
    animation-delay:calc(var(--i, 0) * 12ms + 200ms)}

  /* ── Zeilen eines Belegs laufen von oben ein ─────────────────────────────
     Nur 4 px Versatz. Mehr sieht nach Folienuebergang aus. */
  .beleg .b-zeile{animation:bl-zeile .4s cubic-bezier(.22,.61,.36,1) both}
  .beleg .b-zeile:nth-child(1){animation-delay:.06s}
  .beleg .b-zeile:nth-child(2){animation-delay:.12s}
  .beleg .b-zeile:nth-child(3){animation-delay:.18s}
  .beleg .b-zeile:nth-child(4){animation-delay:.24s}
  .beleg .b-zeile:nth-child(5){animation-delay:.30s}
  .beleg .b-zeile:nth-child(6){animation-delay:.36s}

  /* ── Die Warnung kommt zuletzt und meldet sich ───────────────────────────
     Sie ist der Punkt jedes dieser Belege: „hier stimmt etwas nicht".
     Deshalb erscheint sie NACH den Zeilen, auf die sie sich bezieht. */
  .beleg .b-warn{animation:bl-warn .5s cubic-bezier(.22,.61,.36,1) .55s both}

  /* ── Ein offener Zustand pulst, ein erledigter nicht ─────────────────────
     Die einzige Endlosbewegung an einem Inhalt — und sie traegt eine
     Aussage: „wartet auf dich". Sehr flach (Deckkraft 1 bis .55), damit sie
     im Augenwinkel bleibt und nicht im Blickfeld. */
  .b-marke--an{animation:bl-warten 2.6s ease-in-out 1.2s infinite}
}

@keyframes bl-fort{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes bl-tupfen{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
@keyframes bl-zeile{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
@keyframes bl-warn{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:none}}
@keyframes bl-warten{0%,100%{opacity:1}50%{opacity:.55}}

/* ═══════════════════════════════════════════════════════════════════════════
   DER TAGESPLAN — mit Zeitachse, wie ein Tagesplan aussieht

   Ansage: „planungsdemo näher an realität". Drei Listenzeilen mit einem
   Zustandswort dahinter sind kein Plan. Ein Plan hat eine Achse, Kolonnen
   als Zeilen und Einsaetze als Balken darauf — und das Gespann steht dabei,
   weil genau daran die Pruefung haengt.

   Die Balken sitzen ueber `--von` und `--breite` in Prozent der Achse
   (6 bis 18 Uhr). Gerechnet wird das beim Erzeugen, nicht im Browser: ein
   Prozentwert im Markup ist nachpruefbar, eine Rechnung im Stilblatt nicht.
   ═══════════════════════════════════════════════════════════════════════════ */
.tp-achse{display:flex;justify-content:space-between;
  padding:0 0 6px;margin-bottom:8px;border-bottom:1px solid var(--linie);
  font-size:var(--fs-label);color:var(--grau);font-variant-numeric:tabular-nums}

.tp-zeile{padding:10px 0;border-bottom:1px solid var(--linie)}
.tp-zeile:last-of-type{border-bottom:0}
.tp-kopf{display:flex;align-items:baseline;gap:10px;margin-bottom:6px}
.tp-kopf b{font-size:var(--fs-klein);font-weight:600;letter-spacing:-.01em}
.tp-kopf span{font-size:var(--fs-label);color:var(--grau)}

/* Die Bahn ist die Zeitachse; der Balken liegt darauf. Ein feines Raster im
   Hintergrund zeigt die Stunden, ohne zwoelf Linien ins Markup zu schreiben. */
.tp-bahn{position:relative;height:26px;background:var(--papier);
  background-image:repeating-linear-gradient(to right,
    var(--linie) 0 1px, transparent 1px calc(100% / 6));
  border:1px solid var(--linie)}
.tp-balken{position:absolute;top:3px;bottom:3px;
  left:var(--von);width:var(--breite);
  background:var(--schwarz);display:flex;align-items:center;gap:6px;
  padding:0 8px;overflow:hidden}
.tp-balken__text{font-size:var(--fs-label);font-weight:600;color:var(--d-text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Der Konflikt ist KEIN roter Balken — rot hiesse „Baustelle abgesagt".
   Er ist derselbe Balken mit einer roten Kante und einem Zeichen. */
.tp-balken--konflikt{background:var(--rot)}
.tp-warnzeichen{flex:0 0 auto;width:15px;height:15px;background:var(--w);
  color:var(--rot);font-size:var(--fs-label);font-weight:700;line-height:15px;
  text-align:center}
.tp-gespann{margin-top:6px;font-size:var(--fs-label);color:var(--grau)}

@media (prefers-reduced-motion:no-preference){
  /* Der Balken waechst aus seinem Anfangszeitpunkt heraus — nicht aus der
     Mitte. Ein Einsatz beginnt links und endet rechts. */
  .tp-balken{transform-origin:left center;
    animation:tp-wachsen .55s cubic-bezier(.22,.61,.36,1) var(--verz,0s) both}
  .tp-zeile{animation:tp-zeile .4s ease var(--verz,0s) both}
}
@keyframes tp-wachsen{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes tp-zeile{from{opacity:0}to{opacity:1}}

/* ═══════════════════════════════════════════════════════════════════════════
   DER WEG — die fünf Stationen auf `leistung.html`

   Kein Nummernkranz und kein Pfeilband: eine Reihe mit Trennstrichen. Was
   die Reihenfolge sagt, sagt die Reihenfolge; ein Pfeil dazwischen ist ein
   Wort, das man schon gelesen hat.
   ═══════════════════════════════════════════════════════════════════════════ */
.weg{display:grid;grid-template-columns:repeat(5,1fr);gap:0;
  margin-top:var(--a-gross);counter-reset:w}
.weg li{padding:var(--a-klein) var(--a-mittel) 0 0;position:relative}
.weg li + li{padding-left:var(--a-mittel);border-left:1px solid var(--d-linie)}
.weg li::before{counter-increment:w;content:"0" counter(w);
  display:block;font-size:var(--fs-label);font-weight:700;letter-spacing:.14em;
  color:var(--akzent);margin-bottom:6px}
.weg b{display:block;font-size:var(--fs-body);font-weight:600;letter-spacing:-.015em}
.weg span{display:block;font-size:var(--fs-klein);color:var(--d-grau);margin-top:2px}
@media (max-width:900px){
  .weg{grid-template-columns:1fr 1fr}
  .weg li{padding:var(--a-klein) var(--a-mittel) var(--a-klein) 0}
  .weg li + li{border-left:0}
}
@media (prefers-reduced-motion:no-preference){
  .weg li{animation:wg-auf .45s ease both}
  .weg li:nth-child(1){animation-delay:.10s}
  .weg li:nth-child(2){animation-delay:.18s}
  .weg li:nth-child(3){animation-delay:.26s}
  .weg li:nth-child(4){animation-delay:.34s}
  .weg li:nth-child(5){animation-delay:.42s}
}
@keyframes wg-auf{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ═══════════════════════════════════════════════════════════════════════════
   DAS AUFMASS ENTSTEHT — die Zeichnung baut sich auf

   Von der alten Seite übernommen: dort zog sich die Fläche auf dem Luftbild
   Punkt für Punkt zusammen, statt fertig dazustehen. Genau das ist die
   Aussage des Moduls — die Kante wird NACHGEZEICHNET, nicht gerundet. Ein
   fertiges Vieleck zeigt das Ergebnis; die entstehende Linie zeigt die
   Arbeit.

   Der alte Film lief 14 Sekunden in Endlosschleife samt Mauszeiger. Das
   bleibt draussen: eine Schleife kostet dauerhaft Rechenzeit und wird nach
   dem zweiten Durchlauf zur Unruhe. Hier läuft es einmal, wenn die Zeichnung
   ins Bild kommt.

   GRUNDZUSTAND IST DER ENDZUSTAND. Zurückgenommen wird nur unterhalb von
   `html.js-malt` — die Klasse setzt `main.js` ausschliesslich dann, wenn
   Bewegung erlaubt und die Seite nicht eingefroren ist. Fällt das Skript
   aus, steht das fertige Aufmaß da. Ebenso ohne `:has()` (ältere Browser):
   die Regeln greifen dann nicht, das Bild bleibt vollständig.
   ═══════════════════════════════════════════════════════════════════════════ */
.js-malt .lb-flaeche{opacity:0}
.js-malt .lb:has(.lb-kante.gemalt) .lb-flaeche{opacity:1;transition:opacity .55s ease .5s}

/* Die Griffe werden gesetzt, einer nach dem anderen — in der Reihenfolge,
   in der jemand sie klicken würde. `transform-box:fill-box` ist Pflicht:
   ohne sie bezieht sich `transform-origin:center` auf den Ursprung des
   Zeichenbereichs, und die Kreise fahren aus der Ecke ins Bild. */
.js-malt .lb-griffe circle{opacity:0;transform:scale(.2);
  transform-box:fill-box;transform-origin:center}
.js-malt .lb:has(.lb-kante.gemalt) .lb-griffe circle{opacity:1;transform:none;
  transition:opacity .18s ease,transform .3s cubic-bezier(.34,1.56,.64,1)}
.js-malt .lb:has(.lb-kante.gemalt) .lb-griffe circle:nth-child(1){transition-delay:.62s}
.js-malt .lb:has(.lb-kante.gemalt) .lb-griffe circle:nth-child(2){transition-delay:.74s}
.js-malt .lb:has(.lb-kante.gemalt) .lb-griffe circle:nth-child(3){transition-delay:.86s}
.js-malt .lb:has(.lb-kante.gemalt) .lb-griffe circle:nth-child(4){transition-delay:.98s}

/* Zuletzt die Zahl. Sie steht erst da, wenn die Fläche steht — vorher gibt
   es nichts zu rechnen. */
.js-malt .lb-schrift{opacity:0}
.js-malt .lb:has(.lb-kante.gemalt) .lb-schrift{opacity:1;transition:opacity .4s ease 1.15s}

@media (prefers-reduced-motion:reduce){
  .js-malt .lb-flaeche,.js-malt .lb-schrift{opacity:1}
  .js-malt .lb-griffe circle{opacity:1;transform:none}
}

/* ═══════════════════════════════════════════════════════════════════════════
   DIE BUCHUNGSSTRECKE — links WAS, rechts WANN

   Der Schnitt ist bewusst der, den jedes Buchungswerkzeug benutzt: wer hier
   landet, hat ihn schon hundertmal bedient und braucht keine Anleitung.
   Nur die Mittel sind unsere: keine abgerundeten Ecken, kein Schatten,
   Kanten statt Kästen, Orange nur da, wo etwas gewählt ist.
   ═══════════════════════════════════════════════════════════════════════════ */
.buchung{display:grid;grid-template-columns:minmax(0,360px) minmax(0,1fr);
  gap:0;border:1px solid var(--linie);margin-top:var(--a-mittel)}
.buchung__karte{padding:var(--a-mittel);border-right:1px solid var(--linie);
  display:flex;flex-direction:column;gap:var(--a-mittel)}
.buchung__marke{display:flex;align-items:center;gap:10px;
  padding-bottom:var(--a-klein);border-bottom:1px solid var(--linie)}
.buchung__marke img{height:32px;width:auto;display:block}
.buchung__marke span{font-family:var(--f-marke,var(--f));font-size:var(--fs-lead);
  font-weight:700;letter-spacing:-.02em;color:var(--tinte)}
.buchung__marke i{color:var(--akzent);font-style:normal}
.buchung__firma{display:block;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grau)}
.buchung__titel{margin-top:6px;font-size:var(--fs-h3);font-weight:600;
  letter-spacing:-.03em;line-height:1.1;color:var(--tinte)}
.buchung__daten{list-style:none;margin:var(--a-mittel) 0 0;padding:0;
  display:flex;flex-direction:column;gap:12px}
.buchung__daten li{display:flex;gap:10px;align-items:flex-start;
  font-size:var(--fs-klein);color:var(--grau)}
.buchung__daten li:first-child{font-weight:700;color:var(--tinte)}
.buchung__daten svg{width:18px;height:18px;flex:none;margin-top:1px;
  fill:none;stroke:var(--akzent);stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.buchung__text{margin-top:var(--a-mittel);font-size:var(--fs-klein);color:var(--grau)}
.buchung__fuss{margin-top:auto;font-size:var(--fs-label);color:var(--grau)}
.buchung__fuss a{color:var(--akzent-text);font-weight:600}

.buchung__wann{padding:var(--a-mittel)}
/* ═══ `hidden` MUSS GEWINNEN ═════════════════════════════════════════════
   GEMESSEN im Bild: der Kasten „gewählter Termin" stand da, obwohl nichts
   gewählt war — mit dem Wort „ändern" daneben. Ursache ist keine Logik,
   sondern die Rangfolge: das HTML-Attribut `hidden` wirkt über die
   Vorgabe `display:none` des Browsers, und JEDE eigene `display`-Regel
   schlägt sie. Wer `display:flex` oder `display:grid` an ein Element
   schreibt, das mit `hidden` versteckt wird, muss das hier nachziehen. */
.buchung [hidden],.anfrage [hidden],.slotspalte[hidden]{display:none}
.buchung__h{font-size:var(--fs-lead);font-weight:600;letter-spacing:-.02em;
  color:var(--tinte);margin-bottom:var(--a-mittel)}

/* ── Der Kalender ────────────────────────────────────────────────────────── */
.kalender__kopf{display:flex;align-items:center;justify-content:center;gap:var(--a-mittel)}
.kalender__kopf b{font-size:var(--fs-body);font-weight:600;letter-spacing:-.01em;
  min-width:11ch;text-align:center}
.kalender__kopf button{width:36px;height:36px;border:1px solid var(--linie);
  background:var(--w);color:var(--tinte);font-size:var(--fs-body);line-height:1;
  cursor:pointer;transition:border-color .15s,color .15s}
.kalender__kopf button:hover:not(:disabled){border-color:var(--akzent);color:var(--akzent-text)}
/* ═══ EIN GESPERRTER TAG BLEIBT LESBAR ═══════════════════════════════════
   Hier stand `--linie-stark` (#CFCCC6): auf Weiss 1,6 : 1 — die Zahl war
   praktisch nicht zu entziffern. WCAG nimmt deaktivierte Bedienelemente
   zwar vom Mindestkontrast aus (1.4.3, „incidental"), aber ein Datum, das
   man nicht lesen kann, macht den Kalender unbrauchbar: man sieht dann
   nicht mehr, WELCHER Tag belegt ist. `--grau-leise` (#767676) trägt
   4,54 : 1 und bleibt gegenüber dem Orange der freien Tage deutlich
   zurückgenommen. */
.kalender__kopf button:disabled{color:var(--grau-leise);cursor:default}

/* Der Kalender bleibt schmal und steht mittig. Ohne die Begrenzung dehnen
   sich die Tageszellen über die halbe Seitenbreite — bei `aspect-ratio:1`
   wird ein August dann 900 px hoch. */
.kalender{max-width:440px;margin:0 auto}
.kal-wochentage,.kal-gitter{display:grid;grid-template-columns:repeat(7,1fr)}
.kal-wochentage{margin-top:var(--a-mittel);gap:2px}
.kal-wochentage span{text-align:center;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.08em;color:var(--grau);padding-bottom:8px}
.kal-gitter{gap:2px}
.kal-tag{aspect-ratio:1;display:flex;align-items:center;justify-content:center;
  border:0;background:transparent;font-size:var(--fs-klein);font-family:inherit;
  font-variant-numeric:tabular-nums;color:var(--tinte);cursor:pointer;
  transition:background-color .15s,color .15s}
.kal-tag--leer{cursor:default}
/* Ein Tag ohne freie Zeit ist NICHT anklickbar und sagt das auch: blass,
   ohne Zeiger. Ausgegraut UND klickbar wäre die schlechtere Hälfte von
   beidem. */
.kal-tag:disabled{color:var(--grau-leise);cursor:default}
.kal-tag--frei{background:var(--akzent-hauch);font-weight:600;color:var(--akzent-tief)}
.kal-tag--frei:hover{background:var(--akzent);color:#fff}
.kal-tag--an{background:var(--akzent);color:#fff;font-weight:700}
.kal-tag--heute{box-shadow:inset 0 -2px 0 var(--tinte)}
/* Bei 375px zwingt die Kartenpolsterung (--a-mittel, 32px je Seite) die
   sieben Tagesspalten auf 37x37px — unter dem 44px-Ziel fuer Finger. Die
   Karte behaelt ihre Polsterung fuer Ueberschrift und Text; nur der
   Kalender selbst bricht mit negativem Rand aus ihr aus und gewinnt so
   Breite zurueck. */
@media (max-width:520px){
  .kalender{margin-inline:-28px}
}

.kal-zone{display:flex;align-items:center;gap:8px;margin-top:var(--a-mittel);
  padding-top:var(--a-klein);border-top:1px solid var(--linie);
  font-size:var(--fs-label);color:var(--grau)}
.kal-zone svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.6}

/* ── Die Uhrzeiten ───────────────────────────────────────────────────────── */
.slotspalte{margin-top:var(--a-mittel);padding-top:var(--a-mittel);
  border-top:1px solid var(--linie)}
.slotspalte__kopf{font-size:var(--fs-klein);font-weight:700;color:var(--tinte);
  margin-bottom:var(--a-klein)}
.slots{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:8px}
.slots button{padding:10px 4px;border:1px solid var(--linie-stark);background:var(--w);
  font-family:inherit;font-size:var(--fs-klein);font-weight:600;
  font-variant-numeric:tabular-nums;color:var(--tinte);cursor:pointer;
  transition:border-color .15s,background-color .15s,color .15s}
.slots button:hover{border-color:var(--akzent);color:var(--akzent-text)}
.slots button[aria-pressed="true"]{background:var(--akzent-knopf);border-color:var(--akzent-knopf);color:#fff}

/* ── Das Formular ────────────────────────────────────────────────────────── */
.anfrage{margin-top:var(--a-gross);max-width:var(--text)}
.anfrage__gewaehlt{display:flex;align-items:center;justify-content:space-between;
  gap:var(--a-klein);padding:12px var(--a-klein);
  background:var(--akzent-hauch);border-left:3px solid var(--akzent);
  font-size:var(--fs-klein);font-weight:600;color:var(--akzent-tief);
  margin-bottom:var(--a-mittel)}
.anfrage__gewaehlt button{border:0;background:transparent;font-family:inherit;
  font-size:var(--fs-label);font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--akzent-text);cursor:pointer;
  text-decoration:underline;text-underline-offset:3px}
.anfrage .feldsatz{display:grid;grid-template-columns:1fr 1fr;gap:var(--a-klein);
  border:0;padding:0;margin:0}
.anfrage .feld--breit{grid-column:1 / -1}
.anfrage .btn{width:100%;margin-top:var(--a-mittel)}
.anfrage .klein{margin-top:var(--a-klein)}
.anfrage .klein a{color:var(--akzent-text);font-weight:600}

@media (max-width:900px){
  .buchung{grid-template-columns:1fr}
  .buchung__karte{border-right:0;border-bottom:1px solid var(--linie)}
  .anfrage .feldsatz{grid-template-columns:1fr}
}

/* Das Formular ist Schritt 2 und startet verborgen. `hidden` allein reicht
   nicht — siehe die Anmerkung bei `.buchung [hidden]`. */
.anfrage[hidden]{display:none}
.anfrage .schritt{display:block;margin-bottom:var(--a-klein)}
#weiter{width:100%;margin-top:var(--a-mittel)}


/* Der Kachelrahmen läuft über dasselbe System wie jeder gezeichnete Strich:
   `.malt` bekommt seine Länge von `main.js` gemessen, `.gemalt` löst das
   Zeichnen aus. Ohne Skript ist `--laenge` nicht gesetzt und die Kachel
   steht vollständig da — das ist die sichere Richtung. */
.js-malt .karte__rahmen path.malt.gemalt{
  transition:stroke-dashoffset 1.05s cubic-bezier(.22,.61,.36,1)}

/* ═══════════════════════════════════════════════════════════════════════════
   DER FUNNEL — eine Stufe sichtbar, nie zwei

   Vorher klappte das Formular unter dem Kalender auf. Jetzt tritt der
   Kalender ab und die Angaben stehen an derselben Stelle; nach dem
   Absenden tritt auch das Formular ab und der Haken steht dort.
   ═══════════════════════════════════════════════════════════════════════════ */
.stufe[hidden]{display:none}
@media (prefers-reduced-motion:no-preference){
  .stufe:not([hidden]){animation:st-auf .3s cubic-bezier(.22,.61,.36,1) both}
}
@keyframes st-auf{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

.stufe--fertig{display:grid;place-items:center;min-height:320px}
.quittung{text-align:center;max-width:36ch}
.quittung__kopf{font-size:var(--fs-lead);font-weight:600;letter-spacing:-.02em;
  color:var(--tinte);margin-top:var(--a-mittel)}
.quittung__text{font-size:var(--fs-klein);color:var(--grau);margin-top:8px}
.quittung .btn{margin-top:var(--a-mittel)}

/* ── Ring und Haken ──────────────────────────────────────────────────────
   Zwei Kreise übereinander: eine blasse Spur und ein Bogen, der darauf
   dreht. Ist es durch, wird aus dem Bogen ein voller Ring und der Haken
   zeichnet sich hinein. Alles Pfade — kein Bild, kein Zeichensatz. */
.ring{width:64px;height:64px;display:block;margin:0 auto;overflow:visible}
.ring circle{fill:none;stroke-width:4}
.ring__spur{stroke:var(--linie)}
.ring__bogen{stroke:var(--akzent);stroke-linecap:round;
  stroke-dasharray:40 130;stroke-dashoffset:0;
  transform-box:fill-box;transform-origin:center}
.ring__haken{fill:none;stroke:var(--akzent);stroke-width:5;
  stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:44;stroke-dashoffset:44}

/* Ruhezustand OHNE Klasse: voller Ring, gesetzter Haken. Wer das Skript
   nicht hat, sieht ein fertiges Zeichen und keinen halben. */
.quittung.laeuft .ring__haken{stroke-dashoffset:44}
.quittung.fertig .ring__bogen{stroke-dasharray:170 0;
  transition:stroke-dasharray .34s cubic-bezier(.22,.61,.36,1)}
.quittung.fertig .ring__haken{stroke-dashoffset:0;
  transition:stroke-dashoffset .4s cubic-bezier(.22,.61,.36,1) .2s}

@media (prefers-reduced-motion:no-preference){
  .quittung.laeuft .ring__bogen{animation:ring-dreh 1s linear infinite}
}
@keyframes ring-dreh{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  .quittung .ring__bogen{stroke-dasharray:170 0}
  .quittung .ring__haken{stroke-dashoffset:0}
}


/* ═══ FETT AUF DUNKEL TRÄGT DEN AKZENT ═══════════════════════════════════
   Auf dunklem Grund war ein fettes Wort nur fett — es hob sich vom
   umgebenden Text kaum ab, weil beides hell war. Werkgruen trägt dort
   6,04 : 1 und ist damit auch als Fliesstext zulässig.

   NUR im dunklen Band: auf Weiss hätte #3BA064 bloss 3,28 : 1 und wäre für
   ein Wort in Textgrösse zu wenig — dort bleibt es bei --akzent-text. */
/* ═══ NUR AUF DEM DUNKLEN GRUND SELBST ═══════════════════════════════════
   Erster Anlauf färbte JEDES fette Wort im dunklen Band ein — auch die
   in den weissen Belegen, die darin liegen. GEMESSEN: 12 Verstösse, weil
   #3BA064 auf Weiss nur 3,28 : 1 trägt. Die Ausnahmen unten sind genau die
   hellen Inseln im dunklen Band. */
.band--dunkel :is(strong,b):not(.beleg *):not(.b-telefon *):not(.rechnung *):not(.karte *):not(.vfg-screen *):not(.vfp-screen *):not(.vfm-phone *):not(.vfa *):not(.wa *):not(.blatt *){
  color:var(--akzent)}
.band--dunkel .mark{background:none;color:var(--akzent);
  box-shadow:inset 0 -2px 0 var(--akzent)}

/* ═══ DAS RECHENBEISPIEL AUF DUNKLEM GRUND ═══════════════════════════════
   Der Abschnitt ist am 24.08. auf Schwarz gewechselt; die Rechnung darin
   stand noch auf den hellen Rollen und war stellenweise unlesbar (die
   Zeile „Nicht gestellt, aber bezahlt" mass 1,03 : 1 — Schwarz auf
   Schwarz). Nachgezogen und nachgerechnet. */
.band--dunkel .rechnung__auf{color:var(--d-grau)}
.band--dunkel .rechnung__auf strong{color:var(--akzent)}
.band--dunkel .rechnung__groesse{border-top-color:rgba(255,255,255,.28)}
.band--dunkel .rechnung__groesse b{color:var(--d-text)}
.band--dunkel .rechnung__groesse span{color:var(--d-grau)}
.band--dunkel .rechnung__op{color:var(--akzent)}
.band--dunkel .rechnung__zahl{color:var(--akzent)}
.band--dunkel .rechnung__erg span{color:var(--d-text)}
.band--dunkel .rechnung__bei{color:var(--d-grau);border-top-color:rgba(255,255,255,.14)}
.band--dunkel .rechnung__bei b{color:var(--d-text)}
.band--dunkel .teil-h{color:var(--d-text)}
.band--dunkel .kante{color:var(--d-text)}
.band--dunkel .karte h3,.band--dunkel .karte h4{color:var(--d-text)}
.band--dunkel .fliess p{color:var(--d-grau)}

/* ═══ DEAD SPACE IM BÖSCHUNGS-ABSCHNITT ═════════════════════════════════
   Beanstandet: „bei der Demo is so viel dead space". Ursache war
   `align-items:center` bei zwei ungleich hohen Spalten — die kürzere bekam
   oben und unten Luft, die niemand füllt. `start` lässt beide oben
   anfangen; die Lücke steht dann unten, wo sie nicht auffällt. */
.ref__gitter{align-items:start}
.bo-raster{align-items:start}

/* ═══════════════════════════════════════════════════════════════════════════
   DIE ZÄSUR — ein Themenwechsel INNERHALB eines Abschnitts

   Zwei Themen unter einer Überschrift („was es kostet" und „woran es
   liegt") waren nur durch Abstand getrennt und lasen sich als eins.
   Die Linie mit dem Winkel darin macht den Übergang sichtbar, ohne einen
   zweiten Abschnitt aufzumachen: sie zeigt nach unten und sagt, dass jetzt
   etwas anderes kommt.
   ═══════════════════════════════════════════════════════════════════════════ */
.zaesur{display:flex;align-items:center;gap:var(--a-mittel);
  margin:var(--a-gross) 0 var(--a-mittel)}
.zaesur__strich{flex:1;height:1px;background:var(--linie)}
.band--dunkel .zaesur__strich{background:rgba(255,255,255,.16)}
.zaesur__marke{flex:none;width:38px;height:38px;display:grid;place-items:center;
  border:1px solid var(--akzent)}
.zaesur__marke svg{width:18px;height:18px;fill:none;stroke:var(--akzent);
  stroke-width:2;stroke-linecap:square;stroke-linejoin:miter}

/* Der Winkel fährt einmal herunter, wenn die Zäsur ins Bild kommt — und
   steht danach still. Ohne erlaubte Bewegung steht er von Anfang an. */
@media (prefers-reduced-motion:no-preference){
  .zaesur__marke svg{animation:za-tipp 2.6s ease-in-out 1.2s 2 both}
}
@keyframes za-tipp{
  0%,72%,100%{transform:translateY(0)}
  80%{transform:translateY(3px)}
  88%{transform:translateY(0)}
}

/* ═══ KACHELN EINER GRUPPE SIND GLEICH GEBAUT ════════════════════════════
   Ansage: „zusammenhängende Kacheln immer selbe Zeilenanzahl und selbe
   Größe". Die Textlängen sind dafür im Markup angeglichen (Spanne jetzt
   unter 20 Zeichen je Gruppe). Was der Text allein nicht schafft, hält
   diese Regel: die Überschrift belegt IMMER zwei Zeilen, damit der
   Absatz darunter in jeder Kachel auf derselben Höhe beginnt. Ohne sie
   rutscht der Text der einzeiligen Kachel eine Zeile nach oben, und die
   Reihe franst aus. */
.karte h3,.karte h4{min-height:2.4em;display:flex;align-items:flex-start}
@media (max-width:640px){.karte h3,.karte h4{min-height:0;display:block}}

/* ═══════════════════════════════════════════════════════════════════════════
   DIE VIER VERMESSERPUNKTE

   Draussen misst niemand einen Winkel. Der Vermesser liefert Punkte mit
   Rechtswert, Hochwert und HÖHE — die Neigung ist das Ergebnis. Deshalb
   steht die Messung als Tabelle da und nicht als Regler mit Gradzahl.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ═══ VIER PUNKTE, NEBENEINANDER ═════════════════════════════════════════
   Als Tabelle mit je zwei Zeilen belegten sie rund 300 px Höhe und zogen
   den ganzen Beleg in die Länge — beanstandet als „demo is ewig nach unten
   gestreckt". Vier schmale Blöcke tragen dasselbe auf einem Viertel der
   Höhe: Punkt, Höhe, was er ist, wo er liegt. */
.bo-punkte{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;
  background:var(--linie);border:1px solid var(--linie);
  margin-bottom:var(--a-mittel)}
.bo-punkte > div{background:var(--w);padding:8px 9px;min-width:0}
.bo-punkte b{display:block;font-size:var(--fs-klein);font-weight:700;
  color:var(--akzent-text);line-height:1}
.bo-h{display:block;margin-top:4px;font-size:var(--fs-klein);font-weight:700;
  color:var(--tinte);font-variant-numeric:tabular-nums}
.bo-was{display:block;font-size:var(--fs-label);color:var(--grau);margin-top:1px}
.bo-lage{display:block;font-size:var(--fs-label);color:var(--grau);margin-top:5px;
  font-variant-numeric:tabular-nums;line-height:1.3}
@media (max-width:760px){.bo-punkte{grid-template-columns:1fr 1fr}}

/* Beschriftung der Punkte IM Luftbild. Sie liegt ausserhalb des Clips und
   trägt eine dunkle Hinterlegung, weil ein Luftbild jede Helligkeit haben
   kann — weisse Schrift ohne Grund ist auf hellem Sand unlesbar. */
.lb-punkte text{font-family:var(--f);font-size:var(--fs-label);font-weight:700;
  fill:#fff;paint-order:stroke;stroke:rgba(11,11,11,.85);stroke-width:4;
  stroke-linejoin:round;letter-spacing:.02em}

/* ═══════════════════════════════════════════════════════════════════════════
   DAS PUZZLE — Bausteine, die ineinandergreifen

   Zweiter Anlauf: „edler bauen, animiert zusammensetzen wenn gescrollt
   wird". Edel heisst hier NICHT mehr Zierrat, sondern weniger: eine
   feinere Kante, ein ruhiger Wechsel zwischen Weiss und Papier statt
   sechsmal derselben Fläche, und Beschriftungen, die Luft haben.

   Die Zapfen sind gerechnet, nicht gezeichnet — die rechte Kante eines
   Teils steht genau so weit vor, wie die linke des Nachbarn zurückspringt.
   ═══════════════════════════════════════════════════════════════════════════ */
.puzzle-huelle{margin:var(--a-gross) 0 0;max-width:660px}
.puzzle{width:100%;height:auto;display:block;overflow:visible}

.pz-teil path{fill:var(--w);stroke:var(--linie-stark);stroke-width:1;
  stroke-linejoin:miter}
/* Schachbrett: jedes zweite Teil auf Papier statt Weiss. Der Unterschied
   ist klein (F6F5F3 gegen FFFFFF) und genau deshalb richtig — er trennt
   die Teile, ohne sie zu Kacheln zu machen. */
.pz-2 path,.pz-4 path,.pz-6 path{fill:var(--papier)}
.pz-teil--eigen path{
  fill:var(--akzent);stroke:var(--akzent-tief);stroke-width:1.5}

.puzzle text{font-family:var(--f);text-anchor:middle;letter-spacing:-.015em}
.pz-eins{font-size:calc(var(--fs-klein) * 1.1);font-weight:600;fill:var(--tinte)}
.pz-zwei{font-size:calc(var(--fs-label) * 1.1);font-weight:500;fill:var(--grau)}
.pz-teil--eigen .pz-eins,.pz-teil--eigen .pz-zwei{fill:#fff}

/* WAS IM MARKUP STEHT, IST DAS FERTIGE PUZZLE. Zerlegt wird es nur, wenn
   ein laufendes Skript die Klasse `zerlegt` setzt — ohne Skript, bei
   abgeschalteter Bewegung und im Standbild-Modus liegt es zusammen. */
.puzzle-huelle .pz-teil{transform-box:fill-box;transform-origin:center;
  transition:transform .62s cubic-bezier(.22,.61,.36,1) var(--verz,0s),
             opacity .38s ease var(--verz,0s)}
.puzzle-huelle.zerlegt .pz-teil{opacity:0}
.puzzle-huelle.zerlegt .pz-1{transform:translate(-30px,-22px)}
.puzzle-huelle.zerlegt .pz-2{transform:translate(0,-34px)}
.puzzle-huelle.zerlegt .pz-3{transform:translate(30px,-22px)}
.puzzle-huelle.zerlegt .pz-4{transform:translate(-30px,22px)}
.puzzle-huelle.zerlegt .pz-5{transform:translate(0,34px)}
.puzzle-huelle.zerlegt .pz-6{transform:translate(30px,22px)}

/* ═══════════════════════════════════════════════════════════════════════════
   VIER VORFÜHRUNGEN — von der alten Website übernommen, aufs neue Branding
   umgebaut. Herkunft und Umbau je Baustein im Kopf des Blocks; die
   vollständige Liste der ersetzten Farbwerte in 99-runde-1/DEMOS-LIESMICH.md.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Vorführung „Aufmaß am Luftbild" — Bausteinstile.
   Herkunft: alte Website assets/css/style.css, aus den Blöcken
   „AUFMASS" (Layout) und „PC5 · #aufmass" (Filmablauf, Zeilen ~3941–4036).

   Setzt voraus, dass die :root-Variablen der neuen Website bereits geladen
   sind (--akzent, --tinte, --papier, --linie, --w, --d-text, --d-grau,
   --d-linie, --fs-*). Definiert hier nichts davon neu.

   Kein border-radius, kein box-shadow — Hausregel der neuen Seite. Der
   Zeiger trug im Original ein `filter:drop-shadow(...)`; das ist hier durch
   eine kräftigere Kontur ersetzt (stroke-width), keine Tiefenwirkung mehr.

   FARBEN DER MARKIERUNGEN — kategorial, aber auf drei Töne verknappt
   (Auftrag: „Orange für die Hauptfläche und zwei klar unterscheidbare
   Zusatztöne, die nicht grün sind"):
     #E07C1E  Marken-Orange · Hauptfläche · Rollrasen Garten (fest verdrahtet
              seit 26.08., s. `.vfa-haupt` — der Akzent ist jetzt grün und
              wäre auf einem Rasen-Luftbild unsichtbar)
     #C9A227  Goldocker  · Zusatzton 1 · Zufahrt UND Bäume (unterschiedliche
              Symbolform — Fläche vs. Punkt — macht die Doppelbelegung
              trotzdem eindeutig lesbar)
     #2E6F9E  Kräftiges Blau · Zusatzton 2 · Hecke (Strecke)
   Das Original hatte VIER Farben für vier LV-Positionen (Rasen grün, Zufahrt
   bereits orange, Hecke blau, Bäume bernstein). Mit nur drei erlaubten Tönen
   teilen sich Zufahrt und Bäume den Goldocker-Ton — siehe LIESMICH.md,
   Abschnitt „Verständlichkeit", ob das im Bild wirklich unverwechselbar
   bleibt. */

.vfa{position:relative}
.vfa,.vfa *{box-sizing:border-box}

.vfa-bild{position:relative;aspect-ratio:16/10;overflow:hidden;
  border:1px solid var(--linie);background:var(--papier)}
.vfa-bild>img{width:100%;height:100%;object-fit:cover;position:absolute;inset:0}

/* ── Zeichnung ────────────────────────────────────────────────────────── */
.vfa-zeichnung{position:absolute;inset:0;width:100%;height:100%}
.vfa-form{fill-opacity:0;stroke-width:6;stroke-linejoin:round;
  stroke-dasharray:1800;stroke-dashoffset:1800;
  paint-order:stroke fill markers;
  transition:stroke-dashoffset 1.1s cubic-bezier(.4,0,.2,1),fill-opacity .5s .8s}
/* ENDZUSTAND: `.an` steht im Markup fest — ohne Skript, ohne Bewegung und
   ohne dass `.laeuft` je gesetzt wird, ist die Zeichnung trotzdem fertig.
   Die Füllung liegt bei 46 %: darunter liegt ein Luftbild mit eigenem
   Kontrast, und bei 26 % war die Fläche schlicht nicht zu sehen. */
.vfa-form.an{stroke-dashoffset:0;fill-opacity:.46}
/* KATEGORIEFARBE, NICHT BEDIENFARBE (26.08.). Stand als var(--akzent) hier
   und folgte damit dem Blatt. Seit der Akzent gruen ist, geht das nicht mehr:
   die Hauptflaeche ist „Rollrasen Garten" und liegt auf einem Luftbild aus
   Rasen — gruen auf gruen ist keine Markierung. Fester Wert deshalb, und
   zwar das Marken-Orange #E07C1E aus dem Markenhandbuch, nicht ein neu
   gemischter Ton. Dieselbe Ausnahme wie fuer die Zeichenfarben der App. */
.vfa-haupt{fill:#E07C1E;stroke:#E07C1E}
.vfa-zusatz1{fill:#F2B705;stroke:#F2B705}
.vfa-zusatz2{fill:none;stroke:#2E9BE0;stroke-width:7}

/* Der dunkle Saum unter jeder Markierung. Er trennt sie vom Bild, egal ob
   darunter Rasen, Asphalt oder ein helles Dach liegt — ohne ihn hängt die
   Sichtbarkeit davon ab, worüber die Linie gerade läuft. */
/* Kein Saum mehr. Ein zweiter Pfad unter jeder Markierung sah aus wie
   Nachmalen — egal wie er animiert war. Sichtbarkeit macht hier die
   Strichbreite (6 px) und die Füllung (46 %), sonst nichts. */
/* Umfangslängen in viewBox-Einheiten, aus den Punktlisten gerechnet —
   unverändert aus dem Original übernommen (Rasen 716, Zufahrt 273, Hecke 200). */
.vfa-zeichnung>:nth-child(1){stroke-dasharray:716}
.vfa-zeichnung>:nth-child(2){stroke-dasharray:273}
.vfa-zeichnung>:nth-child(3){stroke-dasharray:200}

.vfa-baum{opacity:0;transition:opacity .4s}
.vfa-baum.an{opacity:1}
.vfa-baum circle{fill:#F2B705;stroke:var(--schwarz);stroke-width:3}

/* Die Eckpunkte stehen immer da — ein fertiges Aufmaß zeigt seine
   Stützpunkte. Kein Deckkraft-Übergang nötig, sie sind Teil des Endbilds. */
.vfa-ecken circle{fill:var(--w);stroke:var(--schwarz);stroke-width:3;
  transform-box:fill-box;transform-origin:center}

/* ── Werkzeugleiste (Requisite, rein dekorativ) ──────────────────────────── */
.vfa-werkzeuge{position:absolute;left:10px;top:10px;display:flex;
  flex-direction:column;gap:6px}
.vfa-wz{width:34px;height:34px;background:rgba(16,16,16,.85);
  border:1px solid var(--d-linie);display:flex;align-items:center;justify-content:center}
.vfa-wz svg{width:16px;height:16px;stroke:var(--d-text);stroke-width:1.8;
  fill:none;stroke-linecap:round;stroke-linejoin:round}
.vfa-wz.an{background:var(--akzent);border-color:var(--akzent)}
.vfa-wz.an svg{stroke:var(--tinte)}

/* ── Zeiger (Requisite, nur während des Films sichtbar) ──────────────────── */
.vfa-zeiger{position:absolute;z-index:8;width:22px;height:22px;
  margin:-3px 0 0 -3px;pointer-events:none;opacity:0;transform-origin:6% 8%}
.vfa-zeiger svg{width:100%;height:100%;display:block;
  fill:var(--w);stroke:var(--tinte);stroke-width:1.6;stroke-linejoin:round}
.vfa-zeiger::after{content:"";position:absolute;left:-7px;top:-7px;
  width:16px;height:16px;border:2px solid var(--akzent);opacity:0;transform:scale(.2)}
@media(prefers-reduced-motion:reduce){.vfa-zeiger{display:none}}

/* ── Legende ──────────────────────────────────────────────────────────── */
/* ═══ DIE LEGENDE SITZT IN DER ECKE ══════════════════════════════════════
   Sie stand auf 55 % der Bildbreite und verdeckte die halbe Baustelle —
   beanstandet als „zu riesig, klein in der Ecke". Das Luftbild ist die
   Aussage; die Legende sagt nur, was welche Farbe bedeutet. Jetzt schmal,
   gedrängt und unten rechts. */
.vfa-legende{position:absolute;right:10px;bottom:10px;width:min(212px,44%);
  z-index:5;background:var(--schwarz);border:1px solid rgba(255,255,255,.18);
  padding:.5rem .6rem}
.vfa-lg-t{font-size:var(--fs-label);font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--akzent);margin-bottom:.35rem}
.vfa-lg-z{display:flex;align-items:center;gap:.4rem;padding:.16rem 0;
  opacity:0;transition:opacity .5s}
/* ENDZUSTAND: `.an` steht im Markup fest — jede Legendenzeile ist ohne
   Film sichtbar. */
.vfa-lg-z.an{opacity:1}
.vfa-sw{width:9px;height:9px;flex:none}
.vfa-sw-haupt{background:#E07C1E}  /* muss .vfa-haupt sein, s. dort */
.vfa-sw-zusatz1{background:#F2B705}
.vfa-sw-zusatz2{background:#2E9BE0}
.vfa-lg-z span{font-size:var(--fs-label);color:var(--d-text);flex:1;line-height:1.3}
.vfa-lg-z small{display:block;font-size:var(--fs-label);color:var(--d-grau)}
.vfa-lg-z b{font-size:var(--fs-klein);color:var(--akzent);font-weight:700;
  font-variant-numeric:tabular-nums;white-space:nowrap}

@media(max-width:520px){.vfa-legende{position:static;width:auto;margin-top:.6rem;
  border-top:0}}

/* ═══════════════════════════════════════════════════════════════════════
   FILM — Punkt-für-Punkt-Setzen. Läuft NUR unter [data-vf="aufmass"].laeuft
   (Klasse setzt das Skript per IntersectionObserver, siehe LIESMICH.md) UND
   nur wenn der Besucher Bewegung zulässt. Ohne beides bleibt exakt das
   Bild stehen, das oben als Endzustand beschrieben ist — keine Regel hier
   verändert die Ruhedarstellung.
   14 s je Durchlauf, Zeiten unverändert aus dem Original übernommen:
     0,9 s Werkzeug wählen · 1,7–4,1 s Rasenfläche, Punkt für Punkt ·
     5,1–6,9 s Zufahrt · 7,9–9,3 s Hecke · 10,3/11,0 s die zwei Bäume ·
     12,3–14 s Standbild = das Bild, das ohne Film dasteht.
   ═══════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion:no-preference){
  [data-vf="aufmass"].laeuft .vfa-zeiger{animation:vfa-zeiger 14s cubic-bezier(.45,0,.25,1) infinite}
  [data-vf="aufmass"].laeuft .vfa-zeiger::after{animation:vfa-klick 14s linear infinite}
  /* Ueber Klassen, nicht ueber Position: in die Zeichnung koennen
     Elemente eingefuegt werden, und dann trifft nth-child das Falsche.
     Jeder Saum laeuft mit seiner Form — nur ohne Flaechenanimation,
     er hat keine Fuellung. */
  [data-vf="aufmass"].laeuft .vfa-haupt{animation:vfa-haupt-linie 14s linear infinite,vfa-haupt-flaeche 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-zusatz1{animation:vfa-zusatz1-linie 14s linear infinite,vfa-zusatz1-flaeche 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-zusatz2{animation:vfa-zusatz2-linie 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-baum circle:nth-child(1){animation:vfa-baum-a 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-baum circle:nth-child(2){animation:vfa-baum-b 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-ecken circle:nth-child(1){animation:vfa-ecke-1 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-ecken circle:nth-child(2){animation:vfa-ecke-2 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-ecken circle:nth-child(3){animation:vfa-ecke-3 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-ecken circle:nth-child(4){animation:vfa-ecke-4 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-ecken circle:nth-child(5){animation:vfa-ecke-5 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-ecken circle:nth-child(6){animation:vfa-ecke-6 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-ecken circle:nth-child(7){animation:vfa-ecke-7 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-ecken circle:nth-child(8){animation:vfa-ecke-8 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-ecken circle:nth-child(9){animation:vfa-ecke-9 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-ecken circle:nth-child(10){animation:vfa-ecke-10 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-ecken circle:nth-child(11){animation:vfa-ecke-11 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-lg-z:nth-child(2){animation:vfa-lg-a 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-lg-z:nth-child(3){animation:vfa-lg-b 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-lg-z:nth-child(4){animation:vfa-lg-c 14s linear infinite}
  [data-vf="aufmass"].laeuft .vfa-lg-z:nth-child(5){animation:vfa-lg-d 14s linear infinite}

  @keyframes vfa-haupt-linie{0%,12.14%{stroke-dashoffset:716}
    17.86%{stroke-dashoffset:522}23.57%{stroke-dashoffset:343}
    29.29%{stroke-dashoffset:118}30.5%,100%{stroke-dashoffset:0}}
  @keyframes vfa-haupt-flaeche{0%,23.57%{fill-opacity:0}
    25%,29.29%{fill-opacity:.1}30.5%,100%{fill-opacity:.26}}
  @keyframes vfa-zusatz1-linie{0%,36.43%{stroke-dashoffset:273}
    40.71%{stroke-dashoffset:220}45%{stroke-dashoffset:141}
    49.29%{stroke-dashoffset:86}50.5%,100%{stroke-dashoffset:0}}
  @keyframes vfa-zusatz1-flaeche{0%,45%{fill-opacity:0}
    46%,49.29%{fill-opacity:.1}50.5%,100%{fill-opacity:.26}}
  @keyframes vfa-zusatz2-linie{0%,56.43%{stroke-dashoffset:200}
    61.43%{stroke-dashoffset:73}66.43%,100%{stroke-dashoffset:0}}
  @keyframes vfa-baum-a{0%,73.57%{opacity:0}74.6%,100%{opacity:1}}
  @keyframes vfa-baum-b{0%,78.57%{opacity:0}79.6%,100%{opacity:1}}
  @keyframes vfa-ecke-1{0%,12.14%{opacity:0;transform:scale(.3)}13.34%,100%{opacity:1;transform:none}}
  @keyframes vfa-ecke-2{0%,17.86%{opacity:0;transform:scale(.3)}19.06%,100%{opacity:1;transform:none}}
  @keyframes vfa-ecke-3{0%,23.57%{opacity:0;transform:scale(.3)}24.77%,100%{opacity:1;transform:none}}
  @keyframes vfa-ecke-4{0%,29.29%{opacity:0;transform:scale(.3)}30.49%,100%{opacity:1;transform:none}}
  @keyframes vfa-ecke-5{0%,36.43%{opacity:0;transform:scale(.3)}37.63%,100%{opacity:1;transform:none}}
  @keyframes vfa-ecke-6{0%,40.71%{opacity:0;transform:scale(.3)}41.91%,100%{opacity:1;transform:none}}
  @keyframes vfa-ecke-7{0%,45.0%{opacity:0;transform:scale(.3)}46.2%,100%{opacity:1;transform:none}}
  @keyframes vfa-ecke-8{0%,49.29%{opacity:0;transform:scale(.3)}50.49%,100%{opacity:1;transform:none}}
  @keyframes vfa-ecke-9{0%,56.43%{opacity:0;transform:scale(.3)}57.63%,100%{opacity:1;transform:none}}
  @keyframes vfa-ecke-10{0%,61.43%{opacity:0;transform:scale(.3)}62.63%,100%{opacity:1;transform:none}}
  @keyframes vfa-ecke-11{0%,66.43%{opacity:0;transform:scale(.3)}67.63%,100%{opacity:1;transform:none}}
  /* Die Legende folgt der Form, nicht der Uhr: jede Zeile erscheint, wenn
     IHRE Form fertig ist — Rasen 30,5 %, Zufahrt 50,5 %, Hecke 67 %, Bäume 79,6 %. */
  @keyframes vfa-lg-a{0%,30.5%{opacity:0}32.5%,100%{opacity:1}}
  @keyframes vfa-lg-b{0%,50.5%{opacity:0}52.5%,100%{opacity:1}}
  @keyframes vfa-lg-c{0%,67%{opacity:0}69%,100%{opacity:1}}
  @keyframes vfa-lg-d{0%,79.6%{opacity:0}81.6%,100%{opacity:1}}

  @keyframes vfa-zeiger{0%{left:8%;top:96%;opacity:0;transform:scale(1)}1.5%{left:8%;top:96%;opacity:0;transform:scale(1)}2.5%{left:8%;top:96%;opacity:1;transform:scale(1)}4%{left:8%;top:96%;opacity:1;transform:scale(1)}6.43%{left:27px;top:67px;opacity:1;transform:scale(1)}6.68%{left:27px;top:67px;opacity:1;transform:scale(0.84)}7.53%{left:27px;top:67px;opacity:1;transform:scale(1)}12.14%{left:40.9%;top:39%;opacity:1;transform:scale(1)}12.39%{left:40.9%;top:39%;opacity:1;transform:scale(0.84)}13.24%{left:40.9%;top:39%;opacity:1;transform:scale(1)}17.86%{left:50.6%;top:38%;opacity:1;transform:scale(1)}18.11%{left:50.6%;top:38%;opacity:1;transform:scale(0.84)}18.96%{left:50.6%;top:38%;opacity:1;transform:scale(1)}23.57%{left:50.1%;top:55.7%;opacity:1;transform:scale(1)}23.82%{left:50.1%;top:55.7%;opacity:1;transform:scale(0.84)}24.67%{left:50.1%;top:55.7%;opacity:1;transform:scale(1)}29.29%{left:39.9%;top:50.7%;opacity:1;transform:scale(1)}29.54%{left:39.9%;top:50.7%;opacity:1;transform:scale(0.84)}30.39%{left:39.9%;top:50.7%;opacity:1;transform:scale(1)}36.43%{left:37.8%;top:61%;opacity:1;transform:scale(1)}36.68%{left:37.8%;top:61%;opacity:1;transform:scale(0.84)}37.53%{left:37.8%;top:61%;opacity:1;transform:scale(1)}40.71%{left:41%;top:62.5%;opacity:1;transform:scale(1)}40.96%{left:41%;top:62.5%;opacity:1;transform:scale(0.84)}41.81%{left:41%;top:62.5%;opacity:1;transform:scale(1)}45.0%{left:40.4%;top:70.3%;opacity:1;transform:scale(1)}45.25%{left:40.4%;top:70.3%;opacity:1;transform:scale(0.84)}46.1%{left:40.4%;top:70.3%;opacity:1;transform:scale(1)}49.29%{left:36.9%;top:69.4%;opacity:1;transform:scale(1)}49.54%{left:36.9%;top:69.4%;opacity:1;transform:scale(0.84)}50.39%{left:36.9%;top:69.4%;opacity:1;transform:scale(1)}56.43%{left:44.8%;top:33.9%;opacity:1;transform:scale(1)}56.68%{left:44.8%;top:33.9%;opacity:1;transform:scale(0.84)}57.53%{left:44.8%;top:33.9%;opacity:1;transform:scale(1)}61.43%{left:52.6%;top:36%;opacity:1;transform:scale(1)}61.68%{left:52.6%;top:36%;opacity:1;transform:scale(0.84)}62.53%{left:52.6%;top:36%;opacity:1;transform:scale(1)}66.43%{left:51.8%;top:43.2%;opacity:1;transform:scale(1)}66.68%{left:51.8%;top:43.2%;opacity:1;transform:scale(0.84)}67.53%{left:51.8%;top:43.2%;opacity:1;transform:scale(1)}73.57%{left:48%;top:42.9%;opacity:1;transform:scale(1)}73.82%{left:48%;top:42.9%;opacity:1;transform:scale(0.84)}74.67%{left:48%;top:42.9%;opacity:1;transform:scale(1)}78.57%{left:42.6%;top:46.9%;opacity:1;transform:scale(1)}78.82%{left:42.6%;top:46.9%;opacity:1;transform:scale(0.84)}79.67%{left:42.6%;top:46.9%;opacity:1;transform:scale(1)}84.3%{left:8%;top:96%;opacity:1;transform:scale(1)}87.9%{left:8%;top:96%;opacity:0;transform:scale(1)}100%{left:8%;top:96%;opacity:0;transform:scale(1)}}
  @keyframes vfa-klick{0%{opacity:0;transform:scale(.2)}6.42%{opacity:0;transform:scale(.2)}6.63%{opacity:.9;transform:scale(.55)}7.73%{opacity:0;transform:scale(1.9)}12.13%{opacity:0;transform:scale(.2)}12.34%{opacity:.9;transform:scale(.55)}13.44%{opacity:0;transform:scale(1.9)}17.85%{opacity:0;transform:scale(.2)}18.06%{opacity:.9;transform:scale(.55)}19.16%{opacity:0;transform:scale(1.9)}23.56%{opacity:0;transform:scale(.2)}23.77%{opacity:.9;transform:scale(.55)}24.87%{opacity:0;transform:scale(1.9)}29.28%{opacity:0;transform:scale(.2)}29.49%{opacity:.9;transform:scale(.55)}30.59%{opacity:0;transform:scale(1.9)}36.42%{opacity:0;transform:scale(.2)}36.63%{opacity:.9;transform:scale(.55)}37.73%{opacity:0;transform:scale(1.9)}40.7%{opacity:0;transform:scale(.2)}40.91%{opacity:.9;transform:scale(.55)}42.01%{opacity:0;transform:scale(1.9)}44.99%{opacity:0;transform:scale(.2)}45.2%{opacity:.9;transform:scale(.55)}46.3%{opacity:0;transform:scale(1.9)}49.28%{opacity:0;transform:scale(.2)}49.49%{opacity:.9;transform:scale(.55)}50.59%{opacity:0;transform:scale(1.9)}56.42%{opacity:0;transform:scale(.2)}56.63%{opacity:.9;transform:scale(.55)}57.73%{opacity:0;transform:scale(1.9)}61.42%{opacity:0;transform:scale(.2)}61.63%{opacity:.9;transform:scale(.55)}62.73%{opacity:0;transform:scale(1.9)}66.42%{opacity:0;transform:scale(.2)}66.63%{opacity:.9;transform:scale(.55)}67.73%{opacity:0;transform:scale(1.9)}73.56%{opacity:0;transform:scale(.2)}73.77%{opacity:.9;transform:scale(.55)}74.87%{opacity:0;transform:scale(1.9)}78.56%{opacity:0;transform:scale(.2)}78.77%{opacity:.9;transform:scale(.55)}79.87%{opacity:0;transform:scale(1.9)}100%{opacity:0;transform:scale(.2)}}
}

/* Vorführung „Meldung von der Fläche" — Bausteinstile.
   Herkunft: alte Website assets/css/style.css — Geräte-Rahmen (Abschnitt
   „Geräte-Rahmen"), Produkt-Skin (Abschnitt „PRODUKT-SKIN", `.screen.appui`)
   und der Filmablauf „ENDLICH MIT DEM FINGER" (#meldung, Zeilen ~4040–4197).

   Setzt die :root-Variablen der neuen Website voraus (--akzent, --akzent-
   text, --akzent-knopf, --tinte, --grau, --papier, --linie, --linie-stark,
   --w, --d-linie, --fs-*). Definiert hier nichts davon neu.

   FARBEN: Das alte Produkt-Skin trug die komplette App-Oberfläche in Grün
   (u. a. --a-pri #005A21 für jeden Knopf und jede Kennzahl, #0B4A26 für die
   Unterschrift). Ersetzt nach der Regel „Orange ist eine Flächenfarbe,
   keine Schriftfarbe": Knopfflächen -> --akzent-knopf (weiße Schrift),
   Text-Akzente (Kennzahl „243,5", aktiver Reiter) -> --akzent-text.
   Die gelbe Warnbox (#FCD34D/#FFFBEB/#78350F) ist NICHT grün und blieb
   unverändert — Amber steht nicht auf der Verbotsliste.

   Kein border-radius, kein box-shadow — Hausregel der neuen Seite. Eine
   Ausnahme wie im :root-Blatt der neuen Seite selbst (Zeile ~1209,
   Fokusring `box-shadow:0 0 0 3px …`): der Fokus-Ring beim Tippen unten
   ist ein flacher, unscharfer Ring ohne Tiefenwirkung, kein Elevation-
   Schatten. */

.vfm-geraet{--vfm-h:2.75rem;position:relative}
.vfm-geraet,.vfm-geraet *{box-sizing:border-box}

/* ── KEIN GEHÄUSE ─────────────────────────────────────────────────────
   Hier stand ein nachgebautes Handy: dunkler Rahmen, Kamera-Insel,
   Heim-Balken, Statusleiste mit Uhrzeit. Alles raus. Ein Gerätegehäuse
   kostet Platz, sagt nichts über die Software und sieht mit jeder neuen
   Gerätegeneration älter aus. Übrig ist die Maske — und die ist der Punkt. */
.vfm-phone{width:min(380px,100%);max-width:100%;background:var(--w);
  border:1px solid var(--linie-stark);padding:0;position:relative}
.vfm-screen{background:var(--w);overflow:hidden;display:flex;
  flex-direction:column;padding:0}

/* ── Statusleiste ─────────────────────────────────────────────────────── */

/* ── Seitenkopf ───────────────────────────────────────────────────────── */
.vfm-seitenkopf{display:flex;align-items:center;gap:.8rem;padding:.65rem 1rem;
  background:var(--w);border-bottom:1px solid var(--linie)}
.vfm-tt{font-size:var(--fs-klein);font-weight:700;color:var(--tinte);line-height:1.2}
.vfm-tt small{display:block;font-size:var(--fs-label);font-weight:400;color:var(--grau)}

.vfm-koerper{padding:.8rem .8rem 1.6rem}

/* ── Festes Feld (LV-Position) ───────────────────────────────────────────── */
.vfm-feld-fest{background:var(--w);border:1px solid var(--linie);
  padding:.6rem .8rem;margin-bottom:.7rem}
.vfm-lab{font-size:var(--fs-label);font-weight:600;color:var(--grau);margin-bottom:.25rem}
.vfm-wert{font-size:var(--fs-body);font-weight:500;color:var(--tinte)}

/* ── Eingabefelder ────────────────────────────────────────────────────── */
.vfm-feld{margin-bottom:.6rem}
.vfm-feld label{display:block;font-size:var(--fs-label);font-weight:600;
  color:var(--tinte);margin-bottom:.25rem}
.vfm-eingabe{display:flex;align-items:center;min-height:var(--vfm-h);
  background:var(--w);border:1px solid var(--linie-stark);
  padding:0 .75rem;font-size:var(--fs-klein);color:var(--tinte);
  font-variant-numeric:tabular-nums}
.vf-tipp{white-space:inherit}

.vfm-hinweis{border:1px solid #FCD34D;background:#FFFBEB;padding:.5rem .6rem;
  font-size:var(--fs-label);line-height:1.4;color:#78350F;margin-bottom:.6rem}

/* ── Foto-Kacheln ─────────────────────────────────────────────────────── */
.vfm-kacheln{display:grid;grid-template-columns:1fr 1fr;gap:.4rem;margin-bottom:.6rem}
.vfm-kachel{display:flex;align-items:center;justify-content:center;
  min-height:var(--vfm-h);border:1px dashed var(--linie-stark);background:var(--w);
  padding:.5rem .3rem;text-align:center;font-size:var(--fs-label);color:var(--grau)}
.vfm-kachel.vfm-foto{position:relative;border-style:solid;padding:0;
  overflow:hidden;min-height:64px}
.vfm-kachel.vfm-foto img{width:100%;height:100%;object-fit:cover;position:absolute;inset:0}
.vfm-ph-tag{position:absolute;left:5px;bottom:5px;background:var(--schwarz);
  padding:.1rem .3rem;font-size:var(--fs-label);line-height:1.4;color:var(--w);
  letter-spacing:.04em;white-space:nowrap}

/* ── Unterschrift ─────────────────────────────────────────────────────── */
.vfm-unterschrift{margin-top:.4rem}
.vfm-unt-flaeche{position:relative;border:1px dashed rgba(59,160,100,.3);
  background:rgba(59,160,100,.04);padding:.15rem .5rem}
.vfm-unt-flaeche svg{display:block;width:72%;height:22px}
.vfm-unt-name{position:absolute;right:.5rem;bottom:.1rem;
  font-size:var(--fs-label);color:var(--grau)}
.vfm-unt-zug{fill:none;stroke:var(--akzent);stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:420;stroke-dashoffset:0}

/* ── Sendeknopf & Heimbalken ──────────────────────────────────────────── */
.vfm-btn{margin-top:auto;background:var(--akzent-knopf);color:var(--w);
  min-height:var(--vfm-h);display:flex;align-items:center;justify-content:center;
  font-weight:600;font-size:var(--fs-body);padding:.75rem}

/* ═══════════════════════════════════════════════════════════════════════
   FILM — Feld bekommt Fokus, Text wird Zeichen für Zeichen getippt, die
   echte Warnung erscheint, das Foto hängt sich an, der Knopf drückt sich.
   Läuft nur unter [data-vf="meldung"].laeuft UND nur bei zugelassener
   Bewegung. OHNE DAS trägt kein einziges Zeichen/Element eine Regel — der
   Satz, die Warnung und das Foto stehen im Ruhezustand bereits vollständig
   da (siehe Basis-CSS oben: nirgends opacity:0 oder display:none als
   Grundzustand). Zeiten unverändert aus dem Original (8 s je Durchlauf).
   ═══════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion:no-preference){
  [data-vf="meldung"].laeuft .vfm-feld1{animation:vfm-fokus-a 8s linear infinite}
  [data-vf="meldung"].laeuft .vfm-feld2{animation:vfm-fokus-b 8s linear infinite}
  [data-vf="meldung"].laeuft .vfm-warn{animation:vfm-warn 8s linear infinite}
  [data-vf="meldung"].laeuft .vfm-foto{animation:vfm-foto 8s linear infinite}
  [data-vf="meldung"].laeuft .vfm-senden{animation:vfm-druck 8s linear infinite}
  [data-vf="meldung"].laeuft .vfm-unt-zug{animation:vfm-unterschreiben 8s linear infinite}
  [data-vf="meldung"].laeuft .m1{animation:vfm-m1 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .m2{animation:vfm-m2 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .m3{animation:vfm-m3 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .m4{animation:vfm-m4 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .m5{animation:vfm-m5 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g1{animation:vfm-g1 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g2{animation:vfm-g2 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g3{animation:vfm-g3 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g4{animation:vfm-g4 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g5{animation:vfm-g5 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g6{animation:vfm-g6 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g7{animation:vfm-g7 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g8{animation:vfm-g8 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g9{animation:vfm-g9 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g10{animation:vfm-g10 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g11{animation:vfm-g11 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g12{animation:vfm-g12 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g13{animation:vfm-g13 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g14{animation:vfm-g14 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g15{animation:vfm-g15 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g16{animation:vfm-g16 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g17{animation:vfm-g17 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g18{animation:vfm-g18 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g19{animation:vfm-g19 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g20{animation:vfm-g20 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g21{animation:vfm-g21 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g22{animation:vfm-g22 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g23{animation:vfm-g23 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g24{animation:vfm-g24 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g25{animation:vfm-g25 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g26{animation:vfm-g26 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g27{animation:vfm-g27 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g28{animation:vfm-g28 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g29{animation:vfm-g29 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g30{animation:vfm-g30 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g31{animation:vfm-g31 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g32{animation:vfm-g32 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g33{animation:vfm-g33 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g34{animation:vfm-g34 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g35{animation:vfm-g35 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g36{animation:vfm-g36 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g37{animation:vfm-g37 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g38{animation:vfm-g38 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g39{animation:vfm-g39 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g40{animation:vfm-g40 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g41{animation:vfm-g41 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g42{animation:vfm-g42 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g43{animation:vfm-g43 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g44{animation:vfm-g44 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g45{animation:vfm-g45 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g46{animation:vfm-g46 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g47{animation:vfm-g47 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g48{animation:vfm-g48 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g49{animation:vfm-g49 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g50{animation:vfm-g50 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g51{animation:vfm-g51 8000ms steps(1,end) infinite}
  [data-vf="meldung"].laeuft .g52{animation:vfm-g52 8000ms steps(1,end) infinite}

  /* Fokusring in der Bedienfarbe der neuen Seite. */
  @keyframes vfm-fokus-a{0%,3.5%{border-color:var(--linie-stark);box-shadow:none}
    4.5%,16%{border-color:var(--akzent);box-shadow:0 0 0 3px rgba(59,160,100,.2)}
    18%,100%{border-color:var(--linie-stark);box-shadow:none}}
  @keyframes vfm-fokus-b{0%,16.5%{border-color:var(--linie-stark);box-shadow:none}
    17.5%,58%{border-color:var(--akzent);box-shadow:0 0 0 3px rgba(59,160,100,.2)}
    60%,100%{border-color:var(--linie-stark);box-shadow:none}}
  @keyframes vfm-warn{0%,12%{opacity:0;transform:translateY(-4px)}
    15%,100%{opacity:1;transform:none}}
  @keyframes vfm-foto{0%,63%{opacity:0;transform:scale(.94)}
    67%,100%{opacity:1;transform:none}}
  @keyframes vfm-druck{0%,69.9%{transform:none;filter:none}
    70.4%{transform:scale(.97);filter:brightness(.88)}
    73%,100%{transform:none;filter:none}}
  @keyframes vfm-unterschreiben{0%,62%{stroke-dashoffset:420}76%,100%{stroke-dashoffset:0}}
  @keyframes vfm-m1{0%,5.388%{display:none}5.398%,100%{display:inline}}
  @keyframes vfm-m2{0%,5.887%{display:none}5.897%,100%{display:inline}}
  @keyframes vfm-m3{0%,6.3%{display:none}6.31%,100%{display:inline}}
  @keyframes vfm-m4{0%,6.8%{display:none}6.81%,100%{display:inline}}
  @keyframes vfm-m5{0%,7.312%{display:none}7.322%,100%{display:inline}}
  @keyframes vfm-g1{0%,19.25%{display:none}19.26%,100%{display:inline}}
  @keyframes vfm-g2{0%,20.0%{display:none}20.01%,100%{display:inline}}
  @keyframes vfm-g3{0%,20.425%{display:none}20.435%,100%{display:inline}}
  @keyframes vfm-g4{0%,20.95%{display:none}20.96%,100%{display:inline}}
  @keyframes vfm-g5{0%,21.575%{display:none}21.585%,100%{display:inline}}
  @keyframes vfm-g6{0%,21.962%{display:none}21.972%,100%{display:inline}}
  @keyframes vfm-g7{0%,22.363%{display:none}22.373%,100%{display:inline}}
  @keyframes vfm-g8{0%,24.562%{display:none}24.572%,100%{display:inline}}
  @keyframes vfm-g9{0%,25.15%{display:none}25.16%,100%{display:inline}}
  @keyframes vfm-g10{0%,25.562%{display:none}25.572%,100%{display:inline}}
  @keyframes vfm-g11{0%,26.075%{display:none}26.085%,100%{display:inline}}
  @keyframes vfm-g12{0%,28.175%{display:none}28.185%,100%{display:inline}}
  @keyframes vfm-g13{0%,28.562%{display:none}28.572%,100%{display:inline}}
  @keyframes vfm-g14{0%,29.3%{display:none}29.31%,100%{display:inline}}
  @keyframes vfm-g15{0%,29.875%{display:none}29.885%,100%{display:inline}}
  @keyframes vfm-g16{0%,30.325%{display:none}30.335%,100%{display:inline}}
  @keyframes vfm-g17{0%,32.212%{display:none}32.222%,100%{display:inline}}
  @keyframes vfm-g18{0%,32.612%{display:none}32.622%,100%{display:inline}}
  @keyframes vfm-g19{0%,33.15%{display:none}33.16%,100%{display:inline}}
  @keyframes vfm-g20{0%,33.688%{display:none}33.698%,100%{display:inline}}
  @keyframes vfm-g21{0%,34.087%{display:none}34.097%,100%{display:inline}}
  @keyframes vfm-g22{0%,34.55%{display:none}34.56%,100%{display:inline}}
  @keyframes vfm-g23{0%,34.95%{display:none}34.96%,100%{display:inline}}
  @keyframes vfm-g24{0%,35.538%{display:none}35.548%,100%{display:inline}}
  @keyframes vfm-g25{0%,36.075%{display:none}36.085%,100%{display:inline}}
  @keyframes vfm-g26{0%,36.462%{display:none}36.472%,100%{display:inline}}
  @keyframes vfm-g27{0%,37.163%{display:none}37.173%,100%{display:inline}}
  @keyframes vfm-g28{0%,37.762%{display:none}37.772%,100%{display:inline}}
  @keyframes vfm-g29{0%,38.175%{display:none}38.185%,100%{display:inline}}
  @keyframes vfm-g30{0%,38.925%{display:none}38.935%,100%{display:inline}}
  @keyframes vfm-g31{0%,39.387%{display:none}39.397%,100%{display:inline}}
  @keyframes vfm-g32{0%,40.013%{display:none}40.023%,100%{display:inline}}
  @keyframes vfm-g33{0%,42.138%{display:none}42.148%,100%{display:inline}}
  @keyframes vfm-g34{0%,42.737%{display:none}42.747%,100%{display:inline}}
  @keyframes vfm-g35{0%,43.488%{display:none}43.498%,100%{display:inline}}
  @keyframes vfm-g36{0%,45.375%{display:none}45.385%,100%{display:inline}}
  @keyframes vfm-g37{0%,45.975%{display:none}45.985%,100%{display:inline}}
  @keyframes vfm-g38{0%,46.575%{display:none}46.585%,100%{display:inline}}
  @keyframes vfm-g39{0%,47.1%{display:none}47.11%,100%{display:inline}}
  @keyframes vfm-g40{0%,48.987%{display:none}48.997%,100%{display:inline}}
  @keyframes vfm-g41{0%,49.45%{display:none}49.46%,100%{display:inline}}
  @keyframes vfm-g42{0%,49.837%{display:none}49.847%,100%{display:inline}}
  @keyframes vfm-g43{0%,50.425%{display:none}50.435%,100%{display:inline}}
  @keyframes vfm-g44{0%,52.638%{display:none}52.648%,100%{display:inline}}
  @keyframes vfm-g45{0%,53.062%{display:none}53.072%,100%{display:inline}}
  @keyframes vfm-g46{0%,53.55%{display:none}53.56%,100%{display:inline}}
  @keyframes vfm-g47{0%,54.087%{display:none}54.097%,100%{display:inline}}
  @keyframes vfm-g48{0%,54.512%{display:none}54.522%,100%{display:inline}}
  @keyframes vfm-g49{0%,55.1%{display:none}55.11%,100%{display:inline}}
  @keyframes vfm-g50{0%,55.512%{display:none}55.522%,100%{display:inline}}
  @keyframes vfm-g51{0%,56.112%{display:none}56.122%,100%{display:inline}}
  @keyframes vfm-g52{0%,56.6%{display:none}56.61%,100%{display:inline}}
}

/* Vorführung „Gefährdungsbeurteilung" — Bausteinstile.
   Herkunft: alte Website assets/css/style.css — „Attrappen ohne
   Geräterahmen" (`.tablet.frei`, Zeilen ~2841–2863), Produkt-Skin
   (`.screen.appui`, GBU-Regeln Zeilen ~1355–1367) und der Filmablauf
   „Film A · #gbu" (Zeilen ~3813–3865).

   Setzt die :root-Variablen der neuen Website voraus (--akzent, --akzent-
   text, --akzent-knopf, --tinte, --grau, --papier, --linie, --rot, --fs-*).

   AMPELFARBEN — drei Zustände, keine geht auf altes Grün zurück:
     Rot     var(--rot)      #C0392B  (Marke, bereits im neuen System)
     Gelb    #E07C1E          (mittleres Risiko = Marken-Orange, fest —
             seit 26.08., s. `.vfg-ampel.vfg-gelb`)
     Grün    #2F7345         nicht aus der alten Seite, sondern dieselbe
             gedeckte Erfolgsfarbe, die die NEUE Website selbst schon für
             „erledigt/erfolgreich" benutzt (assets/css/style.css der neuen
             Seite, u. a. `.fg--ok`, `.b-punkt--fertig`). Kein neu erfundenes
             Grün, keines der verbotenen alten Töne (#8FE9A8, #3DBE63 etc.).
   Diese Entscheidung steht nicht wörtlich im Auftrag — er nennt nur die
   Luftbild-Markierungen als Ausnahme vom Grün-Verbot. Eine Ampel ohne Grün
   verliert aber ihre Lesbarkeit als Ampel; siehe LIESMICH.md zur Prüfung.

   Kein border-radius auf Flächen/Karten/Knöpfen, kein box-shadow — Hausregel
   der neuen Seite. Ausnahme wie im :root-Blatt der neuen Seite selbst:
   `border-radius:50%` bleibt bei echten Punktsymbolen (Ampel-Punkt, Lade-
   Ring) erlaubt — die neue Seite tut das selbst (`.b-punkt`, `.beleg__punkte
   i`), das ist kein Kasten-Radius, sondern die Form eines Punkts. */

.vfg-karte{position:relative}
.vfg-karte,.vfg-karte *{box-sizing:border-box}

.vfg-screen{position:relative;border:1px solid var(--linie);
  background:var(--w);color:var(--tinte);text-align:left}

/* ── Seitenkopf ───────────────────────────────────────────────────────── */
.vfg-seitenkopf{display:flex;align-items:center;gap:.8rem;padding:.65rem 1rem;
  background:var(--w);border-bottom:1px solid var(--linie)}
.vfg-tt{font-size:var(--fs-klein);font-weight:700;color:var(--tinte);line-height:1.2}
.vfg-tt small{display:block;font-size:var(--fs-label);font-weight:400;color:var(--grau)}
.vfg-knopf{margin-left:auto;display:inline-flex;align-items:center;
  min-height:2rem;background:var(--akzent-knopf);color:var(--w);
  border:1px solid transparent;padding:0 .75rem;font-size:var(--fs-label);
  font-weight:600;white-space:nowrap}
.vfg-knopf.vfg-leer{background:var(--w);color:var(--akzent-text);border-color:var(--linie)}
.vfg-knopf+.vfg-knopf{margin-left:.4rem}

/* overflow:hidden gegen das nowrap des `.vfg-vf-knopf` (Requisit, im
   Ruhezustand opacity:0) — ohne das ragte der Knopftext bei 375px 34px
   aus der Karte, unsichtbar aber trotzdem Querlauf-faehig. Der Endzustand
   (Tabelle, Legende) passt ohnehin in die Polsterung, wird also nicht
   beschnitten. */
.vfg-koerper{position:relative;padding:.9rem 1rem 1.1rem;overflow:hidden}

/* ── Requisit: Leistungsverzeichnis (nur während des Films sichtbar) ────── */
.vfg-lv,.vfg-lade{position:absolute;inset:.9rem 1rem 1.1rem;opacity:0;
  pointer-events:none;background:var(--papier)}
.vfg-lv{display:flex;flex-direction:column;gap:.5rem;overflow:hidden}
.vfg-lv-kopf{display:flex;align-items:center;gap:.8rem;
  font-size:var(--fs-label);font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--grau);
  padding-bottom:.55rem;border-bottom:1px solid var(--linie)}
.vfg-vf-knopf{margin-left:auto;text-transform:none;letter-spacing:0}
.vfg-lv-z{display:grid;grid-template-columns:5.5rem 1fr auto;gap:.9rem;
  align-items:center;font-size:var(--fs-klein);color:var(--tinte);
  padding:.45rem 0;border-bottom:1px solid var(--linie)}
.vfg-lv-z span:first-child{color:var(--grau);font-variant-numeric:tabular-nums}
.vfg-lv-z b{font-weight:600;font-variant-numeric:tabular-nums}

/* ── Requisit: Ladezustand ────────────────────────────────────────────── */
.vfg-lade{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.9rem}
.vfg-ring{width:26px;height:26px;border-radius:50%;
  border:2px solid var(--linie);border-top-color:var(--akzent-knopf)}
.vfg-lade-t{position:absolute;top:calc(50% + 1.6rem);opacity:0;
  font-size:var(--fs-klein);color:var(--grau);white-space:nowrap}

/* ── Endzustand: Risikotabelle + Legende ─────────────────────────────── */
.vfg-tabelle{text-align:left}
.vfg-gt-kopf,.vfg-gt-z{display:grid;grid-template-columns:1fr 30px 30px 44px 1.05fr;
  gap:.9rem;align-items:center}
.vfg-gt-kopf{font-size:var(--fs-label);font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:var(--grau);background:var(--papier);
  padding:.4rem .6rem}
.vfg-gt-z{font-size:var(--fs-klein);color:var(--tinte);
  border-bottom:1px solid var(--linie);padding:.55rem .6rem}
.vfg-gt-z b{color:var(--akzent-text);font-weight:700}
.vfg-mitte{text-align:center;font-variant-numeric:tabular-nums}
.vfg-ampel{display:inline-block;width:11px;height:11px;border-radius:50%}
.vfg-ampel.vfg-rot{background:var(--rot)}

/* ═══ DIE RISIKOTABELLE WURDE BEI 393 PX BESCHNITTEN ═════════════════════
   Nicht gegrept, sondern GEMESSEN am 28.08.2026: `.vfg-gt-z` stand 357 px
   breit in einem 319 px breiten Feld, `.vfg-lv` sogar 412 px in 319 px —
   und `.vfg-koerper{overflow:hidden}` schnitt beides ab. Die Seite rollte
   nicht quer, der Inhalt war schlicht weg. Genau die Falle, die der
   Kommentar oben („passt ohnehin in die Polsterung") ausschloss.

   Ursache: `1fr` und `5.5rem` haben als Mindestbreite ihren INHALT.
   „Schnittverletzung" und „Schnittschutz" sind laenger als ihr Anteil,
   also wuchs das Raster ueber seinen Kasten hinaus. `minmax(0,...)` nimmt
   dem Raster diese Untergrenze, der Umbruch im Wort faengt den Rest. */
@media (max-width:640px){
  .vfg-gt-kopf,.vfg-gt-z{grid-template-columns:minmax(0,1fr) 22px 22px 34px minmax(0,1.05fr);
    gap:.5rem}
  .vfg-gt-kopf>*,.vfg-gt-z>*{min-width:0;overflow-wrap:break-word;hyphens:auto}
  .vfg-lv-z{grid-template-columns:minmax(0,4.4rem) minmax(0,1fr) auto;gap:.5rem}
  .vfg-lv-z>*{min-width:0;overflow-wrap:break-word;hyphens:auto}
  /* „Gefährdungsbeurteilung erstellen" ist mit `nowrap` 244 px breit und
     stand neben der Aufschrift der Kopfzeile — zusammen 412 px in 319 px.
     Der Knopf bekommt auf schmalem Schirm eine eigene Zeile und darf
     umbrechen. Damit ist auch das `overflow:hidden` an `.vfg-koerper`
     wieder das, was sein Kommentar behauptet: eine Vorsichtsmassnahme,
     die nichts mehr abschneidet. */
  .vfg-lv-kopf{flex-wrap:wrap;gap:.4rem}
  .vfg-vf-knopf{margin-left:0;white-space:normal}
}
/* Wie .vfa-haupt: Kategoriefarbe. Die Ampel fuehrt zwei Zeilen tiefer
   #2F7345 als „gering" — mit gruenem Akzent haette sie zwei Gruen und
   keine Mitte mehr. Marken-Orange #E07C1E, fest. */
.vfg-ampel.vfg-gelb{background:#E07C1E}
.vfg-ampel.vfg-gruen{background:#2F7345}
.vfg-legende{margin-top:1rem;font-size:var(--fs-label);line-height:1.5;
  color:var(--grau);text-align:left}
.vfg-legende b{color:var(--tinte)}

/* ── Zeiger (Requisite, nur während des Films sichtbar) ──────────────────── */
.vfg-zeiger{position:absolute;z-index:8;width:22px;height:22px;
  margin:-3px 0 0 -3px;pointer-events:none;opacity:0;transform-origin:6% 8%}
.vfg-zeiger svg{width:100%;height:100%;display:block;
  fill:var(--w);stroke:var(--tinte);stroke-width:1.6;stroke-linejoin:round}
.vfg-zeiger::after{content:"";position:absolute;left:-7px;top:-7px;
  width:16px;height:16px;border:2px solid var(--akzent);opacity:0;transform:scale(.2)}
@media(prefers-reduced-motion:reduce){.vfg-zeiger{display:none}}

/* ═══════════════════════════════════════════════════════════════════════
   FILM — LV steht → Zeiger fährt zum Knopf → Klick → Verzeichnis geht →
   Ladezustand (zwei Zeilen, ~2,3 s) → die fertige Beurteilung steht.
   Läuft nur unter [data-vf="gbu"].laeuft UND nur bei zugelassener Bewegung.
   OHNE DAS bleiben `.vfg-lv`/`.vfg-lade` unsichtbar (Basis-CSS oben,
   opacity:0) und Tabelle + Legende stehen ohne jede Bedingung da — das ist
   bereits der Endzustand, keine Regel hier verändert das.
   10 s je Durchlauf, Zeiten unverändert aus dem Original. ═══════════════ */
@media (prefers-reduced-motion:no-preference){
  [data-vf="gbu"].laeuft .vfg-lv{animation:vfg-lv 10s linear infinite}
  [data-vf="gbu"].laeuft .vfg-lade{animation:vfg-lade 10s linear infinite}
  [data-vf="gbu"].laeuft .vfg-lade-a{animation:vfg-t1 10s linear infinite}
  [data-vf="gbu"].laeuft .vfg-lade-b{animation:vfg-t2 10s linear infinite}
  [data-vf="gbu"].laeuft .vfg-tabelle,
  [data-vf="gbu"].laeuft .vfg-legende{animation:vfg-fertig 10s linear infinite}
  [data-vf="gbu"].laeuft .vfg-zeiger{animation:vfg-zeiger 10s cubic-bezier(.45,0,.25,1) infinite}
  [data-vf="gbu"].laeuft .vfg-zeiger::after{animation:vfg-klick 10s linear infinite}
  [data-vf="gbu"].laeuft .vfg-vf-knopf{animation:vfg-druck 10s linear infinite}

  @keyframes vfg-lv{0%{opacity:0}3%{opacity:1}31%{opacity:1}36%{opacity:0}100%{opacity:0}}
  @keyframes vfg-lade{0%,34%{opacity:0}37%{opacity:1}57%{opacity:1}60%{opacity:0}100%{opacity:0}}
  @keyframes vfg-t1{0%,35%{opacity:0}38%,45%{opacity:1}47%{opacity:0}100%{opacity:0}}
  @keyframes vfg-t2{0%,46%{opacity:0}49%,56%{opacity:1}59%{opacity:0}100%{opacity:0}}
  @keyframes vfg-fertig{0%,58%{opacity:0;transform:translateY(6px)}
    62%,100%{opacity:1;transform:translateY(0)}}
  @keyframes vfg-druck{0%,25.9%{filter:none}26%,27.4%{filter:brightness(.86)}27.5%,100%{filter:none}}
  @keyframes vfg-zeiger{
    0%{left:88%;top:106%;opacity:0;transform:scale(1)}
    3%{left:88%;top:106%;opacity:0;transform:scale(1)}
    5%{left:88%;top:106%;opacity:1;transform:scale(1)}
    8%{left:88%;top:106%;opacity:1;transform:scale(1)}
    26%{left:calc(100% - 119px);top:85px;opacity:1;transform:scale(1)}
    26.3%{left:calc(100% - 119px);top:85px;opacity:1;transform:scale(.84)}
    27.6%{left:calc(100% - 119px);top:85px;opacity:1;transform:scale(1)}
    33%{left:calc(100% - 119px);top:85px;opacity:1;transform:scale(1)}
    41%{left:88%;top:106%;opacity:1;transform:scale(1)}
    44%{left:88%;top:106%;opacity:0;transform:scale(1)}
    100%{left:88%;top:106%;opacity:0;transform:scale(1)}}
  @keyframes vfg-klick{0%{opacity:0;transform:scale(.2)}
    25.9%{opacity:0;transform:scale(.2)}
    26.25%{opacity:.9;transform:scale(.55)}
    27.8%{opacity:0;transform:scale(1.9)}
    100%{opacity:0;transform:scale(.2)}}
}

/* Vorführung „Planung / Tagesplan" — Bausteinstile.
   Herkunft: alte Website assets/css/style.css — Einsatzplan-Board (Basis-
   Regeln + `.screen.appui`-Overrides), Auswahlliste „Zuteilen" (`.pk*`,
   Zeilen ~1626–1650) und der Filmablauf „PC7 · #plan" (main.js `plandemo()`
   + CSS-Zeilen ~2865–2903 und die Korrektur „RUNDE AB" Zeilen ~5060–5082).

   Setzt die :root-Variablen der neuen Website voraus (--akzent, --akzent-
   text, --akzent-knopf, --tinte, --grau, --papier, --linie, --linie-stark,
   --w, --rot, --fs-*).

   Wie bei der GBU-Vorführung: das „Grün" für erfüllte/positive Zustände
   (freie Auswahlzeile, „Alle Prüfungen bestanden") ist NICHT eines der
   verbotenen alten Töne, sondern die gedeckte Erfolgsfarbe #1D6633, die die
   neue Website selbst schon führt (dort u. a. `.meldung--gut`). Siehe
   LIESMICH.md.

   Kein border-radius, kein box-shadow — Hausregel der neuen Seite. Die
   Auswahlliste `.vfp-pk` trug im Original einen Elevation-Schatten
   (`box-shadow:0 10px 26px …`); hier ersatzlos weg, dafür eine kräftigere
   Kontur (`--linie-stark` statt `--linie`), damit sie sich trotzdem vom
   Untergrund abhebt. */

#plandemo{position:relative}
.vfp-screen,.vfp-screen *{box-sizing:border-box}
.vfp-screen{border:1px solid var(--linie);background:var(--w);color:var(--tinte);text-align:left}

/* ── Seitenkopf ───────────────────────────────────────────────────────── */
.vfp-seitenkopf{display:flex;align-items:center;gap:.8rem;padding:.65rem 1rem;
  background:var(--w);border-bottom:1px solid var(--linie)}
.vfp-tt{font-size:var(--fs-klein);font-weight:700;color:var(--tinte);line-height:1.2}
.vfp-tt small{display:block;font-size:var(--fs-label);font-weight:400;color:var(--grau)}
.vfp-knopf{margin-left:auto;display:inline-flex;align-items:center;
  min-height:2rem;background:var(--akzent-knopf);color:var(--w);
  border:1px solid transparent;padding:0 .75rem;font-size:var(--fs-label);
  font-weight:600;white-space:nowrap}
.vfp-knopf.vfp-leer{background:var(--w);color:var(--akzent-text);border-color:var(--linie)}
.vfp-knopf+.vfp-knopf{margin-left:.4rem}

.vfp-koerper{padding:.9rem 1rem 1.1rem}
.vfp-board{text-align:left}

/* ── Hinweisbalken über dem Plan ──────────────────────────────────────── */
.vfp-hinweis-oben{margin-top:0;margin-bottom:.9rem}

/* ── Einsatzkarten ────────────────────────────────────────────────────── */
.vfp-bkarte{background:var(--w);border:1px solid var(--linie);padding:.85rem 1rem;margin-top:.7rem}
.vfp-bkarte:first-child{margin-top:0}
.vfp-bkarte.vfp-pf{position:relative}
.vfp-bk-titel{display:flex;justify-content:space-between;gap:1rem;align-items:baseline;flex-wrap:wrap}
.vfp-bk-titel b{color:var(--tinte);font-size:var(--fs-body);font-weight:700}
.vfp-bk-titel span{font-size:var(--fs-klein);color:var(--grau)}
.vfp-bk-zeile{display:flex;gap:.45rem;flex-wrap:wrap;align-items:center;margin-top:.7rem}
.vfp-bkl{width:64px;flex:none;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grau)}
.vfp-chip{background:var(--papier);border:1px solid var(--linie);color:var(--tinte);
  font-size:var(--fs-label);padding:.28rem .5rem;display:inline-flex;align-items:center;gap:.45rem}
.vfp-chip small{color:var(--grau)}
.vfp-chip.vfp-vor{background:#FEF3C7;border-color:#FDE68A;color:#78350F;font-weight:700}
.vfp-chip.vfp-masch{background:#F5F1FE;border-color:#E7DEFB;color:#4C1D95}
.vfp-helm{width:11px;height:11px;flex:none;stroke:#B45309;fill:none;stroke-width:2}
.vfp-bk-ok{margin-top:.9rem;font-size:var(--fs-klein);color:#1D6633;font-weight:600}
.vfp-bk-warn{margin-top:.9rem;border-left:3px solid var(--rot);background:#FEF2F2;
  padding:.55rem .9rem;font-size:var(--fs-klein);color:#7F1D1D}
.vfp-bk-warn b{color:#7F1D1D}
.vfp-bk-warn.vfp-gelb{border-left-color:var(--akzent);background:#FFFBEB;color:#78350F}
.vfp-bk-warn.vfp-gelb b{color:#78350F}

/* ── „+ Technik/Mitarbeiter"-Auslöser ────────────────────────────────── */
.vfp-chip-neu{display:inline-flex;align-items:center;min-height:2rem;
  border:1px dashed var(--linie);padding:.28rem .55rem;font-size:var(--fs-label);
  color:var(--grau);background:none;white-space:nowrap}

/* ── Auswahlliste (Requisit, nur während des Films offen) ────────────────── */
.vfp-pk{width:min(268px,100%);margin:.55rem 0 .2rem 64px;background:var(--w);
  border:1px solid var(--linie-stark);padding:.45rem;transform-origin:top left;
  position:absolute;z-index:5;opacity:0;transform:translateY(-6px) scale(.97);
  pointer-events:none;transition:opacity .3s ease,transform .3s ease}
@media(max-width:640px){.vfp-pk{margin-left:0}}
.vfp-pk-such{display:flex;align-items:center;min-height:2rem;
  border:1px solid var(--linie-stark);padding:0 .5rem;font-size:var(--fs-label);
  color:var(--grau);margin-bottom:.35rem}
.vfp-pk-opt{display:flex;justify-content:space-between;align-items:center;gap:.6rem;
  min-height:2rem;padding:.32rem .45rem;font-size:var(--fs-label);color:var(--tinte);
  transition:background-color .25s ease,color .25s ease}
.vfp-pk-opt small{color:var(--grau);white-space:nowrap}
.vfp-pk-opt.vfp-gesperrt{color:var(--grau)}
.vfp-pk-opt.vfp-gesperrt small{color:var(--grau)}

/* Chip und Warnung bleiben immer im Fluss (nur opacity), damit beim
   Erscheinen nichts umbricht. ENDZUSTAND: ohne `[data-schritt]` (kein
   Skript, abgeschaltete Bewegung, außerhalb des Sichtfelds) matcht KEINE
   der Regeln unten — `.vfp-neu` und `.vfp-warn-neu` bleiben auf ihrer
   normalen, sichtbaren Grunddarstellung stehen. */
.vfp-neu{transition:opacity .3s ease,transform .3s ease}
.vfp-warn-neu{transition:opacity .4s ease}

/* ── Zeiger (Requisite, nur während des Films sichtbar) ──────────────────── */
.vfp-zeiger{position:absolute;z-index:8;width:22px;height:22px;
  margin:-3px 0 0 -3px;pointer-events:none;opacity:0;transform-origin:6% 8%;
  left:297px;top:68px;
  transition:left .55s cubic-bezier(.45,0,.25,1),top .55s cubic-bezier(.45,0,.25,1),
    opacity .3s,transform .18s}
.vfp-zeiger svg{width:100%;height:100%;display:block;
  fill:var(--w);stroke:var(--tinte);stroke-width:1.6;stroke-linejoin:round}
.vfp-zeiger::after{content:"";position:absolute;left:-7px;top:-7px;
  width:16px;height:16px;border:2px solid var(--akzent);opacity:0;transform:scale(.2)}
@media(prefers-reduced-motion:reduce){.vfp-zeiger{display:none}}

/* ═══════════════════════════════════════════════════════════════════════
   FILM — hängt an `data-schritt` (0…4) auf #plandemo, gesetzt von main.js
   im 1200/900/800/700/3600-ms-Takt. KEIN `.vf`/`.laeuft` hier — dieser
   Ablauf ist eigenständig (siehe LIESMICH.md). Zeiger-Koordinaten sind die
   KORRIGIERTEN Werte aus dem Original (297/68 · 211/147 px), nicht die
   ältere Prozent-Fassung.
   0  Zeiger fährt heran · 1  auf „+ Mitarbeiter", Liste geht auf ·
   2  auf „P. Wagner" · 3  fährt weg · 4  weg, Warnung steht (= Endzustand).
   ═══════════════════════════════════════════════════════════════════════ */
#plandemo[data-schritt="1"] .vfp-pk,
#plandemo[data-schritt="2"] .vfp-pk{opacity:1;transform:none}
#plandemo[data-schritt="2"] .vfp-opt-ziel{background:rgba(59,160,100,.08);
  color:var(--akzent-text);font-weight:700}
#plandemo[data-schritt="2"] .vfp-opt-ziel small{color:#1D6633}
#plandemo[data-schritt="1"] .vfp-ausl,
#plandemo[data-schritt="2"] .vfp-ausl{border-style:solid;border-color:var(--akzent-knopf);
  color:var(--akzent-text);background:rgba(59,160,100,.08)}
#plandemo[data-schritt="0"] .vfp-neu,
#plandemo[data-schritt="1"] .vfp-neu,
#plandemo[data-schritt="2"] .vfp-neu{opacity:0;transform:translateY(-4px)}
#plandemo[data-schritt]:not([data-schritt="4"]) .vfp-warn-neu{opacity:0}

#plandemo[data-schritt="0"] .vfp-zeiger{left:297px;top:68px;opacity:1;transform:none}
#plandemo[data-schritt="1"] .vfp-zeiger{left:297px;top:68px;opacity:1;transform:scale(.84)}
#plandemo[data-schritt="2"] .vfp-zeiger{left:211px;top:147px;opacity:1;transform:scale(.84)}
#plandemo[data-schritt="3"] .vfp-zeiger{left:211px;top:147px;opacity:1;transform:none}
#plandemo[data-schritt="4"] .vfp-zeiger{left:211px;top:147px;opacity:0}
#plandemo[data-schritt="1"] .vfp-zeiger::after,
#plandemo[data-schritt="2"] .vfp-zeiger::after{animation:vfp-ring .7s ease-out}

@media (prefers-reduced-motion:no-preference){
  @keyframes vfp-ring{from{opacity:.9;transform:scale(.3)}to{opacity:0;transform:scale(2)}}
}
@media(prefers-reduced-motion:reduce){
  .vfp-pk{display:none}
  .vfp-neu,.vfp-warn-neu{opacity:1;transform:none;transition:none}
}

/* ═══════════════════════════════════════════════════════════════════════════
   DER GRUPPENCHAT — Blasen, sonst nichts

   Zweiter Anlauf. Der erste hatte eine Kopfleiste mit Gruppenbild und
   Menüpunkt, einen Rahmen um das Ganze und einen Bildplatzhalter statt des
   Fotos — beanstandet als „der gruppen header komisch gebaut, das ganze
   ding muss nicht umrandet sein". Jetzt steht er schmal in der rechten
   Spalte neben dem Text: nur Blasen, das echte Foto und eine Sprachnachricht,
   deren Wellenform zeigt, wie weit sie abgespielt ist.
   ═══════════════════════════════════════════════════════════════════════════ */
.hakt{display:grid;grid-template-columns:1fr minmax(0,340px);
  gap:var(--a-gross);align-items:start;margin-top:var(--a-mittel)}
@media (max-width:980px){.hakt{grid-template-columns:1fr}}
.hakt > .fliess{margin-top:0}

/* ═══ DER GRUPPENCHAT — DIE ATTRAPPE AUS DER BROSCHÜRE ═══════════════════
   Hier stand ein Nachbau: freistehende Blasen in Hausfarben, ohne Gerät.
   Beanstandet — „richtige whatsapp hand demo drin haben statt den
   nachgebauten chat". Übernommen ist deshalb die gewachsene Attrappe aus
   `07-marketing/print/broschuere/broschuere.html` (Markup ab .chat-handy,
   CSS .phone/.wa-*), KOPIERT statt ein zweites Mal nachgebaut.

   ── DER MASSSTAB ──────────────────────────────────────────────────────
   Die Broschüre rechnet in Millimetern. EIN Faktor gilt hier für alles:

       1 mm = 5,4 px      (Gerät 53 mm → 286 px)

   Jedes Maß unten ist so entstanden; Prozentwerte bleiben Prozentwerte.
   Nur die Schriftgrößen folgen NICHT dem Faktor, sondern der Leiter der
   Seite (pruefe-schriftleiter.py lässt keine freien Werte zu): 6,8 pt
   ≈ 13 px = --fs-klein, 5,2–6 pt ≈ 11 px = --fs-label. Der Unterschied zur
   reinen Umrechnung ist unter einem Pixel.

   ── ZWEI HAUSREGELN, BEWUSST AUSGESETZT ───────────────────────────────
   Radien und Schatten sind auf dieser Seite sonst verboten. Innerhalb der
   Attrappe gelten sie trotzdem, und die WhatsApp-Farben (#0B141A, #202C33,
   #005C4B, #53BDEB) bleiben fremd statt Marke — genau das ist die Aussage
   des Bildes: SO läuft es heute, neben Ihrer Software. Dieselbe
   Entscheidung steht in der Broschüre.
   ═══════════════════════════════════════════════════════════════════════ */
.wa-handy{display:flex;flex-direction:column;align-items:center}
.wa-handy,.wa-handy *{box-sizing:border-box}

/* ── Gehäuse ─────────────────────────────────────────────────────────── */
/* Die Höhe kommt aus dem Verlauf, nicht aus einem gesetzten Verhältnis:
   gemessen 286 x 664 px = 9 : 20,9 — im Rahmen dessen, was ein heutiges
   Gerät hat. Ein hart gesetztes 9:19,5 würde den Verlauf UNTEN abschneiden,
   und unten steht die Pointe („Wie weit seid ihr gestern gekommen?"). */
.wa-phone{width:min(286px,100%);flex:none;padding:8px;
  position:relative;border-radius:12.5%/5.9%;border:0;
  background:linear-gradient(160deg,#4A5155 0%,#0B0D0E 16%,#0B0D0E 84%,#4A5155 100%);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
.wa-phone::before{content:"";position:absolute;left:-3px;top:19%;width:3px;height:4.2%;
  border-radius:2px;background:#333A3E;box-shadow:0 35px 0 #333A3E,0 66px 0 #333A3E}
.wa-phone::after{content:"";position:absolute;right:-3px;top:29%;width:3px;height:8%;
  border-radius:2px;background:#333A3E}
.wa-screen{position:relative;overflow:hidden;border-radius:11%/5.2%;
  background:#0B141A;padding:0;height:100%;display:flex;flex-direction:column}
.wa-insel{position:absolute;left:50%;top:8px;transform:translateX(-50%);
  width:46%;min-height:18px;height:3.5%;background:#0B0D0E;
  border-radius:0 0 14px 14px;z-index:6;
  display:flex;align-items:center;justify-content:center;gap:8px}
.wa-insel::before{content:"";width:32px;height:4px;border-radius:2px;background:#20262A}
.wa-insel::after{content:"";width:8px;height:8px;border-radius:50%;
  background:#152232;box-shadow:inset 0 0 0 1px #2B3F55}

/* ── Die Oberfläche ──────────────────────────────────────────────────── */
.wa{flex:1;min-height:0;display:flex;flex-direction:column;
  font-family:"Helvetica Neue",Helvetica,"Segoe UI",Roboto,Arial,sans-serif}
.wa-kopf{display:flex;align-items:center;gap:10px;flex:none;
  padding:35px 11px 9px;background:#202C33}
.wa-av{width:30px;height:30px;border-radius:50%;background:#0B141A;flex:none;
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.wa-av img{width:22px;height:auto}
.wa-titel{flex:1;min-width:0}
.wa-titel b{display:block;font-size:var(--fs-klein);font-weight:600;color:#E9EDEF;line-height:1.15}
.wa-titel small{display:block;font-size:var(--fs-label);color:#8696A0;
  line-height:1.25;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wa-menu{color:#8696A0;font-size:var(--fs-klein);flex:none}

.wa-body{flex:1;min-height:0;overflow:hidden;padding:12px;display:flex;
  flex-direction:column;justify-content:flex-start;gap:5px;
  background:#0B141A url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%22260%22%20height%3D%22260%22%20viewBox%3D%220%200%20260%20260%22%3E%0A%3Cg%20fill%3D%22none%22%20stroke%3D%22%238FA6B0%22%20stroke-width%3D%221.6%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20opacity%3D%220.085%22%3E%0A%3Cpath%20d%3D%22M20%2034h26v8H20z%22/%3E%3Cpath%20d%3D%22M24%2042v14M42%2042v14%22/%3E%0A%3Ccircle%20cx%3D%2296%22%20cy%3D%2230%22%20r%3D%229%22/%3E%3Cpath%20d%3D%22M96%2021v-6M96%2045v-6M87%2030h-6M111%2030h-6%22/%3E%0A%3Cpath%20d%3D%22M150%2022l10%206v14l-10%206-10-6V28z%22/%3E%0A%3Cpath%20d%3D%22M196%2020v18M188%2038h16l-3%2010h-10z%22/%3E%0A%3Cpath%20d%3D%22M232%2026h14v12h-14z%22/%3E%3Cpath%20d%3D%22M239%2038v10%22/%3E%0A%3Cpath%20d%3D%22M30%2096l8-14%208%2014z%22/%3E%3Cpath%20d%3D%22M38%2096v10%22/%3E%0A%3Cpath%20d%3D%22M78%2088h20v16H78z%22/%3E%3Cpath%20d%3D%22M78%2096h20M88%2088v16%22/%3E%0A%3Ccircle%20cx%3D%22140%22%20cy%3D%2296%22%20r%3D%2210%22/%3E%3Cpath%20d%3D%22M140%2086v10l7%204%22/%3E%0A%3Cpath%20d%3D%22M184%20104c0-10%206-16%2014-16s14%206%2014%2016%22/%3E%3Cpath%20d%3D%22M184%20104h28%22/%3E%0A%3Cpath%20d%3D%22M236%2088l-6%2018h16l-6-18z%22/%3E%0A%3Cpath%20d%3D%22M22%20160h22v10H22z%22/%3E%3Cpath%20d%3D%22M26%20170v8M40%20170v8%22/%3E%0A%3Cpath%20d%3D%22M76%20150l12%208v16l-12%208-12-8v-16z%22/%3E%0A%3Cpath%20d%3D%22M126%20154v20M118%20174h16%22/%3E%3Ccircle%20cx%3D%22126%22%20cy%3D%22150%22%20r%3D%224%22/%3E%0A%3Cpath%20d%3D%22M170%20152h24v18h-24z%22/%3E%3Cpath%20d%3D%22M170%20161h24%22/%3E%0A%3Cpath%20d%3D%22M222%20156l10%206v12l-10%206-10-6v-12z%22/%3E%0A%3Cpath%20d%3D%22M34%20220h18l4%2012H30z%22/%3E%0A%3Cpath%20d%3D%22M84%20214v18M76%20232h16%22/%3E%0A%3Ccircle%20cx%3D%22132%22%20cy%3D%22222%22%20r%3D%229%22/%3E%3Cpath%20d%3D%22M126%20222h12M132%20216v12%22/%3E%0A%3Cpath%20d%3D%22M176%20216h22v14h-22z%22/%3E%3Cpath%20d%3D%22M180%20230v6M194%20230v6%22/%3E%0A%3Cpath%20d%3D%22M230%20214l8%2016h-16z%22/%3E%0A%3C/g%3E%3C/svg%3E") repeat;background-size:238px 238px}
.wa-datum{text-align:center;margin-bottom:3px}
.wa-datum span{background:#182229;border-radius:6px;padding:4px 12px;
  font-size:var(--fs-label);letter-spacing:.08em;color:#8696A0}
.wa-reihe{display:flex}
.wa-reihe.links{justify-content:flex-start}
.wa-reihe.rechts{justify-content:flex-end;margin-top:auto}

/* Blase: nur so breit wie ihr Inhalt */
.wa-b{display:inline-block;max-width:94%;border-radius:11px;padding:5px 7px 4px;
  box-shadow:0 2px 3px rgba(0,0,0,.22)}
.wa-b.ein{background:#202C33;border-top-left-radius:0}
.wa-b.raus{background:#005C4B;border-top-right-radius:0}
.wa-name{display:block;font-size:var(--fs-label);font-weight:600;margin-bottom:3px}
.wa-name.n1{color:#53BDEB}
.wa-name.n2{color:#E5A2C8}
.wa-name.n3{color:#B4A1E8}
/* Text mit nachlaufender Uhrzeit in derselben Zeile */
.wa-txt{display:block;font-size:var(--fs-klein);line-height:1.3;color:#E9EDEF}
.wa-zeit{float:right;margin:5px 0 0 13px;font-size:var(--fs-label);color:#8696A0;
  line-height:1;white-space:nowrap}
.wa-b.raus .wa-zeit{color:#C9D3D6}
/* Doppelhaken wie in WhatsApp: zwei überlappende Haken, nicht zwei Zeichen */
.wa-haken{display:inline-block;width:18px;height:11px;vertical-align:-1px;
  margin-left:3px;overflow:visible}
.wa-haken path{fill:none;stroke:#53BDEB;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.wa-foto{border-radius:8px;overflow:hidden;margin-bottom:5px;width:100%}
.wa-foto img{width:100%;height:123px;object-fit:cover;object-position:56% 72%;display:block}

/* ── Sprachnachricht ─────────────────────────────────────────────────── */
.wa-b.audio{width:100%}
.wa-audio{display:flex;align-items:center;gap:11px;padding:2px 12px 2px 0}
.wa-play{color:#E9EDEF;font-size:var(--fs-klein);flex:none;width:22px}
.wa-spur{position:relative;flex:1;display:flex;align-items:center;min-width:0}
/* Die Höhen folgen einer Sprach-Hüllkurve — Silben-Cluster mit Pausen
   dazwischen, kein gleichmäßiges Zickzack. */
.wa-wave{flex:1;height:25px;display:block;min-width:0}
/* Der Abspielpunkt bleibt rund — in der gestreckten SVG wäre er ein Oval */
.wa-punkt{position:absolute;left:25.5%;width:11px;height:11px;border-radius:50%;
  background:#53BDEB;transform:translateX(-50%)}
.wa-audio-fuss{display:flex;justify-content:space-between;align-items:center;
  padding-left:32px;margin-top:1px}
.wa-dauer{font-size:var(--fs-label);color:#8696A0}
.wa-zeit.stat{float:none;margin:0}

/* ── Eingabeleiste ───────────────────────────────────────────────────── */
.wa-leiste{flex:none;display:flex;align-items:center;gap:9px;
  padding:9px 12px 12px;background:#0B141A}
.wa-plus{color:#8696A0;font-size:var(--fs-klein);line-height:1;flex:none}
.wa-eingabe{flex:1;background:#1F2C34;border-radius:27px;padding:8px 14px;
  font-size:var(--fs-label);color:#8696A0}
.wa-ic{flex:none;width:22px;height:22px;display:flex;align-items:center;justify-content:center}
.wa-ic svg{width:18px;height:18px;fill:none;stroke:#8696A0;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}

.wa-fuss{margin-top:14px;font-size:var(--fs-label);color:var(--grau);
  max-width:286px;text-align:center}

/* ── Am Telefon: kein Handy im Handy ─────────────────────────────────
   Bei 393 px steht ein 286-px-Gerät mit Gehäuserahmen fast randlos in der
   Spalte — der Rahmen wird zur Zierleiste und frisst Breite, die der Chat
   braucht. Unter 560 px fällt das Gehäuse deshalb weg: Notch, Seitentasten
   und Verlauf raus, die Oberfläche bleibt vollständig. */
@media (max-width:560px){
  .wa-phone{width:100%;max-width:340px;aspect-ratio:auto;padding:0;
    background:none;box-shadow:none;border-radius:0}
  .wa-phone::before,.wa-phone::after{display:none}
  .wa-insel{display:none}
  .wa-screen{border-radius:0;height:auto}
  .wa-kopf{padding-top:11px}
  .wa-fuss{max-width:340px}
}

/* ═══ DER BÖSCHUNGSBELEG STEHT BREIT ════════════════════════════════════
   Er sass in der halben Spalte eines Rasters und teilte diese Hälfte noch
   einmal — Ergebnis: ein Luftbild von 320 px und eine Messtabelle, die in
   vier Zeilen umbrach. Jetzt Text oben über Textbreite, Beleg darunter
   über die volle Breite. */
.ref__text{max-width:var(--text)}
.ref__beleg--breit{margin-top:var(--a-gross)}
.ref__beleg--breit .bo-raster{grid-template-columns:1.6fr 1fr;gap:var(--a-mittel)}
@media (max-width:900px){.ref__beleg--breit .bo-raster{grid-template-columns:1fr}}

/* ═══ KUNDENLOGO UND STIMME ══════════════════════════════════════════════
   Das fremde Zeichen steht frei auf der Fläche, ohne Kachel und ohne
   Rahmen — eine Kachel um ein Logo sieht aus wie eine Anzeige. */
.kundenlogo{margin:0 0 var(--a-mittel);max-width:200px}
.kundenlogo img{width:100%;height:auto;display:block}

.stimme{margin:var(--a-mittel) 0;padding-left:var(--a-klein);
  border-left:3px solid var(--akzent);max-width:var(--text)}
.stimme p{font-size:var(--fs-lead);font-weight:500;letter-spacing:-.015em;
  line-height:1.45;color:var(--tinte)}
.stimme footer{margin-top:10px;display:flex;align-items:baseline;gap:8px;
  font-size:var(--fs-klein)}
.stimme footer b{font-weight:700;color:var(--tinte)}
.stimme footer span{color:var(--grau)}
/* Fall 2 steht auf dunklem Band. Ohne diese vier Zeilen laufen Zitat,
   Name und Überschrift in `--tinte` weiter — dunkel auf dunkel, 1,1 : 1.
   Genau diese Falle hat die Messung hier schon zweimal gefunden. */
.band--dunkel .stimme p{color:var(--d-text)}
.band--dunkel .stimme footer b{color:var(--d-text)}
.band--dunkel .stimme footer span{color:var(--d-grau)}
.band--dunkel .sonder-h{color:var(--d-text)}

/* ═══════════════════════════════════════════════════════════════════════════
   DAS PROTOKOLLBLATT — man muss sehen, wie so etwas aussieht

   Ansage: „protokoll auch einblenden wie sowas aussehen kann". Ein Abschnitt
   über ein Protokollwerkzeug, in dem kein Protokoll vorkommt, verlangt vom
   Leser, es sich vorzustellen. Links das Blatt, rechts der Bestand daraus.
   ═══════════════════════════════════════════════════════════════════════════ */
/* GLEICH HOCH, NICHT UNGEFAEHR GLEICH HOCH. Mit `align-items:start` stand das
   Blatt links auf 541 px und der Beleg rechts auf 399 px — 142 px Unterschied,
   gemessen bei 1280 px. Zwei Belege nebeneinander, verschieden hoch abgesetzt,
   lesen sich als Versehen. `stretch` gibt beiden die Zeilenhoehe.

   `stretch` ALLEIN reicht nicht: die Karte waechst dann zwar mit, ihr Inhalt
   bleibt aber oben stehen und darunter klafften 190 px Weiss — im Bild ein
   Loch, kein Fenster. Der Inhalt wird deshalb selbst eine Spalte und verteilt
   seine vier Gruppen (Zahlen · Reiter mit Nummernfolge · Fehlmeldung ·
   Bericht) ueber die gewonnene Hoehe. Gemessen bei 1280 px: 556 / 556. */
.prot{display:grid;grid-template-columns:1fr 1fr;gap:var(--a-mittel);
  margin-top:var(--a-gross);align-items:stretch}
.prot > .beleg{display:flex;flex-direction:column}
.prot > .beleg > .beleg__inhalt{flex:1;display:flex;flex-direction:column;
  justify-content:space-between}
@media (max-width:980px){.prot{grid-template-columns:1fr}}

.blatt{margin:0;background:var(--w);border:1px solid var(--linie-stark);
  color:var(--tinte)}
.blatt__kopf{display:flex;align-items:flex-start;justify-content:space-between;
  gap:var(--a-klein);padding:12px var(--a-klein);
  border-bottom:2px solid var(--tinte)}
.blatt__kopf b{display:block;font-size:var(--fs-klein);font-weight:700}
.blatt__kopf small{display:block;font-size:var(--fs-label);color:var(--grau)}
/* Die Marke sagt beides in einer Zeile: Vorschlag von der Maschine, und ein
   Mensch hat ihn bestätigt. Getrennt gelesen wäre jedes für sich falsch. */
.blatt__marke{flex:none;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:var(--akzent-tief);
  background:var(--akzent-hauch);border:1px solid var(--akzent);
  padding:3px 8px;white-space:nowrap}

.blatt__zeilen{margin:0;padding:var(--a-klein) var(--a-klein) 0}
.blatt__zeilen > div{display:grid;grid-template-columns:11em 1fr;gap:10px;
  padding:6px 0;border-bottom:1px solid var(--linie)}
.blatt__zeilen dt{font-size:var(--fs-label);font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--grau)}
.blatt__zeilen dd{margin:0;font-size:var(--fs-klein);color:var(--tinte)}
.blatt__zeilen dd b{font-weight:700}
.blatt__zeilen dd i{font-style:italic;color:var(--grau)}

.blatt__text{margin:var(--a-klein);padding:10px var(--a-klein);
  background:var(--papier);border-left:3px solid var(--akzent);
  font-size:var(--fs-klein);line-height:1.55;color:var(--tinte)}
.blatt__gelesen{display:block;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:var(--akzent-text);
  margin-bottom:4px}

.blatt__fuss{display:flex;align-items:center;gap:var(--a-klein);
  padding:var(--a-klein);border-top:1px solid var(--linie)}
.blatt__foto{flex:none;width:84px;height:60px;display:grid;place-items:center;
  background:linear-gradient(135deg,#4A4A48,#6E6E6B);
  font-size:var(--fs-label);font-weight:600;letter-spacing:.08em;
  text-transform:uppercase;color:#fff}
.blatt__erkannt{font-size:var(--fs-klein);color:var(--grau)}
.blatt__erkannt b{color:var(--tinte);font-style:italic}
.blatt__erkannt i{display:block;font-style:normal;font-size:var(--fs-label);
  color:var(--grau);margin-top:2px}

/* Das Blatt trägt seine eigenen Farben, auch im dunklen Band — es IST ein
   Blatt Papier. Die Regel „fett auf dunkel ist orange" gilt hier nicht.
   `inherit` reichte NICHT: geerbt wurde die Farbe eines Elternteils, der
   selbst schon orange war (gemessen 3,12 : 1 auf Weiss). Deshalb der
   ausdrückliche Wert. */
.band--dunkel .blatt :is(b,strong){color:var(--tinte)}
.band--dunkel .blatt__erkannt i,.band--dunkel .blatt__zeilen dd i{color:var(--grau)}
.band--dunkel .blatt__marke{color:var(--akzent-tief)}
.band--dunkel .blatt__gelesen{color:var(--akzent-text)}

/* Die Kennzahlen im dunklen Band: die Beschriftung stand auf --grau
   (2,85 : 1 auf Schwarz). */
.band--dunkel .zahlen span{color:var(--d-grau)}
.band--dunkel .zahlen b{color:var(--akzent)}

@media (prefers-reduced-motion:no-preference){
  .blatt__zeilen > div{animation:bl-auf .4s cubic-bezier(.22,.61,.36,1) both}
  .blatt__zeilen > div:nth-child(1){animation-delay:.10s}
  .blatt__zeilen > div:nth-child(2){animation-delay:.18s}
  .blatt__zeilen > div:nth-child(3){animation-delay:.26s}
  .blatt__zeilen > div:nth-child(4){animation-delay:.34s}
  .blatt__zeilen > div:nth-child(5){animation-delay:.42s}
  .blatt__zeilen > div:nth-child(6){animation-delay:.50s}
  .blatt__text{animation:bl-auf .45s cubic-bezier(.22,.61,.36,1) .62s both}
  .blatt__fuss{animation:bl-auf .45s cubic-bezier(.22,.61,.36,1) .78s both}
}
@keyframes bl-auf{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* Das Zeichen des eigenen Betriebs, nicht umgefärbt, weisse Fassung fürs
   dunkle Band. Es steht ÜBER dem Etikett statt in einer Zeile „Gebaut für":
   Land.Bau.Werk ist nicht der Auftraggeber dieser Entwicklung, sondern der
   Betrieb, aus dem sie kommt. */
.marke img{height:38px;width:auto;display:block}

/* ═══ WAS DIE MASCHINE TUT — DREI SCHRITTE ══════════════════════════════
   Stand vorher als ein Absatz Fliesstext und ging darin unter. Drei
   Blöcke mit Nummer, Satz und Erklärung: die Reihenfolge ist die Aussage. */
.ki-drei{list-style:none;margin:var(--a-gross) 0 0;padding:0;
  display:grid;grid-template-columns:repeat(3,1fr);gap:var(--a-mittel)}
@media (max-width:900px){.ki-drei{grid-template-columns:1fr}}
.ki-drei li{position:relative;padding-top:var(--a-klein);
  border-top:2px solid var(--akzent)}
.ki-drei__nr{display:block;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.14em;color:var(--akzent)}
.ki-drei b{display:block;margin-top:6px;font-size:var(--fs-body);font-weight:600;
  letter-spacing:-.015em;color:var(--d-text)}
.ki-drei p{margin-top:6px;font-size:var(--fs-klein);color:var(--d-grau);
  line-height:1.55}

/* Der wissenschaftliche Name gehört ins Protokoll — aber er erklärt sich
   nicht von selbst. Deshalb steht daneben, warum er dort steht. */
.wiss{display:block;margin-top:2px;font-size:var(--fs-label);color:var(--grau)}
.wiss i{font-style:italic}


/* ═══ DIE KARTE STARTET LEER ═════════════════════════════════════════════
   Nur unterhalb von `js-film` (die Klasse setzt `main.js`, und nur wenn
   Bewegung erlaubt und die Seite nicht eingefroren ist). Ohne Skript steht
   das fertige Aufmaß da — das ist der Zustand, der im Markup beschrieben
   ist, und er bleibt die sichere Richtung. */
@media (prefers-reduced-motion:no-preference){
  .js-film [data-vf="aufmass"]:not(.laeuft) .vfa-form{
    stroke-dashoffset:1800;fill-opacity:0}
  .js-film [data-vf="aufmass"]:not(.laeuft) .vfa-baum,
  .js-film [data-vf="aufmass"]:not(.laeuft) .vfa-ecken circle,
  .js-film [data-vf="aufmass"]:not(.laeuft) .vfa-lg-z{opacity:0}
}

/* Etikett, Überschrift und Text stehen in der linken Spalte — sonst nimmt
   die Überschrift die volle Breite, und der Chat rechts beginnt erst
   darunter. Genau das las sich als „viel zu weit unten". */
.hakt__text > .regel{margin-top:0}
.hakt__text .fliess{margin-top:var(--a-mittel)}

/* ═══════════════════════════════════════════════════════════════════════════
   DIE SONDERANFERTIGUNG — eine Satzbreite für alles

   GEMESSEN, was schief war: der Zwischentitel war 21 px hoch und las sich
   wie ein fetter Absatz. Das Zitat stand auf 864 px, der Text darunter auf
   720 — zwei Satzbreiten direkt untereinander. Das Logo war 200 px breit
   neben einer 86 px hohen Stimme und dazu senkrecht zentriert.

   Jetzt: Etikett und Überschrift wie überall sonst auf der Seite, eine
   Satzbreite für den ganzen Abschnitt, Logo klein und oben bündig.
   ═══════════════════════════════════════════════════════════════════════════ */
.sonder{margin-top:var(--a-gross);max-width:var(--text)}
.sonder-h{margin:6px 0 var(--a-mittel);font-size:var(--fs-h3);font-weight:600;
  letter-spacing:-.03em;line-height:1.15;color:var(--tinte)}

.sonder__kopf{display:grid;grid-template-columns:132px 1fr;gap:var(--a-mittel);
  align-items:start;padding-bottom:var(--a-mittel);
  border-bottom:1px solid var(--linie)}
@media (max-width:640px){.sonder__kopf{grid-template-columns:1fr;gap:var(--a-klein)}}
.sonder__kopf .kundenlogo{margin:0;max-width:132px}
.sonder__kopf .stimme{margin:0;max-width:none;padding-left:var(--a-klein)}
.sonder__kopf .stimme p{font-size:var(--fs-body)}

/* ── DER AUFTAKT: EIN FALL OHNE KUNDENSTIMME ───────────────────────────
   Für Fall 1. Hier gibt es kein freigegebenes Zitat, also auch keine
   Kopfzeile, die eines tragen müsste — das Zeichen steht neben Etikett und
   Überschrift statt allein in einer eigenen Zeile mit Trennlinie darunter.
   Vorher: 128 px hohe Kopfzeile mit einem Kind. Keine Trennlinie hier: die
   Überschrift trennt bereits, eine Linie dazu wäre ein zweiter Zaun. */
.sonder__auftakt{display:grid;grid-template-columns:112px 1fr;
  gap:var(--a-mittel);align-items:center}
@media (max-width:640px){.sonder__auftakt{grid-template-columns:1fr;
  gap:var(--a-klein)}}
.sonder__auftakt .kundenlogo{margin:0;max-width:112px}
.sonder__auftakt .sonder-h{margin:6px 0 0}

.sonder__text{margin-top:var(--a-mittel)}
.sonder__text p + p{margin-top:var(--a-klein)}

/* Zwei Spalten für die Haken-Liste: vier kurze Zeilen untereinander sind
   eine Spalte Luft, nebeneinander sind sie eine Aufzählung. */
.haken--zwei{display:grid;grid-template-columns:1fr 1fr;gap:6px var(--a-mittel);
  margin-top:var(--a-mittel)}
@media (max-width:760px){.haken--zwei{grid-template-columns:1fr}}

/* ═══ DIE VIER PUNKTE ════════════════════════════════════════════════════
   Die LAGE steht fest — sie ist die Messung. Die HÖHE ist ein Eingabefeld,
   weil sich draussen genau sie ändert. Ein Regler für die Neigung wäre die
   falsche Frage: Neigungen misst niemand, Höhen schon. */
.bo-hoehe{display:flex;align-items:baseline;gap:4px;margin-top:4px}
.bo-hoehe input{width:100%;min-width:0;min-height:34px;padding:4px 6px;
  border:1px solid var(--linie-stark);background:var(--w);
  font-family:inherit;font-size:var(--fs-klein);font-weight:700;
  color:var(--tinte);font-variant-numeric:tabular-nums}
.bo-hoehe input:focus{border-color:var(--akzent);outline:none;
  box-shadow:inset 0 0 0 1px var(--akzent)}
.bo-hoehe i{flex:none;font-style:normal;font-size:var(--fs-label);color:var(--grau)}

/* Woher ein Wert kommt, steht neben seinem Namen — sonst sieht die Liste
   aus, als wären alle acht Zeilen gleichermassen eingegeben. */
.bo-werte dt i{display:block;font-style:normal;font-size:var(--fs-label);
  font-weight:500;letter-spacing:0;text-transform:none;color:var(--grau);
  margin-top:1px}

/* ═══ DER BELEG IN DREI BEREICHEN ════════════════════════════════════════
   GEMESSEN: das Panel war 756 px hoch, das Luftbild 407 — 349 px Loch
   darunter. Vier Punktblöcke nebeneinander in einer 395 px schmalen Spalte
   werden eben hoch. Jetzt: Bild links oben, Rechnung rechts über die volle
   Höhe, die vier Punkte darunter über die Bildbreite. */
.bo-raster{display:grid;grid-template-columns:1.7fr 1fr;
  grid-template-areas:"bild werte" "punkte werte";
  gap:var(--a-klein) var(--a-mittel);align-items:start}
.bo-bild{grid-area:bild;min-width:0}
.bo-punkte{grid-area:punkte;margin-bottom:0}
.bo-panel{grid-area:werte;min-width:0}
@media (max-width:900px){
  .bo-raster{grid-template-columns:1fr;
    grid-template-areas:"bild" "punkte" "werte"}
}
/* Die Punkte tragen jetzt Eingabefelder — vier Spalten brauchen dafür mehr
   Luft als vorher, sonst wird das Feld schmaler als seine eigene Zahl. */
.bo-punkte > div{padding:8px 10px}

/* Das Handy steigt ÜBER den Akzentstrich. Gemessen: das Band hat oben 154 px
   Polster, der Inhalt beginnt bei der Regel. Mit -86 px sitzt der Kopf des
   Geräts deutlich darüber und behält 68 px Luft zum Bandrand. */
.hakt > .wa-handy{margin-top:-86px}
@media (max-width:980px){.hakt > .wa-handy{margin-top:var(--a-mittel)}}

/* Abstand zwischen Text und Kacheln: gross genug, dass die letzte Blase
   nicht wie die Überschrift der ersten Kachel liest — und nicht grösser. */
.hakt{margin-bottom:var(--a-mittel)}
.hakt + .karten{margin-top:0}

/* ═══════════════════════════════════════════════════════════════════════════
   DER BETRIEB DAHINTER — eine grosse Kachel

   Steht direkt unter den beiden Portraits: dort wird die Frage „von wem?"
   gestellt, und hier bekommt sie ihre zweite Hälfte — aus welchem Betrieb.
   Eine Kachel mit Rahmen statt zweier loser Spalten, weil das eine Aussage
   ist und nicht zwei.
   ═══════════════════════════════════════════════════════════════════════════ */
.betrieb{display:grid;grid-template-columns:1.05fr 1fr;
  border:1px solid var(--linie-stark);background:var(--w);
  margin-top:var(--a-gross);align-items:stretch}
@media (max-width:900px){.betrieb{grid-template-columns:1fr}}
.betrieb__bild{margin:0;min-height:100%}
.betrieb__bild picture{display:block;height:100%}
.betrieb__bild img{width:100%;height:100%;display:block;object-fit:cover;
  min-height:300px}
@media (max-width:900px){.betrieb__bild img{min-height:0;aspect-ratio:5/3}}

.betrieb__text{padding:var(--a-mittel);display:flex;flex-direction:column;
  justify-content:center}
/* `align-self:start` ist hier PFLICHT, nicht Geschmack: der Elternteil ist
   ein Flex-Container mit `flex-direction:column`, und dessen Vorgabe
   `align-items:stretch` zieht jedes Kind auf die volle Breite — bei einem
   Bild heisst das gezerrt. Gemessen: 470 x 52 statt 208 x 52. */
.betrieb__marke{height:52px;width:auto;align-self:start;display:block;
  margin:10px 0 var(--a-mittel)}
/* Grösser als der übrige Kleintext: dieser Abschnitt ist der
   Vertrauensbeweis der Seite, und er wird gelesen, nicht überflogen. */
.betrieb__satz{font-size:var(--fs-body);color:var(--grau);line-height:1.6}
.betrieb__satz + .betrieb__satz{margin-top:var(--a-klein)}
.betrieb__satz strong{color:var(--tinte);font-weight:600}
.betrieb__text .klein{margin-top:var(--a-mittel)}
.betrieb__text .klein a{color:var(--akzent-text);font-weight:600}

.betrieb__zahlen{list-style:none;margin:var(--a-mittel) 0;padding:0;
  display:grid;grid-template-columns:repeat(3,auto);gap:var(--a-mittel);
  justify-content:start;
  padding-block:var(--a-klein);
  border-block:1px solid var(--linie)}
@media (max-width:520px){.betrieb__zahlen{grid-template-columns:1fr 1fr}}
.betrieb__zahlen b{display:block;font-size:var(--fs-h3);font-weight:700;
  letter-spacing:-.03em;line-height:1;color:var(--akzent-text)}
.betrieb__zahlen span{display:block;margin-top:3px;font-size:var(--fs-label);
  font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--grau)}


/* ═══ ABSCHNITTE OHNE BELEG STEHEN MITTIG ═══════════════════════════════
   Beanstandet: „‚Wie wir bauen' und ‚Der Baukasten' sind so doll
   linkslastig und rechts leer". Beide Abschnitte haben keine Grafik in der
   rechten Spalte — der Text lief auf Satzbreite links an und liess die
   halbe Seite frei. Wo nichts danebensteht, steht der Satz in der Mitte. */
#module .etikett,#module h2,#module .lead,
#module .fliess{margin-inline:auto;text-align:center}
#module .lead,#module .fliess{max-width:var(--text)}
#module .fliess p{text-align:center}
#module .puzzle-huelle{margin-inline:auto}
@media (max-width:760px){
  #module .etikett,#module h2,#module .lead,
  #module .fliess,#module .fliess p{text-align:left}
}

/* ═══════════════════════════════════════════════════════════════════════════
   AUF DEM TELEFON: ZIELE, DIE MAN TRIFFT

   Gemessen auf 393 px (iPhone): das Lockup in der Kopfleiste war 28 px
   hoch, die Höhenfelder im Böschungsbeleg 34 px, der Pfeil-Verweis 30 px.
   Ein Finger braucht 44 px — darunter trifft man den Nachbarn.

   Nur unterhalb von 760 px, weil es am Zeigegerät nicht nötig ist und die
   Kopfleiste sonst unnötig hoch würde.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width:760px){
  .kopf__links a,.fuss__links a{display:inline-flex;align-items:center;min-height:44px}
  .lockup{min-height:44px;align-items:center}
  .pfeil{min-height:44px;display:inline-flex;align-items:center}
  .bo-hoehe input{min-height:44px}
  .feld input,.feld textarea,.feld select{min-height:48px}
  .slots button{min-height:44px}
  /* Die Monatspfeile im Kalender waren 36 x 36 px. */
  .kalender__kopf button{width:44px;height:44px}
}

/* ═══════════════════════════════════════════════════════════════════════════
   ZWEI WEITERE VORFÜHRUNGEN — Wetter und Pflegekalender
   Von der alten Website übernommen und aufs neue Branding umgebaut.
   Herkunft und Farbtausch je Baustein im Kopf des Blocks; die vollständige
   Liste in 99-runde-1/DEMOS2-LIESMICH.md.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════════════════
   Vorführung „Zehn-Tage-Wettervorschau" — Bausteinstile
   Herkunft: alte Website assets/css/style.css, Regeln „.plw*"
   (Basisblock Z. 2699–2726, Ampel-/Fuss-Erweiterung Z. 3270–3282 und
   Z. 3450–3462). Eins zu eins übernommen wurden nur Maße/Raster (10-Kacheln-
   Grid, Umbruch auf 5 bei 760 px); jede Farbe ist neu zugeordnet.

   Setzt die :root-Variablen der neuen Website voraus (--akzent, --akzent-
   text, --akzent-lasur, --tinte, --grau, --papier, --linie, --w, --fs-*).
   Das Original stand auf dunklem Grund (#plan war dort ein dunkler
   Abschnitt); auf der neuen Seite liegt die Planung im HELLEN Band
   (#plandemo/.vfp-*, "band band--eng", nicht "band--dunkel") — deshalb sind
   alle Flächen/Text hier hell gebaut, nicht nachgebaut aus dem alten Dunkel-
   Zweig.

   FARBEN ALT → NEU (siehe Rückgabe-Bericht für die Gesamtliste):
     --mint (#8FE9A8, Label- und "Heute"-Farbe)   → var(--akzent-text) /
                                                      var(--akzent-lasur)
     --w100/--w85/--w60 (Text auf Dunkel)          → var(--tinte) / var(--grau)
     rgba(255,255,255,.03/.04) (Flächen auf Dunkel) → var(--w) / var(--papier)
     --gold (#F2A64A, Warnkante "gewarnt")          → var(--akzent)
     --blau (#4EA8E0, Regen-Kategorie im Diagramm)  → --vfw-regen (lokal,
       Ausnahme laut Auftrag: kategoriale Wetterfarben dürfen unterscheidbar
       bleiben, nur nicht grün; kein :root-Wert der Marke, weil es keine
       Markenfarbe ist, sondern ein Diagrammzeichen)

   Kein border-radius auf Karte/Kacheln/Warnkasten (Hausregel). Der frühere
   Rand-Akzent per box-shadow (Kachel "heute": inset-Ring; Kachel "gewarnt":
   inset-Unterkante) ist durch echte Border-Kanten ersetzt — box-shadow gibt
   es in diesem Baustein nicht.

   KEINE ANIMATION: dieser Block hat keinen Film, kein `data-vf`, keinen
   Lade-Ablauf — im Original wie hier ist die Tabelle der Dauerzustand.
   Deshalb keine @media(prefers-reduced-motion)-Regeln nötig; nichts bewegt
   sich, also kann auch nichts fehlschlagen. ═══════════════════════════ */

.vfw-karte{
  --vfw-regen:#2E6DA4; /* Diagramm-Ausnahme, siehe Kommentarkopf — kein Markenwert */
  position:relative;box-sizing:border-box;text-align:left;
  border:1px solid var(--linie);background:var(--w);color:var(--tinte);
  padding:1.1rem 1.2rem 1.15rem;max-width:640px;
}
.vfw-karte *{box-sizing:border-box}

.vfw-kopf .vfw-dn{margin:0;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--akzent-text)}
.vfw-kopf h3{margin:.25rem 0 1rem;font-size:var(--fs-body);font-weight:600;color:var(--tinte)}

/* ── Warnband: dieselbe Bauform wie die "gelbe" Planungswarnung (.vfp-bk-
   warn.vfp-gelb) auf der neuen Seite — Wetter ist "Teil der Planung" und
   steht direkt daneben, deshalb bewusst dieselbe Sprache statt einer
   eigenen Erfindung. */
.vfw-warn{margin:0 0 1.1rem;padding:.7rem .9rem;
  border-left:3px solid var(--akzent);background:#FFFBEB}
.vfw-warn-t{margin:0;font-size:var(--fs-label);font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:#78350F}
.vfw-warn-s{margin:.3rem 0 0;font-size:var(--fs-klein);color:#78350F;
  line-height:1.55;max-width:62ch}
.vfw-warn-s b{color:#5C2A00;font-weight:700}

.vfw-tage{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(10,1fr);gap:.4rem}
.vfw-tage li{display:flex;flex-direction:column;align-items:center;gap:.28rem;
  padding:.6rem .2rem;border:1px solid var(--linie);background:var(--papier);
  font-variant-numeric:tabular-nums;text-align:center}
.vfw-tage li b{font-size:var(--fs-label);font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;color:var(--grau);white-space:nowrap}

.vfw-tage li.vfw-heute{background:var(--akzent-lasur);border-color:var(--akzent)}
.vfw-tage li.vfw-heute b{color:var(--akzent-text)}

.vfw-ic{width:20px;height:20px;stroke:var(--grau);fill:none;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.vfw-tage li.vfw-nass .vfw-ic{stroke:var(--vfw-regen)}

.vfw-temp{font-size:var(--fs-klein);font-weight:600;color:var(--tinte)}
.vfw-tage li small{font-size:var(--fs-label);color:var(--grau)}
.vfw-tage li.vfw-nass small{color:var(--vfw-regen)}

/* Regenkachel MIT Unwetter-Schwelle erreicht: Unterkante statt inset-
   box-shadow (Hausregel). */
.vfw-tage li.vfw-gewarnt{border-bottom:2px solid var(--akzent)}

.vfw-fuss{list-style:none;margin:1.1rem 0 0;padding-top:.9rem;
  border-top:1px solid var(--linie);
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:1rem clamp(1.2rem,2.4vw,2rem)}
.vfw-fuss dt{margin:0;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--akzent-text)}
.vfw-fuss dd{margin:.3rem 0 0;font-size:var(--fs-klein);color:var(--grau);line-height:1.5}
.vfw-fuss dd b{color:var(--tinte);font-weight:600}

@media(max-width:760px){
  .vfw-tage{grid-template-columns:repeat(5,1fr)}
  .vfw-karte{padding:1rem 1rem .95rem}
}
@media(max-width:720px){
  .vfw-fuss{grid-template-columns:1fr;gap:.8rem}
}

/* ═══════════════════════════════════════════════════════════════════════════
   DAS LIQUIDITÄTSDIAGRAMM

   Je Monat zwei Säulen nebeneinander, nicht übereinander: links die
   gestellten Rechnungen (unterteilt in bezahlt und offen), rechts die
   erbrachte, aber nicht abgerechnete Leistung. Die Trennung ist keine
   Gestaltungsfrage — im Quelltext der App steht dazu „DREI ZAHLEN, ZWEI
   BEDEUTUNGEN — NICHT IN EINEN BALKEN". Was gestellt ist, ist Geld
   unterwegs; was liegen blieb, ist Arbeit ohne Rechnung. Ein gemeinsamer
   Balken machte daraus eine Zahl, die nichts bedeutet.
   ═══════════════════════════════════════════════════════════════════════════ */
.liq{margin:0}
.liq-plot{position:relative;display:grid;grid-auto-flow:column;
  grid-auto-columns:1fr;gap:6px;height:190px;align-items:end;
  padding-top:22px;border-bottom:2px solid var(--tinte)}

/* Die Fixkostenlinie läuft quer durch — darunter heisst darunter. */
.liq-schwelle{position:absolute;left:0;right:0;height:0;
  border-top:2px dashed var(--tinte);pointer-events:none}
/* Die Beschriftung sitzt LINKS und über der Linie: rechts ragte sie über
   den Rand des Belegs hinaus, weil die letzte Säule dort schon steht. */
.liq-schwelle b{position:absolute;left:0;top:-17px;font-size:var(--fs-label);
  font-weight:700;letter-spacing:.04em;color:var(--tinte);
  background:var(--w);padding:0 5px 0 0;white-space:nowrap}

.liq-monat{display:flex;flex-direction:column;justify-content:flex-end;
  height:100%;min-width:0}
.liq-paar{display:flex;align-items:flex-end;gap:2px;height:100%}
.liq-saeule{flex:1;min-width:0;position:relative}
/* Bezahlt ist die volle Fläche, offen sitzt oben darauf — zusammen sind
   sie die gestellte Summe. */
.liq-saeule--gestellt{background:var(--tinte)}
.liq-offen{position:absolute;left:0;right:0;top:0;display:block;
  background:repeating-linear-gradient(135deg,
    var(--linie-stark) 0 3px,var(--papier) 3px 6px)}
.liq-saeule--unab{background:var(--akzent)}
/* Ein Monat unter den Fixkosten bekommt die Farbe, die Alarm heisst. */
.liq-monat--unter .liq-saeule--gestellt{background:var(--rot)}

.liq-m{display:block;margin-top:6px;text-align:center;font-size:var(--fs-label);
  font-weight:600;color:var(--grau)}
.liq-monat--unter .liq-m{color:var(--rot);font-weight:700}

.liq-legende{display:flex;flex-wrap:wrap;gap:var(--a-klein) var(--a-mittel);
  margin-top:var(--a-klein);font-size:var(--fs-label);color:var(--grau)}
.liq-legende span{display:inline-flex;align-items:center;gap:6px}
.liq-pkt{width:10px;height:10px;flex:none}
.liq-pkt--bez{background:var(--tinte)}
.liq-pkt--off{background:repeating-linear-gradient(135deg,
  var(--linie-stark) 0 3px,var(--papier) 3px 6px);
  border:1px solid var(--linie-stark)}
.liq-pkt--unab{background:var(--akzent)}

/* Die Säulen wachsen von unten, wenn das Diagramm ins Bild kommt. Zerlegt
   wird nur unter `zerlegt` — die Klasse setzt `main.js` selbst und nimmt
   sie beim Hinscrollen wieder weg. Ohne Skript steht das Diagramm fertig. */
@media (prefers-reduced-motion:no-preference){
  .liq-plot .liq-saeule{transform-origin:bottom center;
    transition:transform .55s cubic-bezier(.22,.61,.36,1) var(--verz,0s)}
  .liq-plot.zerlegt .liq-saeule{transform:scaleY(0)}
  .liq-plot .liq-schwelle{transition:opacity .4s ease .5s}
  .liq-plot.zerlegt .liq-schwelle{opacity:0}
}

/* ═══ ZWISCHENÜBERSCHRIFT IN EINER FUNKTIONSLISTE ═══════════════════════
   „Was geprüft wird", „Was blockiert wird", „Was daran hängt" — drei
   Listen hintereinander ohne Zwischenüberschrift lesen sich als eine
   lange. Mit ihr sieht man, wo die Aussage wechselt. */
.funk-h{display:block;margin:var(--a-mittel) 0 8px;font-size:var(--fs-label);
  font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--akzent-text);padding-top:var(--a-klein);
  border-top:1px solid var(--linie)}
.band--dunkel .funk-h{color:var(--akzent);border-top-color:rgba(255,255,255,.16)}
.modul__text > .funk-h:first-of-type{margin-top:var(--a-mittel)}

/* Eine Liste, die Verbote aufzählt, bekommt ein anderes Zeichen als eine,
   die Fähigkeiten aufzählt — ein Haken vor „wird blockiert" liest sich
   falsch herum. */
.haken--stopp li::before{content:"";width:10px;height:10px;top:.42em;
  background:var(--rot);border-radius:0}

/* ═══════════════════════════════════════════════════════════════════════════
   MODULSEITE (module.html) — ADDITIVER BLOCK, 26.08.2026

   ALLES HIER IST AUF `.modulseite` GESCHACHTELT. Der Grund ist keine
   Kosmetik: an `index.html` arbeitet gleichzeitig jemand anders, und dieses
   Blatt wird von beiden Seiten geladen. Keine bestehende Regel ist geändert
   worden — jede Abweichung, die die Modulseite braucht, steht hier unten und
   greift nur dort.

   Vier Dinge stehen darin:
     1. Abschnittsformen der Modulseite (Bühne, Kopfzeile zweispaltig)
     2. Vorführung „Leistungsstand" (.vfr-) — Meldungen → Positionen
     3. Vorführung „Pflegeplan als Zeitbalken" (.vfz-)
     4. Nacharbeit an den übernommenen Vorführungen: minimale Rundung,
        Knopfmaß, Rhythmus, Film läuft einmal statt endlos
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1 · Abschnittsformen ───────────────────────────────────────────────── */

/* Kopfzeile eines Moduls, wenn die Vorführung darunter über die volle Breite
   läuft: Überschrift links, die fünf Punkte rechts. Zwei Spalten statt einer
   Textwand — und die Punkte stehen auf Augenhöhe der Überschrift, nicht
   darunter. */
.modulseite .m-kopf{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(24px,4vw,64px);align-items:start;margin-bottom:var(--a-gross)}
@media (max-width:860px){.modulseite .m-kopf{grid-template-columns:1fr;gap:var(--a-mittel)}}
.modulseite .m-kopf h2{font-size:var(--fs-h2);letter-spacing:-.028em;
  margin-bottom:var(--a-klein)}
.modulseite .m-kopf > div > p{color:var(--grau);max-width:34ch}
.modulseite .band--dunkel .m-kopf > div > p{color:var(--d-grau)}
.modulseite .m-kopf .haken{margin:0}

/* Die Bühne: die Vorführung bekommt die ganze Spaltenbreite. Das ist der
   Punkt der Umstellung — vorher stand links ein Textblock und rechts eine
   halbe, abgeschnittene Karte. */
.modulseite .m-buehne{max-width:100%}

/* Zwei Zuschnitte des bestehenden `.modul`-Rasters, ohne es zu ändern:
   `--breit` gibt der Vorführung mehr als die Hälfte, `--kehrt` stellt sie
   nach links. Beides nur hier. */
.modulseite .modul--breit{grid-template-columns:minmax(0,.84fr) minmax(0,1.16fr)}
.modulseite .modul--kehrt .modul__text{order:2}
.modulseite .modul--kehrt .modul__beleg{order:1}
@media (max-width:900px){
  .modulseite .modul--breit{grid-template-columns:1fr}
  .modulseite .modul--kehrt .modul__text,
  .modulseite .modul--kehrt .modul__beleg{order:0}
}

/* ═══ DIE VORFÜHRUNG KLEBTE ÜBER DIE ABSCHNITTSGRENZE ════════════════════
   `.modul__beleg>*{position:sticky;top:80px}` hält die Karte fest, während
   der Text weiterscrollt. Steht die Karte in einem Abschnitt, dessen
   Trennlinie höher liegt als die Karte lang ist, schiebt sie sich über die
   Linie — gemessen, siehe Bericht. Auf der Modulseite ist der Text jetzt
   kurz und die Vorführung hoch; kleben hat damit keinen Nutzen mehr, nur
   noch den Fehler. Weg damit — nur hier. */
.modulseite .modul__beleg>*{position:relative;top:auto}
/* `relative` statt `static`: `static` nimmt dem Baustein den Bezugsrahmen
   für alles, was absolut darin sitzt. Gemessen war die Aufmaß-Legende danach
   54 px rechts aus dem Luftbild heraus — sie hing plötzlich am Abschnitt
   statt am Bild. `relative` mit `top:auto` steht im Fluss wie `static` und
   bleibt trotzdem Bezugsrahmen. */

/* ── 2 · Vorführung „Leistungsstand" (.vfr-) ────────────────────────────── */
/* Was sie zeigt: die Kette vom Feld in die Abrechnung. Links laufen die
   Meldungen ein, rechts stehen die Positionen des Leistungsverzeichnisses
   mit Soll, Ist und Abweichung. Das Liquiditätsbild ist die FOLGE davon und
   steht deshalb kleiner darunter, nicht hier.
   Aufbau bewusst wie `.vfg-`/`.vfp-`: Kopfleiste, Körper, 1px-Kontur, kein
   Schatten. Innen 3 px Rundung wie in der App. */
.modulseite .vfr-karte{background:var(--w);border:1px solid var(--linie-stark);
  border-radius:3px;overflow:hidden;color:var(--tinte)}
.modulseite .vfr-karte,.modulseite .vfr-karte *{box-sizing:border-box}
.modulseite .vfr-seitenkopf{display:flex;align-items:center;gap:.6rem;
  padding:.6rem .8rem;border-bottom:1px solid var(--linie);background:var(--w)}
.modulseite .vfr-tt{font-size:var(--fs-klein);font-weight:700;line-height:1.2;
  flex:1;min-width:0}
.modulseite .vfr-tt small{display:block;font-size:var(--fs-label);font-weight:400;
  color:var(--grau)}
.modulseite .vfr-knopf{flex:none;border-radius:3px;padding:.3rem .6rem;
  font-size:var(--fs-label);font-weight:600;background:var(--akzent-knopf);color:var(--w)}
.modulseite .vfr-knopf.vfr-leer{background:var(--w);color:var(--grau);
  border:1px solid var(--linie-stark)}
.modulseite .vfr-koerper{padding:12px}

.modulseite .vfr-kacheln{display:grid;grid-template-columns:repeat(3,1fr);
  gap:8px;margin-bottom:12px}
@media (max-width:560px){.modulseite .vfr-kacheln{grid-template-columns:1fr}}
.modulseite .vfr-kachel{border:1px solid var(--linie);border-radius:3px;
  padding:8px 10px;background:var(--papier)}
.modulseite .vfr-kachel span{display:block;font-size:var(--fs-label);
  font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--grau)}
.modulseite .vfr-kachel b{display:block;margin-top:2px;font-size:var(--fs-zahl);
  font-weight:700;letter-spacing:-.02em;line-height:1.1;
  font-variant-numeric:tabular-nums;color:var(--tinte)}
.modulseite .vfr-kachel--warn{background:#FFF7ED;border-color:#F5C08A}
.modulseite .vfr-kachel--warn b{color:#8A3B0B}

.modulseite .vfr-spalten{display:grid;grid-template-columns:minmax(0,.62fr) minmax(0,1fr);
  gap:12px;align-items:start}
@media (max-width:820px){.modulseite .vfr-spalten{grid-template-columns:1fr}}

.modulseite .vfr-h{display:block;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--grau);margin-bottom:6px}

.modulseite .vfr-meldung{display:grid;grid-template-columns:auto 1fr auto;
  gap:4px 8px;align-items:baseline;border:1px solid var(--linie);border-radius:3px;
  padding:8px;margin-bottom:8px;background:var(--w)}
.modulseite .vfr-meldung:last-child{margin-bottom:0}
.modulseite .vfr-art{grid-row:1;font-size:var(--fs-label);font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;color:var(--akzent-text)}
.modulseite .vfr-meldung--mehr .vfr-art{color:#8A3B0B}
/* Kein `overflow:hidden;text-overflow:ellipsis;white-space:nowrap` mehr.
   Gemessen bei 393 px auf `module.html`: fuenf dieser Zellen schnitten ab,
   die schlimmste 139 px Text in 53 px Kasten — „S. Krüger · 13.08. 11:40"
   endete nach dem Namen. Abschneiden ist dieselbe Umgehung wie Rollen: der
   Inhalt ist da und nicht lesbar. Der Name darf jetzt umbrechen. */
.modulseite .vfr-wer{grid-row:1;font-size:var(--fs-label);color:var(--grau);
  min-width:0;overflow-wrap:anywhere}
.modulseite .vfr-menge{grid-row:1;font-size:var(--fs-klein);font-weight:700;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.modulseite .vfr-was{grid-column:1/-1;font-size:var(--fs-klein);line-height:1.35}
.modulseite .vfr-was b{font-weight:600}
.modulseite .vfr-pfad{grid-column:1/-1;font-size:var(--fs-label);color:var(--grau)}
.modulseite .vfr-pfad i{font-style:normal;color:var(--akzent-text);font-weight:700}

/* ═══ HIER STAND EIN WAAGERECHTER ROLLKASTEN ═════════════════════════════
   Bis zum 28.08.2026: `.vfr-roll{overflow-x:auto}` mit `.vfr-tab
   {min-width:580px}` — die Tabelle rollte in ihrem eigenen Kasten.
   Gemessen bei 393 px: 580 px Inhalt in 325 px Kasten.

   Der Auftraggeber hat an diesem Tag verschaerft: „nirgends, wirklich
   nirgends horizontal scrolls". Das streicht ausdruecklich die bis dahin
   geltende Ausnahme, ein zu breiter Inhalt duerfe im EIGENEN Kasten rollen.

   `overflow-x:hidden` waere keine Antwort darauf, sondern nur ein anderer
   Weg, den Inhalt unerreichbar zu machen. Umgebaut wurde stattdessen —
   dieselbe Machart wie in der App (`06-software/app/src/app/globals.css`,
   `.lbw-karten-tabelle`; der umgedrehte Waechter steht in
   `06-software/app/src/components/inventar/scrollkasten.test.ts`):
   unterhalb von 640 px wird jede ZEILE eine KARTE, und jeder Wert traegt
   seine Spaltenueberschrift aus `data-spalte` selbst mit. Es faellt keine
   Spalte weg — die Werte stehen untereinander statt nebeneinander.
   Wer `min-width` zurueckbringt, bringt den Rollkasten zurueck. */
.modulseite .vfr-roll{border:1px solid var(--linie);border-radius:3px}
.modulseite .vfr-z{display:grid;
  grid-template-columns:minmax(0,1fr) 56px 74px 104px 102px;
  gap:0;align-items:center;border-top:1px solid var(--linie)}
.modulseite .vfr-z:first-child{border-top:0}
.modulseite .vfr-z>*{padding:7px 8px;font-size:var(--fs-klein);line-height:1.3}
.modulseite .vfr-z>:not(:first-child){text-align:right;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.modulseite .vfr-kopf{background:var(--papier);border-top:0}
.modulseite .vfr-kopf>*{font-size:var(--fs-label);font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:var(--grau)}
.modulseite .vfr-pos b{display:block;font-weight:600}
.modulseite .vfr-pos small{display:block;font-size:var(--fs-label);color:var(--grau)}
.modulseite .vfr-ab{font-weight:700;color:var(--grau)}
.modulseite .vfr-z--mehr{background:#FFF7ED}
.modulseite .vfr-z--mehr .vfr-ab{color:#8A3B0B}
.modulseite .vfr-stand{position:relative}
.modulseite .vfr-stand em{font-style:normal;font-weight:700;display:block;
  font-size:var(--fs-label)}
.modulseite .vfr-balken{display:block;height:4px;margin-top:3px;
  background:var(--linie);border-radius:2px;overflow:hidden}
.modulseite .vfr-balken i{display:block;height:100%;background:var(--akzent);
  border-radius:2px}
.modulseite .vfr-z--mehr .vfr-balken i{background:#C2700F}

.modulseite .vfr-fuss{margin-top:10px;border:1px solid #F5C08A;background:#FFF7ED;
  border-radius:3px;padding:8px 10px;font-size:var(--fs-klein);line-height:1.45;
  color:#5A2A08}
.modulseite .vfr-fuss b{font-weight:700}

/* ═══ SECHS SPALTEN — NUR FÜR DEN LEISTUNGSSTAND ═════════════════════════
   `.vfr-z` hat fünf Spalten, und die benutzt seit dem 27.08. auch der
   Stundenzettel im Arbeitszeit-Modul. Das Raster hier zu ändern hätte den
   mit umgeworfen — deshalb ein Zusatz an der Tabelle statt eines Eingriffs
   in `.vfr-z`. Summe der festen Spalten 388 px.

   `min-width:620px` stand hier bis zum 28.08.2026 und trug den zweiten
   Rollkasten dieser Seite (gemessen bei 393 px: 620 px in 325 px). Weg,
   ersatzlos — unterhalb von 640 px greift die Kartenfassung unten, und die
   braucht keine Mindestbreite. */
.modulseite .vfr-tab--sechs .vfr-z{
  grid-template-columns:minmax(0,1fr) 52px 72px 72px 96px 96px}

/* ═══ DIE MEHRMENGE IST DER GRUND FÜR DIESES MODUL ═══════════════════════
   Sie stand als graue Zelle unter vier anderen. Jetzt trägt sie als
   einzige Zahl der Tabelle einen gefüllten Grund — dieselben zwei Farben,
   die `.vfr-z--mehr` und `.vfr-fuss` schon benutzen, keine neue Familie.

   DIE FARBE HAENGT AN DER ZELLE, NICHT AM `b`. Gemessen 27.08.: mit
   `color` am `b` kam 2,26 : 1 heraus statt der erwarteten 8er-Werte — der
   Abrechnungsabschnitt ist ein `band--dunkel`, und style.css:3810 setzt dort
   `:is(b,strong){color:inherit!important}`. Das `!important` schlaegt jede
   Farbe am `b`. Ueber die Zelle geht sie durch, weil `inherit` genau sie
   erbt. Wer die Farbe zurueck ans `b` schiebt, baut den Verstoss neu ein. */
.modulseite .vfr-mehrzelle{color:#FFF7ED}
.modulseite .vfr-mehrzelle b{display:inline-block;padding:2px 7px;
  border-radius:3px;background:#8A3B0B;font-weight:700;white-space:nowrap}
/* Zweite Kleinzeile an einer Position, die auf etwas WARTET statt zu warnen:
   grau, nicht orange — sonst schreit die Zeile so laut wie die Mehrmenge. */
.modulseite .vfr-mehr--warte{color:var(--grau)!important}

/* ═══ DAS LIQUIDITÄTSBILD IST GANZ RAUS ══════════════════════════════════
   Es stand hier zuerst kleiner unter der Vorführung. Gemessen: 55 sichtbare
   Elemente — daneben war die Meldungs-Karte nicht mehr die Hauptsache,
   sondern eine von zwei. Der Kern des Moduls sind die Meldungen und was aus
   ihnen wird; die Geldsicht ist die Folge und steht auf der Startseite.
   Zwei grosse Vorführungen in einem Abschnitt heben sich gegenseitig auf. */

/* ── 3 · Vorführung „Pflegeplan als Zeitbalken" (.vfz-) ─────────────────── */
/* Waagerecht die zwölf Monate. Je Maßnahme ein Balken über das Fenster, in
   dem sie zulässig und sinnvoll ist; senkrechte Striche darin sind die
   Termine. Die Schonzeit nach § 39 Abs. 5 BNatSchG liegt als eigener
   Bereich hinter allem — sie ist der Grund, warum der Gehölzbalken im
   Sommer aufhört.
   Alle Lagen in MONATSEINHEITEN (0 = 1. Januar, 12 = 31. Dezember), gesetzt
   über --von/--bis/--t im Markup. Keine Pixelwerte, damit der Balken bei
   jeder Breite auf demselben Monat sitzt. */
.modulseite .vfz-karte{--vfz-lab:196px;background:var(--w);
  border:1px solid var(--linie-stark);border-radius:3px;overflow:hidden;color:var(--tinte)}
.modulseite .vfz-karte,.modulseite .vfz-karte *{box-sizing:border-box}
.modulseite .vfz-seitenkopf{display:flex;align-items:center;gap:.6rem;
  padding:.6rem .8rem;border-bottom:1px solid var(--linie)}
.modulseite .vfz-tt{font-size:var(--fs-klein);font-weight:700;line-height:1.2;flex:1;min-width:0}
.modulseite .vfz-tt small{display:block;font-size:var(--fs-label);font-weight:400;color:var(--grau)}
.modulseite .vfz-knopf{flex:none;border-radius:3px;padding:.3rem .6rem;
  font-size:var(--fs-label);font-weight:600;background:var(--akzent-knopf);color:var(--w)}
.modulseite .vfz-knopf.vfz-leer{background:var(--w);color:var(--grau);
  border:1px solid var(--linie-stark)}
.modulseite .vfz-koerper{padding:12px}
/* ═══ AUCH HIER STAND EIN ROLLKASTEN ═════════════════════════════════════
   Bis zum 28.08.2026: `.vfz-roll{overflow-x:auto}` mit `.vfz-gitter
   {min-width:640px}` (gemessen bei 393 px: 640 px in 327 px). Der Kalender
   laesst sich nicht in Karten zerlegen — zwoelf Monate NEBENeinander SIND
   die Aussage. Umgebaut wurde deshalb anders: unterhalb von 640 px faellt
   die Beschriftungsspalte weg und stellt sich UEBER die Spur (siehe
   `--vfz-lab:0px` im Block ganz unten). Die zwoelf Monate bekommen dann die
   volle Kartenbreite statt der Haelfte davon. */
.modulseite .vfz-gitter{position:relative}

/* Die Schonzeit: ein Bereich, kein Muster je Feld. Liegt hinter den Balken
   und läuft durch alle Zeilen — genau so, wie sie im Jahr durchläuft.
   1. März = Monat 2, 30. September = Monat 9. */
.modulseite .vfz-schonband{position:absolute;top:0;bottom:22px;pointer-events:none;
  left:calc(var(--vfz-lab) + (100% - var(--vfz-lab)) * 2 / 12);
  width:calc((100% - var(--vfz-lab)) * 7 / 12);
  /* Die Schraffur war die dritte Strichlage im selben Feld (Raster,
     Terminstrich, Schraffur). Eine ruhige Flaeche sagt „hier gilt etwas
     anderes" genauso — und laesst dem Termin die Buehne. */
  background:rgba(192,57,43,.06);
  border-inline:1px dashed rgba(192,57,43,.45)}
/* Die Beschriftung sass auf der Monatszahl 03 — gemessen im Bild, nicht im
   Quelltext zu sehen. Jetzt bekommt die Kopfzeile eine eigene Etage: Monate
   unten, „Schonzeit" darüber, mittig über dem Bereich, den sie benennt. */
.modulseite .vfz-schon-t{position:absolute;top:1px;left:50%;transform:translateX(-50%);
  font-size:var(--fs-label);font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;color:#8A2318;white-space:nowrap}

.modulseite .vfz-z{display:grid;grid-template-columns:var(--vfz-lab) minmax(0,1fr);
  align-items:center;gap:0;border-top:1px solid var(--linie);min-height:38px}
.modulseite .vfz-mkopf{border-top:0;min-height:40px;align-items:end}
.modulseite .vfz-n{padding:5px 10px 5px 0;font-size:var(--fs-klein);line-height:1.25;
  min-width:0}
.modulseite .vfz-n b{display:block;font-weight:600}
.modulseite .vfz-n small{display:block;font-size:var(--fs-label);color:var(--grau)}
.modulseite .vfz-mkopf .vfz-n{font-size:var(--fs-label);font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:var(--grau)}

.modulseite .vfz-monate{display:grid;grid-template-columns:repeat(12,1fr);
  font-size:var(--fs-label);font-weight:700;color:var(--grau);text-align:center}
.modulseite .vfz-monate span{padding-bottom:3px}

/* Die Spur: der Bezugsrahmen, alles Weitere liegt absolut darin.
   ═══ HIER STANDEN ZWOELF SENKRECHTE RASTERLINIEN ═══════════════════════
   Beanstandet: „0 uebersichtlich, blicke da nicht durch, da muss ja
   irgendwo ne linie sein mit dem optimalen pflegetermin." Genau das war
   das Problem: in jeder Zeile standen elf Rasterlinien neben EINEM
   Terminstrich, alle gleich duenn. Der Strich, auf den es ankommt, ging
   zwischen den Strichen unter, die nichts bedeuten.
   Das Monatsraster steht jetzt nur noch in der Kopfzeile — dort sagt es
   dasselbe, ohne mit dem Termin um Aufmerksamkeit zu ringen. */
.modulseite .vfz-spur{position:relative;height:26px}

.modulseite .vfz-b{position:absolute;top:6px;height:14px;border-radius:3px;
  background:var(--akzent);opacity:.85;
  left:calc(var(--von) * 100% / 12);
  width:calc((var(--bis) - var(--von)) * 100% / 12)}
/* Gehölzarbeiten, die die Schonzeit begrenzt: andere Fläche, damit im Bild
   zu sehen ist, WARUM der Balken dort aufhört. */
.modulseite .vfz-b--gehoelz{background:#2E6F9E;opacity:.9}
.modulseite .vfz-b--weich{background:var(--akzent);opacity:.42}

/* Der Termin. Ein Strich, kein Punkt — er sagt „an diesem Tag", nicht
   „irgendwann hier". Und er ist ab jetzt das lauteste Element der Spur:
   3 px statt 2, ueber die volle Zeilenhoehe statt nur ueber den Balken,
   mit einem Kopf oben und dem Datum daneben. */
.modulseite .vfz-t{position:absolute;top:0;height:26px;width:3px;
  background:var(--tinte);left:calc(var(--t) * 100% / 12);margin-left:-1.5px;
  z-index:2}
/* ═══ HIER SASS EIN PFEILKOPF, EINEN LAUF LANG ═════════════════════════
   Ein 9-px-Dreieck oben auf dem Strich. Gemessen mit `pruefe-kontrast.js`:
   12 Verstoesse, alle `I.vfz-t::before` mit 1,00 : 1 — das Skript misst die
   FARBE eines Pseudoelements gegen den Grund des Elements, an dem es haengt,
   und der ist hier der Strich selbst. Der Kopf sagte ohnehin nichts, was der
   3-px-Strich und das Datum daneben nicht schon sagen. Ersatzlos weg. */
/* Das Datum am Strich. Eigenes Element statt Pseudoelement und mit eigenem,
   deckendem Grund: sonst misst `pruefe-kontrast.js` die Schrift gegen den
   dunklen Strich, an dem sie haengt, und meldet 1,00 : 1. */
.modulseite .vfz-tag{position:absolute;left:6px;top:50%;transform:translateY(-50%);
  background:var(--w);color:var(--tinte);font-size:var(--fs-label);font-weight:700;
  line-height:1.4;padding:0 3px;white-space:nowrap;border:1px solid var(--linie)}
.modulseite .vfz-t--offen{background:#8A3B0B}

.modulseite .vfz-leg{display:flex;flex-wrap:wrap;gap:6px 16px;margin-top:10px;
  font-size:var(--fs-label);color:var(--grau);align-items:center}
.modulseite .vfz-leg span{display:inline-flex;align-items:center;gap:5px}
.modulseite .vfz-leg--haupt{color:var(--tinte)}
.modulseite .vfz-leg--haupt .vfz-lt{width:3px;height:14px}
.modulseite .vfz-lb{width:18px;height:8px;border-radius:2px;background:var(--akzent);opacity:.85}
.modulseite .vfz-lb--gehoelz{background:#2E6F9E;opacity:.9}
.modulseite .vfz-lt{width:2px;height:12px;background:var(--tinte)}
.modulseite .vfz-lr{width:18px;height:10px;
  background:repeating-linear-gradient(-45deg,rgba(192,57,43,.16) 0 4px,transparent 4px 8px);
  border-inline:1px dashed rgba(192,57,43,.45)}
/* `.vfz-hinweis` („Auf dem Handy seitlich schieben") ist am 28.08.2026
   ersatzlos entfallen — zusammen mit dem Schieben, auf das er hinwies.
   Ein Hinweis auf eine Bedienung, die es nicht mehr gibt, ist eine
   Falschauskunft. Beide Absaetze sind aus `module.html` heraus. */
.modulseite .vfz-recht{margin-top:8px;font-size:var(--fs-klein);line-height:1.45;
  color:var(--grau);border-top:1px solid var(--linie);padding-top:8px}
.modulseite .vfz-recht b{color:var(--tinte);font-weight:700}

/* ═══════════════════════════════════════════════════════════════════════════
   SCHMALER SCHIRM: KEIN ROLLKASTEN, SONDERN EIN ANDERER BAU
   Anordnung vom 28.08.2026 — „nirgends, wirklich nirgends horizontal
   scrolls". Drei Rollkaesten sind hier verschwunden; was an ihre Stelle
   tritt, steht in diesem Block. Gemessen wird im Bild bei 393 px:
     document.documentElement.scrollWidth > clientHeight  →  muss falsch sein
     [...document.querySelectorAll('*')].filter(e => e.scrollWidth > e.clientWidth+1)
   Die Grenze liegt bei 640 px: das war die groesste der drei
   Mindestbreiten (580 / 620 / 640), also genau die Breite, unterhalb derer
   frueher gerollt wurde.
   ═══════════════════════════════════════════════════════════════════════ */
@media(max-width:640px){

  /* ── 1 · Zeile wird Karte (`.vfr-tab`, `.vfr-tab--sechs`) ──────────────
     Die Kopfzeile faellt weg, weil jeder Wert seine Ueberschrift ab jetzt
     selbst traegt: `data-spalte` am Wert, ausgegeben als `::before`.
     Genau die Machart der App (`.lbw-karten-tabelle`). */
  .modulseite .vfr-z{display:block;padding:6px 0}
  /* Nach `.vfr-z` und mit derselben Trefferzahl: die Kopfzeile IST eine
     `.vfr-z`, und bei gleicher Spezifitaet gewinnt die spaetere Regel.
     Steht `display:none` davor, bleibt die Kopfzeile stehen — gemessen
     bei 393 px: „Mehrmenge" und „Fortschritt" ragten dann bis 521 px. */
  .modulseite .vfr-kopf{display:none}
  .modulseite .vfr-z>*{padding:2px 10px}
  .modulseite .vfr-z>:not(:first-child){text-align:left;white-space:normal}
  .modulseite .vfr-z>[data-spalte]{display:flex;align-items:baseline;
    justify-content:space-between;gap:1rem}
  .modulseite .vfr-z>[data-spalte]::before{content:attr(data-spalte);flex:none;
    font-size:var(--fs-label);font-weight:700;letter-spacing:.05em;
    text-transform:uppercase;color:var(--grau)}
  .modulseite .vfr-pos{padding-bottom:4px}
  /* Der Fortschritt ist Zahl UND Balken. Als Reihe nebeneinander wuerde
     der Balken zum zweiten Flex-Element und schrumpfte auf seinen Inhalt;
     deshalb steht seine Beschriftung hier darueber statt daneben. */
  .modulseite .vfr-z>.vfr-stand[data-spalte]{display:block}
  .modulseite .vfr-z>.vfr-stand[data-spalte]::before{display:block;margin-bottom:2px}

  /* ── 2 · Der Pflegekalender stellt seine Beschriftung nach oben ────────
     Zwoelf Monate nebeneinander SIND die Aussage dieses Bildes — es laesst
     sich nicht in Karten zerlegen. Statt dessen faellt die 196-px-Spalte
     mit dem Massnahmennamen aus der Zeile heraus und stellt sich darueber;
     die Monate bekommen die volle Kartenbreite. `--vfz-lab:0px` haelt die
     Rechnung von `.vfz-schonband` richtig, die den Bereich Maerz–September
     aus derselben Variablen ableitet. */
  .modulseite .vfz-karte{--vfz-lab:0px}
  .modulseite .vfz-z{grid-template-columns:minmax(0,1fr);min-height:0}
  .modulseite .vfz-n{padding:6px 0 2px}
  /* Das Datum am Terminstrich haengt rechts heraus. Bei voller Breite ist
     das Platz genug; bei halber standen zwei Datumsmarken derselben Zeile
     (05.05. und 25.06.) uebereinander. Enger gesetzt passen sie. */
  .modulseite .vfz-tag{left:4px;padding:0 2px}
}

/* ── 4 · Nacharbeit an den übernommenen Vorführungen ────────────────────── */

/* ═══ MINIMAL RUND — DIE EINE BEGRÜNDETE AUSNAHME ════════════════════════
   Die Hausregel der Seite ist `border-radius:0`. Die App hat runde Ecken.
   Eine Vorführung, die die App zeigt, soll aussehen wie die App und nicht
   wie die Website — deshalb 3 px INNERHALB der Vorführungen. Abschnitte,
   Kacheln der Seite, Knöpfe der Seite bleiben kantig. Der Radius steht an
   den Bauteilen, nicht am Rahmen der Seite. */
/* Die vfm-Familie steht NICHT mehr unter `.modulseite` — sie steht auch auf
   der Startseite. Siehe den Block „EIN BAUTEIL GEHOERT SICH SELBST" unten. */
.modulseite :is(.vfa-bild,.vfa-legende,.vfa-wz,
  .vfp-screen,.vfp-bkarte,.vfp-knopf,.vfp-bk-warn,.vfp-bk-ok,.vfp-pk,.vfp-pk-opt,
  .vfg-screen,.vfg-knopf,.vfg-lv,.vfg-lade,
  .vfw-karte,.vfw-warn,.vfw-tage li,
  .beleg,.b-zeile,.b-feld,.b-warn,.b-marke,.b-luft){border-radius:3px}
.modulseite :is(.vfp-chip,.vfp-chip-neu,.vfa-sw){border-radius:2px}

/* ═══════════════════════════════════════════════════════════════════════════
   EIN BAUTEIL GEHOERT SICH SELBST — NICHT DER SEITE, AUF DER ES ZUERST STAND
   Beanstandet auf der STARTSEITE: „überlappung und dem hart eckigen knopf der
   unten alles füllt".

   GEMESSEN, warum nur dort: die ganze Feinarbeit an dieser Vorfuehrung hing
   unter `.modulseite`. Diese Koerperklasse tragen `module.html` und
   `leistung.html` — `index.html` nicht. Dieselbe Vorfuehrung, zwei Zustaende:
       index.html      378 x 50 px · Abstand 1/1/1 px · Radius 0
       module.html     142 x 44 px · Abstand 13/13 px · Radius 3 px
       leistung.html   142 x 44 px · Abstand 13/13 px · Radius 3 px
   Der Knopf lief auf der Startseite ueber die volle Kartenbreite (Karte 380,
   Knopf 378) und stiess an alle drei Kanten.

   Die Klasse `.modulseite` an die Startseite zu haengen waere die falsche
   Reparatur — der Name saegt dann etwas Unwahres. Diese Regeln beschreiben
   das BAUTEIL, nicht die Seite: sie stehen jetzt unverschachtelt und gelten
   ueberall, wo die Vorfuehrung steht. An `module.html` und `leistung.html`
   aendert sich dadurch nichts (dieselben Deklarationen, nur eine Klasse
   weniger Spezifitaet, und es gibt keine Regel, die dagegen haelt) —
   nachgemessen auf allen drei Seiten.

   NOCH UNTER `.modulseite` und bewusst dort geblieben:
     · `.modulseite .modul--kehrt .vfm-geraet` — das ist Seitenlayout,
       `.modul--kehrt` gibt es nur auf den Modulseiten.
     · `.modulseite :is(…,.vfm-tt)` in der 393-px-Abfrage — steht in einer
       Liste mit fuenf fremden Familien; herausloesen hiesse duplizieren.
   ═══════════════════════════════════════════════════════════════════════════ */
.vfm-phone,.vfm-feld-fest,.vfm-eingabe,.vfm-hinweis,.vfm-kachel,
.vfm-unt-flaeche,.vfm-btn{border-radius:3px}

/* ═══ DER KNOPF WAR DAS GRÖSSTE ELEMENT DER VORFÜHRUNG ═══════════════════
   „Meldung senden" lief als dunkelgrünes Band über die volle Kartenbreite
   und war höher als jedes Feld darüber. In der App ist das ein Knopf. Maße
   aus der App übernommen: 36 px hoch, 16 px Innenabstand seitlich,
   Kleintext — nicht über die Breite gezogen. */
/* Der Knopf haengt im `.vfm-phone`, nicht im `.vfm-koerper` — der
   Innenabstand der Karte sitzt aber auf dem Koerper. Ohne die 12px
   rechts und unten stoesst er an beide Kanten der Karte. Gemessen
   26.08.: Abstand zur rechten und unteren Kante 0px.

   27.08. AUF ANSAGE: `margin-left:auto` (rechtsbuendig) ersetzt durch `auto`
   auf BEIDEN Seiten — der Knopf steht mittig. Die 12px oben und unten
   bleiben stehen; seitlich sind es durch `auto` je rund 107px, die
   Mindestkante von 12px kann also nicht mehr unterschritten werden. */
.vfm-btn{margin:12px auto;display:inline-flex;width:auto;
  min-height:36px;padding:0 16px;font-size:var(--fs-klein);border-radius:3px}
.vfm-koerper{padding:12px 12px 12px;display:flex;flex-direction:column}

/* ═══ EIN RHYTHMUS, NICHT SIEBEN ═════════════════════════════════════════
   Gemessen waren die senkrechten Abstände in der Karte .6rem, .7rem, .4rem
   und 1.6rem durcheinander. Eine Karte hat einen Takt: 12 px, innen 8 px. */
.vfm-feld-fest{margin-bottom:12px;padding:8px 10px}
.vfm-feld{margin-bottom:12px}
.vfm-hinweis{margin-bottom:12px;padding:8px 10px}
.vfm-kacheln{margin-bottom:12px;gap:8px;
  grid-template-columns:minmax(0,1fr) 96px}
.vfm-unterschrift{margin-top:0}
.vfm-kachel.vfm-foto{min-height:88px}
/* Die zweite Kachel war ein grosser gestrichelter Kasten mit „Foto aufnehmen
   oder aus Galerie" — in einer FERTIGEN Meldung steht dort kein leerer
   Platzhalter, sondern der Knopf, mit dem man ein weiteres Foto anhängt. */
.vfm-kachel--plus{min-height:88px;flex-direction:column;gap:2px;
  border-style:solid;border-color:var(--linie);background:var(--papier);
  color:var(--akzent-text);font-weight:600}

/* ═══ DER FILM LÄUFT EINMAL, DANN STEHT DAS ERGEBNIS ═════════════════════
   Die vier Filme liefen endlos. Auf halber Strecke steht ein leeres
   Mengenfeld und eine leere Begründung — genau das Bild, das beanstandet
   wurde („eine Vorführung mit leeren Feldern führt nichts vor").
   Alle Keyframes enden bei 100 % im fertigen Zustand; mit einem Durchlauf
   und `forwards` bleibt dieser Zustand stehen. Beim Herausscrollen nimmt
   das Skript `laeuft` weg, beim Zurückkommen läuft der Film erneut — die
   Bewegung bleibt also, das Dauerflackern nicht.
   Keine der bestehenden Regeln ist dafür geändert worden. */
@media (prefers-reduced-motion:no-preference){
  .modulseite .vf.laeuft *{animation-iteration-count:1;animation-fill-mode:forwards}
}

/* ═══ FETT IM DUNKLEN BAND, ABER INNERHALB EINER VORFÜHRUNG ══════════════
   Die bestehende Regel `.band--dunkel :is(strong,b):not(.beleg *)…` färbt
   jedes <b> im dunklen Band grün. Sie zählt die Vorführungen einzeln auf
   (.beleg, .vfg-screen, .vfp-screen, .vfm-phone, .vfa) — die beiden neuen
   kennt sie nicht, und in ihnen steht das Grün auf WEISS: gemessen 3,09
   und 3,28 : 1 gegen einen Sollwert von 4,5. Zwölf Verstöße, alle daher.

   Die bestehende Regel bleibt unangetastet; diese hier steht danach, ist
   spezifischer und nimmt die Färbung innerhalb der beiden neuen
   Vorführungen wieder zurück. Dasselbe Ergebnis wie ein Eintrag in der
   :not()-Kette, ohne sie anzufassen. */
/* `!important` ist hier kein Faulheitszeichen, sondern die Folge einer
   Spezifitaets-Rechnung: die bestehende Regel traegt zehn `:not(...)`-Glieder
   und kommt damit auf (0,11,1). Ein Selektor, der das ohne `!important`
   ueberbietet, muesste acht sinnlose Klassen aneinanderhaengen — oder die
   bestehende Regel aendern, und genau das ist hier untersagt. */
.modulseite .band--dunkel :is(.vfr-karte,.vfz-karte) :is(b,strong){color:inherit!important}

/* ═══ EIN RASTERFELD SCHRUMPFT NICHT VON SELBST ══════════════════════════
   Gemessen bei 393 px: `.vfr-roll` stand 522 px breit in einem 327 px
   breiten Feld, und weil `.vfr-karte` `overflow:hidden` trägt, war die
   Tabelle nicht abgeschnitten UND nicht erreichbar — die Seite scrollte
   nicht quer, der Inhalt war schlicht weg. Dieselbe Falle wie im
   bestehenden Blatt bei `.modul__text,.modul__beleg{min-width:0}`. */
.modulseite .vfr-spalten>*{min-width:0;max-width:100%}
.modulseite .vfr-roll{max-width:100%}

/* Die Stopp-Liste folgt unmittelbar auf die Haken-Liste; ohne Abstand
   klebt der rote Punkt am letzten Haken. Ein Zeilenschritt, mehr nicht. */
.modulseite .haken + .haken--stopp{margin-top:.42rem}

/* Die Wettervorschau stand als halbbreite Karte neben leerem Grund. Auf der
   Bühne läuft sie über dieselbe Breite wie der Tagesplan darüber — sie ist
   dessen Nebenzeile, nicht ein zweites, kleineres Etwas. */
.modulseite .m-buehne > .vfw-karte{max-width:100%;margin-top:12px}

/* ═══ KNOPFMASSE AUS DER APP, NICHT AUS DEM GEFÜHL ═══════════════════════
   Gemessen: Knöpfe in den Vorführungen 28–36 px hoch, dieselben Knöpfe in
   der laufenden App 44–48 px („Freigeben" 113 × 44, „Melden" 123 × 48).
   44 px ist zugleich die Mindestgröße einer Trefferfläche — eine Vorführung,
   die kleinere Knöpfe zeigt, führt etwas vor, das es so nicht gibt. */
.modulseite :is(.vfr-knopf,.vfz-knopf,.vfg-knopf,.vfp-knopf){
  display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:0 16px;font-size:var(--fs-klein)}
.vfm-btn{min-height:44px;padding:0 20px}

/* ═══ ZUSTANDSPILLEN SIND IN DER APP RUND, DER REST IST ES NICHT ═════════
   Nachgemessen in der App: 303 von 319 Elementen tragen `border-radius:0`.
   Rund sind dort genau die Zustandspillen. Die bekommen sie hier auch —
   voll rund, nicht die 3 px des übrigen Innenlebens. */
.modulseite :is(.vfp-chip,.vfp-chip-neu,.b-marke,.vfr-art){border-radius:999px}
.modulseite .vfr-art{padding:1px 7px;background:var(--akzent-hauch)}
.modulseite .vfr-meldung--mehr .vfr-art{background:#FFF0E0}

/* ═══ DIE KOPFLEISTE EINER VORFÜHRUNG BEI 393 PX ═════════════════════════
   Gemessen im Bild, nicht im Quelltext: mit zwei 44-px-Knöpfen daneben
   blieben für „Pflegeplan 2026 · Park Nordring" 62 px Breite — der Titel
   brach auf neun Zeilen. Auf schmalem Schirm bekommt der Titel eine eigene
   Zeile, die Knöpfe stehen darunter. */
@media (max-width:560px){
  .modulseite :is(.vfr-seitenkopf,.vfz-seitenkopf,.vfg-seitenkopf,
    .vfp-seitenkopf,.vfm-seitenkopf){flex-wrap:wrap;gap:8px}
  .modulseite :is(.vfr-tt,.vfz-tt,.vfg-tt,.vfp-tt,.vfm-tt){flex:1 0 100%}
}

/* ═══ `leistung.html` TRÄGT DIESELBE KÖRPERKLASSE ════════════════════════
   Der Block oben heisst nach der Seite, für die er entstand — was darin
   steht, ist aber nicht modulseiten-eigen, sondern gehört den Vorführungs-
   Bausteinen: Bühne, Kopfzeile, `.vfr-`, `.vfz-`, Knopfmaß, Rhythmus,
   Rundung, Film-Lauf. `leistung.html` zeigt dieselben Bausteine und trägt
   deshalb `class="modulseite"` am Körper. Keine Regel doppelt, keine
   geändert. Wer den Block umbenennt, benennt beide Seiten mit um. */

/* ═══ NACHGEZOGEN AN DIE APP (Ablesung vom 26.08.) ═══════════════════════
   Die Zahlen, Spaltenwoerter und Zustandsnamen der beiden neuen
   Vorfuehrungen stammen jetzt aus dem laufenden Vorfuehrbestand. Was hier
   noch fehlte, sind drei Dinge aus der App-Oberflaeche:
     · der Status neben der Meldungsart (Offen / Freigegeben / Beim AG)
     · die Mehrmengen-Zeile unter der Position
     · die Fortschrittsfarben der App: abgerechnet #005A20, unverrechnet
       #D46700, Gleis #B7C6BD. Sie sind Flaechen, keine Schrift. */
.modulseite .vfr-status{grid-row:1;justify-self:start;font-size:var(--fs-label);
  font-weight:600;color:var(--grau);border:1px solid var(--linie);
  border-radius:999px;padding:1px 7px;white-space:nowrap}
.modulseite .vfr-meldung{grid-template-columns:auto auto minmax(0,1fr) auto}
.modulseite .vfr-mehr{display:block;font-size:var(--fs-label);font-weight:700;
  color:#8A3B0B;margin-top:1px}
.modulseite .vfr-balken{background:#B7C6BD}
.modulseite .vfr-balken i{background:#005A20}
.modulseite .vfr-z--mehr .vfr-balken i{background:#D46700}
.modulseite .vfr-leg{margin-top:8px;font-size:var(--fs-label);line-height:1.45;
  color:var(--grau)}
.modulseite .vfr-leg b{font-weight:700;color:var(--tinte)}

/* Zwei weitere Terminarten im Zeitbalken: ueberfaellig und „steht in der
   Schonzeit, hat aber einen eingetragenen Ausnahmegrund". Der zweite Fall
   ist der Grund, warum der Balken dort ueberhaupt unterbrochen ist — er
   gehoert ins Bild, nicht in eine Fussnote allein. */
.modulseite .vfz-t--ausnahme{background:#B45309;width:3px;margin-left:-1.5px}
.modulseite .vfz-t--ausnahme::after{content:"";position:absolute;left:50%;top:-4px;
  width:9px;height:9px;margin-left:-4.5px;border:2px solid #B45309;border-radius:999px;
  background:var(--w)}
.modulseite .vfz-lt--offen{background:#C0392B}
.modulseite .vfz-lt--ausnahme{background:#B45309;width:3px}

/* ═══════════════════════════════════════════════════════════════════════════
   NACHTRAG 27.08. — DREI BEANSTANDUNGEN AN DER MODULSEITE
   Nur Ergaenzungen. Die drei Regeln, die dafuer im Bestand geaendert werden
   mussten, stehen an ihrem Platz und tragen dort die Begruendung:
   `.vfz-spur` (Rasterlinien raus), `.vfz-schonband` (Schraffur zur Flaeche),
   `.vfz-t` (Terminstrich wird das lauteste Element).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── „TROTZDEM EINPLANEN" — DIE AUSSAGE DES MODULS ────────────────────────
   Die Warnung des Tagesplans ist kein Riegel. Der Betrieb entscheidet, ob er
   faehrt; die App legt ihm nur die Zahl daneben. Deshalb steht der Knopf IN
   der Warnung und nicht darunter — er gehoert zu ihr wie die Antwort zur
   Frage. Farben aus dem Warnband selbst (#78350F auf Weiss = 9,1 : 1). */
.modulseite .vfp-warn-neu{display:flex;flex-wrap:wrap;align-items:center;
  justify-content:space-between;gap:10px}
.modulseite .vfp-warn-txt{flex:1 1 16rem;min-width:0}
.modulseite .vfp-trotzdem{flex:none;display:inline-flex;align-items:center;
  min-height:36px;padding:0 14px;border:1px solid #B45309;border-radius:3px;
  background:var(--w);color:#78350F;font-weight:700;font-size:var(--fs-label);
  white-space:nowrap}

/* ── DIE MELDUNGS-VORFUEHRUNG STAND IN IHRER SPALTE LINKS AUSSEN ──────────
   Gemessen bei 1280 px: die Karte ist 380 px breit, ihre Spalte 530 px —
   150 px Loch zwischen Karte und Textblock, und die Karte klebte an der
   linken Abschnittskante. Ueberlappt hat sie nichts (Kante zur Abschnitts-
   grenze 134 px, Knopf 13 px von beiden Kartenkanten), aber sie sass
   schief im Bild. Zentriert steht sie in der Mitte ihrer eigenen Spalte.

   27.08. — DIE REGEL HING AN `.modulseite` UND HAT DIE STARTSEITE NIE
   ERREICHT. `index.html` traegt am `<body>` keine Klasse (index.html:73),
   `module.html` und `leistung.html` schon. Auf der Startseite stand die
   Karte deshalb weiter links aussen mit 150,4 px Loch rechts — gemessen
   27.08. bei 1280 px: Spalte 665,6–1196, Karte 665,6–1045,6.
   Der Selektor haengt jetzt am Bauteil und nicht mehr an der Seite.
   `.modul--kehrt` faellt mit weg: es beschrieb nur, WO die Karte auf der
   Modulseite stand, nicht WAS zu tun war. */
.vfm-geraet{display:flex;justify-content:center}

/* ── … UND SIE KLEBTE 80 PX ZU TIEF, MIT UEBERSTAND NACH UNTEN ────────────
   Dieselbe Falle ein zweites Mal. `.modul__beleg>*{position:sticky;top:80px}`
   (style.css:618) laesst die Vorfuehrung mitlaufen, waehrend der Text
   weiterscrollt. Fuer die Modulseiten wurde das schon abgeschaltet
   (`.modulseite .modul__beleg>*{position:relative;top:auto}`, style.css:3485)
   — wieder mit Seitenklasse, wieder ohne Wirkung auf der Startseite.

   GEMESSEN am 27.08. bei 1280 px, VOR der Reparatur:
     Artikel        8271,4 – 8993,2
     Belegspalte    8337,9 – 8925,6
     Karte          8417,9 – 9005,6   → 80 px zu tief, 12,4 px UEBERSTAND
   `position:sticky` mit `top:80px` verschiebt nur die Darstellung, nicht den
   Platz — deshalb ragte die Karte unten aus ihrem Abschnitt heraus und
   schloss im Bild „knapp ab". Der Text daneben (378 px) ist kuerzer als die
   Karte (587,7 px); Mitlaufen hat hier also keinen Nutzen, nur den Fehler.

   `relative` statt `static`, aus demselben Grund wie bei style.css:3485: die
   Karte muss Bezugsrahmen fuer das absolut gesetzte `.vfm-ph-tag` bleiben. */
.modul__beleg>.vfm-geraet{position:relative;top:auto}

/* ═══════════════════════════════════════════════════════════════════════════
   STARTSEITE — ADDITIVER BLOCK, 27.08.2026
   Neun Beanstandungen der zweiten Runde plus der Lichthof. Hier wird NICHTS
   umgeschrieben, was oben steht; alles gewinnt ueber Quellreihenfolge oder
   ueber eine engere Auswahl. Die eine Ausnahme ist unten benannt.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ═══ EIN FEHLENDER SPROSSEN IN DER LEITER ══════════════════════════════════
   `--fs-h3` wird an DREI Stellen benutzt — `.sonder-h` (Zeile 3040),
   `.buchung__titel` (1603) und `.betrieb__zahlen b` (3149) — und war NIRGENDS
   definiert. Eine `font-size: var(--fs-h3)` ohne Wert ist ungueltig, die
   Regel faellt aus, und das Element erbt. GEMESSEN: die Ueberschrift beider
   Sonderanfertigungen stand mit 18 px da, also kleiner als der Vorspann
   daneben (bis 20,5 px) — deshalb las sich der Janke-Fall „null aufgeteilt",
   und deshalb waren die Betriebszahlen so unscheinbar.

   `pruefe-schriftleiter.py` findet das NICHT: es prueft, ob eine `font-size`
   eine Variable BENUTZT, nicht, ob die Variable existiert. Der Haken war
   gruen, der Wert war kaputt.

   Der Wert schliesst die Luecke zwischen --fs-h2 (bis 2,55rem) und
   --fs-lead (bis 1,28rem). Bei 1280 px: h2 37,1 px · h3 24,3 px · Lead 17 px.
   Eigener `:root`-Block statt einer Aenderung am ersten — additiv. */
:root{ --fs-h3:clamp(1.28rem,1.9vw,1.6rem); }

/* ═══ .ki-drei STAND BISHER NUR AUF DUNKLEM GRUND ═══════════════════════════
   Die drei Schritte waren fuer das dunkle Protokollband gebaut und tragen
   deshalb --d-text, --d-grau und --akzent. Fall 1 (Boeschung) steht auf
   Papier; dort misst --akzent 3,02 : 1 und faellt als Text durch, --d-grau
   (#98AB9F) sogar auf 1,9 : 1. Drei engere Auswahlen statt drei Aenderungen. */
.band:not(.band--dunkel) .ki-drei b{color:var(--tinte)}
.band:not(.band--dunkel) .ki-drei p{color:var(--grau)}
.band:not(.band--dunkel) .ki-drei__nr{color:var(--akzent-text)}

/* ═══ DAS ZEICHEN VON LAND.BAU.WERK — GROESSER, OHNE NEUE DATEI ════════════
   Beanstandet: „Logo zu klein". GEMESSEN wurde nicht der Kasten, sondern die
   BILDMARKE: `landbauwerk.png` ist 1000 x 250 px gross, die Alphahuelle des
   Zeichens liegt aber nur bei x 67…931 und y 43…184 — 86,4 % der Dateibreite
   und 56,4 % der Dateihoehe. Bei `height:52px` waren davon 180 x 29 px zu
   sehen. Der Kasten war nie zu klein, das Zeichen darin war es.

   Derselbe Weg wie in der Broschuere (`.lbw-zeichen img`, Zeile 901 ff.):
   die Datei bleibt, wie sie ist, und der leere Rand wird mit negativen
   Raendern herausgeholt. Die Marke wird NICHT nachgebaut — es gibt sonst
   zwei Wahrheiten.
     Datei 88 px hoch  →  352 px breit
     leer oben  43/250 * 88  = 15,1 px      leer unten 66/250 * 88 = 23,2 px
     leer links 67/1000 * 352 = 23,6 px     leer rechts 69/1000 * 352 = 24,3 px
   Sichtbar danach: 304 x 50 px statt 180 x 29 px. */
.betrieb__marke{height:88px;margin:-5px -24px calc(var(--a-mittel) - 23px) -24px}

/* ═══ DIE SCHNITT-RECHNUNG BRAUCHT PLATZ, DEN SIE UNTER ~462 PX NICHT HAT ═══
   Beanstandet: „lbw logo auch zussammengedrückt". GEMESSEN bei 375 px: der
   Kasten ist bei `height:88px` (Bildbreite waere 352 px) auf `width:auto`
   angewiesen — und `img,svg{max-width:100%}` (Zeile 174) zwingt die Breite
   auf den verfuegbaren Raum von nur 269 px. Die Hoehe bleibt hart bei 88 px:
   der Browser FUELLT den 269 x 88-Kasten (object-fit ist bei <img> ohne
   eigene Angabe `fill`), also wird das BILD selbst gestaucht, nicht nur
   sein Kasten. Genau das ist die Meldung.

   Verfuegbarer Raum = Ansichtsbreite − 2 × --rand − 2 × 32 px
   (.betrieb__text-Polsterung); mit --rand = clamp(20px,5vw,72px) reicht das
   erst ab ≈ 462 px fuer die vollen 352 px. Unterhalb davon gilt deshalb
   wieder die einfache, bereits gemessene Fassung von weiter oben
   (Zeile 3247): `height:52px;width:auto`, ohne Schnitt-Raender — die passt
   bei 208 px Breite in jeden schmaleren Rahmen, unverzerrt. */
@media (max-width:539px){
  .betrieb__marke{height:52px;margin:10px 0 var(--a-mittel)}
}

/* ═══════════════════════════════════════════════════════════════════════════
   DIE ZAUNEIDECHSE — FOTOGRAFIERT, GESCANNT, EINGETRAGEN
   Ansage: „mach da n bild von ner echten eidechse hin und so animierte linien
   die die scannen". Vorher stand hier eine gezeichnete Erdkroete.

   DREI REGELN DIESER SEITE, UND ALLE DREI GELTEN HIER:
   1. Bewegt werden nur `transform` und `opacity` — kein Layoutwert.
   2. Jeder Schritt liegt zwischen 150 und 300 ms.
   3. DER RUHEZUSTAND IST DER FERTIGE ZUSTAND. Verborgen wird ausschliesslich
      unter `.js-film` — die Klasse setzt `main.js` selbst, und nur wenn
      Bewegung erlaubt und die Seite nicht eingefroren ist. Ohne Skript, bei
      `prefers-reduced-motion` und im Standbild-Modus steht das Foto scharf
      da und der Fund im Blatt.

   Der Ablauf, gemessen in Millisekunden:
     0 …  240   das Foto kommt ins Bild          (opacity + 6 px translate)
     300 … 1200 der Scan laeuft, 3 x 300 ms      (translateY ueber 104 Einheiten)
     1250 … 1490 die Erkennungszeile erscheint   (opacity)
     1550 … 1810 die Fundzeile tritt ins Blatt   (opacity + 8 px translate)
   ═══════════════════════════════════════════════════════════════════════════ */

/* Das Feld ist 4:3 und traegt das Foto formatfuellend; Winkel und Scan liegen
   als SVG darueber. Der Grund bleibt dunkel (#10201A) — er ist nur noch
   sichtbar, solange das Bild nicht geladen ist. */
.blatt__foto.ei{width:132px;height:99px;padding:0;background:#10201A;
  border:1px solid rgba(59,160,100,.34);overflow:hidden;position:relative;
  display:block}
.ei-tier{width:100%;height:100%;object-fit:cover;display:block}
.ei-svg{position:absolute;inset:0;width:100%;height:100%;display:block}
.ei-winkel path{fill:none;stroke:var(--akzent);stroke-width:1.6;opacity:.75}

/* Der Scan ist reine Bewegung — sein Endzustand ist „weg". Deshalb steht er
   IMMER auf `opacity:0` und wird nur waehrend des Laufs sichtbar. Ohne
   Skript liegt also keine eingefrorene Linie ueber dem Tier. */
.ei-scan{opacity:0;transform-box:view-box}
.ei-band{fill:rgba(143,233,168,.22)}
.ei-linie{fill:none;stroke:rgba(143,233,168,.95);stroke-width:1}
.ei-linie--2{stroke:rgba(143,233,168,.5)}
.ei-linie--3{stroke:rgba(143,233,168,.28)}

@media (prefers-reduced-motion:no-preference){
  /* Verborgen wird NUR unter .js-film und NUR solange nicht gelaufen wird. */
  .js-film [data-vf="eidechse"]:not(.laeuft) .ei-tier{opacity:0}
  .js-film [data-vf="eidechse"]:not(.laeuft) .ei-marke{opacity:0}
  .js-film [data-vf="eidechse"]:not(.laeuft) .ei-zeile{opacity:0}

  .js-film [data-vf="eidechse"].laeuft .ei-tier{
    animation:ei-auf .24s cubic-bezier(.22,.61,.36,1) both}
  .js-film [data-vf="eidechse"].laeuft .ei-scan{
    animation:ei-scan .3s linear .3s 3 both}
  .js-film [data-vf="eidechse"].laeuft .ei-marke{
    animation:ei-ein .24s ease-out 1.25s both}
  .js-film [data-vf="eidechse"].laeuft .ei-zeile{
    animation:ei-fund .26s cubic-bezier(.22,.61,.36,1) 1.55s both}
}
@keyframes ei-auf{from{opacity:0;transform:translateY(6px)}
                  to{opacity:1;transform:translateY(0)}}
@keyframes ei-ein{from{opacity:0}to{opacity:1}}
@keyframes ei-fund{from{opacity:0;transform:translateY(8px)}
                   to{opacity:1;transform:translateY(0)}}
/* 104 Einheiten = 90 Kastenhoehe + 14 Bandhoehe: die Gruppe startet ueber dem
   Feld und verlaesst es unten vollstaendig. */
@keyframes ei-scan{
  0%{opacity:0;transform:translateY(0)}
  12%{opacity:1}
  88%{opacity:1}
  100%{opacity:0;transform:translateY(104px)}
}

/* ═══════════════════════════════════════════════════════════════════════════
   DER LICHTHOF
   Ansage: „auf homepage auch mal glow hinpacken, wie bei dem einen abschnitt
   in broschuere, hinter demos, hinter sachen die vorgehoben gehoeren".

   Uebernommen aus `07-marketing/print/broschuere/broschuere.html`, Zeilen
   961–968 (`.wt--gut`): zwei Verlaeufe, KEIN `box-shadow` — Schatten sind im
   Haus verboten, ein Verlauf hinter einem Element ist etwas anderes.

   ── DER MASSSTAB ──────────────────────────────────────────────────────
   Derselbe wie bei der Handy-Attrappe (Zeile 2739): 1 mm = 5,4 px.
       inset -9mm -7,5mm -7,5mm  →  -48,6px -40,5px -40,5px
   Die Verlaeufe selbst rechnen in Prozent und wandern unveraendert mit.

   ── NUR AUF DUNKEL ────────────────────────────────────────────────────
   Auf Weiss und auf Papier ist ein Lichthof entweder unsichtbar oder
   schmutzig. Alle Stellen unten liegen auf `band--dunkel`.

   ── DIE FALLE, DIE IN DER BROSCHUERE ZUGESCHLAGEN HAT ─────────────────
   Der Lichthof HELLT DEN GRUND AUF. Dort stieg der hellste Kartengrund auf
   #266A4C und eine Schrift fiel auf 3,18 : 1. Deshalb sitzt der Lichthof
   hier ausschliesslich hinter Bauteilen, die ihren eigenen deckenden Grund
   mitbringen (Puzzleteile, Blatt, Beleg, Geraet) — die Schrift liegt auf der
   Kachel, nie auf dem Leuchten. Nachgemessen wird trotzdem, im Browser. */
.lichthof{position:relative;z-index:0}
/* ── DER UEBERSTAND IST AN `--rand` GEBUNDEN, NICHT AN EINE FESTE ZAHL ──
   GEMESSEN am 29.08.2026 bei 768 px, im Browser, an index.html:
       Dokument 770 px   Fenster 768 px   -> 2 px waagerechter Rollbalken
   Beweis, dass der Hof es ist und nichts sonst: mit
   `.lichthof::before{display:none}` faellt das Dokument auf genau 768,
   ohne die Regel steht es auf 770. Keine andere Stelle war beteiligt —
   alle 22 Abschnitte einzeln ausgeblendet, keiner allein hat es geloest.

   DIE RECHNUNG. `.wrap` polstert seitlich mit `--rand: clamp(20px,5vw,72px)`;
   bei 768 px sind das 5vw = 38,4 px. Der Hof stand auf 40,5 px Ueberstand.
   40,5 − 38,4 = 2,1 px — er tritt also aus dem Polster heraus und schiebt
   das Dokument um genau diesen Betrag. Bei 1280 px faellt es nicht auf, weil
   `--rand` dort auf 64 px steht und der Hof bequem hineinpasst.

   ZWEI ANSAGEN STEHEN HIER GEGENEINANDER, und beide gelten:
     „glow abgeschnitten"                      (27.08., zum Hof)
     „nirgends, wirklich nirgends horizontal scrolls" (27.08. 19:37)
   Ein `overflow:hidden` wuerde das Zweite erfuellen, indem es das Erste
   bricht — es schneidet den Hof genau dort ab, wo er weich auslaufen soll.
   Stattdessen ist der Ueberstand jetzt `min(<Wunschmass>, var(--rand))`:
   der Hof reicht hoechstens bis an die Fensterkante und keinen Pixel
   darueber hinaus. Er wird dabei nicht beschnitten, sondern beginnt enger —
   ein Verlauf ohne harte Kante bleibt ein Verlauf ohne harte Kante.
   Am Schreibtisch aendert sich NICHTS: bei 1280 px ist `--rand` = 64 px,
   `min(40,5px, 64px)` = 40,5 px, also der bisherige Wert.
   Das ist dieselbe Ueberlegung, die weiter unten schon fuer das Telefon
   steht (`max-width:560px`) — dort war sie nur von Hand auf eine Breite
   gesetzt, statt an das Polster gebunden, und die Luecke dazwischen
   (561 bis rund 1440 px) blieb offen. */
.lichthof::before{
  content:"";position:absolute;
  inset:-48.6px calc(-1 * min(40.5px, var(--rand))) -40.5px;
  z-index:-1;
  pointer-events:none;
  background:radial-gradient(64% 54% at 50% 24%,
    rgba(143,233,168,.62) 0%, rgba(143,233,168,.26) 42%,
    rgba(143,233,168,0) 82%);
}
/* Der innere, sehr leise Verlauf — er hebt die Flaeche selbst leicht an.
   Nur dort, wo das Bauteil eine eigene Flaeche hat. */
.lichthof--flaeche{
  background:radial-gradient(118% 78% at 50% 0%,
    rgba(143,233,168,.06) 0%, rgba(143,233,168,.03) 42%,
    rgba(143,233,168,0) 76%);
}
/* Am Telefon wird der Hof enger — 40 px Ueberstand neben einer 16-px-Kante
   liefe sonst aus dem Band heraus. */
@media (max-width:560px){
  .lichthof::before{inset:-24px -16px -20px}
}

/* ── DER PFLEGEKALENDER AUF DEM TELEFON ───────────────────────────────────
   Hier stand `@media (max-width:560px){ .modulseite .vfz-karte
   {--vfz-lab:132px} }` — die Maßnahmen-Spalte wurde schmaler, damit vom
   Jahr mehr in den Rollkasten passte. Am 28.08.2026 ist der Rollkasten
   weg und mit ihm die Spalte: unter 640 px stellt sich der Maßnahmenname
   ÜBER die Monatsspur (`--vfz-lab:0px`, siehe den Block „SCHMALER SCHIRM").

   Die Regel MUSSTE mit weg, nicht bloß danebenstehen: sie steht später im
   Blatt und hat dieselbe Trefferzahl, hat also `--vfz-lab:0px` überschrieben.
   GEMESSEN im Bild bei 393 px, mit ihr drin: das Schonzeit-Band lag über
   Juli bis Oktober statt über März bis September — `.vfz-schonband` leitet
   seine Lage aus derselben Variablen ab. Ein Rechtshinweis nach § 39 Abs. 5
   BNatSchG, der auf die falschen Monate zeigt. */

/* ═══ EIN `display:block`, DAS ZWEI `<i>` TRAF ══════════════════════════════
   GEFUNDEN im Bild, nicht im Quelltext: die Erkennungszeile brach in vier
   Zeilen um — „Zauneidechse (" · „Lacerta agilis" · „) — im Bild erkannt, 94 %" ·
   „bestätigt von M. Krause". Ursache ist `.blatt__erkannt i` (Zeile 2951):
   die Regel meint das ZWEITE `<i>` (die Bestätigungszeile), trifft aber auch
   das erste — den wissenschaftlichen Namen. Der stand dadurch als eigene
   Zeile UND aufrecht statt kursiv, obwohl der Abschnitt zwei Zeilen weiter
   oben erklaert, dass die Behoerde genau ihn verlangt.

   Der Fehler ist aelter als diese Runde; aufgefallen ist er, weil das
   Fundbild von 84 auf 112 px gewachsen ist und die Spalte enger wurde.
   Geaendert wird die alte Regel nicht — die Auswahl wird nur genauer. */
.blatt__erkannt i{display:inline;font-style:italic;font-size:inherit;
  color:inherit;margin-top:0}
.blatt__erkannt i:last-child{display:block;font-style:normal;
  font-size:var(--fs-label);color:var(--grau);margin-top:2px}

/* Der Akzentstrich stand als einziges Element linksbündig, während Etikett,
   Überschrift, Vorspann und Fliesstext dieses Abschnitts mittig stehen
   (Regel bei `#module .etikett` weiter oben). Auf dem neuen dunklen Grund
   fiel der einzelne Strich links oben auf wie ein Versehen. */
#module > .wrap > .regel{margin-inline:auto}

/* ═══ DIE WEISSE KACHEL IM NEUEN DUNKLEN BAND ══════════════════════════════
   GEMESSEN nach dem Zusammenlegen von Ablauf und Preis: 5 Verstoesse, alle
   mit 3,28 : 1 — „Beratungsgespräch", „Kostenanalyse", „Bauen", „Fertiges
   Werkzeug" und das Wort „Festpreis".

   Ursache ist die Regel `.band--dunkel :is(strong,b):not(…)` (Zeile 1798).
   Sie faerbt jedes fette Wort im dunklen Band gruen und nimmt dafuer genau
   die hellen Inseln aus: `.beleg`, `.karte`, `.blatt`, `.rechnung` und so
   fort. `.etappe` fehlt in dieser Liste — und zwar zu Recht, denn bis heute
   lag die Ablaufstrecke in einem WEISSEN Band. Seit dem Zusammenlegen liegt
   sie im dunklen, ist aber selbst weiss (`background:var(--w)`): #3BA064 auf
   Weiss traegt 3,28 : 1, gefordert sind 4,5. Genau die Falle, die im
   Blattkopf unter „Beleg ohne eigenes color" beschrieben steht.

   `!important` statt einer elfte n `:not()`-Klammer an der alten Regel: die
   traegt Spezifitaet (0,11,1) und ist von aussen nicht sauber zu schlagen.
   Dieselbe Loesung und dieselbe Begruendung wie bei den Modulseiten-Karten
   weiter oben (`.vfr-karte`/`.vfz-karte`). Die alte Regel bleibt unberuehrt.
   Nachgemessen: --tinte auf Weiss 17,52 : 1. */
.band--dunkel .etappe :is(b,strong){color:var(--tinte)!important}

/* ═══════════════════════════════════════════════════════════════════════════
   NACHTRAG ZUM LICHTHOF — DIE KANTE, DIE IM BILD ZU SEHEN WAR
   Beanstandet: „glow abgeschnitten".

   GESUCHT wurde zuerst ein `overflow:hidden` — es gibt keins. Die ganze Kette
   ueber der Grafik (figure · .wrap · section · main · body) steht auf
   `overflow:visible`, kein `clip-path`, kein `contain`, keine `transform`.

   DIE URSACHE IST DER VERLAUF SELBST. Ein `radial-gradient` wird auf seinen
   eigenen Malkasten beschnitten. Der aus der Broschuere uebernommene Wert
   lautet `64% 54% at 50% 24%` mit der letzten Farbmarke bei 82 %. Nachgerechnet
   in Prozent des Kastens:
       oben   24 − 0,82·54 = −20,28 %   → 20 % ausserhalb, HARTE KANTE
       links  50 − 0,82·64 =  −2,48 %   → ebenfalls angeschnitten
       rechts 50 + 0,82·64 = 102,48 %
   Bei einem Kasten von 741 x 406 px lag die Kante damit genau auf der
   Oberkante des `::before`, also 48,6 px ueber der Grafik — mit rund 24 %
   Deckkraft, und deshalb deutlich sichtbar.

   Das laesst sich NICHT durch einen groesseren Kasten heilen: beide Radien
   sind Prozent DESSELBEN Kastens, das Verhaeltnis bleibt. Geheilt wird es nur
   ueber die Geometrie. Bedingung, damit nichts anstoesst:
       cy ≥ ende·ry   ·   cy + ende·ry ≤ 100   ·   ende·rx ≤ 50
   Beide Werte unten erfuellen sie mit Luft; nachgerechnet steht es daneben.

   Die alte Regel bleibt stehen, diese ueberschreibt nur den Verlauf. */
.lichthof::before{
  /* oben 30 − 0,82·28 = 7,04 · unten 52,96 · seitlich 0,80 … 99,20 */
  background:radial-gradient(60% 28% at 50% 30%,
    rgba(143,233,168,.62) 0%, rgba(143,233,168,.26) 42%,
    rgba(143,233,168,0) 82%);
}

/* ═══ DER STARKE LICHTHOF — NUR HINTER DER PUZZLEGRAFIK ═════════════════════
   Ansage: hier „darf kräftiger sein", aber „wenn alles leuchtet, hebt nichts
   mehr hervor" — das Leuchten soll ZUR hervorgehobenen Kachel fuehren. Also
   zwei Verlaeufe: einer traegt die Flaeche, der zweite sitzt unten rechts,
   wo „Ihre Sonderentwicklung" liegt.
     A  oben 34 − 0,80·30 = 10,00 · unten 58,00 · seitlich 3,60 … 96,40
     B  oben 68 − 0,78·30 = 44,60 · unten 91,40 · seitlich 45,48 … 98,52 */
.lichthof--stark::before{
  /* Derselbe Riegel wie oben: seitlich hoechstens so weit wie das Polster
     der Bahn. Bei 1280 px ist `--rand` = 64 px, `min(56px, 64px)` = 56 px —
     der starke Hof steht am Schreibtisch also unveraendert. */
  inset:-64px calc(-1 * min(56px, var(--rand))) -56px;
  background:
    radial-gradient(34% 30% at 72% 68%,
      rgba(143,233,168,.42) 0%, rgba(143,233,168,0) 78%),
    radial-gradient(58% 30% at 50% 34%,
      rgba(143,233,168,.30) 0%, rgba(143,233,168,.12) 45%,
      rgba(143,233,168,0) 80%);
}
@media (max-width:560px){ .lichthof--stark::before{inset:-30px -18px -22px} }

/* ═══════════════════════════════════════════════════════════════════════════
   DAS PUZZLE AUF DUNKLEM GRUND
   Beanstandet: „mach die puzzleteile dunkler, schrift hellgrün mit glow".
   Weisse und hellgraue Teile auf Nacht sahen ausgeschnitten und aufgeklebt
   aus. Dunkle Teile mit feiner Mintkante: die FORM traegt, nicht die Flaeche.
   Die eine gefuellte Kachel bleibt die Ausnahme — das ist die Aussage des
   Bildes: fuenf stehen fertig da, eine wird gebaut.

   ═══ HIER IST DAS MESSGERAET BLIND, UND ZWAR NACHWEISLICH ═══════════════
   `pruefe-kontrast.js` liest den Grund ueber `backgroundColor` und steigt
   dabei die Elternkette hoch. Ein SVG-`fill` ist KEIN `background` — die
   Schrift im Puzzle wird deshalb gegen den Grund des BANDES gerechnet, nicht
   gegen das Teil, auf dem sie liegt. Das Skript meldet fuer diese Grafik
   „0 Verstoesse", egal was dort steht.

   Es war auch schon einer da: „Ihre Sonderentwicklung" stand weiss auf
   `--akzent` (#3BA064) — 3,28 : 1 bei 14,3 px, gefordert 4,5. Gemeldet hat
   das nie jemand, weil das Messgeraet es nicht sehen kann. Die Kachel traegt
   deshalb jetzt `--akzent-knopf` (#005A20), auf dem Weiss 8,46 : 1 misst —
   derselbe Wert, aus dem die Knoepfe der Seite gebaut sind.

   Alle Werte unten sind aus den gerenderten Pixeln nachgemessen, nicht aus
   dem Blatt gelesen; die Zahlen stehen in der Uebergabe. */
.band--dunkel .pz-teil path{fill:#0A1913;stroke:rgba(143,233,168,.34);
  stroke-width:1.1}
.band--dunkel .pz-2 path,.band--dunkel .pz-4 path{fill:#0E2219}
.band--dunkel .pz-teil--eigen path{fill:var(--akzent-knopf);
  stroke:#8FE9A8;stroke-width:1.7}

/* Hellgruen mit Leuchten. `text-shadow` ist KEIN `box-shadow` — die Hausregel
   verbietet Schlagschatten, nicht einen Schein um die Schrift. Ohne Versatz,
   damit es leuchtet und nicht faellt. */
.band--dunkel .pz-eins{fill:#8FE9A8;
  text-shadow:0 0 9px rgba(143,233,168,.42)}
.band--dunkel .pz-zwei{fill:#7FB98D}
.band--dunkel .pz-teil--eigen .pz-eins,
.band--dunkel .pz-teil--eigen .pz-zwei{fill:#fff;text-shadow:none}

/* ═══ DIESELBE FALLE WIE IM PUZZLE, ZWEITER FUNDORT ═════════════════════════
   Die hervorgehobene Kachel des Hero-Schaubilds („Ihre Individualmodule")
   war mit `--akzent` (#3BA064) gefuellt und trug weisse Schrift: 3,28 : 1 bei
   17,6 px — gefordert sind 4,5. Wortgleich derselbe Fehler wie in der
   Puzzlegrafik, nur an einer zweiten Stelle.

   Gefunden hat ihn die inzwischen SVG-taugliche Fassung von
   `pruefe-kontrast.js` — die alte konnte einen SVG-`fill` nicht als Grund
   lesen und meldete hier jahrelang „0". Wie beim Puzzle auf `--akzent-knopf`
   (#005A20) gesetzt; Weiss darauf 8,46 : 1, derselbe Wert wie bei jedem Knopf
   der Seite. Die Flaechenfarbe der Leitungen bleibt unangetastet. */
.nb-block--zuschnitt rect{fill:var(--akzent-knopf);stroke:var(--akzent-knopf)}

/* ═══ EINE KORREKTUR AN DER EIGENEN MESSUNG ══════════════════════════════
   Erst gemessen: „N" der Nordnadel auf #679665, Weiss darauf 3,43 : 1 —
   scheinbar durchgefallen. DIE MESSUNG WAR FALSCH. Genommen wurde die
   haeufigste Farbe eines 24x20-Kastens um das Zeichen; bei einer duennen
   Glyphe auf grossem Grund ist das die WIESE ringsum, nicht der Grund, gegen
   den das Auge die Schrift liest. Richtig gemessen — die direkten Nachbarn
   der Glyphenpixel — waren es #1E221C und 16,14 : 1. Das „N" ist nie
   durchgefallen.

   Der Saum bleibt trotzdem, aber aus einem anderen Grund: das Luftbild
   darunter wechselt die Helligkeit (Asphalt, Acker, Wiese), und das „N" ist
   das einzige Etikett ohne Hinterlegung. Die Punktetiketten daneben tragen
   denselben Saum seit jeher. Gemessen danach: 16,83 : 1. */
.lb-nord{paint-order:stroke;stroke:rgba(11,11,11,.85);stroke-width:3;
  stroke-linejoin:round;opacity:1}

/* ═══════════════════════════════════════════════════════════════════════════
   DAS GRÜN AUF DUNKLEM GRUND WIRD HELLER
   Beanstandet: „für akzente etc grün heller machen für glow effekt".

   Der Lichthof ist aus rgba(143,233,168,…) gebaut. Ein Akzent, der daneben
   in #3BA064 steht, leuchtet nicht mit — er sitzt daneben. Deshalb trägt
   der Akzent auf dunklem Grund jetzt DIESELBE Farbe wie das Leuchten:
   #8FE9A8, das Mint der Marke, dieselbe Farbe, die im Puzzle und in der
   Vergleichsspalte schon steht.

   NUR AUF DUNKEL. Auf Weiss ist Grün die enge Seite: --akzent misst dort
   3,02 : 1 auf --papier und trägt schon heute nur Flächen, keine Schrift.
   Ein helleres Grün fiele dort sofort durch. Deshalb wird nicht die
   Variable in `:root` geändert, sondern nur ihr Wert INNERHALB eines
   dunklen Bandes überschrieben — eine Zeile, und jede der rund fünfzig
   Stellen, die `var(--akzent)` benutzen, wandert automatisch mit.

   Die Logofarben bleiben unangetastet: das Zeichen ist ein Bild, keine
   Variable.

   GEMESSEN am gerenderten Pixel, nicht am Blatt (1280 px, index.html):
     vorher  #3BA064 auf rgb(2,12,9)   6,04 : 1   (alle Textrollen gleich)
     nachher #8FE9A8 auf rgb(2,12,9)  13,74 : 1
   Die Werte je Rolle stehen in der Rückmeldung. */
.band--dunkel{--akzent:#8FE9A8}

/* Die eine Ausnahme, gemessen und nicht geraten: im dunklen Band stehen
   Attrappen mit eigenem WEISSEN Schirm. Dort ist der Grund hell, und dort
   gilt wieder das satte Grün — sonst stünde Mint auf Weiss (1,60 : 1).
   Gefunden wurde genau eine solche Fläche auf index.html und module.html:
   `path.vfm-unt-zug` im Telefonschirm `.vfm-screen`. */
.band--dunkel .vfm-screen{--akzent:#3BA064}

/* Die Fusszeile ist das zweite dunkle Feld der Seite — gemessen
   rgb(2,12,9), derselbe Grund wie ein dunkles Band. Sie bekommt dieselbe
   Aufhellung, sonst stünde die Mailadresse dort als einziger Akzent noch
   auf 6,04 : 1, während alles andere auf Dunkel bei 13,59 liegt.
   AUSGENOMMEN das Zeichen: der Punkt hinter „digital" gehört zur Marke und
   wird nicht umgefärbt. */
.fuss{--akzent:#8FE9A8}
.fuss .lockup{--akzent:#3BA064}

/* ═══════════════════════════════════════════════════════════════════════════
   DAS ROTE QUADRAT WAR EINE WARNUNG, WO EIN VERTRAUENSBEWEIS STEHT
   Beanstandet an `module.html`, Zeile 137: „Kein Offline-Betrieb, nichts
   verschwindet still" trug `var(--rot)` — dieselbe Farbe, mit der die Seite
   sonst Fehler und Überfälligkeit malt. Direkt unter vier grünen Haken liest
   sich das als „Achtung", obwohl der Satz Offenheit zeigt. Ein Warnrot neben
   einem Satz, der Vertrauen schaffen soll, arbeitet gegen ihn.

   Die Aussage bleibt — alle sechs Sätze bleiben, wörtlich. Nur das Zeichen
   wechselt: statt eines roten Quadrats ein waagerechter Strich in der Farbe
   der Zeile selbst. Ein Haken sagt „das kann sie", ein Strich sagt „das kann
   sie bewusst nicht" — dieselbe Sprache wie in jeder Leistungsliste, und
   ohne Alarmfarbe.

   Der alte Wert erbte nebenbei `border-right/-bottom` und `rotate(42deg)`
   vom Haken; das rote Quadrat war deshalb ein gekipptes Viereck mit grünen
   Kanten. Beides wird hier ausdrücklich zurückgesetzt.

   Kontrast als reine Form (WCAG 1.4.11, Soll 3,0):
     --grau   #4A6153 auf Weiss    6,72 : 1
     --d-grau #98AB9F auf Nacht    8,18 : 1
   Nachgemessen im Browser, Werte in der Rückmeldung. */
.haken--stopp li::before{
  content:"";left:1px;top:.72em;width:12px;height:2px;
  background:var(--grau);border:0;border-radius:0;transform:none;
}
.band--dunkel .haken--stopp li::before{background:var(--d-grau)}

/* ═══════════════════════════════════════════════════════════════════════════
   DER VERGLEICH: DREI KARTEN MIT MESSBALKEN STATT EINER TABELLE
   Beanstandet: „den vergleich hochwertiger gestalten, langweilige tabelle
   bisher". Sieben Zeilen mal drei Spalten geben jeder Aussage dasselbe
   Gewicht; „Preis" und „bleibt draußen" standen gleich gross nebeneinander.

   Vorbild ist die Broschüre, `07-marketing/print/broschuere/broschuere.html`
   Zeilen 942–974 (`.welten`, `.wt`, `.wt-mess`, `.wm`, `.wl`, `.wr`, `.wb`,
   `.wv`, `.wt--gut`). Übernommen, nicht nachgebaut.

   ── DER MASSSTAB ──────────────────────────────────────────────────────
   Derselbe wie überall sonst in diesem Blatt, wo Millimeter aus der
   Broschüre herüberkommen: 1 mm = 5,4 px (Handy-Attrappe, Lichthof).
     Kartenabstand   4 mm    -> 22 px      Balkenhöhe    2,2 mm -> 12 px
     Polsterung  3,6/4 mm    -> 19/22 px   Balken-Lücke  2,4 mm -> 13 px
     Oberkante     1,4 mm    ->  8 px      Zeilenschritt 2,2 mm -> 12 px
   AUSNAHME Schrift: 6,4 pt und 6 pt liegen auf --fs-label, 7,6 pt auf
   --fs-body. Die Leiter ist Hausregel und schlägt den Maßstab.

   ── WAS ANDERS IST ALS IN DER BROSCHÜRE, UND WARUM ───────────────────
   · Kein `border-radius` auf den Karten (Hausregel). Der Balken behält
     seine Pillenform — das ist die Form eines Balkens, kein Kastenradius,
     genau wie `.b-fort i` es schon macht.
   · Kein äusserer Lichthof. Dieser Abschnitt steht auf WEISS, und dort ist
     der Hof laut Messung „unsichtbar oder schmutzig" (siehe DER LICHTHOF
     weiter oben). Der INNERE, sehr leise Verlauf funktioniert dagegen, weil
     er auf der dunklen Karte selbst liegt — der wird übernommen.
   · Die Kopfzeile der eigenen Karte bleibt GRAU, nicht gold. Etiketten sind
     in diesem Haus grau (`.band--dunkel .etikett`), und ein Vergleich soll
     nicht mit Farbe schreien, wo die Fläche schon spricht.

   ── DIE PROZENTWERTE ──────────────────────────────────────────────────
   Unverändert die der Broschüre — zwei Wahrheiten wären schlimmer als eine
   diskutable: 35/25 · 96/62 · 100/100. Begründung in der Rückmeldung.
   Beim PREIS misst der Balken den Betrag, nicht das Wohlgefallen: lang ist
   teuer. Deshalb ist „von der Stange" dort kurz und „von Grund auf neu"
   voll. */
/* GEMESSEN bei 1280 px: mit `align-items:start` waren die drei Karten
   343,3 / 350,3 / 349,8 px hoch — die linke 7 px kuerzer als die anderen
   beiden, weil ihr Inhalt kuerzer ist. Beanstandet als „kacheln gleich-
   gewichten ueberall". Die Broschuere, aus der dieser Baustein stammt,
   setzt kein align-items und steht damit auf `stretch`; hier war die
   Abweichung, nicht dort. */
.welten{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;
  margin-top:var(--a-gross);align-items:stretch}
.wt{background:var(--papier);border:1px solid var(--linie);padding:19px 22px}
.wt-t{font-size:var(--fs-label);font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--grau);margin:0 0 13px}
.wt-mess{margin-bottom:13px}
.wt-mess .wm + .wm{margin-top:12px}
.wt-mess .wl{display:block;font-size:var(--fs-label);font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;color:var(--grau);
  margin-bottom:6px}
/* Der Wert steht UNTER dem Balken, nicht daneben — und zwar in allen sechs
   Zeilen. Gemessen mit dem Wert daneben: die Rille war je nach Wortlänge
   183, 197 oder 308 px lang. Ein Vergleich, dessen Maßstäbe unterschiedlich
   lang sind, vergleicht nichts; 35 % von 183 px sahen aus wie 100 % von
   197 px. Untereinander sind alle sechs Rillen gleich lang. */
.wt-mess .wr{display:block}
/* Die Rille ist WEISS, nicht --linie. Gemessen: --akzent auf --linie sind
   2,34 : 1 — unter der Schwelle 3,0 für Bedienelemente und Grafik (WCAG
   1.4.11), der Balken wäre also kaum vom Grund zu unterscheiden. Grün liegt
   in der Mitte der Helligkeit; nur ein sehr heller oder sehr dunkler Grund
   trennt davon. Auf Weiss misst dieselbe Füllung 3,28 : 1. Damit die Rille
   auf --papier trotzdem eine Kante hat, bekommt sie eine Linie — und zwar
   eine, die man SIEHT: --linie misst gegen --papier 1,26 : 1, ohne sichtbares
   Ende ist ein Anteil aber nicht ablesbar. --grau-leise misst 4,67 : 1. */
.wt-mess .wb{display:block;width:100%;height:12px;background:var(--w);
  overflow:hidden;border:1px solid var(--grau-leise);border-radius:99px}
.wt-mess .wb i{display:block;height:100%;width:var(--anteil);
  background:var(--akzent);border-radius:99px}
.wt-mess .wv{display:block;margin-top:7px;font-size:var(--fs-klein);
  font-weight:600;color:var(--tinte)}
.wt p{margin:0;font-size:var(--fs-body);color:var(--grau);line-height:1.55}

/* Die eigene Karte ist die einzige gefüllte — das ist die Aussage des
   Bildes. `--akzent` wird auf ihr aufgehellt, mit demselben Griff wie im
   dunklen Band: die Karte ist dunkler Grund, also gilt dort das Mint. */
.wt--gut{--akzent:#8FE9A8;
  background:radial-gradient(118% 78% at 50% 0%,
    rgba(143,233,168,.06) 0%, rgba(143,233,168,.03) 42%,
    rgba(143,233,168,0) 76%), var(--schwarz);
  border-color:var(--d-linie);border-top:8px solid var(--akzent)}
.wt--gut .wt-t{color:var(--d-grau)}
.wt--gut .wt-mess .wl{color:var(--d-grau)}
/* Dasselbe auf der dunklen Karte: die Rille selbst misst gegen den
   Kartengrund nur 1,39 : 1, ihre Kante in --d-grau dagegen 8,18 : 1. */
.wt--gut .wt-mess .wb{background:rgba(143,233,168,.16);
  border-color:var(--d-grau)}
.wt--gut .wt-mess .wb i{background:linear-gradient(90deg,#3BA064,#8FE9A8)}
.wt--gut .wt-mess .wv{color:var(--d-text)}
.wt--gut p{color:var(--d-text)}
.wt--gut strong{color:var(--w)}

/* Unter 900 px stehen die drei untereinander — nebeneinander bliebe für
   Balken und Wert keine Breite mehr. */
@media (max-width:900px){ .welten{grid-template-columns:1fr} }


/* ═══════════════════════════════════════════════════════════════════════════
   DER VERGLEICH SOLL NICHT TROCKEN SEIN
   Ansage: „glow beim vergleich, alles hochwertiger machen nicht so trocken,
   animieren, auch bei scroll, preis episch rot machen bei dem teuren etc".

   ── 1 · DER SCHEIN ────────────────────────────────────────────────────
   Kein zweites Bauteil: es sind dieselben Verläufe wie im Lichthof, dieselbe
   Farbe (rgba(143,233,168,…)), kein `box-shadow`.
   Was NICHT übernommen wird, ist der ÄUSSERE Hof (`.lichthof::before`), und
   zwar aus einem gemessenen Grund, der weiter oben in diesem Blatt steht:
   auf Weiss ist er „unsichtbar oder schmutzig", und dieser Abschnitt steht
   auf Weiss. Der Schein liegt deshalb IM Kartengrund, wo er dunkel ist und
   trägt — er wirkt wie Licht, das von der Mintkante nach unten fällt.

   Und die Falle dazu, ebenfalls schon dokumentiert: DER SCHEIN HELLT DEN
   GRUND AUF. In der Broschüre stieg der Kartengrund dadurch auf #266A4C und
   eine Schrift fiel auf 3,18 : 1. Der Wert unten ist deshalb nachgemessen,
   nicht geschätzt; die Zahlen stehen in der Rückmeldung.

   ── 2 · DER TEURE PREIS ───────────────────────────────────────────────
   „schnell über 20 000 €" ist das Argument GEGEN die Entwicklung bei null,
   nicht unser Preis. Deshalb trägt genau diese eine Zahl das Rot der Marke,
   gross und fett — sie soll wehtun. Es ist das einzige Rot im Abschnitt.
   Damit sie nicht wie ein Fehler aussieht, steht sie nicht als Fussnote am
   Balken, sondern als eigene Zeile darunter: eine Aussage, keine Meldung.
   Der Wert steht ohnehin unter dem Balken (siehe `.wt-mess .wr`), die grosse
   Zahl braucht dafür keinen Sonderfall.

   ── 3 · DIE BEWEGUNG ──────────────────────────────────────────────────
   Die Balken wachsen beim Hereinscrollen. Sie hängen am VORHANDENEN
   `js-malt`-Beobachter (`main.js`), nicht an einem zweiten — mit allem, was
   daran hängt: der Ruhezustand ist der FERTIGE, versteckt wird erst, wenn
   das Skript `<html>` die Klasse `js-malt` gegeben hat, und das Fangnetz
   für Safaris Verlaufsspeicher gilt auch hier. Ohne JavaScript, bei
   abgeschalteter Bewegung und im Standbild-Modus stehen alle sechs Balken
   sofort vollständig da. */
.js-malt .wachs{transform:scaleX(0);transform-origin:left center}
.js-malt .wachs.gemalt{transform:scaleX(1);
  transition:transform .85s cubic-bezier(.22,.61,.36,1)}
/* Sechs Balken auf einmal sind ein Zucken; nacheinander sind sie eine
   Aussage. Der Versatz läuft von links nach rechts über die drei Karten. */
.js-malt .wt:nth-child(2) .wachs.gemalt{transition-delay:.12s}
.js-malt .wt:nth-child(3) .wachs.gemalt{transition-delay:.24s}
.js-malt .wm + .wm .wachs.gemalt{transition-delay:.18s}
.js-malt .wt:nth-child(2) .wm + .wm .wachs.gemalt{transition-delay:.30s}
.js-malt .wt:nth-child(3) .wm + .wm .wachs.gemalt{transition-delay:.42s}
@media (prefers-reduced-motion:reduce){ .js-malt .wachs{transform:none} }

/* Der Schein in der eigenen Karte — stärker als der stille Flächenverlauf,
   weil er hier die Aussage trägt und nicht nur die Fläche anhebt. */
.wt--gut{background:
    radial-gradient(96% 62% at 50% 0%,
      rgba(143,233,168,.16) 0%, rgba(143,233,168,.07) 40%,
      rgba(143,233,168,0) 78%),
    var(--schwarz)}

/* Der lange Weg: Markenrot. Bis zum 08.09.2026 stand hier eine Preiszahl
   („schnell ueber 20 000 €") in --fs-zahl. Seit die Zeile die ZEIT misst,
   ist der Wert ein Wort und keine Zahl — er bleibt rot, faellt aber auf die
   Stufe der beiden anderen Karten zurueck, sonst kippt die Karte optisch. */
.wm--teuer .wb i{background:var(--rot)}
.wm--teuer .wv{font-weight:700;color:var(--rot);letter-spacing:-.01em;line-height:1.15}
