/* =============================================================================
   Vereinsplattform – Design-System „Kanzlei" (Variante A)
   =============================================================================

   DIE EINZIGE STELLE FÜR OPTIK. Views bringen KEINE Inline-Styles mehr mit –
   wer hier nichts findet, legt ein Token/eine Klasse an, statt `style="…"` in
   ein Blade zu schreiben. Sonst driftet die Optik mit jedem neuen Screen wieder
   auseinander (genau das war der Anlass für diesen Umbau).

   Kein Build-Schritt: statische Datei unter public/css/app.css, eingebunden in
   components/layouts/app.blade.php (Panel) und components/layouts/central.blade.php
   (Landing + zentraler Login). Kein Vite, kein npm.

   Charakter: ruhige Flächen, Haarlinien statt Rahmen, viel Weißraum, Petrol als
   EINZIGER Akzent.

   IMMER TAGMODUS. Die App rendert ausnahmslos die hellen Tokens – unabhängig von
   der Systemeinstellung des Nutzers (ausdrücklicher Nutzerwunsch). Es gibt KEIN
   `prefers-color-scheme` mehr in dieser Datei. Die dunklen Farbwerte liegen als
   Vorrat unter [data-theme="dark"] (siehe dort) und sind derzeit UNBENUTZT.

   ZENTRIERTER INHALT. Alles lebt in EINEM Container (--content-max), auch die
   Menüleiste – deren Fläche/Trennlinie läuft über die volle Breite, ihr INHALT
   sitzt aber auf derselben Achse wie der Seiteninhalt.

   Aufbau:
     1. Tokens (hell = aktiv, dunkel = Vorrat)
     2. Grundgerüst (Reset, Body, Container, Topbar, Layout)
     3. Steuerelemente  <- --h-control: EINE Höhe für input/select/textarea/button
     4. Tabellen, Sortierung, Spaltenauswahl   <- .data-fit: Spalten so breit wie nötig
     5. Panels, Badges, Detailansicht (Slide-over), Modal, Pager
     6. Zentrale Seiten (Landing, Login)
   ========================================================================== */

/* =============================================================================
   1. TOKENS
   ========================================================================== */
:root {
    color-scheme: light;

    /* Flächen & Text */
    --page: #f4f5f5;
    --card: #ffffff;
    --ink: #1b1e20;
    --muted: #6f767b;
    --line: #ebeded;
    --line-strong: #dcdfe0;
    --hover: #f0f2f2;

    /* Akzent – Petrol, der einzige. Kein zweiter Akzent, nirgends. */
    --accent: #1f5f63;
    --on-accent: #ffffff;
    --accent-soft: #dcebeb;
    --accent-ink: #16484b;
    /* DIE SPITZE DES AUFBLITZENS (Handoff 0181) – KEIN zweiter Akzent, sondern
       derselbe Petrol eine Stufe kraeftiger als --accent-soft. Er kommt
       AUSSCHLIESSLICH in `@keyframes zeile-aufblitzen` vor und steht nie
       laenger als 0,9 s; als ruhende Flaeche ist er zu laut. */
    --accent-blitz: #a9d3d4;

    /* Navigationsleiste: weiß mit unterer Linie */
    --nav-bg: #ffffff;
    --nav-line: #e4e7e7;

    /* Tabellenkopf */
    --th-bg: #fafbfb;

    /* Status-Pillen (dezent) */
    --ok-bg: #dcebeb;
    --ok-ink: #16484b;
    --off-bg: #eceeee;
    --off-ink: #6f767b;
    --warn-bg: #f7edd8;
    --warn-ink: #7a5a14;

    /* Startseite-Stern (Aktiv-Zustand, Handoff 0058) – das einzige Gold/Gelb im UI */
    --star-gold: #e0a516;

    /* ALTERUNG EINES AUFGABEN-TICKETS (Handoff 0209, umgestellt 0210, auf die
       Liegezeit-Angabe umgestellt 0212) – EINE Bernstein-Familie in drei Stufen:
       „wartet lange", NICHT „gilt nicht".
       ⚠ KEIN ROT. Rot ist im Haus die Aussage „gilt nicht" (DESIGN §34.6) und auf
       einem Ticket allein der ÜBERSCHRITTENEN FRIST vorbehalten. Ein Ticket, das
       rot wird, weil es alt ist, sähe aus wie ein ungültiges Ticket.
       ⚠ 0212: SIE FÜLLEN DIE LIEGEZEIT-ANGABE (§39.6), nicht mehr einen Punkt –
       der 8-px-Punkt aus 0210 ist vom Nutzer verworfen worden („zu klein und die
       farbe nicht gut zu sehen"). Sie sind deshalb HINTERGRÜNDE UNTER TEXT, und
       daran hängt ihr Wert: Stufe 1 und 2 tragen --ink, Stufe 3 trägt --card.
       ⚠ 0213: DIE LEITER IST AUSEINANDERGEZOGEN. Bis 0212 lagen die Nachbarstufen
       bei 1,31 / 1,29 / 3,22 – die Stufen 0, 1 und 2 waren nebeneinander praktisch
       nicht zu unterscheiden, die ganze Spreizung steckte im letzten Schritt.
       Jetzt sind die drei Schritte GLEICH GROSS: die Gesamtspanne von --off-bg
       (Stufe 0) bis --alter-3 (Stufe 3) betraegt 5,46:1, ihre dritte Wurzel ist
       1,76 – und genau darauf sind --alter-1 (#d7b056) und --alter-2 (#a78127)
       gerechnet. Nachbarstufen jetzt: 1,76 / 1,76 / 1,76.
       Beide bleiben in derselben Bernstein-Familie (Farbton 42°, Saettigung .62)
       und tragen --ink lesbar: 8,17:1 bzw. 4,64:1.
       ⚠ Stufe 3 traegt weiterhin bewusst genau den Wert von --warn-ink – dieselbe
       Aussage eine Stufe weiter, keine zweite Farbe, und die Leiter endet
       UNTERHALB von Rot. */
    /* ⚠⚠ NACHTRAG 25.08.2026 (Handoff 0217): --alter-3 IST ENTFALLEN. Die
       hoechste Stufe der Liegezeit ist auf ausdruecklichen Wunsch des Nutzers
       ROT geworden („die farben finde ich nicht von ‚liegt seit …' — können wir
       das doch rot machen") und nimmt dafuer die vorhandene Gefahr-Familie
       (`--danger-ink`/`--on-danger`, siehe `.board-liegezeit-3`). Damit traegt
       Rot ZWEI benannte Faelle statt einem – nachgetragen in DESIGN §0 und
       §34.6a, nicht stillschweigend gebrochen. Der Absatz darueber („KEIN ROT")
       gilt fuer die Stufen 1 und 2 unveraendert weiter. */
    --alter-1: #d7b056;
    --alter-2: #a78127;

    /* Gefahr (Löschen) */
    --danger: #a33232;
    --on-danger: #ffffff;
    --danger-bg: #fbe9e9;
    --danger-ink: #a33232;

    --shadow: 0 10px 30px rgba(20, 26, 28, .12);
    /* DIE ERHEBUNG EINES TICKETS AUF DER TAFEL (Handoff 0218, §39.6a) – deutlich
       flacher als `--shadow`, das fuer schwebende Fenster gedacht ist. Ein
       Ticket liegt auf der Spalte, es schwebt nicht darueber. Nutzer-Befund,
       woertlich: „grau sieht so trostlos aus und designmäßig nicht der große
       Hit." Die Antwort darauf ist TIEFE, nicht Farbe – die Regel „keine Farbe
       ohne Bedeutung" (DESIGN §1) bleibt unangetastet. */
    --shadow-ticket: 0 1px 2px rgba(20, 26, 28, .07), 0 1px 1px rgba(20, 26, 28, .04);
    --overlay: rgba(27, 30, 32, .45);

    --radius: 6px;

    /* --------------------------------------------------------------------
       DER ZENTRALE CONTAINER – die gemeinsame senkrechte Achse der Seite.
       Menüleiste UND Seiteninhalt nehmen exakt diese Breite (siehe .content /
       .topbar-inner). Wer einen neuen Bereich baut, hängt ihn in .content –
       er darf nicht selbst eine Breite erfinden, sonst sitzt er schief.
       -------------------------------------------------------------------- */
    --content-max: 70rem;   /* 1120px – bewusst schmal (Nutzerwunsch; vorher 80rem/1280px) */
    /* Nur fuer die Produktseite (DESIGN §41). Sie liegt IM Token-Block, weil
       DESIGN §2 verlangt, dass Token an einer Stelle stehen – ein zweiter
       :root-Block am Dateiende waere ein zweiter Ort fuer dieselbe Frage.
       Keine Farben, deshalb kein Eintrag im Dunkel-Block noetig. */
    --pw-lesebreite: 42rem; /* Lesebreite fuer Fliesstext (~110 Zeichen) */
    --pw-atem: 4.5rem;      /* Abstand zwischen zwei Abschnitten – EIN Wert */

    /* ---------------------------------------------------------------------
       DIE PRODUKTSEITE: GRUND, SCHRIFTEN UND BAENDER (Handoff 0246, §41)
       ---------------------------------------------------------------------
       ⚠⚠ DIESE TOKEN GELTEN NUR AUF `body.pw-body`. Sie definieren KEINEN
       Haus-Token um – die Verwaltung sieht von alldem nichts. Der Grund, warum
       sie trotzdem hier stehen und nicht in einem zweiten Block am Dateiende:
       §2 verlangt EINEN Ort fuer Token.

       ⚠ WARMES PAPIER STATT WEISS. Das ist der Kern des Gestaltungsentwurfs
       („professionell, souveraen, farbig, nicht wie ein Krankenhaus").
       Gemessen auf #f4efe6: --ink 14,63 · --accent 6,38.
       ⚠⚠ UND DER BEFUND DAZU: die vier Bereichsfarben halten auf diesem Grund
       5,00 / 7,27 / 4,56 / **4,44** – „Aussenauftritt" liegt UNTER 4,5:1.
       Deshalb steht ein Bereichsname NIE auf dem Papier, sondern immer auf
       einer Kartenflaeche (DESIGN §41.8, zwei Waechter).

       ⚠ --pw-muted IST DUNKLER ALS --muted (#6f767b), und das ist gerechnet:
       auf dem Papier haelt --muted nur 4,03:1, --pw-muted 4,86:1.

       ⚠ DREI SCHRIFTEN, ALLES SYSTEMSCHRIFTEN. Es wird NICHTS nachgeladen –
       kein @font-face, kein CDN. Eine Werbeseite, die eine Schrift von einem
       fremden Host holt, verschickt die IP jedes Besuchers, bevor er ein Wort
       gelesen hat. Die Groteskschrift des Fliesstextes ist die Hausschrift und
       steht unveraendert am `body`.

       ⚠⚠ --pw-band-mix STEHT JE TOKEN-BLOCK, NICHT JE BEREICH. Weisse Schrift
       auf `color-mix(bereich 70%, #000)`: 9,23 / 12,02 / 8,62 / 8,47. Im
       Dunkelmodus sind die Bereichsfarben HELL, und derselbe Faktor ergaebe
       dort 3,48:1 – deshalb dort 55 % (5,66 / 6,72 / 5,22 / 5,76).
       Ein Faktor je Block bleibt EINE Wahrheit; vier je Block waeren vier
       (ADR-0043 §4.7.4). Ein Waechter rechnet beide Bloecke nach.
       --------------------------------------------------------------------- */
    --pw-papier: #f4efe6;
    --pw-muted: #63696e;
    --pw-serif: 'Iowan Old Style', Charter, Constantia, 'Hoefler Text', 'Palatino Linotype', Georgia, serif;
    --pw-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    /* Die dunkle Petrol-Flaeche der bereichslosen Seiten. Weiss darauf: 7,30. */
    --pw-hervor-bg: #1f5f63;
    --pw-hervor-leise: #dcebeb;   /* 5,96 auf --pw-hervor-bg */
    --pw-band-mix: 70%;
    --pw-band-ink: #ffffff;
    --pw-fuss-bg: #173f42;        /* weiss darauf 11,50 */
    --pw-fuss-ink: #ffffff;
    --pw-fuss-muted: #a9c4c5;     /* 6,24 auf --pw-fuss-bg */
    --content-pad: 1.5rem;  /* Seitenabstand; auf schmalen Schirmen kleiner (siehe unten) */

    /* --------------------------------------------------------------------
       DIE GEMEINSAME GRUNDLINIE ALLER STEUERELEMENTE.
       Eingabefeld, Auswahl-Menü, Textfeld und Button sind exakt gleich hoch.
       Wer ein neues Steuerelement baut, nimmt diese Höhe – nicht px.
       -------------------------------------------------------------------- */
    --h-control: 2.375rem;


    /* --------------------------------------------------------------------
       DIE VIER WEGWEISER-FARBEN (ADR-0043, Handoff 0230)
       --------------------------------------------------------------------
       Sie ordnen die Verwaltung nach Taetigkeiten – Menschen, Geld,
       Vorstandsarbeit, Aussenauftritt – und BEDEUTEN NICHTS. Sie stehen immer
       da, unabhaengig vom Zustand, immer neben dem ausgeschriebenen
       Bereichsnamen, und sie aendern sich nie.

       ⚠⚠ SIE SIND KEIN ZWEITER AKZENT. Der Akzent DER BEDIENUNG bleibt Petrol
       (`--accent`): Primaer-Knopf und Fokus-Ring. Merksatz aus ADR-0043:
       „Petrol sagt ‚hier bist du‘, die Bereichsfarbe sagt ‚worum geht es‘."
       Eine Farbe, die man ANKLICKEN kann, gehoert dem Haus; eine Farbe, die
       nur ZEIGT, ordnet.
       ⚠ NACHTRAG 30.08.2026 (Handoff 0232): der AKTIVE MENUEPUNKT ist aus
       diesem Satz herausgenommen und zum vierten Traeger geworden (siehe
       unten). Knopf und Fokus-Ring bleiben Petrol, ohne Ausnahme.

       ⚠⚠ SIE HABEN GENAU VIER ERLAUBTE TRAEGER (ADR-0043 §4.1 + Nachtrag 0232,
       DESIGN §40.1a): den Gruppennamen der Seitenleiste samt seinem Quadrat,
       die linke Kante der Dashboard-Kachel, den Punkt an einer
       Bereichsbeschriftung und den AKTIVEN MENUEPUNKT seiner Gruppe. NIE einen
       Knopf, einen Fokus-Ring, eine Status-Pille, eine Angabe im Fliesstext,
       eine Tabellenzeile, ein PDF, die oeffentliche Seite oder eine E-Mail.
       Ein Waechter haelt das am Stylesheet und an den Vorlagen fest:
       tests/Feature/Design/BereichsfarbeNurAlsWegweiserTest.php.

       ⚠ SEIT 0232 IST DIE BEREICHSFARBE AUCH SCHRIFT (Gruppenname, aktiver
       Punkt) – und damit gilt fuer sie die TEXT-Schwelle 4,5:1, nicht mehr die
       3:1 fuer grafische Formen (WCAG 1.4.11). Gemessen:
         kraeftig gegen #ffffff / #f4f5f5
           menschen 5,73/5,25 · geld 8,33/7,63 · vorstand 5,23/4,78 · aussen 5,09/4,66
         auf der eigenen Toenung des aktiven Punktes (9 % ueber Weiss)
           menschen 5,08 · geld 7,24 · vorstand 4,65 · aussen 4,53
       ⚠ DIE VIER WERTE SIND UNVERAENDERT GEBLIEBEN. Sie wirken trotzdem
       kraeftiger als vor 0232, weil die helle Leiste sie nicht mehr aufhellt.
       Geringster Abstand untereinander 66 (sRGB, euklidisch), geringster
       Abstand zu einer Hausfarbe 55 (menschen zu --accent).

       ⚠ AB ETAPPE 2 (0232) UEBERSCHREIBT DER VEREIN DIESE VIER WERTE. Sie
       stehen hier als VORGABE; wer in „Einstellungen -> Erscheinungsbild"
       einen anderen Satz waehlt, bekommt seine vier Werte als
       Custom-Properties in den `<head>` gelegt (layouts/app, EINE Zeile,
       ausschliesslich aus App\Design\Bereichsfarben::current()). Der Rest
       dieses Stylesheets liest weiterhin nur `var(--bereich-*)` und merkt
       nichts davon.

       ⚠ OCKER IST DURCHGEFALLEN. ADR-0043 §4.5 schlug fuer den Aussenauftritt
       `#8a6a3f` vor und nannte ihn selbst „den kritischen Ton": er lag 49 von
       `--warn-ink` und 44 von `--alter-2` entfernt – naeher an Bernstein als
       die vier Bereichsfarben untereinander. Ersetzt durch Beere `#a1567a`
       (Abstand zu `--warn-ink` 109, zu `--danger` 81). Ersetzt wurde der TON,
       nicht die Regel.
       ⚠ GELD IST BEWUSST NICHT GRUEN: Gruen am Geld laese sich als „alles in
       Ordnung" – und das waere eine Bedeutung, die diese Farbe nicht haben darf.

       Die Werte stehen ein zweites Mal in `App\Design\Bereichsfarben`; ein
       Waechter vergleicht beide Listen Zeichen fuer Zeichen.
       -------------------------------------------------------------------- */
    --bereich-menschen: #2f6b96;
    --bereich-geld: #5d3f86;
    --bereich-vorstand: #46783f;
    --bereich-aussen: #a1567a;

    /* ⚠ DER AUFGEHELLTE SATZ HAT IM TAGMODUS SEIT 0232 KEINEN TRAEGER MEHR.
       Er stand auf der frueheren dunkelpetrolfarbenen Leiste; die ist hell
       geworden und traegt jetzt den kraeftigen Satz. Er bleibt hier als
       VORRAT FUER DEN DUNKELMODUS stehen (dort ist er der kraeftige, siehe
       den Dunkel-Block) – geloescht waere er beim ersten Dunkelmodus-Schritt
       neu zu messen. */
    --bereich-menschen-hell: #86c3ea;
    --bereich-geld-hell: #b39be6;
    --bereich-vorstand-hell: #9ed291;
    --bereich-aussen-hell: #f0a3bd;

    /* --------------------------------------------------------------------
       DIE SEITENLEISTE (Handoff 0230, AUF HELL UMGESTELLT 30.08.2026 / 0232)
       --------------------------------------------------------------------
       Die Verwaltungsnavigation steht seit dem 29.08.2026 LINKS statt oben.

       ⚠⚠ IHR GRUND IST WEISS, NICHT PETROL. 0230 hatte sie dunkelpetrol
       gebaut – das war eine ANNAHME aus dem Auftragssatz „in der farbigen
       Leiste sind die Punkte aufgehellt" und nicht der Entwurf, den der Nutzer
       gewaehlt hatte. Er hat das beanstandet („soweit ich mich erinnere war die
       mir vorgefuehrte Vorlage etwas farbenfroher, und kein gruener Balken?").
       Der gewaehlte Entwurf hat einen HELLEN Grund, eine Trennlinie zur
       Arbeitsflaeche und Schrift in normaler Textfarbe.
       ~~--leiste-bg: #17454a; --leiste-line: #24595e; --leiste-ink: #e9f1f1;
       --leiste-muted: #a6c5c7; --leiste-hover: #1f5257;
       --leiste-aktiv-bg: #2b6e73~~ – abgeloest am 30.08.2026.

       ⚠ FOLGE FUER DIE BEREICHSFARBEN: auf hellem Grund braucht die Leiste
       KEINE aufgehellten Toene mehr. Die vier `.seitenleiste
       .bereichspunkt-*`-Ueberschreibungen sind ersatzlos entfallen; die Leiste
       traegt jetzt denselben KRAEFTIGEN Satz wie die Kachelkante. Deshalb wirkt
       die Farbe staerker als vorher – genau das war der Wunsch.
       `--bereich-*-hell` bleibt als Vorrat fuer den Dunkelmodus stehen.

       ⚠ „HIER BIST DU" IST NICHT MEHR NUR PETROL. Der aktive Menuepunkt traegt
       seit 0232 die Bereichsfarbe seiner Gruppe (sehr helle Toenung als
       Flaeche, die Farbe selbst als Schrift) – der VIERTE Traeger der
       Bereichsfarbe, nachgetragen in DESIGN §0/§17/§40.1a und im Waechter.
       Petrol bleibt der Akzent DER BEDIENUNG (Knopf, Fokus-Ring) und traegt
       weiterhin die zwei bereichslosen Punkte „Start" und „Einstellungen"
       (ADR-0043 §4.3: keine Bereichsfarbe ohne Bereich).

       Gemessen gegen --leiste-bg #ffffff: --leiste-ink 16,76 · --leiste-muted
       4,61 · --leiste-aktiv-ink auf --leiste-aktiv-bg 8,30.
       -------------------------------------------------------------------- */
    --leiste-bg: #ffffff;
    --leiste-line: #e4e7e7;
    --leiste-ink: #1b1e20;
    --leiste-muted: #6f767b;
    --leiste-hover: #f0f2f2;
    /* Die zwei bereichslosen Punkte („Start", „Einstellungen") aktiv: Petrol,
       dieselben zwei Werte wie jede andere Akzentflaeche des Hauses. */
    --leiste-aktiv-bg: #dcebeb;
    --leiste-aktiv-ink: #16484b;
    /* ⚠ WIE HELL DIE TOENUNG DES AKTIVEN BEREICHS-PUNKTES IST – EIN WERT, EINE
       STELLE. Aus ihm rechnet der Browser die Flaeche (color-mix mit
       `transparent`, dasselbe Mittel wie public.css §20.5); ein Waechter
       rechnet ihn nach und prueft, dass die Bereichsfarbe auf ihrer eigenen
       Toenung 4,5:1 traegt (der Punkt ist TEXT, keine Form).
       Gemessen ueber #ffffff: menschen 5,08 · geld 7,24 · vorstand 4,65 ·
       aussen 4,53. Bei 10 % faellt „aussen" auf 4,47 und damit unter die
       Schwelle – deshalb 9 % und nicht die rundere Zahl. */
    --leiste-aktiv-mix: 9%;
    --leiste-breite: 15rem;

    /* Eigener Pfeil für <select>. Muss ein Bild sein (currentColor geht in einer
       data-URI nicht), deshalb je Modus eine eigene Variante. Lucide chevron-down. */
    --select-arrow: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236f767b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

/* -----------------------------------------------------------------------------
   DUNKEL-TOKENS – VORRAT, DERZEIT NICHT AKTIV.

   WARUM SIE HIER LIEGEN: Die App ist bewusst IMMER hell (Nutzerwunsch). Der
   frühere Automatik-Dunkelmodus (`@media (prefers-color-scheme: dark)`) ist
   deshalb ENTFERNT – er hat die Seite ungefragt umgefärbt, sobald das System
   des Nutzers dunkel stand.

   WAS DAS HIER IST: dieselben Werte, nur an einen Selektor gehängt, den
   AKTUELL NICHTS SETZT. Es gibt in der ganzen App kein `data-theme`-Attribut –
   dieser Block ist also wirkungslos, bis jemand ihn bewusst einschaltet.

   WIE MAN IHN SPÄTER EINSCHALTET (bewusster Umschalter, nicht Automatik):
   `<html data-theme="dark">` setzen (Nutzer-Einstellung persistieren) – mehr
   ist nicht nötig, alle Farben hängen bereits an Tokens. Zusätzlich muss dann
   das `<meta name="color-scheme" content="light">` in den beiden Layouts
   mitgezogen werden, sonst bleiben Formularfelder/Scrollbalken hell.

   Wer hier Farben ändert, ändert NICHTS am sichtbaren Erscheinungsbild.
   -------------------------------------------------------------------------- */
[data-theme="dark"] {
    color-scheme: dark;

    --page: #16181a;
    --card: #1c1f21;
    --ink: #e8eaea;
    --muted: #8d9498;
    --line: #26292b;
    --line-strong: #32363a;
    --hover: #24282a;

    --accent: #4c9a9e;
    --on-accent: #06201f;
    --accent-soft: #22403f;
    --accent-ink: #9ed4d5;
    /* Vorrat wie der ganze Dunkel-Block: derzeit wirkungslos (kein Element
       setzt `data-theme`), aber vollstaendig, damit der Blitz beim Umschalten
       nicht auf einen leeren Wert faellt. */
    --accent-blitz: #2f5a59;

    --nav-bg: #1c1f21;
    --nav-line: #2a2e30;

    --th-bg: #202325;

    --ok-bg: #22403f;
    --ok-ink: #9ed4d5;
    --off-bg: #292d2f;
    --off-ink: #8d9498;
    --warn-bg: #3a3427;
    --warn-ink: #d9bd7e;

    /* Startseite-Stern (Aktiv-Zustand, Handoff 0058) – heller im Dunkelmodus */
    --star-gold: #e6c24c;

    /* Alterung eines Aufgaben-Tickets – Vorrat, siehe heller Block (Handoff 0209,
       auf den Punkt umgestellt 0210, auf die Liegezeit-Angabe umgestellt 0212).
       Die Regel aus DESIGN §2 verlangt jede neue Farbe in BEIDEN Blöcken, auch
       solange der dunkle wirkungslos ist: sonst bricht ein späterer Dunkelmodus
       sofort. Auch hier trägt Stufe 3 genau den Wert von --warn-ink.
       ⚠ 0212: --alter-1 und --alter-2 sind DUNKLER geworden (#6b5a30 -> #4e4120,
       #a0842f -> #7d6528), weil sie jetzt Text tragen: mit --ink (hell im
       Dunkelmodus) darauf stehen sie bei 8,28:1 bzw. 4,62:1; mit den alten
       Werten lag Stufe 2 bei 2,98:1. Die Leiter läuft im Dunkelmodus von dunkel
       nach hell – deshalb kippt die Schriftfarbe erst bei Stufe 3 auf --card.
       ⚠ 0213: HIER IST DIE LEITER EBENFALLS AUSEINANDERGEZOGEN, aber NICHT
       gleichmaessig – und das hat einen harten Grund. Die Gesamtspanne ist im
       Dunkelmodus 7,63:1, gleichmaessig waeren 1,97 je Schritt; dann truege
       Stufe 2 aber ein --ink (hell) bei nur 2,97:1, also unlesbaren Text. Die
       OBERGRENZE fuer Stufe 2 ist deshalb die Lesbarkeit (4,6:1), und die zwei
       unteren Schritte teilen sich den Rest gleichmaessig.
       Nachbarstufen jetzt: 1,58 / 1,58 / 3,06 (vorher 1,39 / 1,79 / 3,06).
       Text auf Stufe 1 / 2: 7,28:1 / 4,62:1.
       ⚠ Der Dunkel-Block ist Vorrat (kein Element setzt `data-theme`); diese
       Werte sind GERECHNET, nicht am Schirm angesehen. */
    /* ⚠ Auch hier ist --alter-3 mit Handoff 0217 entfallen – siehe heller
       Block. Im Dunkelmodus traegt Stufe 3 `--danger-ink` (#e08b8b) mit
       `--on-danger` (#16181a): Text 7,16:1, Nachbarkontrast Stufe 2 -> 3 =
       2,19:1 (vorher 3,06:1). GERECHNET, nicht am Schirm gesehen – der dunkle
       Block ist Vorrat. */
    --alter-1: #5b481b;
    --alter-2: #806425;

    --danger: #b45454;
    --on-danger: #16181a;
    --danger-bg: #402525;
    --danger-ink: #e08b8b;

    --shadow: 0 10px 30px rgba(0, 0, 0, .45);
    /* ⚠ IM DUNKELN TRAEGT EIN SCHATTEN WENIGER (schwarz auf fast schwarz), aber
       er traegt. Deshalb derselbe Aufbau, nur kraeftiger – und die eigentliche
       Abgrenzung des Tickets uebernimmt dort der Rahmen (`--line-strong`).
       Vollstaendig eingetragen, obwohl der Dunkelmodus derzeit wirkungslos ist
       (DESIGN §2: jede neue Farbe in BEIDEN Bloecken). */
    --shadow-ticket: 0 1px 2px rgba(0, 0, 0, .35), 0 1px 1px rgba(0, 0, 0, .25);
    --overlay: rgba(0, 0, 0, .6);


    /* Wegweiser-Farben – Vorrat wie der ganze Dunkel-Block (DESIGN §2: jede
       neue Farbe in BEIDEN Bloecken, auch solange der dunkle wirkungslos ist).
       ⚠ AUF DUNKLEM GRUND IST DER KRAEFTIGE SATZ DER AUFGEHELLTE: `--card`
       (#1c1f21) und `--page` (#16181a) tragen die dunklen Toene des hellen
       Blocks nicht (unter 3:1). Deshalb stehen hier beide Token auf denselben
       Werten – EIN Wert je Bereich, zwei Gruende (ADR-0043 §5.1/§5.5).
       GERECHNET, nicht am Schirm gesehen: gegen #1c1f21 / #16181a
       menschen 8,69/9,33 · geld 6,90/7,42 · vorstand 9,53/10,24 · aussen 8,43/9,05. */
    --bereich-menschen: #86c3ea;
    --bereich-geld: #b39be6;
    --bereich-vorstand: #9ed291;
    --bereich-aussen: #f0a3bd;

    --bereich-menschen-hell: #86c3ea;
    --bereich-geld-hell: #b39be6;
    --bereich-vorstand-hell: #9ed291;
    --bereich-aussen-hell: #f0a3bd;

    /* Die Seitenleiste – im Dunkelmodus die KARTENFLAECHE, nicht ein eigener
       Ton: sie ist seit 0232 im Tagmodus weiss (also `--card`), und das
       dunkle Gegenstueck von Weiss ist `--card`. Ein eigener Petrolton waere
       hier eine zweite Bauform.
       ~~--leiste-bg: #123a3e; --leiste-line: #1d4b4f; --leiste-ink: #e2ecec;
       --leiste-muted: #93b4b6; --leiste-hover: #17474b;
       --leiste-aktiv-bg: #235e63~~ – abgeloest am 30.08.2026.
       Ebenfalls Vorrat: kein Element setzt `data-theme`. */
    --leiste-bg: #1c1f21;
    --leiste-line: #2a2f31;
    --leiste-ink: #e7eaec;
    --leiste-muted: #8d9498;
    --leiste-hover: #23282a;
    --leiste-aktiv-bg: #17383a;
    --leiste-aktiv-ink: #9fd4d6;
    --leiste-aktiv-mix: 18%;
    --leiste-breite: 15rem;

    /* DIE PRODUKTSEITE IM DUNKELN – Vorrat, derzeit nicht aktiv (§2 verlangt
       jede Farbe in BEIDEN Bloecken).
       ⚠ --pw-band-mix ist hier 55 %, nicht 70 %: die Bereichsfarben sind im
       Dunkel-Block HELL, und 70 % ergaeben weisse Schrift auf mittelhellem
       Blau mit 3,48:1. Bei 55 % sind es 5,66 / 6,72 / 5,22 / 5,76.
       ⚠ Die zwei SCHRIFT-Token stehen bewusst NUR im hellen Block: sie sind
       keine Farben, und §2 verlangt die Verdopplung fuer Farben. */
    --pw-papier: #16181a;
    --pw-muted: #9aa1a5;          /* 6,79 auf --pw-papier, 6,32 auf --card */
    --pw-hervor-bg: #1c4446;      /* weiss darauf 10,69 */
    --pw-hervor-leise: #9ed4d5;   /* 6,53 auf --pw-hervor-bg */
    --pw-band-mix: 55%;
    --pw-band-ink: #ffffff;
    --pw-fuss-bg: #101f21;        /* weiss darauf 16,94 */
    --pw-fuss-ink: #ffffff;
    --pw-fuss-muted: #a9c4c5;     /* 9,18 auf --pw-fuss-bg */

    --select-arrow: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238d9498' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

/* =============================================================================
   2. GRUNDGERÜST
   ========================================================================== */
* { box-sizing: border-box; }

/* Alpine `x-cloak`: hält ein Element verborgen, bis Alpine seinen `x-show`-/
   `x-if`-Zustand ausgewertet hat – ohne das blitzt der aufgeklappte Zustand
   kurz auf. Genutzt vom einklappbaren Metadaten-Kopf des Sitzungsprotokolls
   (ADR-0025/R1). */
[x-cloak] { display: none !important; }

/* Scrollbalken-Rinne IMMER reservieren. Ohne das verliert eine LANGE Seite (Formular,
   Feldliste) rechts ~15px an den Scrollbalken, während eine KURZE Seite (Liste,
   Dashboard) die volle Breite behält – der zentrierte Container springt beim
   Seitenwechsel um ein paar Pixel seitlich, Menü und Inhalt „wackeln". `stable`
   hält die Breite konstant, egal ob gerade gescrollt werden muss. Damit haben ALLE
   Seiten dieselbe linke und rechte Kante. */
html { scrollbar-gutter: stable; }

body {
    margin: 0;
    min-height: 100vh;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: var(--page);
    color: var(--ink);
    -webkit-font-smoothing: antialiased;
    line-height: 1.55;
}

a { color: var(--accent); }

h1 { font-size: 1.35rem; font-weight: 600; letter-spacing: -.015em; margin: 0; }
h2 { font-size: 1rem; font-weight: 600; letter-spacing: -.01em; margin: 0 0 .4rem; }

/* --- DER ZENTRALE CONTAINER ------------------------------------------------
   Beide Klassen teilen sich EINE Breite: der Seiteninhalt (.content) und der
   Inhalt der Menüleiste (.topbar-inner). Genau deshalb sitzen Logo, Menüpunkte
   und die Tabelle darunter auf derselben senkrechten Achse. Wer einer der
   beiden eine eigene Breite/Polsterung gibt, macht die Seite schief.
   --------------------------------------------------------------------------- */
.content,
.topbar-inner {
    width: 100%;
    max-width: var(--content-max);
    margin-inline: auto;
    padding-inline: var(--content-pad);
}

/* --- Navigationsleiste oben (löst die dunkle Seitenleiste ab) ---------------
   .topbar trägt NUR Fläche und Trennlinie – die laufen über die VOLLE Breite
   (durchgehende Leiste). Ausgerichtet wird erst innen, in .topbar-inner. */
.topbar {
    background: var(--nav-bg);
    border-bottom: 1px solid var(--nav-line);
}
.topbar-inner {
    display: flex;
    align-items: center;
    gap: 1.75rem;
    flex-wrap: wrap;
}

/* Markenblock ZWEIZEILIG: Vereinsname (Zeile 1) über „Vereinsverwaltung"
   (Zeile 2, kleiner + gedämpft). Deshalb column, nicht row. */
.brand {
    display: flex;
    flex-direction: column;
    gap: 0;
    padding: .8rem 0;
    line-height: 1.2;
    color: var(--ink);
}
.brand .brand-name { font-weight: 650; font-size: .95rem; letter-spacing: -.01em; }
.brand small { font-weight: 400; font-size: .72rem; color: var(--muted); }

/* DAS HAUPTMENÜ BRICHT UM (Bestandsfehler aus Handoff 0024, dort gemessen).

   `flex-wrap: wrap` ist hier kein Schönheitswunsch, sondern die Ursache-Behebung
   für „die Seite scrollt bei ≤ 360 px rund 50 px waagerecht" – ein Verstoß gegen
   DESIGN §3 („Die Seite scrollt NIE waagerecht"), sichtbar auf JEDER Seite
   (Dashboard, Mitglieder, Newsletter – überall exakt gleich, weil das Menü im
   Layout steht und nicht in einer Seite).

   DIE MECHANIK, die man kennen muss: Ein Flex-Element hat `min-width: auto`, und
   das löst sich zur MIN-CONTENT-Breite auf. Für einen NICHT umbrechenden
   Flex-Container ist die min-content-Breite die SUMME aller Kinder – hier also
   Dashboard + Mitglieder + Newsletter + Einstellungen + Abstände = 379 px
   (gemessen). Unter dieses Maß ging das Menü nicht, `flex: 1` hin oder her:
   `flex-shrink` darf die min-content-Breite nicht unterschreiten. Bei 360 px
   Bildschirm (328 px nutzbar) blieben 51 px übrig, die die ganze Seite aufzogen.

   Mit `wrap` ist die min-content-Breite nur noch der BREITESTE EINZELNE Punkt
   („Einstellungen", ~86 px) – die Punkte legen sich bei Bedarf in eine zweite
   Zeile, statt die Seite zu sprengen. Eine Medienabfrage braucht es dafür nicht:
   der Umbruch passiert genau dann, wenn er nötig ist.

   `min-width: 0` ist die Absicherung derselben Regel für den Fall, dass ein
   künftiger Menüpunkt selbst länger ist als der Bildschirm. */
.mainnav { display: flex; gap: 1.4rem; flex: 1; flex-wrap: wrap; min-width: 0; }
.mainnav a {
    display: block;
    text-decoration: none;
    color: var(--muted);
    font-size: .875rem;
    font-weight: 500;
    padding: 1.15rem .1rem;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}
.mainnav a:hover { color: var(--ink); }
/* Aktiver Punkt: Akzentfarbe + 2px Unterstrich. Das ist die ganze Markierung. */
.mainnav a.active { color: var(--accent); border-bottom-color: var(--accent); }

/* Aufklapp-Menüpunkt „Außenauftritt" (Handoff 0059): bündelt Website,
   Bekanntmachungen, Veranstaltungen und Newsletter, damit die Kopfleiste
   EINZEILIG bleibt (vorher brach sie bei 7 Punkten auf zwei Zeilen um). Reines
   Alpine (die Verwaltung darf JS, nur die öffentliche Seite ist JS-frei); Optik
   und Verhalten wie das ⋮-Gestaltungs-Popover (`.col-menu`/`.nl-gestaltung-
   popover`): position:absolute, Karte, Schatten, Escape + click.outside
   schließen. Der Auslöser ist ein <button>, sieht aber aus wie ein `.mainnav a`
   (gleiche Farbe/Größe, 2px-Unterstrich im Aktiv-Zustand). */
.nav-dropdown { position: relative; display: flex; }
.nav-dropdown-trigger {
    display: inline-flex; align-items: center; gap: .3rem;
    border: 0; background: transparent; cursor: pointer;
    font: inherit; font-size: .875rem; font-weight: 500;
    color: var(--muted);
    padding: 1.15rem .1rem;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}
.nav-dropdown-trigger:hover { color: var(--ink); }
.nav-dropdown-trigger.active { color: var(--accent); border-bottom-color: var(--accent); }
.nav-dropdown-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nav-dropdown-chevron { width: 1rem; height: 1rem; flex: 0 0 auto; }
/* Das Popover ist rechnerisch an der linken Kante des Auslösers verankert.
   `max-width: calc(100vw - 2rem)` deckelt es gegen schmale Viewports, damit die
   rechte Kante NICHT aus dem Bild läuft (kein waagerechtes Scrollen, DESIGN §3). */
.nav-dropdown-menu {
    position: absolute; left: 0; top: calc(100% + .3rem); z-index: 30;
    min-width: 14rem; max-width: calc(100vw - 2rem);
    background: var(--card);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: .45rem;
}
.nav-dropdown-item {
    display: block; padding: .5rem .6rem; border-radius: var(--radius);
    font-size: .85rem; font-weight: 500; color: var(--ink); text-decoration: none;
    white-space: nowrap;
}
.nav-dropdown-item:hover { background: var(--hover); }
.nav-dropdown-item.active { color: var(--accent-ink); background: var(--accent-soft); font-weight: 600; }

.who { display: flex; align-items: center; gap: .6rem; font-size: .82rem; color: var(--muted); }
.who-name { white-space: nowrap; }
.avatar {
    width: 1.8rem; height: 1.8rem; border-radius: 50%;
    background: var(--accent-soft); color: var(--accent-ink);
    display: grid; place-items: center;
    font-size: .68rem; font-weight: 650; letter-spacing: .02em;
}
.logout-btn {
    border: 1px solid var(--line-strong);
    background: transparent;
    color: var(--muted);
    font: inherit; font-size: .8rem;
    padding: .3rem .6rem;
    border-radius: var(--radius);
    cursor: pointer;
}
.logout-btn:hover { background: var(--hover); color: var(--ink); }

/* =============================================================================
   DIE SEITENLEISTE (`.huelle`/`.seitenleiste`/`.seitennav*`, Handoff 0230)
   =============================================================================
   Die Verwaltungsnavigation steht seit dem 29.08.2026 LINKS statt oben, und sie
   ist nach TAETIGKEITEN geordnet statt nach Modulen: Menschen · Geld ·
   Vorstandsarbeit · Aussenauftritt. Darueber der Vereinsname, darunter „Start"
   und „Einstellungen" – die zwei Punkte, die zu keinem Bereich gehoeren.

   ⚠⚠ DIE KOPFLEISTE (`.topbar`) IST NICHT ENTFALLEN. Sie kleidet weiterhin die
   MITGLIEDER-HUELLE (`$mitglied = true`, Feature 0021 Paket 4): ein angemeldetes
   Mitglied sieht Vereinsname, „Mitglieder-Zugang", seine zwei Punkte und
   „Abmelden" – genau wie vorher, unveraendert. Es bekommt von dieser
   Seitenleiste NICHTS ab; sie steht in `layouts/app` innerhalb von
   `@unless ($mitglied)`. Das ist die Bedingung, unter der DESIGN §20.6 die
   Verwaltungshuelle fuer eine Mitgliederseite ueberhaupt erlaubt.

   ⚠ WARUM WIEDER EINE SEITENLEISTE, NACHDEM DIE DUNKLE 2026 ABGESCHAFFT WURDE:
   weil die Kopfleiste mit vier Gruppen und vierzehn Punkten nicht mehr
   einzeilig zu halten war und der Nutzer die Seitenleiste aus mehreren
   Entwuerfen ausdruecklich gewaehlt hat (ADR-0043, Eskalation 2).
   ⚠⚠ UND SIE IST SEIT DEM 30.08.2026 (0232) HELL. Die dunkelpetrolfarbene
   Flaeche aus 0230 war eine Annahme, kein Entwurf – der Nutzer hat sie
   beanstandet. DESIGN §1 („Die fruehere dunkle Seitenleiste ist entfallen")
   gilt damit wieder ohne Einschraenkung: es gibt keine dunkle Leiste mehr.

   ⚠ DER INHALT BLEIBT IM ZENTRALEN CONTAINER. `.content` (--content-max)
   zentriert sich weiterhin selbst – nur eben in der verbleibenden Spalte. Wer
   hier eine eigene Breite erfindet, macht die Seite schief (§3).
   ========================================================================== */
.huelle {
    display: grid;
    grid-template-columns: var(--leiste-breite) minmax(0, 1fr);
}

/* ⚠ `minmax(0, 1fr)` IST PFLICHT, KEIN SCHMUCK: eine Grid-Spalte hat als
   Voreinstellung `min-width: auto` und schrumpft NICHT unter die Breite ihres
   Inhalts. Eine breite Mitgliedertabelle wuerde die Spalte aufziehen und die
   ganze Seite waagerecht scrollen lassen – genau das schliesst §3 aus.
   Dieselbe Falle wie bei `.settings-layout`. */

.seitenleiste {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    overflow-y: auto;
    background: var(--leiste-bg);
    color: var(--leiste-ink);
    /* ⚠ DIE TRENNLINIE IST PFLICHT, SEIT DIE LEISTE HELL IST (0232): weisse
       Leiste neben `--page` (#f4f5f5) waere sonst nur ein zarter Helligkeits-
       sprung. Sie ist dieselbe Haarlinie wie die frueher untere Linie der
       Kopfleiste (`--nav-line`) – keine zweite Bauform. */
    border-right: 1px solid var(--leiste-line);
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1rem .8rem 1.1rem;
}

/* ⚠ KEIN `overflow` AUF `.huelle` ODER `main`. Ein Vorfahr mit `overflow` haelt
   das Ziehen auf dem Aufgaben-Board (SortableJS) an der falschen Stelle fest
   und macht `position: sticky` unwirksam. Das Scrollen bleibt, wo es hingehoert:
   in der Leiste selbst und in `.table-scroll`. */

.seitenleiste-kopf { display: flex; align-items: center; justify-content: space-between; gap: .75rem; }

/* Der Markenblock ist derselbe wie in der Kopfleiste (`.brand`) – deshalb hier
   nur der Innenabstand und die zwei Farb-Token, keine zweite Bauform. */
.seitenleiste .brand { padding: .15rem 0 .15rem .35rem; color: var(--leiste-ink); }
.seitenleiste .brand small { color: var(--leiste-muted); }

/* DER SCHALTER FUER SCHMALE SCHIRME. Auf breiten Schirmen gibt es ihn nicht –
   dort steht das Menue ohnehin offen. Er traegt Wort UND Zeichen, ist also kein
   Icon-Knopf (§9: kein Kuerzel ohne Vollnamen). */
.leiste-schalter {
    display: none;
    align-items: center; gap: .4rem;
    border: 1px solid var(--leiste-line);
    background: transparent;
    color: var(--leiste-ink);
    font: inherit; font-size: .82rem; font-weight: 500;
    padding: .3rem .6rem;
    border-radius: var(--radius);
    cursor: pointer;
}
.leiste-schalter:hover { background: var(--leiste-hover); }
/* ⚠ SEIT 0232 WIEDER `--accent`, NICHT `--accent-blitz`. Auf der frueheren
   petrolfarbenen Leiste waere Petrol auf Petrol unsichtbar gewesen; auf hellem
   Grund ist der Fokus-Ring des Hauses richtig – und Petrol IST der Akzent der
   Bedienung (ADR-0043 §1.4). */
.leiste-schalter:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.leiste-schalter-icon { width: 1.05rem; height: 1.05rem; flex: 0 0 auto; }

.seitenleiste-klapp { display: flex; flex-direction: column; gap: 1rem; flex: 1; min-height: 0; }

.seitennav { display: flex; flex-direction: column; gap: 1rem; }

/* Eine Gruppe: der Name mit seinem Quadrat, darunter die Punkte des Bereichs. */
.seitennav-gruppe { display: flex; flex-direction: column; gap: .1rem; }
.seitennav-gruppenname {
    display: flex; align-items: center; gap: .45rem;
    margin: 0 0 .25rem;
    padding: 0 .55rem;
    font-size: .72rem; font-weight: 650;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--leiste-muted);
}

/* -----------------------------------------------------------------------------
   TRAEGER 1: DER GRUPPENNAME TRAEGT SEINE BEREICHSFARBE SELBST (Handoff 0232)
   -----------------------------------------------------------------------------
   ⚠ BIS 0230 WAR ES NUR DER PUNKT DANEBEN, der Name blieb grau. Der Nutzer
   wollte den Entwurf, den er gewaehlt hatte: kleine Versalien IN DER FARBE DES
   BEREICHS, davor ein kleines farbiges Quadrat.

   ⚠ DAS IST KEINE AUFWEICHUNG DER REGEL, SONDERN IHRE STRENGSTE FORM.
   DESIGN §0 (Nachtrag 0212): „Farbe braucht einen Traeger, der ohnehin gelesen
   wird." Hier ist der Traeger das WORT „GELD" selbst – die Farbe kann gar nicht
   allein stehen, weil sie auf dem Klartext sitzt, den sie meint. Ein stummer
   Punkt daneben war das schwaechere Mittel.
   Gemessen gegen --leiste-bg #ffffff (TEXT, also 4,5:1):
     menschen 5,73 · geld 8,33 · vorstand 5,23 · aussen 5,09.
   -------------------------------------------------------------------------- */
.seitennav-gruppenname-menschen { color: var(--bereich-menschen); }
.seitennav-gruppenname-geld { color: var(--bereich-geld); }
.seitennav-gruppenname-vorstand { color: var(--bereich-vorstand); }
.seitennav-gruppenname-aussen { color: var(--bereich-aussen); }

.seitennav-punkt {
    display: block;
    padding: .38rem .55rem;
    border-radius: var(--radius);
    font-size: .875rem; font-weight: 500;
    color: var(--leiste-ink);
    text-decoration: none;
}
.seitennav-punkt:hover { background: var(--leiste-hover); }
/* ⚠ SEIT 0232 `--accent` statt `--accent-blitz` – siehe .leiste-schalter. */
.seitennav-punkt:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* „Hier bist du" OHNE BEREICH – „Start" und „Einstellungen" gehoeren zu keiner
   Gruppe (ADR-0043 §4.3: kein Grau als fuenfte Farbe, schlicht nichts) und
   tragen deshalb den Akzent DES HAUSES. Das ist zugleich der Rueckfall fuer
   jeden Punkt ohne Bereichs-Zusatzklasse. */
.seitennav-punkt.active { background: var(--leiste-aktiv-bg); color: var(--leiste-aktiv-ink); font-weight: 650; }

/* -----------------------------------------------------------------------------
   TRAEGER 4: DER AKTIVE MENUEPUNKT TRAEGT DIE FARBE SEINER GRUPPE (Handoff 0232)
   -----------------------------------------------------------------------------
   ⚠⚠ DAS IST EINE ERWEITERUNG DER TRAEGERLISTE AUS ADR-0043 §4.1, und sie ist
   NICHT STILL PASSIERT: der Nutzer hat den Entwurf so gewaehlt, DESIGN §0/§17
   und §40.1a sind fortgeschrieben, der Waechter kennt den Traeger namentlich.
   ADR-0043 §4.2 fuehrte „der aktive Zustand" bis dahin als VERBOTENEN Traeger
   („wo bin ich" bleibt Petrol). Was davon bleibt: Knopf und Fokus-Ring sind und
   bleiben Petrol – die Bedienung gehoert dem Haus. Was faellt: der Menuepunkt
   ist kein Bedienelement im Sinne dieser Grenze, sondern die ANZEIGE, in
   welchem Bereich man steht – dieselbe Aussage, die der Gruppenname darueber in
   derselben Farbe macht.
   ⚠ DER ADR BRAUCHT DAFUER EINEN DATIERTEN NACHTRAG (offen, Handoff 0232).

   ⚠ DIE FLAECHE IST GERECHNET, NICHT GETIPPT: `color-mix` mit `transparent`
   erzeugt die Toenung aus der Bereichsfarbe selbst. Dadurch zieht sie
   automatisch mit, wenn ein Verein eigene Farben setzt (Etappe 2/3) – es gibt
   KEINEN zweiten Wert, den jemand pflegen muesste, und keine
   Ableitungs-Rechnung in PHP (ADR-0043 §1.1/§5.5). Dasselbe Mittel benutzt
   public.css §20.5 fuer die Trennlinien des Stils „gefuellt".
   -------------------------------------------------------------------------- */
.seitennav-punkt.active.seitennav-aktiv-menschen {
    background: color-mix(in srgb, var(--bereich-menschen) var(--leiste-aktiv-mix), transparent);
    color: var(--bereich-menschen);
}
.seitennav-punkt.active.seitennav-aktiv-geld {
    background: color-mix(in srgb, var(--bereich-geld) var(--leiste-aktiv-mix), transparent);
    color: var(--bereich-geld);
}
.seitennav-punkt.active.seitennav-aktiv-vorstand {
    background: color-mix(in srgb, var(--bereich-vorstand) var(--leiste-aktiv-mix), transparent);
    color: var(--bereich-vorstand);
}
.seitennav-punkt.active.seitennav-aktiv-aussen {
    background: color-mix(in srgb, var(--bereich-aussen) var(--leiste-aktiv-mix), transparent);
    color: var(--bereich-aussen);
}

.seitenleiste-fuss {
    margin-top: auto;
    padding-top: .9rem;
    border-top: 1px solid var(--leiste-line);
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
}
.seitenleiste .who { color: var(--leiste-muted); flex: 1; min-width: 0; }
.seitenleiste .who-name { overflow: hidden; text-overflow: ellipsis; }
.seitenleiste .avatar { background: var(--leiste-aktiv-bg); color: var(--leiste-aktiv-ink); }
.seitenleiste .logout-btn { border-color: var(--leiste-line); color: var(--leiste-muted); }
.seitenleiste .logout-btn:hover { background: var(--leiste-hover); color: var(--leiste-ink); }

/* -----------------------------------------------------------------------------
   DAS BEREICHSQUADRAT – TEIL VON TRAEGER 1 (ADR-0043 §4.1, Form geaendert 0232)
   -----------------------------------------------------------------------------
   8 px, unmittelbar links vom Wort. ⚠ ES STEHT NIE ALLEIN: der ausgeschriebene
   Bereichsname steht daneben, immer – und traegt seit 0232 DIESELBE Farbe. Das
   Quadrat traegt `aria-hidden`; es sagt der Vorlesefunktion nichts, weil es
   nichts SAGT. Die Farbe ordnet.

   ⚠ AUS DEM PUNKT IST EIN QUADRAT GEWORDEN (`border-radius: 2px` statt 50 %) –
   so sah der Entwurf aus, den der Nutzer gewaehlt hat. DIE KLASSE HEISST
   WEITERHIN `.bereichspunkt`: der Name steht in DESIGN §17, in drei Tests und
   in der Gegenprobe der Mitglieder-Huelle; ein Umbenennen waere Bewegung ohne
   Gewinn. „Bereichspunkt" ist im Haus der BEGRIFF, nicht die Formbeschreibung.

   ⚠ EINE HELLIGKEIT, EIN GRUND: seit die Leiste hell ist (0232), gilt ueberall
   der kraeftige Satz. Die vier frueheren Ueberschreibungen
   `.seitenleiste .bereichspunkt-* { background: var(--bereich-*-hell) }` sind
   ersatzlos entfallen.
   -------------------------------------------------------------------------- */
.bereichspunkt {
    width: .5rem; height: .5rem;
    border-radius: 2px;
    flex: 0 0 auto;
}
.bereichspunkt-menschen { background: var(--bereich-menschen); }
.bereichspunkt-geld { background: var(--bereich-geld); }
.bereichspunkt-vorstand { background: var(--bereich-vorstand); }
.bereichspunkt-aussen { background: var(--bereich-aussen); }

/* -----------------------------------------------------------------------------
   TRAEGER 5 + 6: DER BEREICH DER SEITE, AUF DER MAN STEHT (Handoff 0233,
   ADR-0043 §4.1 Nachtrag vom 30.08.2026)
   -----------------------------------------------------------------------------
   ⚠⚠ `--bereich-hier` IST EIN ZEIGER, KEINE FUENFTE FARBE. Er steht bewusst
   NICHT in `:root` und in keinem Token-Block: eine Seite OHNE Bereich soll ihn
   gar nicht haben, damit ueberall dort der Rueckfall greift
   (`var(--bereich-hier, var(--accent))` = Petrol). Stuende er in `:root`,
   truege das Dashboard eine erfundene Bereichsfarbe – genau das schliesst
   ADR-0043 §4.3 aus.

   Gesetzt wird er von der Arbeitsflaeche (`layouts/app`, `.content`), und zwar
   aus DERSELBEN Tabelle, aus der die Seitenleiste ihren aktiven Punkt holt
   (`App\Design\Bereichsfarben::ROUTEN`). Es gibt keine zweite Zuordnung.

   ⚠ ER VERERBT SICH. Alles innerhalb der Arbeitsflaeche kann ihn lesen – heute
   tut das genau eine Sache: der aktive Reiter. Wer eine zweite hinzunimmt,
   braucht dafuer einen ADR (die Traegerliste ist abschliessend) und einen
   Eintrag im Waechter.
   -------------------------------------------------------------------------- */
.inhalt-bereich-menschen { --bereich-hier: var(--bereich-menschen); }
.inhalt-bereich-geld { --bereich-hier: var(--bereich-geld); }
.inhalt-bereich-vorstand { --bereich-hier: var(--bereich-vorstand); }
.inhalt-bereich-aussen { --bereich-hier: var(--bereich-aussen); }

/* TRAEGER 5: der Bereichsname ueber der Ueberschrift der Seite.
   Dieselbe Schrift wie der Gruppenname der Seitenleiste (kleine Versalien,
   gesperrt), damit man dasselbe Wort an beiden Orten als dasselbe erkennt –
   und davor dasselbe kleine Quadrat (`.bereichspunkt`).
   ⚠ Er steht nur da, wenn die Seite wirklich zu einem Bereich gehoert; sonst
   rendert `layouts/app` die Zeile gar nicht erst. */
.seitenkopf-bereich {
    display: flex; align-items: center; gap: .45rem;
    margin: 0 0 .3rem;
    font-size: .72rem; font-weight: 650;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--bereich-hier, var(--muted));
}

/* -----------------------------------------------------------------------------
   SCHMALE SCHIRME: DIE LEISTE KLAPPT ZU
   -----------------------------------------------------------------------------
   Sie wird zu einer Zeile ueber dem Inhalt; das Menue erscheint erst auf einen
   Klick. Reines Alpine, dasselbe Muster wie die frueheren Aufklappgruppen
   (Escape schliesst). Kein zweites Markup, keine zweite Navigation – dieselben
   Punkte, nur anders angeordnet.
   ⚠ 60rem, nicht 40rem: bei 15rem Leiste plus Inhalt wird es darunter eng,
   lange bevor der uebliche Handy-Umbruch greift.
   -------------------------------------------------------------------------- */
@media (max-width: 60rem) {
    .huelle { grid-template-columns: 1fr; }
    .seitenleiste {
        position: static;
        height: auto;
        overflow: visible;
        gap: .6rem;
        padding: .55rem var(--content-pad) .6rem;
        /* Die Trennlinie wandert mit: quer ueber dem Inhalt statt neben ihm. */
        border-right: 0;
        border-bottom: 1px solid var(--leiste-line);
    }
    .leiste-schalter { display: inline-flex; }
    .seitenleiste-klapp { display: none; }
    .seitenleiste.offen .seitenleiste-klapp { display: flex; }
    .seitenleiste-fuss { margin-top: 0; }
}

/* --- Inhaltsfläche ---------------------------------------------------------
   KEIN seitliches Padding an main: der Seitenabstand kommt ausschließlich aus
   dem Container (.content). Zwei Polsterungen übereinander würden den Inhalt
   gegen die Menüleiste verschieben – genau das soll der Container verhindern.
   Breite/Zentrierung von .content stehen oben im Container-Block. */
main { padding: 1.6rem 0 2.5rem; }

/* Schmale Schirme: weniger Rand, sonst bleibt für den Inhalt zu wenig übrig. */
@media (max-width: 40rem) {
    :root { --content-pad: 1rem; }
}

.page-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; margin-bottom: 1.25rem; flex-wrap: wrap;
}
.page-head .count { font-size: .82rem; color: var(--muted); font-weight: 400; margin-left: .5rem; }

/* --- Einstellungen: gruppierte Navigation links, Inhalt rechts (Feedback 0018)
   ---------------------------------------------------------------------------
   Loest die frueheren ZWEI GESTAPELTEN REITER-REIHEN (.subnav + .subnav-2) ab:
   Reiter unter Reitern liessen die Hierarchie im Unklaren und zeigten die
   Unterpunkte erst, nachdem man eine Sektion gewaehlt hatte. Jetzt steht alles
   auf einen Blick untereinander.

   `minmax(0, 1fr)` fuer die Inhaltsspalte ist PFLICHT, kein Schmuck: eine
   Grid-Spalte hat als Voreinstellung `min-width: auto` und schrumpft damit NICHT
   unter die Breite ihres Inhalts. Eine breite Mitglieder-/Felder-Tabelle wuerde
   die Spalte aufziehen und die ganze Seite waagerecht scrollen lassen – genau
   das, was DESIGN.md §3 ausschliesst. Mit minmax(0, …) bleibt das Scrollen dort,
   wo es hingehoert: in .table-scroll. */
.settings-layout {
    display: grid;
    grid-template-columns: 11rem minmax(0, 1fr);
    gap: 2.5rem;
    align-items: start;
}

/* Auf schmalen Schirmen: Navigation ueber den Inhalt, nicht daneben. */
@media (max-width: 55rem) {
    .settings-layout { grid-template-columns: 1fr; gap: 1.25rem; }
    .settings-nav {
        display: flex; flex-wrap: wrap; gap: 1.25rem 2rem;
        padding-bottom: 1.1rem;
        border-bottom: 1px solid var(--line-strong);
    }
}

/* `min-width: 0` am Inhalt selbst gehoert zu `minmax(0, 1fr)` an der Spalte dazu:
   die Spur darf schrumpfen, das Grid-ELEMENT darin aber erst mit dieser Zeile
   (Voreinstellung `min-width: auto`). Ohne beides zusammen laeuft eine breite
   Tabelle aus dem Raster heraus. */
.settings-content { min-width: 0; }

.settings-nav { display: grid; gap: 1.1rem; align-content: start; }
.settings-nav-group { display: grid; gap: .15rem; }

/* Gruppenueberschrift: dezent, klein, gedaempft – und nicht klickbar. Sie ordnet
   nur, sie fuehrt nirgendwohin. */
.settings-nav-title {
    margin: 0 0 .2rem;
    font-size: .7rem; font-weight: 600;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted);
}

.settings-nav-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .1rem; }
.settings-nav-list a {
    display: block;
    text-decoration: none; color: var(--ink);
    font-size: .85rem; font-weight: 500;
    padding: .35rem .5rem;
    border-radius: var(--radius);
    /* Haarlinie links als Traeger der Aktiv-Markierung – im Ruhezustand
       unsichtbar, damit der Eintrag beim Aktivieren nicht springt. */
    border-left: 2px solid transparent;
}
.settings-nav-list a:hover { background: var(--hover); }
.settings-nav-list a:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Aktiver Eintrag: Petrol als einziger Akzent (DESIGN.md §1/§2). */
.settings-nav-list a.active {
    color: var(--accent-ink); background: var(--accent-soft);
    border-left-color: var(--accent); font-weight: 600;
}

/* Reiter-Filter (Einstellungen -> Felder, Handoff 0016 §2): schaltet die
   angezeigten Felder nach Mitglied-Typ um. Reiter INNERHALB einer Seite (reiner
   Sichtfilter, Haarlinie + Petrol als aktiver Reiter) – als <button> statt <a>,
   weil hier keine URL gewechselt, sondern eine Livewire-Eigenschaft gesetzt wird.
   NICHT zu verwechseln mit der Einstellungs-Navigation (`.settings-nav`, wechselt
   echte Routen und steht seit Feedback 0018 links neben dem Inhalt). */
.tab-filter {
    display: flex; flex-direction: row; gap: 1.2rem;
    margin: 0 0 1.1rem;
    border-bottom: 1px solid var(--line-strong);
}
.tab-filter button {
    background: none; border: none; cursor: pointer; font-family: inherit;
    color: var(--muted); font-size: .85rem; font-weight: 500;
    padding: .55rem .1rem;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}
.tab-filter button:hover { color: var(--ink); }
/* ⚠ TRAEGER 6: der AKTIVE Reiter traegt die Bereichsfarbe der Seite, auf der er
   steht (ADR-0043 §4.1 Nachtrag 30.08.2026, Handoff 0233). `--bereich-hier`
   setzt die Arbeitsflaeche (`.inhalt-bereich-*`, siehe dort); auf einer Seite
   OHNE Bereich ist der Zeiger nicht gesetzt und der Rueckfall ist PETROL –
   Einstellungen -> Felder bleibt deshalb unveraendert. Der Fokus-Ring darunter
   bleibt in JEDEM Fall Petrol: er ist Bedienung (ADR-0043 §1.4). */
.tab-filter button.active {
    color: var(--bereich-hier, var(--accent));
    border-bottom-color: var(--bereich-hier, var(--accent));
}
.tab-filter button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Vorstandsarbeit (ADR-0024 R3): die Reiter-Leiste ist eine `.tab-filter`. Zwei
   dezente Zutaten: ein kleiner Punkt am Reiter, wenn die Liste oeffentlich ist,
   und die „+ Liste"-Aktion am Ende der Leiste (schiebt sich per margin-left:auto
   nach rechts, bleibt aber Teil derselben Leiste). Reine Tokens, keine Insel. */
.tab-filter .tab-punkt { color: var(--accent); margin-left: .3rem; font-weight: 700; }
.tab-filter .tab-neu { margin-left: auto; color: var(--muted); }
.tab-filter .tab-neu:hover { color: var(--accent); }
.tab-filter .tab-neu .icon { width: .95rem; height: .95rem; vertical-align: -.15rem; margin-right: .2rem; }

/* Sitzungen-Modul-Reiter (ADR-0025 §8): route-wechselnde Reiter (Protokolle ·
   Beschluss-Register). Optik wie `.tab-filter button`, aber `<a>` – sie wechseln
   echte Routen (wire:navigate), kein In-Page-Toggle. */
.tab-filter a.reiter {
    color: var(--muted); font-size: .85rem; font-weight: 500;
    padding: .55rem .1rem; border-bottom: 2px solid transparent;
    margin-bottom: -1px; text-decoration: none;
}
.tab-filter a.reiter:hover { color: var(--ink); }
/* ⚠ TRAEGER 6, zweite Bauform (route-wechselnde Reiter) – dieselbe Regel wie
   oben, derselbe Rueckfall auf Petrol. */
.tab-filter a.reiter.active {
    color: var(--bereich-hier, var(--accent));
    border-bottom-color: var(--bereich-hier, var(--accent));
}
.tab-filter a.reiter:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Prominente Modul-Reiter (Feedback 0113): die dezente Haarlinien-Reiterleiste des
   Sitzungen-Moduls war zu unauffällig. `.modul-reiter` macht daraus eine klar
   erkennbare Karteireiter-Leiste (Ordner-Optik: aktiver Reiter als „vorne"
   liegendes Blatt in --card, Umrandung bis auf die Grundlinie). Nur ein Modifikator
   auf `.tab-filter` – die In-Page-`.tab-filter button` bleiben unberührt. Reine
   Tokens (--card/--line-strong/--th-bg/--accent), keine Insel. */
.tab-filter.modul-reiter { gap: .3rem; align-items: flex-end; }
.tab-filter.modul-reiter a.reiter {
    font-size: .9rem; font-weight: 600;
    padding: .5rem .9rem;
    border: 1px solid transparent; border-bottom: none;
    border-radius: 7px 7px 0 0;
    margin-bottom: -1px;
}
.tab-filter.modul-reiter a.reiter:hover { color: var(--ink); background: var(--th-bg); }
/* ⚠⚠ TRAEGER 6, dritte Bauform – UND HIER GIBT ES KEINE UNTERSTREICHUNG.
   Die Karteireiter-Leiste (`.modul-reiter`, Buchhaltung/Sitzungen/Website)
   legt den aktiven Reiter als Blatt VOR die Grundlinie; sein unterer Rand hat
   die Farbe der Karte darunter (`--card`) und verschmilzt mit ihr. Eine farbige
   Linie an dieser Stelle waere kein Wegweiser, sondern ein zerschnittener
   Ordner. Getragen wird die Bereichsfarbe deshalb vom WORT – was ohnehin der
   staerkere Traeger ist (DESIGN §0: „ein Traeger, der ohnehin gelesen wird").
   ⚠ Wer hier `border-bottom-color` auf die Bereichsfarbe setzt, macht genau
   diesen Fehler; die Reihenfolge im Stylesheet laesst es zu. */
.tab-filter.modul-reiter a.reiter.active {
    color: var(--bereich-hier, var(--accent)); background: var(--card);
    border-color: var(--line-strong); border-bottom-color: var(--card);
}
.tab-filter.modul-reiter a.reiter.active:hover { background: var(--card); }

/* „Zurück zur Liste" (Feedback 0113): ein klar sichtbarer Zurück-Link mit Pfeil am
   Kopf der Formular-/Detailansichten des Sitzungen-Moduls (ersetzt den früheren
   unscheinbaren Textlink). Kein Button-Kasten, aber deutlich: Akzentfarbe, der Pfeil
   rückt beim Hover ein Stück nach links. */
.back-link {
    display: inline-flex; align-items: center; gap: .35rem;
    margin: 0 0 .8rem; text-decoration: none;
    color: var(--accent); font-size: .9rem; font-weight: 600;
}
.back-link:hover { text-decoration: underline; }
.back-link .icon {
    width: 1rem; height: 1rem;
    transition: transform .12s ease;
}
.back-link:hover .icon { transform: translateX(-2px); }
.back-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* =============================================================================
   3. STEUERELEMENTE – alle auf derselben Grundlinie
   =============================================================================
   URSACHE DES ALTEN FEHLERS: <select> rendert ohne `appearance: none` sein
   eigenes Betriebssystem-Widget und ignoriert dabei Höhe und Innenabstand –
   deshalb waren die Auswahl-Menüs in der Filterzeile niedriger als die
   Eingabefelder. Behoben wird das an der Wurzel: appearance:none + eigener
   Pfeil (--select-arrow). Keine Pixel-Flickerei.
   ========================================================================== */
label {
    display: block;
    font-weight: 600;
    font-size: .8rem;
    margin-bottom: .3rem;
    color: var(--ink);
}

input[type=text], input[type=email], input[type=search], input[type=date], input[type=time],
input[type=password], input[type=number], input[type=tel], input[type=url], select, textarea {
    width: 100%;
    height: var(--h-control);          /* EINE Höhe … */
    padding: 0 .65rem;                 /* … gleiche Innenabstände … */
    border: 1px solid var(--line-strong); /* … gleicher Rahmen … */
    border-radius: var(--radius);
    background: var(--card);
    color: var(--ink);
    font-family: inherit;
    font-size: .9rem;
    line-height: 1.2;
    -webkit-appearance: none;
    appearance: none;                  /* auch für date/search: sonst eigenwilliges Widget */
}

select {
    background-image: var(--select-arrow);
    background-repeat: no-repeat;
    background-position: right .6rem center;
    padding-right: 2.1rem;             /* Platz für den eigenen Pfeil */
    cursor: pointer;
}
/* Firefox: den nativen Pfeil ausblenden, falls appearance nicht greift. */
select:-moz-focusring { color: transparent; text-shadow: 0 0 0 var(--ink); }

textarea {
    height: auto;
    min-height: calc(var(--h-control) * 2.4);
    padding: .55rem .65rem;
    line-height: 1.5;
    resize: vertical;
}

input::placeholder, textarea::placeholder { color: var(--muted); }

/* … und derselbe Fokus-Ring bei allen. */
input:focus-visible, select:focus-visible, textarea:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
}

input[type=checkbox] { accent-color: var(--accent); width: 1rem; height: 1rem; }
input[type=checkbox]:disabled { cursor: not-allowed; opacity: .45; }
input[type=checkbox]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* AUSWAHLKNOEPFE TRAGEN DENSELBEN AKZENT (Handoff 0191). Bis dahin galt
   `accent-color` nur fuer das Kontrollkaestchen – ein Radio stand in der
   BLAUEN Vorgabefarbe des Browsers. Aufgefallen ist es, als im
   Veranstaltungs-Editor ein Radio-Paar („Sichtbarkeit") unmittelbar ueber drei
   Kontrollkaestchen zu stehen kam: zwei Farben fuer dieselbe Art Entscheidung,
   auf einem Blick. Es ist dieselbe eine Farbe wie ueberall (§2) und keine neue
   Regel – nur eine, die ein Element bisher uebersprungen hat. */
input[type=radio] { accent-color: var(--accent); width: 1rem; height: 1rem; }
input[type=radio]:disabled { cursor: not-allowed; opacity: .45; }
input[type=radio]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --- DATUMSFELD („Kanzlei"-Datumswähler, `<x-datum-feld>`, DESIGN §29) ------
   Handoff 0131. Markup: resources/views/components/datum-feld.blade.php,
   Verhalten: public/js/datum-feld.js (Alpine `datumFeld`).

   WARUM ES DAS GIBT: `<input type="date">` klappt den Kalender des BETRIEBS-
   SYSTEMS auf – die einzige Fläche der Oberfläche, die diese Datei nicht
   erreicht (kein Selektor, kein Token, keine Schrift). Nutzer-Befund: „der
   kalender soll dem design der seite entsprechen".

   DAS BLATT SCHWEBT (Handoff 0132) – es verändert den Seitenfluss NICHT.
   0131 hatte es bewusst in den Fluss gestellt; dann rutschte beim Aufklappen
   der Formularinhalt weg, und genau das hat der Nutzer zurückgewiesen („es soll
   nicht springen"). Jetzt: `position: fixed` – NICHT `absolute`. Absolut würde
   es an der scrollenden `.modal-overlay` abgeschnitten (Popover-Falle §13/§18);
   `fixed` entkommt dem, muss dafür aber von public/js/schwebeblatt.js am Feld
   verankert und beim Scrollen nachgeführt werden (dort steht auch der Nachweis,
   dass kein Vorfahr `transform`/`filter`/`contain` trägt – sonst hinge `fixed`
   an diesem Vorfahren und das Blatt wäre doch abgeschnitten).
   `top`/`left` setzt deshalb JavaScript; im CSS stehen nur die Startwerte.

   Der Kalenderknopf IM Feld ist weiterhin absolut positioniert – nach demselben
   Prinzip wie der eigene Pfeil des `<select>` (--select-arrow).

   EBENE 40: über den Aufklappmenüs der Seite (Spaltenmenü/Navigation, 30),
   unter dem Newsletter-Spaltenvorhang (46), dem Modal-Overlay (50) und dem
   Detail-Fenster (60). Innerhalb eines Overlays zählt ohnehin nur „über dem
   Formularinhalt" – `.modal-overlay` bildet mit `z-index: 50` einen eigenen
   Stapelzusammenhang. Dieselbe Ebene benutzt die schwebende ⓘ-Erklärung.

   Alle Farben sind Tokens, keine neue Farbe, kein neues Icon (Lucide `calendar`,
   `chevron-left/right` gab es schon). */
.datum-feld { position: relative; }
.datum-eingabe { position: relative; }

/* Platz für den Kalenderknopf im Feld. */
.datum-eingabe .datum-text { padding-right: 2.5rem; }
/* Auf Telefon/Tablet macht der Adapter wieder ein natives `type=date` daraus
   (bewusst, siehe Kopf von datum-feld.js) – dann sitzt dort das Symbol des
   Betriebssystems und der reservierte Platz entfällt. */
.datum-eingabe .datum-text.ist-nativ { padding-right: .65rem; }
/* Unlesbare Eingabe: stiller roter Rahmen. Der SATZ dazu kommt beim Speichern
   vom Server (`.field-error`) – hier entsteht keine zweite Fehlerquelle. */
.datum-text.ist-ungueltig { border-color: var(--danger); }

.datum-knopf {
    position: absolute; top: 50%; right: .3rem; transform: translateY(-50%);
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.85rem; height: 1.85rem;
    padding: 0; border: 0; border-radius: var(--radius);
    background: transparent; color: var(--muted); cursor: pointer;
}
.datum-knopf:hover { background: var(--hover); color: var(--ink); }
.datum-knopf:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.datum-kalender {
    position: fixed; top: 0; left: 0; z-index: 40;
    width: 17rem; max-width: calc(100vw - 1.5rem);
    padding: .5rem;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    background: var(--card);
    box-shadow: var(--shadow);
}
.datum-kalender[hidden] { display: none; }

.datum-kopf { display: flex; align-items: center; gap: .25rem; margin-bottom: .35rem; }
.datum-monat { flex: 1; text-align: center; font-size: .85rem; font-weight: 650; color: var(--ink); }
.datum-nav {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.85rem; height: 1.85rem; flex: none;
    padding: 0; border: 0; border-radius: var(--radius);
    background: transparent; color: var(--muted); cursor: pointer;
}
.datum-nav:hover { background: var(--hover); color: var(--ink); }
.datum-nav:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.datum-raster { width: 100%; table-layout: fixed; border-collapse: collapse; }
.datum-raster th {
    padding: .2rem 0; text-align: center;
    font-size: .68rem; font-weight: 650; letter-spacing: .04em;
    text-transform: uppercase; color: var(--muted);
}
.datum-raster td { padding: 1px; }
.datum-tag {
    display: block; width: 100%; height: 1.95rem;
    padding: 0; border: 1px solid transparent; border-radius: var(--radius);
    background: transparent; color: var(--ink);
    font-family: inherit; font-size: .82rem; line-height: 1; cursor: pointer;
}
.datum-tag:hover { background: var(--hover); }
/* Der Fokus-Ring liegt INNEN (`outline-offset: -1px`): außen überlappte er im
   engen Raster die Nachbartage. */
.datum-tag:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; }
/* Tage des Vor-/Folgemonats – sichtbar, aber zurückgenommen; anklickbar bleiben
   sie (das ist der bequeme Weg über die Monatsgrenze). */
.datum-tag.ist-fremd { color: var(--muted); }
.datum-tag.ist-heute { border-color: var(--line-strong); font-weight: 700; }
.datum-tag.ist-gewaehlt {
    background: var(--accent); border-color: var(--accent);
    color: var(--on-accent); font-weight: 650;
}
.datum-tag.ist-gewaehlt:hover { background: var(--accent); }

.datum-fuss { display: flex; justify-content: flex-end; margin-top: .4rem; }
.datum-heute { height: 1.95rem; padding: 0 .7rem; font-size: .8rem; }

/* --- SUCHFELD (Kombinationsfeld mit Trefferliste, `<x-such-feld>`, §27.4) ---
   Handoff 0141. Markup: resources/views/components/such-feld.blade.php,
   Verhalten: public/js/such-feld.js (Alpine `suchFeld`).

   WARUM ES DAS GIBT: die Beschluss-Auswahl bestand aus ZWEI Feldern – einem
   Suchfeld und einem `<select>` daneben. Nutzer-Befund: „es sollte ein feld
   sein wo beides integriert ist, man kann direkt suchen und durch eingaben
   werden die möglichen treffer angezeigt".

   DER RAHMEN IST DAS FELD, nicht das `<input>`: er trägt Marke UND Eingabe und
   sieht deshalb aus wie ein gewöhnliches Steuerelement (dieselben Tokens,
   dieselbe Mindesthöhe --h-control, derselbe Fokus-Ring – nur über
   `:focus-within`, weil der Fokus im inneren Feld sitzt).

   DAS BLATT SCHWEBT – `position: fixed`, NICHT `absolute`: absolut würde es an
   der scrollenden `.modal-overlay` abgeschnitten (Popover-Falle §13/§18).
   Verankert und nachgeführt wird es von public/js/schwebeblatt.js; `top`/`left`
   setzt deshalb JavaScript, im CSS stehen nur die Startwerte. Ebene 40 wie das
   Kalenderblatt. Alles andere – Farbe, Rahmen, BREITE und Schrift – steht wie
   immer hier. */
.such-feld { position: relative; }

.such-eingabe {
    display: flex; flex-wrap: wrap; align-items: center; gap: .3rem;
    min-height: var(--h-control);
    padding: .18rem .25rem;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    background: var(--card);
}
.such-eingabe:focus-within { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

/* Das Eingabefeld IM Rahmen: kein zweiter Rahmen, keine zweite Höhe, kein
   zweiter Fokus-Ring (den trägt der Rahmen). Zwei Klassen schlagen die
   Grundregel `input[type=text]` – deshalb der zweiteilige Selektor. */
.such-eingabe .such-text {
    flex: 1 1 7rem; min-width: 5rem; width: auto;
    height: calc(var(--h-control) - .6rem);
    padding: 0 .4rem;
    border: 0; background: transparent;
}
.such-eingabe .such-text:focus-visible { outline: 0; border-color: transparent; }

/* DIE MARKE: der gewählte Eintrag, im selben Rahmen. Sie darf umbrechen – eine
   Beschlussbeschriftung ist lang („2026-003 · 12.03.2026 · Anschaffung …
   (Aufgehoben)"), und abgeschnitten wäre sie keine Bestätigung mehr. */
.such-marke {
    display: inline-flex; align-items: center; gap: .2rem;
    max-width: 100%;
    padding: .12rem .12rem .12rem .5rem;
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    background: var(--accent-soft);
    color: var(--ink); font-size: .82rem; line-height: 1.35;
}
.such-marke[hidden] { display: none; }
.such-marke-text { overflow-wrap: anywhere; }
.such-loeschen {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 1.35rem; height: 1.35rem;
    padding: 0; border: 0; border-radius: var(--radius);
    background: transparent; color: var(--muted); cursor: pointer;
}
.such-loeschen:hover { background: var(--hover); color: var(--ink); }
.such-loeschen:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.such-loeschen .icon { width: .85rem; height: .85rem; }

.such-blatt {
    position: fixed; top: 0; left: 0; z-index: 40;
    width: min(34rem, calc(100vw - 1.5rem));
    max-height: 15rem; overflow-y: auto;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    background: var(--card);
    box-shadow: var(--shadow);
}
.such-blatt[hidden] { display: none; }

.such-liste { list-style: none; margin: 0; padding: .25rem; }
.such-treffer {
    padding: .35rem .5rem;
    border-radius: var(--radius);
    color: var(--ink); font-size: .85rem; line-height: 1.35;
    overflow-wrap: anywhere; cursor: pointer;
}
.such-treffer:hover { background: var(--hover); }
/* Der hervorgehobene Treffer (Pfeiltasten). KEIN `:focus` – der Fokus bleibt im
   Eingabefeld, es wandert nur `aria-activedescendant`. */
.such-treffer.ist-aktiv { background: var(--accent); color: var(--on-accent); }

/* MIT `.such-blatt` DAVOR – `.modal p` ist Klasse + Element und damit
   spezifischer als eine einzelne Klasse; es gewönne sonst bei Abstand und
   Schriftgröße (dieselbe Spezifitätsfalle wie bei `.kennzahl-wert`, §28). */
.such-blatt .such-leer,
.such-blatt .such-lade { margin: 0; padding: .5rem .6rem; color: var(--muted); font-size: .84rem; }

/* --- Buttons: dieselbe Höhe wie die Eingabefelder -------------------------- */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
    height: var(--h-control);
    padding: 0 .9rem;
    border: 1px solid transparent;
    border-radius: var(--radius);
    font-family: inherit; font-size: .86rem; font-weight: 600; line-height: 1;
    text-decoration: none; white-space: nowrap; cursor: pointer;
}
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn-primary:hover { filter: brightness(1.08); }
.btn-secondary { background: var(--card); color: var(--ink); border-color: var(--line-strong); }
.btn-secondary:hover { background: var(--hover); }
.btn-danger { background: var(--danger); border-color: var(--danger); color: var(--on-danger); }
.btn-danger:hover { filter: brightness(1.08); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn .icon { width: 1rem; height: 1rem; }

/* NUR-ICON-KNOPF (`.btn-icon`, Feedback 0024) – ein QUADRATISCHER `.btn`, kein
   eigenes Element:

   Die Aktionsleiste und die Filterzeile der Mitgliederliste trugen breite
   Text-Knoepfe („Auswahl als CSV", „Export / Druck", …) und wirkten dadurch
   klobig (Nutzer-Befund 0024). Sie zeigen jetzt nur noch das Icon.

   Warum ein Modifikator von `.btn` und NICHT das `.icon-btn`-Muster der Tabelle?
   1. `.icon-btn` (1.95rem, rahmenlos) ist ein SEKUNDAeR-Element INNERHALB einer
      Zeile – rahmenlos ist dort richtig, weil die Zeile den Kontext gibt. In der
      Werkzeugleiste steht der Knopf frei; ohne Rahmen saehe ihn ein Erstnutzer
      nicht als Knopf. Deshalb: gleicher Rahmen/Radius/Fokus-Ring wie ein `.btn`.
   2. `.btn` haelt `--h-control` und steht damit auf DERSELBEN Grundlinie wie die
      Filterfelder daneben (DESIGN.md §4) – quadratisch, also `--h-control` breit.
   3. `.btn-primary`/`.btn-secondary`/`.is-disabled` gelten damit unveraendert
      weiter. Das „weich deaktiviert"-Muster (siehe unten) funktioniert ohne eine
      einzige Zeile Sonderbehandlung.

   PFLICHT: Ein Knopf ohne Text ist stumm. Jeder `.btn-icon` traegt `title` UND
   `aria-label` (DESIGN.md §9) – sonst ist er ein Raetsel, kein Bedienelement. */
.btn.btn-icon { width: var(--h-control); padding: 0; flex-shrink: 0; }
.btn-icon .icon { width: 1.05rem; height: 1.05rem; }

/* WEICH DEAKTIVIERT (`.is-disabled`, Feedback 0018) – ein eigenes Muster, kein
   Ersatz fuer `disabled`:

   Der Knopf SIEHT deaktiviert aus, BLEIBT aber klick- und fokussierbar. Genau das
   ist der Zweck: ein hart `disabled`-Knopf verschluckt den Klick, loest kein
   Ereignis aus und kann dem Nutzer deshalb nicht erklaeren, warum nichts passiert
   („kaputter Knopf"-Gefuehl). Wer `.is-disabled` setzt, MUSS die Aktion serverseitig
   abfangen und einen Hinweis geben (Beispiel: Aktionsleiste der Mitgliederliste ->
   MemberIndex::auswahlFehlt()).

   Fuer Screenreader gehoert `aria-disabled="true"` an denselben Knopf (nicht
   `disabled`), damit der Zustand angesagt wird und der Fokus erreichbar bleibt.
   Die :hover-Rueckmeldung wird zurueckgenommen, damit er sich nicht „aktiv" anfuehlt.

   NEBENWIRKUNG, DIE SEIT 0024 ZAEHLT: ein hart `disabled`-Knopf zeigt in mehreren
   Browsern auch seinen `title`-Tooltip nicht mehr. `aria-disabled` tut das nicht –
   der ausgegraute NUR-ICON-Knopf bleibt also erklaerbar (Tooltip am Zeiger, Klick-
   Hinweis auf Touch). Mit `disabled` waere ein Icon ohne Text voellig stumm. */
.btn.is-disabled { opacity: .5; cursor: not-allowed; }
.btn.is-disabled:hover { filter: none; }
.btn-secondary.is-disabled:hover { background: var(--card); }

/* --- Formulare ------------------------------------------------------------
   ALLE Panel-Seiten teilen sich die Container-Breite (--content-max): Liste,
   Formulare und Einstellungen stehen damit auf DERSELBEN linken/rechten Kante
   und derselben Achse wie die Menüleiste. Deshalb hat .form-panel KEINE eigene
   Maximalbreite mehr (früher 52rem -> Formular war schmaler als die Liste und
   linksbündig statt zentriert – genau der Nutzer-Befund). Wer hier wieder eine
   max-width setzt, bricht die gemeinsame Kante.

   Damit die Karte trotzdem nicht „endlos gestreckte" Eingabefelder zeigt, liegen
   die Felder in einem ZWEISPALTIGEN Raster (.form-row = Grid): z. B. Vorname |
   Nachname, PLZ | Ort. Ganzbreite nur, wo sinnvoll (Textfeld -> .form-field-wide).
   Auf schmalen Schirmen fällt das Raster auf eine Spalte zurück. */
.form-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem 1.25rem;
    margin-bottom: 1rem;
}
.form-field { margin-bottom: 1rem; min-width: 0; }
/* Im Raster übernimmt der Grid-Abstand (row-gap) das Vertikale – kein doppelter Rand. */
.form-row .form-field { margin-bottom: 0; }
/* .grow wird in der flex-basierten .inline-form (Mitgliedsart hinzufügen) genutzt
   – dort soll das Feld die freie Breite bis zum Button füllen. */
.form-field.grow { flex: 1 1 16rem; min-width: 16rem; }
/* Ganzbreite über beide Spalten (Notiz/Textfeld). */
.form-field.form-field-wide { grid-column: 1 / -1; }
.form-field.no-gap { margin-bottom: 0; }

/* DIE POSITIONSZEILE (Handoff 0179) -----------------------------------------
   Eine Rechnungsposition ist Menge | Einheit | Bezeichnung | Einzelpreis
   [| Umsatzsteuer] [| Entfernen] – fünf bis sechs verschieden breite Felder in
   EINER Zeile. Das ist kein Fall für `.form-row`: dessen Raster hat genau ZWEI
   gleich breite Spalten („Vorname | Nachname").

   ⚠ WARUM ES DIESE KLASSE GIBT. Bis 0179 lag die Positionszeile in einem
   `.form-row` und wurde mit fünf `style="max-width:…"` zu einer Tabellenzeile
   zurechtgebogen. Das war zweimal falsch: Inline-Styles sind in der Verwaltung
   verboten (DESIGN §1), und ein Deckel im Zweispalten-Raster BEGRENZT nur, er
   POSITIONIERT nicht – die Felder standen weiterhin in zwei Spalten und
   fluchteten von Zeile zu Zeile nicht.

   FLEX, NICHT GRID: welche Felder in der Zeile stehen, hängt vom Verein ab (die
   Steuerspalte gibt es nur bei Umsatzsteuerausweis, das Entfernen erst ab der
   zweiten Position, der Befreiungsgrund nur bei „befreit"). Ein festes
   Grid-Raster müsste für jede dieser Kombinationen eine eigene
   `grid-template-columns` mitbringen; Flex ordnet sich von selbst.

   SCHMALE SCHIRME BRAUCHEN KEINE MEDIA-QUERY: `flex-wrap` bricht die Zeile
   um, sobald sie nicht mehr passt. Die Basisbreiten sind so gewählt, dass
   Menge und Einheit auf 360 px NEBENEINANDER bleiben (2 × 5rem + Abstand) und
   Bezeichnung, Preis und Steuersatz je eine eigene Zeile bekommen. */
.positionszeile {
    display: flex; flex-wrap: wrap;
    gap: 1rem 1.25rem;
    align-items: flex-start;
    margin-bottom: 1rem;
}
/* Der senkrechte Abstand kommt aus dem Flex-Gap – kein doppelter Rand
   (dieselbe Regel wie `.form-row .form-field`). */
.positionszeile .form-field { margin-bottom: 0; flex: 0 0 auto; }
.positionszeile .pos-menge { flex: 0 0 5rem; }
.positionszeile .pos-einheit { flex: 0 0 6rem; }
/* Die Bezeichnung nimmt den Rest – sie trägt den längsten Text und ist das
   einzige Feld, das wachsen soll. `min-width: 0` verhindert, dass ihr Inhalt
   die Zeile über die Fensterbreite aufzieht. */
.positionszeile .pos-bezeichnung { flex: 1 1 12rem; min-width: 0; }
.positionszeile .pos-preis { flex: 0 0 8rem; }
.positionszeile .pos-steuer { flex: 0 0 10rem; }
/* Der Befreiungsgrund ist ein ganzer Satz und bekommt eine eigene Zeile. */
.positionszeile .pos-grund { flex: 1 1 100%; min-width: 0; }
/* Der Entfernen-Knopf ist nur so breit wie das Symbol. */
.positionszeile .pos-weg { flex: 0 0 auto; }

@media (max-width: 40rem) {
    .form-row { grid-template-columns: 1fr; }
    /* Auf dem Telefon dürfen Preis und Steuersatz die Zeile füllen, statt als
       schmale Reste neben viel Weissraum zu stehen. */
    .positionszeile .pos-preis,
    .positionszeile .pos-steuer { flex: 1 1 8rem; }
}
.form-actions { display: flex; gap: .6rem; margin-top: .5rem; align-items: center; flex-wrap: wrap; }
.inline-form { display: flex; gap: .75rem; align-items: flex-end; flex-wrap: wrap; }
.inline-input { max-width: 18rem; }
.inline-input-sm { max-width: 9.5rem; }
.beitrag-edit { display: flex; gap: .4rem; flex-wrap: wrap; }

/* ÄMTER-KATALOG (GremiumFunktionManager): Inline-Umbenennen ohne Zeilensprung.
   Der Bearbeiten-Modus tauscht in der Zeile nur den Namen gegen ein Eingabefeld
   und die 4 Anzeige-Icons (hoch/runter/bearbeiten/löschen) gegen 2 (speichern/
   abbrechen). Ohne feste Geometrie schrumpfte dabei die Aktionsspalte und die
   Zeile wurde höher – die Zeile „sprang" beim Klick auf Bearbeiten. Wir nageln
   die Geometrie in beiden Zuständen fest:
   – Bezeichnung nimmt die volle Restbreite (col-actions ist die einzige feste),
   – die Aktionsspalte reserviert die Breite ihrer 4 Anzeige-Icons
     (4 × 1.95rem + 3 × .15rem Lücke = 8.25rem), links ausgerichtet, damit der
     angeklickte Bearbeiten-Knopf an seiner Stelle bleibt,
   – jede Zeile reserviert die Höhe des Eingabefelds (--h-control), sodass der
     Wechsel Text→Input die Zeile nicht wachsen lässt.
   Bewusst klein & lokal (nur diese Tabelle): die Ämter-Seite wird evtl. bald mit
   „Rollen" zusammengelegt. */
table.data.katalog-inline th:first-child,
table.data.katalog-inline td:first-child { width: 100%; }
table.data.katalog-inline th.col-actions,
table.data.katalog-inline td.col-actions { width: 8.25rem; white-space: nowrap; }
table.data.katalog-inline tbody td { height: var(--h-control); }

.field-error { color: var(--danger-ink); font-size: .8rem; margin-top: .3rem; }
.field-error-block { margin-bottom: .75rem; }
.field-hint { color: var(--muted); font-size: .8rem; margin: .3rem 0 0; }
.req { color: var(--danger-ink); font-weight: 700; }
.static-value { margin: 0; padding: .3rem 0; }

/* Abschnitt im Mitglieder-Formular (Person / Kontakt / Adresse / …).
   Die Abschnitte kommen aus App\Enums\FieldGroup, nicht aus dem Markup. */
.form-section { margin-bottom: 1.25rem; }
.form-section + .form-section { border-top: 1px solid var(--line); padding-top: 1.25rem; }
.form-section h3 {
    font-size: .7rem; text-transform: uppercase; letter-spacing: .06em; font-weight: 650;
    color: var(--muted); margin: 0 0 .9rem;
}

/* Checkbox mit Text daneben (Ja/Nein-Felder, Pflicht-Haken) */
.check-label { display: flex; align-items: center; gap: .5rem; font-weight: 600; margin: 0; cursor: pointer; }
.check-label input[type=checkbox] { margin: 0; cursor: pointer; }

/* --- Filter-/Werkzeugleiste über der Tabelle -------------------------------
   KOMPAKT IN EINER ZEILE (Feedback 0024). Vorher stand über jedem Feld eine
   gestapelte Großbuchstaben-Beschriftung („MITGLIEDSART") und die Felder waren
   auf 11.5rem festgenagelt – für Filter, die meistens auf „Alle" stehen, war das
   sehr viel Fläche (Nutzer-Befund: „zu klobig").

   Jetzt: keine Beschriftung darüber, der Sinn steht IM Feld (die „Alle"-Option
   heißt „Mitgliedsart: Alle"), die Felder sind nur so breit wie ihr Inhalt, und
   alles sitzt auf EINER Grundlinie mit der Suche und den beiden Icon-Knöpfen.

   `align-items: center` (nicht `flex-end`): ohne Beschriftungen haben alle
   Elemente dieselbe Höhe (--h-control), es gibt keine Unterkante mehr, an der
   etwas auszurichten wäre. */
.list-toolbar {
    display: flex; align-items: center;
    gap: .5rem; margin-bottom: 1rem; flex-wrap: wrap;
}
.filters { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; min-width: 0; }

/* Die Suche ist das einzige Feld mit fester Breite – sie trägt einen langen
   Platzhalter und soll nicht mit jedem Tastendruck springen.

   `input.filter-search` UND NICHT `.filter-search` – der Elementteil ist hier
   Pflicht, kein Stil: die Basisregel oben adressiert das Feld als
   `input[type=search]` (Spezifität 0-1-1) und setzt `width: 100%`. Eine reine
   Klasse (0-1-0) verliert dagegen. Genau das ist im Browser-Durchgang zu 0024
   passiert: die Suche blieb 100% breit, drängte die Filter in eine zweite Zeile
   und die „eine Zeile" war futsch – im HTML sah alles richtig aus, gesehen hat
   man es erst im Screenshot. Wer hier eine Klasse ohne `input` davor schreibt,
   baut den Fehler nach.

   18rem ist AUSGEMESSEN, nicht geraten: der Platzhalter „Name, E-Mail oder
   Mitgliedsnummer" braucht rund 17rem: bei 15rem stand da „…Mitgliedsnu" und
   die Zeile sah abgeschnitten aus. Wer den Platzhalter aendert, misst neu. */
input.filter-search { width: 18rem; max-width: 100%; }

/* INHALTSBREITE statt starrer Breite: `width: auto` hebt die `width: 100%` der
   Basisregel auf; ein <select> misst sich dann an seiner breitesten Option. Der
   Deckel verhindert, dass eine sehr lang benannte Mitgliedsart die Zeile sprengt
   (der volle Wert steht im title-Tooltip).

   `select.filter-select` aus demselben Grund wie bei der Suche oben: den Element-
   teil mitschreiben, damit die Regel die Basisregel sicher schlägt und nicht bei
   der nächsten Ergänzung dort kippt. */
select.filter-select { width: auto; max-width: 13rem; text-overflow: ellipsis; }

/* AKTIVER FILTER (Feedback 0024): Petrol-Fläche + Rahmen, sobald NICHT „Alle"
   gewählt ist. Ohne das filtert man und merkt es nicht – die Liste zeigt dann
   stillschweigend zu wenig.

   `background-color` (NICHT die `background`-Kurzform!): `select` trägt seinen
   eigenen Pfeil als `background-image` (--select-arrow). Die Kurzform würde ihn
   mit zurücksetzen und das Feld verlöre seinen Pfeil. */
.filter-select.is-active {
    background-color: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent-ink);
    font-weight: 600;
}

/* DATUMSFILTER (Von/Bis) in der Filterzeile, z. B. Beschluss-Register. `input.filter-date`
   MIT Elementteil (0-2-0) schlägt die Basisregel `input[type=date]` (0-1-1), die sonst
   `width: 100%` erzwingen würde und die Datumsfelder über die Zeile sprengte – dasselbe
   Muster wie `input.filter-search` / `select.filter-select` oben. `width: auto` lässt das
   Feld auf seiner nativen Breite (Datum + Kalender-Icon) sitzen. */
input.filter-date { width: auto; }
input.filter-date.is-active {
    border-color: var(--accent);
    color: var(--accent-ink);
    font-weight: 600;
}

/* Die beiden Werkzeug-Knöpfe (Spalten, Export/Druck) rechts. `margin-left: auto`
   statt `justify-content: space-between` am Container: bricht die Zeile um, wird
   die Gruppe TROTZDEM nach rechts geschoben. Das ist Absicht und kein Zierrat –
   die Menüs darunter hängen mit `right: 0` am Knopf; säße der Knopf links außen,
   klappte ein 16rem breites Menü aus dem Bild. */
/* DIE WERKZEUGREIHE (Feedback 0025): Spalten · Export/Druck · CSV · Excel ·
   E-Mail, dazu der Auswahlstand.

   `flex-basis: 100%` – SIE BEKOMMT IHRE EIGENE ZEILE, und das ist AUSGEMESSEN,
   nicht Geschmack:

   Bei 70rem Inhalt (1072 px) belegen Suche + drei Filter 752 px, die fünf Icons
   216 px. Frei bleiben **104 px**. Die Auswahl-Pille braucht aber 127 px
   („3 ausgewählt") bis 249 px („Bitte zuerst Mitglieder auswählen.") – sie passt
   in KEINER Fassung dort hinein. Ohne eigene Zeile sprang die Reihe deshalb beim
   ERSTEN Klick auf ein Kästchen um 46 px nach unten, und mit ihr die ganze
   Tabelle. Schlimmer beim Klick auf ein ausgegrautes Icon: der Knopf, den man
   gerade gedrückt hat, rutscht unter dem Zeiger weg, und wer nachklickt, trifft
   ein Filterfeld. Gesehen im Browser-Durchgang, von keinem Test.

   Der Auftrag verlangt „die Aktions-Icons wandern in dieselbe Reihe wie
   ‚Spalten' und ‚Export / Druck'" – GENAU das tun sie hier. Die Filter sind eine
   andere Sache und keine Knöpfe; sie mit in die Zeile zu zwingen wäre Zufall
   gewesen, der nur solange hält, wie ein Verein kurze Mitgliedsarten hat.
   Eine feste Zeile ist ehrlicher als eine, die manchmal umbricht.

   `justify-content: flex-end` statt `margin-left: auto`: Die Menüs (`.col-menu`)
   hängen mit `right: 0` am Knopf – säße die Gruppe links außen, klappte ein
   16rem breites Menü aus dem Bild. */
.toolbar-actions {
    display: flex; gap: .4rem; align-items: center;
    flex-basis: 100%; flex-wrap: wrap;
    justify-content: flex-end;
    /* RUHIGE ICON-REIHE (Fix B): Die Höhe steht fest an den Knöpfen (--h-control),
       und der Auswahlstand liegt ABSOLUT (siehe .auswahl-stand) – so verschiebt
       weder sein Erscheinen noch der breitere Hinweis-Text je die Icons. Ohne das
       drängte der ~250px breite Hinweis „Bitte zuerst Mitglieder auswählen." die
       Icon-Reihe in eine zweite Zeile (Sprung nach unten) – nur im Browser sichtbar. */
    position: relative;
    min-height: var(--h-control);
}

/* DER AUSWAHLSTAND IN DER WERKZEUGREIHE (Feedback 0025).

   Der Nutzer wollte „alle Buttons in eine Reihe oben" und fand den Rahmen der
   eigenen Aktionsleiste (.bulkbar) unschön. Mit der Leiste ist auch der Platz
   verschwunden, an dem „3 Mitglieder ausgewählt" stand – und ohne diese Zahl
   sind drei Auswahl-Icons nicht zu deuten („Auswahl als …" – WELCHE Auswahl?).

   Sie steht deshalb als Pille in derselben Reihe, aber nur, wenn es etwas zu
   sagen gibt: bei Auswahl (petrol) oder nach einem Klick ohne Auswahl (amber,
   `.is-hinweis`). Ohne beides ist die Reihe still – der Ruhezustand ist der
   Normalfall und braucht keine Zeile über sich.

   `--accent-soft`/`--warn-bg` sind DIESELBEN Flächen, die vorher die ganze
   Leiste trug: derselbe Ton für dieselbe Bedeutung, nur auf der Fläche, die es
   wirklich braucht. */
.auswahl-stand {
    display: flex; align-items: center; gap: .15rem;
    background: var(--accent-soft); color: var(--accent-ink);
    border-radius: 999px;
    padding: .1rem .2rem .1rem .55rem;
    font-size: .8rem; white-space: nowrap;
    /* ABSOLUT am linken Rand, mittig – aus dem Fluss genommen (Fix B): so kann
       weder das Erscheinen der Pille noch der breitere Hinweis-Text die
       rechtsbündigen Icons verschieben. Die Icons füllen die Zeile nie so weit,
       dass sie den linken Auswahlstand berühren (Desktop). */
    position: absolute; left: 0; top: 50%; transform: translateY(-50%);
    max-width: calc(100% - 1rem);
}
/* HINWEIS-ZUSTAND (Zusage aus 0018, hier weitergeführt): Klick auf eine
   ausgegraute Aktion ohne Auswahl. Kein Dialog, keine Fehlerfarbe – ein
   warnender Ton genau dort, wo der Nutzer gerade hinsieht: unmittelbar neben den
   Icons, die er eben gedrückt hat. Auf einem Touchgerät gibt es kein Hover und
   damit keinen Tooltip; dort ist das hier die EINZIGE Erklärung. */
.auswahl-stand.is-hinweis {
    background: var(--warn-bg); color: var(--warn-ink);
    padding: .25rem .6rem;
}
/* Das ✕ erbt die Schriftfarbe der Pille (--accent-ink), statt --muted zu bleiben:
   es steht auf der Akzentfläche, nicht auf der Karte. Der Hover kommt unverändert
   von `.icon-btn` (--hover) – KEINE eigene Farbe hier, DESIGN §2 lässt außerhalb
   der Token-Blöcke keine harten Werte zu. */
.auswahl-stand .icon-btn { color: inherit; }

@media (max-width: 40rem) {
    input.filter-search { width: 100%; }
}

/* Aktionsleiste (Feedback 0015). Hell, mit Akzentfläche – kein dunkles Feld
   (DESIGN.md).

   NUR NOCH EIN VERWENDER (Feedback 0025): die „Ungespeicherte Änderungen"-Leiste
   unter Einstellungen → Felder. Die Mitgliederliste hatte sie bis 0024 für ihre
   Zeilenauswahl – der Nutzer fand den Rahmen unschön und wollte alle Knöpfe in
   EINER Reihe oben; ihre Aktionen stehen seitdem in `.toolbar-actions`, ihr
   Auswahlstand in `.auswahl-stand`. Mit ihr sind `.bulkbar-status`,
   `.bulkbar-idle` und `.bulkbar-hinweis` ersatzlos entfallen (verifiziert gegen
   resources/, app/, tests/ – die Felder-Seite hat sie nie benutzt).

   Der Zustand „Akzentfläche" ist damit der einzige, den es noch gibt: „hier
   liegt gerade etwas an" – ungespeicherte Änderungen. Die Felder-Seite zeigt die
   Leiste ohnehin nur dann. */
.bulkbar {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    flex-wrap: wrap; margin-bottom: 1rem;
    background: var(--accent-soft); color: var(--accent-ink);
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    padding: .5rem .75rem;
}
.bulkbar-count { font-size: .9rem; }
.bulkbar-actions { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; }

/* =============================================================================
   4. TABELLE, SORTIERUNG, SPALTENAUSWAHL
   ========================================================================== */
/* Die Mitgliedertabelle kann durch zugeschaltete Spalten BREITER werden als der
   zentrale Container. Dann scrollt sie IN SICH – die Seite selbst scrollt nie
   waagerecht. Das ist die einzige Stelle, die das sicherstellt. Wer eine breite
   Tabelle NICHT in .table-scroll wickelt, sprengt die Seite.

   `position: relative` IST HIER PFLICHT UND KEIN SCHMUCK – bitte nicht entfernen:
   In der Tabelle steckt ein `.sr-only`-Element (`position: absolute`, der
   „Aktionen"-Text für Screenreader). Ein absolut positioniertes Element wird nur
   von dem Vorfahren geclippt, der auch sein UMSCHLIESSENDER BLOCK ist – und das
   ist ein `position: static`-Vorfahre NICHT. Ohne `relative` hing dieses Element
   also am <html>-Element, blieb bei einer 3000px breiten Tabelle bei x≈2870
   stehen und zog die GANZE SEITE waagerecht auf (im Browser gemessen: 1202px
   Seiten-Scroll), obwohl `overflow-x: auto` die Tabelle selbst brav clippte.
   `overflow` allein reicht gegen absolut positionierte Nachfahren also NICHT.  */
.table-scroll { overflow-x: auto; max-width: 100%; position: relative; }

table.data { width: 100%; border-collapse: collapse; font-size: .845rem; }
table.data thead th {
    text-align: left;
    font-size: .69rem; font-weight: 650; letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted);
    background: var(--th-bg);
    padding: .7rem .9rem;
    border-bottom: 1px solid var(--line-strong);
    white-space: nowrap;
}
table.data tbody td { padding: .8rem .9rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data td.empty { text-align: center; color: var(--muted); padding: 2rem; }
table.data th.col-check, table.data td.col-check { text-align: center; width: 1%; white-space: nowrap; }
table.data tr.row-system td { background: var(--th-bg); color: var(--muted); }

/* GELDSPALTE + SUMMENZEILE (Feature 0012, Kassen-Ausgaben) -------------------
   Betraege stehen RECHTSBUENDIG und brechen nie um – nur so fluchten Euro und
   Cent untereinander und die Summe steht senkrecht unter ihren Summanden.
   `font-variant-numeric: tabular-nums` erzwingt gleich breite Ziffern (sonst
   wandern die Kommata bei proportionaler Schrift gegeneinander).

   Die Summenzeile ist ein echtes <tfoot> – die eine Zahl, die ein Kassenwart
   braucht. Sie sitzt optisch auf dem Tabellenkopf (`--th-bg`) und ist durch die
   staerkere Haarlinie vom letzten Datensatz abgesetzt; sie ist KEINE Datenzeile. */
table.data th.col-betrag, table.data td.col-betrag {
    text-align: right; white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
table.data tfoot td {
    padding: .8rem .9rem;
    background: var(--th-bg);
    border-top: 1px solid var(--line-strong);
    font-weight: 650;
    vertical-align: middle;
}
table.data tfoot .summe-anzahl { color: var(--muted); font-weight: 400; margin-left: .35rem; }

/* DER ⓘ-KNOPF (Feedback 0128, DESIGN.md §27) --------------------------------
   Ein kleiner Info-Knopf neben einer Beschriftung, in einer Karte oder in einer
   Tabellenzelle. DREI WEGE, die Erklaerung zu sehen – Maus (`mouseenter`),
   Tastatur (`focus`) und Finger (`click`); alle drei schaltet der Alpine-
   Baustein `schwebeHinweis` (public/js/schwebeblatt.js).
   AUSLOESER IST DER KNOPF, nicht die ganze Zeile/Karte: sonst klappte beim
   blossen Ueberfahren einer Liste ein Eintrag nach dem anderen auf.
   Bewusst KEIN `title`-Attribut: das ist auf Touch unsichtbar und nicht
   barrierefrei – der Text steht IMMER im HTML und haengt per
   `aria-describedby` am Knopf.
   ⚠ DAS BLATT SCHWEBT IMMER (seit Handoff 0174 ausnahmslos). Die Clipping-Falle
   aus §13/§18, die frueher gegen ein Popover sprach, greift nicht mehr: der
   gemeinsame Positionierer arbeitet mit `position: fixed`, nicht `absolute`
   (§27.1). Die Deklaration steht weiter unten bei den schwebenden Blaettern. */
.info-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.5rem; height: 1.5rem; padding: 0;
    border: 0; border-radius: 50%; background: transparent;
    color: var(--muted); cursor: pointer; line-height: 1;
}
.info-btn:hover { background: var(--hover); color: var(--accent); }
.info-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.info-btn .icon { width: 1rem; height: 1rem; }
.info-text { display: none; color: var(--muted); font-size: .8rem; line-height: 1.45; margin: 0; }

/* ⚠ HIER STAND DIE EINBLENDENDE BAUFORM `.info-hilfe` (frueher DESIGN §27.2b) –
   die Erklaerung schob sich IM FLUSS unter die Zeile und drueckte alles
   darunter weg. Sie ist mit Handoff 0174 ERSATZLOS ENTFALLEN. Ihr letzter
   Einsatzort waren die vier Taetigkeitsbereiche der Buchhaltungs-Uebersicht;
   der Nutzer hat den Sprung dort DREIMAL beanstandet, zuletzt woertlich: „es
   darf nicht sein, dass dadurch das Design einen Sprung macht und alles nach
   unten verschoben wird."
   JEDES ⓘ DES HAUSES OEFFNET JETZT EIN SCHWEBENDES BLATT (§27.1/§27.2a) – auch
   in einer Tabellenzeile. Ein Test haelt das fest und faellt, sobald irgendwo
   wieder ein ⓘ ohne `schwebeHinweis` auftaucht
   (`tests/Feature/Design/KeinHinweisImTextflussTest.php`). Wer die Bauform
   zurueckholen will, holt einen bereits behobenen Fehler zurueck. */

/* TAETIGKEITSBEREICH-WAHL im Ausgabenformular (Feature 0012, Handoff 0132) ----
   Vier gleich breite KARTEN; die Erklaerung SCHWEBT ueber dem Formular.

   DIE GESCHICHTE DIESER STELLE – dreimal dasselbe Problem, dreimal eine andere
   Antwort; wer hier etwas aendert, sollte alle drei kennen:
     0128: die Erklaerung schob sich beim ⓘ IN DEN FLUSS und drueckte alles
           darunter weg. Nutzer: „es springt runter“.
     0130: PLATZ RESERVIEREN – fuenf Absaetze uebereinander in derselben
           Grid-Zelle, geschaltet ueber `visibility`. Sprang nicht mehr, kostete
           aber dauerhaft Platz im Formular.
     0132: SCHWEBEN – die Erklaerung liegt UEBER dem Inhalt und nimmt gar keinen
           Platz mehr ein. Nutzer: „auch die hinweise beim taetigkeitsbereich
           sollen wie das kalender drueber liegen“. Der reservierte Bereich ist
           damit ersatzlos weg – und mit ihm die dauerhaft sichtbare Erklaerung
           des GEWAEHLTEN Bereichs (bewusster Preis, siehe Handoff 0132).

   WARUM SCHWEBEN JETZT GEHT und 0130 es noch ausgeschlossen hat: es gibt seit
   0132 einen ordentlichen Positionierer (public/js/schwebeblatt.js) mit
   `position: fixed` statt `absolute`. Damit greift die Clipping-Falle aus
   §13/§18 nicht mehr – das Blatt haengt am Fenster, nicht am scrollenden
   Overlay. DERSELBE Positionierer traegt den Datumskalender (§29); es gibt
   genau einen, absichtlich.

   VERBORGEN WIRD MIT `visibility`, NICHT MIT `display: none`. Zwei Gruende:
   `aria-describedby` verweist auf den Absatz (verborgen vorgelesen zu werden
   ist so am sichersten), und ein per `visibility` verborgenes Element ist schon
   VOR dem Einblenden messbar – das Blatt sitzt vom ersten Bildaufbau an richtig
   und blitzt nicht in der Ecke auf. Platz kostet es trotzdem keinen: es ist
   `position: fixed` und damit aus dem Fluss.

   Der Gewaehlt-Zustand der Karte kommt weiter aus dem DOM (`:has(input:checked)`),
   NICHT aus einer Livewire-Runde: `wire:model` ist verzoegert, der Server
   erfaehrt die Wahl erst beim Speichern. */
.bereich-wahl { margin-top: .3rem; }

/* Die vier Karten: gleich breit, zweispaltig – vier nebeneinander waeren im
   Overlay (hoechstens 38rem breit) gequetscht. Auf schmalen Geraeten
   untereinander, Breakpoint wie bei `.typ-wahl`. */
.bereich-karten { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem; }
@media (max-width: 34rem) { .bereich-karten { grid-template-columns: 1fr; } }

/* DIE GANZE KARTE SCHALTET: das <label> fuellt sie aus, nicht nur das Kaestchen.
   Das ⓘ liegt als eigener Knopf in der Ecke DARUEBER – ausserhalb des <label>,
   sonst waehlte ein Klick darauf zusaetzlich den Bereich aus. */
.bereich-karte {
    position: relative; display: flex;
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    background: var(--card);
}
.bereich-wahl label {
    flex: 1 1 auto; display: flex; align-items: flex-start; gap: .55rem;
    margin: 0; padding: .6rem 2.1rem .6rem .7rem;
    cursor: pointer; font-weight: 400;
}
.bereich-wahl input[type=radio] { margin: .15rem 0 0; cursor: pointer; flex: none; }
.bereich-wahl .bereich-name { font-weight: 600; color: var(--ink); }
.bereich-karte .info-btn { position: absolute; top: .3rem; right: .3rem; }
.bereich-karte:hover { border-color: var(--accent); }
/* Gewaehlt: derselbe Zustand wie bei den Startvorlagen (`.vorlage.active`) –
   Akzentrahmen + Akzentflaeche, nicht bloss ein gefuelltes Kaestchen. */
.bereich-karte:has(input:checked) {
    border-color: var(--accent); background: var(--accent-soft);
    box-shadow: inset 0 0 0 1px var(--accent);
}
/* Tastaturfokus sichtbar an der GANZEN Karte, nicht nur am Kaestchen. */
.bereich-karte:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 1px; }

/* DAS SCHWEBENDE ERKLAERBLATT – eines je ⓘ, direkt neben seinem Knopf im DOM
   (das haelt `aria-describedby` kurz und den Focus-Trap des Overlays zufrieden).
   Schriftgroesse/Farbe/Abstand stehen ausgeschrieben, weil `.modal p` (Klasse +
   Element) spezifischer ist als `.info-text` allein und sonst gewinnt; deshalb
   auch die ZWEITEILIGEN Selektoren.
   `top`/`left` setzt schwebeblatt.js – im CSS stehen nur die Startwerte.

   ZWEI EINSATZORTE, EINE DEKLARATION (Handoff 0138):
     `.bereich-karte .bereich-hilfe`  – die vier Taetigkeitsbereich-Karten (0132)
     `.feld-hilfe .schwebe-hilfe`     – ein ⓘ neben der BESCHRIFTUNG eines
                                        gewoehnlichen Feldes (Art der Buchung)
     `.bereich-zelle .schwebe-hilfe`  – ein ⓘ in einer TABELLENZELLE (0174, die
                                        vier Bereichszeilen der Uebersicht)
   Nutzer-Befund 0138: „bei der art der buchung ist der hinweis text nicht wie
   bei den anderen hinweis texten, bitte als overlay fenster anzeigen." Die
   Erklaerung dort stand als einziger Erklaertext des Formulars noch IM FLUSS und
   war beim Richtungswechsel mal ein-, mal dreizeilig – sie schob das halbe
   Formular. Zwei Kopien derselben Deklaration waeren zwei Orte gewesen, an denen
   dieselbe Falle repariert werden muss; deshalb EIN Block mit zwei Selektoren.
   Der Positionierer ist ohnehin derselbe (schwebeblatt.js, DESIGN §27.1/§27.4). */
.bereich-karte .bereich-hilfe,
.feld-hilfe .schwebe-hilfe,
.bereich-zelle .schwebe-hilfe {
    position: fixed; top: 0; left: 0; z-index: 40;
    display: block; visibility: hidden;
    width: max-content; max-width: min(22rem, calc(100vw - 1.5rem));
    margin: 0; padding: .5rem .65rem;
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    background: var(--card); box-shadow: var(--shadow);
    color: var(--muted); font-size: .8rem; line-height: 1.45; text-align: left;
}
.bereich-karte .bereich-hilfe.ist-sichtbar,
.feld-hilfe .schwebe-hilfe.ist-sichtbar,
.bereich-zelle .schwebe-hilfe.ist-sichtbar { visibility: visible; }

/* DIE BESCHRIFTUNGSZEILE MIT ⓘ. Der Knopf steht AUSSERHALB des <label> (sonst
   fuehrte ein Klick darauf zusaetzlich auf das Steuerelement, DESIGN §27.2) –
   also braucht es eine Zeile, die beide traegt. Sie ersetzt das <label> nicht,
   sie umschliesst es: Abstand und Schriftschnitt bleiben die der Formulare.
   Der Knopf sitzt eng am Text (`margin-left: -.15rem`), damit die Zeile nicht
   auseinanderfaellt. */
.feld-kopf { display: flex; align-items: center; gap: .1rem; }
.feld-kopf label { margin-bottom: 0; }
.feld-kopf .info-btn { margin-left: -.15rem; }

/* BELEGE je Ausgabe (Feature 0012, Nachtrag) --------------------------------
   Eine schlichte Liste im Formular-Overlay: Name (Download-Link), Typ/Groesse,
   Aktion. KEINE Vorschau und kein Thumbnail – ein Beleg wird nie gerendert.
   Eine zum Entfernen markierte Zeile bleibt sichtbar (durchgestrichen), damit
   der Nutzer sie bis zum Speichern zurueckholen kann. */
.beleg-liste { list-style: none; margin: .2rem 0 .7rem; padding: 0; display: flex; flex-direction: column; gap: .3rem; }
.beleg-zeile {
    display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
    padding: .35rem .55rem; border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--card);
}
.beleg-zeile .beleg-name { font-weight: 600; }
.beleg-zeile .beleg-meta { color: var(--muted); font-size: .8rem; }
.beleg-zeile .beleg-warnung { color: var(--danger-ink); }
.beleg-zeile .icon-btn { margin-left: auto; }
/* Die VOLLSTAENDIGE Datei-Pruefsumme auf der Belegpruefung (Handoff 0148):
   64 Zeichen in acht Bloecken zu acht passen nicht neben Name, Typ und Groesse
   – sie bekommen eine EIGENE, volle Zeile. Umbrechen darf der Wert nur an den
   Blockgrenzen (dort stehen echte Leerzeichen), nie mitten im Block. */
.beleg-zeile .beleg-summe { flex-basis: 100%; display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem; }
.beleg-zeile.wird-entfernt { background: var(--danger-bg); }
.beleg-zeile.wird-entfernt .beleg-name { text-decoration: line-through; color: var(--muted); }
table.data th.col-belege, table.data td.col-belege { text-align: right; width: 1%; white-space: nowrap; }

/* BELEGPRUEFUNG (Feature 0012, Handoff 0134/0135) ----------------------------
   Ein Zugangsschluessel wird vom Papier ABGETIPPT, eine Pruefsumme ZEICHEN FUER
   ZEICHEN verglichen – beides monospaced und mit etwas Sperrung: in einer
   Proportionalschrift sind 8 und B, 5 und S nebeneinander schwer zu halten.
   Das Alphabet selbst schliesst verwechselbare Paare bereits aus (I/L/O/U
   kommen nicht vor, siehe App\Pruefung\Crockford) – die Schrift ist die
   zweite Haelfte derselben Ueberlegung.
   Kein neues Token, keine neue Farbe. */
.pruefcode-feld { font-family: monospace; letter-spacing: .06em; text-transform: uppercase; }
.pruefcode-wert { font-family: monospace; letter-spacing: .04em; color: var(--accent-ink); }

/* Die abweichenden Zeilen der Gegenueberstellung „Ausdruck ⇄ heute" (Handoff
   0135). Aus vorhandenen Tokens; die FARBE IST NIE DIE EINZIGE AUSSAGE – ueber
   der Tabelle steht ausgeschrieben, dass die hervorgehobenen Zeilen sich
   unterscheiden, und die beiden Werte stehen ohnehin nebeneinander. */
tr.zeile-abweichend > td { background: var(--danger-bg); }
tr.zeile-abweichend > td:first-child { font-weight: 600; }

/* BUCHHALTUNGS-UEBERSICHT (Feature 0012, Handoffs 0129/0136/0137) -----------
   Die Startseite des Moduls: vier Kennzahlen (Einnahmen, Ausgaben, Ergebnis,
   laufender Monat), die SPHAERENRECHNUNG (Einnahmen · Ausgaben · Ergebnis je
   Taetigkeitsbereich mit Gesamtzeile), ZWEI Kategorie-Diagramme und die letzten
   fuenf Buchungen. Alles aus vorhandenen Tokens, keine neue Farbe, kein
   Inline-Style (DESIGN.md §1).

   BIS HANDOFF 0135 STAND HIER: „BEWUSST KEINE BALKEN-DARSTELLUNG – ein Balken
   braucht je Zeile eine dynamische Breite, und die gaebe es nur als Inline-Style
   oder als zwanzig Stufenklassen."
   DAS GALT FUER HTML-ELEMENTE UND GILT DORT WEITER. Seit Handoff 0136 gibt es
   Balken – als server-gerendertes SVG (siehe `.diagramm` weiter unten): dort ist
   die Balkenlaenge GEOMETRIE (`width` am `<rect>`), kein Stil. Die
   Sphaerenrechnung bleibt trotzdem eine schlichte Zahlentabelle: sie ist die
   Aufstellung, die abgeschrieben wird, kein Bild zum Ueberfliegen.

   ENTFALLEN MIT HANDOFF 0137: die Prozentspalte `.col-anteil`. Sie zeigte den
   Anteil einer Sphaere an den AUSGABEN – neben Einnahmen, Ausgaben und Ergebnis
   waere sie eine vierte Zahl ohne eigene Aussage gewesen. Wer sie zurueckholt,
   braucht auch die Regel wieder. */

/* Knopfreihe im Seitenkopf. NICHT `.actions` benutzen: dessen Regeln
   (`.actions a/button { background: none; border: 0; padding: 0 }`) sind
   spezifischer als `.btn` und wuerden einen Knopf zum Textlink flachdruecken. */
.kopf-aktionen { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }

/* Zwei gleich breite Kennzahl-Karten; auf schmalen Schirmen untereinander.
   Die Karte IST ein `.panel` – nur ohne dessen Aussenabstand, den hier das Grid
   setzt. */
.kennzahlen {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem; margin-bottom: 1.1rem;
}
.kennzahlen .panel { margin-bottom: 0; }
/* Beide Regeln bewusst MIT `.panel` davor: `.panel p` (Klasse + Element) ist
   spezifischer als eine blosse Klasse und wuerde sonst Abstand und Farbe
   ueberschreiben. */
.panel .kennzahl-label { font-size: .82rem; margin: 0 0 .3rem; }
.panel .kennzahl-wert {
    font-size: 1.65rem; font-weight: 650; line-height: 1.15;
    color: var(--ink); font-variant-numeric: tabular-nums; margin: 0;
}
@media (max-width: 40rem) {
    .kennzahlen { grid-template-columns: minmax(0, 1fr); }
}

/* NEGATIVER KASSENSTAND (Feature 0012, Handoff 0133) – ein WARNSIGNAL, kein
   Fehler: eine Kasse kann nicht weniger als nichts enthalten, also stimmt dann
   etwas nicht. Sichtbar kennzeichnen, aber nicht verhindern und nicht
   verstecken; die Erklaerung steht daneben als stehender `.flash.flash-warn`
   (DESIGN.md §26).
   Wieder MIT `.panel .kennzahl-wert` davor: die Grundregel ist Klasse+Klasse und
   gewaenne sonst gegen eine einzelne Klasse (dieselbe Falle wie oben). */
.panel .kennzahl-wert.ist-negativ { color: var(--danger-ink); }

/* Zwischenueberschrift ueber einer Tabelle (Muster `.menu-fuss-head`). */
.uebersicht-head { margin-top: 1.75rem; margin-bottom: .6rem; }

/* Knopf im Leerzustand: `.panel p { margin: 0 }` gilt fuer Absaetze, deshalb
   traegt den Knopf ein <div> mit eigenem Abstand. */
.uebersicht-leer-aktion { margin-top: 1rem; }

/* KLEINE ZEILE UNTER EINEM BETRAG (Handoff 0137) – in der Sphaerenrechnung
   traegt das Ergebnis je Bereich den Wortlaut, unter dem es im amtlichen
   Vordruck steht („Ueberschuss / Verlust" bzw. „Gewinn / Verlust"). Eigene
   Zeile, damit die Zahlenspalte flucht; leiser als die Zahl, weil sie eine
   Beschriftung ist und kein Wert.
   MIT `table.data` davor, weil `table.data tfoot td` (Element + Klasse)
   `font-weight: 650` setzt und sonst gewaenne. */
table.data .betrag-hinweis {
    display: block; font-weight: 400;
    color: var(--muted); font-size: .74rem;
    white-space: nowrap;
}

/* =============================================================================
   DIE ZWEIZEILIGE KASSENLISTE (`table.data.data-kasse`, Handoff 0163)
   =============================================================================
   Nutzer-Befund 14.08.2026: „man muss waagerecht scrollen". Die Liste hatte
   NEUN Spalten (acht ohne Kontospalte); die Haelfte davon trug kurze Woerter,
   verlangte aber trotzdem eine eigene Spaltenbreite. Jetzt sind es VIER
   (Datum · Verwendungszweck · Betrag · Aktionen), und was in den uebrigen fuenf
   stand, steht als zweite, leisere Zeile IN der Zweckspalte.

   `vertical-align: top` IST HIER PFLICHT, nicht Geschmack: die geerbte Regel
   `table.data tbody td` setzt `middle`, und damit ruecken Datum und Betrag in
   die Mitte der zwei Zeilen – sie flucheten dann weder mit dem Zweck noch
   miteinander. Genau davon lebt die obere Zeile („Datum · Betrag · Zweck").

   `.zeile-haupt` darf breiter werden als das allgemeine `.cell-lang` (20rem):
   in dieser Tabelle gibt es nur noch eine Textspalte, sie hat den Platz. */
table.data.data-kasse tbody td { vertical-align: top; }
table.data.data-kasse .zeile-haupt { max-width: 42rem; font-weight: 600; }

/* DIE ZWEITE ZEILE: kleiner, ruhiger, umbrechend. Sie bricht um, statt die
   Tabelle breiter zu machen – daran haengt die ganze Uebung. Auf schmalen
   Schirmen wird die Zeile damit von selbst zu einer lesbaren Karte. */
.zeile-meta {
    display: flex; flex-wrap: wrap; align-items: center;
    margin-top: .3rem;
    font-size: .78rem; color: var(--muted); line-height: 1.5;
}
.zeile-meta .meta-teil { display: inline-flex; align-items: center; gap: .25rem; }
/* DIE TRENNPUNKTE KOMMEN AUS DEM CSS und nicht aus dem Markup: welche Teile es
   ueberhaupt gibt, haengt vom Verein ab (kein Konto bei nur einem, keine
   Kategorie ohne Kategorien). Ein von Hand gesetztes „·" stuende sonst
   irgendwann fuehrend oder doppelt da.

   ⚠ DER PUNKT HAENGT AM VORIGEN TEIL (`::after`), NICHT AM FOLGENDEN
   (Nutzer-Befund 18.08.2026). Bis dahin stand hier `> * + *::before`. Das ist
   fuer eine NICHT umbrechende Zeile dasselbe – die Zahl der Punkte ist in
   beiden Fassungen n-1 und die Positionen sind dieselben. `.zeile-meta` ist
   aber ein `flex-wrap: wrap`: bricht die Zeile zwischen zwei Teilen um, wandert
   ein `::before` MIT SEINEM TEIL in die neue Zeile und steht dort fuehrend –
   „· KATEGORIE Porto, Buero und Verwaltung". Ein `::after` bleibt beim
   VORIGEN Teil und damit am Ende der vorigen Zeile haengen, wo ein Trenner
   hingehoert. DESIGN §5.1a haelt das fest.
   ⚠ NICHT `> * + *::after` NEHMEN: das liesse den ersten Teil ohne Punkt und
   haengte dafuer einen an den letzten – ein Trenner am Zeilenende der ganzen
   Meta-Zeile. `:not(:last-child)` ist die richtige Auswahl. */
.zeile-meta > *:not(:last-child)::after {
    content: "·"; margin: 0 .45rem; color: var(--line-strong);
}
/* ABSTANDSAUSGLEICH: `.meta-teil` ist ein `inline-flex` mit `gap: .25rem`, und
   das Pseudoelement ist darin ein eigenes Flex-Kind – der gap kommt links zum
   Rand hinzu. Ohne diese Zeile stuende der Punkt .7rem hinter seinem Teil und
   nur .45rem vor dem naechsten; .2rem + .25rem gap ergeben wieder die .45rem
   von vorher. Die Abstaende sind damit Pixel fuer Pixel die von 0181. */
.zeile-meta .meta-teil::after { margin-left: .2rem; }
.zeile-meta .meta-nr { font-variant-numeric: tabular-nums; }

/* DAS LEITWORT VOR JEDEM WERT (Nutzer-Durchsicht 18.08.2026). Bis dahin standen
   in dieser Zeile nackte Werte nebeneinander – „K-2026-0169 · Barkasse ·
   Zweckbetrieb · arts". Wer neu in das Amt kommt, kann daraus nicht ablesen,
   welcher davon die Kategorie und welcher der Taetigkeitsbereich ist.
   ES IST BEWUSST DIE OPTIK DES SPALTENKOPFS (`table.data thead th`): klein,
   Versalien, gesperrt, DIESELBE gedaempfte Farbe wie der Wert. Damit
   beschriftet das Wort, ohne einen zweiten Ton in die ohnehin leise Zeile zu
   bringen – und es liest sich als das, was es ist: eine Ueberschrift.
   ⚠ KEIN Doppelpunkt und KEIN eigener Abstand nach hinten: den Abstand macht
   das Leerzeichen im Markup, den Schnitt machen die Versalien. */
.zeile-meta .meta-label {
    font-size: .69rem; font-weight: 650; letter-spacing: .06em;
    text-transform: uppercase; color: var(--muted);
}
.zeile-meta .meta-beleg .icon { width: .95rem; height: .95rem; }

/* DER TAETIGKEITSBEREICH STEHT AUSGESCHRIEBEN (Nutzer-Durchsicht 15.08.2026).
   ⚠ HIER STAND `.bereich-kuerzel`: der Bereich als BUCHSTABE A · B · C · D
   (Handoff 0163), mit `.sr-only`-Vollnamen daneben und einer Legende unter der
   Tabelle. Die Abkuerzung war der Preis fuer die schmale Liste – und sie ist
   nicht mehr noetig: in der UMBRECHENDEN Meta-Zeile kostet das ganze Wort keine
   Spaltenbreite. ERPROBT UND WIEDER VERWORFEN, siehe DESIGN §5.1.
   ⚠ WER SIE ZURUECKHOLT, holt `.sr-only` und Legende mit zurueck.

   `.meta-bereich` braucht KEINE eigene Regel und bekommt vor allem KEIN
   `white-space: nowrap`: „Wirtschaftlicher Geschaeftsbetrieb" ist 33 Zeichen
   lang und muss umbrechen duerfen, sonst waechst die Tabelle wieder in die
   Breite. Der Eintrag steht hier nur, damit niemand ihn „vergessen" glaubt. */

/* DIE STORNIERTE ZEILE BLEIBT RUHIG – ROT TRAEGT ALLEIN DIE MARKE.
   Nutzer-Durchsicht 15.08.2026 woertlich: „das der hintergrund rot ist gefaellt
   mir nicht, nur der schriftzug Storno." Bis dahin lag `--danger-bg` unter der
   ganzen Zeile (Handoff 0163). Das war zu laut UND inhaltlich schief: nicht die
   BUCHUNG ist ein Alarm, sondern ihr ZUSTAND – und der steht in der Marke
   (`.tag-danger`, unveraendert in den Danger-Tokens). Auf der weissen Zeile ist
   sie jetzt ueberhaupt erst sichtbar; vorher lag rot auf rot.
   Die Zeile sagt „gilt nicht" trotzdem doppelt, nur leiser: GEDAEMPFTE Schrift
   und DURCHGESTRICHENER Betrag – beides ohne Farbe, wie DESIGN §34.6 es fuer
   „Farbe ist nie die einzige Aussage" verlangt. Der Betrag ist bewusst
   `--muted` und nicht mehr `--danger-ink`: sonst waere die Marke nicht mehr das
   einzige Rote. Die GEGENBUCHUNG bleibt neutral, sie ist gueltig. */
table.data tr.zeile-storniert td { color: var(--muted); }
table.data tr.zeile-storniert .kasse-betrag {
    text-decoration: line-through; color: var(--muted);
}

/* DER VERWEIS AUF DIE ANDERE ZEILE DES STORNO-PAARES. Ein echter <button>
   (Tastatur!), der aussieht wie ein Textverweis; er sortiert NICHTS um – die
   Liste bleibt ein Kassenbuch in Zeitfolge. */
.zeile-verweis {
    background: none; border: 0; padding: 0; margin: 0;
    font: inherit; color: var(--accent); text-decoration: underline;
    cursor: pointer;
}
.zeile-verweis:hover { color: var(--accent-ink); }
.zeile-verweis:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* DIE NOTIZZEILEN UNTER DER BUCHUNG (Handoff 0181) – „Storniert am …",
   „Grund …", „Grundlage …". Sie sind `.field-hint`-Spans in einer Tabellenzelle
   und liefen deshalb IN EINER ZEILE ineinander: „… Grund: falsch erfasst
   Grundlage: Beschluss 2026-009 vom 09.08.2026". Nutzer-Befund 18.08.2026,
   woertlich: „fände ich es besser wenn da eine trennung zwischen den zeilen gäbe
   wie ‚|' oder fett gedruckter titel."
   ER HAT DAS LEITWORT GEWAEHLT – und das ist auch das Richtigere: ein „|"
   zwischen zwei UNTEREINANDER stehenden Zeilen trennt nichts, es verwischt.
   `display: block` macht aus jedem Span eine eigene Zeile, das <strong> im
   Markup benennt sie. Der Doppelpunkt ist entfallen: der Fettdruck trennt
   bereits, ein zweites Trennzeichen waere doppelt gemoppelt.
   ⚠ Der Abstand steht hier und nicht an `.field-hint` – die Klasse traegt im
   ganzen Haus Formularhinweise, die keine Blockzeilen sein duerfen. */
.zeile-meta + .zeile-notiz { margin-top: .35rem; }
/* ⚠ DIE REGEL GILT SEIT DEM 18.08.2026 FUER JEDE `table.data`, NICHT MEHR NUR
   FUER `.data-kasse`. Das Problem ist keins der Kassenliste, sondern eins jeder
   Tabellenzelle, die ZWEI Hinweise untereinander stellen will: die
   Konten-Tafel der Buchhaltungs-Uebersicht zeigte
   „Stichtag 07.08.2026 Steht fest, seit auf diesem Konto gebucht wurde." –
   zwei Saetze in einer Zeile, ohne jede Fuge. Der Name der Klasse war nie
   kassenspezifisch, die Ursache ist es auch nicht. */
table.data .zeile-notiz { display: block; margin: .15rem 0 0; }
table.data .zeile-notiz strong { font-weight: 650; color: var(--ink); }
table.data tr.zeile-storniert .zeile-notiz strong { color: inherit; }

/* DIE HERVORGEHOBENE ZEILE. Steht NACH `.zeile-storniert`, damit sie bei einem
   stornierten Original gewinnt – sonst klickte man den Verweis und saehe nichts.
   Muster wie `tr.row-click.is-open`. */
table.data tr.ist-hervor td { background: var(--accent-soft); }

/* DER SPRUNG BLITZT KURZ AUF (Nutzer-Wunsch 18.08.2026).
   ZWEI AUSSAGEN, ZWEI MITTEL: das Aufblitzen sagt „HIER bist du gelandet" und
   ist vorbei, bevor man es zu Ende gedacht hat; die ruhende Hervorhebung
   (`.ist-hervor`, darueber) BLEIBT und hilft beim Wiederfinden, wenn man
   zwischendurch wegschaut. Der Blitz LAEUFT DESHALB IN SIE HINEIN: er beginnt
   und endet auf `--accent-soft`, dazwischen liegt eine kraeftigere Stufe
   desselben Petrol. Kein Ein- und Ausblenden gegen Weiss – das saehe aus, als
   verschwaende die Hervorhebung wieder.
   `animation-fill-mode` bleibt bewusst `none`: nach dem Ablauf gilt wieder die
   Regel von `.ist-hervor`, es bleibt also KEIN Animationszustand haengen.
   ⚠ Neustarten laesst sich eine CSS-Animation nur durch NEUES Setzen der
   Klasse – das erledigt `hin()` in der Vorlage (Klasse weg, 40 ms spaeter
   wieder hin). */
@keyframes zeile-aufblitzen {
    0%   { background: var(--accent-soft); }
    18%  { background: var(--accent-blitz); }
    45%  { background: var(--accent-blitz); }
    100% { background: var(--accent-soft); }
}
table.data tr.ist-blitz td { animation: zeile-aufblitzen .9s ease-out 1; }

/* ⚠ KEIN BLITZ FUER WEN BLINKEN EIN PROBLEM IST. Die HERVORHEBUNG bleibt –
   sie ist die Information, das Blitzen nur ihre Ankuendigung. Die allgemeine
   Regel weiter unten schaltet nur `transition` ab, nicht `animation`. */
@media (prefers-reduced-motion: reduce) {
    table.data tr.ist-blitz td { animation: none; }
}

/* DIE ERKLAERZEILE UNTER DEM SUMMENFUSS: sie sagt, warum die drei Summen NICHT
   der Summe der sichtbaren Zeilen entsprechen. Leiser als eine Summenzeile –
   sie ist ein Satz, kein Wert. */
table.data tfoot tr.fuss-hinweis td {
    font-weight: 400; color: var(--muted); font-size: .78rem; line-height: 1.5;
    border-top: 1px solid var(--line);
}

/* ⚠ HIER STAND `.bereich-legende*` – die Legende der vier Buchstaben unter der
   Kassenliste (Handoff 0163). Sie ist mit der Abkuerzung ERSATZLOS ENTFALLEN
   (Nutzer-Durchsicht 15.08.2026): der Bereich steht jetzt ausgeschrieben in der
   Meta-Zeile, und eine Legende, die Woerter erklaert, die schon dastehen, ist
   Laerm. Die ERKLAERUNGEN selbst gibt es unveraendert – im Erfassungsformular
   hinter dem ⓘ, aus derselben einen Quelle
   (`Taetigkeitsbereich::erklaerungBeideRichtungen()`).
   Wer die Buchstaben je zurueckholt, braucht diesen Block wieder; er stand hier
   und benutzte `.info-btn`/`.info-text` nach DESIGN §27.2b. */

/* Bereichsname + ⓘ in einer Tabellenzelle (DESIGN.md §27). Das Flex sitzt in
   einem <div> IN der Zelle, nie am <td> (DESIGN.md §5).
   ⚠ DIE ERKLAERUNG BRICHT NICHT MEHR ALS ZEILE DARUNTER UM (Handoff 0174): sie
   SCHWEBT (`.bereich-zelle .schwebe-hilfe`, Block weiter oben) und liegt
   `position: fixed` – die Zelle aendert ihre Hoehe nicht mehr, die Tabelle
   springt nicht. Deshalb steht hier auch kein `flex-basis: 100%` mehr fuer den
   Absatz: er nimmt gar keinen Platz im Fluss ein. */
.bereich-zelle { display: flex; flex-wrap: wrap; align-items: center; gap: .1rem .35rem; }
.bereich-zelle .bereich-name { font-weight: 600; color: var(--ink); }

/* Fusszeile eines Tabellen-Panels („Alle anzeigen →") – dieselbe Polsterung wie
   `.panel-flush .pager-wrap`. */
.tabellen-fuss { padding: .7rem 1.35rem; border-top: 1px solid var(--line); }
.tabellen-fuss a { color: var(--accent); font-weight: 600; font-size: .84rem; text-decoration: none; }
.tabellen-fuss a:hover { text-decoration: underline; }
.tabellen-fuss a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* BALKENDIAGRAMM als server-gerendertes SVG (Handoff 0136, DESIGN.md §33) ----
   Gezeichnet wird in `resources/views/components/balken-diagramm.blade.php`, die
   Koordinaten kommen aus App\Buchhaltung\Balkendiagramm. HIER steht ausschliess-
   lich das AUSSEHEN – Position und Laenge stehen als SVG-Geometrie im Markup.

   WARUM DAS KEIN VERSTOSS GEGEN §1 IST: `width` an einem `<rect>` ist ein
   Struktur-Attribut wie `colspan` an einem `<td>`, kein Inline-Style. Es gibt
   im Diagramm KEIN `style="…"`.

   `width: 100%` + `height: auto` + `viewBox` = das SVG skaliert mit dem Panel.
   `max-width` deckelt die Skalierung: ohne sie wuerde auf einem breiten Schirm
   auch die Schrift im Diagramm mitwachsen und neben der uebrigen Seite zu gross
   wirken (SVG skaliert Text mit, anders als HTML). */
.diagramm { display: block; width: 100%; max-width: 40rem; height: auto; }

/* Petrol als EINZIGER Akzent (DESIGN.md §1): Ausgaben- und Einnahmen-Diagramm
   tragen dieselbe Balkenfarbe. Unterschieden werden sie durch ihre Ueberschrift,
   nicht durch eine zweite Farbe – ein „rot fuer Ausgaben, gruen fuer Einnahmen"
   waere ein zweiter und dritter Akzent und ausserdem fuer Farbfehlsichtige die
   einzige Aussage. */
.diagramm .diagramm-balken { fill: var(--accent); }
.diagramm .diagramm-label { fill: var(--ink); font-size: 13px; font-weight: 500; }
.diagramm .diagramm-wert { fill: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }

/* PLAN GEGEN IST (Handoff 0152): der Ist-Balken traegt den EINEN Akzent wie
   ueberall sonst, der Plan-Balken die vorhandene Linienfarbe. Das ist KEIN
   zweiter Akzent und kein neues Farbsystem – und es ist auch nicht die Aussage:
   jeder Balken nennt seine Reihe ausgeschrieben im Werttext („Plan 2.000,00 €"),
   und Plan steht in jeder Gruppe oben. In Graustufen, bei Farbfehlsichtigkeit
   und in der Vorlesesoftware bleibt das Bild damit vollstaendig lesbar. */
.diagramm .diagramm-balken-plan { fill: var(--line); }

.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .82rem; white-space: nowrap; }

/* MENUE-MANAGER als DRAG-AND-DROP-BAUM (Handoff 0054, ADR-0017 §7) ----------
   Statt einer Tabelle eine geschachtelte <ul>-Struktur (SortableJS nested groups):
   nur so laesst sich sauber umsortieren UND EINE Ebene verschachteln. Damit die
   Aktions-Icons TROTZDEM in festen Spalten FLUCHTEN, ist jede Zeile (.menu-row) ein
   CSS-Grid mit festen Aktionsspalten – jede Aktion haelt auch leer ihren Platz. */
.menu-tree, .menu-children { list-style: none; margin: 0; padding: 0; }

/* Ein Knoten: die Zeile plus (bei Top-Eintraegen) seine Kinderliste. */
.menu-node { position: relative; }

/* DIE ZEILE als Grid. Feste Spalten:
   Griff | Titel(dehnt) | Adresse | Status | Hoch | Runter | Ein-/Ausruecken |
   Startseite-Stern | Sichtbar | Bearbeiten | Ansehen | Loeschen.
   Die acht Aktionsspalten sind je genau eine Icon-Knopf-Breite -> untereinander
   fluchtend, egal wie viele Aktionen die Zeile fuellt. Die Titelleiste `.menu-head`
   teilt dasselbe Raster (Feedback 0057). */
/* TITELLEISTE (Feedback 0057): Spaltenkoepfe ueber demselben Raster wie `.menu-row`,
   damit Titel/Adresse/Status/Aktionen mit den Zeilen fluchten. */
.menu-head {
    display: grid;
    grid-template-columns:
        1.4rem
        minmax(7rem, 2fr)
        minmax(5rem, 1.3fr)
        minmax(5.5rem, auto)
        1.95rem 1.95rem 1.95rem 1.95rem 1.95rem 1.95rem 1.95rem 1.95rem;
    gap: .5rem;
    align-items: center;
    padding: .55rem .9rem;
    background: var(--th-bg);
    border-bottom: 1px solid var(--line);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--muted);
}
.menu-head .menu-head-akt { grid-column: span 8; text-align: right; }

.menu-row {
    display: grid;
    grid-template-columns:
        1.4rem
        minmax(7rem, 2fr)
        minmax(5rem, 1.3fr)
        minmax(5.5rem, auto)
        1.95rem 1.95rem 1.95rem 1.95rem 1.95rem 1.95rem 1.95rem 1.95rem;
    align-items: center;
    gap: .5rem;
    padding: .7rem .9rem;
    border-bottom: 1px solid var(--line);
}
/* System-Zeilen gedaempft (wie frueher .row-system). */
.menu-node-system > .menu-row { background: var(--th-bg); color: var(--muted); }

/* KIND-EINRUECKUNG: nur der TITEL-Zelleninhalt rueckt ein (+↳), damit Adresse,
   Status und die Aktionsspalten mit den Top-Zeilen fluchten. */
.menu-node-kind > .menu-row { border-left: 2px solid var(--line-strong, var(--line)); }
.menu-node-kind > .menu-row .menu-titel { padding-left: 1.4rem; position: relative; }
.menu-node-kind > .menu-row .menu-titel::before {
    content: "↳";
    position: absolute;
    left: .1rem;
    color: var(--muted);
    font-size: .9rem;
}

.menu-titel { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.menu-adresse, .menu-status { min-width: 0; }
.menu-akt { display: flex; align-items: center; justify-content: center; }

/* Der Ziehgriff (nur er zieht; Links/Knoepfe bleiben klickbar). */
.menu-grip {
    display: inline-flex; align-items: center;
    color: var(--muted); cursor: grab; flex: 0 0 auto;
}
.menu-grip:active { cursor: grabbing; }
.menu-grip .icon { width: 1rem; height: 1rem; }
.menu-node:hover > .menu-row .menu-grip { color: var(--accent); }

/* Icon-Knoepfe in der Zeile (nicht in einem .actions-Container – daher eigene
   Regel, spiegelt `.actions .icon-btn`). */
.menu-row .icon-btn {
    display: inline-grid; place-items: center;
    width: 1.95rem; height: 1.95rem;
    padding: 0; border: 0; border-radius: var(--radius);
    background: none; color: var(--muted); cursor: pointer; text-decoration: none;
}
.menu-row .icon-btn:hover { background: var(--hover); color: var(--ink); text-decoration: none; }
.menu-row .icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.menu-row .icon-btn.icon-danger { color: var(--danger-ink); }
.menu-row .icon-btn.icon-danger:hover { background: var(--danger-bg); color: var(--danger-ink); }

/* Der Sichtbar-Umschalter je Zeile (Auge/Auge-durchgestrichen). Aus = gedaempft. */
.menu-sichtbar-aus { color: var(--muted); }

/* STARTSEITE-STERN (Handoff 0058): grau-ungefuellt = keine Startseite (Outline-SVG
   erbt `--muted`); gold-gefuellt = aktuelle Startseite. Weil das SVG `stroke` UND
   (per CSS) `fill` auf die Knopf-Farbe legt, faerbt EINE Farbe den ganzen Stern.
   Gold ist der EINZIGE Ort dieses Aktiv-Gelbs (DESIGN §2 – Farbe nur als Token). */
.menu-row .icon-btn.menu-star { color: var(--muted); }
.menu-row .icon-btn.menu-star:hover { color: var(--star-gold); background: var(--hover); }
.menu-row .icon-btn.menu-star-aktiv { color: var(--star-gold); }
.menu-row .icon-btn.menu-star-aktiv .icon { fill: var(--star-gold); }

/* ABLEGEZIEL fuer Untermenue-Eintraege (Feedback 0068) -----------------------
   OBERSTE REGEL: Waehrend eines Zuges aendert KEIN Element seine Hoehe.
   Vorgeschichte: erst bekam beim Ziehen jede leere Kinderliste einen grossen
   gestrichelten Kasten (Kaesten-Wand, 0064), danach immerhin nur noch eine
   Mindesthoehe von 1.2rem. Auch die war schaedlich – sie gab JEDER leeren Liste ein
   eigenes y-Band zwischen zwei Zeilen. Beim ruhigen Herunterziehen durchquerte man
   dieses Band zwangslaeufig, und die Einfuegemarke sprang an jeder Zeilengrenze
   zwischen „daneben" und „verschachtelt" hin und her (gemessen: 22 Ruecksprünge auf
   vier Zuegen). Deshalb: leere Kinderlisten bleiben beim Ziehen 0 px hoch. Treffbar
   sind sie ueber `emptyInsertThreshold` (menu-manager.js), zustaendig aber nur bei
   bewusster Seitwaerts-Geste nach rechts. So gehoert jede Hoehe genau EINEM Ziel. */
body.menu-is-dragging {
    cursor: grabbing;
    -webkit-user-select: none;
    user-select: none;
}

/* `.menu-children.menu-nest-target` (von onMove gesetzt) traegt BEWUSST KEINE eigene
   Umrandung: die Liste enthaelt in diesem Moment bereits den eingerueckten
   Platzhalter, der selbst gestrichelt umrandet ist. Eine zweite Umrandung um die
   Liste ergaebe zwei ineinander liegende Kaesten – unnoetige Unruhe. Die Klasse
   bleibt als Anker fuer JS/Tests bestehen. Angezeigt wird das Verschachteln durch
   ZWEI Dinge: die hervorgehobene Elternzeile und den eingerueckten Platzhalter. */

/* Die ELTERNZEILE des Nest-Ziels: der Eintrag, unter den gehaengt wird. `outline`
   statt `border` – wieder ohne jede Groessenaenderung. */
.menu-row.menu-nest-row {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
    border-radius: var(--radius);
    background: var(--accent-soft);
}

/* DRAG-ZUSTAENDE (forceFallback – gleiches Bild in allen Browsern, wie Baukasten). */
/* EINFUEGE-ANZEIGE: der Platzhalter (ghost) behaelt die VOLLE ZEILENHOEHE und wird
   zum leeren, gestrichelt umrandeten Fach. Er ist damit exakt die Luecke, die der
   Eintrag beim Loslassen einnimmt – man sieht die Zielposition massstabsgetreu.
   Wichtig fuers Zielen: weil die Hoehe der Zeile erhalten bleibt, springt beim
   Anfassen NICHTS (frueher schrumpfte die Zeile auf eine 4px-Linie und alles
   darunter ruckte ~41 px hoch). Der Inhalt ist versteckt, es wirkt also als Fach und
   nicht als Duplikat der Zeile. */
.menu-ghost > .menu-row {
    background: var(--accent-soft);
    outline: 2px dashed var(--accent);
    outline-offset: -3px;
    border-radius: var(--radius);
    border-bottom-color: transparent;
}
.menu-ghost > .menu-row > * { visibility: hidden; }
.menu-ghost > .menu-children { display: none; }
/* Liegt der Platzhalter in einer Kinderliste, rueckt er ein – so sieht man auf einen
   Blick, dass hier VERSCHACHTELT und nicht daneben einsortiert wird. `margin-left`
   aendert nur die BREITE, nicht die Hoehe: das Layout bleibt still. */
.menu-children > .menu-ghost > .menu-row { margin-left: 2.3rem; }

.menu-fallback {
    box-sizing: border-box;
    box-shadow: var(--shadow);
    border: 1px solid var(--accent); border-radius: var(--radius);
    background: var(--card);
}
/* Das Zieh-Abbild ist NUR die Zeile (nicht der ganze Unterbaum) – ruhiger und
   haelt die Zeilenbreite (Breite zusaetzlich in onStart fixiert). */
.menu-fallback > .menu-children { display: none; }

/* Leer-Zustand des Managers (kein Menue-Eintrag). */
.menu-empty { text-align: center; color: var(--muted); padding: 2rem; margin: 0; }

/* Aktionsspalten des „Immer im Fuß"-Tabellenabschnitts fluchten ebenfalls: je
   Aktion eine feste, schmale Spalte (statt eines rechtsbuendigen .actions-Bündels). */
table.data td.col-akt-slot, table.data th.col-akt-slot { width: 1%; text-align: center; white-space: nowrap; padding-left: .1rem; padding-right: .1rem; }
table.data td.col-akt-slot .icon-btn {
    display: inline-grid; place-items: center;
    width: 1.95rem; height: 1.95rem;
    padding: 0; border: 0; border-radius: var(--radius);
    background: none; color: var(--muted); cursor: pointer; text-decoration: none;
}
table.data td.col-akt-slot .icon-btn:hover { background: var(--hover); color: var(--ink); text-decoration: none; }
table.data td.col-akt-slot .icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Ueberschrift des „Immer im Fuß"-Abschnitts unter dem Menue-Manager. */
.menu-fuss-head { margin-top: 2rem; }

/* --- SPALTENBREITE NACH INHALT (.data-fit) ---------------------------------
   Das Problem: Bei `table-layout: auto` + `width: 100%` verteilt der Browser die
   überschüssige Breite auf ALLE Spalten. Bei den vier Standardspalten stand dann
   „Aktiv" einsam am rechten Rand seiner 280px-Spalte – die Tabelle wirkte
   auseinandergezogen (genau der Nutzer-Befund).

   Die Lösung ist EINE leere FÜLLSPALTE, die den Rest schluckt (`width: 100%`). Alle
   anderen Spalten bekommen dann nur noch, was ihr Inhalt verlangt – "so breit wie
   nötig". Die Tabelle bleibt trotzdem 100% breit, damit die Haarlinien der Zeilen bis
   an die Panel-Kante laufen.

   ⚠️ DIE FÜLLSPALTE STEHT IM MARKUP VOR DER AKTIONSSPALTE, NICHT DAHINTER.
   Nur so schiebt sie die Aktions-Icons an den RECHTEN Tabellenrand. Stand sie dahinter,
   klebten die Icons direkt hinter der letzten Datenspalte mitten in der Tabelle und
   rechts davon klaffte eine leere Fläche – genau so sah es aus, bis der Nutzer es
   gemeldet hat. Reihenfolge in <thead> UND <tbody> gleich halten.

   NICHT `table-layout: fixed` nehmen: das ignoriert den Inhalt komplett und macht
   alle Spalten gleich breit – das Gegenteil von dem, was hier gewollt ist. */
table.data.data-fit th.col-filler, table.data.data-fit td.col-filler { width: 100%; padding: 0; }
table.data.data-fit th.col-actions, table.data.data-fit td.col-actions { width: 1%; white-space: nowrap; }
table.data.data-fit tbody td { white-space: nowrap; }

/* ⚠️ DIE AKTIONSZELLE IST HIER EIN GANZ NORMALES <td>. Das Flex sitzt auf einem INNEREN
   <div class="actions actions-icons"> (siehe member-index.blade.php). Bitte NICHT
   "vereinfachen", indem man die Klassen wieder ans <td> hängt – so war es, und es hatte
   ZWEI sichtbare Fehler zur Folge:

   1. ZERRISSENE ZEILENLINIEN. Ein <td> mit `display: flex` ist keine Tabellenzelle mehr:
      der Browser blockifiziert es und wickelt es in eine anonyme Zelle. Sein
      `border-bottom` liegt dann nicht mehr auf derselben Grundlinie wie die der
      Nachbarzellen – die Zeilentrennlinie brach an der Aktionsspalte ab und setzte
      versetzt wieder an. (Die berechneten Werte sahen dabei völlig korrekt aus – das
      hat mich beim ersten Anlauf getäuscht. Nur das AUGE bzw. ein Screenshot sieht es.)
   2. SENKRECHT GESTAPELTE ICONS. `td.actions` bringt `flex-wrap: wrap` mit und schlägt
      `.actions-icons` (0,1,1 gegen 0,1,0). Sobald die Spalte auf Inhaltsbreite schrumpft
      (`width: 1%`), ist die Mindestbreite eines umbrechenden Flex-Containers nur noch das
      BREITESTE EINZELNE ICON – der Browser drückt die Spalte auf ~60px und die vier Icons
      brechen untereinander um.

   Mit dem inneren <div> ist das <td> wieder eine echte Zelle (Linie durchgehend) und der
   Flex-Container ist `.actions .actions-icons` (dort gewinnt `nowrap`: gleiche
   Spezifität, steht später in dieser Datei). Beide Fehler sind damit STRUKTURELL weg –
   nicht per Sonderregel überklebt. */
table.data.data-fit td.col-actions .actions { justify-content: flex-end; }

/* Zellinhalt: lange Werte werden GEKÜRZT statt die Spalte aufzublähen.
   Der vollständige Wert hängt im title-Tooltip (siehe _cell.blade.php).

   Die Ellipse MUSS an einem Element IN der Zelle hängen, nicht am <td>: bei
   `table-layout: auto` ist eine Breitenangabe an der Zelle für den Browser nur ein
   Vorschlag, den er verwirft, sobald der Inhalt mehr verlangt. Ein Block-Element
   in der Zelle kann er nicht verwerfen. */
.cell { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cell-fest  { max-width: none; }   /* Datum, Betrag, Zahl, Ja/Nein – von Natur aus kurz */
.cell-kurz  { max-width: 12rem; }  /* Mitgliedsart, Auswahl */
.cell-text  { max-width: 14rem; }  /* Text (Name, Ort, Straße …) */
.cell-email { max-width: 16rem; }  /* E-Mail */
.cell-lang  { max-width: 20rem; }  /* Notiz und andere mehrzeilige Texte */

/* Anklickbarer NAME -> Detailansicht. Ein echter <button>, damit auch
   Tastaturnutzer ihn anspringen (Tab) und mit Enter öffnen können. Sieht aus wie
   Text, verrät die Klickbarkeit über Unterstreichung + Akzent beim Überfahren
   bzw. Fokus. Erbt Schrift/Farbe der Zelle; die Ellipse bleibt am inneren .cell. */
.cell-link {
    display: inline-flex; max-width: 100%;
    background: none; border: 0; padding: 0; margin: 0;
    font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.cell-link:hover { color: var(--accent); text-decoration: underline; }
.cell-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* Namenszelle der (gemischten) Liste: kleines Typ-Icon vor dem anklickbaren
   Namen (Verbands-Fall, ADR-0008). Das Icon steht dezent, gedämpft und nimmt
   keine eigene Spalte weg. */
.name-cell { display: inline-flex; align-items: center; gap: .4rem; max-width: 100%; }
.typ-icon { display: inline-flex; align-items: center; color: var(--muted); flex: 0 0 auto; }
.typ-icon .icon { width: 1rem; height: 1rem; }
.detail-modal-sub .typ-icon { color: var(--muted); }

/* Anklickbare Zeile -> Detailansicht. Die Aktionsspalte ist bewusst
   ausgenommen (kein Handler, eigener Zeiger). */
table.data tr.row-click td { cursor: pointer; }
table.data tr.row-click td.col-actions { cursor: default; }
table.data tr.row-click:hover td { background: var(--hover); }
table.data tr.row-click.is-open td { background: var(--accent-soft); }

/* Sortierbare Spaltenüberschrift: die ganze Überschrift ist der Knopf.
   Der Sortierzustand steht im Query-String (?sort=…&dir=…), nicht nur im
   Komponenten-Zustand – Neuladen und Teilen überstehen ihn deshalb. */
table.data th.sortable { padding: 0; }
.sort-btn {
    display: inline-flex; align-items: center; gap: .35rem;
    width: 100%;
    padding: .7rem .9rem;
    background: none; border: 0;
    font: inherit; color: inherit;
    text-transform: inherit; letter-spacing: inherit;
    text-align: left; cursor: pointer;
}
.sort-btn:hover { color: var(--ink); }
.sort-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
table.data th.sorted .sort-btn { color: var(--accent); }
.sort-ind { width: .8rem; height: .8rem; flex-shrink: 0; }
/* Ruhezustand: der Pfeil ist da, aber unsichtbar – er hält den Platz, damit die
   Überschrift beim Sortieren nicht springt, und erscheint beim Überfahren. */
.sort-ind-idle { opacity: 0; }
.sort-btn:hover .sort-ind-idle { opacity: .4; }

td.actions, .actions { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }
.actions a, .actions button {
    background: none; border: 0; padding: 0; margin: 0; cursor: pointer;
    color: var(--accent); font-family: inherit; font-size: .84rem; font-weight: 600; text-decoration: none;
}
.actions a:hover, .actions button:hover { text-decoration: underline; }
.actions .danger-link { color: var(--danger-ink); }

/* Icon-Aktionen (Lucide, inline via <x-icon.*>). Kompakte, nicht umbrechende
   Aktionsspalte; die Bedeutung hängt an title/aria-label. */
.actions-icons { flex-wrap: nowrap; gap: .15rem; white-space: nowrap; }
.icon { width: 1.05rem; height: 1.05rem; display: block; }
.actions .icon-btn, .detail-modal-head .icon-btn {
    display: inline-grid; place-items: center;
    width: 1.95rem; height: 1.95rem;
    padding: 0; border: 0; border-radius: var(--radius);
    background: none; color: var(--muted); cursor: pointer; text-decoration: none;
}
.actions .icon-btn:hover, .detail-modal-head .icon-btn:hover { background: var(--hover); color: var(--ink); text-decoration: none; }
.actions .icon-btn:focus-visible, .detail-modal-head .icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.actions .icon-btn.icon-danger { color: var(--danger-ink); }
.actions .icon-btn.icon-danger:hover { background: var(--danger-bg); color: var(--danger-ink); }
/* Gesperrte Aktion (z. B. amt-verwaltetes Login: „über Amt gesteuert"): sichtbar
   inert, kein Hover-Feedback. */
.actions .icon-btn:disabled { color: var(--muted); opacity: .4; cursor: not-allowed; }
.actions .icon-btn:disabled:hover { background: none; color: var(--muted); }
/* WEICH deaktiviert am Zeilensymbol (`.is-disabled`, DESIGN §4, Handoff 0143).
   Unterschied zu `:disabled` eine Zeile darueber: der Klick BLEIBT erhalten –
   nur so kann die Aktion serverseitig sagen, WARUM sie gerade nicht geht
   ("Anfangsbestand"/"Loeschen" an einem bebuchten Konto). Vorher verschwanden
   diese beiden Symbole wortlos, und die Begruendung stand ausgerechnet in der
   Meldung, die dadurch unerreichbar war. Deshalb auch kein `not-allowed`: der
   Zeiger darf nicht "kaputt" sagen, wenn ein Klick etwas erklaert. */
.actions .icon-btn.is-disabled { color: var(--muted); opacity: .4; }
.actions .icon-btn.is-disabled:hover { background: none; color: var(--muted); }
.actions .icon-btn.icon-danger.is-disabled:hover { background: none; color: var(--muted); }

/* --- Spaltenauswahl ("Spalten"-Knopf über der Liste) -----------------------
   Schreibt auf DIESELBE Einstellung wie "Einstellungen -> Felder": das
   in_liste-Flag im Feldregister. Es gibt keinen zweiten Speicherort. */
.col-menu-wrap { position: relative; }
.col-menu {
    position: absolute; right: 0; top: calc(100% + .4rem); z-index: 30;
    min-width: 16rem; max-height: 22rem; overflow-y: auto;
    background: var(--card);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: .45rem;
}
.col-menu-head {
    font-size: .67rem; font-weight: 650; letter-spacing: .05em; text-transform: uppercase;
    color: var(--muted); padding: .4rem .55rem .5rem;
}
.col-menu-item {
    display: flex; align-items: center; gap: .55rem;
    padding: .4rem .55rem; border-radius: var(--radius);
    font-size: .85rem; font-weight: 500; color: var(--ink);
    cursor: pointer; margin: 0;
}
.col-menu-item:hover { background: var(--hover); }
.col-menu-item.is-fixed { color: var(--muted); cursor: default; }
.col-menu-item.is-fixed:hover { background: transparent; }
.col-menu-note { font-size: .75rem; color: var(--muted); padding: .5rem .55rem 0; border-top: 1px solid var(--line); margin-top: .35rem; }

/* =============================================================================
   5. PANELS, BADGES, DETAILANSICHT, MODAL, PAGER
   ========================================================================== */
.panel {
    background: var(--card);
    border: 1px solid var(--nav-line);
    border-radius: var(--radius);
    padding: 1.25rem 1.35rem;
    margin-bottom: 1.1rem;
}
.panel p { color: var(--muted); margin: 0; }
.panel-lead { margin-bottom: 1.25rem !important; line-height: 1.5; font-size: .875rem; }
/* Tabellen-Panel: die Tabelle geht bis an die Kante (Haarlinien statt Innenrahmen). */
.panel-flush { padding: 0; overflow: hidden; }
.panel-flush .pager-wrap { padding: .75rem 1.35rem; border-top: 1px solid var(--line); margin: 0; }

.badge { display: inline-block; padding: .18rem .55rem; border-radius: 999px; font-size: .7rem; font-weight: 650; white-space: nowrap; }
.badge-aktiv { background: var(--ok-bg); color: var(--ok-ink); }
.badge-inaktiv { background: var(--off-bg); color: var(--off-ink); }
.badge-mandat-aktiv { background: var(--ok-bg); color: var(--ok-ink); }
.badge-mandat-ersetzt { background: var(--warn-bg); color: var(--warn-ink); }
.badge-mandat-widerrufen { background: var(--off-bg); color: var(--off-ink); }

/* ⚠ EINE MARKE BRICHT NICHT UM (`white-space: nowrap`, Nutzer-Befund
   18.08.2026). In der schmalen Spalte „Konto" der Konten-Tafel wurde aus
   „fest vorhanden" ein zweizeiliges Plaettchen – ein Kaestchen mit Rundung und
   Fuellung, in dem der Text auf zwei Zeilen umbricht, sieht gedrueckt aus und
   liest sich als zwei Marken. Die Marke ist EIN Etikett und damit unteilbar;
   dass sie ihrer Spalte etwas Breite abverlangt, ist billiger als ein
   gebrochenes Plaettchen. Die laengsten Marken des Hauses („seit N Tagen
   ueberfaellig", „Datei unveraendert") stehen alle in breiten Textspalten
   (`.zeile-haupt` = 42rem) bzw. in Listen ueber die ganze Breite – nachgesehen,
   nicht angenommen. */
.tag {
    display: inline-block; margin-left: .35rem; padding: .1rem .4rem;
    border-radius: 4px; font-size: .7rem; font-weight: 650;
    background: var(--accent-soft); color: var(--accent-ink);
    white-space: nowrap;
}
.tag-quiet { background: var(--off-bg); color: var(--off-ink); }
.tag-custom { background: var(--accent-soft); color: var(--accent-ink); }
/* Handoff 0134: „Datei weicht ab" auf der Belegpruefung – dieselbe Marke, nur
   in den vorhandenen Danger-Tokens. */
.tag-danger { background: var(--danger-bg); color: var(--danger-ink); }

.flash {
    background: var(--accent-soft); color: var(--accent-ink);
    border: 1px solid transparent;
    padding: .65rem .9rem; border-radius: var(--radius);
    margin-bottom: 1.1rem; font-size: .86rem; font-weight: 500;
}

.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* SEPA-Mandatsformular */
.mandat-form { margin-top: 1.25rem; border-top: 1px solid var(--line); padding-top: 1.25rem; }

/* =============================================================================
   DETAILANSICHT – zentriertes OVERLAY-FENSTER (Modal)
   =============================================================================
   WOZU: Es ersetzt das waagerechte Scrollen. Die Liste zeigt im Standard nur die
   vier Systemspalten; wer mehr sehen will, klickt den NAMEN an, statt Spalten
   zuzuschalten und die Tabelle breit zu ziehen. Das Fenster zeigt JEDES aktive Feld.

   FRÜHER war das ein Slide-over von rechts (.drawer*). Auf Nutzerwunsch jetzt ein
   zentriertes Fenster mit abgedunkeltem Hintergrund. Bedienung wie ein Modal: Esc
   schließt, Klick auf den Hintergrund schließt, der Fokus bleibt im Fenster
   gefangen (x-trap im Blade) und kehrt beim Schließen auf den auslösenden
   Namens-Button zurück.

   Es liegt über allem (z-index 60 > Lösch-Modal 50 > Spalten-Menü 30). Angemessene
   Breite (max. 44rem ≈ 704px); bei langem Inhalt scrollt der RUMPF in sich, nicht
   die Seite. Auf schmalen Schirmen nimmt es fast die volle Breite ein.
   ========================================================================== */
.detail-modal-overlay {
    position: fixed; inset: 0; z-index: 60;
    background: var(--overlay);
    display: grid; place-items: center;
    padding: 1.5rem; overflow-y: auto;
}
.detail-modal {
    width: 100%; max-width: 44rem;
    max-height: calc(100vh - 3rem);
    display: flex; flex-direction: column;
    background: var(--card); color: var(--ink);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    animation: detail-modal-in .16s ease-out;
}
@keyframes detail-modal-in { from { transform: translateY(.75rem); opacity: .6; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .detail-modal { animation: none; } }

.detail-modal-head {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem;
    padding: 1.25rem 1.35rem;
    border-bottom: 1px solid var(--line);
}
.detail-modal-head h2 { margin: 0 0 .35rem; font-size: 1.05rem; }
.detail-modal-sub { display: flex; align-items: center; gap: .5rem; margin: 0; font-size: .82rem; color: var(--muted); }

/* Der Rumpf scrollt, Kopf und Fuß bleiben stehen. */
.detail-modal-body { flex: 1; overflow-y: auto; padding: .5rem 1.35rem 1.25rem; }

.detail-section { padding-top: 1rem; }
.detail-section + .detail-section { border-top: 1px solid var(--line); margin-top: 1rem; }
.detail-section h3 {
    font-size: .7rem; text-transform: uppercase; letter-spacing: .06em; font-weight: 650;
    color: var(--muted); margin: 0 0 .7rem;
}

.detail-list { margin: 0; }
.detail-row {
    display: grid; grid-template-columns: 9.5rem 1fr; gap: .75rem;
    padding: .3rem 0; align-items: baseline;
}
.detail-row dt { color: var(--muted); font-size: .8rem; }
.detail-row dd { margin: 0; font-size: .875rem; word-break: break-word; }
/* Im Fenster wird NICHT gekürzt – hier soll der ganze Wert stehen (die Ellipse ist
   eine Eigenschaft der schmalen Tabellenspalte, nicht des Wertes). */
.detail-modal .cell { max-width: none; white-space: normal; overflow: visible; }

/* ⚠ `flex-wrap: wrap` IST HIER KEINE VERSCHOENERUNG, SONDERN DIE HAUSFORM
   (Handoff 0231, Nutzer-Befund 29.08.2026: „ich will nicht, dass es ueber das
   Overlay-Fenster ueberragt").

   Der Fuss ist eine Flex-Zeile, und ein `.btn` traegt `white-space: nowrap`
   (DESIGN §4). Ein Flex-Kind schrumpft nie unter seine Mindestbreite – bei
   einem nicht umbrechenden Knopf ist das seine VOLLE Breite. Ohne `flex-wrap`
   laeuft die Reihe deshalb nicht in den Umbruch, sondern GERADEAUS AUS DEM
   FENSTER HERAUS: gemessen am Mitgliedsantrag mit fuenf Knoepfen ragten
   „Schreiben" und „Schliessen" 70 px bzw. 176 px ueber die Fensterkante auf den
   abgedunkelten Hintergrund (Fenster 704 px breit, Knopfreihe 879 px).

   `.modal-actions` hatte den Umbruch von Anfang an; der Fuss des
   Detail-Fensters ist die zweite Bauform derselben Sache und war der einzige
   Ort, an dem er fehlte. Ein Waechter haelt beides fest:
   tests/Feature/Design/KnopfreiheBleibtImFensterTest.php.

   ⚠ `min-width: 0` am Knopf waere die falsche Antwort: dann schrumpfte die
   Beschriftung statt umzubrechen, und „Als Beschlusspunkt uebernehmen" stuende
   abgeschnitten da. Im Fenster wird NICHT gekuerzt (§8, vgl. `.detail-modal
   .cell`). */
.detail-modal-foot {
    display: flex; flex-wrap: wrap; gap: .6rem; align-items: center;
    padding: 1rem 1.35rem;
    border-top: 1px solid var(--line);
}

/* Modal (Sicherheitsabfragen, Feld anlegen/bearbeiten) */
.modal-overlay {
    position: fixed; inset: 0; z-index: 50;
    background: var(--overlay);
    display: grid; place-items: center; padding: 1.5rem; overflow-y: auto;
}
.modal {
    background: var(--card); color: var(--ink);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    padding: 1.6rem;
    max-width: 30rem; width: 100%;
    box-shadow: var(--shadow);
}
.modal-wide { max-width: 38rem; }
.modal h2 { margin: 0 0 .6rem; font-size: 1.05rem; }
.modal p { color: var(--muted); margin: 0 0 1rem; line-height: 1.5; font-size: .88rem; }
.modal .field-hint { margin: .3rem 0 0; }
.modal .static-value { font-size: .9rem; }
.modal code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .8rem; }
.modal-actions { display: flex; gap: .6rem; justify-content: flex-end; margin-top: 1rem; flex-wrap: wrap; }
/* „Standardbezeichnung wiederherstellen" gehört nach LINKS – es ist keine
   Bestätigung, sondern ein Rückweg. */
.modal-actions .btn-reset { margin-right: auto; }

/* Pagination */
.pager-wrap { margin-top: 1rem; }
.pager { display: flex; align-items: center; gap: .75rem; font-size: .82rem; }
.pager-btn {
    height: 2rem; padding: 0 .7rem;
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    background: var(--card); color: var(--ink);
    font-family: inherit; font-size: .82rem; cursor: pointer;
}
.pager-btn:hover { background: var(--hover); }
.pager-btn.disabled { color: var(--muted); cursor: default; background: transparent; }
.pager-info { color: var(--muted); }

/* =============================================================================
   6. ZENTRALE SEITEN (Landing + zentraler Login) – dieselben Tokens
   ========================================================================== */
/* Zentriert wie das Panel, nur enger: Der Container (--content-max) ist hier die
   OBERGRENZE, die tatsächliche Karte ist mit 26rem bewusst schmaler – eine
   Login-Karte über 1280px auszuwalzen wäre sinnlos. Sie sitzt auf derselben
   Achse (Seitenmitte) wie der Panel-Inhalt; der Seitenabstand kommt aus
   demselben Token wie dort. */
body.central { display: grid; place-items: center; padding: var(--content-pad); }

.central-card {
    width: 100%; max-width: min(26rem, var(--content-max));
    background: var(--card);
    border: 1px solid var(--nav-line);
    border-radius: var(--radius);
    padding: 2.25rem;
    box-shadow: var(--shadow);
}
.central-card h1 { font-size: 1.35rem; margin: 0 0 .4rem; }
.central-card .brand-central {
    font-weight: 650; font-size: 1rem; color: var(--ink);
    margin-bottom: 1.75rem; letter-spacing: -.01em;
}
.central-card .brand-central span { color: var(--accent); }
.central-card .muted { color: var(--muted); margin: 0 0 1.6rem; font-size: .9rem; line-height: 1.55; }
.central-card label { margin-bottom: .3rem; }
.central-card input { margin-bottom: 1rem; }
.central-card .btn, .central-card button[type=submit] { width: 100%; }

/* Passwort-Sichtbarkeit (Auge) im zentralen Login. Der Knopf sitzt rechts IM
   Feld und ueberlagert den Text NICHT (das Feld traegt rechts Platz per
   padding-right). Reines type-Umschalten via Alpine – siehe
   resources/views/livewire/auth/central-login.blade.php. Der Feld-Wrapper
   uebernimmt den Abstand nach unten (statt des Inputs), damit der Knopf an der
   Feld-Oberkante ausgerichtet bleibt. */
.pw-field { position: relative; margin-bottom: 1rem; }
.pw-field input { margin-bottom: 0; padding-right: 2.6rem; }
.pw-toggle {
    position: absolute; top: 0; right: 0;
    display: inline-grid; place-items: center;
    width: var(--h-control); height: var(--h-control);
    padding: 0; border: 0; border-radius: var(--radius);
    background: none; color: var(--muted); cursor: pointer;
}
.pw-toggle:hover { color: var(--ink); }
.pw-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.pw-toggle .icon { width: 1.1rem; height: 1.1rem; }
.central-card .error { color: var(--danger-ink); font-size: .8rem; margin: -.7rem 0 1rem; }
.central-card .notice {
    background: var(--warn-bg); color: var(--warn-ink);
    padding: .6rem .75rem; border-radius: var(--radius);
    font-size: .84rem; margin-bottom: 1.25rem;
}
.central-card .lead { color: var(--muted); font-size: .85rem; margin: 1.5rem 0 0; text-align: center; line-height: 1.5; }

.choices { display: flex; flex-direction: column; gap: .5rem; }
.choice {
    width: 100%; text-align: left;
    height: var(--h-control); padding: 0 .8rem;
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    background: var(--card); color: var(--ink);
    font-family: inherit; font-size: .9rem; font-weight: 600; cursor: pointer;
}
.choice:hover { border-color: var(--accent); background: var(--hover); }
.choice:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* =============================================================================
   IMPORT / EXPORT / DRUCK (Feature 0003)
   ========================================================================== */

/* Allgemeiner gedämpfter Fließtext (bisher nur in .central-card definiert). */
.muted { color: var(--muted); font-size: .875rem; line-height: 1.55; }

/* Flash-Varianten: warnend (übersprungene Zeilen) und Fehler (Ladefehler). */
.flash-warn { background: var(--warn-bg); color: var(--warn-ink); }
.flash-danger { background: var(--danger-bg); color: var(--danger-ink); }

/* Export-/Druck-Menü: Links als volle Zeilen (wie col-menu-item, aber <a>). */
.col-menu-link {
    display: block; padding: .4rem .55rem; border-radius: var(--radius);
    font-size: .85rem; font-weight: 500; color: var(--ink); text-decoration: none;
}
.col-menu-link:hover { background: var(--hover); }

/* Import-Assistent: Schrittanzeige. */
.import-steps {
    display: flex; flex-wrap: wrap; gap: .5rem; list-style: none;
    margin: 0 0 1.1rem; padding: 0;
}
.import-steps li {
    font-size: .8rem; font-weight: 600; color: var(--muted);
    background: var(--th-bg); border: 1px solid var(--line);
    padding: .35rem .7rem; border-radius: 999px;
}
.import-steps li.is-active { color: var(--on-accent); background: var(--accent); border-color: var(--accent); }

/* Import-Assistent: Zähl-Kacheln der Vorschau/des Ergebnisses. */
.import-counts { display: flex; flex-wrap: wrap; gap: .8rem; margin: 1rem 0 1.2rem; }
.import-count {
    background: var(--th-bg); border: 1px solid var(--line);
    border-radius: var(--radius); padding: .6rem 1rem; font-size: .85rem; color: var(--muted);
}
.import-count-num { display: block; font-size: 1.5rem; font-weight: 700; color: var(--ink); }
.import-errors { margin: .5rem 0 0; padding-left: 1.2rem; font-size: .82rem; }
.import-errors li { margin: .15rem 0; }

/* =============================================================================
   MAIL-CLUSTER (Rundmail + Newsletter, ADR-0010)
   ==========================================================================
   Der WYSIWYG-Editor ist Trix (selbst gehostet aus public/vendor/trix). Diese
   Overrides ziehen die Trix-Default-Optik auf das Kanzlei-System (Petrol-Akzent,
   Hairline, gemeinsame Höhe/Radius). trix.css wird VOR app.css geladen, damit
   diese Regeln greifen. */
.trix-field { display: block; }
trix-editor {
    min-height: calc(var(--h-control) * 4);
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    background: var(--card); color: var(--ink);
    padding: .6rem .75rem; font-family: inherit; font-size: .9rem; line-height: 1.5;
}
trix-editor:empty:not(:focus)::before { color: var(--muted); }
trix-editor:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
trix-editor h1 { font-size: 1.2rem; }
/* Zwischenüberschriften des Protokoll-Profils (ADR-0025/R1, Block-Attribute
   heading2/heading3 aus trix-livewire.js). H1 bleibt dem PDF-Dokumenttitel
   vorbehalten – im Editor tritt es nur bei Fremd-Einfügungen auf. */
trix-editor h2 { font-size: 1.1rem; }
trix-editor h3 { font-size: 1rem; }
trix-editor a { color: var(--accent); }

/* ============================================================================
   SITZUNGSPROTOKOLL: FOKUS-LAYOUT (ADR-0025/R1)
   ============================================================================
   Der Protokoll-Editor ist das Herz der Seite und bekommt viel Höhe; die
   Metadaten (Datum/Ort/Anwesende) sitzen darüber in einem einklappbaren Block
   und verdrängen ihn nicht. `x-cloak` verhindert das Aufblitzen des noch nicht
   von Alpine bearbeiteten Auf/Zu-Zustands (erste, projektweit genutzte Regel). */
.protokoll-editor trix-editor { min-height: min(60vh, 34rem); }
.sitzung-meta-zeile { margin-top: .25rem; }

/* TOP-EINFÜGEHILFE über dem Protokoll-Editor (ADR-0025, Etappe 3) ------------
   Die Tagesordnungspunkte stehen als kompakte Pillen ÜBER dem Textfeld; der
   Icon-Knopf je Pille setzt „TOP n: Titel" an der Cursorstelle in den Text
   (public/vendor/trix/trix-livewire.js → `trixTopEinfuegen`). Eine Zeile, die
   umbricht statt zu wachsen – sie darf den großen Editor NICHT verdrängen
   (Fokus-Layout oben). Lange Titel werden in der Pille abgeschnitten; der
   vollständige Titel steht im `title`/`aria-label` des Knopfes.

   `.icon-btn` ist projektweit IMMER kontextgebunden definiert (siehe
   `.actions .icon-btn`, `.menu-row .icon-btn`) – deshalb hier dieselbe Regel im
   eigenen Kontext, etwas kleiner als in einer Tabellenzeile. */
.protokoll-top-leiste {
    display: flex; flex-wrap: wrap; align-items: center; gap: .3rem;
    margin-bottom: .45rem;
}
.protokoll-top-leiste-titel { font-size: .82rem; color: var(--muted); margin-right: .1rem; }
.protokoll-top-chip {
    display: inline-flex; align-items: center; gap: .15rem; max-width: 20rem;
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    background: var(--card); padding: .1rem .15rem .1rem .5rem;
    font-size: .82rem; color: var(--ink);
}
.protokoll-top-chip-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.protokoll-top-chip-ohne { color: var(--muted); font-style: italic; }
.protokoll-top-leiste .icon-btn {
    display: inline-grid; place-items: center;
    width: 1.6rem; height: 1.6rem;
    padding: 0; border: 0; border-radius: var(--radius);
    background: none; color: var(--muted); cursor: pointer; text-decoration: none;
}
.protokoll-top-leiste .icon-btn:hover { background: var(--hover); color: var(--accent-ink); }
.protokoll-top-leiste .icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.protokoll-top-leiste .icon-btn:disabled { color: var(--muted); opacity: .4; cursor: not-allowed; }
.protokoll-top-leiste .icon-btn:disabled:hover { background: none; color: var(--muted); }
trix-toolbar { margin-bottom: .4rem; }
trix-toolbar .trix-button-row { flex-wrap: wrap; }
trix-toolbar .trix-button-group {
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    margin-bottom: .3rem;
}
trix-toolbar .trix-button {
    border-bottom: none; background: var(--card); color: var(--ink);
}
trix-toolbar .trix-button:not(:first-child) { border-left: 1px solid var(--line); }
trix-toolbar .trix-button:hover { background: var(--hover); }
trix-toolbar .trix-button.trix-active { background: var(--accent-soft); color: var(--accent-ink); }

/* ============================================================================
   UNSERE ICONS IN DER WERKZEUGLEISTE (Nutzerwunsch, DESIGN §9)
   ============================================================================
   Trix bringt eigene Icons mit – als `background-image`-Daten-URIs auf
   `.trix-button--icon-bold::before` & Co. Die passen nicht zum Lucide-Set des
   Rests, und weil sie Bilder sind, folgen sie auch keiner `currentColor`.

   DESHALB TRAGEN UNSERE KNÖPFE `trix-button--lucide` UND NICHT
   `trix-button--icon`: Die Klasse `--icon` bringt in trix.css `text-indent:
   -9999px` mit (sie versteckt die Beschriftung, damit nur das Hintergrundbild
   bleibt). Ein inline-SVG ist Inline-Inhalt – `text-indent` schöbe es mit den
   9999 px aus dem Knopf heraus. Die Klasse zu meiden ist der Fix; sie zu
   überschreiben wäre ein Kampf gegen drei Regeln statt eine Zeile.

   Trix ist das egal: der Toolbar-Controller findet seine Knöpfe über
   `data-trix-attribute`/`data-trix-action`, nie über eine Klasse. Die Klassen
   sind reine Optik.

   `float: left` aus trix.css blockifiziert `inline-flex` zu `flex` – zentriert
   wird trotzdem korrekt. */
trix-toolbar .trix-button--lucide {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.1rem; height: 1.8rem; padding: 0;
    color: var(--muted);
}
trix-toolbar .trix-button--lucide .icon { width: 1rem; height: 1rem; }
trix-toolbar .trix-button--lucide:hover { color: var(--ink); }
/* `trix-active` setzt Trix selbst, sobald der Cursor in fettem Text steht –
   der Knopf zeigt damit den Zustand, nicht nur die Möglichkeit. */
trix-toolbar .trix-button--lucide.trix-active { color: var(--accent-ink); }
trix-toolbar .trix-button--lucide:focus-visible {
    outline: 2px solid var(--accent); outline-offset: -2px;
}

/* Der Link-Dialog: Trix' Eingabefeld auf Kanzlei-Optik. (0,2,1) schlägt die
   gemeinsame Steuerelement-Regel `input[type=url]` (0,1,1) – dieselbe Lektion
   wie bei .nl-inline-input. */
trix-toolbar .trix-dialog {
    background: var(--card); border: 1px solid var(--line-strong);
    border-radius: var(--radius); box-shadow: var(--shadow);
    padding: .6rem;
}
trix-toolbar .trix-dialog input.trix-input--dialog {
    height: var(--h-control); font-size: .85rem;
    background: var(--card); color: var(--ink);
    border: 1px solid var(--line-strong); border-radius: var(--radius);
}
trix-toolbar .trix-dialog .trix-button--dialog {
    height: var(--h-control); padding: 0 .7rem;
    font-size: .8rem; font-weight: 600;
    border: 1px solid var(--line-strong); background: var(--card); color: var(--ink);
}

/* KEIN Datei-/Anhang-Knopf und KEIN `--file-tools`-Ausblenden mehr nötig: unsere
   Leiste baut die Gruppe gar nicht erst (components/trix-field.blade.php). Ein
   Knopf, den man erst rendert und dann versteckt, ist eine Zusage, die die
   Anwendung nicht hält – Anhänge sind projektweit verboten (ADR-0010). */

/* Der Rundmail-Verfassen-Dialog nutzt die bestehende `.modal-wide` (38rem,
   DESIGN §7) – keine eigene Modal-Breite (QA-Minor 3). Der Trix-Editor passt
   darin; die Toolbar bricht bei Bedarf auf zwei Reihen um. */

/* Newsletter: zweispaltig (Verfassen | Vorschau); auf schmalen Schirmen gestapelt. */
.newsletter-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; align-items: start; }
@media (max-width: 55rem) { .newsletter-grid { grid-template-columns: 1fr; } }
.newsletter-actions { display: flex; gap: .6rem; flex-wrap: wrap; }
.mail-preview {
    width: 100%; height: 30rem; border: 1px solid var(--line-strong);
    border-radius: var(--radius); background: var(--page);
}
/* Der Baukasten zeigt die ganze Mail (Kopf + Bausteine + Abmelde-Fuß) – 30rem
   wären dafür ein Guckloch. */
.mail-preview-hoch { height: 40rem; }

/* =============================================================================
   NEWSLETTER-BAUKASTEN (ADR-0011)
   ==========================================================================
   Drei Spalten: Palette | Leinwand | Optionen. `minmax(0, 1fr)` für die
   Leinwand ist PFLICHT, kein Schmuck: eine Grid-Spalte hat als Voreinstellung
   `min-width: auto` und schrumpft NICHT unter die Breite ihres Inhalts. Die
   Bausteine sind Tabellen mit `width: 100%` – ohne minmax(0, …) zögen sie die
   Spalte auf und die Seite scrollte waagerecht (DESIGN §3 schließt das aus).
   Dieselbe Lektion wie bei .settings-layout. */
/* ============================================================================
   EDITOR-ARBEITSBEREICH: ZWEI SPALTEN, NORMALE INHALTSBREITE (UI 0030)
   ============================================================================
   Bausteine (links, kompakt) · Leinwand (rechts). KEIN Breakout mehr – der
   Bereich bleibt im zentrierten Container (--content-max) wie der Rest der App
   (der Sonderfall „Editor breiter als der Container" aus UI 0027/0029 ist
   zurückgenommen). Die Leinwand nutzt den Platz der früheren rechten
   Gestaltungs-Spalte mit; diese ist abgeschafft. Die Gestaltung öffnet je
   Baustein über das ⋮-Popover in der Leinwand (siehe .nl-gestaltung-popover).
   Die Bausteine-Spalte klebt beim Scrollen; schmal klappt sie als Overlay ein. */
.nl-builder {
    margin-bottom: 1.1rem;
    min-width: 0;
    /* Breite der Bausteine-Spalte – hier justierbar. Kompakt (UI 0030: nur
       Symbol + Name, keine Beschreibung mehr), damit die Leinwand viel Platz
       bekommt. */
    --nl-rail-left: 11rem;
}

/* Karten-Fläche: Bausteine-Spalte, Leinwand UND das Gestaltungs-Popover
   (`.nl-options` trägt weiter die Kartenfläche; positioniert wird es als
   .nl-gestaltung-popover). */
.nl-palette-wrap, .nl-options, .nl-canvas-wrap {
    background: var(--card);
    border: 1px solid var(--nav-line);
    border-radius: var(--radius);
    padding: 1rem;
    min-width: 0;
}

/* --- BREIT (ab 64rem): zwei Spalten, normale Breite --------------------- */
@media (min-width: 64rem) {
    .nl-builder {
        display: grid;
        grid-template-columns: var(--nl-rail-left) minmax(0, 1fr);
        gap: 1rem;
        align-items: start;
    }
    .nl-builder-solo { grid-template-columns: minmax(0, 1fr); }

    /* Die Bausteine-Spalte klebt und scrollt intern – so bleibt sie erreichbar,
       ohne hochzuscrollen. `align-items: start` (oben) ist Bedingung fürs Kleben. */
    .nl-palette-wrap {
        position: sticky;
        top: 1rem;
        max-height: calc(100vh - 2rem);
        overflow-y: auto;
    }

    /* Kompakt-Umschalter, Overlay-Kopf und Abdunkelung gibt es nur schmal. */
    .nl-compact-bar { display: none; }
    .nl-col-close { display: none; }
    .nl-col-backdrop { display: none !important; }
}

/* --- SCHMAL (< 64rem): Spalten klappen ein, öffnen als Overlay ------------ */
/* Voreinstellung AUSGEBLENDET (die Umschalter gibt es nur schmal). WICHTIG: als
   `none` gesetzt, NICHT als `flex` – sonst gewönne diese (spätere) Basisregel
   gegen das `display: none` im Breit-Media-Query (gleiche Spezifität, Quell-
   Reihenfolge entscheidet) und die Leiste würde breit als 4. Grid-Element den
   Dreispalter zerlegen. `flex` wird unten im Schmal-Media-Query gesetzt. */
.nl-compact-bar { display: none; gap: .5rem; margin-bottom: 1rem; }
.nl-compact-btn {
    display: inline-flex; align-items: center; gap: .4rem;
    height: var(--h-control); padding: 0 .8rem;
    background: var(--card); color: var(--ink);
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    font: inherit; font-size: .85rem; font-weight: 600; cursor: pointer;
}
.nl-compact-btn:hover { background: var(--hover); border-color: var(--accent); }
.nl-compact-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nl-compact-btn.is-active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-ink); }
.nl-compact-btn .icon { width: 1.05rem; height: 1.05rem; flex: 0 0 auto; }

@media (max-width: 63.99rem) {
    /* Nur hier sind die Umschalter sichtbar. */
    .nl-compact-bar { display: flex; }

    /* Die Bausteine-Spalte liegt als Overlay über der Leinwand; per `is-open`
       (Alpine) fährt sie von links ein. Der Backdrop schließt sie. Die Leinwand
       bleibt lesbar breit, weil die Spalte aus dem Fluss ist. (Die rechte
       Gestaltungs-Spalte ist mit UI 0030 entfallen.) */
    .nl-col {
        position: fixed; top: 0; bottom: 0; z-index: 48;
        width: min(20rem, 86vw);
        max-height: 100vh; overflow-y: auto;
        border-radius: 0;
        transition: transform .2s ease;
    }
    .nl-palette-wrap.nl-col { left: 0; transform: translateX(-102%); }
    .nl-col.is-open { transform: none; box-shadow: var(--shadow); }
    .nl-col-backdrop { position: fixed; inset: 0; background: var(--overlay); z-index: 46; border: 0; }
}

.nl-col-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: .35rem; }
.nl-col-head h2 { margin: 0; }

.nl-hint { color: var(--muted); font-size: .78rem; margin: 0 0 .75rem; line-height: 1.45; }

/* --- LINKS: Bausteine, kompakt (UI 0030) --------------------------------
   Jeder Eintrag ist ein echter <button>: Klick hängt den Baustein unten an
   (ADR-0011 §3); der ganze Knopf ist zugleich der Sortable-Griff (Ziehen in die
   Leinwand). Kompakt: nur Griff + Symbol + Name in EINER Zeile – die Erklärung
   steckt im `title`-Tooltip (Nutzerwunsch: die Liste wird dadurch kleiner). */
.nl-palette { display: flex; flex-direction: column; gap: .3rem; }
.nl-palette-item {
    display: flex; align-items: center; gap: .45rem;
    width: 100%; padding: .35rem .5rem;
    background: var(--card); color: var(--ink);
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    font-family: inherit; text-align: left; cursor: pointer;
}
.nl-palette-item:hover { background: var(--hover); border-color: var(--accent); }
.nl-palette-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nl-palette-icon { display: inline-flex; color: var(--accent); flex: 0 0 auto; }
.nl-palette-icon .icon { width: 1.05rem; height: 1.05rem; }
.nl-palette-label { font-size: .82rem; font-weight: 600; line-height: 1.25; min-width: 0; overflow-wrap: anywhere; word-break: break-word; hyphens: auto; }

/* Griff: sichtbar in Palette UND Leinwand (dort zieht nur er). */
.nl-grip {
    display: inline-flex; align-items: center;
    color: var(--muted); cursor: grab; flex: 0 0 auto;
}
.nl-grip:active { cursor: grabbing; }
.nl-grip .icon { width: .95rem; height: .95rem; }
.nl-palette-item:hover .nl-grip { color: var(--accent); }

/* --- RECHTS: Ein-Zeilen-Hinweis je Optionsgruppe (UI 0029) --------------- */
.nl-opt-hint { color: var(--muted); font-size: .72rem; line-height: 1.35; margin: 0 0 .4rem; }

/* DER KOPF DES GESTALTUNGS-PANELS: „wessen Optionen stehen hier?"

   Nutzer-Befund: die Option „Bild-Position" wurde nicht gefunden, obwohl sie seit
   Etappe 2 in genau diesem Panel steht. Sie stand dort nur für einen Baustein,
   den man erst auswählen musste – und die Auskunft darüber, welcher das gerade
   ist, war eine graue Hinweiszeile in derselben Schrift wie die Erklärtexte
   darunter. Zwischen „Gestaltung" und den Kacheln fehlte der Satz „von DIESEM
   Baustein hier".

   Die Fläche ist dieselbe wie die der Auswahl-Marke am Baustein
   (`--accent-soft`): gleiche Farbe = gleiche Sache. Wer die Verbindung kappt,
   nimmt genau die Auskunft weg, um die es hier geht. */
.nl-options-block {
    display: flex; align-items: center; gap: .5rem;
    background: var(--accent-soft); color: var(--accent-ink);
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    padding: .45rem .6rem;
    margin-bottom: .9rem;
}
.nl-options-block-icon { display: inline-flex; flex: 0 0 auto; }
.nl-options-block-icon .icon { width: 1.05rem; height: 1.05rem; }
.nl-options-block-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.nl-options-block-text strong { font-size: .85rem; font-weight: 650; }
.nl-options-block-text small { font-size: .68rem; opacity: .8; }

/* --- Leinwand ------------------------------------------------------------- */
.nl-canvas-wrap { padding: 1rem 1rem 1.25rem; }
.nl-canvas-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.nl-saved { font-size: .75rem; color: var(--muted); }

.nl-canvas {
    display: flex; flex-direction: column; gap: .5rem;
    min-height: 8rem; margin-top: .75rem;
    border-radius: var(--radius);
}
/* Rückmeldung WÄHREND des Ziehens: die Leinwand bekommt einen Akzent-Umriss,
   damit unmissverständlich ist, wo abgelegt werden kann. */
body.nl-is-dragging .nl-canvas {
    outline: 2px dashed var(--accent); outline-offset: 4px;
    background: var(--accent-soft);
}

/* KEIN `overflow: hidden` mehr (UI 0030): das ⋮-Gestaltungs-Popover ist
   `position: absolute` INNERHALB des Bausteins und würde von einem Overflow
   abgeschnitten (dieselbe Lehre wie beim „Erweitert"-Popover, Handoff 0028).
   Die runden Ecken, die früher das Overflow erledigte, übernehmen jetzt die
   Leiste (oben) und das Band (unten) selbst. */
.nl-block {
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    background: var(--card);
}
/* AUSGEWÄHLT – deutlich, nicht dezent (Nutzer-Befund: die Option „Bild-Position"
   wurde nicht gefunden, weil unklar war, welcher Baustein gerade gestaltet wird).

   Vorher trug der Zustand nur einen 2 px starken Petrol-Rand. Der ist auf einer
   Leinwand aus zehn weißen Karten, die alle einen Rand haben, kein Signal – er
   ist eine Nuance. Jetzt färbt sich zusätzlich die KOPFZEILE des Bausteins in
   der Akzentfläche und trägt das Wort „Ausgewählt". Dieselbe Fläche und dasselbe
   Wort stehen im Kopf des Gestaltungs-Panels (.nl-options-block) – die beiden
   sind über Farbe UND Text verbunden, nicht nur über die Behauptung. */
.nl-block.is-selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.nl-block.is-selected .nl-block-bar {
    background: var(--accent-soft); border-bottom-color: var(--accent);
}
.nl-block.is-selected .nl-block-typ { color: var(--accent-ink); }

/* DIE KOPFZEILE IST DER WEG ZUR AUSWAHL – sie muss sich als klickbar zu
   erkennen geben. Der Text darunter ist es nicht mehr: seit 0023 öffnet ein
   Klick darauf das Editor-Fenster. */
/* `flex-wrap: wrap` IST PFLICHT, KEIN SCHLIFF – und es ist meine eigene Lehre
   aus dieser Runde:

   Die Leiste ist eine Flex-Zeile aus Griff + Name + Marke + vier Icons. Ohne
   `wrap` ist ihre min-content-Breite die SUMME davon (gemessen: 355 px), und
   weil sie in einer Grid-Spalte steckt, wurde die Spalte nie schmaler als das –
   die Seite scrollte bei 320 px waagerecht. Die „Ausgewählt"-Marke dieser Runde
   hat 90 px davon beigesteuert und den Fehler ERST AUSGELÖST: vorher blieb die
   Summe knapp unter der Grenze. Ich habe damit auf der Newsletter-Seite genau
   den Fehler gebaut, den ich auf den anderen Seiten beheben sollte – gesehen hat
   ihn nur der Browser-Durchgang bei 320 px, kein Test.

   Mit `wrap` ist die min-content-Breite nur noch das breiteste EINZELNE Kind
   (die Icon-Gruppe, 132 px). Dieselbe Mechanik und dieselbe Antwort wie beim
   Hauptmenü (`.mainnav`) weiter oben. Wer eine fünfte Sache in die Leiste hängt,
   muss das hier nicht anfassen – genau dafür ist es da. */
.nl-block-bar {
    display: flex; align-items: center; gap: .4rem;
    flex-wrap: wrap;
    padding: .25rem .4rem;
    background: var(--th-bg); border-bottom: 1px solid var(--line);
    /* Runde die obere Kante selbst (der Baustein hat kein overflow:hidden mehr,
       UI 0030), sonst überragte die Leistenfläche die runde Baustein-Ecke. */
    border-top-left-radius: calc(var(--radius) - 1px);
    border-top-right-radius: calc(var(--radius) - 1px);
    /* Anker für das ⋮-Gestaltungs-Popover (rechtsbündig zur Leiste). */
    position: relative;
    cursor: pointer;
}
.nl-block-bar:hover { background: var(--hover); }
.nl-block.is-selected .nl-block-bar:hover { background: var(--accent-soft); }
/* Der Fokus-Ring liegt INNEN (`-2px`): die Leiste sitzt bündig am Rand des
   Bausteins, ein außenliegender Ring würde vom `overflow: hidden` des .nl-block
   abgeschnitten. */
.nl-block-bar:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.nl-block-typ { font-size: .7rem; font-weight: 650; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }

/* „Ausgewählt" in Worten. Ein Farbunterschied allein ist für Rot-Grün-Schwäche
   und auf schlechten Bildschirmen keine Auskunft (DESIGN §1: Petrol ist der
   einzige Akzent – er muss also nicht allein tragen müssen). */
.nl-block-marke {
    font-size: .62rem; font-weight: 650;
    text-transform: uppercase; letter-spacing: .04em;
    color: var(--accent-ink);
    border: 1px solid var(--accent);
    border-radius: 999px;
    padding: 0 .4rem;
    white-space: nowrap;
}
.nl-block-bar .actions { margin-left: auto; }
.nl-block-bar .icon-btn:disabled { opacity: .3; cursor: not-allowed; }
.nl-block-bar .icon-btn:disabled:hover { background: transparent; }

/* --- ⋮ GESTALTUNG PRO BAUSTEIN (UI 0030) ---------------------------------
   Das ⋮-Menü in der Baustein-Leiste öffnet die Optionen GENAU dieses Bausteins
   als schwebendes Popover – Anwendung des Popover-Musters aus Handoff 0028.
   Verankert an der Leiste (`.nl-block-bar` ist `position: relative`),
   rechtsbündig, über dem Inhalt: KEIN Reflow, schiebt nichts. Der Baustein
   trägt dafür kein `overflow: hidden` mehr (sonst würde das Popover
   abgeschnitten – dieselbe Falle wie beim „Erweitert"-Popover, 0028).

   FLÄCHE/RAHMEN/RADIUS/PADDING kommen aus `.nl-options` (Kartenregel), das der
   Popover-Container zusätzlich trägt – so greifen ALLE bestehenden Options-Stile
   (Kacheln, Segmente, Farbfeld, Erweitert) unverändert (reine Anordnung). */
.nl-gestaltung-anker { display: inline-flex; }
.nl-gestaltung-anker .icon-btn.is-active {
    color: var(--accent-ink); background: var(--accent-soft);
}
.nl-gestaltung-popover {
    position: absolute; top: calc(100% + .35rem); right: .4rem; z-index: 45;
    /* Gegen schmale Viewports gedeckelt: das Popover ist rechtsbündig an der
       Leiste verankert, deren rechte Kante rund 3 rem vom Viewport-Rand einrückt.
       Damit die linke Kante bei ~360 px NICHT aus dem Bild läuft (kein
       Abschneiden, DESIGN §3), deckelt `100vw - 4.5rem` die Breite so, dass die
       Box vollständig im Viewport bleibt. Breit greift die 20-rem-Grenze. */
    width: min(20rem, calc(100vw - 4.5rem));
    max-height: min(70vh, 34rem); overflow-y: auto;
    box-shadow: var(--shadow);
    /* Die Leiste vererbt `cursor: pointer` – im Popover ist der Zeiger normal. */
    cursor: default;
    text-align: left;
}
/* Zu = aus dem Bild. Wie bei `.nl-erweitert-inhalt`: ein eigenes `display`
   könnte sonst das UA-`[hidden]` überstimmen – hier explizit sichergestellt. */
.nl-gestaltung-popover[hidden] { display: none; }

/* --- Die ABLEGEZONE (ADR-0011 §3) -----------------------------------------
   Der Ghost ist der gezogene Knoten selbst; `ghostClass` macht ihn zur
   Ablegezone: gestrichelter Petrol-Rahmen auf --accent-soft mit KLARTEXT
   („Text hier ablegen"). Der Text kommt per attr() aus data-drop-label, das
   der Sortable-Adapter beim Ziehstart setzt. Direkte Antwort auf den früheren
   Nutzer-Befund „unklares Drag-and-drop". */
.nl-ghost {
    position: relative;
    min-height: 4rem;
    border: 2px dashed var(--accent) !important;
    border-radius: var(--radius);
    background: var(--accent-soft) !important;
    box-shadow: none !important;
    overflow: hidden;
}
.nl-ghost > * { visibility: hidden; }
.nl-ghost::after {
    content: attr(data-drop-label);
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    color: var(--accent-ink); font-size: .82rem; font-weight: 650;
    visibility: visible;
}
/* Das Drag-Bild (forceFallback: gleiches Bild in allen Browsern). */
.nl-fallback {
    opacity: .9; box-shadow: var(--shadow);
    border: 1px solid var(--accent) !important; border-radius: var(--radius);
    background: var(--card) !important;
}

/* Dauerhafter Hinweis auf leerer Leinwand; beim Ziehen zusätzlich sichtbar. */
.nl-drop-hint {
    display: none;
    padding: 1.35rem; text-align: center;
    color: var(--accent-ink); font-size: .82rem; font-weight: 600;
    border: 2px dashed var(--line-strong); border-radius: var(--radius);
}
.nl-drop-hint.is-empty { display: block; }
body.nl-is-dragging .nl-drop-hint { display: block; border-color: var(--accent); }

/* --- Das BAND: die Bausteine im Editor ------------------------------------
   Die Partials unter resources/views/emails/blocks/* sind vollständig INLINE
   gestylt und schlagen damit app.css in der Kaskade – die Editor-Fläche zeigt
   deshalb dieselbe Optik wie die Mail. Dieser knappe Scope fängt nur die
   Restrisiken ab (Basis-Typografie, table-Resets), die sonst aus app.css in
   die Bänder lecken würden (ADR-0011 §2). */
/* Das Band rundet seine UNTERE Kante selbst und klippt seinen Inhalt darauf
   (der Baustein hat kein overflow:hidden mehr, UI 0030) – sonst überragte die
   Baustein-Fläche die runde untere Ecke. Das Popover liegt in der Leiste, nicht
   im Band, wird also nicht angeschnitten. */
.nl-band {
    display: block; overflow: hidden;
    border-bottom-left-radius: calc(var(--radius) - 1px);
    border-bottom-right-radius: calc(var(--radius) - 1px);
}
.nl-band table { border-collapse: collapse; max-width: 100%; }
.nl-band p, .nl-band h1, .nl-band h2, .nl-band h3 { margin: 0 0 .6rem; }
.nl-band p:last-child, .nl-band h1:last-child, .nl-band h2:last-child, .nl-band h3:last-child { margin-bottom: 0; }
.nl-band ul, .nl-band ol { margin: 0 0 .6rem; padding-left: 1.4rem; }

/* Inline-Bearbeitung IM Band: das Feld erbt Schrift, Größe, Farbe und
   Ausrichtung von der Zelle des Bausteins – deshalb sieht der Text schon beim
   Tippen so aus wie in der Mail. Kein zweiter Editor-Look.

   `.nl-band input.nl-inline-input` (0,2,1) ist PFLICHT, keine Angeberei: die
   gemeinsame Steuerelement-Regel oben adressiert `input[type=text]` und hat
   damit Spezifität 0,1,1 – eine reine Klasse (0,1,0) verliert gegen sie. Mit
   nur `.nl-inline-input` bekam das Feld die weiße Karten-Fläche samt Rahmen und
   stand als weißer Kasten IM Akzent-Band (im Browser-Check gesehen; in keinem
   Backend-Test sichtbar). */
.nl-band input.nl-inline-input {
    width: 100%; height: auto; min-height: 0;
    padding: 0; margin: 0;
    background: transparent; border: 0; border-radius: 0;
    font: inherit; color: inherit; text-align: inherit; line-height: inherit;
}
.nl-band input.nl-inline-input::placeholder { color: currentColor; opacity: .55; }
.nl-band input.nl-inline-input:focus, .nl-band input.nl-inline-input:focus-visible {
    outline: 2px solid currentColor; outline-offset: 3px; border: 0;
}
.nl-band input.nl-inline-input-knopf { width: auto; min-width: 6rem; text-align: center; }

/* Zusatzfeld eines Bausteins (z. B. die Ziel-Adresse des Knopfes). Sichtbar
   NUR im Editor – in der Mail existiert es nicht. */
.nl-editor-feld { margin-top: .6rem; text-align: left; }
.nl-editor-feld label {
    display: block; font-size: .7rem; font-weight: 600;
    color: var(--muted); margin-bottom: .2rem;
}
/* Das Feld liegt IN einem Band, dessen Zelle Farbe/Größe/Ausrichtung vererbt –
   hier gilt wieder die normale Kanzlei-Optik, deshalb explizit zurücksetzen.
   `input[type=text]` (Alt-Text der Bild-Bausteine) braucht dieselbe Behandlung;
   beide Selektoren haben (0,2,1) und schlagen damit die gemeinsame
   Steuerelement-Regel (0,1,1) – dieselbe Lektion wie bei .nl-inline-input. */
.nl-editor-feld input[type=url],
.nl-editor-feld input[type=text] {
    height: 2rem; font-size: .8rem;
    background: var(--card); color: var(--ink); text-align: left;
}
.nl-editor-feld .field-hint { color: var(--muted); }

/* --- Bild-Bausteine: Upload-Fläche im Band (ETAPPE 2, ADR-0011 §7) ---------
   Sichtbar NUR im Editor – in der Mail existiert nichts davon.

   `input[type=file]` ist nicht stylebar (der Browser rendert sein eigenes
   Widget – dieselbe Lektion wie bei <select>, DESIGN §4). Deshalb liegt das
   Feld unsichtbar IN einem <label>: der Klick auf das Label öffnet den Dialog,
   die Tastaturbedienung bleibt erhalten. `display:none` wäre falsch – das nähme
   dem Feld den Fokus. */
.nl-bild-edit, .nl-galerie-edit { text-align: left; }

.nl-upload-zone {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .25rem; padding: 1.5rem 1rem; cursor: pointer;
    border: 1px dashed var(--line-strong); border-radius: var(--radius);
    background: var(--card); color: var(--muted); text-align: center;
}
.nl-upload-zone:hover { border-color: var(--accent); color: var(--accent-ink); background: var(--accent-soft); }
.nl-upload-zone:focus-within { outline: 2px solid var(--accent); outline-offset: 1px; }
.nl-upload-zone .icon { width: 1.25rem; height: 1.25rem; color: var(--accent); }
.nl-upload-zone-schmal { padding: .9rem 1rem; }
.nl-upload-titel { font-size: .85rem; font-weight: 600; color: var(--ink); }
.nl-upload-sub { font-size: .72rem; color: var(--muted); }
/* Das echte Feld: unsichtbar, aber vorhanden und fokussierbar. */
.nl-upload-zone input[type=file], .nl-datei-btn input[type=file] {
    position: absolute; width: 1px; height: 1px; opacity: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

.nl-bild-vorschau {
    display: block; max-width: 100%; height: auto;
    border-radius: var(--radius); border: 1px solid var(--line);
}
.nl-bild-aktionen { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .5rem; }
.nl-bild-aktionen .btn { height: 2rem; font-size: .78rem; padding: 0 .7rem; }
.nl-datei-btn { position: relative; display: inline-flex; align-items: center; gap: .35rem; cursor: pointer; }
.nl-datei-btn .icon { width: .9rem; height: .9rem; }

.nl-upload-laeuft { margin-top: .4rem; font-size: .75rem; color: var(--muted); }
.nl-upload-fehler { margin-top: .4rem; }

/* --- Abgelehnte Datei: SICHTBARE Meldung an der Upload-Fläche (Handoff 0067) --
   Aufbau wie .nl-warn (Icon + Text im Kasten), aber in --danger-*: hier gilt
   nicht „das solltest du wissen", sondern „diese Datei wurde nicht angenommen".
   Der frühere `.field-error`-Einzeiler ging neben dem Hilfetext unter – genau
   deshalb wirkte ein HEIC-Foto vom iPhone wie „es passiert einfach nichts". */
.nl-upload-meldung {
    display: flex; gap: .5rem; align-items: flex-start;
    background: var(--danger-bg); color: var(--danger-ink);
    border: 1px solid var(--danger-ink);
    border-radius: var(--radius); padding: .5rem .6rem; margin-top: .5rem;
}
.nl-upload-meldung .icon { width: 1rem; height: 1rem; flex: 0 0 auto; margin-top: .1rem; }
.nl-upload-meldung p { margin: 0; font-size: .8rem; line-height: 1.45; font-weight: 600; }
/* Die Handlungsanweisung (z. B. der iPhone-Weg zu „Maximale Kompatibilität")
   trägt weniger Gewicht als der Grund, steht aber im selben Kasten. */
.nl-upload-meldung p.nl-upload-meldung-tun { margin-top: .25rem; font-weight: 400; }
/* Galerie-Mehrfachauswahl: pro abgelehnter Datei eine Zeile (Handoff 0073) –
   z. B. „foto.heic“ – HEIC-Format … . Der iPhone-Weg steht danach
   EINMAL in .nl-upload-meldung-tun, nicht je Zeile. */
.nl-upload-meldung-liste { margin: .3rem 0 0; padding-left: 1.1rem; }
.nl-upload-meldung-liste li { margin: 0; font-size: .8rem; line-height: 1.45; font-weight: 600; }

/* Der Ehrlichkeits-Satz zum öffentlichen Bild-Link (ADR-0011 §7 verlangt ihn
   ausdrücklich) – dezent, aber immer da. */
.nl-bild-hinweis { margin-top: .5rem; color: var(--muted); }

/* --- Galerie-Baustein: die Liste im Editor -------------------------------- */
.nl-galerie-liste { display: flex; flex-direction: column; gap: .4rem; margin-bottom: .6rem; }
.nl-galerie-item {
    display: flex; align-items: center; gap: .5rem;
    padding: .35rem; border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--card);
}
.nl-galerie-thumb {
    flex: 0 0 auto; width: 3rem; height: 3rem;
    object-fit: cover; border-radius: 4px; background: var(--hover);
}
.nl-galerie-fehlt {
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--muted); border: 1px dashed var(--line-strong);
}
.nl-galerie-fehlt .icon { width: 1.1rem; height: 1.1rem; }
/* (0,2,1) – schlägt die gemeinsame Steuerelement-Regel, wie .nl-inline-input. */
.nl-galerie-item input.nl-galerie-alt {
    flex: 1 1 auto; min-width: 0;
    height: 2rem; font-size: .8rem;
    background: var(--card); color: var(--ink); text-align: left;
}

/* --- Dokument-Baustein (Feature 0011): Liste + Editor ---------------------- */
.nl-dokument-edit { text-align: left; }
.nl-dokument-warnung {
    display: flex; align-items: flex-start; gap: .5rem;
    margin-bottom: .7rem; padding: .55rem .7rem;
    border: 1px solid var(--warn-line, #e0b64d); border-radius: var(--radius);
    background: var(--warn-soft, #fdf6e3); color: var(--ink);
}
.nl-dokument-warnung .icon { width: 1rem; height: 1rem; flex: 0 0 auto; margin-top: .15rem; color: var(--warn-ink, #9a6b00); }
.nl-dokument-warnung p { margin: 0; font-size: .78rem; line-height: 1.45; }
.nl-dokument-liste { display: flex; flex-direction: column; gap: .4rem; margin-bottom: .6rem; }
.nl-dokument-item {
    display: flex; align-items: center; gap: .5rem;
    padding: .4rem .5rem; border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--card);
}
.nl-dokument-symbol { flex: 0 0 auto; display: inline-flex; color: var(--muted); }
.nl-dokument-symbol .icon { width: 1.25rem; height: 1.25rem; }
.nl-dokument-daten { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: .2rem; }
.nl-dokument-datei { font-size: .82rem; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nl-dokument-fehlt { color: var(--muted); font-style: italic; font-weight: 400; }
.nl-dokument-groesse { font-size: .72rem; color: var(--muted); }
/* (0,2,1) – schlägt die gemeinsame Steuerelement-Regel, wie .nl-galerie-alt. */
.nl-dokument-daten input.nl-dokument-label {
    height: 1.9rem; font-size: .78rem;
    background: var(--card); color: var(--ink); text-align: left;
}
.nl-dokument-knoepfe { flex: 0 0 auto; display: inline-flex; gap: .1rem; }

/* --- Dokument-Baustein: die öffentliche Download-Liste (auch Editor-Leinwand) --- */
.wb-dokumente .wb-dokument-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.wb-dokument-item { margin: 0; }
.wb-dokument-link {
    display: flex; align-items: center; gap: .7rem;
    padding: .7rem .9rem; border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--card); text-decoration: none; color: var(--ink);
    transition: border-color .12s, background .12s;
}
.wb-dokument-link:hover { border-color: var(--accent); background: var(--accent-soft); }
.wb-dokument-icon { flex: 0 0 auto; display: inline-flex; color: var(--accent); }
.wb-dokument-icon .icon { width: 1.25rem; height: 1.25rem; }
.wb-dokument-text { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.wb-dokument-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; }
.wb-dokument-meta { font-size: .75rem; color: var(--muted); }

/* ============================================================================
   RICH-TEXT AUF DER LEINWAND: ANKLICKEN STATT TIPPEN
   ============================================================================
   Seit der Overlay-Umstellung steht in der Leinwand KEIN Trix-Editor mehr,
   sondern das gerenderte Ergebnis (emails/blocks/_rt_editor.blade.php). Damit
   sind ZWEI frühere Regeln ersatzlos entfallen – sie hatten keine Ursache mehr:

     - `.nl-band trix-editor { … }` (heller Grund für den Editor im Band),
     - `.nl-canvas trix-toolbar .trix-button-group { flex-wrap: wrap }` – der
       FLICKEN aus Handoff 0021 gegen die Werkzeugleiste, die aus der
       „Zwei Spalten"-Zelle lief. Das Fenster hat die Ursache beseitigt: das
       Werkzeug steht nicht mehr in der schmalen Spalte.

   Die Fläche muss als anklickbar ERKENNBAR sein, ohne die Vorschau zu
   verfälschen: kein Rahmen, keine Fläche im Ruhezustand – die Leinwand soll
   zeigen, wie die Mail aussieht. Erst Hover/Fokus zeigen das Angebot. */
.nl-band .nl-rt-klick {
    cursor: text;
    border-radius: 4px;
    /* Der Umriss liegt AUSSERHALB (outline, nicht border): eine border
       verschöbe das Layout beim Hover um 2 px und die Vorschau flackerte. */
    outline: 2px dashed transparent;
    outline-offset: 3px;
    transition: outline-color .12s ease-out, background-color .12s ease-out;
}
.nl-band .nl-rt-klick:hover { outline-color: var(--accent); }
.nl-band .nl-rt-klick:focus-visible {
    outline: 2px solid var(--accent); outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) { .nl-band .nl-rt-klick { transition: none; } }

/* Eine leere Fläche braucht sichtbaren Platz – sonst gibt es nichts zu klicken.
   `currentColor` + Deckkraft statt --muted: der Platzhalter steht auf der Fläche
   des Bausteins und muss auch auf „Dunkel"/„Akzent" lesbar bleiben. Dieselbe
   Lösung wie bei ::placeholder der Inline-Felder. */
.nl-band .nl-rt-klick.is-leer { min-height: 1.5em; }
.nl-band .nl-rt-leer { color: currentColor; opacity: .55; }

/* ============================================================================
   KURZER RICH-TEXT + MARKIER-LEISTE (Überschrift, Zitat-Quelle)
   ============================================================================
   Nutzerwunsch: „Vielleicht, wenn man den Text markiert, erscheint ein Editor."

   Das Feld erbt Schrift, Größe, Farbe und Ausrichtung von der Zelle des
   Bausteins – exakt wie das frühere `.nl-inline-input`, das es ablöst. Kein
   zweiter Editor-Look: Was man tippt, sieht schon beim Tippen aus wie in der
   Mail. Ein `contenteditable` bringt (anders als ein `<input>`) von sich aus
   keine Steuerelement-Optik mit, deshalb ist hier weniger zurückzunehmen –
   die Spezifitätsfalle von `.nl-inline-input` (input[type=text] = 0,1,1 schlägt
   eine reine Klasse) gibt es hier nicht. */
.nl-band .nl-kurz-feld { display: block; }
.nl-band .nl-kurz {
    display: block;
    min-height: 1.3em;
    outline: 2px dashed transparent;
    outline-offset: 3px;
    border-radius: 4px;
    cursor: text;
    /* Einzeilig ist eine Zusage des Feldes (Enter wird abgefangen), aber ein
       langer Titel MUSS umbrechen dürfen – sonst zöge er das Band auf und die
       Leinwand scrollte waagerecht. */
    overflow-wrap: anywhere;
}
/* Dieselbe Rückmeldung wie an der Rich-Text-Fläche (.nl-rt-klick): outline statt
   border, sonst verschöbe der Hover das Layout um 2 px. */
.nl-band .nl-kurz:hover { outline-color: var(--accent); }
.nl-band .nl-kurz:focus, .nl-band .nl-kurz:focus-visible {
    outline: 2px solid currentColor; outline-offset: 3px;
}
/* Der Platzhalter. `currentColor` + Deckkraft statt --muted, damit er auch auf
   „Dunkel"/„Akzent" lesbar bleibt – dieselbe Lösung wie bei .nl-rt-leer und
   ::placeholder. `:empty` reicht als Bedingung NICHT: der Browser hinterlässt
   beim Leeren ein <br>, und das Element ist dann nicht mehr leer. Die Klasse
   setzt deshalb JS (kurztext.js). */
.nl-band .nl-kurz.is-leer::before {
    content: attr(data-platzhalter);
    color: currentColor; opacity: .55;
    pointer-events: none;
}

/* DIE MARKIER-LEISTE – sie erscheint nur bei einer Markierung.

   `position: fixed`, nicht `absolute`: Sie steht in einer Tabellenzelle eines
   Bausteins. Ein `absolute`-Anker bräuchte einen `relative`-Vorfahren, und den
   dürfen die Baustein-Partials nicht bekommen – sie rendern auch die MAIL, und
   dort hat `position` nichts verloren (halbe Client-Landschaft ignoriert es).
   `fixed` entkommt außerdem jedem `overflow` auf dem Weg nach oben. Gestellt
   und auf die Leinwand geklemmt wird sie in JS.

   `--shadow` + Karte: sie schwebt über dem Text und muss sich davon absetzen –
   dasselbe Mittel wie beim Overlay-Fenster. */
.nl-markierleiste {
    position: fixed;
    z-index: 30;
    display: flex; align-items: center;
    background: var(--card);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: .2rem;
}
/* `hidden` muss gewinnen: `.nl-markierleiste` setzt `display: flex` und schlüge
   sonst das Attribut (dessen Vorgabe `display: none` aus dem Browser-Stylesheet
   kommt und nur Spezifität 0,0,1 hat). Ohne diese Zeile stünde die Leiste
   dauerhaft im Bild – und zwar an Position 0/0. */
.nl-markierleiste[hidden] { display: none; }
.nl-mark-werkzeuge { display: flex; gap: .1rem; }
.nl-mark-werkzeuge[hidden] { display: none; }

/* Die vier Werkzeuge. Kompakt wie `.icon-btn` (Sekundärelement INNERHALB der
   Leiste, die den Kontext gibt) – NICHT `.btn-icon`: der wäre --h-control hoch
   und machte aus der schwebenden Leiste einen Klotz über dem Text. */
.nl-mark-btn {
    display: grid; place-items: center;
    width: 1.9rem; height: 1.9rem;
    border: 0; border-radius: 4px;
    background: transparent; color: var(--ink);
    cursor: pointer;
}
.nl-mark-btn:hover { background: var(--hover); }
.nl-mark-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.nl-mark-btn .icon { width: 1rem; height: 1rem; }
/* GEDRÜCKT = „die Markierung ist schon so ausgezeichnet". Ohne diesen Zustand
   wäre die Leiste ein Auslöser statt eines Umschalters, und man wüsste nie, ob
   ein Klick fett MACHT oder fett WEGNIMMT. */
.nl-mark-btn.is-an { background: var(--accent-soft); color: var(--accent-ink); }

/* Der Link-Dialog LÖST DIE WERKZEUGE AB, statt neben ihnen aufzugehen: die
   Leiste schwebt frei über dem Text und hat keinen Platz für ein zweites
   Fenster. Muster wie beim Link-Dialog des Trix-Editors – ein Editor, ein
   Modell. */
.nl-mark-link { display: flex; align-items: center; gap: .25rem; padding: .1rem; }
.nl-mark-link[hidden] { display: none; }
/* (0,2,0) – schlägt die gemeinsame Steuerelement-Regel `input[type=url]`?
   Nein: die Basisregel adressiert `input[type=url]` gar nicht (nur text/email/
   search/date/password/number/tel). Das Feld ist hier deshalb komplett selbst
   beschrieben. Wer `url` je in die Basisregel aufnimmt, muss hier prüfen. */
.nl-mark-link .nl-mark-url {
    width: 14rem; height: 1.9rem;
    padding: 0 .4rem;
    border: 1px solid var(--line-strong); border-radius: 4px;
    background: var(--card); color: var(--ink);
    font: inherit; font-size: .8rem;
}
.nl-mark-link .nl-mark-url:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nl-mark-txt {
    height: 1.9rem; padding: 0 .5rem;
    border: 1px solid var(--line-strong); border-radius: 4px;
    background: transparent; color: var(--ink);
    font: inherit; font-size: .75rem; font-weight: 500;
    cursor: pointer; white-space: nowrap;
}
.nl-mark-txt:hover { background: var(--hover); }
.nl-mark-txt:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ============================================================================
   DAS EDITOR-FENSTER (DESIGN §8 – .detail-modal, kein neuer Typ)
   ============================================================================
   Nur die Abweichungen vom .detail-modal: ein Fuß mit Statuszeile + „Fertig".
   Die Breite (44rem) ist Absicht und keine Willkür – die Mail-Hülle ist 640 px
   (40rem) breit, der Editor zeigt den Text also ungefähr so breit, wie er beim
   Empfänger ankommt. */
/* ⚠ `flex-wrap: wrap` aus demselben Grund wie am `.detail-modal-foot`
   (Handoff 0231): auch das ist ein Fenster-Fuss mit einem `.btn` darin. Hier
   ist der Fall harmloser (eine Statuszeile + ein Knopf), aber die Hausform gilt
   fuer JEDEN Fenster-Fuss – sonst waere sie keine. */
.nl-editor-fuss {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem;
    padding: .85rem 1.35rem;
    border-top: 1px solid var(--line);
}

/* Im Fenster hat die Werkzeugleiste endlich die Breite, die sie braucht.
   Trotzdem umbrechen lassen: auf einem schmalen Schirm ist das Fenster
   schmaler als 44rem, und eine Leiste, die nicht umbricht, wäre wieder das
   alte Problem – nur an einem anderen Ort. */
.nl-editor-modal trix-toolbar .trix-button-row { flex-wrap: wrap; }
.nl-editor-modal trix-editor {
    min-height: 14rem;
    background: var(--card); color: var(--ink);
}

/* --- Termin-Baustein: INLINE-EDITOR in der Karte (Handoff 0034) -------------
   Die Karte IST das Eingabefeld (Nutzerwunsch: „direkt in der Vorschau
   schreiben"). Oben ein anklickbares Datum (öffnet den nativen Kalender) mit
   kompaktem Aufklapp für Uhrzeit/Enddatum/ganztägig; darunter die gerenderte
   Karte, deren Textstellen contenteditable sind. Das abgesetzte Formular aus
   Etappe 1/2 ist entfallen. */
.nl-editor-feld input[type=date],
.nl-editor-feld input[type=time] {
    height: 2rem; font-size: .8rem;
    background: var(--card); color: var(--ink); text-align: left;
}
/* von/bis (Uhrzeit) nebeneinander, auf schmalem Panel umbrechend. */
.nl-termin-edit-row { display: flex; flex-wrap: wrap; gap: .6rem; align-items: flex-end; }
.nl-termin-edit-row .nl-editor-feld { flex: 1 1 8rem; margin-top: .6rem; }
.nl-termin-ganztags {
    display: inline-flex; align-items: center; gap: .4rem;
    font-size: .8rem; color: var(--ink); margin-top: .6rem; white-space: nowrap;
}
.nl-termin-ganztags input[type=checkbox] {
    width: auto; height: auto; min-height: 0; margin: 0; background: none;
}
.nl-termin-hint { color: var(--muted); font-size: .72rem; line-height: 1.4; margin: .8rem 0 0; }

.nl-termin-edit2 { display: flex; flex-direction: column; gap: .1rem; }

/* Die Datum-Zeile über der Karte: Chip + Aufklapp. */
.nl-termin-datumzeile {
    display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-bottom: .7rem;
}

/* ANKLICKBARES DATUM: der Chip ist der sichtbare Auslöser, das native
   date-Element liegt unsichtbar darüber (damit der Kalender-Popup am Datum
   erscheint) und trägt den Wert (wire:model). `pointer-events:none`, damit der
   Chip die Klicks bekommt; geöffnet wird per `showPicker()`. */
.nl-termin-datumchip-wrap { position: relative; display: inline-flex; }
.nl-termin-datumchip {
    display: inline-flex; align-items: center; gap: .4rem; cursor: pointer;
    font: inherit; font-size: .82rem; font-weight: 600; color: var(--ink);
    background: var(--accent-soft); border: 1px solid var(--accent);
    border-radius: 999px; padding: .32rem .7rem;
}
.nl-termin-datumchip:hover { background: var(--accent); color: #fff; }
.nl-termin-datumchip:hover .icon { color: #fff; }
.nl-termin-datumchip .icon { width: 1rem; height: 1rem; color: var(--accent-ink); }
.nl-termin-datumchip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nl-termin-datum-nativ {
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: 0; pointer-events: none; border: 0; padding: 0; margin: 0; background: none;
}

/* Uhrzeit/Enddatum/ganztägig – schwebendes Popover „am Datum" (UI 0035, Muster
   aus Handoff 0028/0030). NICHT mehr als inline aufklappendes <details> (das
   schob den Karteninhalt nach unten – Nutzerwunsch: „wie beim Kalender als
   Overlay-Fenster"): der Zeit-Chip öffnet ein Fenster ÜBER der Karte, das nichts
   verschiebt. `position: fixed` (NICHT `absolute`), weil das umgebende `.nl-band`
   `overflow: hidden` trägt und ein absolutes Fenster abschnitte (DESIGN §13,
   dieselbe Falle wie beim ⋮-Popover). Die Fixierung platziert termininline.js
   (platziereZeitPop) am Chip und klemmt sie in den Viewport – auch auf schmalen
   Fenstern, ohne waagerechtes Seiten-Scrollen. */
.nl-termin-zeitpop-wrap { position: relative; display: inline-flex; }
.nl-termin-zeitchip {
    display: inline-flex; align-items: center; gap: .3rem; cursor: pointer;
    font: inherit; font-size: .78rem; color: var(--muted);
    background: none; border: 1px solid var(--line-strong);
    border-radius: 999px; padding: .3rem .6rem;
}
.nl-termin-zeitchip::before { content: "⏰"; font-size: .8rem; }
.nl-termin-zeitchip:hover { background: var(--hover); }
.nl-termin-zeitchip.is-active { color: var(--ink); border-color: var(--accent); }
.nl-termin-zeitchip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nl-termin-zeitpop-pop {
    position: fixed; top: 0; left: 0; z-index: 60;
    width: max-content; max-width: min(20rem, calc(100vw - 1.5rem));
    max-height: calc(100vh - 1.5rem); overflow-y: auto;
    padding: .6rem .7rem; text-align: left;
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    background: var(--card); box-shadow: var(--shadow);
}
.nl-termin-zeitpop-pop[hidden] { display: none; }

/* „Übernehmen"-Fuß im Uhrzeit-Popover (UI 0036): sichtbarer Bestätigungsweg –
   Enter UND dieser Knopf committen das fokussierte Feld (blur) und schließen. */
.nl-termin-zeitpop-fuss {
    display: flex; justify-content: flex-end;
    margin-top: .8rem; padding-top: .7rem; border-top: 1px solid var(--line);
}
.nl-termin-zeit-fertig { height: 2rem; min-height: 0; padding: 0 1rem; font-size: .8rem; }

/* --- EIGENER KALENDER-POPOVER am Termin-Datum (UI 0036) ---------------------
   Ersetzt den nativen, nicht stylebaren `<input type=date>`-Picker (Nutzer:
   „das Kalender soll dem Design des Ganzen anpassen"). Dasselbe Float-Muster wie
   das Uhrzeit-Popover: `position: fixed` (das `.nl-band` trägt `overflow:hidden`,
   ein absolutes Fenster würde abgeschnitten – DESIGN §13), von termininline.js
   (`terminKalender.platziere`) am Auslöser verankert und in den Viewport geklemmt.
   Monatsnavigation clientseitig (Alpine); erst der Tag-Klick schreibt ins
   Livewire-Feld. */
.nl-termin-kal-wrap { position: relative; display: inline-flex; }
/* Auslöser des Enddatum-Kalenders im Uhrzeit-Popover: schlichter Feld-Look
   (wie ein Steuerelement), nicht der kräftige Akzent-Chip des Startdatums. */
.nl-termin-endchip {
    display: inline-flex; align-items: center; gap: .4rem; cursor: pointer;
    font: inherit; font-size: .82rem; color: var(--ink); text-align: left;
    background: var(--card); border: 1px solid var(--line-strong);
    border-radius: var(--radius); padding: .3rem .6rem; min-height: 2rem;
}
.nl-termin-endchip:hover { background: var(--hover); }
.nl-termin-endchip .icon { width: .95rem; height: .95rem; color: var(--muted); }
.nl-termin-endchip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Enddatum-Entfernen (UI 0036): sitzt als Flex-Kind im Kalender-Wrap neben dem
   Auslöser, per Alpine `x-show` nur sichtbar, wenn ein Datum gewählt ist. */
.nl-termin-endclear {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.9rem; height: 1.9rem; flex: none; cursor: pointer;
    background: var(--card); color: var(--muted);
    border: 1px solid var(--line-strong); border-radius: var(--radius);
}
.nl-termin-endclear:hover { background: var(--danger-bg); color: var(--danger); border-color: var(--danger); }
.nl-termin-endclear .icon { width: 1rem; height: 1rem; }
.nl-termin-endclear:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.nl-termin-kalpop {
    position: fixed; top: 0; left: 0; z-index: 65;
    width: 17rem; max-width: calc(100vw - 1.5rem);
    padding: .7rem; text-align: left;
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    background: var(--card); color: var(--ink); box-shadow: var(--shadow);
}
.nl-kal-kopf {
    display: flex; align-items: center; justify-content: space-between;
    gap: .4rem; margin-bottom: .5rem;
}
.nl-kal-titel { font-size: .85rem; font-weight: 600; color: var(--ink); }
.nl-kal-nav {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.9rem; height: 1.9rem; flex: none; cursor: pointer;
    background: var(--card); color: var(--ink);
    border: 1px solid var(--line-strong); border-radius: var(--radius);
}
.nl-kal-nav:hover { background: var(--hover); }
.nl-kal-nav:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nl-kal-nav .icon { width: 1rem; height: 1rem; }
.nl-kal-woche, .nl-kal-raster {
    display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px;
}
.nl-kal-woche { margin-bottom: .25rem; }
.nl-kal-woche span {
    text-align: center; font-size: .68rem; font-weight: 600;
    color: var(--muted); padding: .15rem 0;
}
.nl-kal-tag {
    display: inline-flex; align-items: center; justify-content: center;
    aspect-ratio: 1 / 1; min-height: 2rem; cursor: pointer;
    background: none; color: var(--ink); font: inherit; font-size: .8rem;
    border: 1px solid transparent; border-radius: var(--radius);
}
.nl-kal-tag:hover { background: var(--hover); }
.nl-kal-tag:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nl-kal-tag.is-leer { visibility: hidden; pointer-events: none; }
.nl-kal-tag.is-heute { border-color: var(--line-strong); font-weight: 600; }
.nl-kal-tag.is-gewaehlt,
.nl-kal-tag.is-gewaehlt:hover {
    background: var(--accent); color: var(--on-accent);
    border-color: var(--accent); font-weight: 600;
}

/* Die editierbare Karte selbst rendert über die Band-Tabellen-Regeln
   (`.nl-band table`); der Wrapper hebt sie nur leicht ab. */
.nl-termin-karte-edit { padding-top: .2rem; }

/* EIN INLINE-TEXTFELD der Karte (contenteditable). Erbt Größe/Farbe/Abstand aus
   dem übergebenen Inline-Style; hier nur der Bearbeitbarkeits-Hinweis (dezenter
   Rahmen bei Hover/Fokus) und der Platzhalter (`.is-leer::before` – `:empty`
   reicht nicht, der Browser lässt beim Leeren ein <br> stehen). */
.nl-termin-inline-feld { display: block; }
.nl-termin-inline {
    outline: 1px dashed transparent; outline-offset: 2px; border-radius: 3px;
    cursor: text; min-width: 2rem;
}
.nl-termin-inline:hover { outline-color: var(--line-strong); }
.nl-termin-inline:focus, .nl-termin-inline:focus-visible {
    outline: 2px solid var(--accent); outline-offset: 2px;
}
.nl-termin-inline.is-leer::before {
    content: attr(data-platzhalter); color: var(--muted); font-style: italic; opacity: .8;
}

/* --- Sichtbarkeits-Schalter: CHECKBOX-LISTE „Anzeigen" (ADR-0014 Thema 2b;
   Handoff 0034) ------------------------------------------------------------
   Zuvor Antipp-Chips – der An/Aus-Zustand war „nicht gleich ersichtlich"
   (Nutzer). Jetzt echte Checkboxen: Häkchen gesetzt = wird angezeigt. Nutzt das
   `.check-label`-Steuerelement des Kanzlei-Designs, kompakt untereinander. */
.nl-zeig-liste { display: flex; flex-direction: column; gap: .35rem; margin-top: .1rem; }
.nl-zeig-item { font-weight: 500; font-size: .8rem; color: var(--ink); }

.nl-termin-stilhinweis { color: var(--warn-ink, var(--muted)); margin-top: .4rem; }

/* --- Optionen-Panel ------------------------------------------------------- */
.nl-options .form-field { margin-bottom: .7rem; }
.nl-options label { display: block; font-size: .75rem; font-weight: 600; color: var(--muted); margin-bottom: .2rem; }
.nl-options select { font-size: .8rem; }

/* --- Kuratierte Optionen: Farbkacheln + Segment-Schalter (ETAPPE 4) --------
   Ersetzt die früheren <select>-Felder. Das verbindliche Muster ist dasselbe wie
   bei den Vorlagen-Karten (Etappe 3): Die Kachel IST das <label> eines per
   .sr-only versteckten ECHTEN Radios. Tastatur (Pfeiltasten innerhalb der
   Gruppe), Screenreader-Ansage und Klickfläche kommen damit vom Browser statt
   aus eigenem JS; `:focus-within` macht den Fokus sichtbar, obwohl der Radio
   unsichtbar ist.

   ACHTUNG SPEZIFITÄT (zum sechsten Mal dieselbe Lektion aus 0019/0020/0021):
   `.nl-options label` ist (0,1,1) und schlägt eine reine Klasse wie `.nl-kachel`
   (0,1,0) – die Kacheln behielten sonst `display: block` und stapelten sich
   senkrecht. Deshalb stehen sie hier als `.nl-options label.nl-kachel` (0,2,1). */
.nl-opt { margin: 0 0 .6rem; min-width: 0; }
.nl-opt-titel {
    display: flex; align-items: center; gap: .35rem;
    font-size: .75rem; font-weight: 600; color: var(--muted); margin: 0 0 .25rem;
}

/* „Eigen" – ein freier Wert überschreibt die kuratierte Auswahl. Die Pille ist
   der einzige Hinweis darauf, WARUM oben keine Kachel markiert ist. */
.nl-opt-frei {
    font-size: .62rem; font-weight: 700; letter-spacing: .02em; text-transform: uppercase;
    background: var(--accent-soft); color: var(--accent-ink);
    border-radius: 999px; padding: .1rem .35rem; line-height: 1.4;
}

/* Die Kachel-Reihe zeigt die TENANT-EIGENE Palette (ADR-0013), deren Zahl 4–7
   variiert – deshalb `auto-fill` statt fester vier Spalten. Jede Kachel-Fläche
   trägt ihren Hex INLINE (sie zeigt DATEN, nicht Design – dieselbe begründete
   Ausnahme wie .farb-vorschau); harte Farben stehen deshalb NICHT hier, DESIGN §2
   bleibt gewahrt. */
/* `minmax(2.75rem, …)`: in der breiteren Spalte (0027) passen die vier
   Standard-Flächen PLUS die „Eigene"-Kachel in EINE Reihe. Eine größere
   Tenant-Palette bricht sauber in die zweite Reihe (auto-fill). */
/* Basis-Grid nicht mehr genutzt (die Kacheln liegen jetzt in .nl-flaeche-wahl als
   flex-Reihe, 0027) – als harmloser Rückfall belassen. */
.nl-kacheln { display: grid; grid-template-columns: repeat(auto-fill, minmax(2.75rem, 1fr)); gap: .3rem; }
/* Die „Eigene"-Kachel ist ein <button> (öffnet die Farbwahl), kein <label>
   eines Radios – deshalb steht sie mit im Selektor und bekommt die
   Button-Resets (0027). Spezifität wie gehabt (0,2,1), damit `.nl-options label`
   die Flex-Spalte nicht zurückdrückt (Lektion aus 0019–0021).
   KEIN `width: 100%` mehr: in der waagerechten Leiste (0027) legt
   `.nl-flaeche-wahl .nl-kachel { width: 2.9rem }` die kompakte Kachelbreite fest;
   ein `width: 100%` (0,2,1) hätte das überstimmt und die Kacheln in je eine volle
   Zeile gestapelt. */
.nl-options label.nl-kachel,
.nl-options button.nl-kachel {
    display: flex; flex-direction: column; align-items: center; gap: .25rem;
    margin: 0; padding: .3rem .1rem; cursor: pointer;
    border: 1px solid transparent; border-radius: var(--radius);
    background: transparent; font: inherit; text-align: center;
}
.nl-options label.nl-kachel:hover,
.nl-options button.nl-kachel:hover { border-color: var(--line-strong); background: var(--hover); }
.nl-kachel:focus-within,
.nl-options button.nl-kachel:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nl-options label.nl-kachel.active,
.nl-options button.nl-kachel.active { border-color: var(--accent); background: var(--accent-soft); }
.nl-kachel-flaeche {
    display: block; width: 100%; height: 1.4rem;
    border: 1px solid var(--line-strong); border-radius: 4px;
}
.nl-kachel-name { font-size: .66rem; font-weight: 500; color: var(--muted); line-height: 1.2; }
.nl-kachel.active .nl-kachel-name { color: var(--accent-ink); font-weight: 600; }

/* Die „Eigene"-Kachel: solange keine eigene Farbe gesetzt ist, zeigt die Fläche
   ein „+" auf gestricheltem Grund (eine Einladung, keine Farbe). Sobald ein
   Literal gilt, trägt sie – wie jede Palette-Kachel – ihren Hex als Inline-Style
   (DATEN, keine harte Farbe im CSS; dieselbe begründete Ausnahme wie .nl-kachel-
   flaeche). */
.nl-kachel-eigen-flaeche {
    display: flex; align-items: center; justify-content: center;
    border-style: dashed; color: var(--muted);
}
.nl-kachel-eigen.active .nl-kachel-eigen-flaeche { border-style: solid; color: transparent; }
.nl-kachel-eigen-flaeche .icon { width: .9rem; height: .9rem; }

/* DIE INLINE-FARBWAHL unter den Kacheln (0027): früher eine getrennte
   „Erweitert"-Sektion, jetzt direkt an der Kachel-Reihe. Ein schmaler Abstand
   trennt sie von den Kacheln; die Feld-Regeln (.farb-feld/.farb-hex/
   .nl-kachel-speichern) sind unverändert. */
.nl-eigene-farbe { margin-top: .5rem; }
.nl-eigene-farbe .nl-kachel-speichern { margin-top: .4rem; }

.nl-segment {
    display: flex; border: 1px solid var(--line-strong);
    border-radius: var(--radius); overflow: hidden;
}
.nl-options label.nl-segment-teil {
    flex: 1 1 0; min-width: 0; margin: 0;
    display: flex; align-items: center; justify-content: center;
    padding: .38rem .2rem; font-size: .72rem; font-weight: 500; text-align: center;
    color: var(--muted); background: var(--card);
    border-right: 1px solid var(--line-strong); cursor: pointer;
}
.nl-options label.nl-segment-teil:last-child { border-right: 0; }
.nl-options label.nl-segment-teil:hover { background: var(--hover); }
.nl-segment-teil:focus-within { outline: 2px solid var(--accent); outline-offset: -2px; }
/* AKTIV = GEFÜLLTES Segment (Handoff 0034, Fix): der zuvor verwendete
   accent-soft-Ton war zu leise – man sah nicht auf einen Blick, welcher Wert
   (z. B. welche Termin-Darstellung) gewählt ist. Jetzt volle Akzentfläche mit
   `--on-accent` (in beiden Themes lesbar). */
.nl-options label.nl-segment-teil.active {
    background: var(--accent); color: var(--on-accent); font-weight: 600;
}
/* In der Leiste flacher gesetzt (0028): (0,3,0) schlägt die Basis (0,2,1). */
.nl-bar .nl-segment .nl-segment-teil { padding: .28rem .45rem; }

/* --- Kontrast-Hinweis (ETAPPE 4, ADR-0011 §5) -----------------------------
   HINWEIS, KEIN FEHLER: --warn-* und NICHT --danger. Ein roter Kasten hieße
   „das darfst du nicht" – hier gilt „das solltest du wissen". Der Nutzer
   entscheidet, nichts blockiert. */
.nl-warn {
    display: flex; gap: .5rem; align-items: flex-start;
    background: var(--warn-bg); color: var(--warn-ink);
    border-radius: var(--radius); padding: .5rem .6rem; margin: 0 0 .8rem;
}
.nl-warn .icon { width: 1rem; height: 1rem; flex: 0 0 auto; margin-top: .1rem; }
.nl-warn p { margin: 0; font-size: .75rem; line-height: 1.4; }
.nl-warn-btn {
    background: none; border: 0; padding: 0; margin-top: .25rem;
    font: inherit; font-size: .75rem; font-weight: 600; color: var(--warn-ink);
    text-decoration: underline; cursor: pointer;
}
.nl-warn-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Dieselbe Pille über volle Panel-Breite (Gmail-Hinweis vor den Versand-Knöpfen,
   ADR-0011 §4d). Der Hinweis steht dort, wo die Entscheidung fällt – am
   „Versenden", nicht an einem Baustein. */
.nl-warn-breit { padding: .7rem .8rem; margin-bottom: 1rem; }
.nl-warn-breit p { font-size: .82rem; }
.nl-warn-breit .field-hint { margin-top: .25rem; color: inherit; opacity: .8; }

/* --- „Erweitert" – freie Werte je Baustein (ETAPPE 4) ---------------------
   ZUGEKLAPPT IST DIE VOREINSTELLUNG: Wer nichts aufklappt, sieht nur kuratierte
   Werte und kann nichts kaputt machen (ADR-0011 „Verworfene Alternativen (D)").

   Bewusst KEIN <details>: dessen `open` gehört dem Browser und würde von
   Livewires Morphing bei jedem Roundtrip zurückgesetzt. Der Zustand liegt auf
   dem Server; hier steht ein echter <button> mit aria-expanded. */
.nl-erweitert { border-top: 1px solid var(--line); margin-top: .9rem; padding-top: .6rem; }
.nl-erweitert-kopf {
    display: flex; align-items: center; gap: .35rem; width: 100%;
    background: none; border: 0; padding: .15rem 0; cursor: pointer;
    font: inherit; font-size: .75rem; font-weight: 600; color: var(--ink);
}
.nl-erweitert-kopf:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.nl-erweitert-pfeil { width: .85rem; height: .85rem; color: var(--muted); transition: transform .12s ease; }
.nl-erweitert-kopf[aria-expanded="true"] .nl-erweitert-pfeil { transform: rotate(180deg); }
.nl-erweitert-inhalt { padding-top: .5rem; }
/* Ohne diese Regel gewönne ein eigenes `display` gegen das UA-`[hidden]`. */
.nl-erweitert-inhalt[hidden] { display: none; }
.nl-options input.nl-frei-zahl { width: 6rem; font-size: .8rem; }
.nl-reset { width: 100%; margin-top: .3rem; font-size: .75rem; }

/* FUNKTIONAL, NICHT KOSMETIK – im Browser gemessen, kein Test zeigt es:
   Ein `<input>` hat eine intrinsische Mindestbreite (rund 20 Zeichen ≈ 205px).
   Als Flex-Kind gilt zusätzlich `min-width: auto`, was genau diese min-content-
   Breite als HARTE Untergrenze setzt – das Feld schrumpft dann NICHT, obwohl
   `flex: 1 1 auto` es dürfte. In „Einstellungen → Verein" fällt das nie auf
   (das Formularraster gibt ~500px her); im 190px schmalen Gestaltungs-Panel
   stand das Hex-Feld 83px ausserhalb der Karte und war abgeschnitten
   (gemessen: farb-hex right=1332 gegen panelRight=1249).
   Dieselbe Klasse Fehler wie die Trix-Werkzeugleiste in der Zwei-Spalten-Zelle
   (Handoff 0021).

   Spezifität (0,3,1) ist Pflicht: `input.farb-hex` (0,2,1) steht in dieser Datei
   WEITER UNTEN und gewönne sonst den Gleichstand. */
.nl-options .farb-feld { min-width: 0; }
.nl-options .farb-feld input.farb-hex { min-width: 0; font-size: .8rem; }

/* DIE BRÜCKE IN DIE VEREINSPALETTE (ADR-0013 §4): „als Kachel speichern" unter
   dem eigenen Farbfeld. Dezent (Textknopf mit Icon), weil es eine Zusatz-Option
   zum Literal ist, kein Primärweg – der Default bleibt „nur hier verwenden". */
.nl-kachel-speichern {
    display: inline-flex; align-items: center; gap: .3rem;
    margin-top: .45rem; padding: .2rem .1rem;
    background: none; border: 0; cursor: pointer;
    font: inherit; font-size: .78rem; color: var(--accent);
}
.nl-kachel-speichern:hover { text-decoration: underline; }
.nl-kachel-speichern:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius); }
.nl-kachel-speichern .icon { width: .9rem; height: .9rem; }

/* =============================================================================
   ERSCHEINUNGSBILD – Vereinsfarbe + Logo (Einstellungen -> Verein, ADR-0011 §4)
   =============================================================================
   Die Vereinsfarbe ist EINE Entscheidung je Verein und speist Hülle + Fläche
   „Akzent". Seit ETAPPE 4 ist sie nicht mehr die einzige freie Farbwahl: unter
   „Erweitert" kann jeder Baustein eigene Werte bekommen. Der SICHTBARE Default
   bleibt überall kuratiert.

   WER WAS BENUTZT (seit der Palette – bitte nicht durcheinanderbringen):
     - `.farb-palette`/`.farb-kachel*` – NUR „Einstellungen → Verein": die
       kuratierten Vereinsfarben.
     - `.farb-feld`/`.farb-wahl` – NUR der Baukasten („Erweitert" → eigene
       Farbe eines Bausteins). Dort ist `input[type=color]` weiterhin richtig:
       gefragt ist eine BELIEBIGE Farbe, es gibt keine kuratierte Liste dafür.
     - `input.farb-hex` – BEIDE. Das Hex-Feld ist das gemeinsame Muster.

   WARUM DIE VEREINSFARBE KEINEN `input[type=color]` MEHR HAT: Er ist – wie
   `<select>` und `input[type=file]` – NICHT stylebar (DESIGN §4), sieht in jedem
   Betriebssystem anders aus und wirkte im Kanzlei-System als Fremdkörper. Vor
   allem stellt er die falsche Frage: „wähle aus 16,7 Millionen" hilft einem
   Laien nicht, „welche kommt deinem Wappen am nächsten?" schon. Die Palette
   beantwortet die richtige. `.farb-wahl` bleibt für den Baukasten erhalten –
   dort ist die Frage wirklich „irgendeine Farbe".

   `input[type=color]` ist nicht stylebar: der Browser rendert sein eigenes
   Widget. Deshalb wird es nur auf Steuerelement-Höhe und -Breite gebracht und
   als Farbfleck neben das Hex-Feld gestellt; die eigentliche Eingabe ist das
   Textfeld daneben. */
.farb-feld { display: flex; align-items: center; gap: .5rem; }

/* --- Die kuratierten Vereinsfarben (Kacheln) ------------------------------
   Dasselbe verbindliche Muster wie die Farbkacheln am Baustein und die
   Vorlagen-Karten: Die Kachel IST das <label> eines per .sr-only versteckten
   ECHTEN Radios – Tastatur, Pfeiltasten-Gruppe und Screenreader-Ansage kommen
   vom Browser statt aus eigenem JS; `:focus-within` macht den Fokus sichtbar,
   obwohl der Radio unsichtbar ist.

   `auto-fill` + `minmax`: die Palette darf wachsen, ohne dass hier jemand eine
   Spaltenzahl nachzieht. */
.farb-palette {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));
    gap: .4rem;
    margin-bottom: .8rem;
}
/* (0,2,1): `.form-field label` bzw. die gemeinsame Label-Regel schlagen eine
   reine Klasse – dieselbe Spezifitäts-Lektion wie bei `.nl-options label
   .nl-kachel`. Ohne das Element im Selektor stapeln sich die Kacheln senkrecht. */
.form-field label.farb-kachel {
    display: flex; flex-direction: column; align-items: center; gap: .25rem;
    margin: 0; padding: .3rem .15rem; cursor: pointer;
    border: 1px solid transparent; border-radius: var(--radius);
    font-size: .7rem; font-weight: 600; color: var(--muted);
}
.form-field label.farb-kachel:hover { border-color: var(--line-strong); background: var(--hover); }
.farb-kachel:focus-within { outline: 2px solid var(--accent); outline-offset: 1px; }
.form-field label.farb-kachel.active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-ink); }
.farb-kachel-flaeche {
    display: block; width: 100%; height: 1.6rem;
    border: 1px solid var(--line-strong); border-radius: 4px;
}
.farb-kachel-name { line-height: 1.2; text-align: center; }

/* --- DIE WEGWEISER-FARBEN DER VERWALTUNG (ADR-0043 Etappe 2/3, Handoff 0232)
   -----------------------------------------------------------------------------
   Derselbe Ort wie Vereinsfarbe, Logo und Flaechen-Palette – „Einstellungen ->
   Erscheinungsbild", KEIN zweiter Ort fuer Gestaltung (ADR-0008 §7, ADR-0043
   §1.2). Und dasselbe Muster wie ueberall im Haus: kuratiert SICHTBAR (vier
   fertige Saetze als Kacheln), frei ERREICHBAR (vier Hex-Felder hinter
   „Erweitert", zugeklappt).

   ⚠ EINE KACHEL ZEIGT ALLE VIER FARBEN NEBENEINANDER, nicht eine. Der Verein
   waehlt EINE Sache, nicht vier – deshalb ist der Streifen die Kachelflaeche.

   ⚠ KEIN `var(--bereich-*)` IN DIESEM ABSCHNITT. Die Faecher zeigen DATEN (die
   Farbe, um die es gerade geht), nicht die geltende Bereichsfarbe – sie stehen
   deshalb als Inline-Style am Element, dieselbe begruendete Ausnahme wie
   `.farb-kachel-flaeche` und `.flaeche-swatch` darueber. Wuerden sie das Token
   lesen, zeigte jede Kachel dasselbe. */
.wegweiser-block { margin-top: .9rem; }
.wegweiser-lead { margin-top: 0; margin-bottom: .8rem; }
/* Die vier Farben eines Satzes als durchgehender Streifen. */
.satz-streifen {
    display: flex; width: 100%; height: 1.6rem;
    border: 1px solid var(--line-strong); border-radius: 4px;
    overflow: hidden;
}
.satz-farbe { flex: 1 1 0; }
/* Eine Zeile je Bereich hinter „Erweitert": Fleck · Hex-Feld · Bereichsname. */
.wegweiser-zeile { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-bottom: .5rem; }
.wegweiser-name { font-size: .85rem; font-weight: 500; color: var(--ink); flex: 1 1 8rem; min-width: 0; }
.wegweiser-zeile input.farb-hex { flex: 0 0 7rem; width: 7rem; min-width: 0; }
.wegweiser-fehler { flex-basis: 100%; }

/* --- Die tenant-eigene HINTERGRUND-PALETTE (ADR-0013) ----------------------
   Eine Zeile je Fläche: Farbe (Fleck + Hex-Feld) · Name · Kontrast-Pille ·
   Löschen. „Weiß" und die reservierte „Vereinsfarbe" sind feste Zeilen (Anzeige
   statt Eingabe). Eigener Block mit Trennlinie wie `.logo-block`. */
.palette-block { margin-top: 1.25rem; border-top: 1px solid var(--line); padding-top: 1.25rem; }
.palette-block > label { display: block; font-size: .8rem; font-weight: 600; margin-bottom: .35rem; }
.palette-lead { margin-top: 0; margin-bottom: .8rem; }
.palette-liste { display: flex; flex-direction: column; gap: .5rem; margin-bottom: .9rem; }
.flaeche-slot { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
/* Farbfleck als VORSCHAU (kein Steuerelement) + Hex-Feld – kein input[type=color]
   in den Einstellungen (DESIGN §4). */
.flaeche-swatch { flex: 0 0 auto; width: 2.375rem; height: 2.375rem; }
.flaeche-slot input.farb-hex.flaeche-hex { flex: 0 0 7rem; width: 7rem; min-width: 0; }
.flaeche-name { flex: 1 1 8rem; min-width: 0; }
/* Feste Zeilen (Weiß / Vereinsfarbe): nur Anzeige. */
.flaeche-fest { flex: 0 0 auto; width: 2.375rem; height: 2.375rem; }
.flaeche-name-fest { font-size: .85rem; font-weight: 500; color: var(--ink); }
.flaeche-hinweis { margin: 0; }
.flaeche-loeschen { flex: 0 0 auto; margin-left: auto; }
.flaeche-fehler { flex-basis: 100%; }
/* Kontrast-Pille je Slot – amber wie die Warnung an der Vereinsfarbe. */
.flaeche-warn {
    display: inline-flex; align-items: center; gap: .25rem;
    background: var(--warn-bg); color: var(--warn-ink);
    border-radius: 999px; padding: .15rem .5rem;
    font-size: .72rem; font-weight: 600; white-space: nowrap;
}
.flaeche-warn .icon { width: .85rem; height: .85rem; }

/* „Eigene Farbe" – das Hex-Feld unter den Kacheln. Kein `.form-row`: es ist
   eine Alternative zur Palette, keine zweite Frage. */
.farb-eigen { margin-bottom: 0; }
.farb-eigen label { display: flex; align-items: center; gap: .35rem; }

.farb-wahl {
    flex: 0 0 auto;
    width: 2.75rem; height: var(--h-control);
    padding: 2px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    background: var(--card);
    cursor: pointer;
}
.farb-wahl:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ELEMENT-SPEZIFITÄT (0,2,1) IST PFLICHT, keine Angeberei – zum vierten Mal
   dieselbe Lektion (Handoffs 0019/0020): die gemeinsame Steuerelement-Regel
   adressiert `input[type=text]` (0,1,1) und schlägt eine reine Klasse (0,1,0).
   Mit nur `.farb-hex` behielte das Feld `width:100%` und schöbe den Farbfleck
   aus der Zeile. */
input.farb-hex { flex: 1 1 auto; width: auto; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

.farb-vorschau {
    display: flex; align-items: center; justify-content: center;
    height: var(--h-control);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    font-size: .85rem; font-weight: 600;
}

/* --- Sidebar-Stil-Wähler (Feature 0079/0081) --------------------------------
   Vier wählbare Kacheln für die Gestaltung der öffentlichen Sidebar. Jede Kachel
   IST das <label> eines per .sr-only versteckten ECHTEN Radios (wie .farb-kachel):
   Tastatur/Pfeiltasten-Gruppe/Screenreader kommen vom Browser. Links eine
   schematische Mini-Vorschau des Kachel-Prinzips, rechts Titel + Beschreibung. */
.stil-wahl {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: .6rem;
    margin: .4rem 0 1rem;
}
.form-field label.stil-kachel,
label.stil-kachel {
    display: flex; align-items: center; gap: .8rem;
    margin: 0; padding: .7rem .8rem; cursor: pointer;
    border: 1px solid var(--line-strong); border-radius: var(--radius);
    background: var(--card);
}
label.stil-kachel:hover { border-color: var(--accent); background: var(--hover); }
.stil-kachel:focus-within { outline: 2px solid var(--accent); outline-offset: 1px; }
label.stil-kachel.active { border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent); }
.stil-kachel-text { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.stil-kachel-titel { font-size: .9rem; font-weight: 700; color: var(--ink); }
.stil-kachel-beschreibung { font-size: .76rem; line-height: 1.35; color: var(--muted); }

/* Mini-Vorschau: zwei „Widget"-Blöcke, je Variante anders gerahmt. --accent
   steht hier stellvertretend für die Vereinsfarbe (schematisch). */
.stil-vorschau {
    flex: 0 0 auto;
    display: flex; flex-direction: column; gap: .3rem;
    width: 3.4rem; padding: .35rem;
    border-radius: 5px; background: var(--hover);
}
.stil-vorschau-widget {
    display: flex; flex-direction: column; gap: .18rem;
    padding: .3rem .35rem;
    border-radius: 3px;
    background: #fff; border-left: 3px solid var(--accent);
}
.stil-vorschau-titel { height: 4px; width: 70%; border-radius: 2px; background: var(--accent); }
.stil-vorschau-zeile { height: 3px; width: 100%; border-radius: 2px; background: var(--line-strong); }
.stil-vorschau-zeile.kurz { width: 60%; }
/* Schlicht: kein Kasten-Grund, nur eine untere Trennlinie. */
.stil-schlicht .stil-vorschau-widget {
    background: transparent; border-left: 0;
    border-bottom: 1px solid var(--line-strong);
    border-radius: 0; padding: .3rem 0;
}
.stil-schlicht .stil-vorschau-widget:last-child { border-bottom: 0; }
/* Gefüllt (0081): jeder Kasten VOLL in der Vereinsfarbe, helle Linien darauf –
   zeigt schematisch den hohen Kontrast (kein linker Balken, weil die ganze
   Fläche das Signal ist). */
.stil-gefuellt .stil-vorschau-widget {
    background: var(--accent); border-left: 0;
}
.stil-gefuellt .stil-vorschau-titel,
.stil-gefuellt .stil-vorschau-zeile { background: rgba(255, 255, 255, .85); }
/* Umrandet (0081): transparenter Grund, nur ein Rahmen in der Vereinsfarbe. */
.stil-umrandet .stil-vorschau-widget {
    background: transparent; border: 1.5px solid var(--accent);
    border-left: 1.5px solid var(--accent);
}

.logo-block { margin-top: 1.25rem; border-top: 1px solid var(--line); padding-top: 1.25rem; }
.logo-block > label { display: block; font-size: .8rem; font-weight: 600; margin-bottom: .35rem; }

.logo-aktuell { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }

/* Karierter Hintergrund: ein Logo ist meist ein transparentes PNG – auf weiß
   sähe man nicht, wo es aufhört. */
.logo-vorschau {
    max-height: 3.5rem; max-width: 14rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: .35rem;
    background-color: var(--card);
    background-image:
        linear-gradient(45deg, var(--hover) 25%, transparent 25%, transparent 75%, var(--hover) 75%),
        linear-gradient(45deg, var(--hover) 25%, transparent 25%, transparent 75%, var(--hover) 75%);
    background-size: 12px 12px;
    background-position: 0 0, 6px 6px;
}

/* =============================================================================
   STARTVORLAGEN – Auswahlkarten mit Mini-Skizze (newsletter.create, ADR-0011 §8)
   =============================================================================
   Die Karte IST das Label eines versteckten Radios (`.sr-only`): Tastatur,
   Screenreader und Klickfläche kommen damit vom Browser, nicht aus eigenem JS.
   `:has(:checked)` bräuchte es nicht – die aktive Karte kennt der Server, er
   setzt `.active`. */
.vorlagen-feld { border: 0; padding: 0; margin: 1.25rem 0 0; min-width: 0; }
.vorlagen-feld legend { padding: 0; font-size: .8rem; font-weight: 600; color: var(--ink); }
.vorlagen-lead { margin: .2rem 0 .75rem; }

.vorlagen { display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); gap: .75rem; }

.vorlage {
    display: block;
    background: var(--card);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    padding: .7rem;
    cursor: pointer;
}
.vorlage:hover { border-color: var(--accent); background: var(--accent-soft); }
/* Fokus sichtbar machen, obwohl der Radio unsichtbar ist – sonst ist die
   Tastaturbedienung blind. */
.vorlage:focus-within { outline: 2px solid var(--accent); outline-offset: 1px; }
.vorlage.active { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }

/* Mini-Skizze: zeigt den AUFBAU, nicht den Inhalt. */
.vorlage-mini {
    display: flex; flex-direction: column; gap: 4px;
    height: 4.2rem; padding: 6px; margin-bottom: .55rem;
    background: var(--hover); border-radius: 4px;
}
.vorlage-mini i { display: block; background: var(--line-strong); border-radius: 2px; }
.vorlage-mini i.mini-h { height: 6px; width: 60%; }
.vorlage-mini i.mini-t { height: 4px; }
.vorlage-mini i.mini-t-kurz { height: 4px; width: 40%; }
.vorlage-mini i.mini-img { flex: 1; min-height: 10px; }
.vorlage-mini i.mini-row { height: 13px; }
.vorlage-mini i.mini-btn { height: 8px; width: 38%; background: var(--accent); opacity: .55; }

.vorlage-name { display: block; font-size: .85rem; font-weight: 600; color: var(--ink); }
.vorlage-sub { display: block; font-size: .75rem; color: var(--muted); }

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* ==========================================================================
   SEITEN-EDITOR (ADR-0015 §4, ToDo 5) – Admin-Chrome des Baukastens für die
   öffentlichen Seiten. Die Leinwand rendert dieselben WEB-Partials wie die
   öffentliche Seite; ihre Optik trägt public.css und die INLINE-Primitive der
   Partials ($o['bg']/fg/…). Hier stehen (a) die Metadaten-Schalter und (b) eine
   auf die Leinwand GESCOPTE Kopie der wb-*-Layoutregeln (Grid/Flex/Bildbreite),
   damit die Bausteine auf der Leinwand so aussehen wie später öffentlich –
   OHNE public.css in den Admin zu ziehen (dessen Body-/Token-Reset würde mit
   dem Kanzlei-Chrome kollidieren). Farben kommen aus den Inline-Primitiven; die
   Vorschau unten ist die pixelgenaue Wahrheit.
   ========================================================================== */

/* --- Metadaten: Adresse (Slug) + Schalter --------------------------------- */
.slug-eingabe { display: flex; align-items: center; }
.slug-eingabe .slug-praefix { color: var(--muted); padding: 0 .15rem 0 .1rem; font-weight: 600; }
.slug-eingabe input { flex: 1 1 auto; }

.seiten-schalter {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin-top: .75rem;
}
.seiten-schalter .nl-saved { margin-left: auto; }

/* --- Leinwand: WEB-Bausteine (gescopte wb-* Layoutregeln) ----------------- */
.nl-band-web {
    --akzent: currentColor;
    --linie: #e2e4e7;
    --text-leise: var(--muted, #6f767b);
    --radius-klein: 6px;
}
.nl-band-web .wb { margin: 0; }
.nl-band-web .wb--flaeche { border-radius: var(--radius); }
.nl-band-web .wb-heading { margin: 0; line-height: 1.25; font-weight: 700; }
.nl-band-web .wb-rich > :first-child { margin-top: 0; }
.nl-band-web .wb-rich > :last-child { margin-bottom: 0; }
.nl-band-web .wb-rich p { margin: 0 0 1rem; }
.nl-band-web .wb-rich ul, .nl-band-web .wb-rich ol { margin: 0 0 1rem; padding-left: 1.4em; }
.nl-band-web .wb-rich li { margin: .25rem 0; }
.nl-band-web .wb-figure { margin: 0; }
.nl-band-web .wb-img { width: 100%; height: auto; display: block; border-radius: var(--radius-klein); }
.nl-band-web .wb-bildtext-grid { display: grid; grid-template-columns: 1fr; gap: 1.25rem; align-items: center; }
.nl-band-web .wb-bildtext-bild { margin: 0; }
@media (min-width: 40rem) {
    .nl-band-web .wb-bildtext-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr); }
    .nl-band-web .wb-bildtext--rechts .wb-bildtext-bild { order: 2; }
}
.nl-band-web .wb-spalten { display: grid; grid-template-columns: 1fr; gap: 1.5rem; }
@media (min-width: 40rem) {
    .nl-band-web .wb-spalten { grid-template-columns: 1fr 1fr; }
}
.nl-band-web .wb-galerie-grid { display: grid; grid-template-columns: repeat(var(--wb-spalten, 2), 1fr); gap: .75rem; }
.nl-band-web .wb-galerie-item { margin: 0; }
.nl-band-web .wb-zitat-box { margin: 0; padding: .25rem 0 .25rem 1.25rem; border-left: 4px solid; line-height: 1.5; font-style: italic; }
.nl-band-web .wb-zitat-quelle { display: block; margin-top: .75rem; font-size: .9rem; font-style: normal; color: var(--text-leise); }
.nl-band-web .wb-knopf-btn { display: inline-block; padding: .7rem 1.4rem; border-radius: 999px; font-weight: 600; line-height: 1.2; text-decoration: none; }
.nl-band-web .wb-knopf-btn--tot { opacity: .6; }
.nl-band-web .wb-hr { border: 0; border-top: 1px solid var(--linie); margin: 0; }

/* Termin-Web-Karte auf der Leinwand. */
.nl-band-web .wb-termin-karte { display: grid; grid-template-columns: auto 1fr; gap: 1.25rem; align-items: start; }
.nl-band-web .wb-termin-karte--freitext { grid-template-columns: 1fr; }
.nl-band-web .wb-termin-datum { display: flex; flex-direction: column; align-items: center; text-align: center; padding-right: 1.25rem; border-right: 1px solid var(--linie); min-width: 3.5rem; }
.nl-band-web .wb-termin-tag { font-size: 2.6rem; line-height: 1; font-weight: 700; }
.nl-band-web .wb-termin-monat { font-size: .85rem; font-weight: 700; letter-spacing: .08em; margin-top: .25rem; }
.nl-band-web .wb-termin-kw { font-size: .72rem; color: var(--text-leise); margin-top: .4rem; white-space: nowrap; }
.nl-band-web .wb-termin-body > * { margin: 0 0 .35rem; }
.nl-band-web .wb-termin-body > :last-child { margin-bottom: 0; }
.nl-band-web .wb-termin-wochentag { font-weight: 700; font-size: .95rem; }
.nl-band-web .wb-termin-zeit { color: var(--text-leise); font-size: .95rem; }
.nl-band-web .wb-termin-titel { font-size: 1.2rem; font-weight: 600; line-height: 1.3; }

/* Termin-Web-Karte: Ort/Herkunft/Zusatz + ICS-Link (fehlten auf der Leinwand). */
.nl-band-web .wb-termin-ort { color: var(--text-leise); }
.nl-band-web .wb-termin-ort::before { content: "\1F4CD\00a0"; }   /* Pin-Symbol */
.nl-band-web .wb-termin-herkunft { font-style: italic; color: var(--text-leise); font-size: .9rem; }
.nl-band-web .wb-termin-zusatz { color: var(--text-leise); font-size: .9rem; }
.nl-band-web .wb-termin-ics { margin-top: .6rem; font-size: .9rem; }
.nl-band-web .wb-termin-ics a { display: inline-flex; align-items: center; gap: .35rem; text-decoration: none; }
.nl-band-web .wb-termin-ics a:hover { text-decoration: underline; }
.nl-band-web .wb-termin-ics-icon { width: 1rem; height: 1rem; }

/* --- Leinwand: DYNAMISCHE Web-Bausteine (Newsletter-Karten-Optik, Feature 0060) --
   Spiegel der auf `.wb-veranstaltungen`/`.wb-bekanntmachungen` gescopten Regeln
   aus public.css (dort Zeilen ~709-810). MUSS mit jenen synchron bleiben: wer die
   oeffentliche Optik der Listen aendert, zieht diese Kopie nach. Trennlinien-FARBE
   kommt inline aus der Baustein-Option ($o['line']); hier nur Breite/Abstand. */

/* Veranstaltungen-Liste: je Eintrag durch eine feine Linie getrennt. */
.nl-band-web .veranstaltung-eintrag { padding: 0 0 1.5rem; margin: 0 0 1.5rem; border-bottom: 1px solid var(--linie); }
.nl-band-web .veranstaltung-eintrag:last-of-type { border-bottom: 0; margin-bottom: 0; }
/* Termin-Karte auf Newsletter-Mass (kleinere Datums-/Textgroessen, ohne Pin). */
.nl-band-web .wb-veranstaltungen .wb-termin-karte { gap: 1rem; }
.nl-band-web .wb-veranstaltungen .wb-termin-datum { border-right: 0; padding-right: 0; min-width: 3.25rem; }
.nl-band-web .wb-veranstaltungen .wb-termin-tag { font-size: 2.125rem; }
.nl-band-web .wb-veranstaltungen .wb-termin-monat { font-size: .75rem; }
.nl-band-web .wb-veranstaltungen .wb-termin-body > * { margin-bottom: .15rem; }
.nl-band-web .wb-veranstaltungen .wb-termin-wochentag { font-size: .8125rem; }
.nl-band-web .wb-veranstaltungen .wb-termin-zeit { font-size: .875rem; }
.nl-band-web .wb-veranstaltungen .wb-termin-titel { font-size: 1rem; }
.nl-band-web .wb-veranstaltungen .wb-termin-ort { font-size: .875rem; }
.nl-band-web .wb-veranstaltungen .wb-termin-ort::before { content: none; }

/* Bekanntmachungen-Liste: je Eintrag klar getrennt, Titelmass wie in der Mail. */
.nl-band-web .wb-bekanntmachungen .bekanntmachung-eintrag { padding: 0 0 1.5rem; margin: 0 0 1.5rem; border-bottom: 1px solid var(--linie); }
.nl-band-web .wb-bekanntmachungen .aktuelles-titel { font-size: 1.125rem; font-weight: 600; margin: 0 0 .15rem; }
.nl-band-web .wb-bekanntmachungen .aktuelles-datum { display: flex; align-items: center; gap: .35rem; font-size: .8125rem; margin: 0 0 .5rem; }
.nl-band-web .wb-bekanntmachungen .aktuelles-text { font-size: .9375rem; line-height: 1.55; }

/* Datums-/Personen-Icon folgt der gedaempften Zeilenfarbe (inline am Elternabsatz). */
.nl-band-web .wb-liste-datum-icon { width: .95rem; height: .95rem; flex: none; color: inherit; }
.nl-band-web .wb-liste-alle { margin-top: 1.25rem; }

/* Abstand-Baustein: auf der Leinwand sichtbar machen (sonst unsichtbar). */
.wb-abstand--editor {
    display: flex; align-items: center; justify-content: center;
    border: 1px dashed var(--linie, #d7dade); border-radius: var(--radius);
    color: var(--muted); background: repeating-linear-gradient(45deg, transparent, transparent 6px, rgba(0,0,0,.02) 6px, rgba(0,0,0,.02) 12px);
}
.nl-abstand-hinweis { font-size: .85rem; }

/* ============================================================================
   PFLICHTSEITEN-ASSISTENT (ADR-0015 §5, ToDo 6)
   Gefuehrtes Impressum-/Datenschutz-Formular + Vorschau des generierten Texts.
   ============================================================================ */
.badge-warn { background: var(--warn-bg); color: var(--warn-ink); }

.pflicht-editor-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1.25rem;
    align-items: start;
}
@media (max-width: 60rem) {
    .pflicht-editor-grid { grid-template-columns: 1fr; }
}

.pflicht-fehlend { margin: .5rem 0 0; padding-left: 1.2rem; }
.pflicht-fehlend li { margin: .1rem 0; }

/* Vorschau: die generierte oeffentliche Ausgabe im Admin (public.css ist hier
   nicht geladen -> eine schlichte, gescopte Kopie der Rechtstext-Optik). */
.pflicht-vorschau {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1.25rem 1.4rem;
    background: var(--surface);
}
.pflicht-vorschau-titel { font-size: 1.4rem; font-weight: 650; margin: 0 0 1rem; }
.pflicht-vorschau .rechtstext-abschnitt { margin: 0 0 1.1rem; }
.pflicht-vorschau .rechtstext-abschnitt h2 { font-size: 1.02rem; margin: 0 0 .35rem; }
.pflicht-vorschau .rechtstext-abschnitt p { margin: 0 0 .2rem; line-height: 1.5; }
.pflicht-vorschau .rechtstext-entwurf {
    background: var(--warn-bg); color: var(--warn-ink);
    border-radius: var(--radius); padding: .7rem .9rem; margin: 0 0 1.1rem;
    font-size: .85rem; line-height: 1.45;
}
.pflicht-vorschau .rechtstext-unvollstaendig {
    color: var(--muted); font-style: italic; margin: 0;
}

/* Banner-Vorschau im Bekanntmachungs-Editor (VEREINFACHT): breiter als das Logo,
   zeigt den Aufmacher in seinem Seitenverhaeltnis, gedeckelt. */
/* WAHRHEITSGEMAESSE VORSCHAU: dasselbe Verhaeltnis wie die oeffentliche Kachel
   `.aktuelles-banner` in public.css (16 / 7). Vorher stand hier eine freie
   max-height – die Vorschau log dann ueber den spaeter sichtbaren Ausschnitt.
   Seit ADR-0019 ist das gespeicherte Bild bereits 16:7 zugeschnitten, `cover`
   ist nur noch Sicherheitsnetz. Wer das Verhaeltnis aendert, muss public.css,
   diese Regel UND public/js/banner-cropper.js gemeinsam anfassen. */
.banner-vorschau {
    display: block;
    width: 100%;
    max-width: 22rem;
    aspect-ratio: 16 / 7;
    object-fit: cover;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background-color: var(--card);
}

/* =============================================================================
   BANNER-ZUSCHNITT (Cropper.js im Kanzlei-Modal, ADR-0019 §2)
   ============================================================================= */

/* Die Buehne begrenzt die Hoehe des Zuschnitt-Fensters: ohne den Deckel waechst
   ein hochkantiges Handyfoto ueber den Bildschirm hinaus und die Knoepfe
   „Abbrechen"/„Uebernehmen" waeren nicht mehr erreichbar. Cropper.js ersetzt das
   <img> durch einen eigenen Container – die max-width auf `img` ist Pflicht,
   damit er ueberhaupt korrekt misst. */
.cropper-buehne {
    max-height: 55vh;
    margin: 0 0 1rem;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background-color: var(--card);
}

.cropper-buehne img {
    display: block;
    max-width: 100%;
}

/* Der Zuschnitt-Rahmen in Kanzlei-Akzent statt Cropper-Blau. */
.cropper-buehne .cropper-view-box {
    outline-color: var(--accent);
}

.cropper-buehne .cropper-point,
.cropper-buehne .cropper-line {
    background-color: var(--accent);
}

/* =============================================================================
   GREMIEN-PERSONENFOTO (ADR-0024 §4, ToDo 3)
   =============================================================================
   Kleines Foto-Vorschaubild in der Personen-Tabelle (`.foto-thumb`) und die
   groessere Vorschau im Bearbeiten-Overlay (`.foto-vorschau`). Kein festes
   Seitenverhaeltnis erzwungen – das Bild ist bereits zugeschnitten (Hochformat
   oder Quadrat, foto-cropper.js). Alle Farben aus den Tokens (§2). */
.foto-thumb {
    display: block;
    width: 2.4rem;
    height: 2.4rem;
    object-fit: cover;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background-color: var(--card);
}

/* Platzhalter (kein Foto): dasselbe Quadrat, zentriertes user-Icon in --muted. */
.foto-thumb-leer {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--muted);
}

.foto-thumb-leer .icon {
    width: 1.1rem;
    height: 1.1rem;
}

.foto-vorschau {
    display: block;
    width: 8rem;
    max-width: 100%;
    height: auto;
    object-fit: cover;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background-color: var(--card);
}

/* Leerer Tabellenhinweis („Noch keine Personen …") in gedaempfter Schrift. */
.cell-leer {
    color: var(--muted);
}

/* =============================================================================
   VERANSTALTUNGS-MONATSKALENDER (Backend, Feature 0063)
   =============================================================================
   Zweite Ansicht der Veranstaltungs-Liste (`.tab-filter` schaltet um). Reines
   serverseitiges Monatsraster (Mo–So) im Kanzlei-Design – kein JS, keine neue
   Abhaengigkeit. Auf schmalen Schirmen faellt das Raster auf eine gestapelte
   Agenda (nur Tage mit Terminen) zurueck (DESIGN.md §3: „scrollt nie waagerecht").
   Alle Farben aus den Tokens (§2). */

/* Kleines Icon im Ansicht-Reiter (Liste/Kalender) – inline, ohne die globale
   .tab-filter-Regel zu veraendern. */
.tab-icon { width: 1rem; height: 1rem; vertical-align: -.15rem; margin-right: .35rem; }

/* Kopf: Monatsnavigation links, Monatstitel rechts. */
.kalender-kopf {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; margin: 0 0 1rem; flex-wrap: wrap;
}
.kalender-nav { display: flex; align-items: center; gap: .5rem; }
.kalender-heute { padding: 0 .9rem; }
.kalender-titel {
    font-size: 1.05rem; font-weight: 650; margin: 0; text-transform: capitalize;
    letter-spacing: -.01em;
}

/* --- Monatsraster (Desktop) ------------------------------------------------ */
/* Das Kalender-Panel darf NICHT clippen (Feature 0069): es traegt die schwebende
   Vorschau-Sprechblase `.kalender-vorschau`. `.panel-flush` bringt aber
   `overflow: hidden` mit (fuer Tabellen richtig) – deshalb dieser Modifier statt
   einer Aenderung an `.panel-flush` selbst. Die Eckenrundung, die sonst per
   `overflow` entstand, sitzt dafuer an den Eck-Zellen (DESIGN.md, Popover-Muster). */
.panel-kalender { overflow: visible; }
.panel-kalender .kalender-wochentage span:first-child { border-top-left-radius: calc(var(--radius) - 1px); }
.panel-kalender .kalender-wochentage span:last-child { border-top-right-radius: calc(var(--radius) - 1px); }
.panel-kalender .kalender-woche:last-child .kalender-tag:first-child { border-bottom-left-radius: calc(var(--radius) - 1px); }
.panel-kalender .kalender-woche:last-child .kalender-tag:last-child { border-bottom-right-radius: calc(var(--radius) - 1px); }

.kalender-grid { padding: 0; }
.kalender-wochentage,
.kalender-woche {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
}
.kalender-wochentage {
    background: var(--th-bg);
    border-bottom: 1px solid var(--line-strong);
}
.kalender-wochentage span {
    padding: .55rem .6rem; font-size: .72rem; font-weight: 650;
    color: var(--muted); text-align: left; text-transform: uppercase;
    letter-spacing: .04em;
}
.kalender-woche { border-bottom: 1px solid var(--line); }
.kalender-woche:last-child { border-bottom: 0; }

.kalender-tag {
    min-height: 6.5rem;
    padding: .35rem .4rem .5rem;
    border-right: 1px solid var(--line);
    display: flex; flex-direction: column; gap: .2rem;
    min-width: 0;
}
.kalender-tag:nth-child(7n) { border-right: 0; }
.kalender-tag.ausser-monat { background: var(--page); }
.kalender-tag.ausser-monat .kalender-tag-zahl { color: var(--muted); opacity: .65; }
.kalender-tag-zahl {
    font-size: .8rem; font-weight: 600; color: var(--ink);
    align-self: flex-start; line-height: 1.4;
    min-width: 1.5rem; text-align: center; border-radius: 999px;
}
.kalender-tag.heute .kalender-tag-zahl {
    background: var(--accent); color: var(--on-accent);
}

/* Ein Termin-Chip im Tag. Klick fuehrt in den Editor.
   `position: relative` = Anker der Vorschau-Sprechblase (Feature 0069). */
.kalender-event {
    position: relative;
    display: flex; align-items: flex-start; gap: .25rem;
    padding: .15rem .35rem; border-radius: var(--radius);
    background: var(--accent-soft); color: var(--accent-ink);
    font-size: .74rem; line-height: 1.3; text-decoration: none;
    min-width: 0;
}
.kalender-event:hover { filter: brightness(.97); text-decoration: none; }
.kalender-event:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.kalender-event.intern {
    background: var(--off-bg); color: var(--off-ink);
    border: 1px dashed var(--line-strong);
    padding: calc(.15rem - 1px) calc(.35rem - 1px);
}
.kalender-event-icon { width: .8rem; height: .8rem; flex-shrink: 0; margin-top: .15rem; }
.kalender-event-zeit { font-weight: 650; flex-shrink: 0; font-variant-numeric: tabular-nums; }
/* MEHRZEILIGER TITEL (Feature 0069): zwei Zeilen, bei genau einem Termin am Tag
   (`.ein-termin`) drei – abgeschnitten per `line-clamp` mit Ellipse. */
.kalender-event-titel {
    display: -webkit-box; -webkit-box-orient: vertical;
    -webkit-line-clamp: 2; line-clamp: 2;
    overflow: hidden; min-width: 0;
    /* Lange deutsche Komposita („Jahreshauptversammlung“) sollen an sinnvollen
       Stellen trennen statt mitten im Wort zu brechen; `break-word` bleibt als
       Rueckfall fuer Woerter, die auch getrennt nicht passen. */
    white-space: normal; overflow-wrap: break-word; hyphens: auto;
}
.kalender-tag.ein-termin .kalender-event-titel { -webkit-line-clamp: 3; line-clamp: 3; }
.kalender-event-mehr { flex-shrink: 0; font-weight: 700; opacity: .7; }

/* --- Vorschau-Sprechblase (Feature 0069) -----------------------------------
   Schwebendes Fenster mit Datum, Uhrzeit, Ort, Kurzbeschreibung und der
   Kennzeichnung oeffentlich/intern. Rein CSS: `:hover` + `:focus-within` (der
   Chip ist ein `<a>`, also auch per Tastatur erreichbar). Sie liegt INNERHALB
   des Links – ein Klick darauf oeffnet den Editor, sie faengt nichts ab. Nur auf
   Geraeten mit echtem Hover; schmale Schirme zeigen ohnehin die Agenda. */
.kalender-vorschau { display: none; }

@media (hover: hover) {
    .kalender-vorschau {
        display: block; position: absolute; z-index: 30;
        top: calc(100% + .3rem); left: -.2rem;
        width: max-content; max-width: 18rem;
        padding: .6rem .7rem;
        background: var(--card); color: var(--ink);
        border: 1px solid var(--line-strong); border-radius: var(--radius);
        box-shadow: var(--shadow);
        font-size: .78rem; line-height: 1.45;
        white-space: normal; text-align: left;
        opacity: 0; visibility: hidden;
        transition: opacity .12s ease-out, visibility .12s ease-out;
    }
    .kalender-event:hover,
    .kalender-event:focus-within { z-index: 31; }
    .kalender-event:hover .kalender-vorschau,
    .kalender-event:focus-within .kalender-vorschau { opacity: 1; visibility: visible; }

    /* In den beiden rechten Spalten nach links kippen, in der letzten Woche nach oben. */
    .kalender-tag:nth-child(n+6) .kalender-vorschau { left: auto; right: -.2rem; }
    .kalender-woche:last-child .kalender-vorschau { top: auto; bottom: calc(100% + .3rem); }

    .kalender-vorschau-titel {
        display: block; font-weight: 650; font-size: .87rem;
        line-height: 1.3; margin: 0 0 .25rem; color: var(--ink);
    }
    .kalender-vorschau-meta { display: block; color: var(--ink); font-weight: 600; }
    .kalender-vorschau-ort { display: block; color: var(--muted); }
    .kalender-vorschau-text { display: block; margin: .35rem 0 0; color: var(--muted); }
    .kalender-vorschau-marker {
        display: block; margin: .35rem 0 0; font-size: .72rem;
        font-weight: 650; color: var(--muted);
    }
    .kalender-vorschau-mehr {
        display: block; margin: .45rem 0 0; padding: .35rem 0 0;
        border-top: 1px solid var(--line);
        font-weight: 650; font-size: .74rem; color: var(--accent);
    }
}

.kalender-leer { color: var(--muted); padding: 1.25rem 1.35rem; margin: 0; }

/* --- Agenda (schmale Schirme) ---------------------------------------------- */
/* Standard: versteckt; ab schmaler Breite tritt sie an die Stelle des Rasters. */
.kalender-agenda { display: none; list-style: none; margin: 0; padding: 0; }
.kalender-agenda-tag {
    display: flex; gap: .85rem; align-items: flex-start;
    padding: .7rem 1rem; border-bottom: 1px solid var(--line);
}
.kalender-agenda-tag:last-child { border-bottom: 0; }
.kalender-agenda-datum {
    display: flex; flex-direction: column; align-items: center;
    min-width: 2.2rem; flex-shrink: 0;
}
.kalender-agenda-tag.heute .kalender-agenda-zahl {
    background: var(--accent); color: var(--on-accent);
    border-radius: 999px; width: 1.8rem; height: 1.8rem;
    display: flex; align-items: center; justify-content: center;
}
.kalender-agenda-zahl { font-size: 1.05rem; font-weight: 700; color: var(--ink); }
.kalender-agenda-wt { font-size: .7rem; font-weight: 650; color: var(--muted); text-transform: uppercase; }
.kalender-agenda-events { display: flex; flex-direction: column; gap: .3rem; min-width: 0; flex: 1; }
.kalender-agenda-events .kalender-event { font-size: .82rem; padding: .3rem .5rem; }
/* In der Agenda ist Platz: der Titel laeuft voll aus, kein `line-clamp`. */
.kalender-agenda-events .kalender-event-titel {
    display: block; -webkit-line-clamp: none; line-clamp: none; overflow: visible;
}
.kalender-agenda-mehr { margin-left: auto; flex-shrink: 0; }

@media (max-width: 48rem) {
    .kalender-grid { display: none; }
    .kalender-agenda { display: block; }
    /* Leer-Hinweis behaelt seine Randabstaende auch ohne Raster darueber. */
}

/* =============================================================================
   TEILNEHMER / RSVP im Veranstaltungsformular (ADR-0020 §5)
   ========================================================================== */
.page-head-sub { margin-top: .25rem; }
.page-head-sub h2 { margin: 0; font-size: 1.15rem; }

/* „Link kopieren"-Zeile: read-only URL + Knopf nebeneinander. */
.kopier-zeile { display: flex; gap: .5rem; align-items: stretch; flex-wrap: wrap; }
.kopier-zeile input { flex: 1 1 18rem; min-width: 0; }
.kopier-zeile .btn { flex: none; white-space: nowrap; }

/* Zähler-Kacheln (Personen zugesagt / Zusagen / Vielleicht / Absagen). */
.rsvp-zaehler {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
    gap: .75rem; margin: 1.25rem 0;
}
.rsvp-zaehler-kachel {
    background: var(--th-bg); border: 1px solid var(--line);
    border-radius: 10px; padding: .85rem 1rem; text-align: center;
    display: flex; flex-direction: column; gap: .2rem;
}
.rsvp-zaehler-zahl { font-size: 1.6rem; font-weight: 700; line-height: 1; color: var(--accent); }
.rsvp-zaehler-label { font-size: .78rem; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }

.rsvp-listen-titel { font-size: 1rem; margin: 1.5rem 0 .5rem; }

/* --- Sidebar-Module: Typ-Auswahl im Anlegen-Overlay (Feature-0008) -----------
   Vier Optionen als anklickbare Karten. Kanzlei-Design: helle Flaeche, dezenter
   Rahmen, Akzent bei Hover/Fokus. */
.typ-wahl {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .6rem;
    margin: 1rem 0 .5rem;
}
@media (max-width: 34rem) { .typ-wahl { grid-template-columns: 1fr; } }
.typ-wahl-option {
    display: flex;
    flex-direction: column;
    gap: .2rem;
    text-align: left;
    padding: .8rem .9rem;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius, .5rem);
    cursor: pointer;
    font: inherit;
    color: var(--ink);
}
.typ-wahl-option:hover { border-color: var(--accent); background: var(--hover); }
.typ-wahl-option:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.typ-wahl-option strong { font-size: .95rem; }
.typ-wahl-option span { font-size: .82rem; color: var(--muted); line-height: 1.4; }

/* KONTOAUSZUG-IMPORT (Feature 0012, Handoff 0138) ----------------------------
   Der Import ist ein IN-PAGE-SCHRITT (DESIGN §25) und benutzt ausschliesslich
   die erprobten Formularflaechen (`.panel.form-panel`, `.form-section`,
   `.form-row`, `.form-actions`) und die `.data`-Tabelle. Hier stehen nur die
   drei Kleinigkeiten, fuer die es sonst nichts gibt. */

/* Die fuenf Spaltenzuordnungen passen nicht in das ZWEIspaltige `.form-row`:
   sie gehoeren zusammen und sollen so viele nebeneinander stehen, wie Platz ist.
   Deshalb ein eigenes, mitwachsendes Raster statt fuenf halber Zeilen. */
.import-zuordnung {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 1rem 1.25rem;
    margin-bottom: 1rem;
}
.import-zuordnung .form-field { margin-bottom: 0; }

/* Eine Zeile der Pruefansicht, die NICHT uebernommen wird (bereits vorhanden
   oder nicht lesbar). Sie wird zurueckgenommen, aber NICHT versteckt: der
   Kassenwart muss sehen koennen, wo die uebersprungenen Zeilen geblieben sind.
   Kein `display: none`, kein Ausfiltern – das waere genau das stillschweigende
   Verschlucken, das der Auftrag ausschliesst. */
table.data tr.zeile-still td { color: var(--muted); background: var(--off-bg); }

/* „wird uebernommen" – dieselbe Marke wie `.tag-quiet`, nur in den vorhandenen
   Ok-Tokens (Muster `.tag-danger` aus Handoff 0134). */
.tag-ok { background: var(--ok-bg); color: var(--ok-ink); }

/* DAS ANGEBOT „ALS UMBUCHUNG UEBERNEHMEN" in der Befund-Spalte der Pruefansicht
   (Handoff 0142). Ein Haekchen mit Beschriftung IN einer Tabellenzelle – dafuer
   gibt es kein `.form-field` (das traegt Aussenabstand und Blockbreite eines
   Formulars). Nur die drei Angaben, die eine Zelle wirklich braucht: eine Zeile,
   ein Abstand nach oben, und der Text bricht mit dem Kaestchen buendig um. */
.umbuchung-angebot {
    display: flex; align-items: flex-start; gap: .4rem;
    margin-top: .4rem; font-size: .82rem; cursor: pointer;
}
.umbuchung-angebot input { margin-top: .15rem; flex-shrink: 0; }

/* BESTAND JE KONTO in der Kennzahl-Karte der Uebersicht (Handoff 0138).
   Eine schlichte Aufteilung UNTER der Gesamtzahl – keine zweite Tabelle und
   keine zweite Karte: die Konten erklaeren die Zahl darueber, sie stehen nicht
   daneben. Erst ab dem zweiten Konto sichtbar (sonst staende dieselbe Zahl
   zweimal). */
.konten-liste { list-style: none; margin: .75rem 0 0; padding: .6rem 0 0; border-top: 1px solid var(--line); }
.konten-liste li { display: flex; justify-content: space-between; gap: 1rem; padding: .2rem 0; font-size: .86rem; }
.konten-liste .konto-name { color: var(--muted); }
.konten-liste .konto-wert { font-weight: 650; font-variant-numeric: tabular-nums; }
.konten-liste .konto-wert.ist-negativ { color: var(--danger-ink); }

/* MEHRERE BEFUNDE IN EINEM STEHENDEN HINWEIS (Handoff 0144). Der
   Kontoauszug-Import kann gleichzeitig mehreres zu sagen haben: die Datei
   gehoert zu einer fremden IBAN, ihre Salden gehen nicht auf, drei
   Vormerkposten wurden uebersprungen. Das sind UNABHAENGIGE Saetze – als
   Fliesstext-Absatz liest sie niemand einzeln, als Aufzaehlung hakt man sie ab.
   Kein neuer Kasten, kein neues Token: es bleibt der `.flash.flash-warn` aus
   DESIGN §26. Zurueckgenommen werden nur die Browservorgaben der Liste (weiter
   Einzug, grosse Aussenabstaende), die den kleinen Kasten sonst sprengen. */
.flash > ul { margin: 0; padding-left: 1.15rem; }
.flash > ul > li + li { margin-top: .4rem; }

/* ==========================================================================
   ZENTRALE DATEIABLAGE (Handoff 0166) – Kontingent-Balken, Brotkrumen,
   Namenszelle, Meldungsliste. Alles aus vorhandenen Tokens; kein neuer Akzent,
   keine neue Farbe. Dokumentiert in docs/DESIGN.md §35.
   ========================================================================== */

/* Der Fuellstand steht IMMER da, nicht erst bei der Absage. */
.kontingent .kontingent-kopf {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .75rem;
    margin-bottom: .45rem;
}

.kontingent .kontingent-stand { font-size: .875rem; font-weight: 600; color: var(--ink); }
.kontingent .kontingent-frei { font-size: .8rem; color: var(--muted); }

.kontingent-balken {
    position: relative;
    height: .5rem;
    border-radius: 999px;
    background: var(--line);
    overflow: hidden;
}

.kontingent-balken .kontingent-fuellung {
    display: block;
    height: 100%;
    background: var(--accent);
    border-radius: 999px;
    transition: width .2s ease;
}

/* Ab 90 % faerbt sich die Fuellung – ein Hinweis VOR der Sperre. Farbe ist
   nie die einzige Aussage: die Zahl daneben sagt dasselbe in Worten. */
.kontingent-balken.ist-eng .kontingent-fuellung { background: var(--danger); }

/* Der Weg als Anzeige – die Ordner sind Kennungen, keine Pfadstuecke. */
.brotkrumen {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .25rem;
    margin: 0 0 .9rem;
    font-size: .875rem;
}

.brotkrumen .brotkrumen-pfeil { color: var(--muted); }

.brotkrumen .brotkrume {
    background: none;
    border: 0;
    padding: .15rem .3rem;
    border-radius: 4px;
    font: inherit;
    color: var(--accent);
    cursor: pointer;
}

.brotkrumen .brotkrume:hover { background: var(--hover); }
.brotkrumen .brotkrume:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.brotkrumen .brotkrume.ist-hier { color: var(--ink); font-weight: 600; cursor: default; }
.brotkrumen .brotkrume.ist-hier:hover { background: none; }

/* Symbol + Name in einer Zeile. Bei einem Ordner ist das Ganze ein Knopf
   (er fuehrt hinein), bei einer Datei nur ein Behaelter. */
.ablage-name {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    max-width: 100%;
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: inherit;
    text-align: left;
}

button.ablage-name { cursor: pointer; }
button.ablage-name:hover .cell { color: var(--accent); text-decoration: underline; }
button.ablage-name:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

.ablage-name .ablage-symbol { width: 1.05rem; height: 1.05rem; flex: 0 0 auto; color: var(--muted); }
button.ablage-name .ablage-symbol { color: var(--accent); }

/* EINE EBENE HOEHER – der erste Eintrag der Liste (Handoff 0178, DESIGN §35.3a).
   Nutzer-Befund 17.08.2026: der Weg zurueck in den uebergeordneten Ordner war
   „zu umstaendlich und nicht intuitiv" – es gab ihn nur ueber die Brotkrumen.
   Die Zeile ist NAVIGATION, kein Inhalt. Genau das sagt die Flaeche des
   Tabellenkopfes (`--th-bg`, vorhandenes Token, keine neue Farbe) und der
   halbfette Name; das Symbol ist `arrow-left` – dasselbe „zurueck", das der
   `.back-link` traegt (DESIGN §6). Ein eigenes Icon dafuer waere der Fehler aus
   §9: zwei Silhouetten fuer dieselbe Bedeutung. */
table.data tbody tr.ablage-hoch > td { background: var(--th-bg); }
table.data tbody tr.ablage-hoch button.ablage-name { font-weight: 600; }

/* Rueckmeldung nach dem Ablegen: je Datei eine Zeile, geglueckt UND abgelehnt
   nebeneinander. Bewusst NICHT `.nl-upload-meldung` (DESIGN §16) – jener Kasten
   ist durchgehend rot und meint EINE abgelehnte Datei. */
.ablage-meldungen {
    margin: .75rem 0 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: .3rem;
}

.ablage-meldungen li {
    font-size: .82rem;
    line-height: 1.45;
    padding: .4rem .6rem;
    border-radius: 6px;
}

.ablage-meldungen li.ist-ok { background: var(--ok-bg); color: var(--ok-ink); }
.ablage-meldungen li.ist-fehler { background: var(--danger-bg); color: var(--danger-ink); font-weight: 600; }

/* =============================================================================
   FREIGABE-LINKS IN DER DATEIABLAGE (Handoff 0167, DESIGN §36)
   ----------------------------------------------------------------------------
   Nur zwei Klassen, beide aus vorhandenen Tokens – kein neuer Akzent, keine
   neue Farbe. Alles Uebrige des Reiters „Freigaben" ist bestehendes Muster:
   `table.data` (§5), `.zeile-meta` (§5.1), `.tab-filter` (§6), `.modal` (§8).
   ========================================================================== */

/* DIE ADRESSE STEHT IN EINEM FELD, NICHT IN EINEM ABSATZ. Ein Klick hinein
   markiert sie ganz (Alpine: `x-on:focus="$el.select()"`) – niemand muss mit
   der Maus zielen. `readonly` statt `disabled`, sonst liesse sich der Text
   nicht auswaehlen.

   ⚠ HIER STAND BIS HANDOFF 0180: „BEWUSST KEIN Clipboard-Aufruf: der braucht
   eine sichere Herkunft und eine Erlaubnis und schluege im Zweifel still fehl."
   Das galt, SOLANGE ES KEINEN RUECKFALLWEG GAB. Seit 0180 gibt es einen
   (`.kopier-zeile`/`.kopier-meldung` weiter unten, public/js/link-kopieren.js):
   der Versuch wird unternommen, und ein Fehlschlag sagt AUSDRUECKLICH, dass von
   Hand zu kopieren ist. Dieses Feld bleibt dabei der Anker – markiert liegt die
   Adresse dann bereit. */
.freigabe-url {
    width: 100%;
    min-width: 14rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .78rem;
    padding: .35rem .5rem;
    border: 1px solid var(--line-strong);
    border-radius: 6px;
    background: var(--page);
    color: var(--ink);
}

.freigabe-url:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Der Zustand als dezente Pille – FARBE IST NIE DIE EINZIGE AUSSAGE: das Wort
   („offen", „abgelaufen", „zurückgezogen") steht darin. */
.freigabe-zustand {
    display: inline-block;
    font-size: .78rem;
    font-weight: 600;
    padding: .1rem .45rem;
    border-radius: 999px;
    background: var(--off-bg);
    color: var(--off-ink);
}

.freigabe-zustand.ist-offen { background: var(--ok-bg); color: var(--ok-ink); }
.freigabe-zustand.ist-abgelaufen { background: var(--warn-bg); color: var(--warn-ink); }
.freigabe-zustand.ist-widerrufen { background: var(--danger-bg); color: var(--danger-ink); }

/* =============================================================================
   DEN VORHANDENEN LINK KOPIEREN (Handoff 0180, DESIGN §36.2b)
   ----------------------------------------------------------------------------
   Zwei Klassen im Fenster „Freigabe-Link", beide aus vorhandenen Tokens. Alles
   Uebrige ist bestehendes Muster: `.modal` (§8), `.form-field` (§7),
   `.freigabe-url` und `.freigabe-zustand` (§36.2), `.field-hint` (§7.1).
   ========================================================================== */

/* Knopf und Restlaufzeit in einer Zeile; sie bricht um, statt das Fenster
   waagerecht aufzuziehen. */
.kopier-zeile {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .6rem;
    margin-top: .5rem;
}

/* ⚠ DER PLATZ FUER DIE RUECKMELDUNG IST RESERVIERT (`min-height`), UND DAS IST
   DER PUNKT: die Meldung erscheint erst auf einen Klick. Waechse das Fenster
   dabei, rutschte der Knopf unter dem Finger weg und die Sicherheitsabfrage
   darunter mit ihm. DIE HOEHE IST GEMESSEN, NICHT GESCHAETZT: im 30-rem-Fenster
   braucht der laengere (Rueckfall-)Satz drei Zeilen – `min-height` traegt sie.
   Auf sehr schmalen Schirmen kann eine vierte hinzukommen; dann waechst das
   Fenster doch, und der Satz gehoerte gekuerzt.

   FARBE IST NIE DIE EINZIGE AUSSAGE: der Satz selbst sagt, was los ist. Warn-
   und nicht Danger-Tokens im Fehlschlag-Fall – es ist kein „gilt nicht" (§34.6),
   sondern eine Handarbeit, die jetzt noetig ist. */
.kopier-meldung {
    min-height: 3.4rem;
    margin: .4rem 0 0;
    padding: .35rem .55rem;
    font-size: .82rem;
    line-height: 1.45;
    border-radius: 6px;
    background: none;
    color: var(--muted);
}

.kopier-meldung.ist-sichtbar { background: var(--warn-bg); color: var(--warn-ink); }
.kopier-meldung.ist-sichtbar.ist-ok { background: var(--ok-bg); color: var(--ok-ink); }

/* =============================================================================
   EINLASS-SEITE: AMPEL, NAME, ABZAEHLEN (Handoff 0192, DESIGN §37, ADR-0037)
   ----------------------------------------------------------------------------
   Die einzige Seite der Verwaltung, die IM STEHEN, EINHAENDIG, AUF EINEM TELEFON
   bedient wird. Daraus folgt jede Zahl hier unten:

   1. DIE AMPEL IST GROSS, WEIL SIE AUS ARMLAENGE LESBAR SEIN MUSS – nicht, weil
      Grosses schoener waere. Der Name darunter ist klein: er ist die Kontrolle,
      nicht die Aussage (ADR-0037 §10, Menschenentscheidung).
   2. DIE ZAHLENKNOEPFE SIND 3 rem HOCH UND MINDESTENS 3 rem BREIT. Ein Ziel
      unter ~2,5 rem trifft ein Daumen im Halbdunkel nicht zuverlaessig; die
      Reihe bricht um, statt schmaler zu werden.
   3. FARBE IST NIE DIE EINZIGE AUSSAGE: jede Ampel traegt eine ausgeschriebene
      Kopfzeile und `role="status"`/`role="alert"`.

   DIE DREI FARBEN SIND DIESELBEN DREI wie auf der oeffentlichen Ampel-Pruefseite
   (public.css §11, DESIGN §32) – bewusst dieselben Werte und NICHT die Tokens
   `--ok-*`/`--danger-*`: eine Ampel ist Information, keine Statuspille, und sie
   soll im Haus ueberall gleich aussehen. `--danger-*` bliebe hier ausserdem
   falsch, weil eine aufgebrauchte Karte nicht „defekt" ist, sondern „gilt
   nicht (mehr)" – genau die Aussage, fuer die Rot im Haus reserviert ist
   (DESIGN §34.6).
   ========================================================================== */

/* ⚠ DIE BETRIEBSAUFLAGE (ADR-0037 §10) STEHT ALS ERSTE ZEILE DER SEITE, nicht
   hinter einem ⓘ: sie ist die Bedingung, unter der ein fremder Name auf diesem
   Bildschirm ueberhaupt vertretbar ist. Warn-Toene, kein Rot – die Seite gilt. */
.einlass-auflage {
    background: var(--warn-bg);
    color: var(--warn-ink);
    border-radius: var(--radius);
    padding: .7rem .9rem;
    margin: 0 0 1.25rem;
    font-size: .88rem;
    line-height: 1.5;
}

.einlass-auflage-vorbei { background: var(--off-bg); color: var(--off-ink); }

/* Der Befund liegt in einer `.panel`-Karte; nur Rahmen und Flaeche kommen von
   der Ampel. So bleibt der Abstand derselbe wie ueberall in der Verwaltung. */
.einlass-befund { border-width: 2px; border-style: solid; text-align: center; }

.einlass-befund-gruen { background: #e9f6ec; border-color: #7bbb8c; color: #16491f; }
.einlass-befund-gelb  { background: #fdf4e3; border-color: #d9a94a; color: #6a4708; }
.einlass-befund-rot   { background: #fdecec; border-color: #d98b8b; color: #7d1d1d; }

/* AUS ARMLAENGE LESBAR. `clamp` haelt sie auf sehr schmalen Telefonen im
   Kasten, ohne dass eine zweite Regel noetig waere. */
.einlass-ampel {
    font-size: clamp(1.6rem, 7vw, 2.3rem);
    font-weight: 700;
    line-height: 1.15;
    margin: .2rem 0 .5rem;
}

.einlass-stand { margin: 0; font-size: .95rem; }

/* ⚠ KLEIN, UND ER BLEIBT NICHT LIEGEN (ADR-0037 §10): nach 20 Sekunden tritt
   `.einlass-name-weg` an seine Stelle. Zwischen zwei Gaesten steht kein fremder
   Name mehr auf dem Bildschirm. */
.einlass-name {
    margin: .6rem 0 0;
    font-size: .95rem;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.einlass-name-weg { font-weight: 400; opacity: .55; }

.einlass-frage { margin: 1.1rem 0 .5rem; font-size: .88rem; font-weight: 600; }

/* Die Knopfreihe bricht um, statt die Knoepfe zu verkleinern. */
.einlass-zahlen {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .5rem;
    margin-top: 1.1rem;
}

.einlass-zahl {
    height: 3rem;
    min-width: 3rem;
    font-size: 1.05rem;
    font-weight: 700;
}

.einlass-zahl-weit { min-width: 12rem; }

.einlass-ruecknahme { margin-top: 1rem; }

/* Feld und Knopf nebeneinander, auf schmalen Schirmen untereinander. */
.einlass-eingabe-zeile { display: flex; gap: .5rem; align-items: stretch; flex-wrap: wrap; }
.einlass-eingabe-zeile input { flex: 1 1 16rem; min-width: 0; }
.einlass-eingabe-zeile .btn { flex: none; }

.einlass-scan { margin-top: 1.1rem; }

/* ----------------------------------------------------------------------------
   37c. OHNE ANMELDUNG (Nutzer-Entscheidung 2026-08-21)
   ----------------------------------------------------------------------------
   Der Block steht IMMER auf der Einlass-Seite, nicht erst, wenn jemand ohne
   Karte davorsteht: wer an der Tuer erst ueberlegen muss, ob das erlaubt ist,
   haelt die Schlange auf. Er borgt sich Frage und Zahlenknoepfe aus §37 – es
   ist dieselbe Handbewegung, nur ein anderer Gegenstand.
   ⚠ „Ausgebucht" ist WARN, nicht Danger (DESIGN §34.6): die Seite gilt, sie ist
   nur voll. Rot ist im Haus fuer „gilt nicht" reserviert.
   -------------------------------------------------------------------------- */
.einlass-ohne { margin-top: 1.25rem; }

/* ⚠ HIER STEHEN DIE ZAHLEN LINKS, nicht mittig wie im Befund (§37): der Befund
   ist eine Ampel und wird als Ganzes zentriert, dieser Block ist eine
   gewoehnliche Karte mit Ueberschrift und Fliesstext. Mittige Knoepfe unter
   linksbuendigem Text saehen aus wie ein Fehler. */
.einlass-ohne .einlass-zahlen { justify-content: flex-start; }

.einlass-ohne-aus,
.einlass-ohne-voll {
    margin: 0;
    padding: .7rem .85rem;
    border-radius: var(--radius);
    font-size: .9rem;
    line-height: 1.5;
}

.einlass-ohne-aus { background: var(--off-bg); color: var(--off-ink); }
.einlass-ohne-voll { background: var(--warn-bg); color: var(--warn-ink); }

/* Die Standzeile der Platzobergrenze im Veranstaltungs-Editor. Sie sagt eine
   Zahl, keine Meinung – und „ueberbucht"/„ausgebucht" ist WARN, nicht Danger:
   die Veranstaltung gilt, sie ist nur voll (DESIGN §34.6). */
.plaetze-stand {
    margin: -.25rem 0 .9rem;
    padding: .55rem .8rem;
    border-radius: var(--radius);
    background: var(--off-bg);
    color: var(--off-ink);
    font-size: .86rem;
    line-height: 1.5;
}

.plaetze-stand-warn { background: var(--warn-bg); color: var(--warn-ink); }

/* Der Anwesenheits-Kasten ueber der Zusagen-Liste (Handoff 0196). Gleiche
   Bauart wie `.plaetze-stand`, aber EIGENE Klasse und OHNE dessen negativen
   oberen Abstand: der steht dort unter einem Feld, dieser hier unter einer
   Zwischenueberschrift (`.rsvp-listen-titel`).

   ⚠ WARN, NICHT DANGER, FUER DEN LEERFALL (DESIGN §34.6): „es wurde nicht
   gescannt" ist ein offener Punkt, kein Defekt. Rot heisst im Haus „gilt
   nicht" – und die Veranstaltung gilt sehr wohl, es hat nur niemand gezaehlt.
   Genau diese Unterscheidung ist der ganze Zweck des Kastens. */
.anwesenheit-stand {
    margin: 0 0 .9rem;
    padding: .55rem .8rem;
    border-radius: var(--radius);
    background: var(--off-bg);
    color: var(--off-ink);
    font-size: .86rem;
    line-height: 1.5;
}

.anwesenheit-stand p { margin: 0 0 .35rem; }
.anwesenheit-stand p:last-child { margin-bottom: 0; }
.anwesenheit-stand-warn { background: var(--warn-bg); color: var(--warn-ink); }

/* =============================================================================
   37a. EINLASS-ZUGAENGE UND DIE GEDRUCKTE LISTE (Handoff 0193, ADR-0037 §7–§9)
   ----------------------------------------------------------------------------
   Der Verwaltungsteil des Einlasses – NICHT die Tuer selbst (die liegt in §37
   bzw., fuer den Helfer ohne Konto, im oeffentlichen Theme). Wenig Eigenes: die
   Liste der Zugaenge ist eine gewoehnliche `.data`-Tabelle, die zwei Haekchen
   sind `.check-label`. Neu ist nur, was NEBENEINANDER stehen muss.
   ========================================================================== */

/* Bezeichnung + Knopf in einer Zeile. ⚠ Daneben steht KEIN Feld fuer die
   Laufzeit: sie wird aus dem Termin gerechnet (ADR-0037 §8). */
.einlass-zugang-neu { margin: 0 0 1rem; }
.einlass-zugang-neu > label { display: block; font-weight: 600; margin-bottom: .3rem; }

.einlass-zugang-zeile { display: flex; gap: .5rem; align-items: stretch; flex-wrap: wrap; }
.einlass-zugang-zeile input { flex: 1 1 18rem; min-width: 0; }
.einlass-zugang-zeile .btn { flex: none; }

/* Der weitergebbare Link steht in einem Feld zum Antippen/Markieren – wie die
   Teilnahme-URL darueber. Schmal gehalten: er ist zum Kopieren da, nicht zum
   Lesen. */
.einlass-zugang-url {
    width: 11rem;
    max-width: 100%;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .78rem;
}

/* Die zwei Haekchen der gedruckten Liste und der Knopf daneben. Sie sind eine
   Datenschutz-Entscheidung, keine Formatierung (was am Eingang offen liegt),
   deshalb stehen sie SICHTBAR beim Knopf und nicht hinter einem ⓘ. */
.liste-drucken {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem 1.25rem;
    margin: .5rem 0 .75rem;
}

/* =============================================================================
   39. AUFGABEN-BOARD: DIE TAFEL (Handoff 0208, ADR-0039 Paket 1)
   ----------------------------------------------------------------------------
   Eine Tafel ist weder Tabelle noch Formular – sie ist das erste waagerechte
   Element des Hauses. Deshalb ein eigener Abschnitt; alles andere auf der Seite
   (Kopfzeile, Knoepfe, Overlay-Fenster, Marken) kommt unveraendert aus dem
   vorhandenen Kanzlei-Satz.

   ⚠ DIE SEITE SCROLLT NIE WAAGERECHT (DESIGN §3). `.board-tafel` spiegelt
   deshalb `.table-scroll` inklusive `position: relative` – ohne das entkaeme ein
   `position: absolute`-Kind (`.sr-only`) dem Container und zoege die ganze Seite
   auf.

   ⚠ KEIN ZWEITER AKZENT (DESIGN §1). Die Tafel arbeitet mit denselben
   Flaechen-Tokens wie jede Liste und keine eigene Farbe. Petrol taucht nur dort auf, wo es
   ueberall auftaucht: am Fokus-Ring und am Ziehgriff im Hover.

   ⚠⚠ 0218: DIE FLAECHEN SIND VERTAUSCHT. Bis 0217 trug die SPALTE `--card`
   (weiss) und das Ticket darin `--page` (hellgrau) – die Umkehrung, die im Haus
   ueberall gilt, wo etwas IN einer Flaeche liegt. Auf der Tafel ergab das ein
   graues Rechteck auf Weiss mit 1,07:1: das Ticket, also das Einzige, was ein
   Mensch hier anfasst, war das Blasseste auf dem Schirm. Nutzer-Befund,
   woertlich: „grau sieht so trostlos aus und designmäßig nicht der große Hit."

   SEIT 0218 IST DIE SPALTE DIE FLAECHE (`--page`) UND DAS TICKET LIEGT DARAUF
   (`--card` + `--shadow-ticket`). Das ist KEIN Bruch der Haus-Umkehrung, sondern
   ihre Anwendung auf die richtige Ebene: eine Spalte ist ein Behaelter wie eine
   Seite, ein Ticket ist der Datensatz darin – wie eine `.panel`-Karte auf
   `--page`. Und es ist KEINE neue Farbe: getauscht werden zwei Tokens, die
   beide schon dastanden (DESIGN §39.6a).
   ========================================================================== */

/* DER BOARD-KOPF: Beschreibung, Sichtbarkeitszeile, Sichtvermerk. */
.board-kopf > * + * { margin-top: .5rem; }
.board-beschreibung { margin: 0; }

/* ⚠ DIE SICHTBARKEITSZEILE (ADR-0039 §4). Sie ist die Bedingung, unter der die
   Vollsicht der Vereinsverwaltung vertretbar ist – und deshalb bewusst KEIN
   gedaempfter Kleintext und KEIN einklappbarer Kasten: sie steht in Textfarbe,
   halbfett, in der ersten Zeile des Kopfes. Wer sie leiser macht, macht die
   Einsicht wieder verdeckt. */
/* ⚠ MIT `.panel` DAVOR, und das ist kein Schmuck, sondern die Spezifitaetsfalle
   aus DESIGN §28: `.panel p { color: var(--muted) }` ist mit Klasse + Element
   staerker als eine blosse Klasse. Ohne den Vorsatz stuende ausgerechnet DIESE
   Zeile gedaempft da – die eine Zeile, die nicht leise sein darf. (Beim Bau
   genau so passiert und im Bildschirmfoto aufgefallen.) Kein `!important`. */
.panel .board-zugang {
    margin: 0;
    font-weight: 600;
    color: var(--ink);
}

/* Der Sichtvermerk ist eine Beobachtung, keine Warnung – also GEDAEMPFT und
   NICHT rot (DESIGN §34.6: Rot heisst „gilt nicht"). */
.board-sichtvermerk { margin: 0; font-size: .82rem; color: var(--muted); }

/* DIE TAFEL – waagerechte Spalten, die IN SICH scrollen. */
.board-tafel {
    display: flex;
    /* GLEICH HOHE SPALTEN. Mit `flex-start` endete jede Spalte dort, wo ihre
       letzte Ticket aufhoert – drei verschieden lange Zettel nebeneinander,
       und der Knopf „Ticket hinzufuegen" sass in jeder Spalte auf einer
       anderen Hoehe. Eine Tafel ist eine Flaeche, keine Reihe von Zetteln. */
    align-items: stretch;
    gap: 1rem;
    overflow-x: auto;
    max-width: 100%;
    position: relative;
    padding-bottom: .5rem;
}

/* ============================================================================
   ⚠ 0213: DIE SPALTEN TEILEN SICH DIE BREITE ZU GLEICHEN TEILEN
   ----------------------------------------------------------------------------
   > „können wir bitte die spalten immer so breit machen, dass sie die gesamte
   > seite füllen, wenn es 3 spalten sind dann auch breiter…" (Nutzer, 25.08.2026)

   Bis 0212 stand hier `flex: 0 0 17rem` – nicht wachsen, nicht schrumpfen. Drei
   Spalten liessen dadurch rechts die halbe Tafel leer.

   `flex: 1 1 0` heisst: gleicher Anteil fuer jede Spalte, unabhaengig vom
   Inhalt. ⚠ DAS IST NICHT DIE „INHALTSABHAENGIGE BREITE", DIE 0209 VERBOTEN HAT:
   die Breite haengt an der ZAHL DER SPALTEN, und die aendert sich waehrend einer
   Ziehgeste nicht (ein Ticket kann seit 0212 nicht mehr als Spalte in der Tafel
   landen – `pull`/`put` nennen ihre Gruppe namentlich). Gemessen in 0213: waehrend
   des Ziehens aendert keine Spalte und kein Ticket ihr Rechteck.
   ⚠ `flex-basis: 0`, NICHT `auto`. Mit `auto` bekaeme die inhaltsreichste Spalte
   den groessten Anteil – genau die inhaltsabhaengige Breite von 0209.

   ⚠ `min-width` IST DIE UNTERGRENZE, UND SIE IST PFLICHT: reicht der Platz nicht,
   schiebt sich die Tafel waagerecht (sie hat `overflow-x: auto`), statt die
   Spalten unlesbar schmal zu machen. 16rem ist knapp unter der alten festen
   Breite von 17rem – bis zu vier Spalten passen damit auf 1440 px nebeneinander,
   ab der fuenften wird gescrollt.
   ⚠ KEIN `max-width`: eine einzelne Spalte darf die ganze Tafel fuellen. Ein
   Deckel liesse rechts wieder Leerraum stehen – genau den Befund von 0213.
   ============================================================================ */
.board-spalte {
    flex: 1 1 0;
    min-width: 16rem;
    /* SÄULE statt Block: die Ticketliste fuellt den Rest der Spalte, und
       „Ticket hinzufuegen" sitzt in JEDER Spalte auf derselben Hoehe – unten.
       Das ist derselbe Gedanke, mit dem §39.1 `align-items: stretch` begruendet
       hat, nur eine Ebene tiefer. Nebenwirkung, die hier die Hauptsache ist:
       die ganze freie Flaeche der Spalte wird zum Ablegeziel. */
    display: flex;
    flex-direction: column;
    /* ⚠ 0218: `--page` STATT `--card` – siehe den Abschnittskopf. Die Spalte ist
       die Flaeche, das Ticket liegt darauf. */
    background: var(--page);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    padding: .6rem;
}

.board-spalte-kopf {
    display: flex;
    align-items: center;
    gap: .35rem;
    flex-wrap: wrap;
    padding-bottom: .5rem;
    border-bottom: 1px solid var(--line);
}
.board-spalte-name {
    margin: 0;
    font-size: .95rem;
    font-weight: 650;
    min-width: 0;
    overflow-wrap: anywhere;
}
.board-spalte-zahl {
    font-size: .78rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}
/* ⚠ HIER STAND BIS 0213 `.board-spalte-kopf .actions { margin-left: auto }`.
   Der Spaltenkopf traegt seit 0214 KEINE Aktionsreihe mehr – er ist reine
   Beschriftung (Name · Zahl · ggf. „schliesst ab"). Alles, was den Aufbau des
   Boards aendert, wohnt im Fenster „Board bearbeiten", Abschnitt „Spalten"
   (DESIGN §39.11). */

/* DER ZIEHGRIFF DES TICKETS (nur er zieht; ein Klick auf den Titel oeffnet das
   Ticketfenster) – dieselbe Regel wie `.menu-grip` beim Menue-Baum.
   ⚠ SEIT 0214 GIBT ES IHN NUR NOCH AM TICKET. Die Spalten werden nicht mehr
   gezogen; ihr Griff im Spaltenkopf ist mit der Spalten-Sortable entfallen. */
.board-griff {
    display: inline-flex;
    align-items: center;
    color: var(--muted);
    cursor: grab;
    flex: 0 0 auto;
}
.board-griff:active { cursor: grabbing; }
.board-griff .icon { width: 1rem; height: 1rem; }
.board-ticket:hover .board-griff { color: var(--accent); }

/* DIE TICKETLISTE. ⚠ `min-height` ist Pflicht, kein Schmuck: eine LEERE Spalte
   waere sonst 0 px hoch und damit kein Ablegeziel – man koennte ein Ticket
   nirgends hineinziehen. */
.board-tickets {
    list-style: none;
    margin: .5rem 0 0;
    padding: 0;
    min-height: 2.5rem;
    /* Fuellt die Spalte (siehe `.board-spalte`). */
    flex: 1 1 auto;
    /* ========================================================================
       ⚠ DER SCROLLBALKEN DARF NICHT ERST BEIM ZIEHEN ENTSTEHEN (Befund 0210)
       ------------------------------------------------------------------------
       Bis 0209 stand `overflow-y: auto` NUR unter `.board-zieht`. Sobald die
       gezogene Ticket in einer Spalte ankam, deren Inhalt dadurch ueber die
       eingefrorene Hoehe hinauswuchs, schaltete Chromium in DIESEM Augenblick
       einen Scrollbalken IN die Spalte. GEMESSEN am Live-Musterverein:
       clientWidth 251 -> 236 px (-15), JEDES Ticket dieser Spalte 15 px schmaler,
       zwei von ihnen dadurch mit einer Zeile mehr im Titel (+21,6 px hoch), und
       die Tickets darunter dadurch bis zu 43 px WEITER nach unten als der reine
       Platzwechsel es erklaert. Genau das sah der Nutzer als „die Bloecke
       springen hin und her" – und Handoff 0209 hat es nicht gesehen, weil dort
       nur die SPALTEN gemessen wurden, nicht die Tickets.

       Die Abhilfe steht hier und nicht unter `.board-zieht`: die Liste ist
       IMMER ein Scrollbehaelter, und `scrollbar-gutter: stable` haelt den Platz
       dafuer STAENDIG frei. Damit aendert sich im Augenblick des Ziehens nichts
       mehr. Auf Systemen mit ueberlagerten Scrollbalken (macOS) kostet das
       nichts (Breite 0), auf den uebrigen kostet es einmalig und gleichmaessig
       15 px – und nie mehr mitten in einer Geste.
       ⚠ `scrollbar-gutter` wirkt NUR an einem Scrollbehaelter. Wer `overflow-y`
       wieder herausnimmt, nimmt die Abhilfe mit heraus.
       ======================================================================== */
    overflow-y: auto;
    scrollbar-gutter: stable;
}

/* ============================================================================
   39.6a DAS TICKET LIEGT AUF DER SPALTE (Nutzer-Wunsch 0218)
   ----------------------------------------------------------------------------
   > „können wir nicht die Karten/Tickets anders gestalten, grau sieht so
   > trostlos aus und designmäßig nicht der große Hit."

   ⚠ DIE ANTWORT IST NICHT FARBE. „Keine Farbe ohne Bedeutung" (DESIGN §1) gilt
   unveraendert – auf einem Ticket traegt ausschliesslich die Liegezeit-Marke
   Farbe, und die ueberschrittene Frist roten Text. Gearbeitet wird mit den fuenf
   Mitteln, die dafuer da sind:
     FLAECHE   die Umkehrung ist getauscht (Spalte `--page`, Ticket `--card`)
     TIEFE     `--shadow-ticket` statt einer harten Kante; der Rahmen wird
               dafuer von `--line` auf `--line-strong` gezogen, damit das Ticket
               auch dort steht, wo Schatten nichts tragen (Dunkelmodus, Druck)
     ABSTAND   Innenpolster .55/.65rem statt .5/.55rem, Abstand zwischen zwei
               Tickets .5rem statt .45rem
     TYPOGRAFIE der Titel traegt .9rem/650 statt .875rem/600
     RUHE      der Fuss wird leiser: feine Linie statt `--line-strong`,
               .74rem statt .76rem

   ⚠ WAS AUSDRUECKLICH NICHT ANGEFASST IST: `--radius` bleibt der Hausradius
   (6px) – eine eigene Rundung nur fuer das Ticket waere ein zweites Mass ohne
   Not. Und die Geometrie des Ziehens ist unberuehrt: ein Schatten aendert kein
   Rechteck (`getBoundingClientRect`), die Ruhe aus 0209/0210/0212/0213 bleibt.
   ============================================================================ */
.board-ticket {
    background: var(--card);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    box-shadow: var(--shadow-ticket);
    padding: .55rem .65rem;
    /* ⚠ BEZUGSRAHMEN FUER DIE `.sr-only`-TEXTE IM TICKET (§39.1). `.sr-only`
       ist `position: absolute`; ohne einen naeheren Bezugsrahmen haengt es an
       der Tafel. Das geht gut (die Tafel ist `position: relative`), aber es ist
       genau die Konstruktion, die in Handoff 0009 die Seite waagerecht aufgezogen
       hat – ein zweiter Riegel kostet nichts. Bis 0212 stand hier „Bezugsrahmen
       fuer den Punkt oben rechts"; den Punkt gibt es nicht mehr. */
    position: relative;
}
.board-ticket + .board-ticket { margin-top: .5rem; }

/* ⚠ 0212: DAS `padding-right` IST WEG, UND ZWAR ERSATZLOS. Es hielt seit 0210
   den Platz fuer den Punkt oben rechts frei; den Punkt gibt es nicht mehr (die
   Liegezeit steht jetzt in der Fusszeile, §39.6). Ein Polster fuer ein Element,
   das nicht mehr existiert, verschmaelert nur jeden Titel um 6,4 px. */
.board-ticket-kopf { display: flex; align-items: flex-start; gap: .35rem; }

/* ============================================================================
   ⚠ 0213: DER TITEL IST EIN KNOPF – EIN KLICK OEFFNET DAS TICKETFENSTER
   ----------------------------------------------------------------------------
   > „durch klick auf die kartentitel sollte sich ein overlay fenster öffnen wo
   > dann die karten informationen zu sehen sind und dort gelöscht oder
   > bearbeitet werden kann." (Nutzer, 25.08.2026)

   Ein `<button>` und kein klickbares `<span>`: er ist damit von selbst mit der
   Tastatur erreichbar (Tab) und mit Leertaste/Enter ausloesbar, ohne `tabindex`,
   ohne `role`, ohne Tastatur-Behelf.
   ⚠ ER STREITET NICHT MIT DEM ZIEHEN. Gezogen wird ausschliesslich am Griff
   (`handle: '[data-ticket-griff]'`), also faengt ein Druck auf den Titel gar kein
   Ziehen an; und ein Ziehen endet nie mit einem Klick auf den Titel, weil ein
   `click` erst am gemeinsamen Vorfahren von `mousedown` und `mouseup` entsteht –
   und das ist bei einer Ziehgeste nie der Knopf. Beides ist in 0213 gemessen.
   Kein `user-select: none`, kein `pointer-events`-Kunststueck. */
.board-ticket-titel {
    display: block;
    flex: 1 1 auto;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    text-align: left;
    font: inherit;
    /* ⚠ 0218: KRAEFTIGER (vorher .875rem/600). Der Titel ist das Erste, was ein
       Mensch auf einem Ticket sucht – er darf sich von der Beschreibung
       darunter deutlicher abheben als um 0,055rem. */
    font-weight: 650;
    font-size: .9rem;
    line-height: 1.35;
    color: var(--ink);
    cursor: pointer;
    min-width: 0;
    overflow-wrap: anywhere;
}
.board-ticket-titel:hover { color: var(--accent); text-decoration: underline; }
.board-ticket-titel:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ⚠ 0213: DIE BESCHREIBUNG IST DER KOERPER DES TICKETS, ALSO TEXTFARBE.
   > „in den karten sind die informationen nicht deutlich zu erkennen ob es
   > systemtext ist oder beschreibung"
   Bis 0212 stand sie in `--muted` – also BLASSER als die Angaben des Systems
   darunter, obwohl sie das Einzige ist, was ein Mensch geschrieben hat. Jetzt
   traegt sie `--ink`, und gedaempft ist nur noch, was die Anwendung selbst
   beisteuert (die Fusszeile, §39.6). */
.board-ticket-text {
    margin: .35rem 0 0;
    font-size: .82rem;
    line-height: 1.45;
    color: var(--ink);
    overflow-wrap: anywhere;
    white-space: pre-line;
}
/* ⚠ MIT `.modal` DAVOR – die Spezifitaetsfalle aus DESIGN §28: `.modal p` ist
   mit Klasse + Element staerker als die blosse Klasse und faerbte die
   Beschreibung im Ticketfenster sonst wieder gedaempft. Kein `!important`. */
.modal .board-ticket-text { margin: 0; font-size: .875rem; color: var(--ink); }
.board-ticket .actions { margin-top: .35rem; justify-content: flex-end; }

/* Icon-Knoepfe ausserhalb einer Tabelle – spiegelt `.actions .icon-btn`
   (dieselbe Notwendigkeit wie bei `.menu-row .icon-btn`). */
.board-spalte .icon-btn {
    display: inline-grid;
    place-items: center;
    width: 1.95rem;
    height: 1.95rem;
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    background: none;
    color: var(--muted);
    cursor: pointer;
}
.board-spalte .icon-btn:hover:not(:disabled) { background: var(--hover); color: var(--ink); }
.board-spalte .icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.board-spalte .icon-btn:disabled { opacity: .35; cursor: default; }
/* ⚠ HIER STANDEN BIS 0213 ZWEI `.icon-danger`-REGELN. In einer Spalte gibt es
   seit 0213 (Ticket) bzw. 0214 (Spaltenkopf) keinen Muelleimer mehr – geloescht
   wird in einem Fenster, mit einem beschrifteten roten Knopf. Wer eine
   `.icon-danger` in die Tafel zurueckholt, braucht sie wieder. */

/* „Ticket hinzufuegen" – ein leiser Knopf ueber die volle Spaltenbreite, damit
   die Stelle, an der etwas entsteht, dort liegt, wo es entsteht. */
.board-ticket-neu {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .3rem;
    width: 100%;
    margin-top: .5rem;
    padding: .4rem;
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius);
    background: none;
    color: var(--muted);
    font: inherit;
    font-size: .82rem;
    cursor: pointer;
}
/* ⚠ 0218: DER HOVER NIMMT `--card`, NICHT `--hover`. Die Spalte ist seit 0218
   selbst `--page`; `--hover` (#f0f2f2) laege darauf bei 1,03:1 und waere kein
   sichtbarer Zustand mehr. */
.board-ticket-neu:hover { background: var(--card); color: var(--ink); }
.board-ticket-neu:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.board-ticket-neu .icon { width: .95rem; height: .95rem; }

/* Der Leerfall – eine Spalte ohne Ticket, ein Board ohne Spalte. */
.board-leer { margin: .5rem 0 0; font-size: .82rem; color: var(--muted); text-align: center; }

/* Zieh-Zustaende (SortableJS, `public/js/aufgaben-board.js`). */
/* ⚠ DER GHOST IST DER PLATZHALTER. Mit `forceFallback` bleibt das GEZOGENE
   Element im Fluss stehen (nur gedaempft) und die Kopie folgt dem Zeiger – die
   Luecke hat also von selbst genau die Groesse des Tickets. Wer hier `display:
   none` einsetzt, nimmt den Platzhalter weg, und alles springt. */
.board-ghost { opacity: .35; }
.board-fallback { box-shadow: 0 6px 18px rgba(0, 0, 0, .14); }

/* ============================================================================
   39.5 BEIM ZIEHEN BEWEGT SICH NICHTS (Nutzer-Befund 0209, korrigiert 0210,
        Zwischenraum 0212)
   ----------------------------------------------------------------------------
   > „wenn man Tickets verschieben moechte, springen auch die Bloecke hin und
   > her, das macht es etwas verwirrend. Die Bloecke sollen sich nicht bewegen."

   Die Breite war nie das Problem – die steht seit 0208 fest. Es war die HOEHE:
   `align-items: stretch` macht alle Spalten so hoch wie die laengste, und beim
   Ziehen einem Ticket WANDERT sie im DOM sofort mit. Verlaesst sie die laengste
   Spalte, schrumpft die ganze Reihe; kommt sie in einer anderen an, waechst sie.
   Und weil damit auch die SEITE kuerzer oder laenger wird, kam und ging der
   Seiten-Scrollbalken – und die Tafel rutschte zusaetzlich waagerecht.

   Deshalb friert `aufgaben-board.js` beim Anfassen die gemessene Hoehe der Tafel
   ein (`style.height`) und setzt diese Klasse. Solange sie steht, kann keine
   Spalte hoeher oder niedriger werden; die Ticketliste scrollt notfalls in sich,
   statt die Spalte aufzublaehen.
   ⚠ `min-height: 0` IST PFLICHT: ohne sie waechst ein Flex-Kind ueber seinen
   Container hinaus, statt zu scrollen – die Spalte liefe dann doch aus.

   ⚠ 0212: DER ZWEITE TEIL DER RUHE STEHT NICHT IM STYLESHEET, SONDERN IN DER
   BRUECKE. Der Zwischenraum zwischen zwei Spalten (37,2 px: Spaltenpolster +
   Tafel-Luecke + Spaltenpolster) liegt ueber KEINER Ticketliste. Weil beide
   Sortables `put: true` trugen, nahm dort die TAFEL das gezogene Ticket an und
   haengte sie als vierte Spalte in die Reihe – die Nachbarspalten sprangen
   gemessen um +224 px nach rechts. `pull`/`put` nennen jetzt namentlich die
   erlaubte Gruppe (`public/js/aufgaben-board.js`); im Spalt bleibt damit die
   zuletzt gueltige Einfuegestelle stehen. GEOMETRIE HIER NICHT ANFASSEN: den
   Spalt einer Spalte zuzuschlagen haette das `scrollbar-gutter` von 0210
   beruehrt und den Umschlagpunkt nur verlegt (DESIGN §39.5).

   ⚠ 0210: DAS `overflow-y: auto` STAND FRUEHER HIER – UND GENAU DAS WAR DER
   ZWEITE, GROESSERE TEIL DES GEMELDETEN FEHLERS. Es schaltete den Scrollbalken
   erst im Augenblick des Ziehens zu und verschob damit den ganzen Spalteninhalt
   um die Balkenbreite. Es steht jetzt in der Grundregel `.board-tickets`, samt
   `scrollbar-gutter: stable`. Die Begruendung mit den Messwerten steht dort;
   wer es hierher zurueckschiebt, holt den Fehler zurueck.
   ========================================================================== */
.board-tafel.board-zieht .board-tickets {
    min-height: 0;
}

/* ============================================================================
   39.6 DAS TICKET MIT SUBSTANZ (Handoff 0209, Farbe auf einen Punkt
        zusammengezogen 0210, Punkt durch die farbige LIEGEZEIT ersetzt 0212)
   ========================================================================== */

/* DIE NUMMER – kurz, im Verein eindeutig, nie wiederverwendet. Sie steht vor dem
   Titel und bleibt ruhig: sie ist eine Kennung, keine Aussage.
   ⚠ 0213: SIE TRAEGT JETZT EINEN EIGENEN RAHMEN. Der Titel ist seit 0213 ein
   Knopf und wird beim Ueberfahren unterstrichen; stuende die Nummer weiterhin
   nur als etwas kleinerer Text davor, laese sie sich als Anfang der Ueberschrift
   lesen. Der duenne Rahmen (`--line-strong`, keine Fuellung, keine neue Farbe)
   sagt ohne ein Wort: das ist eine Kennung, nicht der Anfang des Titels.
   ⚠ 0218: SIE IST EIN EIGENES ELEMENT GEWORDEN. Auf der weissen Ticketflaeche
   trug der blosse Rahmen zu wenig; jetzt liegt die Nummer auf `--page`, also
   auf demselben Ton, den die Spalte darunter hat – eingelassen statt aufgesetzt.
   ⚠ KEINE NEUE FARBE, KEIN AKZENT: die Nummer ist eine Kennung, keine Aussage.
   Wer sie einfaerbt, macht aus einer Fundstelle eine Warnung. */
.board-ticket-nr {
    flex: 0 0 auto;
    padding: .05rem .3rem;
    border: 1px solid var(--line);
    border-radius: 4px;
    background: var(--page);
    font-size: .72rem;
    font-weight: 600;
    line-height: 1.5;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* ============================================================================
   ⚠ 0213: DIE FUSSZEILE IST DER ABGESETZTE FUSS – JEDE ANGABE MIT IHREM NAMEN
   ----------------------------------------------------------------------------
   > „in den karten sind die informationen nicht deutlich zu erkennen ob es
   > systemtext ist oder beschreibung, dies sollten wir etwas besser anpassen."

   Bis 0212 standen Beschreibung, Person, Frist und Liegezeit untereinander und
   unterschieden sich nur durch die Schriftfarbe – und ausgerechnet die
   Beschreibung war die blasseste. Jetzt gilt:
     - die BESCHREIBUNG ist der Koerper des Tickets (`--ink`, siehe oben),
     - die ANGABEN DER ANWENDUNG stehen unter einer feinen Trennlinie,
     - und JEDE traegt ihren Namen davor („Zuständig:", „Fällig:", „Liegt seit:").
   Kein nacktes Datum, kein nackter Name: „05.09.2026" allein sagt nicht, ob das
   ein Fristende oder ein Anlagedatum ist.

   ⚠ NAME GEDAEMPFT, WERT IN TEXTFARBE – das ist die ganze Mechanik. `.board-
   ticket-angabe` faerbt den Wert (`--ink`), `.board-ticket-name` faerbt den Namen
   zurueck auf `--muted`. Die ueberschrittene Frist sticht beides und faerbt
   Name UND Wert rot; dafuer nennt sie den Namen ausdruecklich mit
   (`.board-ticket-frist.ist-ueberfaellig .board-ticket-name`), sonst bliebe das
   Wort „Fällig:" als einziges graues Stueck in einer roten Angabe stehen.
   ============================================================================ */
.board-ticket-fuss {
    display: flex;
    flex-wrap: wrap;
    /* ⚠ 0218: DER FUSS IST LEISER GEWORDEN. Die Trennlinie kommt von
       `--line-strong` auf `--line`, die Schrift von .76rem auf .74rem, das
       Polster darueber waechst. Die Angaben der Anwendung sollen unter dem
       Titel STEHEN, nicht mit ihm konkurrieren – die Trennung selbst (0213:
       jede Angabe mit ihrem Namen davor) bleibt unangetastet. */
    gap: .2rem .55rem;
    margin: .5rem 0 0;
    padding-top: .45rem;
    border-top: 1px solid var(--line);
    font-size: .74rem;
    color: var(--muted);
}
.board-ticket-angabe {
    display: inline-flex;
    align-items: baseline;
    gap: .25rem;
    color: var(--ink);
}
.board-ticket-name { color: var(--muted); font-weight: 400; }
.board-ticket-person { font-weight: 600; color: var(--ink); }

/* ============================================================================
   DIE LIEGEZEIT IST DIE FARBE – KEIN PUNKT DANEBEN (Nutzer-Befund 0212)
   ----------------------------------------------------------------------------
   > „den farbpunkt finde ich jetzt nicht gelungen, es ist zu klein und die farbe
   > nicht gut zu sehen, vielleicht machen wir das anders, die zeit dran steht
   > und das eine andere farbe bekommt, z. B. 1 h, 6 h, 1 d, 1 w, usw…"

   DREI ANLAEUFE, EINE LEHRE. 0209 faerbte das GANZE Ticket (zu viel: eine Flaeche
   sagt im Haus „dieser Datensatz gilt nicht"). 0210 zog das auf einen 8-px-Punkt
   zusammen (zu wenig: 64 px² stumme Farbe, die niemand deutet). 0212 faerbt
   DIE ANGABE SELBST – rund 640 px², und die Farbe liegt auf etwas, das ohnehin
   gelesen wird. ⚠ Damit ist Farbe hier zum ersten Mal nicht mehr die einzige
   Aussage, sondern nur noch der Ton einer Aussage, die als Text dasteht
   (DESIGN §0/§34.6a).

   ⚠ SIE STEHT IN DER FUSSZEILE, NICHT IM TICKETKOPF. Im Kopf haette sie dem
   Titel Breite genommen und ihn zum Umbrechen gebracht – 0210 hat teuer gelernt,
   dass ein umbrechender Titel ein Ticket um eine ganze Zeile wachsen laesst.
   In der Fusszeile steht sie neben Person und Frist, wo ohnehin die Angaben
   ueber den Vorgang stehen.

   ⚠ DIE VIER STUFEN STEHEN IN `App\Aufgaben\Ticketalter::SCHWELLEN` UND NUR
   DORT (0/14/30/60 Tage). Hier steht ausschliesslich, wie sie aussehen.

   ⚠ DIE FARBLEITER, GEMESSEN (WCAG-Kontrast, heller Modus / dunkler Modus),
   MIT 0213 AUSEINANDERGEZOGEN – die Stufen 0/1/2 waren mit 1,31 und 1,29
   nebeneinander praktisch nicht zu unterscheiden:
     Stufe 0  --off-bg / --muted    Text  3,96 : 4,52   Flaeche zum Ticket 1,07 : 1,28
     Stufe 1  --alter-1 / --ink     Text  8,17 : 7,28   Flaeche zum Ticket 1,88 : 2,02
     Stufe 2  --alter-2 / --ink     Text  4,64 : 4,62   Flaeche zum Ticket 3,31 : 3,19
     Stufe 3  --danger-ink / --on-danger   Text  6,87 : 7,16   Flaeche zum Ticket 6,87 : (dunkel gerechnet)
     Nachbarstufen (Flaeche gegen Flaeche): 1,76 / 1,76 / 1,90 (hell; vor 0213
     1,31 / 1,29 / 3,22, vor 0217 endete sie mit 1,76) und 1,58 / 1,58 / 2,19
     (dunkel).
   ⚠ Stufe 0 ist ABSICHTLICH das leiseste Paar des Hauses (`--off-bg`/`--muted`,
   dieselbe Kombination wie `.tag-quiet` und `.badge-inaktiv`) – „unter zwei
   Wochen" ist keine Warnung, und die Zeit steht trotzdem da.
   ⚠⚠ NACHTRAG 25.08.2026 (Handoff 0217): HIER STAND „KEIN ROT". Die Leiter
   endete in kraeftigem Bernstein, und Rot war auf dem Ticket allein der
   ueberschrittenen Frist vorbehalten. Der Nutzer hat das am 25.08.2026
   ausdruecklich umgedreht: „die farben finde ich nicht von ‚liegt seit …' —
   können wir das doch rot machen." Seither endet die Leiter in ROT, und Rot
   heisst auf dem Ticket „braucht Aufmerksamkeit" – getragen von ZWEI benannten
   Dingen: der ueberschrittenen Frist und der langen Liegezeit. Beide stehen
   nebeneinander im Fuss und sind am TEXT zu unterscheiden („12 Wochen" gegen
   „Fällig: 18.08.2026 (überfällig)"). Nachgetragen in DESIGN §0 und §34.6a.
   ============================================================================ */
.board-ticket-liegezeit {
    display: inline-block;
    padding: .05rem .35rem;
    border-radius: 4px;
    background: var(--off-bg);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.board-liegezeit-1 { background: var(--alter-1); color: var(--ink); }
.board-liegezeit-2 { background: var(--alter-2); color: var(--ink); }

/* ⚠⚠ DIE LEITER ENDET SEIT DEM 25.08.2026 IN ROT – AUF AUSDRUECKLICHEN WUNSCH
   DES NUTZERS: „die farben finde ich nicht von ‚liegt seit …' — können wir das
   doch rot machen." Das aendert eine der sechs bewachten Regeln aus DESIGN §0;
   sie ist deshalb NACHGETRAGEN worden, nicht umgangen (§0 und §34.6a, datierter
   Nachtrag): Rot traegt jetzt ZWEI benannte Faelle – die ueberschrittene Frist
   UND die lange Liegezeit. Gemeinsame Aussage: „braucht Aufmerksamkeit".
   ⚠ WAS DABEI NICHT FAELLT: Farbe steht nie allein. Neben der roten Marke steht
   die Zeit im Klartext („12 Wochen", voller Wortlaut im `title`), neben der
   roten Frist das Datum mit „(überfällig)".
   ⚠ KEINE NEUE FARBE: genommen wird die vorhandene Gefahr-Familie
   (`--danger-ink` auf `--on-danger`) – im hellen Modus #a33232 mit weisser
   Schrift, im dunklen #e08b8b mit dunkler. Genau deshalb steht hier kein
   `--alter-3` mehr; das Token ist mit dieser Aenderung entfallen.
   ⚠ GEMESSEN am Live-Musterverein (heller Modus, 0217): Text auf Flaeche
   6,87:1, Nachbarkontrast Stufe 2 -> 3 = 1,90:1 (vorher 1,76:1) – die Leiter
   ist also nicht enger geworden. Die Werte gegen die TICKETFLAECHE sind mit
   0218 neu, weil das Ticket seither weiss ist (§39.6a); sie stehen in
   DESIGN §34.6a.

   ⚠⚠ 0218: DIESE REGEL GREIFT NICHT, SOLANGE EINE FRIST UEBERSCHRITTEN IST.
   Zwei rote Marken untereinander auf demselben Ticket sind keine doppelte
   Dringlichkeit, sondern ein unlesbares Ticket. Entschieden wird das NICHT
   hier, sondern im Dienst: {@see App\Aufgaben\Ticketalter::stufeAmTicket()}
   gibt in diesem Fall Stufe 2 zurueck, das Ticket traegt dann
   `.board-liegezeit-2`. ⚠ WER DAS IM STYLESHEET NACHBAUEN WILL (`:has()`),
   baut eine zweite Wahrheit – die Farbe wird im Dienst gerechnet wie alles
   andere auf der Tafel (DESIGN §39.3). */
.board-liegezeit-3 { background: var(--danger-ink); color: var(--on-danger); }

/* ⚠ DER EINZIGE ROTE FALL AUF EINEM TICKET: DIE FRIST IST ÜBERSCHRITTEN.
   Rot heisst im Haus „gilt nicht / hier stimmt etwas nicht" (DESIGN §34.6) – und
   ein Ticket, dessen Termin verstrichen ist, ist genau das. Seit 0212 traegt sie
   es NUR NOCH im Klartext („ueberfaellig seit 21.08.2026", rot und halbfett):
   der rote Punkt ist mit demselben Befund gefallen wie der bernsteinfarbene.
   Der Klartext steht bei 6,28:1 auf der Ticketflaeche und ist damit sichtbarer
   als der 8-px-Punkt je war.
   ⚠ 0213 HAT DIESE FRAGE ENTSCHIEDEN (Vorlage aus 0212, Variante A): die Frist
   bekommt KEINE eigene rote Marke neben der Liegezeit-Marke. Sie bleibt roter
   Klartext – nur jetzt als BENANNTE Angabe im Fuss („Fällig: 21.08.2026
   (überfällig)"). Zwei gefuellte Marken nebeneinander waeren wieder die dritte
   Aussage, die §34.6a verhindern will. */
.board-ticket-frist.ist-ueberfaellig,
.board-ticket-frist.ist-ueberfaellig .board-ticket-name { color: var(--danger-ink); font-weight: 600; }

/* ============================================================================
   39.6b DIE SPALTENLISTE IN „Board bearbeiten" (Nutzer-Wunsch 0218)
   ----------------------------------------------------------------------------
   > „Board bearbeiten kann man die Reihenfolge der Spalten nicht ändern. Dies
   > sollte aber möglich sein."

   Sie GING seit 0214 – aber zwei Ebenen tief (Spalte anklicken → Stellenwahl →
   Speichern). Jetzt traegt jede Zeile zwei BESCHRIFTETE Knoepfe „nach links"
   und „nach rechts"; die Stellenwahl ist dafuer entfallen (DESIGN §39.11).

   ⚠ EINE LISTE, KEINE `.data`-TABELLE: DESIGN §5 verlangt dort Icon-
   Zeilenaktionen – also genau das, was der Nutzer 0214 abbestellt hat.
   ⚠ DIE ZEILE LIEGT AUF `--page` IM WEISSEN `.modal` – dieselbe gedaempfte
   Flaeche wie die zwei Bloecke im Ticketfenster (§39.12), kein neues Bauteil.
   ⚠ KEINE FESTE HOEHE, KEIN `overflow`: ein Board mit zwoelf Spalten soll die
   Liste laenger machen, nicht abschneiden – das Fenster scrollt in sich
   (DESIGN §3). */
.board-spaltenliste {
    list-style: none;
    margin: 0 0 .75rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .35rem;
}
.board-spaltenzeile {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem;
    padding: .35rem .5rem;
    background: var(--page);
    border-radius: var(--radius);
}
.board-spaltenstelle {
    flex: 0 0 auto;
    min-width: 1.2rem;
    font-size: .8rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}
/* Der Name nimmt den Platz, damit die zwei Schiebe-Knoepfe in jeder Zeile auf
   derselben Hoehe UND an derselben Stelle stehen. */
.board-spaltenname { flex: 1 1 8rem; min-width: 0; justify-content: flex-start; text-align: left; }
/* „ganz links"/„ganz rechts" als Klartext – damit niemand mitzaehlen muss und
   niemand den Satz „oben ist links" braucht. */
.board-spaltenrand { flex: 0 0 auto; font-size: .76rem; color: var(--muted); }
/* ⚠ `flex-wrap: wrap` – dieselbe Hausform wie am Fenster-Fuss (Handoff 0231).
   Auch das hier ist eine Knopfreihe INNERHALB eines Fensters (`.modal`, 30rem),
   und auch hier tragen die Knoepfe `white-space: nowrap`. Auf einem 320-px-Schirm
   bleiben von der Fensterbreite nach den Polstern von `.modal` und
   `.board-spaltenzeile` rund 205 px – genau so breit sind die zwei Knoepfe
   zusammen. Ohne Umbruch waere das der Befund vom 29.08.2026 an einer zweiten
   Stelle. */
.board-spaltenschieber { flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: .35rem; }

/* Person auswaehlen + „Hinzufuegen" nebeneinander – im Anlegen-Dialog und im
   Zugangs-Fenster dieselbe Zeile. */
.board-personenwahl {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
}
.board-personenwahl select { flex: 1 1 12rem; min-width: 0; }

/* ============================================================================
   39.12 DER VERLAUF UND DIE ANHÄNGE AM TICKET (Handoff 0215, Feature 0022 /
   ADR-0040; ÜBERARBEITET 0216 nach Nutzer-Befund)
   ============================================================================
   ⚠ KEINE CHAT-OPTIK. Feature 0022 verlangt ausdrücklich die vorhandenen
   Bauteile des Hauses statt einer eigenständigen Nachrichten-Ansicht: keine
   Sprechblasen, keine Avatare, keine Wechselseiten, KEINE NEUE FARBE und KEIN
   NEUES ICON. Was hier steht, ist eine Liste mit einer Kopfzeile je Eintrag –
   dieselbe Sprache wie `.detail-list` daneben.

   ⚠ DAS FENSTER SCROLLT IN SICH, NICHT DIE SEITE (DESIGN §3). Ein Ticket mit
   dreißig Zwischenständen darf das `.modal` nicht über den Bildschirm hinaus
   wachsen lassen – deshalb `max-height` + `overflow-y` an den beiden Listen und
   nicht am Fenster.

   ============================================================================
   ⚠⚠ NACHTRAG 0216: DREI SACHEN WAREN „IN DER ERSCHEINUNG UNSCHÖN"
   ============================================================================
   > „die auf der karte sich befinden verlauf und datei upload finde ich etwas
   > in der erscheinung etwas unschön. bitte etwas schöner designen,
   > übersichtlicher und klarer." (Nutzer, 25.08.2026)

   1. EIN EINGABEBEREICH IST EIN BLOCK, KEINE LOSE ZEILE. Die Hochladefläche und
      das Verlaufs-Formular liegen auf einer gedämpften Fläche (`--page` im
      weißen `.modal`) statt frei im Abschnitt zu schweben. EINE FLÄCHE STATT
      EINER KANTE – kein Rahmen, keine neue Farbe: die Füllung allein grenzt ab,
      und das ist die ruhigere von zwei Möglichkeiten (dieselbe Lehre wie bei
      der Ticketfläche, §39.6).
   2. EINE LISTENZEILE HAT EINEN KOPF UND EINEN RAND. Beim Anhang steht der NAME
      als Hauptsache links, Art/Größe/Herkunft LEISE darunter, die Aktionen
      rechts (`.actions.actions-icons`, das vorhandene Bauteil aus §5). Beim
      Zwischenstand ist es umgekehrt zur bisherigen Gewichtung: Verfasser und
      Zeit sind LEISE, der TEXT ist laut.
   3. EINE LÖSCHSPUR IST KEIN BEITRAG OHNE TEXT. Sie trägt die stille Marke
      `.tag-quiet` (§5) – ein Wort, kein neues Bauteil, keine neue Farbe. */

/* --------------------------------------------------------------- Verlauf */

/* ⚠ FELD UND KNOPF GEHÖREN SICHTBAR ZUSAMMEN (0216). Vorher stand „Eintragen"
   frei unter dem Feldhinweis und sah aus wie eine Aktion des ganzen Fensters. */
.board-verlauf-form,
.board-anhang-flaeche {
    background: var(--page);
    border-radius: var(--radius);
    padding: .7rem .8rem;
}

.board-verlauf-form { margin-bottom: 1rem; }
.board-verlauf-form .form-field { margin-bottom: 0; }

/* Hinweis links, Knopf rechts – eine Fußzeile des Blocks, kein eigener Absatz. */
.board-verlauf-absenden {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: .8rem;
    margin-top: .5rem;
    flex-wrap: wrap;
}
.board-verlauf-absenden .field-hint { margin: 0; flex: 1 1 14rem; }
.board-verlauf-absenden .btn { flex: 0 0 auto; }

.board-verlauf {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 22rem;
    overflow-y: auto;
    scrollbar-gutter: stable;
    /* ⚠ 0217: DIE BEITRÄGE STEHEN AUSEINANDER. Vorher lagen sie luecken- und
       fugenlos untereinander (gemessen: Abstand 0 px zwischen JEDEM Paar), nur
       getrennt von einer Haarlinie in `--line` – auf Weiss ein Kontrast von
       1,15:1. Der Nutzer-Befund dazu, woertlich: „mache in den karten den
       verlauf etwas deutlicher, ich meine damit die einzelnen nachrichten
       voneinander zu unterscheiden." */
    display: flex;
    flex-direction: column;
    gap: .45rem;
}

/* ⚠ EIN BEITRAG IST EINE EIGENE FLÄCHE, KEINE ZEILE ZWISCHEN ZWEI LINIEN
   (0217). Dieselbe gedaempfte Fuellung wie das Eingabefeld darueber und die
   Hochladeflaeche (`--page` im weissen `.modal`) – KEINE neue Farbe, KEIN neues
   Bauteil, nur das Muster, das 0216 in diesem Fenster schon zweimal benutzt:
   „keine Kante, kein Rahmen – die Fuellung allein grenzt ab".
   ⚠ DIE HAARLINIE IST DAMIT WEG. Zwei Trennmittel nebeneinander (Fuge UND
   Linie) waeren doppelt gemoppelt; die Fuge ist das staerkere. */
.board-verlauf-eintrag {
    padding: .55rem .7rem;
    border-top: 0;
    border-radius: var(--radius);
    background: var(--page);
}

/* ⚠ DIE KOPFZEILE IST LEISE (0216). Sie war bis 0215 in Textfarbe und halbfett
   und damit fast so laut wie der Eintrag selbst – „die Gewichtung ist zu flach"
   (Nutzer). Wer geschrieben hat und wann, ist die Nebenauskunft; WAS dasteht,
   ist die Hauptsache. */
/* ⚠ ZWEITEILIGE SELEKTOREN, UND DAS IST KEINE ZIERDE (die Falle aus §28/§39.3):
   `.modal p` ist mit KLASSE + ELEMENT spezifischer als eine blosse Klasse und
   gewinnt sonst mit `color: var(--muted); font-size: .88rem; margin: 0 0 1rem`.
   ⚠ GENAU DARAN LAG DIE „ZU FLACHE GEWICHTUNG", die der Nutzer am 25.08.2026
   beanstandet hat: der Text eines Zwischenstandes stand seit 0215 in `--ink`
   IM STYLESHEET und trotzdem GEDAEMPFT AUF DEM SCHIRM (gemessen:
   rgb(111,118,123) statt rgb(27,30,32)). Kein `!important` – ein Selektor mehr.
   Dieselbe Loesung steht schon bei `.modal .board-ticket-text` (§39.9). */
.modal .board-verlauf-kopf {
    display: flex;
    align-items: center;
    gap: .4rem;
    margin: 0 0 .25rem;
    font-size: .73rem;
    color: var(--muted);
}

.board-verlauf-person { font-weight: 600; color: var(--muted); }
.board-verlauf-zeit { color: var(--muted); }

/* ⚠ 0223 – DER BEARBEITUNGSVERMERK („bearbeitet am 26.08.2026 um 14:12 Uhr").
   Er ist der Preis dafür, dass es das Bearbeiten überhaupt gibt (Nutzer,
   26.08.2026); ohne ihn wäre die Begründung von Option C zurück, die
   ausdrücklich am Wort UNBEMERKT hing.
   ⚠ KEINE NEUE FARBE UND KEIN NEUES BAUTEIL: derselbe Ton wie „wer und wann"
   daneben (`--muted`) – der Vermerk ist eine Nebenauskunft der Anwendung und
   gehört genau dahin, wo im Haus die Nebenauskunft steht (§39.6). Die KURSIVE
   ist der einzige Unterschied zur Zeitangabe: sie ist dieselbe Sprache, in der
   die Lösch-Spur spricht – „hier ist nachträglich etwas passiert".
   ⚠ ER WIRD NICHT VERSTECKT. Kein `title`, kein ⓘ, kein Aufklappen: was andere
   Menschen angeht, steht offen da (dieselbe Trennlinie wie beim Anhang-Satz,
   §39.12). */
.board-verlauf-bearbeitet { color: var(--muted); font-style: italic; }

/* Der Mülleimer rutscht ans Ende der Kopfzeile – er gehört zum Eintrag, nicht
   zur Zeitangabe. */
/* ⚠⚠ EIN `.icon-btn` BRAUCHT IN JEDEM NEUEN ZUSAMMENHANG SEINE EIGENE REGEL –
   `.icon-btn` ist im Haus IMMER kontextgebunden definiert (`.actions .icon-btn`,
   `.menu-row .icon-btn`, `.board-spalte .icon-btn`, §39.2). SEIT 0215 STAND DER
   MUELLEIMER DES VERLAUFS OHNE JEDE REGEL DA und trug deshalb das nackte
   Browser-Knopfbild: grauer Kasten, Rahmen, Fuellung – mitten in einer Liste aus
   Haarlinien (auf den Bildern von 0215 zu sehen, beim Bau von 0216 gefunden).
   Diese Regel spiegelt `.board-spalte .icon-btn` Zeile fuer Zeile.
   ⚠ `.icon-danger` MUSS hier mit, sonst ist der Knopf grau statt rot: die
   Regeln dafuer haengen an `.actions .icon-btn.icon-danger` und greifen hier
   nicht. Rot ist an DIESER Stelle richtig – es geht wirklich etwas verloren
   (der Text des Eintrags), anders als beim Abnehmen eines Anhangs. */
.modal .board-verlauf-kopf .icon-btn {
    display: inline-grid;
    place-items: center;
    width: 1.95rem;
    height: 1.95rem;
    margin-left: auto;
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    background: none;
    color: var(--muted);
    cursor: pointer;
}
/* ⚠ 0223 – ZWEI KNÖPFE, EIN `margin-left: auto`. Seit der Stift danebensteht,
   trügen BEIDE das `auto` von oben – und CSS verteilt freien Raum GLEICHMÄSSIG
   auf alle `auto`-Ränder: die zwei Knöpfe stünden auseinandergezogen, einer in
   der Mitte der Kopfzeile. Der zweite bekommt deshalb `0`; der erste schiebt die
   Gruppe als Ganzes nach rechts. */
.modal .board-verlauf-kopf .icon-btn + .icon-btn { margin-left: 0; }
.modal .board-verlauf-kopf .icon-btn:hover { background: var(--hover); color: var(--ink); }
.modal .board-verlauf-kopf .icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.modal .board-verlauf-kopf .icon-btn.icon-danger { color: var(--danger-ink); }
.modal .board-verlauf-kopf .icon-btn.icon-danger:hover { background: var(--danger-bg); color: var(--danger-ink); }

/* ⚠⚠ 0224 – BEIDE KNOEPFE SIND AUS, SOLANGE IRGENDWO EIN EINTRAG BEARBEITET
   WIRD. Das ist die Regel „immer nur einer zugleich": ein zweites Feld
   verdraengte das erste MITSAMT der ungespeicherten Eingabe.
   ⚠ SIE BLEIBEN IM MARKUP STEHEN und werden nicht ausgeblendet – die Kopfzeile
   ist eine Flex-Zeile, ihre Hoehe kommt von diesen 1,95 rem. Ohne sie schrumpfte
   sie auf die Zeilenhoehe von 0,73 rem, und der halbe Verlauf ruckte hoch. Genau
   das soll beim Umschalten NICHT passieren.
   ⚠ KEIN `not-allowed`: der Knopf ist nicht verboten, er ist gerade nur nicht
   dran. Der `title` sagt, was zuerst zu tun ist. */
.modal .board-verlauf-kopf .icon-btn:disabled { opacity: .35; cursor: default; }
.modal .board-verlauf-kopf .icon-btn:disabled:hover { background: none; color: var(--muted); }
.modal .board-verlauf-kopf .icon-btn.icon-danger:disabled:hover { background: none; color: var(--danger-ink); }

/* ⚠ DER TEXT IST DIE HAUPTSACHE: Textfarbe, eine Spur größer als die Kopfzeile
   darüber – dasselbe Verhältnis wie zwischen `.board-ticket-text` und dem
   Ticketfuß (§39.6). */
.modal .board-verlauf-text {
    margin: 0;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--ink);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* ⚠⚠ 0224 – DAS FELD AN ORT UND STELLE. Es steht ANSTELLE von
   `.modal .board-verlauf-text`, im selben Eintrag, unter derselben Kopfzeile:

     > „die Bearbeitungsfunktion ist im Prinzip gut, aber ich moechte nicht, dass
     > sich in dem Moment ein eigenes Fenster oeffnet, sondern der Text zu einem
     > Textfeld umwandelt und direkt dort bearbeitet bzw. Aenderungen vorgenommen
     > werden koennen." (Nutzer, 27.08.2026)

   ⚠ DAS FELD SPRICHT IN DERSELBEN SCHRIFT WIE DER TEXT, DEN ES ERSETZT (.9rem /
   1.5, wie `.modal .board-verlauf-text`) – die Grundregel der Steuerelemente
   setzt .9rem/1.2, und der Zeilenabstand allein schoebe den Verlauf sonst weiter
   auseinander, als noetig ist.
   ⚠ UND `min-height` WIRD ZURUECKGENOMMEN. Die Hausregel gibt jedem `textarea`
   `min-height: calc(var(--h-control) * 2.4)` = rund 91 px; das ist richtig fuer
   ein Formular und falsch in einer Liste kurzer Eintraege, wo jede ueberzaehlige
   Zeile die Eintraege darunter nach unten schiebt. Zwei Zeilen sind der
   Ausgangspunkt, `resize: vertical` aus der Grundregel bleibt – wer mehr
   braucht, zieht das Feld auf. KEINE neue Farbe, KEIN neues Bauteil: es ist das
   Steuerelement des Hauses, nur nicht kuenstlich hoch.
   ⚠ WAS SICH TROTZDEM BEWEGT, UND WARUM ES NICHT ZU VERMEIDEN IST: Feld und
   Knopfzeile brauchen mehr Hoehe als eine Zeile Text. Die Eintraege OBERHALB
   stehen pixelgenau still (gemessen, Handoff 0224); die darunter ruecken um
   genau diese Differenz nach. Das ist die Folge davon, dass der Text sich an
   seinem Platz in ein Feld verwandelt – und nicht ein Fenster darueber legt. */
.board-verlauf-feld { margin: 0; }

.board-verlauf-feld textarea {
    min-height: 0;
    font-size: .9rem;
    line-height: 1.5;
}

/* Knopfzeile des Feldes: das ⓘ ganz links, „Abbrechen" und „Speichern" rechts.
   ⚠ `.feld-kopf` (§7) bringt die Flex-Zeile mit, `.feld-hilfe` ist der VORFAHR,
   den `.feld-hilfe .schwebe-hilfe` braucht (§27.2a) – KEIN vierter Selektor fuer
   das schwebende Blatt, sonst gaebe es einen zweiten Ort, an dem dieselbe Falle
   repariert werden muesste (Handoff 0178).
   ⚠ `flex-wrap`, DAMIT DIE ZWEI KNOEPFE AUF SCHMALEM SCHIRM UMBRECHEN statt das
   Feld daneben zu quetschen. */
.board-verlauf-feld-aktionen {
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: .4rem;
    margin-top: .45rem;
}
.board-verlauf-feld-aktionen .info-btn { margin-right: auto; margin-left: 0; }

/* ⚠ DIE SPUR IST GEDÄMPFT UND KURSIV, ABER NICHT VERSTECKT (Feature 0022,
   Option C). Sie ist Teil des Verlaufs und steht an ihrer Stelle in der
   Zeitfolge; wer sie ausblendet oder ans Ende schiebt, hat den ganzen Zweck von
   Option C erledigt. KEINE eigene Farbe – `--muted` ist der vorhandene Ton für
   „Nebenauskunft".
   ⚠ SEIT 0216 TRÄGT SIE DIE STILLE MARKE `.tag-quiet` (§5). Ohne sie las sie
   sich wie ein Eintrag, dem der Text fehlt – genau der Nutzer-Befund. Die Marke
   ist ein vorhandenes Bauteil; ihr `margin-left` aus §5 wird hier zurückgesetzt,
   weil sie am ZEILENANFANG steht und nicht hinter einem Wort. */
/* ⚠ UND DIE SPUR BEKOMMT KEINE FLÄCHE (0217) – genau daran erkennt man sie
   jetzt auf den ersten Blick als etwas ANDERES als einen Beitrag: die Beitraege
   sind Flaechen, die Spur ist eine Zeile dazwischen. Zusammen mit der stillen
   Marke „Entfernt" (0216) und der Kursive sind das drei Unterschiede – und
   trotzdem KEINE eigene Farbe und KEIN eigenes Bauteil.
   ⚠ SIE BLEIBT AN IHRER STELLE IN DER ZEITFOLGE. Wer sie ausblendet, wegklappt
   oder ans Ende schiebt, hat den Zweck von Option C erledigt (Feature 0022). */
.board-verlauf-eintrag.ist-spur {
    padding: .25rem .1rem;
    background: none;
    border-radius: 0;
}

.modal .board-verlauf-spur {
    margin: 0;
    font-size: .8rem;
    font-style: italic;
    color: var(--muted);
}

.modal .board-verlauf-spur .tag { margin-left: 0; margin-right: .35rem; font-style: normal; }

/* ---------------------------------------------------------------- Anhänge */

/* Die Fläche mit Knopf, Satz und ⓘ. ⚠ DER SATZ STEHT OFFEN DA und nicht in einem
   Kasten (ADR-0040 §9): was eine Folge für andere Menschen hat, wird nicht
   hinter ein Zeichen geschoben.
   ⚠ SEIT 0216 STEHT DER KNOPF ÜBER DEM SATZ und nicht daneben – nebeneinander
   las sich der Satz als Fließtext neben einem Knopf. `.feld-kopf` (§7) bringt
   die Reihe mit; hier wird daraus eine Säule. */
.board-anhang-flaeche {
    flex-direction: column;
    align-items: flex-start;
    gap: .45rem;
    margin-bottom: 1rem;
}

/* Satz und ⓘ bleiben in EINER Zeile – das ⓘ gehört an den Satz, nicht darunter. */
.board-anhang-hinweis { display: flex; align-items: center; gap: .1rem; }

.board-anhang-satz { font-size: .78rem; color: var(--muted); }

.board-anhaenge {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 16rem;
    overflow-y: auto;
    scrollbar-gutter: stable;
}

/* ⚠ EINE ZEILE MIT ZWEI SEITEN (0216): links der Text, rechts die Aktionen.
   `align-items: flex-start`, damit die Icon-Knöpfe an der ersten Zeile stehen
   und nicht in der Mitte eines dreizeiligen Blocks schweben. */
.board-anhang {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    padding: .55rem 0;
    border-top: 1px solid var(--line);
}

.board-anhang:first-child { border-top: 0; padding-top: 0; }

/* ⚠ `min-width: 0` ist Pflicht: ohne sie sprengt ein langer Dateiname das
   Flex-Kind, statt umzubrechen, und schiebt die Aktionen aus dem Fenster. */
.board-anhang-text {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    flex: 1 1 auto;
    min-width: 0;
}

.board-anhang .actions { flex: 0 0 auto; margin-left: auto; }

.board-anhang-name { font-size: .875rem; font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
a.board-anhang-name { color: var(--accent); }
a.board-anhang-name:hover { text-decoration: underline; }

.board-anhang-angabe { font-size: .75rem; color: var(--muted); }

/* ⚠ „liegt im Papierkorb" / „liegt nicht mehr in der Dateiablage" ist eine
   Zustandsauskunft, keine Fehlermeldung – gedämpft, nicht rot. Rot heißt in
   diesem Haus genau eines: „gilt nicht" (DESIGN §0/§34.6).
   ⚠ SEIT 0216 STEHT SIE MIT DERSELBEN KLASSE AUCH IM REITER „DATEIEN" – beide
   Ansichten sagen dasselbe, in derselben Schrift. Deshalb `display: block`: in
   der Tabellenzelle steht sie unter dem Namen, nicht dahinter. */
.board-anhang-zustand { display: block; font-size: .75rem; color: var(--muted); font-style: italic; }

/* Der Weg von der Datei zurück zum Ticket im Reiter „Dateien": ein Knopf, der
   sich als Link liest – dieselbe Bauform wie `.board-ticket-titel`, weil er
   dasselbe tut (er öffnet das Ticketfenster). */
.board-ticketlink {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--accent);
    text-align: left;
    cursor: pointer;
}

.board-ticketlink:hover { text-decoration: underline; }
.board-ticketlink:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* =============================================================================
   DIE KACHELN DES VERWALTUNGS-DASHBOARDS (`.kachel*`, Feature 0024, Handoff 0225)
   =============================================================================
   Die Startseite hinter dem Login. Eine Kachel beantwortet EINE Frage und
   führt mit EINEM Klick dorthin, wo man die Sache erledigt. Die vollständige
   Regel steht in DESIGN.md §40.

   ⚠ SIE IST DER `.kennzahlen`-KARTE VERWANDT (§28), ABER NICHT DIESELBE. Eine
   Kennzahl-Karte trägt eine Zahl mit Beschriftung; eine Kachel trägt einen
   BEFUND – Titel, Wortmarke, wahlweise einen Wert, einen Satz, einen leiseren
   zweiten Satz und den Verweis. Vor allem: der Verweis sitzt am FUSS und muss
   in einer Reihe von Kacheln auf gleicher Höhe stehen, auch wenn die Sätze
   verschieden lang sind. Deshalb ist die Kachel eine Flex-Säule mit
   `margin-top: auto` am Fuß – etwas, das `.kennzahlen` nicht kennt und auch
   nicht braucht.

   ⚠ KEINE EIGENE FARBE, KEINE AMPEL, KEIN FARBIGER RAND. Was dringend ist,
   steht als Wort in der Marke (`.tag.tag-quiet`). Rot heisst im Haus „dieses
   Blatt gilt nicht" (§34.6) und hätte auf einer Statusanzeige nur eine
   Bedeutung zu viel.
   ⚠⚠ NACHTRAG 29.08.2026 (Handoff 0230, ADR-0043): Der Satz „Deshalb steht hier
   kein einziges Farb-Token" gilt NICHT MEHR WOERTLICH. Die Kachel traegt seither
   die Farbe ihres Bereichs. Der VERBOTSTEIL bleibt in voller Haerte: keine
   Ampel, kein Rot, kein Farb-Token an Marke, Wert, Satz, Zusatz, Eintrag oder
   Knopf. Die Bereichsfarbe behauptet keinen Zustand – sie ist an derselben
   Kachel immer dieselbe.
   ⚠⚠ NACHTRAG 30.08.2026 (Handoff 0233): ~~an ihrer LINKEN KANTE
   (`.kachel-kante-*`, siehe unten)~~ – die Kante ist ERSATZLOS ENTFALLEN. Die
   Farbe sitzt jetzt auf dem BEREICHSNAMEN ueber dem Titel (`.kachel-bereich-*`,
   siehe unten). Grund: die Kante war stumm – eine Farbe ohne Wort. */
.kacheln {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem; margin-bottom: 1.1rem;
    align-items: stretch;
}
/* Die Kachel IST ein `.panel` – nur ohne dessen Außenabstand, den hier das
   Grid setzt (dieselbe Bauweise wie `.kennzahlen .panel`, §28). */
.kacheln .panel { margin-bottom: 0; }
.kachel { display: flex; flex-direction: column; }

/* -----------------------------------------------------------------------------
   TRAEGER 2: DER BEREICHSNAME UEBER DEM KACHELTITEL (ADR-0043 §4.1 samt
   Nachtrag vom 30.08.2026, Handoff 0233)
   -----------------------------------------------------------------------------
   ⚠⚠ HIER STAND BIS ZUM 30.08.2026 DIE LINKE KANTE:
     ~~.kachel { border-left-width: 3px; }~~
     ~~.kachel-kante-geld { border-left-color: var(--bereich-geld); }~~ (x4)
   Sie ist ERSATZLOS ENTFALLEN. Der Nutzer hat Entwurf 2 gewaehlt und die
   Grenze dafuer ausdruecklich verschoben: „ich will dass die Bereichsfarben
   auch deutlich zu sehen sind."

   DIE BEGRUENDUNG, DIE MAN KENNEN MUSS: **die Kante war stumm — eine Farbe
   ohne Wort.** Mit dem Bereichsnamen arbeitet die Farbe, statt zu dekorieren;
   DESIGN §0 („Farbe steht nie allein", Nachtrag 0212: „Farbe braucht einen
   Traeger, der ohnehin gelesen wird") ist damit von selbst erfuellt – der
   Traeger IST das Wort. Ein 3-px-Streifen war das schwaechere Mittel.

   ⚠ DER ABSATZ WEITER OBEN („kein einziges Farb-Token") IST DAMIT NICHT MEHR
   VOLLSTAENDIG WAHR – und er gilt trotzdem fuer alles, was er meinte. Was er
   verbietet, ist eine Farbe, die einen ZUSTAND behauptet: Ampel, Rot, roter
   Rand, „dringend". Genau das tut diese Beschriftung nicht:

     Ampel / Rot                      Bereichsfarbe
     erscheint, WEIL etwas passiert   ist IMMER da, unabhaengig vom Bestand
     steht an der Angabe selbst       steht an einer Beschriftung, nie an einer Angabe
     traegt Klartext („ueberfaellig") IST der Klartext („GELD")

   Die Kachel sagt weiterhin mit einem WORT, was dringend ist (`.tag.tag-quiet`);
   die Beschriftung sagt nur, worum es geht. Sie ist an einer Kachel deshalb
   immer dieselbe, egal was die Kachel gerade meldet.

   ⚠ EINE KACHEL OHNE BEREICH BEKOMMT GAR KEINE ZEILE (nicht eine graue). Das
   Raster springt dadurch nicht: die Kacheln sind `align-items: stretch`, und
   der Fuss haengt an `margin-top: auto`. Kein Grau als fuenfte Farbe, sondern
   gar keine Farbe (ADR-0043 §4.3).

   ⚠ DIE VERSALIEN MACHT DAS STYLESHEET, NICHT DER TEXT. Im Markup steht „Geld";
   vorgelesen wird „Geld", nicht „G-E-L-D".
   Gemessen gegen --card #ffffff (TEXT, also 4,5:1):
     menschen 5,73 · geld 8,33 · vorstand 5,23 · aussen 5,09.
   -------------------------------------------------------------------------- */
/* ⚠⚠ ALLE FUENF REGELN BEWUSST MIT `.panel` DAVOR – dieselbe Falle wie bei
   `.kachel-wert` und `.kennzahl-wert` (§28): `.panel p` ist Klasse + Element
   (0,1,1) und damit SPEZIFISCHER als eine blosse Klasse (0,1,0). Ohne den
   Vorsatz stuende der Bereichsname GRAU da – die Farbe waere im Stylesheet
   vorhanden und auf dem Schirm unsichtbar.
   ⚠ AM 30.08.2026 GENAU SO PASSIERT: das erste Bildschirmfoto dieses Handoffs
   zeigte vier graue Kachel-Beschriftungen neben vier farbigen Gruppennamen der
   Seitenleiste. Kein Test hat es gemeldet – der Waechter prueft, WELCHE
   Selektoren die Farbe tragen duerfen, nicht, ob sie am Ende gewinnen. */
.panel .kachel-bereich {
    margin: 0 0 .2rem;
    font-size: .66rem; font-weight: 700;
    letter-spacing: .09em; text-transform: uppercase;
    line-height: 1.2;
}
.panel .kachel-bereich-menschen { color: var(--bereich-menschen); }
.panel .kachel-bereich-geld { color: var(--bereich-geld); }
.panel .kachel-bereich-vorstand { color: var(--bereich-vorstand); }
.panel .kachel-bereich-aussen { color: var(--bereich-aussen); }

/* Titelzeile: Überschrift links, Wortmarke rechts daneben. Die Marke bricht
   nicht um (`.tag` trägt `white-space: nowrap`), deshalb darf die Zeile
   umbrechen statt die Marke zu quetschen. */
.kachel-kopf { display: flex; align-items: baseline; gap: .35rem; flex-wrap: wrap; margin-bottom: .5rem; }
.kachel-titel { margin: 0; font-size: 1rem; font-weight: 650; color: var(--ink); }

/* ⚠ BEIDE REGELN BEWUSST MIT `.panel` DAVOR: `.panel p` ist Klasse + Element
   und damit spezifischer als eine bloße Klasse – ohne den Vorsatz verlören
   Farbe und Abstand (dieselbe Falle wie bei `.kennzahl-wert`, §28). */
.panel .kachel-wert {
    font-size: 1.65rem; font-weight: 650; line-height: 1.15;
    color: var(--ink); font-variant-numeric: tabular-nums; margin: 0 0 .2rem;
}
.panel .kachel-satz { color: var(--ink); font-size: .9rem; line-height: 1.45; margin: 0; }
.panel .kachel-zusatz { color: var(--muted); font-size: .8rem; line-height: 1.45; margin: .35rem 0 0; }

/* -----------------------------------------------------------------------------
   DIE EINTRÄGE AUF DER KACHEL (Handoff 0228)
   -----------------------------------------------------------------------------
   Seit dem Nutzer-Befund vom 28.08.2026 meldet eine Kachel nicht nur einen
   Zustand („3 Tickets"), sondern nennt die dringendsten Fälle beim Namen. Jeder
   Eintrag ist zwei Zeilen: die Sache als Verweis, darunter leiser die
   Einordnung und die Wartezeit.

   ⚠ ES IST KEINE TABELLE UND KEINE `.liste`. Eine Kachel bleibt eine Kachel
   (DESIGN.md §40.9); höchstens drei Einträge, danach ein ehrlicher Satz
   („und 7 weitere Einträge"). Wer hier Spalten einführt, hat ein zweites Modul
   gebaut.

   ⚠ KEIN EIGENES FARB-TOKEN – wie im ganzen `.kachel*`-Abschnitt. Der Verweis
   ist `--ink` und unterstreicht sich beim Überfahren; dringend wird nichts
   durch Farbe, sondern durch das Wort daneben. */
.kachel-eintraege { list-style: none; margin: .7rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .45rem; }
.kachel-eintrag { display: flex; flex-direction: column; gap: .05rem; min-width: 0; }
/* Der Name ist der Verweis. Er darf lang sein (ein Ticketttitel ist ein Satz),
   deshalb bricht er um statt die Kachel zu sprengen. */
.kachel-eintrag-name {
    font-size: .88rem; font-weight: 600; line-height: 1.35;
    color: var(--ink); text-decoration: none; overflow-wrap: anywhere;
}
.kachel-eintrag-name:hover { text-decoration: underline; }
.kachel-eintrag-name:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius); }
.kachel-eintrag-bei { font-size: .78rem; line-height: 1.35; color: var(--muted); overflow-wrap: anywhere; }
/* „und 7 weitere Einträge" – der ehrliche Rest, nicht verschwiegen und nicht
   als vierter Eintrag getarnt: kein Verweis, leiser als die Einträge. */
.panel .kachel-weitere { font-size: .78rem; line-height: 1.35; color: var(--muted); margin: .5rem 0 0; }

/* ⚠⚠ HIER STAND BIS ZUM 01.09.2026 `margin-top: auto` (Handoff 0240):
     ~~.kachel-fuss { margin-top: auto; … }~~
   Der Fuß wurde damit nach unten gedrückt, damit in einer Reihe verschieden
   hoher Kacheln die KNÖPFE fluchten (DESIGN.md §40.1 Nr. 6 – geschrieben 0225,
   und dort ausdrücklich für „eine Reihe verschieden langer SÄTZE“).

   SEIT DIE KACHELN EINTRÄGE TRAGEN (0228) IST DER HÖHENUNTERSCHIED KEIN SATZ
   MEHR, SONDERN EINE LISTE. Eine Kachel, die einen EINZELFALL meldet
   (Zuwendungsfrist, Anstehende Mitgliederversammlung), kann nach §40.9 Nr. 1
   NIE Einträge tragen; stand sie neben einer Bestands-Kachel, bekam sie deren
   Listenhöhe als LEERRAUM ZWISCHEN IHREM LETZTEN SATZ UND IHREN KNÖPFEN.
   Gemessen (`pruefwerkzeug/luecke0240.mjs`, Chromium 1440 px): 160 px im
   Sitzungen-Überblick, 92 px bei nur zwei Einträgen beim Nachbarn, 0 px
   einspaltig – es war ein Fehler der zweispaltigen Rasterzeile, nicht der Kachel.

   OHNE `margin-top: auto` FOLGT DER FUSS DEM INHALT. Die Karte bleibt gleich
   hoch (`.kacheln { align-items: stretch }` steht unverändert), die Rasterkante
   fluchtet also weiter – nur die Knöpfe tun es nicht mehr. Das ist die
   schwächere Hälfte von §40.1 Nr. 6, und sie wird bewusst aufgegeben:
   ⚠ EIN KNOPF, DER VON SEINEM SATZ DURCH 160 px NICHTS GETRENNT IST, IST
   SCHLIMMER ALS WEISSRAUM AM KARTENENDE. Die Lücke in der Mitte liest sich als
   Fehler, der Weißraum unten als Polster.
   ⚠ Verworfene Alternative: `align-items: start` hätte BEIDES aufgegeben –
   dann franst auch die Unterkante der Rasterzeile aus. Umsortieren scheidet
   ohnehin aus (§40.6 Nr. 1: „fest je Betrachter, nie je Bestand“).
   Vollständige Begründung samt Messwerten: DESIGN.md §40.2a.

   Seit 0228 stehen im Fuß bis zu ZWEI Knöpfe – die naheliegende Handlung und
   der Verweis zur Liste –, beide `.btn-secondary` (DESIGN.md §40.9: ein
   `.btn-primary` je Kachel ließe die ganze Startseite leuchten). Auf schmalem
   Schirm brechen sie um. */
.kachel-fuss { padding-top: .9rem; display: flex; flex-wrap: wrap; gap: .5rem; }

/* Der Gesamt-Leerzustand (keine einzige Kachel trifft zu): eine einzelne,
   ruhige Karte in derselben Sprache – kein „keine Berechtigung", kein leerer
   Kasten. Sie steht ALLEIN und braucht deshalb kein Grid. */
.kachel-hinweis .kachel-titel { margin-bottom: .5rem; }

@media (max-width: 40rem) {
    .kacheln { grid-template-columns: minmax(0, 1fr); }
}

/* =============================================================================
   41. DIE PRODUKTSEITE AUF vereinfachen.eu (Feature 0028, DESIGN §41)
   =============================================================================

   ⚠⚠ AM 02.09.2026 NACH EINEM GESTALTUNGSENTWURF NEU GESETZT (Handoff 0246).
   Der Nutzer hatte die frueheren Fassungen als „wie eine Krankenhausseite"
   zurueckgewiesen: weisser Grund, eine Schrift, Petrol und Grau. Der Entwurf
   loest das mit DREI Mitteln, und alle drei stehen unten:

     1. WARMES PAPIER STATT WEISS (`--pw-papier`, #f4efe6). Das ist der Kern.
        Der Grund traegt die Seite; die Kaesten darauf bleiben `--card`.
     2. DREI SCHRIFTEN MIT DREI ROLLEN: Serife fuer jede Ueberschrift
        (`--pw-serif`), Schreibmaschine fuer Rubriken und Bildunterschriften
        (`--pw-mono`), Grotesk fuer den Fliesstext (die Hausschrift, unveraendert).
        ⚠ AUSSCHLIESSLICH SYSTEMSCHRIFTEN. Es wird NICHTS nachgeladen: keine
        Webfont-Datei, kein `@font-face`, kein fremder Host. Eine Werbeseite,
        die eine Schrift von einem CDN holt, verschickt die IP jedes Besuchers,
        bevor er ein Wort gelesen hat.
     3. DUNKLE BAENDER als Zaesur: die Petrol-Flaeche (`.pw-hervor`), das
        Bereichsband (`.pw-band`) und der Fuss (`.pw-fuss`).

   ⚠ DIESELBE FAMILIE, EIN ANDERER ATEM. Die Produktseite benutzt die Tokens
   dieses Stylesheets und ist ausdruecklich KEIN drittes Design-System: die
   oeffentliche VEREINSseite (public.css, DESIGN §15) ist eines, weil sie dem
   VEREIN gehoert und dessen Branding traegt. Diese Seite gehoert dem Haus.
   ⚠ Was sie seit dem 02.09.2026 eigenes hat, sind GRUND und SCHRIFTROLLEN –
   nicht die Palette: Petrol bleibt der Akzent, Bernstein die Warnung, und die
   vier Bereichsfarben kommen aus denselben Token wie in der Verwaltung.

   ⚠ DIE BREITE BLEIBT --content-max (DESIGN §3: „gleiche Breite und Achse auf
   ALLEN Seiten"). Auch die Baender sind INNERHALB dieser Breite gesetzt und
   laufen nicht ueber den ganzen Schirm - der Entwurf zeigt sie randlos, das
   Haus setzt sie als Kasten mit `--radius`. Begruendung: eine Werbeseite, die
   breiter laeuft als der Rest des Hauses, waere der erste Schritt zu einem
   zweiten Layout-System. Ausgenommen sind Kopfleiste und Fuss - sie waren es
   schon vorher.

   ⚠ KEIN ROT (DESIGN §34.6). Der Hinweis auf die noch nicht ausgefuellten
   Pflichtseiten traegt BERNSTEIN (--warn-bg/--warn-ink): dort gilt nichts
   „nicht" – es fehlt etwas.

   ============================================================================
   ⚠⚠ DIE BEREICHSFARBE AUF DIESER FLAECHE – DREI FORMEN, UND KEINE VIERTE
   ============================================================================
   ADR-0043 §4.6 hat die Produktwebsite als FLAECHE freigegeben, §4.7 die
   FORMEN. Erlaubt sind genau drei, alle unten namentlich:

     A   das WORT (`.pw-bereichsname`) in der Bereichsfarbe,
     A'  die GETOENTE Kartenflaeche darunter (`.pw-eingang`, `.pw-thema`),
     C   GENAU EIN dunkles Band je Bereichsseite (`.pw-band`).

   ⚠⚠ ABGELEHNT: die farbige OBERKANTE des Entwurfs (`border-top`, 2–3 px).
      Sie ist am 30.08.2026 ersatzlos gestrichen worden – „die Kante war stumm,
      eine Farbe ohne Wort" (ADR-0043 §4.7.2). Eine Linie in der Bereichsfarbe
      ist zulaessig, wenn sie UNTER dem Bereichswort sitzt; sonst nicht.

   ⚠⚠ JEDER TON AUSSER DEN VIER TOKEN IST EINE RECHNUNG, KEIN WERT. Es gibt in
      diesem Kapitel GENAU ZWEI Rezepte, jedes wortgleich an jeder
      Verwendungsstelle (ADR-0043 §4.7.3/§4.7.8 Nr. 3):

        Toenung  color-mix(in srgb, var(--bereich-hier) 9%, var(--card))
        Band     color-mix(in srgb, var(--bereich-hier) var(--pw-band-mix), #000)

      Ein `#rrggbb` aus der Bereichsfamilie steht in Kapitel 41 NIRGENDS. Der
      Entwurf nannte vier feste Toenungen (#e8eff5 · #eeeaf4 · #eaf1e8 ·
      #f6ebf1); sie sind NICHT uebernommen. Sie waeren eine zweite Wahrheit
      fuer dieselbe Farbfamilie – und die vierte unterschritt die Kontrastnorm
      (Aussenauftritt ≈ 4,46:1). Gerechnet kann das nicht passieren.

   ⚠⚠ UND HIER IST DER BEFUND, DEN NUR DAS RECHNEN FINDET (Handoff 0246):
      DER BEREICHSNAME STEHT NIE AUF DEM PAPIER. Auf `--pw-papier` (#f4efe6)
      haelt „Aussenauftritt" (#a1567a) nur **4,44:1** und „Vorstandsarbeit"
      (#46783f) nur 4,56:1 – das erste ist unter der Schwelle von 4,5:1
      (DESIGN §40.1a Nr. 2b). Deshalb sitzt JEDES `.pw-bereichsname` auf einer
      KARTENFLAECHE: auf `--card` (5,09–8,33:1), auf der 9-%-Toenung
      (4,53–7,24:1) oder auf dem Band (dort ist es weiss). Wer eine neue Stelle
      mit einem Bereichsnamen baut, gibt ihr vorher einen Kartengrund.
      Ein Waechter rechnet alle drei Gruende nach, in beiden Token-Bloecken.
   ========================================================================== */

/* ------------------------------------------------------- Grund und Schrift */

/* ⚠ DER GRUND HAENGT AM `<body>`, nicht an `.pw-blatt`: sonst endete das
   Papier an der Unterkante des Inhalts, und unter einer kurzen Seite (Kontakt,
   1377 px) staende ein weisser Streifen. */
.pw-body {
    background: var(--pw-papier);
    color: var(--ink);
}

/* ⚠⚠ DIE SERIFE TRAEGT JEDE UEBERSCHRIFT DIESER FLAECHE – und nur diese
   Flaeche. Sie steht als Regel HIER und nicht an jeder einzelnen Klasse: sonst
   waere die naechste Ueberschrift, die jemand ergaenzt, die eine, die in der
   Groteskschrift stehen bleibt.
   ⚠ `font-weight: 400` ist Absicht: eine Serife in Halbfett wirkt in dieser
   Groesse gedrungen. Das Gewicht kommt aus der GROESSE, nicht aus der Staerke. */
.pw-body h1,
.pw-body h2,
.pw-body h3 {
    font-family: var(--pw-serif);
    font-weight: 400;
    letter-spacing: -.015em;
}

/* Die RUBRIK: kleine Versalien in der Schreibmaschinenschrift. Sie sagt, worum
   es im Folgenden geht, und sie ist absichtlich klein – sie ist ein Schild an
   der Tuer, nicht die Ueberschrift.
   ⚠ SIE IST GRAU. Die farbige Rubrik ist `.pw-bereichsname` und traegt einen
   BEREICHSNAMEN; eine graue Rubrik darf alles andere sagen. */
.pw-rubrik {
    margin: 0 0 .9rem;
    font-family: var(--pw-mono);
    font-size: .78rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--pw-muted);
}

/* ------------------------------------------------------------------ Geruest */

.pw-kopf {
    background: var(--pw-papier);
    border-bottom: 1px solid var(--line-strong);
    position: sticky;
    top: 0;
    z-index: 20;
}

.pw-kopf-inner {
    max-width: var(--content-max);
    margin: 0 auto;
    padding: 1rem var(--content-pad);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

/* Der Markenblock – seit 0246 in der Serife, wie im Entwurf. Das „.eu" traegt
   Petrol, wie auf der Login-Karte (`.brand-central`). */
.pw-marke {
    font-family: var(--pw-serif);
    font-size: 1.35rem;
    letter-spacing: -.01em;
    color: var(--ink);
    text-decoration: none;
}

.pw-marke span { color: var(--accent); }

.pw-blatt {
    max-width: var(--content-max);
    margin: 0 auto;
    padding: 0 var(--content-pad) var(--pw-atem);
}

/* ------------------------------------------------------------- Kopfabschnitt */

.pw-hero { padding: calc(var(--pw-atem) * .9) 0 calc(var(--pw-atem) * .6); }

/* ⚠⚠ DER KOPFABSCHNITT IST ZWEISPALTIG: Text links, ein Bildschirmfoto
   rechts. Bis zum 02.09.2026 stand rechts NICHTS - der Text endet bei
   --pw-lesebreite, und die rechte Haelfte blieb auf 1440 px leer.

   ⚠ DIE BILDSPALTE IST DIE BREITERE (1.15fr gegen 1fr). Ein Bildschirmfoto
   verliert bei jeder Verkleinerung; der Text nicht.

   ⚠ `align-items: center` - nicht `start`. Der Text ist kuerzer als das Bild
   hoch ist; oben ausgerichtet haenge der Text an der Oberkante und darunter
   staende wieder Leere, nur an anderer Stelle. */
.pw-hero-raster {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: 2.5rem;
    align-items: center;
}

/* Das Bild im Kopfabschnitt. Dieselbe Kartenbehandlung wie `.pw-bild`, aber
   OHNE Bildunterschrift: hier erklaert der Text daneben, was zu sehen ist.
   ⚠ KEIN `loading="lazy"` an diesem Bild (siehe Vorlage) - es steht ueber der
   Faltkante, und ein spaeter nachgeladenes Kopfbild laesst die Seite springen. */
.pw-hero-bild {
    margin: 0;
    background: var(--card);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    overflow: hidden;
}

.pw-hero-bild img { display: block; width: 100%; height: auto; }

/* ⚠ DER KOPF EINER UNTERSEITE ATMET WENIGER. Auf der Startseite ist der grosse
   Abstand richtig - dort folgt ein neues Thema. Auf dem Formular und den
   Rechtsseiten folgt die SACHE SELBST. */
.pw-hero-kurz { padding-bottom: 0; }

.pw-hero-kurz + .pw-abschnitt { padding-top: 1.8rem; }

/* ⚠⚠ DIE GROESSTE SCHRIFT DER SEITE, UND SIE IST EIN SATZ, KEIN SCHLAGWORT.
   Auf der Startseite steht dort „In zwei Jahren macht das jemand anderes." –
   `clamp()` haelt ihn auf dem Telefon lesbar und auf 1440 px gross genug, dass
   er die Seite traegt. */
.pw-hero h1 {
    font-size: clamp(2.1rem, 5.2vw, 3.6rem);
    line-height: 1.08;
    letter-spacing: -.02em;
    margin: 0 0 1.2rem;
}

.pw-vorspann {
    font-size: clamp(1.08rem, 1.6vw, 1.32rem);
    line-height: 1.55;
    color: var(--ink);
    max-width: var(--pw-lesebreite);
    margin: 0 0 1.8rem;
}

.pw-knopfreihe {
    display: flex;
    flex-wrap: wrap;
    gap: .7rem;
    align-items: center;
}

/* Der ruhige Satz unter der Knopfreihe – er nimmt dem Knopf das Versprechen,
   das er sonst machen wuerde.
   ⚠ ER TRAEGT EINE LINIE LINKS, KEINEN KASTEN. „Die Plattform ist im Aufbau"
   ist ein HINWEIS, keine Warnung: ein bernsteiner Kasten an dieser Stelle
   laese die Seite wie eine Stoerungsmeldung aussehen. */
.pw-knopfreihe-fuss {
    margin: 1.4rem 0 0;
    padding-left: 1rem;
    border-left: 2px solid var(--accent-blitz);
    font-size: .95rem;
    color: var(--pw-muted);
    max-width: var(--pw-lesebreite);
    line-height: 1.6;
}

/* --------------------------------------------------------------- Abschnitte */

.pw-abschnitt { padding-top: var(--pw-atem); }

/* ⚠⚠ DIE SEITE KENNT GENAU ZWEI BREITEN, UND SIE HAELT SIE.
   – VOLL (--content-max, 70rem): Kopfleiste, Fuss, Kartenraster, Bilder,
     die Baender. Alles, was aus Kaesten besteht.
   – PROSA (--pw-lesebreite, 42rem): Ueberschrift, Vorspann, Fliesstext,
     Aufzaehlung, Hinweiskasten, Preisliste, Formular, Rechtsseiten.
   Wer eine dritte Breite braucht, braucht in Wahrheit eine Begruendung; ein
   Waechter liest dieses Kapitel daraufhin durch. */
.pw-abschnitt > h2,
.pw-tafel > h2 {
    font-size: clamp(1.6rem, 2.8vw, 2.3rem);
    line-height: 1.2;
    margin: 0 0 .7rem;
    max-width: var(--pw-lesebreite);
}

.pw-lead {
    font-size: 1.02rem;
    line-height: 1.65;
    color: var(--pw-muted);
    max-width: var(--pw-lesebreite);
    margin: 0 0 2rem;
}

/* Fliesstext innerhalb eines Abschnitts (Rechtsseiten, Erklaerungen). */
.pw-text {
    line-height: 1.7;
    max-width: var(--pw-lesebreite);
    margin: 0 0 1rem;
}

/* ⚠ DIE TAFEL: eine neutrale, weisse Flaeche innerhalb des Papiers. Sie ist
   KEINE Farbform – sie traegt `--card` und sonst nichts. Sie hat zwei Aufgaben:
     1. Rhythmus (der Entwurf wechselt Papier und Weiss ab), und
     2. ⚠⚠ SIE IST DER GRUND, AUF DEM EIN BEREICHSNAME STEHEN DARF. Auf dem
        Papier haelt „Aussenauftritt" nur 4,44:1 (siehe Kapitelkopf), auf
        `--card` 5,09:1. */
.pw-tafel {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 2.2rem 1.8rem;
    margin-top: var(--pw-atem);
}

.pw-tafel > .pw-lead:last-child,
.pw-tafel > p:last-child { margin-bottom: 0; }

/* Der Kopf einer BEREICHSSEITE. Er hat dieselbe Rolle wie `.pw-hero` auf der
   Startseite, steht aber auf einer Tafel – weil dort der Bereichsname steht
   und der auf dem Papier nur 4,44:1 haelt (siehe Kapitelkopf). */
.pw-kopfblatt {
    margin-top: calc(var(--pw-atem) * .7);
    padding: clamp(2rem, 4vw, 3.2rem) clamp(1.4rem, 3vw, 2.4rem);
}

.pw-kopfblatt h1 {
    font-size: clamp(2rem, 4.6vw, 3.2rem);
    line-height: 1.1;
    letter-spacing: -.02em;
    margin: 0 0 1.1rem;
}

.pw-kopfblatt .pw-vorspann { margin-bottom: 0; }

/* ------------------------------------------------------------------ Raster */

.pw-raster {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: 1.4rem;
}

.pw-raster-zwei { grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr)); }

/* Eine Karte im Raster. Haarlinie statt Rahmen, kein Schatten – DESIGN §1. */
.pw-karte {
    background: var(--card);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    padding: 1.4rem 1.5rem;
}

.pw-karte h3 {
    font-size: 1.2rem;
    margin: 0 0 .5rem;
}

.pw-karte p {
    margin: 0;
    color: var(--pw-muted);
    line-height: 1.65;
    font-size: .95rem;
}

/* -------------------------------------------------- Die Petrol-Flaeche */

/* ⚠⚠ DIE EINE HERVORGEHOBENE FLAECHE EINER SEITE OHNE BEREICH (DESIGN §41.3).
   Sie traegt EINEN Abschnitt, nicht drei – sonst hebt sich nichts mehr ab.
   Seit 0246 ist sie DUNKEL statt hellpetrol: der Entwurf setzt an dieser
   Stelle ein Band, das die Seite teilt.
   ⚠ AUF IHR STEHT KEIN BEDIENELEMENT. Ein Petrol-Knopf auf Petrol ist
   unsichtbar, und eine weisse Knopfvariante gibt es im Haus nicht (dieselbe
   Auflage wie beim Bereichsband, ADR-0043 §4.7.4 Nr. 4). Die Handlung steht
   UNTER dem Band. Ein Waechter prueft das an der gerenderten Seite. */
.pw-hervor {
    background: var(--pw-hervor-bg);
    color: var(--pw-band-ink);
    border-radius: var(--radius);
    padding: clamp(2rem, 4vw, 3.4rem) clamp(1.4rem, 3vw, 2.6rem);
    margin-top: var(--pw-atem);
}

.pw-hervor > h2 {
    font-family: var(--pw-serif);
    font-weight: 400;
    font-size: clamp(1.5rem, 2.6vw, 2.1rem);
    line-height: 1.25;
    letter-spacing: -.015em;
    margin: 0 0 .8rem;
    max-width: var(--pw-lesebreite);
    color: var(--pw-band-ink);
}

.pw-hervor .pw-lead,
.pw-hervor .pw-text,
.pw-hervor .pw-punkte { color: var(--pw-hervor-leise); }

.pw-hervor .pw-rubrik { color: var(--pw-hervor-leise); }

.pw-hervor /* ⚠ Ein Absatz nach der Aufzaehlung klebte an ihrem letzten Punkt (auf
   `/produkt/zugang` sass „Die Plattform ist im Aufbau" ohne Luft unter dem
   dritten Aufzaehlungspunkt und las sich als vierter). Die Liste traegt ihren
   Abstand innen, nicht unten – deshalb steht er hier am Nachbarn. */
.pw-punkte + .pw-text,
.pw-punkte + .pw-lead { margin-top: 1.4rem; }

.pw-punkte li::before { background: var(--pw-hervor-leise); }

.pw-hervor strong { color: var(--pw-band-ink); }

/* Nach dem Umbruch (eine Spalte) braucht der Satz Luft zum Text darunter. */
.pw-hervor .pw-band-raster > div + div { margin-top: 0; }

/* ⚠ DER GROSSE SATZ auf dem Band – die einzige Stelle der Seite, an der ein
   ABSATZ die Groesse einer Ueberschrift hat. Er ist keine Ueberschrift: er
   gliedert nichts, er behauptet etwas. Deshalb `<p>` und nicht `<h2>`. */
.pw-satz {
    font-family: var(--pw-serif);
    /* ⚠ Auf breitem Schirm steht er in der linken Spalte und braucht keinen
       Abstand nach unten; sobald das Raster umbricht, steht der Text
       darunter. Deshalb der Abstand am Raster, nicht am Satz. */
    font-size: clamp(1.35rem, 2.4vw, 1.95rem);
    line-height: 1.32;
    letter-spacing: -.01em;
    margin: 0;
    color: var(--pw-band-ink);
}

/* --------------------------------------------------------------- Aufzaehlung */

.pw-punkte {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: .7rem;
    max-width: var(--pw-lesebreite);
}

.pw-punkte li {
    position: relative;
    padding-left: 1.4rem;
    line-height: 1.65;
}

.pw-punkte li::before {
    content: "";
    position: absolute;
    left: 0;
    top: .62em;
    width: .42rem;
    height: .42rem;
    border-radius: 50%;
    background: var(--accent);
}

/* ---------------------------------------------------------- Bildschirmfotos */

/* ⚠⚠ EINE SPALTE, NICHT DREI - und das ist eine Lehre, keine Vorliebe.
   Ein Bildschirmfoto der Anwendung ist 1100-1430 px breit. In einer
   dreispaltigen Kachelreihe (~340 px) schrumpft es auf ein Viertel, und dann
   zeigt es NICHTS mehr: eine dichte Tabelle wird zu grauen Streifen. */
.pw-bilder {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 2.2rem;
}

.pw-bild {
    margin: 0;
    background: var(--card);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    overflow: hidden;
}

/* ⚠ `display: block` ist Pflicht: ein Inline-Bild traegt die Grundlinie mit
   und laesst unten einen Spalt zum Rahmen stehen. */
.pw-bild img {
    display: block;
    width: 100%;
    height: auto;
    border-bottom: 1px solid var(--line);
}

/* ⚠ DIE BILDUNTERSCHRIFT STEHT IN DER SCHREIBMASCHINENSCHRIFT. Sie ist eine
   Beschriftung, kein Text – der Wechsel der Schrift sagt das, ohne es zu
   schreiben (Entwurf 02.09.2026). */
.pw-bild figcaption {
    padding: .8rem 1rem 1rem;
    font-family: var(--pw-mono);
    font-size: .8rem;
    line-height: 1.55;
    color: var(--pw-muted);
    border-top: 1px solid var(--line);
}

/* ------------------------------------------------------------------- Preis */

/* ⚠⚠ EIN PAKET, ZWEI ZAHLWEISEN – KEINE STAFFEL (Nutzer 02.09.2026,
   ADR-0045 Weiche 1 = B).
   ⚠ Die zwei Karten sind zwei ZAHLWEISEN desselben Pakets, nicht zwei Stufen.
   Sie sind deshalb OPTISCH GLEICHWERTIG. Keine ist hervorgehoben – wer
   monatlich zahlt, soll sich nicht fuer die zweite Wahl halten. */
.pw-preis {
    max-width: var(--pw-lesebreite);
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 1rem;
}

.pw-preis-karte {
    background: var(--card);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    padding: 1.2rem 1.3rem;
}

.pw-preis-karte-name {
    margin: 0 0 .5rem;
    font-family: var(--pw-mono);
    font-size: .8rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--pw-muted);
}

/* Der Nachlass-Merker. ⚠ Petrol als EINZIGER Akzent des Hauses (DESIGN §1),
   nie Rot und nie Bernstein - hier ist nichts ungueltig und nichts zu warnen,
   hier ist etwas guenstiger. */
.pw-preis-merker {
    display: inline-block;
    margin-left: .4rem;
    padding: .1rem .45rem;
    border-radius: var(--radius);
    background: var(--accent-soft);
    color: var(--accent-ink);
    font-family: var(--pw-mono);
    font-size: .72rem;
    letter-spacing: .04em;
    white-space: nowrap;
}

.pw-preis-wert {
    margin: 0;
    font-size: 2.2rem;
    line-height: 1.15;
}

/* ⚠ DER BETRAG STEHT IN DER SERIFE. Er ist die Zahl, um die es geht; im
   Entwurf traegt sie dieselbe Schrift wie die Ueberschriften.
   ⚠ WARUM DIE SERIFE AN DER ZAHL HAENGT UND NICHT AM ABSATZ: der ZEITRAUM
   („im Monat") steht im selben Absatz und soll in der Groteskschrift bleiben.
   Saesse die Serife am Absatz, muesste der Zeitraum die Hausschrift ein
   zweites Mal aufzaehlen – und die steht nur an einer Stelle, am `body`. */
.pw-preis-zahl {
    font-family: var(--pw-serif);
    font-weight: 400;
    font-variant-numeric: tabular-nums;
}

/* Der Zeitraum haengt an der Zahl, ist aber nicht die Zahl. */
.pw-preis-zeitraum {
    font-size: 1rem;
    font-weight: 500;
    color: var(--pw-muted);
}

.pw-preis-karte-text {
    margin: .6rem 0 0;
    font-size: .9375rem;
    line-height: 1.6;
    color: var(--pw-muted);
}

/* ⚠⚠ „Der ganze Betrag wird auf einmal faellig“. Das ist die AUSKUNFT, die
   der kleine Verein wirklich braucht - deshalb steht sie IM Kasten und traegt
   volle Textfarbe statt der gedaempften.
   ⚠ KEIN ROT (DESIGN §34.6): hier gilt nichts nicht, hier ist nur etwas
   wichtig. */
.pw-preis-achtung {
    margin: .6rem 0 0;
    padding-top: .6rem;
    border-top: 1px solid var(--line);
    font-size: .9375rem;
    line-height: 1.6;
    color: var(--ink);
}

/* Der Satz unter beiden Karten. ⚠ Er nennt bewusst keine Mehrwertsteuer -
   die Kleinunternehmerfrage ist offen (ADR-0045 §10 Rechtsfrage 1). */
.pw-preis-zusatz {
    max-width: var(--pw-lesebreite);
    margin: .8rem 0 1.6rem;
    font-size: .9375rem;
    color: var(--pw-muted);
}

/* ------------------------------------------------------- Hinweis / Warnung */

/* Der ruhige, ehrliche Hinweis. Er sagt, was NOCH NICHT ist. */
.pw-hinweis {
    background: var(--card);
    border: 1px solid var(--line-strong);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
    padding: 1rem 1.2rem;
    max-width: var(--pw-lesebreite);
    line-height: 1.65;
    font-size: .925rem;
}

/* Der laute Hinweis auf eine nicht ausgefuellte Pflichtseite.
   ⚠ BERNSTEIN, NICHT ROT (DESIGN §34.6): hier gilt nichts „nicht" – es fehlt
   etwas. Dieselben zwei Token wie jede andere Warnung des Hauses. */
.pw-warnung {
    background: var(--warn-bg);
    color: var(--warn-ink);
    border-radius: var(--radius);
    padding: 1.1rem 1.3rem;
    margin-bottom: 2rem;
    line-height: 1.65;
}

.pw-warnung ul { margin: .6rem 0 0; padding-left: 1.2rem; }

.pw-warnung li { margin-bottom: .2rem; }

/* ------------------------------------------------------------------ Formular */

.pw-formular {
    max-width: var(--pw-lesebreite);
    background: var(--card);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    padding: 1.6rem;
}

.pw-feld { margin-bottom: 1.1rem; }

.pw-feld label { display: block; margin-bottom: .3rem; }

.pw-feld input, .pw-feld textarea { width: 100%; }

/* Die Erklaerung unter einem Feld – dieselbe Rolle wie `.field-hint` in der
   Verwaltung, nur mit dem Zeilenabstand dieser Seite. */
.pw-feld-hinweis {
    margin: .35rem 0 0;
    font-size: .825rem;
    color: var(--pw-muted);
    line-height: 1.55;
}

/* ⚠ DAS LOCKFELD. Es steht im Markup, ein Mensch sieht es nie, ein Bot fuellt
   es aus (Muster der oeffentlichen Vereinsformulare). `display: none` waere zu
   auffaellig – manche Bots ueberspringen genau das. */
.pw-lockfeld {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Die Einwilligungszeile: Kaestchen links, Wortlaut daneben – nie darunter.
   ⚠ `font-weight: normal` IST HIER PFLICHT, NICHT GESCHMACK: das Element ist
   ein `<label>`, und `label` traegt im Haus die Etikett-Staerke. */
.pw-einwilligung {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    line-height: 1.6;
    font-size: .925rem;
    font-weight: normal;
    margin-bottom: 1.4rem;
}

.pw-einwilligung input { margin-top: .25rem; flex: 0 0 auto; }

/* --------------------------------------------------------------- Rechtsseiten */

.pw-recht { max-width: var(--pw-lesebreite); }

.pw-recht h2 {
    font-size: 1.3rem;
    margin: 2rem 0 .5rem;
}

.pw-recht dl { margin: 0 0 1rem; }

.pw-recht dt {
    font-weight: 500;
    margin-top: .7rem;
}

.pw-recht dd {
    margin: .1rem 0 0;
    color: var(--pw-muted);
}

/* -------------------------------------------------------------------- Fuss */

/* ⚠⚠ DER FUSS IST DUNKEL UND VIERSPALTIG (Entwurf 02.09.2026). Er ist die
   einzige Flaeche der Seite ausser der Kopfleiste, die ueber die volle Breite
   laeuft – er schliesst das Blatt ab, statt darauf zu liegen.
   ⚠ ER FUEHRT ZU IMPRESSUM UND DATENSCHUTZ, von JEDER Seite aus in einem
   Schritt (§ 5 DDG). Ein Waechter prueft das fuer jede Seite. */
.pw-fuss {
    background: var(--pw-fuss-bg);
    color: var(--pw-fuss-muted);
    margin-top: var(--pw-atem);
}

.pw-fuss-inner {
    max-width: var(--content-max);
    margin: 0 auto;
    padding: 3rem var(--content-pad) 3.5rem;
}

.pw-fuss-raster {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 2.2rem;
    font-size: .95rem;
}

.pw-fuss-marke {
    margin: 0 0 .6rem;
    font-family: var(--pw-serif);
    font-size: 1.3rem;
    color: var(--pw-fuss-ink);
}

.pw-fuss-marke span { color: var(--pw-fuss-muted); }

.pw-fuss-titel {
    margin: 0 0 .9rem;
    font-family: var(--pw-mono);
    font-size: .72rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--pw-fuss-muted);
}

.pw-fuss-spalte {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: .55rem;
}

.pw-fuss-inner a {
    color: var(--pw-fuss-ink);
    text-decoration: none;
}

.pw-fuss-inner a:hover { text-decoration: underline; }

.pw-fuss-inner p { color: var(--pw-fuss-muted); }

/* ============================================================================
   41.7 DIE ACHT SEITEN UND DIE BEREICHSFARBEN (Handoffs 0245/0246)
   ============================================================================
   Aus einer langen Seite sind acht geworden: Start, vier Bereichsseiten,
   Preise, Zugang, Kontakt (dazu Vormerkung, Impressum, Datenschutz).

   ⚠ DREI TRAEGER, MEHR NICHT (ADR-0043 §4.6/§4.7):
      1. `.pw-bereich-*` - DER ZEIGER. Er faerbt nichts. Er setzt nur
         `--bereich-hier`, genau wie `.inhalt-bereich-*` in der Verwaltung.
      2. `.pw-bereichsname` - DAS WORT, das den Bereich benennt, in seiner
         Farbe; `.pw-eingang`/`.pw-thema` - seine getoente Flaeche.
      3. `.pw-band` - GENAU EIN dunkles Band je Bereichsseite.

   ⚠⚠ KEIN KNOPF, KEIN FOKUS-RING, KEINE KANTE. Die Knoepfe dieser Seite sind
      Haus-Knoepfe in Petrol. Petrol sagt „hier bist du", die Bereichsfarbe
      sagt „worum geht es".

   ⚠ DIE KACHEL DER STARTSEITE IST KEIN LINK (`<article>`, nicht `<a>`) - der
     Link ist der Knopf in ihr. Ein Waechter prueft das Markup.
   -------------------------------------------------------------------------- */

/* Der Zeiger. ⚠ Er steht NICHT in `:root` - eine Seite ohne Bereich (Start,
   Preise, Zugang, Kontakt) faellt damit auf Petrol zurueck, statt eine
   erfundene Bereichsfarbe zu behaupten. */
.pw-bereich-menschen { --bereich-hier: var(--bereich-menschen); }
.pw-bereich-geld { --bereich-hier: var(--bereich-geld); }
.pw-bereich-vorstand { --bereich-hier: var(--bereich-vorstand); }
.pw-bereich-aussen { --bereich-hier: var(--bereich-aussen); }

/* Das Wort. ⚠ FARBE STEHT NIE ALLEIN (DESIGN §0): der Traeger IST der
   ausgeschriebene Bereichsname. Ohne Bereich - also auf jeder Seite, die zu
   keinem gehoert - bleibt er Petrol.
   ⚠⚠ ER STEHT NIE AUF DEM PAPIER, sondern immer auf `--card`, auf der
   9-%-Toenung oder auf dem Band (siehe Kapitelkopf, 4,44:1). */
.pw-bereichsname {
    margin: 0 0 .9rem;
    font-family: var(--pw-mono);
    font-size: .78rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--bereich-hier, var(--accent));
}

/* ------------------------------------------------- Die getoente Kartenflaeche */

/* ⚠⚠ FORM A' (ADR-0043 §4.7.1/§4.7.3). Sie ist KEINE neue Form: sie ist
   buchstaeblich Traeger 2 der Verwaltung („sehr helle Toenung derselben Farbe
   als Flaeche, die Farbe selbst als Schrift", seit 30.08.2026).

   ⚠⚠ 9 %, UND DIE ZAHL IST NICHT FREI: Bei 9 % haelt das Bereichswort auf
      seiner eigenen Toenung 4,53:1 (Aussenauftritt) bis 7,24:1 (Geld). Bei
      10 % faellt „Aussenauftritt" auf 4,47:1 und damit unter die Schwelle.
      Es ist derselbe Anteil, den `--leiste-aktiv-mix` in der Verwaltung
      benutzt – ein Anteil im Haus, kein zweiter.

   ⚠ DIE ZEICHENKETTE STEHT WORTGLEICH AN JEDER VERWENDUNGSSTELLE. Ein
     abweichender Prozentsatz oder ein `#rrggbb` der Bereichsfamilie laesst den
     Waechter fallen (ADR-0043 §4.7.8 Nr. 3). */

/* ⚠ Bauform der Dashboard-Kachel: eine Karte, kein Link. */
.pw-eingang {
    margin-top: 0;
    display: flex;
    flex-direction: column;
    background: color-mix(in srgb, var(--bereich-hier) 9%, var(--card));
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    padding: 1.6rem 1.6rem 1.5rem;
}

.pw-eingang h3 { margin: 0 0 .6rem; font-size: 1.35rem; }

.pw-eingang-text { margin: 0 0 1.1rem; color: var(--pw-muted); font-size: .95rem; }

/* Die Merkmalsliste. Sie ist eine AUFZAEHLUNG und kein Fliesstext – deshalb
   ohne Aufzaehlungspunkt, nur mit Zeilenabstand.

   ⚠⚠ SEIT 0247 STEHT SIE AUF DER BEREICHSSEITE, NICHT MEHR AUF DER
      STARTSEITE. Vier Listen zu je fuenf Punkten machten aus den vier
      Eingangskacheln zwanzig zusaetzliche Zeilen, die dasselbe sagten wie die
      vier Zielseiten; auf dem Telefon war die Startseite damit 8774 px hoch.
      Die Kachel traegt jetzt EINEN Satz, die Liste steht dort, wo sie
      hingehoert. */
.pw-merkmale {
    list-style: none;
    margin: 0 0 1.3rem;
    padding: 0;
    display: grid;
    gap: .5rem;
    font-size: .95rem;
    line-height: 1.5;
}

/* Dieselbe Liste auf dem Kopfblatt einer Bereichsseite. Sie schliesst den
   Abschnitt ab, deshalb Abstand nach OBEN statt nach unten – sonst stuende
   unter der letzten Zeile ein Leerraum, den keiner bestellt hat. */
.pw-merkmale-kopf { margin: 1.5rem 0 0; }

/* Schiebt den Knopf auf die Unterkante, damit die vier Kacheln trotz
   verschieden langer Texte eine gemeinsame Fusslinie haben. */
.pw-eingang .btn { margin-top: auto; align-self: flex-start; }

/* Die getoente Karte auf einer Bereichsseite („Was dazugehoert"). Dieselbe
   Rechnung, dasselbe Rezept, wortgleich. */
.pw-thema {
    background: color-mix(in srgb, var(--bereich-hier) 9%, var(--card));
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    padding: 1.4rem 1.5rem;
}

.pw-thema h3 { margin: 0 0 .5rem; font-size: 1.2rem; }

.pw-thema p { margin: 0; color: var(--pw-muted); line-height: 1.65; font-size: .95rem; }

/* ------------------------------------------------------------- Das Band */

/* ⚠⚠ FORM C (ADR-0043 §4.7.4) – DIE TEUERSTE ZUSAGE DES NACHTRAGS, MIT VIER
   AUFLAGEN, UND ALLE VIER SIND ZAEHLBAR:

     1. GENAU EINES je Seite, und nur auf einer der vier Bereichsseiten.
        Start, Preise, Zugang und Kontakt setzen `--bereich-hier` nicht und
        bekommen deshalb KEIN Band – dort steht `.pw-hervor`.
     2. ⚠⚠ ES TRITT NICHT NEBEN DIE HERVORGEHOBENE FLAECHE, ES *IST* SIE. Eine
        Bereichsseite hat KEIN `.pw-hervor`. Zwei hervorgehobene Flaechen heben
        nichts mehr hervor (DESIGN §41.3).
     3. AUF IHM STEHT DER BEREICHSNAME IM KLARTEXT – sonst waere es eine stumme
        Flaeche und fiele aus demselben Grund wie die Oberkante.
     4. AUF IHM STEHT KEIN BEDIENELEMENT – kein `<a>`, kein `<button>`, kein
        `.btn`. Die Handlung steht UNTER dem Band.

   ⚠⚠ DER TON WIRD GERECHNET, NICHT GESETZT, UND DER FAKTOR STEHT JE
      TOKEN-BLOCK. Der Entwurfswert #2f5129 entspraeche 67 % – der Unterschied
      zu 70 % ist nicht wahrnehmbar, der Unterschied in der Pflege ist der
      ganze Punkt. Gerechnet gegen weisse Schrift:
        hell  (70 %): Menschen 9,23 · Geld 12,02 · Vorstandsarbeit 8,62 ·
                      Aussenauftritt 8,47
        dunkel(55 %): Menschen 5,66 · Geld 6,72 · Vorstandsarbeit 5,22 ·
                      Aussenauftritt 5,76
      ⚠ IM DUNKELMODUS SIND DIE BEREICHSFARBEN HELL. Derselbe 70-%-Faktor
        ergaebe dort 3,48:1 – UNTER der Schwelle. Genau deshalb steht der
        Faktor in `--pw-band-mix` und nicht in dieser Regel. */
.pw-band {
    background: color-mix(in srgb, var(--bereich-hier) var(--pw-band-mix), #000);
    color: var(--pw-band-ink);
    border-radius: var(--radius);
    padding: clamp(2rem, 4vw, 3.4rem) clamp(1.4rem, 3vw, 2.6rem);
    margin-top: var(--pw-atem);
}

/* ⚠⚠ AUF DEM BAND IST DER BEREICHSNAME WEISS, NICHT BUNT – und das ist
   gerechnet, nicht dekoriert: der aufgehellte Satz (`--bereich-*-hell`) haelt
   auf dem Band 4,84 / 5,01 / 4,96 – aber „Aussenauftritt" nur **4,31:1** und
   damit unter der Schwelle. Der Bereichsname steht trotzdem da (Auflage 3);
   er traegt nur die Farbe des Bandes statt seiner eigenen. */
.pw-band .pw-bereichsname { color: var(--pw-band-ink); }

.pw-band h2 {
    font-size: clamp(1.5rem, 2.6vw, 2.1rem);
    line-height: 1.25;
    margin: 0 0 .8rem;
    color: var(--pw-band-ink);
}

.pw-band p { color: var(--pw-band-ink); max-width: var(--pw-lesebreite); }

.pw-band p:last-child { margin-bottom: 0; }

/* Das Band mit einem Bild daneben – Text links, Bildschirmfoto rechts. */
/* Das Band mit einem Bild daneben – Text links, Bildschirmfoto rechts.
   ⚠ Oben ausgerichtet, aus demselben Grund wie beim Szenenraster. Auf der
   Startseite traegt dasselbe Raster den grossen Satz links und die zwei
   Absaetze rechts (der Entwurf setzt es dort genauso). */
.pw-band-raster {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
    gap: 2.4rem;
    align-items: start;
}

.pw-band-raster > div > p:last-child { margin-bottom: 0; }

/* Ein Bildschirmfoto AUF dem Band: es bleibt eine weisse Karte. Ein Bild auf
   dunklem Grund ohne Karte saehe aus wie ein Loch. */
.pw-band .pw-bild { border-color: transparent; }

.pw-band .pw-bild figcaption { color: var(--pw-muted); }

/* -------------------------------------------------------- Die Kopfnavigation */

/* ⚠ KEINE BEREICHSFARBE HIER. Die Punkte sind Links; sie bleiben im Hausgrau
   und werden auf Petrol hell (ADR-0043 §4.7.6 Nr. 7). */
.pw-nav {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem 1.3rem;
    margin: 0 1rem;
}

.pw-nav-punkt {
    color: var(--ink);
    font-size: .95rem;
    text-decoration: none;
}

.pw-nav-punkt:hover { color: var(--accent); text-decoration: underline; }

/* -------------------------------------------------------------- Die Szenen */

/* Der Abschnitt mit den wiedererkennbaren Situationen. Auf der Startseite
   steht neben jeder Szene ein Bildschirmfoto, auf einer Bereichsseite nicht –
   dieselbe Klasse, ein Raster mehr. */
.pw-szene { margin-top: 2.4rem; }

.pw-szene:first-of-type { margin-top: 1.2rem; }

.pw-szene h3 {
    margin: 0 0 .6rem;
    font-size: clamp(1.35rem, 2.4vw, 1.85rem);
    line-height: 1.22;
}

.pw-szene p { margin: 0; max-width: var(--pw-lesebreite); font-size: 1.02rem; line-height: 1.65; }

/* ⚠ OBEN AUSGERICHTET, NICHT ZENTRIERT. Beim Ansehen der Bildnachweise stand
   neben dem hohen Lastschrift-Fenster ein Loch von rund 250 px ueber dem
   Rubrikwort – der Text war gegen ein Bild zentriert, das dreimal so hoch ist.
   Oben ausgerichtet beginnen Rubrik und Bild auf derselben Linie. */
.pw-szene-raster {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
    gap: 2.6rem;
    align-items: start;
}

/* --------------------------------------------------- Die Schritte (Zugang) */

.pw-schritte {
    list-style: none;
    margin: 1.6rem 0 0;
    padding: 0;
    display: grid;
    gap: 1.4rem;
}

.pw-schritt {
    border-left: 2px solid var(--line-strong);
    padding-left: 1.2rem;
}

/* ⚠ „Schritt 3" ist eine ZAEHLUNG, keine Bereichsangabe - deshalb Petrol und
   keine Bereichsfarbe. */
.pw-schritt-nr {
    margin: 0 0 .3rem;
    font-family: var(--pw-mono);
    font-size: .75rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--accent);
}

.pw-schritt h2 { margin: 0 0 .5rem; font-size: 1.3rem; }

.pw-schritt p { max-width: var(--pw-lesebreite); }

.pw-schritt p:last-child { margin-bottom: 0; }

/* ⚠ HIER STANDEN BIS ZUM 02.09.2026 DREI REGELN FUER DIE KURZFASSUNG DER
   SCHRITTLISTE (`.pw-schritte-kurz` und `.pw-schritte + .pw-knopfreihe`).
   Sie sind mit ihr entfallen (Handoff 0248): die vier Schritte standen auf der
   Startseite UND auf /produkt/zugang; auf der Startseite steht jetzt nur noch
   der Aufruf. Die Klassen kamen danach in keiner Vorlage mehr vor - eine
   CSS-Regel ohne Markup ist Drift, und `KeineGeisterklasseTest` prueft nur die
   andere Richtung (Klasse im Markup, Regel im Stylesheet). `.pw-schritte`
   selbst bleibt: die Liste steht unveraendert auf /produkt/zugang. */

.pw-hervor .pw-schritt { border-left-color: var(--pw-hervor-leise); }

.pw-hervor .pw-schritt-nr { color: var(--pw-hervor-leise); }

.pw-hervor .pw-schritt p { color: var(--pw-band-ink); }

/* ------------------------------------------- Weiter zu den anderen Bereichen */

/* ⚠ JEDER EINTRAG TRAEGT SEINEN BEREICHSNAMEN – und deshalb einen KARTENGRUND
   und nicht das Papier (4,44:1, siehe Kapitelkopf). */
.pw-weiter {
    list-style: none;
    margin: 1.4rem 0 1.8rem;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 1.2rem;
}

.pw-weiter li {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1.1rem 1.2rem;
}

.pw-weiter a { font-weight: 600; }

/* ------------------------------------------------------------ Schmaler Schirm */

/* ⚠ DIE MEISTEN VORSTAENDE LESEN DIESE SEITE AM TELEFON. Der Rhythmus wird
   enger, die Ueberschrift kleiner – die Lesebreite bleibt, sie ist dort ohnehin
   die Bildschirmbreite. */
/* ⚠⚠ DAS KOPFRASTER KLAPPT FRUEHER ZU ALS DER REST (56rem statt 40rem).
   Zwei Spalten unter ~900 px heissen: eine Textspalte von 25 Zeichen neben
   einem Bild von 25 % Groesse - beides unbrauchbar. Das Bild rutscht dann UNTER
   den Text.
   ⚠ DIE REIHENFOLGE IST DABEI DIE ENTSCHEIDENDE: Ueberschrift, Vorspann,
   KNOPF, ehrlicher Satz - und ERST DANN das Bild. Der Vormerk-Knopf steht auf
   einem 390-x-844-Telefon ohne Scrollen erreichbar. Wer das Bild nach oben
   zieht, verliert genau das. */
@media (max-width: 56rem) {
    .pw-hero-raster { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
}

@media (max-width: 40rem) {
    :root { --pw-atem: 3rem; }

    .pw-tafel,
    .pw-hervor,
    .pw-band { padding: 1.6rem 1.2rem; }

    /* Auf schmalem Schirm sollen die zwei Knoepfe die volle Breite nehmen –
       ein 40 % breiter Knopf mitten auf dem Telefon liest sich als Rest. */
    .pw-knopfreihe .btn { flex: 1 1 100%; justify-content: center; }

    /* ⚠ DIE KOPFNAVIGATION BRICHT UNTER DIE MARKE, statt den Anmelde-Knopf aus
       der Leiste zu druecken. Sechs Punkte nebeneinander passen auf 390 px
       nicht; sie rutschen sonst hinter den rechten Rand. */
    .pw-kopf-inner { flex-wrap: wrap; }

    .pw-nav { order: 3; flex-basis: 100%; margin: .2rem 0 0; }

    .pw-eingang .btn { align-self: stretch; justify-content: center; }
}
