/* ============================================================================
   LAYOUT · Leinwand, Skalierung, Breakpoints, Container, Fokus
   ----------------------------------------------------------------------------
   Breakpoints sind REFERENZ — @media kann CSS-Variablen nicht lesen; echte
   Nutzung nur in der Tailwind-Config. 3xl=1800 (bewusst < 1920, für Full HD).
============================================================================ */

:root {

  --bp-sm:640px;--bp-md:768px;--bp-lg:1024px;--bp-xl:1280px;--bp-2xl:1536px;--bp-3xl:1800px;
  --container-max:1920px;   /* max. Inhaltsbreite; ab hier zentriert mit Rand */

  /* ---- Lesebreite einer allein stehenden Karte ----
     Für Änderungs-Historien, Formulare, Platzhalter, Bereichsschutz — jede
     Karte ohne Nachbarn auf sonst leerer Seite. Über `breite="lese"` an
     `@kavacon/ui/karte` anfordern, nie als Zahl an der Aufrufstelle. */
  --breite-lese:55rem;      /* 880px */

  /* ---- Breite einer allein stehenden DATENTABELLE ----
     Für Tabellen-Seiten ohne Nachbarn (Benutzerverwaltung): die Lesebreite
     ließ die Spalten rollen (gemessen 30.08.2026: 1009px Bedarf gegen 856px
     Fläche). Nutzer-Maß: höchstens die Hälfte über der Lesebreite. Zwischen
     Fläche und Deckel wächst die Spalte mit, darüber wachsen die Ränder. */
  --breite-tabelle:82.5rem; /* 1320px = 880 × 1,5 */

  /* ---- Die Rollzonen-Randzone (Nutzer-Regel 21.08.) ----
     EIN Muster für jede senkrechte Rollzone, auf Seiten- wie Kartenebene:
     Der Inhalt endet 16px vor dem Rand, und diese 16 teilen sich fest in
     4 (Abtrennung außen) + 8 (Balkenspur, per scrollbar-gutter immer
     reserviert) + 4 (Abtrennung innen — zugleich die Luft, die der
     Ruheschatten seitlich braucht; eine eigene Schattenraum-Mechanik gibt
     es damit nicht mehr). Der Balken läuft also zentriert in der Randzone,
     und beim Auftauchen bricht nichts um. Werkzeugzeilen und alles andere
     außerhalb einer Rollzone stehen auf den vollen 16 (die 4px trägt die
     globale <main>, die 12 der Seiten-Baustein). Wo das rollende Element
     selbst die sichtbare Fläche ist (Tabellenfläche, Sidebar), setzt ein
     transparenter 4px-Rand den Balken von der Kante ab. */
  --balken-breite:8px;

  /* ---- Das Suchfeld IN einer Werkzeugzeile ----
     Nicht zu verwechseln mit `.suchfeld` der Topbar (Einstieg Befehlspalette,
     wächst auf 35rem) — hier geht es um den schmalen Schlitz, der eine
     Tabelle filtert. */
  --breite-suche-werkzeug:15rem;   /* 240px */

  /* ---- Der Taschenrechner (Seite /taschenrechner) ----
     Feste Spalte in Taschenrechner-Proportion (hochkant statt breit):
     vier Tastenspalten samt Kartenpolster. Fest heißt max = min
     (Regel 10.1); den Rest der Zeile nimmt die Datenfelder-Karte. */
  --breite-rechner:26rem;          /* 416px */

  /* ---- Die dritte Werkzeugzeile der Kostenzuordnung ----
     Suche + Bundesland + Pflegeart sind zusammen so breit wie die Reiterleiste
     darüber — dafür brauchen die Wähler feste Breiten, gemessen an der
     längsten Option. */
  --breite-kz-zeile3:47.5rem;      /* 760px — die Reiterleiste misst mit fünf
                                      Reitern rund 762 (vier waren 575) */
  --breite-wahl-bundesland:12rem;  /* 192px — trägt „Nordrhein-Westfalen" */
  --breite-wahl-pflegeart:10rem;   /* 160px — trägt „teilstationär" */

  /* ---- SPALTEN DER KALKULATIONSTABELLEN ----
     EINE Breite je Datenspalte (Bezeichnung nimmt den Rest), bemessen am
     ungünstigsten Inhalt („12.345.678,90" + Zellpolsterung).
     ⚠ Gilt für 100 % Ansichtsgröße — beim Zoomen wachsen Spalte und Zahl
     gleich mit, die Tabelle rollt bei Bedarf (`.kkarte__leib` = overflow-x:auto).
     Eine Zelle mit zwei Feldern ist genau zwei Spalten breit. */
  --spalte-zahl:9rem;              /* 144px — jede Datenspalte */
  --spalte-paar:calc(var(--spalte-zahl) * 2);   /* 288px — Zelle mit zwei Feldern */
  --spalte-bezeichnung-min:11rem;  /* 176px — die erste Spalte fällt nie darunter */
  /* Die Nummernspalte der Rastertabelle. Bemessen an dreistelligen Zeilen-
     nummern in Metagröße; sie liegt IN der ersten Spalte und kommt zu deren
     Mindestbreite hinzu. */
  --spalte-nummer:2.5rem;          /* 40px — Zeilennummer links */

  /* ---- GRUNDLAGEN-KARTEN (Seite und Verfahrens-Reiter) ----
     Die Zeile hat ein Label und je Jahr eine Wertspalte. Aus beidem rechnet
     sich die Mindestbreite der Karte; DARUNTER stapelt das Raster, statt
     Label oder Wert umbrechen zu lassen (Regel 10.5).
     ⚠ Die Karte trägt links und rechts das Kartenpolster (2 × 20px) und
     zwischen den Spalten die Zeilenfuge (12px) — beides steckt in der Summe. */
  --spalte-grundlagen:6.5rem;        /* 104px — breitester Wert samt Spaltenkopf */
  --grundlagen-label-min:20.75rem;   /* 332px — längstes Katalog-Label (329) plus Luft */
  --karte-grundlagen-min:37.75rem;   /* 604px — 332 + 2 × (104 + 12) + 40 */
  --karte-grundlagen-min-3:45rem;    /* 720px — dasselbe mit dritter Spalte */

  /* ---- DIE FUGE ZWISCHEN RASTERELEMENTEN — wächst mit der Fläche.
     Auf großen Bildschirmen bleibt sonst kein sichtbarer Zwischenraum, wenn
     die Karten an ihrem Deckel stehen und nur noch die Ränder wachsen.
     Geeicht auf die Referenzbreite: 1920 / 120 = 16px = `--space-4`, also der
     bisherige feste Wert. Gedeckelt bei 32px, damit die Fuge nie mit dem
     Abstand zwischen zwei Karten-Gruppen verwechselt wird.
     ⚠ `--vw100` statt `vw` — sonst rechnet die Fuge am Zoom vorbei. */
  --raster-fuge:clamp(var(--space-4), calc(var(--vw100) / 120), var(--space-8));

  /* ==== DIE RASTER-ROLLEN ===================================================
     JEDE Rolle trägt genau ZWEI Zahlen, und mehr braucht es nicht:
       `-min` — ab hier bricht der Inhalt. Folgt aus dem Inhalt.
       `-max` — so breit darf die Rolle höchstens werden. Darüber wachsen die
                RÄNDER: das Raster zentriert sich.
     Dazwischen wächst die Rolle mit der Fläche. `fest` ist kein eigener Fall,
     sondern `-max` gleich `-min`; `voll` ist `-max: 1fr`.
     ⚠ `-max` ist eine GEPFLEGTE ZAHL, kein Faktor auf einer Standardbreite.
     Ein Faktor wirkt an zwei Orten verschieden: In einem `auto-fit`-Raster
     bestimmt die Höchstbreite der Spur auch die SPALTENZAHL — 20 % Aufschlag
     kosteten dort die dritte Spalte, außerhalb eines Rasters nicht. Wo die
     Zahl herkommt, steht je Rolle daneben.
     STEUEREBENE IST DAS RASTER, NICHT DIE KARTE — dieselbe <Karte> steht in
     mehreren Umgebungen, die Breite gehört der Umgebung (Regel 5).
     ======================================================================== */

  /* 1 · OBJEKT-RASTER — Einrichtungen · Dokumente · Einstellungen ·
     Verteilungsschlüssel · Betriebsstätten. Minimum = bestehende
     Einstellungs-Kachel, deckt alle gemessenen Minima.
     ⚠ Das Maximum entscheidet über die Spaltenzahl: 3 × 408 + 2 × 16 Fuge =
     1256 ≤ 1264 (Fläche der Standardansicht bei offener Kontextleiste).
     Gemessen sind 410,67 — die Zahl liegt bewusst knapp darunter, ein
     Aufschlag kostet die dritte Spalte. Wer sie ändert, rechnet nach. */
  --raster-objekt-min:18.5rem;   /* 296px — gemessen, deckt 283 */
  --raster-objekt-max:25.5rem;   /* 408px — drei Spalten in 1264 */

  /* 2 · PROZESS-KACHELN — die vier KAVA-Schritte. Sie tragen Kennzahlen, nicht
     nur eine Marke, und wachsen deshalb wie die uebrigen Rollen mit. */
  --raster-prozess-min:16rem;    /* 256px — gemessen, deckt 248 */
  --raster-prozess-max:20.75rem; /* 332px — 256 plus 30 % Wachstum */

  /* 3 · KANBAN-SPALTEN — die Spalten wachsen mit, darüber zentriert sich das
     Board. Der Platz bleibt für zusätzliche Spalten reserviert, sobald nach
     etwas anderem als Status gruppiert wird. Kein `auto-fit`: hier deckelt
     die Spalte selbst, die Spaltenzahl kommt aus den Daten. */
  --raster-kanban-min:14rem;     /* 224px */
  --raster-kanban-max:25rem;     /* 400px — Standardbreite 308 plus 30 % Wachstum */

  /* 4 · JAHRESKACHELN DES KALENDERS — zwölf gleich große Monatsblöcke; eine
     breitere Kachel zeigt keinen Tag mehr, deshalb max = min. Die Kachel
     rechnet sich aus der FLÄCHENHÖHE (drei Zeilen ohne Rollen); der Boden
     hält sie lesbar, wenn Fenster oder Ansichtsgröße sie darunter drücken —
     dann rollt die Fläche, statt die Tage unleserlich zu machen. */
  --raster-jahr-min:18.75rem;    /* 300px — Bestand aus KalYear */
  --raster-jahr-max:18.75rem;
  --raster-jahr-boden:11.25rem;  /* 180px — darunter ist ein Monat nicht mehr lesbar */

  /* 5 · VIERFELDER DER ÜBERSICHT — 2:1 statt `auto-fit`, deshalb eine eigene
     Rolle. Die Mindestbreite ist die Schwelle, unter der das Raster stapelt
     (`--container-uebersicht`), als Zahl wiederholt: eine Container-Bedingung
     kann keine `var()` lesen. Der Boden (Umbruch auf eine Spalte, darunter
     waagerechter Bildlauf) ist `--karte-tabelle-min`, weil hier
     Tabellenkarten stehen. */
  --raster-uebersicht-min:77.5rem;   /* 1240px — s. --container-uebersicht */
  --raster-uebersicht-max:101.75rem; /* 1628px — Standardbreite 1252 plus 30 % Wachstum */

  /* 6 · TABELLENKARTEN — Historien, Kontenrahmen, Kostenstellen. Sie standen
     bis zum 11.08. als einziger Bausteintyp NEBEN den Rollen (Breite gleich
     Inhalt, kein Wachstum, keine Zentrierung); jetzt folgen sie derselben
     Regel wie alles andere. Untergrenze ist die rollende Tabellenfläche,
     Obergrenze die Standardansicht plus 30 %. */
  --raster-tabelle-min:var(--karte-tabelle-min);
  --raster-tabelle-max:101.75rem;   /* 1628px — Standardfläche 1252 plus 30 % */

  /* 7 · LISTE NEBEN DETAIL (Nachrichten) — die Liste wächst mit, hört aber vor
     dem Detail auf: 416 ist ihre Standardbreite bei 1264, dieselben 30 % wie
     bei Kanban und Übersicht darüber. Danach nimmt alles Weitere das Detail. */
  --raster-liste-min:var(--karte-tabelle-min);  /* 380px — die Liste IST eine Tabellenkarte */
  --raster-liste-anteil:33.33%;  /* ein Drittel der Fläche — 416px bei 1264 */
  --raster-liste-max:33.75rem;   /* 540px — Standardbreite 416 plus 30 % */
  /* Das Detail trägt Fließtext, keine Liste: Bei 296 war eine Nachricht nicht
     mehr normal zu lesen. Rund 50 % mehr, dann rollt lieber die Fläche. */
  --raster-detail-min:27.75rem;  /* 444px */

  /* 8 · FELDER IN DER KONTEXTLEISTE — dieselbe Rollen-Idee eine Ebene tiefer:
     Felder rücken beim Breiterziehen NEBENEINANDER, statt untereinander zu
     bleiben. Sie nehmen ihre Spalte ganz (`1fr`), weil die Karte darüber schon
     deckelt — ein zweiter Deckel ließe sie mitten in ihrer eigenen Karte vor
     leerer Fläche enden. */
  --raster-feld-min:11rem;       /* 176px — gemessen, heutige Halbspalte */
  --raster-feld-max:1fr;

  /* ---- STAPELBREITEN — DIE HÖCHSTBREITE GILT AUCH NACH DEM UMBRUCH.
     Bricht ein Raster auf eine Spalte, hätte ein Feld sonst plötzlich die
     ganze Rasterbreite: Die Karte wird im STAPEL BREITER als nebeneinander,
     und der Deckel ihrer Rolle gälte nur noch in der Spaltenlage. Ihr Anteil
     an der Spur bleibt deshalb ihre Obergrenze.
     ⚠ Hier steht die ROLLE ausgeschrieben, nicht `var(--raster-max)`: Ein
     Custom Property wird an seiner DEFINITIONSSTELLE aufgelöst, nicht beim
     Verwender. Auf `:root` ist `--raster-max` nicht gesetzt — das Token wäre
     ungültig, und `max-width` fiele stillschweigend auf `none`. */
  --stapel-uebersicht-2von3:calc((var(--raster-uebersicht-max) - var(--raster-fuge)) * 2 / 3);
  /* ---- DIE SPURANTEILE DER ÜBERSICHT ALS LÄNGE ----
     Nur dafür da, dass eine Karte beim Umbruch ihre Breite FÄHRT statt zu
     springen: `max-width` lässt sich zwischen zwei Längen überblenden, gegen
     `none` nicht. Im Zwei-Spalten-Fall trägt die Karte ihren Spuranteil als
     Deckel, im Stapel den Stapel-Deckel — der Wechsel ist dann ein
     Längenwechsel und damit eine Fahrt.
     ⚠ `cqw` misst die ROLLZONE; die Fläche darin ist um Randluft und
     Rollleisten-Platzhalter schmaler. Der Deckel liegt dadurch immer knapp
     ÜBER der Spur und beschneidet sie nie — das ist Absicht, ein zu kleiner
     Deckel risse eine Lücke neben die Karte. */
  --ub-spur-breit:calc((100cqw - var(--raster-fuge)) * 2 / 3);
  --ub-spur-schmal:calc((100cqw - var(--raster-fuge)) / 3);
  --stapel-prozess-1von4:calc((var(--raster-tabelle-max) - 3 * var(--space-3)) / 4);
  --stapel-paar-2von3:calc((var(--raster-tabelle-max) - var(--raster-fuge)) * 2 / 3);
  --stapel-paar-1von3:calc((var(--raster-tabelle-max) - var(--raster-fuge)) / 3);
  --stapel-paar-1von2:calc((var(--raster-tabelle-max) - var(--raster-fuge)) / 2);

  /* 4 · DIE ROLLENDE TABELLENFLÄCHE — über ihr steht kein Raster, die
     Mindestbreite gehört deshalb dem Baustein. Gemessen an der Kartenkopfzeile
     (Icon, Titel, Zähler, Info einzeilig): 380px Karte minus zweimal 20px
     Polsterung. Die Tabelle darin rollt unabhängig davon in sich selbst —
     sonst bestimmte die breiteste Tabelle die Mindestbreite ihrer Karte. */
  --tabellenflaeche-min:21.25rem;  /* 340px — gemessen, deckt 339 */
  --karte-tabelle-min:calc(var(--tabellenflaeche-min) + 2 * var(--card-pad,var(--space-5)));

  /* ==== SCHWELLEN FÜR CONTAINER-QUERIES ====================================
     ⚠ Tailwind liest die Schwelle einer benannten Container-Query AUS DIESEM
     NAMENSRAUM. Fehlt der Token, erzeugt es für `@max-<name>:`/`@min-<name>:`
     KEINE Regel — die Utility steht im Markup und tut nichts, ohne Fehler und
     ohne Warnung. Genau so war die Umbruch-Mechanik der Übersicht monatelang
     wirkungslos. Wer eine neue benannte Query einführt, trägt sie hier ein.
     ⚠ In `app.css` steht die ZAHL, keine `var()` — eine Container-Bedingung
     wird zur Bauzeit aufgelöst. Sie schreibt `erzeuge-theme-abbildung.mjs`
     von hier ab; der `build` prüft das mit `--pruefen`.
     ======================================================================== */
  /* Vierfelder stapeln darunter.
     ⚠ Die Zahl ist der GEMESSENE Bedarf der zwei Spalten, nicht ein
     Wunschwert: Seit die Spuren auf `min-content` stehen (s.
     `routes/uebersicht.tsx`), stellt das Raster seine echte Mindestbreite
     selbst her — die Schwelle muss ihr folgen, sonst rollt die Seite in
     einem Fenster, in dem sie stapeln könnte. Gerechnet aus den Spaltenminima:
       breite Spalte  803  (Laufzeit Vereinbarungen: Tabelle 733 + Polsterung)
       schmale Spalte 406  (Termine: Tabelle 336 + Polsterung)
       + 16 Fuge      = 1225
     Dazu die Differenz zwischen Zone und Fläche (Randluft für den Schatten,
     Rollleisten-Platzhalter): rund 13px. Gemessen wird die ZONE — sie kennt
     den verfügbaren Platz, die Fläche darin kennt nur ihr eigenes Ergebnis.
     (Ein Query-Container kann seine Größe nie aus dem Inhalt nehmen:
     `container-type: inline-size` schließt den Inhalt aus der Breitenrechnung
     aus. Genau deshalb rollte die Fläche früher in sich, statt zu wachsen.)
     ⚠ DIE SCHWELLE STAND BIS ZUM NACHRECHNEN AUF 1376 (Bedarf 1337) — damit
     stapelte die Übersicht auf Full HD, zweispaltig wurde sie erst ab 2032px
     Fensterbreite (Zone = Fenster − 656). Nachgegeben wurde nicht die
     Schwelle (das brächte das Rollen-in-der-Karte zurück), sondern die drei
     Spalten, deren NAME breiter war als ihr Inhalt: „IK-Nummer" → „IK"
     (147 → 120), „gültig bis" → „gültig" (158 → 132), beide in
     `Auslaufend.tsx`, sowie „Wann" (220 → 176, `KarteTermine.tsx`).
     ⚠ Weiter geht es nur noch über `MIN_BREITE` in `@kavacon/ui/tabelle` oder
     über eine Spalte WENIGER: Alle fünf Spalten der Laufzeit-Karte stehen
     jetzt auf der Untergrenze ihrer Spaltenart.
     ⚠ FOLGE, die eine Entscheidung ist: Die Fläche der Standardansicht misst
     bei offener Kontextleiste 1249 — die Übersicht ist dort jetzt ZWEISPALTIG
     (1249 > 1240), vorher war sie es nur mit eingeklappter Kontextleiste. Wer
     noch mehr Luft braucht, nimmt eine Spalte aus „Laufzeit Vereinbarungen"
     (jede kostet 120–169px). */
  --container-uebersicht:77.5rem;  /* 1240px — Bedarf 1225 + Zonen-Zuschlag, aufgerundet */
  --container-terzeile:26.25rem;   /* 420px — Termin-Editor wird zweispaltig */
  /* Vier Schritt-Kacheln nebeneinander; darunter stehen sie 2 × 2 — nie
     einspaltig, die Reihe bliebe sonst als schmale Saeule stehen.
     4 × 256 Mindestbreite + 3 × 12 Fuge = 1060. */
  --container-prozess:66.25rem;    /* 1060px */
  /* Zwei Karten-Spalten nebeneinander; darunter stapeln sie. Gerechnet, nicht
     gegriffen: die schmale Spalte darf nie unter `--raster-objekt-min` fallen.
     2:1 → 3 × 296 + 16 Fuge = 904 · 1:1 → 2 × 296 + 16 = 608. Das ungleiche
     Paar deckt 1,6:1 mit ab (es stapelt 118px früher als nötig). */
  --container-paar-2zu1:56.5rem;   /* 904px */
  --container-paar-1zu1:38rem;     /* 608px */

  --focus-ring-width:2px;--focus-ring-offset:2px;
  --opacity-disabled:0.45;
  --target-min:44px;       /* Mindest-Trefferfläche (WCAG 2.5.5 / Touch) */
}

/* ==== FESTE LEINWAND UND ANSICHTSGRÖSSE ==================================
   Referenz 1920×910, Skalierung nur nach oben (CSS-`zoom` auf <body>, nicht
   `transform: scale()`). ⚠ `vh`/`vw` kennen den Zoom nicht — immer
   `var(--vh100)`/`var(--vw100)` nutzen (Wächter: ESLint
   `kava/no-raw-viewport-units`).
============================================================================ */
:root {
  /* Standard 1 = 100 %. Die App überschreibt ihn am <html>; die Grenzen
     (70–160 %) liegen in `apps/kavacon/src/data/prefs.ts` — dort sind sie eine
     Aussage über den GESPEICHERTEN Wert und nicht über seine Darstellung. */
  --skala:1;
  --vh100:calc(100vh / var(--skala));
  --vw100:calc(100vw / var(--skala));
}

/* WO DER ZOOM GESETZT WIRD: nicht hier, sondern in `app.css` — diese Datei
   liegt auch auf der Landing-Seite, wo eine `body{zoom;height}`-Regel die
   scrollende Marketingseite abschneiden würde. Bei --skala:1 sind
   --vh100/--vw100 exakt 100vh/100vw, also wirkungslos für jeden Konsumenten. */
