/* Intenture News — Design-Tokens (die EINE Quelle), 29.07.2026
   ============================================================================================
   Warum diese Datei: Der Audit hat gemessen, dass es zwar Farben gibt, aber kein System —
   0 Abstands-Tokens (66 % der Abstände „off-grid"), 20 Schriftgrößen, 17 Radien, 13 Z-Index-Werte,
   7 Breakpoints, und die Anmeldestrecke lief auf einem eigenen Farbsystem. Folge: „mach es überall
   gleich" war eine Suchaktion statt einer Änderung.

   Ab jetzt: Farben, Abstände, Radien, Ebenen und Umbruchpunkte stehen HIER. Wer eine Fläche baut,
   nimmt ein Token — keine neue Zahl. Eingebunden von der App (index.html) UND allen Anmeldeseiten,
   damit der Weg Login → Dashboard eine Formsprache hat.

   Die FARBWERTE sind bewusst identisch mit dem, was die App schon nutzt (kein optischer Bruch beim
   Einführen) — neu sind nur die bisher fehlenden Achsen (Abstand/Radius/Ebene/Umbruch).
   ============================================================================================ */

:root{
  /* ---- Marke & Signale ------------------------------------------------------------------- */
  --navy:#2A2A84;           /* INTENTURE-Navy: die EINZIGE Aktionsfarbe (Buttons/aktiv/Auswahl) */
  --brand:#2563EB;          /* Link + Fokus (in Haarstärke lesbarer als Navy) */
  --navy-wash:#F1F1F8;      /* zarte Navy-Waschung: aktive/ausgewählte Flächen */
  --green:#1E874B;          /* Signal: Erfolg/geplant/veröffentlicht */
  --amber:#B26C09;          /* Signal: Achtung */
  --pink:#DC2626;           /* destruktiv/Alarm */

  /* ---- Flächen & Text ------------------------------------------------------------------- */
  --bg:#FAFAF8;             /* warmes Off-White (App-Hintergrund) */
  --surface:#FFFFFF;        /* Karten/Flächen */
  --surface2:#F7F5F2;       /* ruhige Füllfläche (Segmente/Filter/Eingaben) */
  --ink:#1A1A18;            /* Titel/Haupttext */
  --muted:#57544E;          /* sekundärer Text */
  --faint:#8A857D;          /* leiser Text / Meta */
  --line:#F0ECE8;           /* feine Hairline */
  --line-2:#E8E4DF;         /* kräftigere Linie (Hover/Rahmen) */

  /* ---- Schalter (PROMPT 47 §1, 19.08.2026) -------------------------------------------------
     Die Bahn AN ist --navy — Grün war für Schalter nie vorgesehen (nur Erfolgsmeldungen tragen
     es), PROMPT 28 nannte für die Bahn bereits Navy. Die drei Grautöne unten treffen KEINEN
     bestehenden Flächen-/Linienton der Datei (--line-2 ist #E8E4DF, die Bahn will #E4E4DF) und
     stehen darum wörtlich als eigene Token, nicht auf den Nachbarwert gerundet. */
  --sch-aus:#E4E4DF;              /* Bahn im Aus-Zustand */
  --sch-sperr-aus:#EFEFEC;        /* gesperrt + aus */
  --sch-sperr-an:#D8D8D3;         /* gesperrt + an — auch „an" wird grau, nur eine Stufe tiefer */
  --sch-knauf:#FFFFFF;            /* Knauf, in JEDEM Zustand weiß (auch gesperrt) */
  --sch-knauf-schatten:0 1px 2px rgba(22,22,26,.25), 0 1px 1px rgba(22,22,26,.15);

  /* ---- Diagramme (gerechnet, nicht geschätzt — s. Kommentar in index.html) ---------------- */
  --chart-mark:#2A2A84;     /* Datenmarke (wir) */
  --chart-dim:#8A857D;      /* De-Emphase (Kontext/Wettbewerb) */

  /* ---- Abstände: EINE 4px-Leiter. Vorher gab es dafür gar keine Tokens. -------------------
     04.08. auf die sieben Werte aus Spec 1.5 gezogen (4·8·12·16·20·24·32). Geändert haben sich
     nur --raum-5 (24→20), --raum-6 (32→24) und --raum-7 (48→32); die Obergrenze ist jetzt 32,
     weil Befund 1 aus ungenutzter Breite entsteht und nicht aus zu kleinen Abständen. Gefahrlos,
     weil im ganzen Repo 0 Fundstellen auf --raum-* zeigen (geprüft, nicht vermutet). */
  --raum-1:4px;
  --raum-2:8px;
  --raum-3:12px;
  --raum-4:16px;
  --raum-5:20px;
  --raum-6:24px;
  --raum-7:32px;

  /* ---- Radien: --rund-* (13.08., P1 Zug 3) entfernt -- abgeloest durch --r-klein/-mittel/
     -gross/-pille weiter unten (Spec 1.6), die vier Verbraucher dorthin migriert. ----------- */
  --radius:16px;            /* Altlast-Name, damit bestehende Regeln weiterlaufen */

  /* ---- Ebenen (Paket P4, 13.08.): sechs Stufen statt 85 gewachsener Zahlen zwischen 1 und
     10000, nichts dazwischen. Ersetzt die vorigen sechs Namen/Werte (--ebene-inhalt/-haftend/
     -schwebend/-overlay/-dialog/-toast, 1/40/200/1000/1200/1400) — nur --ebene-dialog behält
     zufällig denselben Vorbildwert wie `.set-overlay` vorher, alle anderen ändern sich.
     Wer eine siebte Ebene braucht, hat ein Strukturproblem, keine neue Zahl. */
  --ebene-grund:0;          /* Inhalt, Karten, Listen */
  --ebene-klebend:10;       /* Kopfzeile, Bedienzeile, Tabellenkopf — mitlaufend */
  --ebene-aufklapper:100;   /* Auswahlfeld-Liste, Menü, Glocke, Profil */
  --ebene-schleier:200;     /* die Verdunkelung hinter Dialog und Schublade */
  --ebene-dialog:300;       /* Dialog, Schublade, Leseoverlay */
  --ebene-toast:400;        /* Meldungen — liegt über ALLEM, auch über dem Dialog */

  /* ---- Schrift: EINE Familie, klare Stufen. ------------------------------------------------ */
  /* "Figtree" am 19.08.2026 gestrichen — es wurde seit der CDN-Ablösung (PR #241) NICHT MEHR
     GELADEN und griff dadurch nur noch auf Rechnern mit lokal installierter Figtree. Das machte
     die Darstellung maschinenabhängig: derselbe Text lief bei Lisa anders als bei Anna, ohne dass
     eine Einstellung das erklärt. docs/DESIGN-SYSTEM.md (13.08., bindendes CD-Blatt) hatte den
     Schritt ohnehin schon formalisiert: "Satoshi ist die einzige Schrift". Der Stack sagte bis
     heute etwas anderes als das Blatt.
     Die Legacy-Einträge (-apple-system für Safari ≤10.1, Roboto/Helvetica/Arial) bleiben bewusst
     stehen: sie kosten nichts, und sie herauszunehmen wäre Aufräumen, nicht Fehlerbehebung —
     das gehört in ein eigenes Paket mit den 20 handgeschriebenen Stacks, die es außerdem gibt. */
  --schrift:"Satoshi",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --text-xs:11.5px;
  --text-s:12.5px;
  --text-m:14px;
  --text-l:16px;
  --text-xl:20px;
  --text-hero:32px;

  /* PROMPT 31 §2: eine Ebene statt zwei — die zweite, weit ausladende Schatten-Ebene (0 10px 30px)
     kommt aus dem Prompt nicht vor. --shadow hat im ganzen Werkzeug genau einen Verbraucher
     (.card, geprüft per grep) — die Vereinfachung wirkt darum nur hier, kein Seiteneffekt. */
  --shadow:0 1px 2px rgba(37,36,33,.04);
}

/* Dunkles Thema: EIGENE Stufen, keine Umkehrung der hellen Werte (sonst kippen Kontraste).
   Die App setzt data-theme explizit; die Anmeldeseiten bleiben bewusst immer hell. */
:root[data-theme="dark"]{
  --navy:#3D46B8;
  --brand:#9FB6DE;
  --navy-wash:#262A3D;
  --green:#6FCC91;
  --amber:#D6A85C;
  --pink:#E38B86;
  --bg:#1B1C1F;
  --surface:#232427;
  --surface2:#2B2C30;
  --ink:#ECEDEF;
  --muted:#B4B6BA;
  --faint:#86888D;
  --line:#33353A;
  --line-2:#42444A;
  --chart-mark:#6B78E0;     /* hellere Navy-Stufe: auf #232427 sonst nur 2,04:1 Kontrast */
  --chart-dim:#86888D;
  --shadow:0 4px 20px rgba(0,0,0,.45);
  /* Schalter dunkel: PROMPT 47 nennt nur die hellen Werte. --sch-aus und --sch-sperr-aus sind
     bestehende Linienstufen dieses Blocks (= --line-2 bzw. --linie); Vorzeichen kehrt sich um
     (Regel 9.1, „Höhe trägt sich als Helligkeit"): gesperrt+aus zieht Richtung Grund,
     gesperrt+an liegt darüber — im Hellen ist es andersherum.
     ZWEITMEINUNG-FUND (19.08.): --sch-sperr-an stand hier zuerst identisch zu --sch-aus (beide
     #42444A) — ein gesperrter, eingeschalteter Schalter war farblich nicht von einem freien,
     ausgeschalteten zu unterscheiden, nur die Knaufposition trug den Unterschied noch. Für
     „liegt darüber" gibt es in diesem Block keine passende bestehende Stufe (--muted-dunkel
     wäre ein Textton, --flaeche-hoch geht in die falsche Richtung) — darum hier, anders als die
     zwei Nachbarn, ein eigener neuer Wert, denselben Abstand wie der helle Schritt (E4E4DF→
     D8D8D3, −12 je Kanal) nur nach oben gespiegelt. */
  --sch-aus:#42444A;              /* = --line-2 dunkel */
  --sch-sperr-aus:#2E3138;        /* = --linie dunkel */
  --sch-sperr-an:#4C4F57;         /* neu: --sch-aus + 10 je Kanal, sichtbar heller */
  --sch-knauf:#ECEDEF;            /* liest sich als weiß, ohne auf #1B1C1F zu blenden */
  --sch-knauf-schatten:none;      /* ein Schatten leistet auf dunklem Grund nichts (Regel 9.1) */
}

/* ##############################################################################################
   SPEC-DESIGN-INTENTURE-NEWS · Runde 2 (04.08.2026) — Abschnitt 1, vollständig
   ##############################################################################################
   Das ist ab hier die Quelle aller Werte. Die Namen oberhalb dieses Trenners sind BESTAND: sie
   tragen die Anmeldestrecke und die Nebenseiten (report/kapazitaet/medien/verteiler/auth) und
   bleiben unverändert, bis Spec 7.1 entschieden ist — würde man sie jetzt auf die App-Palette
   ziehen, änderten sich die Anmeldeseiten sichtbar, und genau das ist ausdrücklich ausgenommen.
   Deshalb zwei Schichten mit getrennten Namen statt einer halb umgestellten.

   Die dunklen Werte sind KEINE Spiegelung der hellen, sondern eigens gerechnet (Spec 9). Wo eine
   Gruppe im Dunkeln nicht vorkommt, steht das ausdrücklich dabei, statt still zu fehlen.
   ============================================================================================== */
:root{
  /* ---- 1.1 Grundwerte -----------------------------------------------------------------------
     Sechs Werte tragen die gesamte Fläche; was nicht Grund, Fläche, erhöhte Fläche oder eine
     benannte Signalfläche ist, existiert nicht. */
  --grund:#FAFAF8;              /* warmes Off-White: Karten heben sich ohne Schatten ab */
  --flaeche:#FFFFFF;            /* Karten, Sidebar, Panels — die eine Ebene, auf der Inhalt steht */
  --flaeche-hoch:#F4F3F0;       /* nur was ÜBER dem Inhalt liegt: Menü, Sprechblase, Aufklapper */
  --text:#16161A;               /* Titel und Fließtext — nie in Navy, Navy ist Aktion (16,4:1) */
  --text-leise:#72726D;         /* EIN leiser Ton, nicht zwei (4,63:1 Grund · 4,84:1 Fläche) */
  --linie:#E4E4DF;             /* genau EINE Rahmenfarbe; Abstufung über Abstand, nicht Helligkeit */
  /* NEU (13.08., Paket P2): sichtbare Überfahren-Fläche für randlose Bausteine (Rolle Geist,
     Icon-Knopf). Bewusst kein neuer Farbwert — derselbe Ton wie --linie, nur unter einem
     Flächen- statt Randnamen, weil .klern-btn vorher auf --surface2 überfuhr (#F7F5F2 auf
     #FFFFFF = 1,09:1, praktisch unsichtbar). */
  --senke:#E4E4DF;
  /* NEU (13.08., Paket P3 Teil 3): die eingesenkte RUHEfläche für Bedienelemente, die lesen oder
     eingeben (Auswahlfeld — Eingabefeld/Chip/Skelett folgen in einem späteren Paket, hier bewusst
     nicht angefasst). Bewusst ein EIGENER Name statt --senke direkt zu verwenden: --senke bleibt
     unverändert die P2-Überfahren-Fläche für randlose Knöpfe (dort ist Dunkel bewusst HELLER als
     der Träger — Annäherung an Weiß signalisiert dort Bewegung, s. --aktion-ueber-Kommentar unten).
     Eine eingesenkte Ruhefläche braucht im Dunkeln das UMGEKEHRTE Vorzeichen (dunkler als der
     Träger, s. 9.1 unten) — ein Token für beide Bedeutungen hätte sich bei der nächsten Änderung
     der einen Fläche im Wege der anderen gestanden. Hell: identischer Ton wie --senke (im Hellen
     zufällig dieselbe Fläche gemeint), Dunkel: eigens gerechnet (Regel in 9.1). */
  --eingesenkt:var(--senke);

  /* ---- 1.2 Aktion in ihren Zuständen --------------------------------------------------------
     Navy ist die EINZIGE Aktionsfarbe: Knöpfe, aktive Zustände, Fokus, Links — sonst nichts. */
  --aktion:#2A2A84;             /* Ruhe (11,3:1 auf Grund) */
  --aktion-ueber:#22226B;       /* Überfahren: eine spürbare Stufe, kein Sprung */
  --aktion-gedr:#1A1A56;        /* Gedrückt: zweite Stufe — ersetzt jede Skalierungs-Animation */
  --aktion-fokus:#2A2A84;       /* Fokusring, 2px Ring / 2px Versatz (Spec 2.5) */
  --aktiv-flaeche:#EEEEF7;      /* Fläche aktiver/ausgewählter Elemente — aus zwei Metern erkennbar */
  --aktiv-rahmen:#C9C9E4;       /* trägt den Aktiv-Zustand auch ohne Farbwahrnehmung */
  /* PROMPT 34 (15.08.): Kopfzeile/Eingrenzen-Tafel/Fenster — eigene Namen für zwei Werte, die im
     Auftrag wörtlich benannt sind, aber nicht mit den obigen identisch sind. --wash IST derselbe
     Ton wie --aktiv-flaeche (#EEEEF7), deshalb ein Alias statt einer zweiten Zahl. --markenrand
     (#DCDCF0) ist dagegen ein EIGENER, etwas hellerer Rand als --aktiv-rahmen (#C9C9E4) — der
     Auftrag nennt beide Werte namentlich nebeneinander, sie sind bewusst verschieden (Marken sind
     zarter gerahmt als z. B. eine gesetzte Auswahlfeld-Fläche). */
  --wash:var(--aktiv-flaeche);
  --markenrand:#DCDCF0;
  --aus-inaktiv:#C4C1BA;        /* Zurücksetzen/Marken-Ikon im leeren Zustand — bewusst kein --faint-Alias */
  /* NEU (P6, 14.08.): index.html setzt diesen Alias bisher nur in seiner eigenen inline-:root-
     Kopie (Zeile 82/195), .btn-zweit:hover dort verlangt ihn aber. Hier nachgezogen, damit
     .btn-zweit auf den Nebenseiten (die NUR tokens.css laden) denselben Überfahren-Rand zeigt,
     statt eine undefinierte Variable stumm zu ignorieren. */
  --navy-wash-rand:var(--aktiv-rahmen);
  /* Eigene Zeile, kein Alias auf --aktion: im Dunkeln erreicht #3D46B8 als TEXT nur 2,2:1 auf
     der Fläche. Dort trägt die Aktionsfarbe nur Flächen und Ränder, farbiger Text braucht #8E97F0. */
  --aktion-text:#2A2A84;
  --gesperrt-flaeche:#EFEFEC;   /* bewusst unter 4,5:1 — Gesperrtes darf nicht wie Aktives lesbar */
  --gesperrt-text:#A8A8A3;      /* wirken (2,6:1), es ist von der Bedienung ausgenommen */

  /* ---- 1.3 Semantische Farben ---------------------------------------------------------------
     Vier Bedeutungen, mehr gibt es nicht — braucht ein Baustein eine fünfte, ist der Baustein
     falsch. Strikt getrennt von Aktion und NIE als Alias darauf, sonst wandert ein Signal in
     einen Knopf und umgekehrt. */
  --erfolg-text:#197440;        /* 5,3:1 — Bestandswert #1E874B erreicht als Text nur 4,43:1 */
  --erfolg-flaeche:#EAF5EE;
  --erfolg-rahmen:#1E874B;      /* als Punkt- und Rahmenfarbe bleibt der Bestandswert */
  --achtung-text:#96590A;       /* 5,5:1 — Einzelquelle, Zuschneiden nötig, Teil-Ausfall */
  --achtung-flaeche:#FBF2E4;
  --achtung-rahmen:#C08A2E;
  /* Die lauteste Farbe im Werkzeug und deshalb RESERVIERT für Paywall und §7 UWG: jede weitere
     Verwendung nimmt ihr die Wirkung — und ein übersehenes „Paywall" sieht man erst in einer Klage.
     ABWEICHUNG VON DER SPEC, freigegeben 04.08.: Die Spec nennt für den Text #DC2626 und dafür
     4,7:1 auf der Fläche. Nachgerechnet sind es 4,25:1 — unter der 4,5:1-Grenze, und zwar am
     Paywall-Kennzeichen, dem einzigen Baustein, dessen Übersehen ein Verfahren nach sich zieht.
     #C81E1E hält denselben Farbton bei 5,05:1 und lässt echte Luft; die Fläche bleibt unberührt,
     damit die rote Waschung als Wiedererkennung erhalten bleibt. Der dunkle Wert war nie
     betroffen (#F87171 auf #2B1718 = 6,13:1) und bleibt wie spezifiziert. */
  --warnung-text:#C81E1E;       /* 5,05:1 auf --warnung-flaeche (Spec-Wert #DC2626: 4,25:1) */
  --warnung-flaeche:#FCEDED;
  --warnung-rahmen:#E88A8A;
  --info-text:#2A4A8A;          /* 7,2:1 — Quellenzahl, neutrale Systemmeldung, Zählhinweise */
  --info-flaeche:#EDF1FB;
  --info-rahmen:#7D97CC;

  /* ---- 1.4 Kategorie-Töne -------------------------------------------------------------------
     Sechs entsättigte Töne gleicher Helligkeit, unverändert aus dem Bestand. Sie erscheinen NUR
     als 3px-Laufkante und als 8px-Punkt, nie als Fläche — sechs Flächenfarben würden mit der einen
     Aktionsfarbe konkurrieren; als Punkt sind sie Sortierhilfe und kein Signal. */
  --kat-tax-audit:#5E7391;
  --kat-private-markets:#7E6593;
  --kat-legal:#71716E;
  --kat-wirtschaft:#A9755C;
  --kat-ki-tech:#4E8681;
  --kat-karriere:#A96A7D;

  /* ---- 1.6 Radien --------------------------------------------------------------------------
     Vier Werte. 999px ist die EINZIGE Ausnahme und gilt nur für Punkte und Zähler ≤10px Höhe —
     jede Pille darüber ist ein Fehler. Skelette übernehmen den Radius des Elements, das sie
     vertreten (die 4px-Ausnahme ist in Spec 1.6 aufgelöst, gegengezeichnet in 7.3): kenntlich
     macht sie die Füllung ohne Rahmen und das Schimmern, nicht der Radius. */
  /* ⚠️ RADIEN-AUFRÄUMEN IST HIER ZU ENDE (01.09.2026) — bitte nicht neu aufmachen.
     Die Feierabendliste vom 26.08. nannte „~50 von 63 handgetippten border-radius-Werten sind
     exakt ein vorhandener Token" und schlug ein mechanisches Aufräumpaket vor. Nachgemessen am
     01.09.: von 107 rohen Werten in `index.html` liegen 50 INNERHALB der beiden wörtlich
     übernommenen Claude-Design-Vorlagen (`#pf-vorlage`, `#wb-vorlage`) — die tragen ihr eigenes
     „NICHT VON HAND ÄNDERN" und dürfen laut Tobias (15.08.) nicht ans Bestandsraster gebeugt
     werden. Weitere sitzen im maßstäblich verkleinerten Laptop-Mock (`.est-lt-*`): dort sind 22px
     Deckel und 14px Schirm bewusst gewählte ABSOLUTE Maße für die verkleinerte Darstellung, kein
     Blatt und keine Karte — sie an `--r-blatt`/`--r-karte` zu hängen hieße, dass eine
     Meeting-Blatt-Entscheidung still die Laptop-Attrappe verzieht.
     Übrig blieben 8 echte Treffer, davon 5 gezogen: 3× 999px → `--r-pille` (maßstabsunabhängig,
     „voll gerundet" bleibt in jeder Größe richtig) sowie `.as-treffer` 12px → `--r-gross`
     (Aufklapper) und `.as-enter` 6px → `--r-klein` (Chip). Der Rest ist absichtlich roh.
     Die 29× `50%` sind Kreise, kein Radius-Token, und die gerichteten Mehrwert-Shorthands
     (`0 12px 12px 0` …) sind Form-, nicht Wertentscheidungen — beides wie schon 13.08. (P1 Zug 3)
     bewusst ausgenommen. */
  --r-klein:6px;                /* Chips, Kennzeichen, Eingabefelder */
  --r-mittel:8px;               /* Knöpfe, kleine Kacheln */
  --r-gross:12px;               /* Karten, Panels, Aufklapper, Dialoge */
  --r-pille:999px;              /* voll gerundet — Punkte/Zähler ≤10px hoch, seit PROMPT 47
                                   (19.08.) auch die 24px-Schalterbahn (.tm-switch, „Radius
                                   full"). Kein zweiter 999px-Token dafür, derselbe Wert. */
  /* PROMPT 58 §0 (20.08.2026): 18px für die Vergleichszeilen-Zelle im Performance-Board — trifft
     auf KEINEN Bestandswert. ZWEITMEINUNG-KORREKTUR (20.08. auf PR #273): hieß zuerst
     --pf-r-karte, das kollidierte im Namen mit dem bereits bestehenden --r-karte (14px, s. u.,
     generischer Kartenradius mit vier echten Verbrauchern) — beide klangen nach derselben Sache
     mit unterschiedlichem Wert. „22 Blatt" aus dem Auftrag ist HIER bewusst noch nicht angelegt:
     diese PR baut noch kein Blatt/Overlay, das ihn bräuchte (das neue Wochen-Menü ist ein
     schmales Popover und erbt --r-gross von der gemeinsamen .popover-Klasse) — der Token kommt,
     wenn ein späterer Abschnitt (Meeting-Blatt/Detail-Overlay) ihn tatsächlich verwendet, nicht
     spekulativ vorab. „12 innen" aus dem Auftrag braucht ohnehin keinen eigenen Token — das IST
     --r-gross. */
  --pf-r-vergleich:18px;
  --skelett-fuellung:#EFEFEC;   /* Lade-Skelett: Füllung ohne Rahmen */
  /* 13.08.: reservierter Platz für die feste Top-Story-Ecke (.card-corner) auf Karten ohne die
     eigene .card-2col-Spaltenreservierung — als Token statt Rohwert, damit test_design_sperre.py
     die Sperre gegen neue rohe px-Werte nicht auf diesen einen Anlass hochsetzen muss. */
  --k-ecke-badge:118px;
  /* Kartenradius der Einstellungen-Tafel (PROMPT 60): .est-karte/.est-dst-kasten/.est-konto-zeile/
     .tm2-gruppe trugen denselben Wert 16 vierfach getrennt (einmal roh, zweimal über --r-gross,
     das mit 12 zu eng war) — jetzt EIN Token, aus demselben Grund wie --k-ecke-badge: damit
     test_design_sperre.py die Sperre gegen neue rohe px-Werte nicht anheben muss. Bewusst ein
     eigener Name statt --r-karte (14px) — andere Fläche (Artikelkarten/Toast), anderer Wert. */
  --r-est-karte:16px;

  /* ---- 1.7 Schrift-Rollen ------------------------------------------------------------------
     Acht Rollen (13.08.: +1 — --tx-bedienung neu). Heute standen die Größen als Einzelwerte an
     rund 200 Stellen; gemessen im laufenden Werkzeug waren es auf BEDIENELEMENTEN allein zehn
     verschiedene Größen gleichzeitig, darunter 13px/13,3333px/13,5px nebeneinander (Design-Audit
     12.08., 0 Verbraucher dieser Tokens zum Zeitpunkt der Messung). Drei Werte darum jetzt
     geändert (Kartentitel, Fließtext, Leise) — Begründung je Zeile unten; volle Herleitung in
     design-review/audit-2026-08-12/{FORMSPRACHE.md,PROMPT-CLAUDE-DESIGN.md}.
     Der Kleinstwert (-min) ist die Untergrenze für die stufenlose Dichte-Anpassung: darunter darf
     der Faktor eine Rolle nicht drücken. Nie unter 12px — außer dem Kleinlabel, das bei 11px
     konstant bleibt, weil es nur in Versalien steht und bei Faktor 0,29 sonst unlesbar wäre.
     KEINE dunkle Entsprechung: Schriftgrößen sind vom Thema unabhängig. */
  --tx-seitentitel:24px;   --tx-seitentitel-min:18px; --tx-seitentitel-gew:700; --tx-seitentitel-zh:1.25;
  --tx-abschnitt:18px;     --tx-abschnitt-min:15px;   --tx-abschnitt-gew:700;   --tx-abschnitt-zh:1.3;
  /* 15→17px (13.08.): 15px lag nur 1px über --tx-fliess (14px) — das war keine wahrnehmbare
     Rangfolge, sondern ein Messfehler des Auges. 17px macht den Kartentitel wieder eine echte
     Stufe. */
  --tx-kartentitel:17px;   --tx-kartentitel-min:15px; --tx-kartentitel-gew:700; --tx-kartentitel-zh:1.3;
  /* 14→13,5px (13.08.): jetzt bewusst GLEICH groß wie --tx-bedienung darunter — unterschieden
     durch Gewicht (400 vs. 600) und Zeilenhöhe, nicht durch einen weiteren Halbpixel-Sprung.
     Genau die 13/13,3333/13,5-Häufung war der Befund; zwei Rollen auf einer Größe mit klarem
     Gewichtsunterschied ist lesbarer als drei Rollen auf drei Größen im Abstand von 0,5px. */
  --tx-fliess:13.5px;      --tx-fliess-min:13px;      --tx-fliess-gew:400;      --tx-fliess-zh:1.6;
  /* NEU (13.08.): die eine Bedienschrift für ALLE Bedienelemente — Knöpfe, Felder,
     Auswahlfelder, Segmente, Reiter, Sidebar-Einträge, Menüzeilen. Deckt sich bewusst mit
     --such-fs (der Suchbaustein hatte den Wert schon richtig). Ersetzt zehn Größen.
     Gewicht 600->500 (19.08.2026): Satoshi hat keinen 600er-Schnitt, der Browser rendert 600
     seither identisch zu 700 (Bold) — gemessen über Tintendeckung, nicht geschätzt. Damit waren
     Bedienelemente optisch nicht von Kartentiteln (--tx-kartentitel-gew:700) zu unterscheiden,
     obwohl zwei verschiedene Werte im Code standen. 500 ist Satoshis echter Medium-Schnitt und
     liegt sichtbar unter 700 — dieselbe Hierarchie wie bei iOS (Bedienelemente Medium, Titel
     Bold). Nebeneffekt, der die Änderung zusätzlich rechtfertigt: mehrere Komponenten springen
     auf `.active`/`.aktiv` von diesem Token auf rohes font-weight:700 (u. a. .thema-eintrag,
     .est-lt-side-item, .pf-katmenu-eintrag) — dieser Sprung war bislang unsichtbar (600 und 700
     rendern gleich) und wird mit 500 als Basis erstmals zur echten Betonung. */
  --tx-bedienung:13.5px;   --tx-bedienung-min:13px;   --tx-bedienung-gew:500;   --tx-bedienung-zh:1.35;
  /* 13→12,5px (13.08.): und die Farbe läuft ab jetzt IMMER über --text-leise, nie über
     opacity auf --text — eine 11,5px-Zeile mit opacity:.8 maß im Audit nur 3,55:1 Kontrast,
     derselbe Ton direkt gesetzt erreicht 4,63:1.
     Nachtrag (13.08., Sammel-Merge #165): die Aussage "0 Verbraucher" oben gilt für dieses Token
     nicht mehr unverändert — die Entwürfe-Vollansicht (zeigeEntwurfVollansicht) bekam im selben
     Merge ihren ersten echten Verbraucher: .ev-zurueck{font-size:var(--tx-leise)} in
     static/index.html. Wirkung bleibt trivial (0,5px), aber ein künftiges Verschieben dieses
     Werts hat jetzt einen sichtbaren Effekt an dieser einen Stelle. */
  --tx-leise:12.5px;       --tx-leise-min:12px;       --tx-leise-gew:400;       --tx-leise-zh:1.4;
  --tx-klein:11px;         --tx-klein-min:11px;       --tx-klein-gew:700;       --tx-klein-zh:1.2;
  --tx-klein-sperrung:0.08em;   /* nur Versalien-Kicker und Sidebar-Gruppenüberschriften */
  /* 20→28px (13.08.): eine Leitzahl, die nur 2px über der Abschnittsüberschrift lag, WAR keine
     Leitzahl — Kacheln in Performance/Kosten/Nutzung brauchen echten Abstand nach oben. */
  --tx-zahl:28px;          --tx-zahl-min:20px;        --tx-zahl-gew:700;        --tx-zahl-zh:1.0;
  /* Zahlen laufen IMMER tabellarisch — ohne das zappelt der Sidebar-Zähler bei jedem Neuladen,
     bei 6.447 sichtbar. */
  --zahl-tabellarisch:tabular-nums;
  /* Gewichte GENAU drei im ganzen Werkzeug: 400 · 600 · 700. 800 (Wortmarke u.a.) faellt weg. */
  --schrift-gew-normal:400; --schrift-gew-mittel:600; --schrift-gew-stark:700;

  /* ---- 1.8 Höhen ---------------------------------------------------------------------------
     Acht Höhen (13.08.: +1 — --h-dicht neu). Heute rechnete jede Stelle ihre eigene aus — das ist
     die Wurzel von Befund 3; gemessen waren 17 verschiedene gerenderte Knopfhöhen. Drei Stufen
     für alle Bedienelemente: GROSS (40px, --h-knopf) nur Hauptaktion + Formularfeld im Dialog,
     STANDARD (32px, --h-knopf-klein) für praktisch alles andere, DICHT (28px, --h-dicht) für
     Icon-Knopf-Gruppen und den Kategorie-Chip in der Sidebar. Drei Höhen betreffen Lade-Skelette
     (Eingabefeld, Kennzeichen, Zeile): wird eine geändert, wird das Skelett im selben
     Arbeitsschritt geändert. KEINE dunkle Entsprechung: Höhen sind vom Thema unabhängig. */
  --h-knopf:40px;               --pad-knopf:16px;
  --h-knopf-klein:32px;         --pad-knopf-klein:12px;
  /* NEU (13.08.): dicht, für Icon-Knopf-Gruppen am Kartenfuß und den Kategorie-Chip. */
  --h-dicht:28px;               --pad-dicht:8px;
  /* 36→32px (13.08.): auf die STANDARD-Stufe gezogen, damit ein Feld in einer Filterzeile nicht
     eine eigene, vierte Höhe neben Knopf/Auswahlfeld/Reiter aufmacht. Skelett im selben Zug
     mitgezogen (Filterleiste). */
  --h-feld:32px;                --pad-feld:12px;        /* Skelett betroffen: Filterleiste */
  --h-chip:26px;                --pad-chip:10px;
  --h-kennzeichen:22px;         --pad-kennzeichen:8px;  /* Skelett betroffen: Artikelkarte, Zeile 1 */
  /* 34→32px (13.08.): ebenfalls auf STANDARD gezogen und FEST (kein Bereich mehr) — gemessen
     schwankte der Sidebar-Eintrag zwischen 29px (ohne Zähler) und 30px (mit Zähler), Ursache der
     7px-Drift der ganzen Navigation beim Laden. line-height:1 gehört zwingend dazu, siehe
     .sb-item beim Wiring — der Zähler darf nie mehr die Zeilenhöhe bestimmen.
     32→30px (PROMPT 62 §1, 20.08.): bleibt FEST aus demselben Grund wie oben — nur die Zahl
     ändert sich, nicht das Prinzip. Der alte Scroll-Fallback (`.sidebar{overflow-y:auto}`) fällt
     im selben Paket weg; die stufenlose Dichtesuche (Abstände/Schrift, unverändert) bleibt das
     einzige Sicherheitsnetz gegen zu wenig Platz. */
  --h-sb-eintrag:30px;          --pad-sb-eintrag:12px;
  --h-zeile:44px;               --pad-zeile:12px;       /* Skelett betroffen: alle Listenansichten */
  --h-zaehler:18px;             /* Zähler-Kennzeichen, Radius --r-pille, bei 0 unsichtbar */
  --h-punkt:8px;                /* Kategorie- und Ampel-Punkt */
  /* PROMPT 58 §5 (21.08.2026): Meeting-Modus — eigene Reihe wie --h-chip/--h-kennzeichen oben,
     bewusst NICHT in BEDIENHOEHEN_TOKENS (tests/test_design_sperre.py): Auftragswerte wörtlich,
     keine Rundung auf die kuratierte 28/30/32/40-Stufe. */
  --h-knopf-blatt:36px;         /* Leiste-/Blatt-/Protokoll-Fußknöpfe (Eigene Aufgabe, Protokoll,
                                    Beenden, Abbrechen, Übernehmen, Weiter im Meeting, Verschicken,
                                    Mail-Vorschau) */
  --h-blatt-chip:34px;          /* WER-/BIS-WANN-Chips im Aufgaben-Blatt (Person, Frist, Datum
                                    wählen, Ohne Frist) */
  --h-blatt-notiz:42px;         /* Notiz-Eingabe im Aufgaben-Blatt */
  /* NEU (13.08., Paket P3 Teil 2): "Bänder" — Seiten-Chrome, keine Bedienelemente. Eigene Kategorie
     neben den Höhen oben (PROMPT-CLAUDE-DESIGN.md: „Bänder: Kopfzeile 56 · Seitenkopf 64 ·
     Bedienzeile 48"); nur die Bedienzeile bekommt hier einen Token, weil sie die einzige ist, die
     eine echte CSS-`height`-Deklaration braucht — Kopfzeile/Seitenkopf entstehen aus Innenabstand,
     nicht aus einer festen Höhe. */
  /* 48 -> 60 (25.08.): Wert aus `Apple-Schale.dc.html` (Claude Design, PROMPT 62 §2:
     „Höhe 60“). Der Entwurf rechnet 10 px davon als unteren Innenabstand, sodass die
     Knöpfe darin auf derselben 36-px-Linie sitzen wie in der Kopfzeile darüber. */
  --h-bedienzeile:60px;
  /* NEU (P6, 14.08.): die zwei fehlenden Bänder nachgezogen, für den gemeinsamen Rahmen der sieben
     Nebenseiten (`.rahmen-kopf`/`.seitenkopf` weiter unten). ALS explizite Höhe statt aus
     Innenabstand: `.bedienzeile` selbst macht es schon so (`height:var(--h-bedienzeile)`, direkt
     oben) — der alte Kommentar beschrieb, dass diese zwei Bänder noch KEINEN Token hatten, keine
     Regel, dass sie nie einen bekommen dürften. Explizit + `display:flex;align-items:center` ist
     robuster gegen Schriftmetrik-Überraschungen als aus Zeilenhöhe+Innenabstand zurückgerechnet. */
  --h-kopf:56px;
  /* `--kopf-hoehe` ist die LAUFENDE Höhe der Kopfzeile: ein ResizeObserver in index.html
     schreibt sie bei jeder Änderung neu, `.bedienzeile` und `.nach-oben` lesen sie.
     Bis 25.08. war sie NIRGENDS statisch definiert — beide Verbraucher hingen an ihrem
     Rückfall `56px`, während die Leiste 78 px maß. Eine nie definierte Variable meldet
     keinen Fehler, sie nimmt still den Rückfall: die Bedienzeile klebte dadurch 22 px zu
     hoch. Seit die Leiste wieder 56 px ist, wäre der Rückfall zufällig richtig — genau
     deshalb steht der Wert jetzt hier: sonst schlägt dasselbe beim nächsten Höhenwechsel
     wieder zu, wenn der Beobachter einmal nicht läuft (sehr alte Browser, Fehler vor
     DOMContentLoaded, abgeschaltetes JS). Der Beobachter überschreibt ihn weiterhin. */
  --kopf-hoehe:var(--h-kopf);
  --h-seitenkopf:64px;
  /* NEU (P7, 14.08.): die Listenkarte war hier bewusst ausgespart (s. Kommentar bei GRENZEN in
     tests/test_design_sperre.py: "ein Ziel dort wäre eine neue Regel, keine Migration ...").
     Jetzt gebaut — feste Höhe statt der bisherigen, gemessenen Bandbreite (173–211px). Eigene
     Tokens statt eine der acht Bedienelement-Höhen zweckzuentfremden: Titel/Teaser sind
     mehrzeilige Textblöcke, kein Bedienelement. Kartenfuß/Kennzeichen/Chip/Zähler/Punkt nutzen
     bewusst --h-dicht/--h-kennzeichen/--h-chip/--h-zaehler/--h-punkt weiter oben mit (exakt
     dieselben Werte, s. deren "Skelett betroffen: Artikelkarte"-Kommentare). */
  --h-listenkarte:184px;
  --h-medium:64px;
  --h-titelzeile:45px;
  --h-teaserzeile:44px;
  --h-begruendung:18px;

  /* ---- 1.9 Bewegung (NEU, 13.08.) ------------------------------------------------------------
     Drei Kurven, vier Dauern. --k-aus ist keine Erfindung: cubic-bezier(.32,.72,0,1) steht schon
     21x im Werkzeug (u. a. Toast, Aufklapper) — hier nur zur EINEN Hauskurve erklärt. Regel:
     Bewegung erklärt Herkunft, Ziel oder Konsequenz, sonst ist sie Deko. In Ruhe bewegt sich
     nichts; nach einer Handlung bewegt sich genau eine Sache. Voller Bewegungskatalog (13
     Anlässe) in design-review/audit-2026-08-12/PROMPT-CLAUDE-DESIGN.md. */
  --k-aus:cubic-bezier(.32,.72,0,1);      /* Erscheinen, Öffnen, Wandern */
  /* --k-ein ist seit 19.08.2026 UNGENUTZT (vorher: Verschwinden). Alle drei Verwendungen
     (login.html, Freigabe-Ausblenden, Karten-Wisch-Geste) liefen auf --k-aus um — Emils
     einzige harte Verbotsregel ist ease-in auf Bedienoberflächen, und genau das ist diese
     Kurve (Anfangssteigung 0, Endgeschwindigkeit maximal: sie verschwindet im Moment ihrer
     höchsten Geschwindigkeit). Definition bewusst stehen gelassen statt gelöscht — sie
     dokumentiert die Entscheidung und verhindert, dass ein künftiges "schnell mal eine
     Verschwinden-Kurve" versehentlich wieder ease-in einführt, ohne diesen Kommentar zu
     lesen. Nicht verwenden. */
  --k-ein:cubic-bezier(.4,0,1,1);
  --k-zustand:cubic-bezier(.2,0,.4,1);    /* Überfahren, Fokus, Druck */
  /* PROMPT 47 §1 (19.08.2026): der Schalterknauf läuft auf einer eigenen Kurve. Sie trifft
     KEINE der drei oberen — --k-aus bremst zum Ende hin härter ab (.32,.72,0,1), der Knauf soll
     weicher einlaufen. Wörtlich aus dem Auftrag übernommen, nicht auf --k-aus gerundet. */
  --k-schalter:cubic-bezier(.2,.8,.2,1);  /* Knaufweg im Schalter (Dauer: --d-klein/160ms) */
  --k-schalter-bahn:ease-out;             /* Bahnfarbe, gleichzeitig — Auftrag nennt hier
                                             ausdrücklich ease-out, nicht dieselbe Kurve: der
                                             Farbwechsel meldet „Zustand ist gewechselt", der
                                             Knaufweg zeigt die Bewegung dorthin. */
  --d-zustand:90ms;    /* Überfahren, Fokus, Druck */
  --d-klein:160ms;     /* kleine Fläche erscheint/verschwindet (Menü, Auswahlfeld) */
  --d-flaeche:220ms;   /* Fläche/Panel, Bereichs- und Reiterwechsel — deckt sich mit dem Toast */
  --d-gross:320ms;     /* Karte verlässt die Liste, Nachbarn rücken nach */
  /* EIN Druckpunkt im ganzen Werkzeug (13.08.): vorher sieben verschiedene Tiefen (.9 bis .985),
     der Arbeitsknopf hatte gar keine. */
  --druck-tiefe:.97;

  /* ---- PROMPT 34 (15.08.2026): Kopfzeile/Eingrenzen-Tafel/Fenster ----------------------------
     Eigene, im Auftrag wörtlich benannte Werte, die auf KEINEN bestehenden Wert dieser Datei
     treffen — als eigene Token statt als Rohwert in index.html, aus demselben Grund wie die
     P1-Zug-3-Ausnahmen (.est-tafel 28px u.a., s. tests/test_design_sperre.py GRENZEN["border-
     radius"]): die Sperre dort zählt jeden rohen px-Wert in static/index.html und darf nur
     SINKEN, nie wachsen — border-radius steht bereits auf ihrer Obergrenze (14/14, keine Reserve).
     Ein neuer Rohwert dort bräche den Test; ein neuer TOKEN hier nicht (tokens.css wird von der
     Sperre nicht gelesen). Bewegung entsprechend über eigene --d-*-Namen, damit
     test_bewegung_nur_token_oder_dokumentierte_ausnahme jede neue transition/animation weiterhin
     als "trägt nur var(--d-*)/var(--k-*)" durchlässt, ohne BEWEGUNGS_AUSNAHMEN anfassen zu müssen. */
  --d-schirm:300ms;      /* Eingrenzen-/Fenster-Hintergrund (Milchglas-Einblendung) */
  --d-tafel:360ms;        /* Eingrenzen-Tafel UND die zwei Fenster (§B4: "dieselbe Bewegung wie die Tafel") */
  --r-eg:16px;            /* Eingrenzen-Tafel + Quelle/Artikel-Fenster (§B3/§B4, eigene Ausnahme wie .est-tafel) */
  --r-blatt:22px;         /* PROMPT 58 §5: Meeting-Aufgaben-Blatt + Protokoll, eigene Ausnahme wie --r-eg (Auftragstext nennt 22px wörtlich) */
  --r-bz-neu:9px;         /* Quelle/Artikel-Knöpfe rechts in der Kopfzeile (§B2: "beide eckig, 9px Radius") */
  --bz-abstand:11px;      /* Abstand zwischen den Gruppen in der Kopfzeile (§B2: "Abstände 11px") */
  /* Kategorie-Töne, zart: für die Themen-Vorschläge/-Gruppen der Eingrenzen-Tafel gebraucht, aber
     NICHT hier neu angelegt — PROMPT 31 (Artikelkarte, parallel entstanden) hat exakt dieselben
     sechs Werte bereits weiter unten ergänzt (beide Prompts teilen dieselbe Farbtabelle). Eigene,
     zweite Deklaration wäre eine Dopplung (Station 3 der Merge-Steckliste) — s. dort. */

  /* ---- PROMPT 37 (18.08.2026): Artikel-Werkbank (Entwurf-Bearbeitungsansicht) -----------------
     Gleicher Grund wie PROMPT 34 oben: eigene, im Auftrag wörtlich genannte Maße, die auf keinen
     bestehenden Wert treffen, laufen als TOKEN statt als Rohwert in index.html (test_design_sperre
     GRENZEN zählt height/padding/gap/margin/border-radius/font-size als Rohwerte in index.html,
     nicht hier). Werte, die exakt einem Bestandstoken entsprechen (14px→--r-eg, 16px→--raum-4,
     12px→--r-gross, 40px→--h-knopf, 17px→--tx-kartentitel, 11px→--tx-klein u.a.), werden im
     Auftrag direkt wiederverwendet, nicht hier zweit-deklariert. */
  --wb-h-kopf:58px;              /* Kopfleiste der Werkbank (Teil B) */
  --wb-h-schritte:46px;          /* Schrittleiste (Teil B) */
  --wb-h-punkt-schritt:9px;      /* Zustandszeichen vor jeder Schrittmarke (Teil B) */
  --wb-r-abschnitt:14px;         /* Radius der weißen Abschnittsflächen links (Teil B) */
  --wb-raum-abschnitt:28px;      /* Abstand zwischen den Abschnitten links (Teil B) */
  --wb-h-wunschleiste-mobil:260px;  /* Änderungswunsch als Leiste unten, aufgeklappt (Teil B, <1180px) */
  --wb-h-freigabeleiste:64px;    /* Klebende Fußleiste mit Sichern/Freigeben (§I) */
  /* Zwei zusätzliche Bewegungswerte (Teil J), die auf keine bestehende --d-*-Dauer treffen —
     test_bewegung_nur_token_oder_dokumentierte_ausnahme verlangt AUSSCHLIESSLICH var(--d-*)/
     var(--k-*) in jeder transition/animation; ein neuer TOKEN hier erfüllt das (kein roher
     Zeit-/Kurven-Text in index.html), ein neuer Rohwert dort bräche den Test. */
  --wb-d-umschalter:340ms;   /* Umschalter (Ziel/Herkunft) gleiten, Originaltext-Höhe auf/zu */
  --wb-d-farbe:190ms;        /* "Farbwechsel überall": Fläche/Rand/Text, 180–200ms */
  --wb-r-kachel:10px;        /* Überschriftenzeile (§D) UND Bildkachel (§F) — dieselbe Zahl, ein Token */
  --wb-h-uez:52px;           /* Höhe einer Überschriften-Vorschlagszeile (§D) */
  --wb-h-haken-klein:20px;   /* Haken-Kreis auf der gewählten Überschrift (§D) */
  --wb-h-haken-gross:22px;   /* Haken-Kreis auf der gewählten Bildkachel (§F) — bewusst 2px größer */
  --wb-d-haken:240ms;        /* Haken-Auftritt aus scale(.86) auf Überschrift/Bildkachel (§J) */
  /* Eigene Schriftgrößen für Artikeltext/Caption in der Werkbank (§E1/§E2) — bewusst NICHT die
     alten .draft-reich .az-*-Regeln (16pt/11pt/13pt/11pt, für die frühere Ein-Spalten-Ansicht
     getunt): der Auftrag nennt eigene, glatte px-Werte, die davon leicht abweichen. */
  --wb-tx-artikeltitel:22px;    /* Artikel-Überschrift im Fließtext-Block */
  --wb-tx-zwischentitel:16px;   /* Zwischentitel */
  --wb-tx-artikel-fliess:15px;  /* Vorspann UND Fließtext — beide 15px laut Auftrag */
  --wb-tx-mini:10px;            /* Satznummern im Rand, Tastenzettel-Badge */
  --wb-h-kachel-icon:34px;      /* Stift-Kachel im Änderungswunsch (§E3) */
  --wb-h-umschalter:36px;       /* Segment-Umschalter Ziel (§E3) UND Herkunft (§F1) */
  --wb-h-pille:27px;            /* Bausteine-Pillen im Änderungswunsch (§E3) */

  /* ---- Freigabe-Karte: Raster und Höhen-Deckel (25.08.2026, Tobias' ToDo 1) ---------------------
     Auftrag wörtlich: „Layout so anpassen, dass drei Artikel GLEICHZEITIG übersichtlich
     dargestellt werden können ... (desktop responsive)". Gemessen war das nicht der Fall: drei
     Spalten standen zwar nebeneinander, eine Karte war aber 872 px hoch (bei 1600 px Fenster) —
     eine Zeile füllte mehr als einen Bildschirm, die Aktionsreihe lag unter der Faltkante. Die
     Höhe kam von der jeweils LÄNGSTEN Caption der Zeile; deckelt man die Karte, ist sie
     berechenbar.
     Kein Bestandstoken passte: --h-* sind Bedienelement-Höhen, keine Flächenmaße. */
  /* --- Ladevorschau der Freigabe-Karte (02.09.2026) ---------------------------------------
     Das Skelett des Freigabe-Reiters muss dieselbe Höhe einnehmen wie die Karte danach; im
     Browser gemessen war es 693px zu kurz (200px gegen 893px), s. skelettKarten() in
     index.html und den Reiter `freigabe` in pruefe_skelette.py.
     Diese vier Werte sind AM ECHTEN ELEMENT GEMESSEN, nicht aus dem Raster gewählt — sie sind
     die Entsprechung zu card-kicker, card-title (zweizeilig), einer Caption-Textzeile und der
     Link-Zeile im Caption-Kasten. Genau deshalb hängen sie an eigenen Tokens und nicht an
     --raum-* oder --h-*: ein Abstands- oder Bedienelement-Token hier zu verwenden wäre eine
     falsche Kopplung (dieselbe Begründung wie beim Laptop-Mock, s. Radien-Kommentar unten) —
     ändert sich die Schriftgröße der Caption, müssen diese Werte mitwandern, die Raster-Tokens
     aber nicht.
     Wer einen Wert hier ändert, lässt danach pruefe_skelette.py --reiter freigabe laufen. */
  --skel-fg-kicker:16px;          /* = card-kicker */
  --skel-fg-titel:43px;           /* = card-title auf zwei Zeilen (gemessen 42,9px) */
  --skel-fg-titel-abstand:6px;    /* = dessen Abstand nach oben */
  --skel-fg-capzeile:13px;        /* = eine Textzeile im Caption-Kasten */
  --skel-fg-caplink:44px;         /* = die Link-Zeile darin */

  /* --- Ladevorschau von „Redaktionsplan" (plan) und „Fertige Artikel" (fertig), 02.09.2026 ----
     Zwei Reiter, zwei EIGENE Kartenbauer — und beide bekamen bis hierher das Standard-Skelett:
     im Browser gemessen 296px gegen echt 663,8px (plan, größte Skelett-Abweichung im Haus) und
     gegen echt 196,4px (fertig, das Skelett war hier ZU HOCH). Warum es so lange unentdeckt
     blieb: in der REITER-Liste von pruefe_skelette.py stand `geplant` — ein Artikel-STATUS, kein
     Reiter. stageStatus() fällt für unbekannte Namen stumm auf „neu" zurück, gemessen wurde also
     eine Sichten-Liste unter falschem Namen, und der Bericht meldete „passt" (behoben in PR #441).

     ⚠️ NICHT derselbe Kartenbauer, auch wenn der Name das nahelegt: `plan` baut über
     redaktionsplanKarteBauen() (Termin/Live-URL/Caption), `fertig` über planKarteBauen()
     („Fertige Artikel", Caption-Anriss + 92px-Bildfach). Wer beide für eine Form hält, macht
     die eine Hälfte der Abweichung zwangsläufig größer.

     Was hier NICHT steht, ist Absicht: Bildfach (180px/92px), Chips-Zeile, Aktionszeile samt
     Oberabstand und die Polsterung des Caption-Kastens kommen aus den Klassen der ECHTEN Karte
     (.card-media, .chips, .card-p29 .card-actions, .plan-cap-text) — dieselbe Lehre wie bei der
     Freigabe-Karte oben: Bausteine statt Pixelzahlen, dann stimmt die Höhe bei jeder
     Fensterbreite von selbst. Getokenisiert ist nur, was ein LEERER Platzhalter nicht von sich
     aus hat: die Höhe einer Textzeile.
     Wer einen Wert ändert, lässt danach `pruefe_skelette.py --reiter plan fertig` laufen. */
  /* Abgeleitet, nicht gemessen: eine Titelzeile ist Schriftgröße × Zeilenhöhe der echten
     .card-title (16,5 × 1,3 = 21,45px). Ändert jemand die Kartentypografie, wandert der Wert
     mit — genau das kann eine eingetragene Pixelzahl nicht. */
  --skel-titel-eine:calc(var(--tx-karte-titel) * var(--tx-kartentitel-zh));
  /* Der Caption-Anriss in „Fertige Artikel" ist auf DREI Zeilen geklemmt (-webkit-line-clamp:3
     an .fa-caption-vorschau), Schrift --text-m bei Zeilenhöhe 1,5 → 3 × 21 = 63px. Auch das eine
     Ableitung: die Klemme ist der Grund für die Höhe, nicht die Textlänge.
     Drei Zeilen sind allerdings die OBERgrenze, nicht die feste Höhe: auf einer sehr breiten
     Karte (gemessen 1640px bei einem 1920er Fenster) passt derselbe Text in zwei Zeilen, der
     Anriss ist dann 42px und die Karte 176 statt 196,4px. 63px ist der Wert für alle geprüften
     Fensterbreiten von 900 bis 1440px und liegt damit am oberen Rand der Spanne — dieselbe
     Richtungswahl wie bei .skel-teaser („Sprung nach unten fällt weniger auf als nach oben"). */
  --skel-fa-vorschau:calc(var(--text-m) * var(--fa-vorschau-zh) * var(--fa-vorschau-zeilen));
  /* Die beiden Werte, aus denen sich das ergibt — und die `.fa-caption-vorschau` in index.html
     SELBST verbraucht. Sie stehen hier, damit es nicht zwei Zahlenreihen gibt: bis zur
     Zweitmeinung am 02.09.2026 standen 1.5 und 3 roh in der Regel und roh im calc() daneben,
     und eine Klemme auf vier Zeilen hätte die Karte 21px höher gemacht, ohne das Skelett zu
     bewegen. Jetzt zieht eine Änderung hier beide Seiten mit. */
  --fa-vorschau-zh:1.5;           /* Zeilenhöhe des Caption-Anrisses */
  --fa-vorschau-zeilen:3;         /* … und seine Klemme (-webkit-line-clamp) */
  /* Redaktionsplan, je eine Textzeile — am echten Element gemessen, weil die Schriftgrößen dieser
     drei Zeilen roh in ihren Klassen stehen (13 / 12,5 / 11px bei Zeilenhöhe 1,45). */
  --skel-plan-zeile13:18.9px;     /* eine Zeile 13px-Schrift (13 × 1,45 = 18,85) — sie trägt
                                     .plan-termin UND den Textkörper von .plan-live-input, ist
                                     also EIN Wert und nicht zwei (Zweitmeinung 02.09.2026) */
  --skel-plan-livelab:18.2px;     /* = .plan-live-lab, die Beschriftung über dem Eingabefeld */
  --skel-plan-caplab:16px;        /* = .plan-cap-lab („LINKEDIN-CAPTION") */
  /* Das Eingabefeld für die Live-URL — ABGELEITET, nicht gemessen: Polsterung aus --raum-2 (die
     echte Regel nimmt denselben Token), 2px Rahmen, dazu die Zeile darin. Vorher stand hier die
     gemessene Summe 36,9px; eine Änderung an --raum-2 (ein Haus-Token) hätte das echte Feld
     verschoben und den Platzhalter stehen gelassen.
     Der „Übernehmen"-Knopf daneben braucht kein Token — er ist --h-knopf-klein hoch. */
  --skel-plan-liveinput:calc(var(--raum-2) * 2 + 2px + var(--skel-plan-zeile13));
  /* Zeilenzahl der Titelzone im Redaktionsplan-Skelett, wie --fg-titel-zeilen bei der
     Freigabe-Karte: die echte Überschrift dort läuft zweizeilig (`.card-bild-gross .card-title`
     schnürt sie auf 66% Breite). */
  --skel-plan-titel-zeilen:2;
  /* Der Caption-TEXTKÖRPER ist der einzige Wert hier, der sich nicht ableiten lässt: .plan-cap-text
     hat bewusst KEINEN Höhen-Deckel (04.08.: die Caption ist der Text, der auf LinkedIn erscheint,
     wer sie prüfen soll, muss sie ganz sehen). Seine Höhe hängt damit allein an der Länge der
     jeweiligen Caption — 20 echte Karten streuen von 597,9 bis 708px Kartenhöhe. Ein Skelett kann
     diese Streuung nicht treffen, den MEDIAN aber schon, und genau gegen den Median prüft
     pruefe_skelette.py. Gemessener Median des Textkörpers: 176px. Dazu kommen aus .plan-cap-text
     selbst 24px Polsterung UND 2px Rahmen — der Kasten hat keine gesetzte Höhe, also greift
     `box-sizing:border-box` nicht und beides zählt oben drauf: 176 + 24 + 2 = 202px, genau der
     gemessene Wert. (Beim ersten Anlauf standen hier 178px, weil der Rahmen vergessen war — das
     Skelett war dann 2px zu hoch.) Die Balken darin sind reine Optik, die Höhe trägt der Kasten.

     ⚠️ GRENZE DIESES ANSATZES, gemessen und bewusst so gelassen: der Caption-Text fließt mit der
     Kartenbreite um, die Karte atmet also mit dem Fenster. Gemessen an derselben Datenlage —
     1640px Karte: 641,8px · 1160/1000px Karte: 663,8px · 744/796px Karte: 707,8px. Ein Skelett mit
     EINER Höhe kann nur ein Band treffen; 664px ist der Median über diese Spanne, also der beste
     Einzelwert, den es hier gibt. Wer eine Fenstergröße nachmisst und „daneben" findet, hat NICHT
     einen Fehler gefunden, sondern diese Grenze — bitte nicht auf die gerade gemessene Breite
     nachziehen, das verschiebt den Fehler nur auf die anderen.
     Die P48-Reiter haben das Problem nicht: dort deckelt --k-karte-min-p48 die Karte bei 276px
     nach unten, und der umfließende Anriss bleibt darunter (gemessen 276px bei allen sechs
     geprüften Fenstergrößen). „Fertige Artikel" und „Redaktionsplan" haben keinen solchen Boden. */
  --skel-plan-captext:176px;
  /* Die Balken IM Caption-Kasten. Reine Optik — die Höhe des Kastens trägt --skel-plan-captext
     darüber, diese Balken werden an seiner Unterkante abgeschnitten. Trotzdem ein eigener Wert
     und NICHT --skel-fg-capzeile: der gehört zur Freigabe-Karte, deren Caption eine andere
     Zeilenhöhe hat (20,9px gegen 20,25px hier). Ein Griff in den fremden Namensraum würde die
     Balken der einen Karte wandern lassen, wenn jemand die Schrift der anderen ändert. */
  --skel-plan-capzeile:13px;
  /* Flex-Grundbreite des Live-URL-Eingabefelds. Steht als Token da, weil ZWEI Stellen denselben
     Wert brauchen: die echte `.plan-live-input` und ihr Platzhalter im Skelett. Er ist nicht
     Kosmetik, sondern entscheidet, ab welcher Kartenbreite „Übernehmen" in die zweite Zeile
     umbricht — bräche die Vorschau an einer anderen Breite um als die Karte, wäre der Sprung
     zurück, nur eben nicht bei jeder Fenstergröße. */
  --plan-liveinput-basis:320px;
  --fg-titel-zeilen:2;          /* Titelzone der Freigabe-Karte, in Zeilen — nagelt die Höhe fest,
                                   damit die drei Visuals einer Zeile auf gleicher Höhe beginnen */
  --fg-caption-deckel:clamp(120px,calc(100svh - 740px),300px);
                                /* Höchsthöhe des Caption-Textkörpers in der Freigabe-Karte.
                                   Fensterhöhen-relativ, damit derselbe Wert auf einem flachen
                                   Laptop und auf einem 1440p-Schirm das Richtige tut; die 300px
                                   deckeln zusätzlich nach oben, sonst wächst die Karte auf einem
                                   sehr hohen Schirm wieder über jedes Maß.
                                   ⚠️ 02.09.2026 — VON `min(300px,26vh)` AUF `clamp()` GEÄNDERT.
                                   Gemeldet: „ich will, dass bei 100 % Bildschirmzoom die Karte
                                   genau so auf einen ganzen Bildschirm passt wie bei Zoom 90 %."
                                   Im Browser gegen den Probeserver nachgemessen (Playwright,
                                   1080p-Schirm, Karte beginnt bei y=88):
                                     100 % Zoom (1920×950):  Karte 876px, Platz 862px → PASST NICHT
                                      90 % Zoom (2133×1055): Karte 893px, Platz 967px → passt
                                   Genau der gemeldete Unterschied, und er ist knapp: 14px.
                                   Ursache ist die Bezugsgröße. `26vh` ist ein ANTEIL der
                                   Fensterhöhe und weiß nichts davon, dass der nicht kürzbare Teil
                                   der Karte eine FESTE Höhe hat (gemessen 629px: Kopf 65 +
                                   Visual 297 + Link-Zeile 44 + Aktionsreihe 47 + Polster 176).
                                   Ein Anteil wächst mit dem Fenster mit — der Bedarf darüber
                                   nicht. Deshalb jetzt aus dem echten Restplatz gerechnet:
                                     100svh − 740px  (= 629 fester Teil + 88 Oberkante + 23 Luft)
                                   Nachgerechnet: 950px Fenster → 210px Caption, Karte 839 ≤ 850 ✔ ·
                                   1055px → 300px (obere Grenze), Karte 929 ≤ 967 ✔.
                                   Der UNTERE Wert 120px ist neu und wichtig: ohne ihn wird der
                                   Ausdruck auf einem flachen Fenster negativ (700px → −40px) und
                                   der Caption-Kasten verschwindet ganz. `clamp` hält ihn bei
                                   120px — dann rollt die Seite, wie im Grenzfall unten
                                   beschrieben, statt den Text unlesbar zu machen.
                                   `svh` statt `vh`: gefragt ist die Höhe MIT sichtbaren
                                   Browserleisten, also der kleine Viewport. Auf dem Desktop sind
                                   beide gleich; der Unterschied schützt die Rechnung, falls das
                                   Werkzeug je auf einem Tablet geöffnet wird.

                                   Am Dienst nachgemessen (Kartenhöhe / Fensterhöhe): 1920×955 →
                                   916/955 ✔ · 1920×1080 → 948/1080 ✔ · 1600×1000 → 856/1000 ✔.
                                   (Diese Reihe ist vom 25.08. und beschreibt den ALTEN
                                   26vh-Deckel — als Historie stehengelassen, nicht als Ist-Stand.)
                                   GRENZE, bewusst dokumentiert statt weggerechnet: auf einem
                                   flachen 1366×657-Fenster ist die Karte 736px hoch, weil der
                                   NICHT kürzbare Teil (Kopf 81 + Visual 217 + Link-Zeile +
                                   Aktionsreihen = 565px) allein schon höher ist als das Fenster.
                                   Dort rollt die Seite ~80px — ein Deckel kann das nicht lösen,
                                   nur ein kleineres Visual, und dessen 3:2-Größe ist seit
                                   12.08. bindend („das Visual soll immer gleich groß sein"). */
  /* ---- Quellenmaterial von Hand (Tobias' ToDo 3, 25.08.2026) ---------------------------------- */
  --qm-b-marke:52px;            /* Spaltenbreite der Art-Marke „Zahl"/„Grafik" in der Liste —
                                   fest, damit beide Arten bündig untereinander stehen */

  --fg-link-zeilen:2;           /* „Hier geht's zum Artikel: <URL>" — geklammert, sonst schwankt die
                                   Boxhöhe mit der Slug-Länge (gemessen 2 bis 4 Zeilen) */
  --fg-caption-min:72px;        /* so viel Caption bleibt IMMER stehen, auch auf flachen Fenstern —
                                   darunter wäre der Rollbalken länger als der Lesebereich */
}

/* ---- Dunkel: eigene, gerechnete Stufen (Spec 9) ---------------------------------------------
   Nur Farben haben eine dunkle Entsprechung. Abstände (1.5), Radien (1.6), Schrift-Rollen (1.7)
   und Höhen (1.8) sind vom Thema unabhängig und kommen hier ausdrücklich NICHT vor. */
:root[data-theme="dark"]{
  /* 1.1 — Grund eine Stufe UNTER der Fläche, damit dieselbe Beziehung wie im Hellen gilt. */
  --grund:#131417;
  --flaeche:#1A1C21;
  --flaeche-hoch:#22252B;
  --text:#ECEDEF;               /* 13,7:1 */
  --text-leise:#9A9C9F;         /* 6,1:1 */
  --linie:#2E3138;
  --senke:#33353A;              /* dieselbe Stufe wie --line-2 dunkel: auf --flaeche (#1A1C21) sichtbar */
  /* 9.1 (Paket P3 Teil 3) — DIE Dunkel-Regel für Höhensprache: „Höhe trägt sich als Helligkeit,
     nicht als Schatten" (ein box-shadow leistet auf #131417 fast nichts). Eingesenkt wird darum
     DUNKLER als der Träger — umgekehrtes Vorzeichen zum Hellen, wo --senke heller als --flaeche
     ist. Alias auf --grund: exakt dieselbe Stufe, die schon die App-Grundfläche trägt (#131417
     auf #1A1C21) — keine neue Zahl, nur ein neuer Name für eine bestehende. Erhöhte/schwebende
     Flächen (--flaeche-hoch, #22252B) sind bereits die passende Gegenstufe und brauchen dafür
     KEINE Änderung; sie bekommen zusätzlich einen 1px rgba(255,255,255,.07)-Rand (s. .af-liste in
     der Auswahlfeld-Komponente unten) — das ist die zweite Hälfte derselben Regel. */
  --eingesenkt:var(--grund);

  /* 1.2 — eigens gerechnet: #2A2A84 käme auf dunklem Grund auf 2,04:1. Überfahren/Gedrückt gehen
     HELLER, weil auf dunklem Grund die Annäherung an Weiß die Bewegung ist. */
  --aktion:#3D46B8;             /* 7,7:1 weiß auf der Fläche */
  --aktion-ueber:#4A54CC;
  --aktion-gedr:#333BA0;
  --aktion-fokus:#8E97F0;       /* hell genug, um auf der Aktiv-Fläche #262A3D zu tragen */
  --aktiv-flaeche:#262A3D;
  --aktiv-rahmen:#3C4266;
  --wash:var(--aktiv-flaeche);
  --markenrand:#454C74;         /* eigens gerechnet, dieselbe Stufe-über-Rand-Logik wie 1.2 oben */
  --aus-inaktiv:#5A5D6B;
  --aktion-text:#8E97F0;        /* 6,4:1 — #3D46B8 als Text erreicht hier nur 2,2:1 */
  --gesperrt-flaeche:#23252A;
  --gesperrt-text:#5F6167;      /* 2,7:1, bewusst unter der Grenze */

  /* 1.3 — vier Bedeutungen, eigene dunkle Stufen. */
  --erfolg-text:#6BD79B;        /* 9,6:1 */
  --erfolg-flaeche:#16251C;
  --erfolg-rahmen:#2E7A50;
  --achtung-text:#E0A94A;       /* 8,0:1 */
  --achtung-flaeche:#2A2114;
  --achtung-rahmen:#7A5E23;
  --warnung-text:#F87171;       /* 6,2:1 — weiter exklusiv für Paywall und §7 UWG */
  --warnung-flaeche:#2B1718;
  --warnung-rahmen:#7A3436;
  --info-text:#8FB0EE;          /* 6,9:1 */
  --info-flaeche:#181D2A;
  --info-rahmen:#3B4A6B;

  /* 1.4 — aufgehellt, weil die hellen Töne auf #1A1C21 als 8px-Punkt nicht mehr auseinander-
     zuhalten sind. */
  --kat-tax-audit:#8CA3C2;
  --kat-private-markets:#AC93C1;
  --kat-legal:#A0A09C;
  --kat-wirtschaft:#CFA189;
  --kat-ki-tech:#7DB6B1;
  --kat-karriere:#D298A9;

  /* PROMPT 31, dunkle Fassung — der Prompt nennt nur die hellen Werte (§6); diese sechs sind eine
     eigene, in sich konsistente Herleitung (dieselbe Idee wie --flaeche-hoch: ein sehr dunkler,
     leicht zum Ressortton hin verschobener Fond statt eines hellen Pastells, das auf #1A1C21
     grell stünde). Kein Bestandswert wird dafür verändert — nur neu ergänzt. */
  --kat-tax-audit-zart:#1E2530;
  --kat-private-markets-zart:#241E2C;
  --kat-legal-zart:#242422;
  --kat-wirtschaft-zart:#2B2118;
  --kat-ki-tech-zart:#1B2624;
  --kat-karriere-zart:#2B1E24;

  /* 1.6 — nur die Füllung hat eine dunkle Stufe, die Radien nicht. */
  --skelett-fuellung:#23252A;
}

/* ##############################################################################################
   SUCHLEISTE — EIN Baustein für JEDES Suchfeld (04.08.2026)
   ##############################################################################################
   Auftrag Tobias: „Alle Suchleisten auf der gesamten Website sollen einheitlich gestaltet sein …
   Höhe, Breite, Abstände, Rahmen, Rundungen, Typografie, Positionierung, animierte Punkte,
   Interaktionsverhalten." Maßstab ist die globale Suche in der Topbar des Dashboards.

   Warum HIER und nicht nur in index.html: die Suchfelder verteilen sich über fünf Dateien
   (index.html, quellen.html, medien.html, verteiler.html, kapazitaet.html). „Überall gleich" kann
   nur eine Datei versprechen — tokens.css ist die, die alle Nebenseiten schon laden.
   index.html bindet tokens.css seit dem 04.08. sehr wohl ein (Zeile 27) — ändert an dieser Stelle
   nichts, weil index.html in seinem eigenen inline-Stilblock dieselben Custom Properties in einem
   zweiten :root-Block erneut setzt (Kaskade: der spätere Block gewinnt). Beide Fassungen sind
   wortgleich zu halten; ändert sich hier ein Wert, muss er dort mitgeändert werden.

   Die wippenden Punkte (.pkt-wrap/.pkt-ph) sind Teil des Bausteins, aber nur in index.html
   verdrahtet — dort liegt `punkteFeld()`. Auf den Nebenseiten bleibt der echte `placeholder`
   stehen; Höhe, Rahmen, Radius, Lupe und Fokusverhalten sind trotzdem identisch, und genau das
   war der Auftrag. Ein zweites Mal dieselbe JS-Mechanik in vier Dateien zu kopieren wäre der
   sichere Weg zu vier Fassungen davon.
   ============================================================================================== */
:root{
  --such-h:36px;             /* eine Höhe, überall — auch neben 32er-Knöpfen */
  --such-r:9px;              /* zwischen --r-mittel (8) und --r-gross (12): Feld, keine Karte */
  --such-fs:var(--tx-bedienung);   /* Zug 1 (13.08.) nannte das schon Alias, hatte es aber nur in
     index.htmls eigener :root-Kopie umgesetzt -- hier nachgezogen (P1 Zug 3, gleicher Anlass). */
  --such-pad-l:36px;         /* Platz für die Lupe: 12 Rand + 16 Symbol + 8 Luft */
  --such-pad-r:12px;
}
.suchleiste{position:relative;display:flex;align-items:center;flex:0 0 auto;
  width:300px;max-width:42vw;}
.suchleiste.breit{width:100%;max-width:none;flex:1 1 240px;min-width:160px;}
/* Nachkomme statt Kind: wo die wippenden Punkte laufen, sitzt zwischen Hülle und Feld noch
   `.pkt-wrap`. Mit `>` verlöre genau das Feld sein Aussehen, das die Punkte zeigt. */
.suchleiste input{box-sizing:border-box;width:100%;height:var(--such-h);
  padding:0 var(--such-pad-r) 0 var(--such-pad-l);border-radius:var(--such-r);
  border:1.5px solid var(--line-2);background:var(--surface2);color:var(--ink);
  font-family:inherit;font-size:var(--such-fs);font-weight:500;outline:none;
  transition:border-color .15s, background .15s, box-shadow .15s;}
.suchleiste .pkt-wrap{display:block;width:100%;}
.suchleiste input::placeholder{color:var(--faint);}
/* Das native Kreuz von type=search fliegt raus: nur in WebKit vorhanden, dort auf eigener Höhe —
   das einzige uneinheitliche Element in einem Baustein, dessen Zweck Einheitlichkeit ist. */
.suchleiste input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none;}
.suchleiste input:hover{border-color:var(--line-2);background:var(--surface);}
.suchleiste input:focus{border-color:var(--navy);background:var(--surface);
  box-shadow:0 0 0 3px rgba(42,42,132,.10);}
/* `z-index:2` ist PFLICHT: `.pkt-wrap` (Hülle der wippenden Punkte) ist selbst
   `position:relative` und steht nach der Lupe — ohne z-index deckt der Feld-Hintergrund die Lupe ab. */
.suchleiste-ic{position:absolute;z-index:2;left:12px;top:50%;transform:translateY(-50%);
  width:16px;height:16px;color:var(--faint);pointer-events:none;transition:color .15s;}
.suchleiste:focus-within .suchleiste-ic{color:var(--navy);}
.suchleiste-ic svg{display:block;width:16px;height:16px;}
.suchleiste .pkt-ph{left:var(--such-pad-l);font-size:var(--such-fs);}

/* ##############################################################################################
   AUSWAHLFELD — EIN eigener Baustein statt natives <select> (Paket P3 Teil 1, 13.08.2026)
   ##############################################################################################
   Ersetzt an 18 Fundstellen (index.html, quellen.html, medien.html) das native <select>: es
   ignoriert jedes Token (Systemschrift, Browser-Radius/-Rand/-Höhe, eigener Pfeil) und bleibt im
   dunklen Thema hell — der einzige Baustein, der auf jedem Betriebssystem anders aussieht. Baumarkup
   und Verhalten liefert /static/auswahlfeld.js (auswahlfeldErsetzen/auswahlfeldBauen); hier nur die
   Optik. Von allen drei Dokumenten geladen, aus demselben Grund wie `.suchleiste` oben: EINE
   Formsprache statt drei Kopien, die bei der nächsten Änderung auseinanderlaufen.

   Grammatik (Spec „Die EINE Auswahl-Formel", design-review/audit-2026-08-12/PROMPT-CLAUDE-DESIGN.md):
   „Eingesenkt heißt lesen oder eingeben, gefüllt heißt drücken." Der Auslöser ist darum eingesenkt
   (--eingesenkt, s.o.), nie gefüllt — Navy ist Handlung, nicht Zustand. Quittiert wird über eine
   gefüllte Haken-Glyphe in --text, nicht über Navy. */
.auswahlfeld{position:relative;display:inline-flex;vertical-align:middle;max-width:100%;}
.auswahlfeld[hidden]{display:none;}

.af-trigger{display:inline-flex;align-items:center;justify-content:space-between;gap:var(--raum-2);
  height:var(--h-knopf-klein);padding:0 var(--pad-knopf-klein);max-width:100%;
  border:0;border-radius:var(--r-klein);background:var(--eingesenkt);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.05);
  font-family:inherit;font-size:var(--tx-bedienung);font-weight:var(--tx-bedienung-gew);
  line-height:var(--tx-bedienung-zh);color:var(--text);cursor:pointer;white-space:nowrap;
  transition:background-color .15s,box-shadow .15s,color .15s;}
/* Dunkel: Schatten leistet auf #131417 fast nichts (Teil 3, Höhensprache als Helligkeit statt
   Schatten) — die dunklere Fläche selbst (--eingesenkt→--grund im Dunkel-Scope) trägt allein. */
:root[data-theme="dark"] .af-trigger{box-shadow:none;}
.af-trigger:disabled{background:var(--gesperrt-flaeche);color:var(--gesperrt-text);
  box-shadow:none;cursor:default;}
.af-trigger:focus-visible{outline:2px solid var(--aktion-fokus);outline-offset:2px;}
.af-wert{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.af-pfeil{flex:none;display:inline-flex;width:14px;height:14px;color:var(--text-leise);
  transition:transform var(--d-klein) var(--k-aus);}
.af-trigger[aria-expanded="true"] .af-pfeil{transform:rotate(180deg);}
.af-pfeil svg{display:block;width:14px;height:14px;}

/* Liste: eigene Ebene (Paket P4, 13.08.) — lieh sich vorher die Zahl des Überlaufmenüs
   (`.tb-menu`, z-index 210), ist aber selbst ein Aufklapper wie jedes Menü/jede Glocke/jedes
   Profil. Bewegung bleibt vom `.popover`-Muster geliehen (160ms, --k-aus, dieselbe Kurve/Dauer).
   `transform-origin` an der Ecke des Auslösers (Auftrag P3), abweichend vom `.popover`-Normalfall
   (Mitte). */
.af-liste{position:absolute;top:calc(100% + 4px);left:0;z-index:var(--ebene-aufklapper);
  min-width:100%;width:max-content;max-width:320px;max-height:min(60vh,400px);overflow-y:auto;
  margin:0;padding:var(--raum-2) 0;list-style:none;background:var(--flaeche-hoch);
  border-radius:var(--r-gross);transform-origin:top left;
  /* P5 Moment 4: das oben angekündigte Geliehene tatsächlich eingelöst — bis dahin stand hier nur
     der transform-origin, die Fläche selbst schaltete über [hidden] ohne jede Bewegung um. */
  animation:popoverEin var(--d-klein) var(--k-aus);}
.af-liste[hidden]{display:none;}
/* Ausflug an <body>: solange die Liste dort hängt (s. `positioniere()` in auswahlfeld.js),
   liegt sie außerhalb der Stapel-Ebene ihres Dialogs und braucht die einzige Ebene, die
   über dem Dialog steht. --ebene-toast ist genau dafür da („liegt über ALLEM, auch über dem
   Dialog") — eine siebte Ebene wäre laut Sperre ein Strukturproblem, keine neue Zahl.
   Trifft eine echte Meldung dazu, gewinnt sie über die Dokumentreihenfolge: der Toast wird
   später an <body> gehängt. */
.af-liste.af-frei{z-index:var(--ebene-toast);}
@media (prefers-reduced-motion:reduce){ .af-liste{animation:none;} }
:root[data-theme="dark"] .af-liste{
  /* Dieselbe Regel wie beim Auslöser: Höhe als Helligkeit. Zusätzlich der 1px-Rand aus Teil 3 für
     erhöhte/schwebende Flächen im Dunkeln (`rgba(255,255,255,.07)`), als inset-Ring statt Rahmen,
     damit `border-radius` nicht durchbrochen wird. */
  box-shadow:0 10px 30px -8px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.35),
    inset 0 0 0 1px rgba(255,255,255,.07);
}

.af-option{display:flex;align-items:center;height:var(--h-knopf-klein);
  padding:0 var(--raum-3) 0 0;margin:0 var(--raum-1);border-radius:var(--r-klein);
  font-family:inherit;font-size:var(--tx-bedienung);color:var(--text);cursor:pointer;}
.af-option[aria-disabled="true"]{color:var(--text-leise);cursor:default;}
/* Überfahren/aktiv: dieselbe eingesenkte Fläche wie der Ruhezustand des Auslösers oben, hier aber
   in ihrer ursprünglichen P2-Bedeutung (Überfahren, nicht Ruhe) — deshalb bewusst --senke direkt,
   nicht --eingesenkt. */
.af-option:not([aria-disabled="true"]):hover,.af-option.ist-aktiv{background:var(--senke);}
.af-haken{flex:none;width:14px;height:14px;margin-right:var(--raum-1);display:inline-flex;
  align-items:center;color:var(--text);}
.af-haken svg{display:block;width:14px;height:14px;}

/* ≤1024px (Paket P3 Teil 2, s.u. .bedienzeile): keine Sonderregel nötig — das Auswahlfeld ist
   `inline-flex` und schrumpft/scrollt mit der Bedienzeile mit wie jedes andere Fach. */

/* ##############################################################################################
   SKELETT — allgemein verfügbar (Paket P5, Moment 6, 14.08.2026)
   ##############################################################################################
   Dieselbe Basis wie das ausgereifte Kartenskelett in index.html (Schimmer-Farben/-Radius, seit
   31.07. am echten Browser gemessen) — hier bewusst NOCH EINMAL als eigenständige, minimale
   Kopie statt eines Umbaus: index.html trägt daneben ein Dutzend eng an Kartenmaße gemessener
   Unterklassen (.skel-title, .skel-teaser, …), die nichts mit anderen Seiten zu tun haben. Ein
   Verschieben hätte dieses austarierte System angefasst, ohne einen Zugewinn für die anderen
   Seiten zu bringen — die geteilte Basis (`.skel`/`.skel-line`) reicht ihnen. Bewusste, kleine
   Redundanz statt eines riskanten Umbaus unter Zeitdruck.
   `.skel-line` ersetzt jeden „Lädt …"/„Wird geladen …"-Text auf Seiten außerhalb von index.html
   (und an generischen Stellen innerhalb): ein Text verspricht nichts über die Menge, ein
   Skelett zeigt sie — auch wenn es hier nur eine austauschbare Zeilenform ist, nicht die exakte
   Endform (die kennt nur index.html je Kartentyp). */
@keyframes skel-shimmer{ 0%{background-position:-400px 0;} 100%{background-position:400px 0;} }
.skel{background:#EFEEEA;background-image:linear-gradient(90deg,#EFEEEA 0px,#F7F6F3 200px,#EFEEEA 400px);
  background-size:800px 100%;border-radius:var(--r-klein);animation:skel-shimmer 1.3s infinite linear;}
.skel-line{height:12px;margin:var(--raum-2) 0;}
@media (prefers-reduced-motion:reduce){ .skel{animation:none;} }

/* ##################################################################################################
   GEMEINSAMER RAHMEN — Paket P6 (14.08.2026), Zug 2
   ##################################################################################################
   Sidebar/Kopfzeile/Seitenkopf/Bedienzeile/Knopfrollen für die sieben Nebenseiten
   (quellen/medien/verteiler/kapazitaet/leitung/report/portal), damit sie dieselbe Sidebar und
   denselben Kopf wie das Board tragen, OHNE index.html anzufassen (P6-Auftrag: „Die Dateien
   bleiben getrennt — index.html wird nicht zum Sammelbecken"). index.html trägt seine eigene,
   inline gebaute Fassung dieser Bausteine unverändert weiter (dort teils mit Aliasnamen/
   Rollen-Legacy, die die Nebenseiten nicht brauchen) — Werte hier sind identisch zu index.html,
   wo ein Vergleich sinnvoll ist (Knopfrollen, Bedienzeile), oder neu (`.rahmen-kopf`/`.seitenkopf`:
   von Zug 1 gemessen als „Kopfzeile 56/Seitenkopf 64" dokumentiert, aber nirgends als echter
   Baustein gebaut — hier zum ersten Mal).

   report.html/portal.html laden dieses Stylesheet zwar (Zug 2 zieht sie auf tokens.css, s. dort),
   binden aber NUR die Kopf-/Knopf-/Bewegungs-Bausteine ein, NICHT die Sidebar: beide werden ohne
   Anmeldung an externe Kund:innen ausgeliefert (server.py `_send_freigegebener_report`/
   `_send_portal`, `/r/<token>`/`/k/<token>`) — die interne Redaktions-Navigation (Sichten/
   Freigabe/Kosten/…) hätte dort nichts zu suchen und liefe für jeden Link auf eine Anmelde-
   Weiche. Entschieden ohne Rückfrage zu blockieren (sicherer Standardweg, s. PR-Text), aber
   ausdrücklich vorgelegt, nicht still entschieden.
   ================================================================================================ */

/* ---- Die äußere Hülle (Sidebar + Inhaltsspalte nebeneinander) — nachgezogen (Zweitmeinung vor
   dem Merge, 14.08.): stand identisch in allen fünf Nebenseiten mit Sidebar, statt hier zu stehen
   wie der Rest des Rahmens. Zwei Zeilen, keine Variable, aber genau die Sorte Kopie, die dieses
   Paket eigentlich auflösen soll. */
.shell{display:flex;align-items:flex-start;}
.shell-main{flex:1 1 auto;min-width:0;min-height:100vh;display:flex;flex-direction:column;}

/* ---- Kopfzeile (56px) + Seitenkopf (64px) — die zwei Bänder, die vorher nur ein Kommentar
   waren. Eine sticky Topbar (Logo/Status/Werkzeuge), darunter ein Seitentitel-Band. Eigene
   Klassennamen (`.rahmen-*`) statt `.header`/`.header-inner` aus index.html zu recyceln: index.html
   binden diese Namen bereits an ANDERE Werte (padding, kein fester height), ein gemeinsamer Name
   mit widersprüchlicher Regel je Datei wäre die Sorte Falle, die P1-P5 gerade aufgeräumt haben. */
.rahmen-kopf{
  height:var(--h-kopf);display:flex;align-items:center;
  padding:0 var(--raum-7);gap:var(--raum-5);
  background:var(--flaeche);border-bottom:1px solid var(--linie);
  position:sticky;top:0;z-index:var(--ebene-klebend);box-sizing:border-box;
}
.rahmen-kopf .logo{font-family:var(--schrift);font-size:19px;font-weight:700;
  letter-spacing:.4px;white-space:nowrap;color:var(--text);flex:none;}
.rahmen-kopf .logo .news{color:var(--navy);}
/* Trägt heute nur das Logo — kein Aufklapper verdrahtet, darum bisher kein Fehler sichtbar.
   WARNUNG (18.08., aus PR #212): `.rahmen-kopf` ist wie `.header` in index.html sticky + trägt
   selbst einen z-index, macht sie also zu einem eigenen Stapelkontext. Zieht hier je ein
   Profil-/Glocken-artiger Aufklapper ein, kann er NIE über eine gleichrangige `.bedienzeile`
   (o.ä., ebenfalls --ebene-klebend) hinausragen, unabhängig vom eigenen z-index — exakt der
   Fehler, den PR #212 in index.html behoben hat. Fix wäre derselbe: `.rahmen-kopf` auf
   `--ebene-aufklapper` heben, keine neue Zahl. */
.rahmen-kopf-rechts{margin-left:auto;display:flex;align-items:center;gap:var(--raum-3);}

.seitenkopf{
  height:var(--h-seitenkopf);display:flex;align-items:center;justify-content:space-between;
  flex-wrap:wrap;gap:var(--raum-3) var(--raum-5);
  padding:0 var(--raum-7);background:var(--flaeche);border-bottom:1px solid var(--linie);
  box-sizing:border-box;
}
.seitenkopf h1{margin:0;font-family:var(--schrift);
  font-size:var(--tx-seitentitel);font-weight:var(--tx-seitentitel-gew);
  line-height:var(--tx-seitentitel-zh);color:var(--text);}
.seitenkopf .seitenkopf-meta{font-size:var(--tx-leise);color:var(--text-leise);
  font-weight:var(--tx-leise-gew);}
.seitenkopf-aktionen{display:flex;align-items:center;gap:var(--raum-3);flex:none;}

/* ---- Inhaltsbreite (1240px, Seitenrand 32px) — dieselben Werte wie `.wrap`/`.header-inner` in
   index.html (dort bereits genau 1240/var(--raum-7), gegengeprüft P6 Zug 1). Eigener Name, damit
   eine Nebenseite ihn einbinden kann, ohne index.htmls interne `.wrap`-Kaskade zu erben. */
/* `width:100%` PFLICHT neben `max-width` (gemessen, nicht vermutet, P6 Zug 2): als Flex-Kind von
   `.shell-main` rechnet der Auto-Größenalgorithmus ohne explizite Breite über den Inhalt statt
   über den verfügbaren Platz — gerendert kamen so 1023px heraus, nicht 1240px, obwohl `max-width`
   korrekt gesetzt war. Mit `width:100%` steht immer `min(100% des Elternteils, 1240px)`. */
.rahmen-inhalt{width:100%;max-width:1240px;margin:0 auto;
  padding:var(--raum-6) var(--raum-7) var(--raum-7);}
/* Oberkante des Inhalts, 24px unter der Bedienzeile/dem Seitenkopf (Auftrag) — deckt sich mit
   `--raum-6` oben, eigene Regel nur zur Lesbarkeit des Namens. */

/* ---- Bedienzeile (48px, fünf feste Fächer) — UNVERÄNDERT aus index.html/P3 übernommen (exakt
   dieselben Klassennamen/Werte, damit „dieselbe Bedienzeile" nicht nur behauptet, sondern
   dieselbe Regel ist). `top:56px` passt jetzt zu `--h-kopf`, nicht mehr zu einem geratenen Wert. */
.bedienzeile{
  height:var(--h-bedienzeile);position:sticky;top:var(--h-kopf);z-index:var(--ebene-klebend);
  display:flex;align-items:center;gap:var(--raum-4);
  padding:0 var(--raum-1);background:var(--grund);border-bottom:1px solid var(--linie);
  box-sizing:border-box;
}
@media (max-width:1024px){
  .bedienzeile{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;padding:0 var(--raum-4);}
  .bedienzeile::-webkit-scrollbar{display:none;}
  .bz-fach,.bz-trenner{flex:0 0 auto;}
}
.bz-fach{display:flex;align-items:center;gap:var(--raum-3) var(--raum-4);min-width:0;}
.bz-fach[hidden]{display:none;}
.bz-filter{position:relative;flex:1 1 auto;flex-wrap:wrap;}
.bz-suche{flex:0 0 auto;}
.bz-trenner{width:1px;height:var(--raum-5);background:var(--linie);flex:0 0 auto;align-self:center;}
.bz-trenner[hidden]{display:none;}
.bz-ansicht{flex:0 0 auto;}
.bz-rechts{flex:0 0 auto;margin-left:auto;}
.bz-zahl{font-size:var(--tx-leise);font-weight:var(--tx-leise-gew);color:var(--text-leise);
  white-space:nowrap;}
.bz-zahl:empty{display:none;}

/* ---- Knopfrollen (Paket P2) — nur die vier kanonischen Namen, keine Alt-Aliasse: die Nebenseiten
   hatten eigene, bespoke Knopf-CSS (button.tun, .knopf, .btn im lokalen Stilblock je Seite), keine
   der 39 historisch gewachsenen index.html-Klassen zu ersetzen. */
.btn-haupt,.btn-zweit,.btn-geist,.btn-icon{
  font-family:var(--schrift);cursor:pointer;text-decoration:none;
  display:inline-flex;align-items:center;justify-content:center;gap:var(--raum-1);white-space:nowrap;
  transition:background var(--d-zustand) var(--k-zustand),border-color var(--d-zustand) var(--k-zustand),
    color var(--d-zustand) var(--k-zustand),transform var(--d-zustand) var(--k-zustand);
}
.btn-haupt,.btn-zweit,.btn-geist{
  font-size:var(--tx-bedienung);font-weight:var(--tx-bedienung-gew);line-height:1;
  border-radius:var(--r-mittel);border:1px solid transparent;
}
.btn-haupt:active:not(:disabled),.btn-zweit:active:not(:disabled),.btn-geist:active:not(:disabled),
.btn-icon:active:not(:disabled){transform:scale(var(--druck-tiefe,.97));}
/* Rolle HAUPT: die eine Hauptaktion je Karte/Dialog/Seitenkopf. */
.btn-haupt{height:var(--h-knopf);padding:0 var(--raum-4);border-color:var(--aktion);
  background:var(--aktion);color:#fff;}
.btn-haupt:hover:not(:disabled){background:var(--aktion-ueber);border-color:var(--aktion-ueber);}
.btn-haupt:active:not(:disabled){background:var(--aktion-gedr);border-color:var(--aktion-gedr);}
.btn-haupt:disabled{background:#D8D8E4;border-color:#D8D8E4;color:#fff;cursor:default;}
/* Rolle ZWEIT: gleichrangige Wahl, Fläche + 1px Rand. */
.btn-zweit{height:var(--h-knopf-klein);padding:0 var(--raum-3);
  background:var(--flaeche);color:var(--text);border-color:var(--linie);}
.btn-zweit:hover:not(:disabled){border-color:var(--navy-wash-rand);background:#FBFBFE;color:var(--navy);}
.btn-zweit:active:not(:disabled){border-color:var(--navy);background:var(--navy-wash);}
.btn-zweit:disabled{border-color:var(--gesperrt-flaeche);color:var(--gesperrt-text);
  background:var(--flaeche);cursor:default;}
/* Rolle GEIST: beiläufige Aktion, keine Fläche im Ruhezustand. */
.btn-geist{height:var(--h-knopf-klein);padding:0 var(--raum-3);
  background:transparent;color:var(--text);border-color:transparent;}
.btn-geist:hover:not(:disabled){background:var(--senke);}
.btn-geist:active:not(:disabled){background:var(--linie);}
.btn-geist:disabled{color:var(--gesperrt-text);background:transparent;cursor:default;}
/* Icon-Knopf: Geist-Farbgebung, quadratische Trefferfläche. */
.btn-icon{position:relative;width:var(--h-knopf-klein);height:var(--h-knopf-klein);padding:0;
  border:0;background:transparent;border-radius:var(--r-mittel);color:var(--muted);}
.btn-icon::after{content:"";position:absolute;inset:-4px;}
.btn-icon:hover:not(:disabled){background:var(--senke);color:var(--text);}
.btn-icon:active:not(:disabled){background:var(--linie);}
.btn-icon:disabled{opacity:.4;cursor:default;background:transparent;}

/* ---- Sidebar (280px) — dieselben Klassennamen/Werte wie index.html's `.sidebar`, OHNE die
   Laufzeit-Dichteanpassung (`sidebarDichteAnpassen()`/`--sb-d` per JS): die Nebenseiten tragen eine
   kurze, FESTE Liste (12 Board-Einträge + Werkzeuge-Gruppe), die nie über die Fensterhöhe hinaus
   wächst — die Dichte-Suche wurde für index.htmls variable, rollenabhängige Länge gebaut, hier
   unnötig. `--sb-d` bleibt fest auf 0.4 (der eigentliche Deckel des Reglers, s. index.html-
   Kommentar „DECKE BEI 0.4 STATT 1") statt von JS gesetzt — identische Optik zum geräumigsten
   Zustand des Boards, nie zu dessen eng gerechneten Fassungen (die hier nie gebraucht werden). */
.sidebar{
  --sb-d:0.4;
  --sb-luft-1:max(1px, calc(1.5px + 2.5px * var(--sb-d)));
  --sb-luft-2:max(2px, calc(3px   + 5px   * var(--sb-d)));
  --sb-luft-3:max(3px, calc(5px   + 9px   * var(--sb-d)));
  --sb-luft-4:max(4px, calc(8px   + 12px  * var(--sb-d)));
  --sb-item-font:min(13.5px, max(12.5px, calc(12.5px + 5px * var(--sb-d))));
  --sb-grp-font:min(10px, max(9.5px, calc(9.5px + 3.75px * var(--sb-d))));
  width:280px;flex:none;background:var(--surface2);border-right:1px solid var(--line);
  display:flex;flex-direction:column;gap:0;
  padding:var(--sb-luft-4) 12px var(--sb-luft-4);
  position:sticky;top:0;height:100vh;overflow-y:auto;overflow-x:hidden;
}
.sidebar > *{flex-shrink:0;}
.sidebar .logo{padding:0 var(--raum-2);margin-bottom:var(--sb-luft-4);font-size:19px;line-height:1.2;
  font-family:var(--schrift);font-weight:700;color:var(--text);}
.sidebar .logo .news{color:var(--navy);}
.sb-nav{display:flex;flex-direction:column;gap:var(--sb-luft-1);}
.sb-group-label{font-size:var(--sb-grp-font);font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--faint,var(--text-leise));
  padding:0 var(--raum-3) var(--sb-luft-1);line-height:1.3;}
.sb-divider{height:1px;background:var(--linie);margin:var(--sb-luft-3) 4px var(--sb-luft-2);}
.sb-item{
  position:relative;display:flex;align-items:center;gap:var(--raum-2);width:100%;text-align:left;
  text-decoration:none;height:var(--h-sb-eintrag);line-height:1;
  border:0;border-left:3px solid transparent;background:transparent;border-radius:0 12px 12px 0;
  padding:0 var(--pad-sb-eintrag);cursor:pointer;font-family:var(--schrift);
  font-size:var(--sb-item-font);font-weight:var(--tx-bedienung-gew);color:var(--text-leise);
  transition:background var(--d-zustand) var(--k-zustand),color var(--d-zustand) var(--k-zustand),
    border-color var(--d-zustand) var(--k-zustand);
}
.sb-item:hover{background:var(--flaeche);color:var(--text);}
.sb-item.active{background:var(--flaeche);color:var(--text);border-left-color:var(--navy);
  font-weight:700;}
.sb-ico{flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:17px;height:17px;color:inherit;}
.sb-ico svg{display:block;}
.sb-txt{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* line-height:1.3 wie in index.html (derselbe Bug, dieselbe Ursache): line-height:1 ließ
   overflow:hidden den Bauch von Unterlängen ("Nutzung") abschneiden. Auf `.sb-item .sb-txt`
   verengt, wortgleich zu index.html — hier gibt es die Kategorie-Chips (`.sb-kat`) nicht, die
   dort der Grund für die Verengung waren, aber dieselbe Klasse soll auf beiden Seiten dasselbe
   bedeuten. Bekommt eine Nebenseite später Chips, erbt sie nicht still eine engere Zeile. */
.sb-item .sb-txt{line-height:1.3;}
.sb-item.sb-bald{cursor:default;color:var(--faint,var(--text-leise));opacity:.72;}
.sb-item.sb-bald:hover{background:transparent;color:var(--faint,var(--text-leise));}

/* ##############################################################################################
   PAKET P29 (14.08.2026) — DIE EINE ARTIKELKARTE
   ##############################################################################################
   Warum dieser Abschnitt überhaupt existiert: PROMPT 29 nennt Maße, die es in den P1-Achsen nicht
   gibt — Radius 14, Kartenabstand 10, Innenabstand 18/14, Bild 116×74, Kicker-Sperrung .06em.
   Gleichzeitig verlangt seine Abnahme (§7.11) „Jede verwendete Farbe steht in den Achsen aus P1.
   Kein Wert außerhalb." Beides zusammen ist nur auf EINE Art erfüllbar: die genannten Zahlen sind
   verbindlich (§0: „Wo eine Zahl steht, ist sie zu übernehmen, nicht zu interpretieren"), also
   werden sie zu benannten Achsen-Werten gemacht statt als Rohwerte in Klassen zu stehen. Damit
   bleibt die Rohwert-Sperre (tests/test_design_sperre.py) unangetastet — sie zählt Rohwerte in
   index.html, und dort steht nach diesem Paket kein einziger neuer.

   ⚠️ Namensregel für alles, was hier dazukommt: die Sperre liest den QUELLTEXT mit den Mustern
   `padding[a-z-]*: *[0-9]+px`, `gap: *…`, `margin[a-z-]*: *…`, `border-radius: *…`,
   `[^-a-z]height: *…`, `font-size: *…`. Ein Token namens `--x-gap:10px` enthält wörtlich
   „gap:10px" und würde SICH SELBST als Rohwert zählen. Deshalb heißt der Kartenabstand
   `--k-karten-luft` und nicht `--k-karten-gap`, die Bildhöhe `--k-bild-h` und nicht
   `--k-bild-height`. Wer hier ein Token ergänzt, prüft den Namen gegen diese sechs Muster.
   (Derselbe Fehlertyp wie in tests/CLAUDE.md unter „Wächter-Tests lesen den Quelltext".)
   ============================================================================================== */
:root{
  /* ---- Geometrie der Karte (§1.1) --------------------------------------------------------- */
  --r-karte:14px;               /* Kartenradius — zwischen --r-gross (12) und der Pille */
  --r-bild:10px;                /* Bild in der Karte (§1.2) */
  --k-karten-luft:10px;         /* Abstand zwischen zwei Karten */
  /* PROMPT 31 §2: 16/15px statt der bisherigen 18/14 — eigene Werte aus dem Claude-Design-Prompt,
     bewusst NICHT auf die Bestandswerte gerundet (Tobias 15.08.: das alte Tokenraster gefiel ihm
     nicht, der neue Prompt gilt eins zu eins). --k-karte-pad-t neu, weil oben bisher --raum-4
     (die geteilte Abstandsleiter) mitbenutzt wurde — 15px ist kein Leiterwert, ein eigenes Token
     vermeidet einen stillen Seiteneffekt auf jeden anderen --raum-4-Verbraucher. */
  --k-karte-pad-t:15px;         /* Innenabstand oben */
  --k-karte-pad-x:16px;         /* Innenabstand links/rechts */
  --k-karte-pad-b:15px;         /* Innenabstand unten */
  --k-kante-b:3px;              /* Kantenstrich: eine LINIE, keine Fläche */
  /* PROMPT 31 §1: 142×92 statt 116×74 — Bildplatz wird mit diesem Paket zum PFLICHT-Element
     (s. .card-media-leer weiter unten), darum die etwas größere, vom Prompt vorgegebene Fläche. */
  --k-bild-b:142px;
  --k-bild-h:92px;
  --k-punkt-klein:5px;          /* Kicker-Punkt und Top-Story-Punkt (§1.3/§1.4) */
  /* Befund-Symbol (§1.3 Punkt 3: "Symbol 14px links") — als Token statt Rohwert: die Sperre
     zählt rohe `height:Npx` in index.html (nicht hier), und der Kartenumbau darf sie laut
     tests/test_design_sperre.py nur SENKEN, nie erhöhen. */
  --k-icon-befund:14px;

  /* ---- Innenabstände der Inhaltsfolge (§1.3: 1→2:6 · 2→3:8 · 3→4:6 · 4→5:14) ------------- */
  --k-eng:6px;                  /* Kicker→Überschrift und Befund→Anriss */
  --k-vor-aktion:14px;          /* Anriss→Aktionszeile, zugleich Luft über der Haarlinie */

  /* ---- Höhen der Kartenzeilen (§1.3/§2) ---------------------------------------------------- */
  --h-kicker:16px;
  --h-befund:20px;
  --h-marke:20px;               /* Top Story/Relevant/Follow-up — nie höher (§1.4) */
  --k-symbolknopf:28px;         /* 👍/👎/↗ in der Aktionszeile */
  --h-rueckhol:26px;            /* „Ausgewählt · Rückgängig" (§3.5) */

  /* ---- Kopfzeile und Seitenleiste (§4/§5) -------------------------------------------------- */
  --k-sidebar-b:240px;          /* 280→240 (§5) */
  /* .05em (PROMPT 31 §2, 15.08.): war .06em (P29) — eigener Wert aus dem Claude-Design-Prompt,
     einziger Verbraucher (geprüft per grep), Wert direkt angepasst statt eines zweiten Tokens. */
  --k-kicker-sperrung:.05em;    /* NUR der Kartenkicker; --tx-klein-sperrung (.08em) bleibt für
                                   Sidebar-Gruppenüberschriften — zwei Anlässe, zwei Werte. */
  /* PROMPT 31 §2: eigene Kopfzeilen-/Titelgröße, bewusst NICHT auf --tx-klein (11px) bzw.
     --tx-kartentitel (17px) gerundet — beide liegen nah, aber nicht exakt am Prompt-Wert, und
     Tobias 15.08. wollte die Prompt-Zahlen eins zu eins, nicht an das Bestandsraster angeglichen. */
  --tx-karte-kopf:11.5px;       /* ganze Kickerzeile: Punkt/Ressort/Quelle/Alter einheitlich */
  --tx-karte-titel:16.5px;      /* Kartenüberschrift */
  --k-ressort-punkt:7px;        /* eigener Kicker-Punkt, NICHT --k-punkt-klein (5px, wird auch
                                   von der Top-Story-Marke mitbenutzt — eigener Wert vermeidet
                                   einen stillen Seiteneffekt dort) */

  /* ---- Farben, die P1 noch nicht hatte ----------------------------------------------------- */
  /* Überfahren-Rahmen der Karte: eine Stufe dunkler als --linie (#E4E4DF), damit die Karte beim
     Zeigen fasst wird, ohne die Fläche zu wechseln. Ersetzt das bisherige #D3D1CA in .card:hover. */
  --linie-ueber:#D6D6D0;
  /* Verwerfen beim Überfahren (§2). Bewusst NICHT --warnung-text (#C81E1E): dieses Rot ist laut
     P1 für Paywall und §7 UWG RESERVIERT, und ein Verwerfen-Knopf ist keine Rechtsaussage. Ein
     eigener, ruhigerer Ton hält die Reservierung intakt und erfüllt zugleich §7.12. */
  --verwerfen-ueber:#B3352C;
  --k-fokusring:rgba(42,42,132,.28);    /* 3px Ring außen (§1.1) */
  --haarlinie:rgba(22,22,26,.06);       /* über der Aktionszeile (§2) */
  --fuell-leise:rgba(22,22,26,.05);     /* Marken-/Symbolknopf-Fläche, Segment-Bahn (§1.4/§2/§4) */
  --bild-innenrand:rgba(22,22,26,.08);  /* 1px Innenrand am Bild (§1.2) */

  /* ---- PROMPT 31 (15.08.2026) — Aktionsspalte: eigene Höhen, eigene Farben ------------------
     Eigenständige Werte aus dem Claude-Design-Prompt, bewusst NICHT auf --h-knopf/--h-knopf-klein
     gerundet: 38/30px liegen zwischen den bestehenden Stufen (40/32), keine davon trifft genau.
     Tobias 15.08.: das alte, gerade erst vereinheitlichte Tokenraster hat ihm nicht gefallen —
     der neue Prompt gilt eins zu eins, nicht als Kompromiss mit dem Bestand. */
  --h-primaer-karte:38px;       /* „Auswählen" — der einzige gefüllte Knopf der Karte */
  --h-sekundaer-karte:30px;     /* „Verwerfen" — textartig, kein Rahmen, keine Fläche */
  --k-symbolknopf-b:30px;       /* Breite der drei Symbolknöpfe (Daumen/Weitergeben) — Höhe
                                   bleibt --k-symbolknopf (28px, bereits vorhanden) */
  --k-icon-leise:#9A968F;       /* Ruhefarbe der drei Symbolknöpfe — heller als --muted (Text),
                                   damit sie neben „Auswählen" zurücktreten statt zu konkurrieren */
  /* Daumen runter aktiv: eigene, dediziert benannte Töne statt --pink/--warnung-flaeche
     wiederzuverwenden — beide Namen tragen anderswo eine eigene Reservierung (--pink „destruktiv/
     Alarm" allgemein, --warnung-* laut static/CLAUDE.md exklusiv Paywall/§7 UWG). Ein Daumen
     runter ist keine der beiden Bedeutungen, darum ein dritter, eigener Ton (Muster wie
     --verwerfen-ueber oben: ein Anlass, ein eigener Name). */
  --daumen-runter-text:#C2372F;
  --daumen-runter-flaeche:#FBEDEC;
  /* Bildplatzhalter-Flächen je Ressort (§1/§6) — helle Fassung. Die kräftigen --kat-*-Werte oben
     decken sich bereits exakt mit §6; nur die zarte (Fläche ohne Bild) fehlte bisher. */
  --kat-tax-audit-zart:#EDF1F5;
  --kat-private-markets-zart:#F2ECF6;
  --kat-legal-zart:#EFEFEC;
  --kat-wirtschaft-zart:#F6EEE9;
  --kat-ki-tech-zart:#EAF2F1;
  --kat-karriere-zart:#F7EDF0;

  /* ---- Die Lichtkante (§3.2) --------------------------------------------------------------- */
  /* „Ein heller Kopf mit navyfarbenem Schweif, kein Regenbogen, kein Neon." Drei Stufen: der Kopf
     ist Weiß, die Mitte die aufgehellte Navy-Stufe (identisch mit --chart-mark im Dunkeln — kein
     neuer Farbwert, nur ein zweiter Anlass), der Schweif die Aktionsfarbe selbst. */
  --licht-kopf:#FFFFFF;
  --licht-mitte:#6B78E0;
  --licht-schweif:#2A2A84;

  /* ---- Bewegung (§1.1/§3) ------------------------------------------------------------------ */
  --d-karte-ueber:200ms;        /* Überfahren der Karte — zwischen --d-flaeche und --d-zustand */
  --d-licht:620ms;              /* Lichtkante läuft einmal um — PROMPT 31 §4: „0,62s“, deckungsgleich */
  --d-wash:420ms;               /* verwaist seit PROMPT 31 (Wash-Fläche entfernt, §4 verbietet sie
                                   ausdrücklich) — Token bewusst NICHT gelöscht, s. Kommentar bei
                                   .k-wash in index.html. */
  --d-schliessen:260ms;         /* verwaist seit PROMPT 31 (altes vertikales Schließen ersetzt durch
                                   .k-schliesst-seitlich, eigene .55s/.5s-Dauer direkt im Prompt) */
  --k-licht:cubic-bezier(.32,.72,0,1);   /* = --k-aus, hier unter eigenem Namen für §3.2 */
  /* PROMPT 31 §4 (15.08.): eigene Kurve für die seitliche Karten-Bewegung beim Auswählen/
     Verwerfen — der Prompt nennt cubic-bezier(.4,0,.2,1) namentlich, keine der drei Bestandskurven
     (--k-aus/-ein/-zustand) trifft exakt diesen Wert. */
  --k-licht-karte:cubic-bezier(.4,0,.2,1);
  --k-licht-b:1.5px;            /* Ringbreite der Lichtkante (mask-Doppel-Trick) — eigener Wert,
    keine Ableitung von --k-kante-b (das ist die Breite des STATISCHEN Kantenstrichs links, ein
    anderes Element; 3px = 2×1,5px ist Zufall, keine gemeinte Beziehung) */
  --schatten-karte:0 1px 2px rgba(37,36,33,.04), 0 10px 30px -18px rgba(37,36,33,.20);
  /* Eigener Schatten für aufklappende Listen (19.08.2026, Auswahlfeld im Hausdesign): tiefer als
     --schatten-karte, weil ein Aufklapper über dem Inhalt schwebt und nicht in der Fläche liegt.
     Zwei Lagen — eine weite für die Höhe, eine enge für die Kante, damit der Rand nicht ausfranst. */
  --schatten-aufklapper:0 12px 32px -12px rgba(34,34,60,.28), 0 2px 6px rgba(34,34,60,.08);

  /* ── GLAS (19.08.2026) ──────────────────────────────────────────────────────────────────────
     Bisher stand die Milchglas-Rezeptur neunmal als Rohwert in index.html, in drei Fassungen:
     blur(16px)/blur(14px)/blur(2px), saturate 180%/140%, und zweimal in umgekehrter Reihenfolge.
     Dieselbe Aussage, drei Ergebnisse — der Toast wirkte anders als der Eingrenzen-Schirm.
     Hier EIN Satz Token dafür.
     Die Sättigung ist der Teil, der den Unterschied macht: eine reine Unschärfe wirkt wie eine
     graue Scheibe, erst das Anheben der Sättigung lässt die Farben dahinter durchleuchten. Genau
     das macht Apples Vibranz aus, und deshalb steht sie höher als 100%.
     --glas-deckung ist die verbleibende Deckkraft der Fläche: NICHT beliebig senkbar, denn
     darunter läuft Text durch. Bei 68% bleibt die Bedienzeilen-Schrift über der Artikelliste
     nachweisbar über 4,5:1 (nachgerechnet, s. Commit) — tiefer wird es zur Ratesache.
     --glas-kante setzt oben eine helle, unten eine dunkle Innenlinie: das ist die Lichtbrechung
     an einer echten Glaskante und der Grund, warum die Fläche als Scheibe gelesen wird und nicht
     als Weichzeichner. */
  --glas-unschaerfe:blur(22px) saturate(185%);
  --glas-deckung:68%;
  /* Zwei Deckungen, nicht eine — der Unterschied ist gemessen, nicht Geschmack:
     Über einer ÜBERLAGERUNG (Toast, Schirm) liegt Fläche, dort darf viel durchscheinen.
     Unter einer klebenden LEISTE läuft die Artikelliste durch, also Text. Bei 68 % blieb der
     Kartentitel unter der Bedienzeile als blasse, aber klar erkennbare Schrift stehen und
     kollidierte mit "Zurücksetzen" — im Bildschirmfoto eindeutig, in einer Kantenenergie-Messung
     dagegen unauffällig (0,65 gegen 0,56 bei deckender Fläche). Das Auge erkennt Buchstaben auch
     blass; eine Kantenmessung erkennt sie nicht. Deshalb entscheidet hier das Bild.
     Bei 88 % bleibt der Glas-Charakter — Farbe und Sättigung des Untergrunds schlagen durch —
     ohne dass Schrift darunter lesbar bliebe. In einem Werkzeug, dessen Hauptarbeit Lesen ist,
     ist das die Grenze. */
  --glas-deckung-leiste:88%;
  --glas-kante:inset 0 1px 0 rgba(255,255,255,.62), inset 0 -1px 0 rgba(22,22,26,.05);

  /* LOKALE Geschwister-Reihenfolge innerhalb EINER Karte (§3: Inhalt muss über der Wash-Fläche
     liegen) — kein Fall für die globalen --ebene-*-Werte weiter oben (die ordnen Flächen ÜBER dem
     GESAMTEN Seiteninhalt: Menüs, Dialoge, Toasts). Eigener, klar benannter Mini-Bereich statt
     eines rohen `z-index:1`, das test_design_sperre.py als undokumentierten Ausreißer zählen würde
     (Grenze in static/index.html ist bereits ausgeschöpft, s. .card-corner-Kommentar dort). */
  --k-ueber-wash:1;

  /* ---- §4 (Kopfzeile): Segmentwähler + Filter-Pillen ------------------------------------- */
  /* "Polster 3" — die einzige Stelle im Auftrag mit einem Wert außerhalb der 4er-Raum-Leiter
     (4·8·12·16·20·24·32). Eigener Token statt Rohwert (test_design_sperre.py zählt rohe
     `padding:Npx` in index.html, s. GRENZEN dort). */
  --k-segment-polster:3px;
  --k-zeiger-schatten:0 1px 2px rgba(22,22,26,.10);
  --k-gruppentrenner-luft:12px;
  --k-punkt-kat:6px;   /* §5: Kategorie-Punkt in der Seitenleiste, kleiner als der Karten-Punkt (5px) und der alte Sidebar-Punkt (8px) */

  /* ---- PROMPT 48 (18.08.2026) — Abgleich Artikelkarte: Werte, die P31 noch nicht hatte. Eigene
     Token statt naheliegender Bestandswerte (--line-2:#E8E4DF, --aktion-ueber:#22226B liegen beide
     nah dran) — dieselbe Regel wie bei --h-primaer-karte oben: neue Prompt-Zahlen eins zu eins. */
  --k-marke-rand:#E4E4DF;              /* Rand: Hinweismarken (§3) + neuer Kartenrand (§1) */
  --k-marke-punkt:#B8B4AE;             /* grauer Punkt in jeder Hinweismarke (§3) */
  --k-primaer-ueber:#1E1E63;           /* Haupt-Knopf-Hover NUR in der Kartenaktionszeile (§7) —
    scoped auf .card-p29 .card-actions, NICHT --aktion-ueber selbst geändert: das träfe jeden
    anderen Knopf mit derselben Rolle im ganzen Werkzeug (Dialoge, Kopfzeile). */
  --k-toast-ring-bahn:#EFEBE6;         /* Kreisbahn des Fortschritts-Rings im Toast (§8) */
  --k-toast-meta:#9A968F;              /* „Titel des Beitrags"-Text im Toast (§8) — deckt sich
    zufällig exakt mit --k-icon-leise, eigener Name für einen eigenen Anlass (dasselbe Muster wie
    --licht-mitte/--chart-mark oben). */
  --k-toast-schatten:inset 0 0 0 1px rgba(22,22,26,.08), 0 2px 6px rgba(22,22,26,.07),
    0 22px 48px -22px rgba(22,22,26,.42);   /* §8 — Bündel-Token wie --schatten-karte oben */

  /* ---- PROMPT 48, Geometrie (§1/§2/§3/§5/§8): test_rohe_masse_wachsen_nicht zieht die Grenze
     bei jedem Raum-/Höhen-/Radius-/Schrift-Rohwert nach — jede neue Zahl unten bekommt ihr
     eigenes Token statt eines rohen `Npx` in index.html, wie überall sonst in dieser Datei. */
  --k-karte-hoehe-p48:276px;
  --k-karte-pad-t-p48:16px;
  --k-karte-pad-x-p48:18px;
  --k-zeile-gap-p48:18px;
  --k-zeile-hoehe-p48:180px;         /* .card-zeile UND .card-inhalt — dieselbe Zeile */
  --k-titel-abstand-p48:7px;         /* Titel→Anriss, erster der zwei Spacer (§1: „7+6") */
  --k-titel-hoehe-p48:44px;
  --k-anriss-abstand-p48:6px;        /* Titel→Anriss, zweiter Spacer */
  --k-anriss-hoehe-p48:105px;
  /* SICHTEN-RUNDGANG 26.08.2026 — die Karte wächst, statt zu kürzen.
     Auftrag: „bei den Artikeln noch keine ganzen Headlines … teilweise mit … abgekürzt. Das darf
     nicht sein" + „immer drei bis vier Zeilen mit Artikeltext in der Vorschau". Beides ist mit
     einer FESTEN Kartenhöhe nicht zu haben: 276px = 18 Kopfzeile + 44 Titel + 13 + 105 Anriss +
     Aktionszeile, und in 44px passen genau zwei Titelzeilen. Eine dritte Titelzeile ODER eine
     vierte Anrisszeile muss also irgendwo Platz herholen — es gibt keinen. Die drei Maße unten
     drehen die bisherigen DECKEL in BÖDEN um: jede Karte ist mindestens so hoch wie bisher (die
     Liste sieht bei kurzen Titeln unverändert aus), eine lange Überschrift oder ein langer Anriss
     darf sie überschreiten. Aufgegeben wird damit PROMPT 48 §1 („276px FEST") und §10.2 (gleiche
     Y-Koordinate für Anriss/Aktionszeile über alle Karten) — bewusst, auf ausdrückliche Anweisung,
     nicht aus Versehen. Kopfzeile und Titel beginnen weiterhin überall auf derselben Linie. */
  --k-karte-min-p48:276px;           /* war --k-karte-hoehe-p48 (fest), jetzt Untergrenze */
  --k-anriss-zh-p48:21px;            /* 13,5px × 1,55 = 20,9 — auf das §1-Raster gerundet */
  /* 105px = 5 × 21 seit 03.09.2026 (vorher 84 = 4 Zeilen). Tobias: „mir wäre es wichtig, wenn
     wirklich bei allen Reitern Sichten, Ausgewählte, Entwürfe … immer fünf Zeilen geschriebener
     Text steht, immer, immer, immer, immer." Der Wert wird gegen _P48_ANRISS_MIN_ZEILEN geprüft
     (tests/test_anriss_fuenf_zeilen.py) — beide müssen dieselbe Zeilenzahl meinen. */
  --k-anriss-min-p48:105px;
  --k-anriss-max-p48:126px;          /* 6 × 21 — Netz gegen einen ungewöhnlich langen Rest */
  /* Lesebreite NUR in „Ansehen" (Fertige Artikel / Archiv): dort steht rechts die 420px-Spalte
     mit dem Visual, und die 34em von .draft-text ließen die Fläche dazwischen leer stehen.
     26.08.2026, Tobias: „halt einfach nur ein bisschen breiter gezogen oder auf dem Drittel." */
  --fa-text-breite:46em;
  /* Wie lange die Hervorhebung des Geänderten STEHEN BLEIBT, bevor sie verblasst (26.08.2026).
     8 s ist die Zeit, um einen überarbeiteten Absatz einmal zu lesen — kürzer und man sucht die
     Stelle, länger und die Farbe liegt bei der nächsten Änderung noch da.

     ⚠️ Bewusst NICHT `--d-…`: dieser Namensraum ist der Bewegungskatalog, und der ist auf zehn
     erlaubte Werte festgenagelt (test_dauern_sind_genau_die_zehn_erlaubten_werte). 8 s ist keine
     Bewegungsdauer, sondern eine Standzeit — sie in diesen Katalog zu heben, hieße ihn für einen
     Fall zu öffnen, der nichts mit Bewegung zu tun hat. Die Sperre hat den Namen zu Recht
     abgelehnt; die richtige Antwort ist ein eigener Name, nicht eine gelockerte Sperre. */
  --wb-neu-standzeit:8000ms;
  --k-bild-b-p48:240px;
  --k-bild-h-p48:180px;
  --r-bild-p48:12px;
  --k-icon-leer-b-p48:88px;
  --k-icon-leer-h-p48:68px;
  --h-kicker-p48:18px;
  --k-vor-aktion-t-p48:13px;         /* Abstand nach der oberen Zeile, vor der Trennlinie */
  --k-vor-aktion-b-p48:12px;         /* Abstand nach der Trennlinie, vor der Aktionszeile */
  /* 20px seit 03.09.2026 (vorher 22): Tobias wollte die Marken „nebeneinander, aber dann halt
     kompakt". Der Wert steht hier und nicht als Sonderregel im Stylesheet, damit
     --k-marke-ueberhang-p48 darunter automatisch mitrechnet — sonst reservierte .card-inhalt
     weiter Kopffreiheit für eine Höhe, die es nicht mehr gibt. */
  --h-marke-p48:20px;
  /* Wie weit die Hinweismarke oben und unten aus ihrer Kickerzeile ragt: sie ist 22px hoch,
     die Zeile 18px, `align-items:center` verteilt die Differenz auf beide Seiten. Gerechnet
     statt getippt — ändert sich eine der beiden Höhen, wandert der Wert mit. Gebraucht wird
     er als Kopffreiheit für den Beschnitt von .card-inhalt, s. dort. */
  --k-marke-ueberhang-p48:calc((var(--h-marke-p48) - var(--h-kicker-p48)) / 2);

  /* Senkrechte Reserve in der waagerecht scrollenden Filterzeile. `overflow-x:auto` zieht
     `overflow-y` zwangsweise mit — ohne diese Luft läge jedes runde Bedienelement dort auf
     null Reserve an einer Beschnittkante. 4px, weil das den größten Sprung abfängt, den eine
     andere Schriftmetrik an einem 32-38px hohen Knopf erzeugt, ohne die Zeile spürbar zu
     verbreitern; sie wird per negativem Abstand ohnehin wieder herausgerechnet. */
  --bz-filter-reserve:4px;
  --k-marke-punkt-d-p48:6px;
  --k-marke-punkt-top-d-p48:5px;     /* Top-Story-Punkt, eine Stufe kleiner (§3, wie .marke-top) */
  /* --k-marken-spalte (168px) ist am 03.09.2026 nachmittags entfallen: die Markenspalte, für die
     sie die Breite hielt, stand nur einen halben Tag. Tobias hat sie zurückgenommen („macht das
     bitte doch wieder nebeneinander, aber dann halt kompakt"). Die drei Tokens darunter sind ihr
     Ersatz — sie beschreiben die kompakte REIHE, nicht die Spalte. */
  --k-marke-polster-p48:6px;         /* Innenabstand links/rechts, vorher --raum-2 (8px) */
  --k-marke-abstand-p48:4px;         /* Abstand zwischen zwei Marken, vorher --raum-1 */
  --tx-toast-klein:11.5px;           /* Toast Zeile 2: „Warum passt das?"-Label + Chips */
  --k-toast-ring-d:28px;
  --k-toast-ring-ico:14px;
  --k-toast-trenn-h:16px;
  --k-toast-schliessen:16px;         /* Schließen-Kreuz */
  --k-toast-knopf-pad:2px;           /* Rückgängig/Zweit-Knopf/Schließen: Hover-Fläche, Polster */
  --k-toast-pad-t:13px;
  --k-toast-pad-x:16px;
  --h-teilen-p48:34px;   /* §7: "In n Beiträge teilen" — eigene Höhe zwischen 30 und 38 */
  --k-teilung-box-d:18px;   /* §6: Kästchen im Teilungsvorschlag */
}

/* ---- Dunkel: eigens gerechnet, keine Umkehrung (dieselbe Regel wie P1 Abschnitt 9) ----------
   §7.12 verlangt: „alle sechs Flächen wechseln, Kantenstriche nehmen die aufgehellten Töne, Rot
   bleibt Paywall und §7 vorbehalten." Die sechs Flächen und die Kategorie-Töne liegen bereits in
   P1 (--flaeche/--grund/--flaeche-hoch/--text/--text-leise/--linie bzw. --kat-*) und wechseln von
   selbst mit — hier stehen nur die Werte, die dieses Paket neu einführt. Geometrie, Höhen und
   Bewegung kommen bewusst NICHT vor: sie sind vom Thema unabhängig. */
:root[data-theme="dark"]{
  /* Eine Stufe HELLER als --linie (#2E3138) — im Dunkeln ist Annäherung an Weiß die Bewegung. */
  --linie-ueber:#3A3D45;
  /* #B3352C erreicht auf --flaeche (#1A1C21) nur 3,1:1. Derselbe Ton wie der Bestandswert --pink
     im dunklen Thema (#E38B86, 6,4:1) — kein neuer Farbwert, ein zweiter Anlass. */
  --verwerfen-ueber:#E38B86;
  --k-fokusring:rgba(142,151,240,.30);   /* auf --aktion-fokus (#8E97F0) gerechnet, nicht auf Navy */
  --haarlinie:rgba(255,255,255,.07);
  --fuell-leise:rgba(255,255,255,.06);
  --bild-innenrand:rgba(255,255,255,.09);
  /* Der Schweif nimmt die aufgehellte Aktionsstufe: #2A2A84 käme auf #1A1C21 auf 2,0:1 und wäre
     als laufende Kante schlicht unsichtbar. Kopf und Mitte tragen im Dunkeln von selbst. */
  --licht-schweif:#3D46B8;
  --schatten-karte:0 4px 20px rgba(0,0,0,.45);
  /* Im Dunkeln trägt der Aufklapper-Schatten Schwarz, nicht Navy: auf dunklem Grund liest sich ein
     farbiger Schatten als Schleier, nicht als Höhe. Dieselbe Zwei-Lagen-Bauart wie im Hellen. */
  --schatten-aufklapper:0 14px 34px -12px rgba(0,0,0,.55), 0 2px 6px rgba(0,0,0,.35);
  /* Im Dunkeln trägt die Lichtkante oben nur eine Spur Weiß — mehr liest sich als Rand statt als
     Kante — und unten Schwarz. Die Deckung liegt tiefer als im Hellen: dunkle Flächen verzeihen
     Transparenz besser, weil der Text darauf hell ist und der Untergrund ohnehin dunkel bleibt. */
  --glas-deckung:62%;
  --glas-deckung-leiste:84%;
  --glas-kante:inset 0 1px 0 rgba(255,255,255,.10), inset 0 -1px 0 rgba(0,0,0,.30);
  /* PROMPT 31, dunkle Fassung (15.08.) — Symbolknopf-Ruhefarbe eine Stufe heller als im Hellen
     (dieselbe Logik wie --muted dunkel heller als --muted hell), Daumen-runter-Ton wiederverwendet
     denselben Rotwert wie --pink/--verwerfen-ueber im Dunkeln (#E38B86, hier bereits als
     ausreichend kontrastreiches „Dunkel-Rot" etabliert — kein dritter, eigener Rotwert nötig). */
  --k-icon-leise:#9C9890;
  --daumen-runter-text:#E38B86;
  --daumen-runter-flaeche:#2B1718;

  /* PROMPT 48, dunkle Fassung — Rand/Punkt eine Stufe heller als ihr Grund (dieselbe Bewegung wie
     --linie-ueber oben), Toast-Ring-Bahn nah an --line dunkel, Hover übernimmt den bereits
     etablierten dunklen --aktion-ueber-Wert (kein dritter Navy-Ton für denselben Zweck). */
  --k-marke-rand:#3D4048;
  --k-marke-punkt:#7A766F;
  --k-primaer-ueber:#4A54CC;
  --k-toast-ring-bahn:#35363B;
  --k-toast-meta:#9C9890;
  --k-toast-schatten:inset 0 0 0 1px rgba(255,255,255,.08), 0 2px 6px rgba(0,0,0,.30),
    0 22px 48px -22px rgba(0,0,0,.55);
}

/* ════════════════════════════════════════════════════════════════════════════════════════════
   NEBENSEITEN: DRUCKPUNKT UND ZUSTANDSÜBERGANG (19.08.2026)
   ════════════════════════════════════════════════════════════════════════════════════════════
   Gemessen am 19.08.: quellen.html, verteiler.html und kapazitaet.html haben keine einzige
   Übergangsregel, medien.html zwei, leitung.html drei — das Board dagegen über zweihundert.
   Dieselbe Anwendung verhält sich damit auf der einen Seite lebendig und auf der anderen wie
   ein Formular von vorgestern: Reiter schalten hart um, Knöpfe bestätigen den Druck nicht.
   Emil Kowalski nennt das Zusammenhalt (Skill emil-design-eng): Bewegung darf sich je Bereich
   unterscheiden, aber nicht zwischen "da ist welche" und "da ist keine".
   Diese Datei laden alle Nebenseiten — deshalb steht die Regel hier und nicht fünfmal kopiert.
   Bewusst nur Druckpunkt und Zustandsübergang; die Nebenseiten bekommen keine eigenen
   Auftritts- oder Aufklapp-Bewegungen, dafür fehlt ihnen der Anlass.
   Werte ausschließlich aus den Haus-Token oben (--druck-tiefe/--d-zustand/--k-zustand), damit
   der Druck sich überall gleich anfühlt. .btn und .reiter gibt es auch im Board — dort stehen
   eigene, spezifischere Regeln, die diese hier überschreiben; hier greifen sie nur da, wo
   bisher gar nichts stand. */
.reiter, .chip-wahl, .rang-tab, .btn{
  transition:transform var(--d-zustand) var(--k-zustand),
             color var(--d-zustand) var(--k-zustand),
             background-color var(--d-zustand) var(--k-zustand),
             border-color var(--d-zustand) var(--k-zustand);}
.reiter:active:not(:disabled),
.chip-wahl:active:not(:disabled),
.rang-tab:active:not(:disabled),
.btn:active:not(:disabled){
  transform:scale(var(--druck-tiefe));}
@media (prefers-reduced-motion:reduce){
  .reiter, .chip-wahl, .rang-tab, .btn{transition:none;}
  .reiter:active:not(:disabled),
  .chip-wahl:active:not(:disabled),
  .rang-tab:active:not(:disabled),
  .btn:active:not(:disabled){transform:none;}
}

/* ════════════════════════════════════════════════════════════════════════════════════════════
   PROMPT 62 §0/§1 (20.08.2026): Material — Grund/Chrome/Overlay
   ════════════════════════════════════════════════════════════════════════════════════════════
   Drei Flächenarten, nicht drei neue Tokens. Grund (deckend, ruhend — Sidebar, Karten, Fenster-
   Innenfläche) ist bereits --flaeche, seit P1 — keine zweite Deklaration für dieselbe Fläche.
   Chrome (durchscheinend, nur auf mitlaufenden Leisten) ist bereits die GLAS-Rezeptur weiter oben
   (--glas-unschaerfe/--glas-deckung/--glas-deckung-leiste/--glas-kante, 19.08.) — Kopfzeile glast,
   Bedienzeile bleibt bewusst deckend, genau wie der Auftrag es für beide verlangt. Beide Bausteine
   bleiben unangetastet.
   Overlay (schwebend, die einzige Flächenart mit Schatten) fehlte als EIN Baustein: bisher trägt
   jede schwebende Fläche ihren eigenen, historisch gewachsenen Schatten (--schatten-aufklapper,
   --k-toast-schatten, rohe Werte an .eg-tafel/.est-tafel/.wb-*-Schublade/.popover). Das bleibt für
   JENE Bausteine bewusst so — eigener Scope, eigene Messung, s. deren Kommentare; sie hier auf
   einen gemeinsamen Wert zu ziehen wäre ein Umbau, den PROMPT 62 nicht beauftragt. Für die mit
   PROMPT 62 neu entstehenden Flächen (Suchpanel, Quelle-/Artikel-Fenster, Leseansicht,
   Originalquelle) gilt ab hier GENAU ein Schatten, wörtlich aus dem Auftrag übernommen.
   Dunkel eigens gerechnet, nicht gespiegelt (dieselbe Regel wie überall in dieser Datei): ein
   Schwarz-Schatten bei .18 Deckkraft liest auf dunklem Grund kaum noch als Höhe (vgl. --schatten-
   karte dunkel, die aus demselben Grund auf .45 angehoben ist, oder --schatten-aufklapper dunkel
   auf .55/.35) — hier entsprechend auf .5 angehoben, Geometrie unverändert. */
:root{
  --schatten-overlay:0 24px 60px rgba(0,0,0,.18);
}
:root[data-theme="dark"]{
  --schatten-overlay:0 24px 60px rgba(0,0,0,.5);
}

/* ════════════════════════════════════════════════════════════════════════════════════════════
   PROMPT 62 §1 (20.08.2026): Sidebar-Zeile — Ruhe/Überfahren als eigene Töne
   ════════════════════════════════════════════════════════════════════════════════════════════
   Zwei Werte, die auf keinen Bestandswert treffen (--text-leise:#72726D ist deutlich heller als
   das geforderte Ruhe-#3A3A38, --senke:#E4E4DF ist ein anderer Ton als das geforderte Überfahren-
   #F4F3F0) — eigene Token statt Rundung, wie überall in dieser Datei. Betrifft nur `.sb-item`,
   nicht `--text-leise`/`--senke` selbst (deren andere Verbraucher bleiben unberührt).
   Dunkel eigens gerechnet: Ruhe übernimmt denselben Ton wie --text-leise dunkel (#9A9C9F) — die
   Hell/Dunkel-Spreizung zwischen „normal gedämpft" und „sidebar-eigen dunkler" braucht im Dunkeln
   keine zweite Stufe, dort komprimiert sich die Text-Hierarchie ohnehin (vgl. 9.1). Überfahren
   übernimmt --flaeche-hoch dunkel (#22252B) — eine Stufe heller als die neue Sidebar-Grundfläche
   --flaeche (#1A1C21), dieselbe Richtung wie im Hellen (Überfahren heller als Grund). */
:root{
  --sb-zeile-ruhe:#3A3A38;
  --sb-zeile-ueber:#F4F3F0;
}
:root[data-theme="dark"]{
  --sb-zeile-ruhe:#9A9C9F;
  --sb-zeile-ueber:#22252B;
}

/* ════════════════════════════════════════════════════════════════════════════════════════════
   PROMPT 63 (25.08.2026): Einstellungen 1:1 aus zwei Claude-Design-Entwürfen
   ════════════════════════════════════════════════════════════════════════════════════════════
   Quellen, per DesignSync gelesen (nicht aus der Chat-Prosa nachgebaut):
   `Einstellungen-Darstellung-Laptop.dc.html` und `Einstellungen-Urlaub.dc.html`.
   Eigener --p63-Namensraum statt Angleichen ans Bestandsraster (Tobias, 15.08.): jeder Wert
   steht wörtlich so im Entwurf. Hier statt roh in index.html, weil
   test_design_sperre.test_rohe_masse_wachsen_nicht dort jede nackte Zahl mitzählt — dieselbe
   Bauart wie die --k-*-Blöcke aus PROMPT 48 weiter oben.

   Was BEWUSST nicht übernommen wird, und warum:
   • Die Schale. Der Urlaub-Entwurf zeichnet die Tafel als 1080-Karte mit Radius 24 ohne feste
     Höhe, der Darstellungs-Entwurf als 1108×664 mit Radius 26 über abgedunkeltem Board. Beide
     können nicht gleichzeitig stimmen. Der Darstellungs-Entwurf gewinnt: nur er zeigt die Tafel
     IM Werkzeug (mit Schirm dahinter), der Urlaub-Entwurf ist ein freigestelltes Artboard.
     `.est-tafel` bleibt damit unverändert.
   • `flex:1` auf der Reiterzeile (Urlaub-Entwurf, acht gleich breite Reiter). Der
     Darstellungs-Entwurf packt dieselben Reiter links (`flex:none` + Polster 16). Ein Dialog
     kann seine Reiterzeile nicht je nach offenem Reiter umbauen — auch hier gewinnt der
     Darstellungs-Entwurf, weil er die Reiterzeile im Zusammenhang zeigt.
   Dunkel eigens gerechnet, nicht gespiegelt (Regel dieser Datei): die beiden Alpha-Töne
   (Segmentspur, Haarlinie) liegen im Hellen auf Schwarz und im Dunkeln auf Weiß — ein
   schwarzer Alpha-Ton auf dunklem Grund ist schlicht unsichtbar. */
:root{
  /* --- Kopf + Reiterzeile (Darstellungs-Entwurf) --- */
  --p63-kopf-polster:24px 28px 0;
  --p63-titel-gewicht:600;             /* Entwurf: font-weight:600 (Haus-Rolle wäre 700) */
  --p63-titel-sperrung:-0.024em;
  --p63-rolle-abstand:5px;
  --p63-reiter-polster:16px 28px 0;
  --p63-reiter-innen:4px;              /* Polster der Reiter-Spur, vorher 3 */
  --p63-reiter-schrift:13px;

  /* --- Reglerspalte (Darstellungs-Entwurf) --- */
  --p63-kasten-r:12px;
  --p63-kasten-titel:13px;
  --p63-seg-spur-polster:3px;
  --p63-seg-spur-luft:2px;
  --p63-seg-spur:rgba(22,22,26,.05);
  --p63-seg-h:28px;
  --p63-seg-schrift:12px;

  /* --- Schalter (Darstellungs-Entwurf 42×24/Knauf 18, Urlaub-Entwurf 46×28/Knauf 22) --- */
  --p63-schalter-b:42px;
  --p63-schalter-h:24px;
  --p63-schalter-knauf:18px;
  --p63-schalter-rand:3px;
  --p63-schalter-weg:18px;             /* b − knauf − 2·rand */
  /* Der Urlaub-Entwurf zeichnet SEINEN einen Schalter größer (46×28, Knauf 22). Bewusst NICHT
     gebaut: PROMPT 47 §1 verlangt EINE Schalter-Komponente in EINER Größe für das ganze Werkzeug,
     und derselbe Entwurf weicht auch bei Schale und Reiterzeile vom Darstellungs-Entwurf ab (s.
     oben). Drei Abweichungen, eine Ursache: ein freigestelltes Artboard. Liegt bei Tobias/Leo. */

  /* --- Urlaub-Entwurf --- */
  --p63-feld-h:44px;
  --p63-feld-r:10px;
  --p63-feld-schrift:15px;
  --p63-feld-polster:14px;
  --p63-label-abstand:6px;
  --p63-karte-r:18px;
  --p63-karte-polster:16px 20px;
  --p63-karte-titel:16px;
  --p63-karte-begr:13.5px;
  --p63-zeile-h:40px;
  --p63-zeile-r:12px;
  --p63-zeile-polster:14px;
  --p63-punkt:6px;
  --p63-chip-polster:3px 9px;
  --p63-knopf-h:40px;
  --p63-knopf-polster:20px;
  --p63-knopf-schrift:14px;
  --p63-zeilenknopf-polster:14px;
  --p63-grund-r:14px;
  --p63-grund-polster:16px 18px;
  --p63-bestaetige-h:38px;
  --p63-bestaetige-polster:18px;
  --p63-avatar-gross:30px;
  --p63-verlauf-wer:140px;
  --p63-verlauf-detail:270px;
  --p63-verlauf-luft:14px;
  --p63-gesperrt-text:#A8A8A3;         /* gesperrter Haupt-Knopf: Schrift auf --sch-sperr-aus */
  /* Luft-Werte des Urlaub-Entwurfs, die keine Sprosse der 4er-Raum-Leiter treffen. Als Token
     statt roh, wie die --k-*-Blöcke oben — test_rohe_masse_wachsen_nicht zählt rohe gap/margin
     in index.html, und die Grenze dort wird nur gesenkt, nie erhöht. */
  --p63-chip-luft:9px;                 /* Avatar↔Name im Vertretungs-Chip */
  --p63-karten-luft:10px;              /* die zwei Kategorie-Karten, Kategoriezeile, Grund-Zeile */
  --p63-chips-luft:6px;                /* Grund-Chips untereinander */
  --p63-senden-abstand:18px;           /* über der Senden-Zeile */
  --p63-detail-abstand:2px;            /* Zeile→Zeitraum in „Laufende Vertretungen" */
}
:root[data-theme="dark"]{
  --p63-seg-spur:rgba(255,255,255,.07);
  --p63-gesperrt-text:#7C7E82;         /* auf --sch-sperr-aus dunkel (#2E3138) gerechnet */
}

/* ════════════════════════════════════════════════════════════════════════════════════════════
   PROMPT 62 §4, zweite Hälfte (25.08.2026): Leseansicht und Originalquelle
   ════════════════════════════════════════════════════════════════════════════════════════════
   Quelle: `Apple-Schale.dc.html` (Claude Design, per DesignSync gelesen) — die beiden
   `sc-if`-Blöcke `leseOffen` und `originOffen`. Jede Zahl steht dort wörtlich.
   Eigener --ls-/--oq-Namensraum, kein Angleichen ans Bestandsraster (Tobias, 15.08.).
   Die Prozenthöhen des Entwurfs (76 % / 78 % des Artboards) werden zu vh — im Werkzeug
   spannt der Schirm über das ganze Fenster, das Artboard war nur ein Ausschnitt davon.
   Dunkel: nur die zwei Töne, die im Hellen auf Schwarz liegen; Geometrie ist themenfrei. */
:root{
  --ls-b:980px;                    /* Entwurf: 820 — Tobias 26.08.: „und dann gerne breiter" */
  --ls-r:24px;
  --ls-max-h:76vh;
  --ls-polster:32px 36px 28px;
  --ls-urs:18% 4%;
  --ls-kopf-luft:18px;
  --ls-titel:28px;
  --ls-titel-sperrung:-0.02em;
  --ls-text:16px;
  --ls-text-abstand:20px;
  --ls-zeile:80ch;                 /* wächst mit der Breite mit, sonst nur mehr Weißraum */
  --ls-aktion-abstand:26px;
  --ls-knopf-h:40px;
  --ls-x:28px;

  /* ── EIN Dialogschirm für alle (26.08.2026, Tobias: „anderen elf Dialoge nachziehen aber
     milchiger effekt schwächer machen weicher") ────────────────────────────────────────────
     Vorher trugen acht Schirmflächen SIEBEN verschiedene Farben: hell `rgba(250,250,248,.3)`
     beim Eingrenzen-Fenster, blaustichig `rgba(11,11,63,.28)` in der Palette, schiefergrau
     `rgba(15,23,42,.42)` beim Bewerten, dazu drei Grautöne und einmal reines Schwarz. Welchen
     ein Dialog erwischte, hing davon ab, wann er gebaut wurde — nicht davon, was er tut.
     Der Ebenen-Entwurf (`Schritt8-Ebenen.dc.html`, Ebene „Schleier") nennt die Fläche
     ausdrücklich „die Verdunkelung": dunkel ist Vorgabe, nicht Geschmack.
     Zwei Stufen, weil Schirme sich stapeln können: die Originalquelle liegt über der
     Leseansicht, und zwei gleich dunkle Schirme übereinander lesen sich als einer.
     Die Weichzeichnung war beim Eingrenzen-Fenster `blur(10px) saturate(150%)` und damit der
     stärkste Effekt im Werkzeug — jetzt EIN Wert für alle, deutlich zurückgenommen. Der Rest
     des Hauses hält das schon so: die Bedienzeile verzichtet bewusst ganz darauf
     („teuerster Effekt bei geringstem Aussagewert"). Wer nachjustieren will, dreht hier
     an einer Stelle und trifft alle acht. */
  --schirm:rgba(0,0,0,.32);
  --schirm-hoch:rgba(0,0,0,.42);
  --schirm-weich:blur(4px) saturate(118%);

  --oq-b:900px;
  --oq-h:78vh;
  --oq-r:20px;
  --oq-schirm:var(--schirm-hoch);   /* Alias, kein zweiter Wert — s. --schirm oben */
  --oq-leiste-h:48px;
  --oq-feld-h:28px;
  --oq-polster:36px 56px 40px;
  --oq-luft:16px;
  --oq-titel:30px;
  --oq-text:17px;
  --oq-zeile:64ch;
  --oq-bild-h:220px;
  --oq-skelett-h:12px;
  --oq-platz-icon:#C3C3BD;         /* Symbol im leeren Bildplatz — leiser als --faint */

  /* Schrift-, Luft- und Symbolmaße der beiden Fenster. Als Token statt roh, weil
     test_rohe_masse_wachsen_nicht in index.html jede nackte Zahl mitzählt und die Grenzen dort
     nur gesenkt werden — dieselbe Bauart wie die --k-*-Blöcke aus PROMPT 48 weiter oben
     (--k-toast-ring-ico, --k-teilung-box-d). Für Symbolgrößen gibt es im Haus kein eigenes
     Token (s. Notiz an `.est-schliess svg`); diese hier sind die des Entwurfs. */
  --ls-knopf-schrift:14px;
  --ls-rubrik-luft:7px;
  --ls-knopf-luft:8px;
  --ls-aktion-luft:10px;
  --ls-ikon:15px;                  /* Schließen-Kreuz der Leseansicht */
  --ls-knopf-ikon:14px;            /* Chevron im Haupt-Knopf */
  --oq-klein:12px;                 /* Adresszeile und „Quelle · Alter" */
  --oq-fuss-schrift:12.5px;
  --oq-leiste-luft:10px;
  --oq-skelett-luft:10px;
  --oq-ikon:14px;                  /* Zurück und Schließen in der Adresszeile */
  --oq-schloss:12px;
  --oq-bild-ikon:36px;
}
:root[data-theme="dark"]{
  /* Auf dunklem Grund trägt .32/.42 nicht mehr als Trennung — dieselbe Anhebung um .16,
     die für die Originalquelle schon gemessen war, gilt jetzt für beide Stufen. */
  --schirm:rgba(0,0,0,.48);
  --schirm-hoch:rgba(0,0,0,.58);
  --oq-platz-icon:#5A5D64;
}
