/* =========================================================================
   tillY — Design-Tokens
   =========================================================================
   Rams × Aicher, Palette aus Tils Entwurf tilly-aicher.html. Begründungen in
   /opt/tilly-werkzeuge/DESIGNSYSTEM.md, die Rechnung in farben_ableiten.py.

   WARUM EINE EIGENE DATEI
     Bis zum 06.08.2026 lagen die Tokens an vier Orten in drei Namensschemata:
     style.css (lang), basis.html (kurz), patient.html (ein drittes) und
     touren.css als Übersetzung dazwischen. Jedes neue Token hieß vier Zeilen
     Handpflege — und wenn eine fehlte, wurde das Element nicht kaputt,
     sondern farblos. Ein Fehler, der nur als Farbe sichtbar ist, nie als
     Meldung.

     Jetzt gibt es EINEN Wert und beliebig viele Namen dafür. Diese Datei ist
     der Wert; die kurzen Namen in tillY Termine sind Aliasse, die
     hierher zeigen (--akzent: var(--farbe-akzent)), nicht umgekehrt.

   WER SIE LÄDT
     tillY          base.html, relativ
     tillY Termine  basis.html und patient.html mit absolutem Pfad
                    /static/design-tokens.css — beide liegen hinter nginx auf
                    derselben Herkunft, wie schon bei tafel.css.
     Sie muss als ERSTES Stylesheet kommen, vor style.css.

   DIE FARBQUELLE — gewechselt am 07.08.2026
     Bis zum 06.08.2026: Sanzo Wada, "A Dictionary of Color Combinations"
     (1933), Kombination 214 — drei Originale (Ivory Buff #EBD3A2, Sudan
     Brown #A36752, Violet #4F4086), alles andere als Mischung daraus.

     Jetzt: Tils Entwurf "tilly-aicher.html" — neutrales Papier #F4F4F1,
     Ink #1A1A18 und ZEHN feste Funktionsfarben nach Otl Aicher / HfG Ulm.

     WARUM DER WECHSEL MEHR IST ALS EIN ANDERER FARBTON
     Wada gab drei Farben und ein Ableitungsgesetz. Daraus mussten vierzehn
     Bereichstöne fallen, und sie lagen zwangsläufig eng beieinander — fünf
     von 28 Portal-Paaren unter ΔE 10, vier Töne unter 3:1. Das stand als
     bewusster Mangel im System und war ehrlich dokumentiert, aber es war
     einer.

     Aicher gibt zehn UNABHÄNGIGE Töne. In normaler Sicht liegen alle über
     ΔE 13,6. Der Preis: es gibt kein Gesetz mehr, aus dem ein elfter Ton
     fällt. An seine Stelle tritt die Erweiterungsregel — Tinte einer
     bestehenden Farbe für eine Unterfunktion, oder für eine wirklich neue
     Kategorie ein Ton, der ein Suchkriterium erfüllt. Sie ist strenger als
     das alte Gesetz, nicht lockerer.

     DIE DREI HERKUNFTSARTEN, die neben jedem Wert stehen:
         ENTWURF     unverändert aus tilly-aicher.html
         KORRIGIERT  aus dem Entwurf, nachgerechnet und geändert — mit Grund
         GERECHNET   Tinte einer Funktionsfarbe, oder ein Ton nach Kriterium

     Sie sind keine Zierde: sie halten nachvollziehbar, was Tils Entscheidung
     war und was eine Rechnung. Wer sie entfernt, nimmt dem System seinen
     Beleg. Wer eine Farbe ändern will, ändert sie in
     tilly-werkzeuge/farben_ableiten.py und erzeugt den Block neu
     (`python3 farben_ableiten.py --css`). `--pruefe` rechnet nach, ob die
     Palette ihre Zusagen noch hält, und ist als Test eingehängt.
   ========================================================================= */

:root {
  /* ---- Flächen ---------------------------------------------------------
     Stand 07.08.2026 — nach Tils Entwurf "tilly-aicher.html". Vier der
     fünf Werte kommen unverändert von dort; der fünfte ist korrigiert und
     sagt es.

     Gemessen: Ink auf Papier 15,82:1 · Ink auf Panel 17,43:1 ·
     gedämpfter Text 4,57:1 (AA) · Weiß auf ink-Knopf 17,43:1 ·
     Kontur auf Papier 1,23:1 · Panel auf Papier 1,10:1.

     Diese Zahlen stehen hier als Dokumentation, nicht als Beweis. Wer
     wissen will, was der Browser GERADE zeichnet, ruft /farben auf — die
     Seite liest die Tokens im laufenden System aus und rechnet neu.
     Die Rechnung selbst steht in tilly-werkzeuge/farben_ableiten.py und
     prüft sich mit `--pruefe` selbst nach.

     WAS DER WECHSEL VON WADA AUF AICHER HIER ÄNDERT
     Der Grund ist nicht mehr warm, sondern neutral: #F7F0DE → #F4F4F1.
     Damit fällt die Begründung weg, die bisher jeden Ton getragen hat
     ("aus Ivory Buff abgeleitet") — an ihre Stelle tritt die Herkunft aus
     dem Entwurf. Die Ordnung der Flächen bleibt: Papier trägt Panel,
     Panel trägt Karten, die Kontur trennt sie.

     Ein Nebeneffekt, der kein Nebeneffekt ist: --farbe-karte ist jetzt
     REINES Weiß. pruefe_ui_konsistenz.py erkennt eine Karte an
     `all(z > 250 for z in rgb)`; #FFFCF4 hatte im Blaukanal 244 und war
     damit für den Prüfer unsichtbar — er meldete auf /backend/bank-csv
     null Karten, wo er drei verlangt, und bestätigte die dreizehn flachen
     Seiten, ohne hinsehen zu können. Mit #FFFFFF greift er wieder. Die
     Schwelle wird trotzdem auf "unterscheidet sich vom Seitengrund"
     umgestellt: ein Prüfer, der an einem Hexwert hängt, geht beim
     nächsten Palettenwechsel wieder blind.                                */
  --farbe-hintergrund:    #F4F4F1;  /* ENTWURF (tilly-aicher.html, --paper)
                                       Papier: der Seitengrund */
  --farbe-karte:          #FFFFFF;  /* ENTWURF (--panel)
                                       Panel: Karten und Kacheln. Reines Weiß, siehe oben. */
  --farbe-flaeche:        #E8E7E3;  /* GERECHNET: Papier + 55 % Kontur
                                       ruhige Zone: Kachelleiste, Spaltenköpfe.
                                       Der Entwurf kennt diesen Ton nicht — er braucht ihn
                                       nicht, weil er nur einen Screen zeigt. Das Portal
                                       braucht eine Fläche zwischen Papier und Kontur, und
                                       sie wird aus beiden gemischt statt geraten. */
  --farbe-flaeche-rand:   #DEDDD8;  /* ENTWURF (--line)
                                       Die Konturlinie. Sie ersetzt JEDEN Schatten und ist
                                       damit das einzige Mittel, das Flächen trennt. Wer
                                       sie "dezenter" macht, nimmt ihr die einzige Aufgabe,
                                       die sie hat.
                                       NEU: Der Entwurf setzt daneben 2px-INK-Linien als
                                       Gliederung (Kopf, über der Legende). Das ist kein
                                       Ersatz für die Kontur, sondern die Stufe darüber —
                                       siehe --strich-gliederung weiter unten. */
  --farbe-text:           #1A1A18;  /* ENTWURF (--ink)
                                       Text UND Primäraktionen. 15,82:1 auf Papier.
                                       Vorher #3A2E24 (warm, 11,57:1). */
  --farbe-text-gedaempft: #706F6A;  /* KORRIGIERT: Entwurf-Grau #8C8B84 + 20 % Schwarz.
                                       Und das ist zum ZWEITEN Mal derselbe Fall: schon
                                       #9B8F79 aus dem Wada-Entwurf lag bei 2,80:1 und
                                       musste nachgedunkelt werden. Der Entwurfswert
                                       #8C8B84 kommt auf 3,10:1 — das ist Fließtext
                                       ("Posteingang · seit 15 Tagen", "Alle beglichen"),
                                       für den 4,5:1 gilt, nicht 3:1. Ton und Sättigung
                                       bleiben, nur die Helligkeit sinkt, bis es hält:
                                       4,57:1 auf Papier, 5,03:1 auf der Karte.

                                       Wer den Entwurfswert "wiederherstellen" will, macht
                                       den Nebentext des ganzen Portals unlesbar. */

  /* ---- Aktion, Akzent, Fokus -------------------------------------------
     --farbe-primaer trug DREI Bedeutungen gleichzeitig: die Fläche des
     Primärknopfs, den Hover-/Aktivrand und den Fokusring. 228 Aufrufstellen
     über beide Anwendungen. Solange alles Salbeigrün war, fiel das nicht
     auf; als die Knopffläche ink wurde, wurden Rand und Fokusring es auch —
     und ein Fokusring in Textfarbe ist von jeder Kontur nicht zu
     unterscheiden.

     Sortiert wurde nach der EIGENSCHAFT, in der das Token stand:
     background → Aktion, border → Akzent, outline → Fokus, color → Akzent.
     --farbe-primaer gibt es seit dem 06.08.2026 nicht mehr.                 */

  /* AKTION — was etwas TUT. Ink gefüllt, weiße Schrift.
     "Speichern", "Zuordnen", "Bestätigen". Nie in einer Funktionsfarbe:
     Farbe navigiert, sie fordert nicht auf.                                */
  --farbe-aktion:       var(--farbe-text);
  --farbe-aktion-hover: #353534;   /* Ink + 12 % Weiß. Die Richtung hat sich am
                                      07.08.2026 UMGEDREHT: Ink war #3A2E24 und
                                      konnte dunkler werden. Jetzt ist es #1A1A18,
                                      fast schwarz — darunter ist kein Platz mehr.
                                      Ein Hover, der nichts ändert, ist keiner,
                                      also hellt der Knopf jetzt auf.
                                      Weiß darauf 12,28:1. */

  /* AKZENT — was HERVORGEHOBEN ist, ohne zu handeln: aktive Ränder, Hover,
     betonter Text. Muss sich von der Kontur (#DEDDD8) UND von Ink
     unterscheiden, sonst sieht ein Element im Hover aus wie eines mit
     Rahmen.

     DER ENTWURF KENNT KEINEN AKZENT. Er zeigt einen Screen, und dort ist
     "aktiv" schlicht eine weiße Kachel auf grauem Grund. Das Portal hat
     aber 39 Stellen, die den Akzent als FLÄCHE benutzen, 69 als Rand und
     57 als Textfarbe — das lässt sich nicht auf "keine Farbe" abbilden,
     ohne 165 Stellen einzeln zu entscheiden. Das ist eigene Arbeit und
     nicht Teil eines Token-Tauschs.

     Gewählt: das Blau von "Start". Zwei Namen, ein Wert — genau das Muster,
     das --farbe-fokus und --bereich-aufnahme schon einmal geteilt haben.
     Es ist der institutionellste der zehn Töne und liest sich als
     Bedienoberfläche, nicht als Bereichsmarke.

     WER EINEN DAVON VERSCHIEBT, SOLL DEN ANDEREN NICHT MITNEHMEN.          */
  --farbe-akzent:        #2F5C8A;  /* = --bereich-start, siehe oben      6,31:1 */
  --farbe-akzent-dunkel: #214061;  /* Start + 30 % Schwarz               9,67:1 */
  --farbe-akzent-sanft:  #D4DCE1;  /* Start + 84 % Papier — die ruhige Fläche
                                      unter Akzenttext (Chips, gewählte Tage).
                                      84 % und nicht mehr: bei 90 % lag die Fläche
                                      nur ΔE 6,3 vom Papier und verschwamm. Jetzt
                                      ΔE 10,1, Ink darauf 12,55:1. */

  /* FOKUS — wo die Tastatur gerade steht.
     Eigenes Token, obwohl es denselben Wert wie --farbe-akzent hat: die
     beiden bedeuten Verschiedenes. Ein Fokusring, der aussieht wie ein
     Rahmen, ist keiner — bis zum 06.08.2026 war er ink und damit von jeder
     Kontur nicht zu unterscheiden.                                        */
  --farbe-fokus: #2F5C8A;

  /* ---- Fehler ---------------------------------------------------------- */
  --farbe-fehler:       #974740;            /* = --status-inkasso, siehe unten */
  --farbe-fehler-sanft: #E1D1CE;            /* = --status-inkasso-bg, auf dem
                                               neuen Papier neu gerechnet */

  /* ---- Vorgabefarbe ----------------------------------------------------
     Für Einträge, deren Farbe aus der Datenbank kommt und dort leer ist:
     Behandler und Terminarten ohne eigene Farbe. Bis zum 06.08.2026 stand
     dafür #9A9086 an FÜNFZEHN Stellen in zwei Vorlagen -- ein Wert, den
     niemand entschieden hatte und den keine Palette kannte.

     Am 07.08.2026 von warm-taupe (#766A51) auf ein NEUTRALES Grau
     gewechselt. Auf cremefarbenem Grund war das Taupe unauffällig; auf
     neutralem Grund wäre es der einzige warme Ton weit und breit und damit
     ausgerechnet als "keine Farbe gewählt" der auffälligste Wert.

     Ein Grau ist hier stärker als jeder ΔE-Abstand: es ist unbunt, und
     unbunt liest sich auch bei Farbfehlsicht nie als Funktionsfarbe. Eine
     Vorgabe soll nicht aussehen wie eine Wahl.                             */
  --farbe-vorgabe: #6D6D6A;  /* Ink + 38 % Papier — gerechnet, 4,71:1 */

  /* ---- Die 26 Bereichsfarben --------------------------------------------
     Sie erscheinen als Strich am linken Rand einer Kachel ODER als Fuellung
     des Piktogramms. Nie als Knopf, nie als grosse Flaeche.

     DAS IST DIE UMKEHR VOM 07.08.2026. Bis dahin galt hier: "Nie in einem
     Symbol." Die Begruendung war gut -- ein zweites farbiges Element auf
     derselben Kachel machte aus Orientierung Dekoration. Tils Aicher-Entwurf
     dreht sie um: das Piktogramm IST die Farbflaeche, flaechig gefuellt mit
     weissen Aussparungen, nach Muenchen 1972. Wer das wieder auf "Symbole
     sind ink" zurueckstellt, nimmt dem Entwurf seinen Kern.

     Vier Gruppen, und die Unterschiede zwischen ihnen sind der ganze Punkt:

       ZEHN aus dem Entwurf        feste Bereiche, Ebene 2 der Navigation
       VIER Kategorien             Ebene 1, gerechnet nach Regel 2.1.2
       SIEBEN Unterfunktionen      eigener Ton IM FARBTON ihrer Kategorie
       FUENF Portaltoene           eigener Ton, KEINE Familienregel

     Gemessen am 07.08.2026: 26 Farben, 325 Paare. Unter dE 10 liegen DREI,
     alle drei Paare von Entwurfsfarben, alle drei in verschiedenen
     Kategorien und damit nie nebeneinander sichtbar:
         start/archiv      dE 4,2 (Protanopie)
         archiv/zahlung    dE 3,0 (Deuteranopie)
         termine/signatur  dE 8,4 (Deuteranopie)
     Sie stehen mit Begruendung in farben_ableiten.py unter HINGENOMMEN.
     Alles, was gerechnet wurde und nicht aus dem Entwurf stammt, haelt dE 10.

     PFLICHT BEI JEDER AENDERUNG: `python3 tilly-werkzeuge/farben_ableiten.py
     --pruefe`. Er rechnet Kontrast, dE ueber drei Sichtweisen, die
     Familienregel und das Portal-Raster nach und faellt mit Exitcode 1.    */

  /* Die zehn aus dem Entwurf -- Ebene 2 */
  --bereich-start:       #2F5C8A;  /* ENTWURF                    6,31:1  Start */
  --bereich-termine:     #3F7A4A;  /* ENTWURF                    4,65:1  Termine */
  --bereich-posteingang: #CA793C;  /* KORRIGIERT aus #D3812E     3,02:1  Posteingang
                                      Der Entwurf lag bei 2,74:1. Nachgedunkelt --
                                      aber NICHT geradeaus: das erste Nachdunkeln
                                      (+10 % Schwarz) drueckte den Abstand zu
                                      "wartend" unter Deuteranopie auf dE 1,4.
                                      Orange und Gelb liegen dort auf einer Achse. */
  --bereich-archiv:      #7A5A96;  /* ENTWURF                    5,11:1  Archiv */
  --bereich-wartend:     #AF880F;  /* KORRIGIERT aus #C79A2E     3,00:1  Wartend
                                      Entwurf 2,36:1. Siehe posteingang. */
  --bereich-abgleich:    #B85430;  /* ENTWURF                    4,38:1  Zahlungsabgleich */
  --bereich-zahlung:     #4A7290;  /* ENTWURF                    4,65:1  Zahlungen */
  --bereich-karte:       #A34F6B;  /* ENTWURF                    4,90:1  Kartenzahlung */
  --bereich-signatur:    #7A5238;  /* ENTWURF                    6,16:1  Signatur */

  /* Die vier Kategorien -- Ebene 1. Gerechnet: Kernband L 40-54 / C 28-45,
     60 Grad Farbtonabstand untereinander, dE >= 10 gegen alles. */
  --kategorie-praxisablauf:  #1088C4;  /* 3,57:1 */
  --kategorie-kommunikation: #B06C64;  /* 3,68:1 */
  --kategorie-verwaltung:    #9C70AC;  /* 3,58:1 */
  --kategorie-finanzen:      #106C54;  /* 5,78:1 */

  /* Sieben Unterfunktionen. Eigener Ton im FARBTON ihrer Kategorie
     (hoechstens 25 Grad daneben) -- damit man im aufgeklappten Flyout
     sieht, wohin sie gehoeren. Keine Tinte: eine Mischung hat nur eine
     Achse, und darauf bekommen zwei Kinder keine dE 10 zueinander. */
  --bereich-akte:        #AF7DAA;  /* Verwaltung, 11 Grad        3,01:1  Patientenakte */
  --bereich-dsgvo:       #784673;  /* Verwaltung, 11 Grad        6,52:1  Betroffenenrechte */
  --bereich-aufnahme:    #008CDC;  /* Praxisablauf, 9 Grad       3,29:1  Aufnahme */
  --bereich-recall:      #BE7D5A;  /* Kommunikation, 22 Grad     3,04:1  Recall */
  --bereich-bugreports:  #874623;  /* Kommunikation, 21 Grad     6,50:1  Fehlermeldungen */
  --bereich-mahnwesen:   #005037;  /* Finanzen, 6 Grad           8,65:1  Mahnwesen */
  --bereich-labor:       #00504B;  /* Finanzen, 19 Grad          8,47:1  Laborbelege */
  /* TELEFONIE, 13.08.2026. Unterfunktion von Kommunikation -- wie Recall und
     Fehlermeldungen. Eine elfte KATEGORIE ist nach den eigenen Regeln nicht
     mehr moeglich: sie braeuchte 60 Grad Farbtonabstand zu allen anderen, und
     die groesste Luecke im Farbkreis ist gemessen 67,6 Grad. Die Rechnung
     steht in farben_ableiten.py, die Messung auf /farben.
     Kontrast 3,30:1 auf Papier. WEISSE SCHRIFT DARAUF HAELT NUR 3,63:1 --
     wo Text auf dieser Farbe steht, gehoert Tinte darauf (4,80:1). */
  --bereich-telefon:     #B6747C;  /* GERECHNET: Farbton Kommunikation, 18 Grad  3,30:1  Telefonie */

  /* ---- Die zwei Sorten im Posteingang (08.08.2026) --------------------
     Til: "Orange = Zuordnung/Dokument (Funktionsfarbe Kommunikation),
     Violett = Aufgabe (Funktionsfarbe Verwaltung). Falls im Projekt bereits
     eine definierte Funktionsfarben-Palette existiert, DIESE Farben
     verwenden statt der Platzhalterwerte aus dem Mockup."

     Es gibt sie: --kategorie-kommunikation und --kategorie-verwaltung, zwei
     Zeilen weiter oben. Die Platzhalter (#B96A2C / #7C5F84) bleiben deshalb
     ungenutzt.

     WARUM ZWEI TOENE JE SORTE UND NICHT EINER
         Der Kategorieton traegt 3,68:1 bzw. 3,58:1. Fuer einen Punkt von
         7 px und fuer einen Rahmen reicht das (SC 1.4.11 verlangt 3:1 fuer
         Bedienelemente), fuer die 11-px-Schrift eines Abzeichens nicht --
         dort gilt 4,5:1. Ein Abzeichen im Kategorieton waere genau die
         Sorte Farbe, die auf dem Bildschirm des Entwicklers gut aussieht
         und am Tresen bei Sonne nicht mehr lesbar ist.

         Der dunkle Ton ist deshalb kein neuer: es ist der dunkle Verwandte
         aus derselben Familie (Kommunikation 21 Grad, Verwaltung 11 Grad),
         der ohnehin schon im Bestand steht. Gleiche Familie, gleicher
         Farbton, nur genug Tiefe zum Lesen. */
  --pe-zuordnung:       var(--kategorie-kommunikation); /* Punkt, Rahmen  3,68:1 */
  --pe-zuordnung-text:  #874623;   /* = --bereich-bugreports          6,50:1 */
  --pe-zuordnung-wash:  #FBF3E8;   /* Abzeichenflaeche, aus dem Entwurf */
  --pe-aufgabe:         var(--kategorie-verwaltung);    /* Punkt, Rahmen  3,58:1 */
  --pe-aufgabe-text:    #784673;   /* = --bereich-dsgvo               6,52:1 */
  --pe-aufgabe-wash:    #F4EFF5;   /* Abzeichenflaeche, aus dem Entwurf */

  /* Fuenf Toene des Patientenportals. Hier gilt die Familienregel NICHT:
     das Portal hat keine Kategorien und keine Leiste, sein Navigationsmodell
     ist das flache Raster auf /portal. Es gibt kein Elternteil, zu dem etwas
     gehoeren koennte.

     Streng gilt dafuer etwas anderes: die acht Kacheln stehen NEBENEINANDER
     und brechen je nach Fensterbreite anders um. Jede muss sich von jeder
     unterscheiden, nicht nur von ihren Nachbarn.

     DREI Kacheln teilen ihre Farbe mit dem Backend, weil sie dasselbe
     meinen: Termin vereinbaren = termine, Rechnungen = zahlung,
     Nachricht an die Praxis = posteingang. Sie brauchen kein eigenes Token.

     ZWEI durften es nicht -- und das ist der Fall, an dem man sieht, wozu
     eine begruendete Ausnahme gut ist: "Meine Unterlagen" waere archiv und
     steht neben "Rechnungen" = zahlung, und genau dieses Paar liegt unter
     Deuteranopie bei dE 3,0. Im Backend ist das hingenommen, WEIL die
     beiden in verschiedenen Kategorien liegen und sich nie sehen. Im Raster
     faellt diese Begruendung weg -- also faellt auch die Ausnahme. */
  --bereich-portal-dokumente:  #B96E91;  /* 3,34:1  Dokumente hochladen */
  --bereich-portal-anamnese:   #0069AA;  /* 5,29:1  Anamnese */
  --bereich-portal-daten:      #006CC4;  /* 4,83:1  Meine Daten */
  --bereich-portal-unterlagen: #5A376E;  /* 8,64:1  Meine Unterlagen -- dE 14 zu archiv */
  --bereich-portal-therapie:   #5A3C1E;  /* 9,08:1  Therapievorschlaege -- dE 11 zu signatur */

  /* ---- Statusfarben ----------------------------------------------------
     AUSSERHALB des Bereichssystems, mit Absicht. Sie sind Signal, nicht
     Orientierung: Grün heißt bezahlt, Rot heißt Inkasso. Sie dürfen NICHT in
     die Bereichspalette gemischt werden — weder in die zehn noch in die vier.

     DIE WERTE BLEIBEN, Stand 07.08.2026. Nachgemessen auf dem neuen Papier
     steigen alle fünf sogar leicht: bezahlt 4,40 → 4,54 · erinnerung
     4,40 → 4,54 · mahnung 4,45 → 4,59 · inkasso 5,61 → 5,79 ·
     info 5,86 → 6,05. Alle über 4,5:1, denn sie tragen Text.

     Ihre Herkunft ist damit historisch: je 14 % Ivory Buff für die Wärme
     und danach so viel Schwarz, dass sie halten. Ivory Buff gibt es im
     System nicht mehr — die Werte schon, und sie sind gemessen gut.

     EIN VORBEHALT, DER KEIN MESSWERT IST: gewärmt wurden sie für den
     cremefarbenen Grund. Auf neutralem Papier wirken sie leicht gelbstichig.
     Das ist Geschmack, nicht Lesbarkeit; sie bleiben, bis jemand mit einem
     Bildschirm daneben entscheidet. Wer sie neu rechnet, nimmt ihnen den
     Nachweis, dass zwei von ihnen zum ersten Mal AA-tauglich sind.         */
  --status-bezahlt:       #4D795A;  /* #3F7D5C + 14 % IB + 12 % Schwarz   4,52:1 */
  --status-erinnerung:    #8B6A2D;  /* #B8862E + 14 % IB + 27 % Schwarz   4,52:1 */
  --status-mahnung:       #A25D33;  /* #C0622E + 14 % IB + 18 % Schwarz   4,57:1 */
  --status-inkasso:       #974740;  /* #A63D3D + 14 % IB + 14 % Schwarz   5,77:1 */
  --status-info:          #485B8C;  /* #3D5AA6 + 14 % IB + 15 % Schwarz   6,02:1 */

  /* Die Flächen dazu: 80 % Papier. Bei 88 % lagen sie nur ΔE 6,3–7,5 vom
     Grund entfernt und verschwammen damit — auf dem alten, fast weißen
     Papier fiel derselbe Anteil noch auf. Das ist der Unterschied, den ein
     warmer Grund macht. Jetzt ΔE 10,2–12,4, Ink darauf rund 11:1. */
  --status-bezahlt-bg:    #D3DBD3;
  --status-erinnerung-bg: #DFD8CA;
  --status-inkasso-bg:    #E1D1CE;
  --status-info-bg:       #D2D5DD;

  /* ---- Typografie ------------------------------------------------------
     Unverändert. Selbst gehostet in static/fonts/ — ein @import auf
     fonts.googleapis.com wurde von der eigenen CSP blockiert und hätte die
     IP jedes Patienten an Google übertragen. Web und PDF benutzen dieselben
     drei Familien; das ist der stärkste Konsistenzbefund des Systems.       */
  --font-display: 'Space Grotesk', -apple-system, sans-serif;
  --font-text:    'Inter', -apple-system, sans-serif;
  --font-mono:    'JetBrains Mono', 'Courier New', monospace;

  /* ---- Schriftgrößen ---------------------------------------------------
     JEDE Größe hängt an --schrift-skalierung (1,35 im Barrierefrei-Modus).
     Wer eine Größe hart schreibt, nimmt sie aus dem Modus heraus — und das
     fällt niemandem auf, der ihn nicht einschaltet.

     WOHER DIE FÜNF STUFEN KOMMEN
       Gezählt am 06.08.2026: SIEBZEHN verschiedene Größen auf 39 Stellen in
       style.css und tafel.css — 10 und 10,5 nebeneinander, 11 und 11,5,
       12 und 12,5, 13 und 13,5. Dahinter steckte aber kein Wildwuchs,
       sondern fünf klar erkennbare Rollen:

           Mikro        Zähler, Kachelbeschriftung, Fußhinweise
           Hinweis      Feldhinweise, Nebenangaben, Trefferzeilen
           Sekundär     Etiketten, Chips, Meldungen, Nebenlinks
           Fließtext    Absätze, Knöpfe, Eingabefelder
           Titel        h1

       Dieselbe Lage wie bei den Radien am 30.07.2026, und dieselbe
       Entscheidung: die Stufen bekommen Namen, statt eingeebnet zu werden.
       Die Zuordnung verschiebt keinen Wert um mehr als 1 px, die meisten um
       0,5 px. Die zwei Ausreißer mit 1 px sind der Zähler an der Kachel
       (10 → 11, wird dabei lesbarer) und die Wortmarke (16 → 15).

     WAS HIER NICHT STEHT
       Die Größen, die ein SYMBOL bemessen und keinen Text: 19 px für die
       Kachelsymbole, 17 px für das ⓘ, 18 px für die Wortmarke-Grafik. Sie
       sind keine Typografie, und die 19 px verschwinden ohnehin mit dem
       Icon-Satz -- eine SVG-Zeichnung bekommt Breite und Höhe, keine
       Schriftgröße. Der Betrag auf einer Rechnung (24 px) bleibt ebenfalls
       für sich: er ist eine Zahl zum Ablesen, keine Überschrift.

     NACHTRAG, EINE STUNDE SPÄTER: es sind SECHS Stufen, nicht fünf. Die
     erste Zählung sah nur die Größen, die schon an --schrift-skalierung
     hingen. Elf weitere standen als nackte Zahl da und wuchsen im
     Barrierefrei-Modus überhaupt nicht mit — darunter die Überschrift des
     Hilfe-Fensters und die Sprachauswahl. Wer große Schrift einschaltet,
     weil er schlecht sieht, las ausgerechnet die Hilfe weiter klein.
     Zwischen Fließtext und Titel fehlte dafür eine Stufe; sie heißt jetzt
     --schrift-titel.                                                        */
  --schrift-xs: calc(11px   * var(--schrift-skalierung, 1));  /* Mikro      */
  --schrift-s:  calc(12.5px * var(--schrift-skalierung, 1));  /* Hinweis    */
  --schrift-m:  calc(13.5px * var(--schrift-skalierung, 1));  /* Sekundär   */
  --schrift-l:  calc(15px   * var(--schrift-skalierung, 1));  /* Fließtext  */
  --schrift-titel: calc(18px * var(--schrift-skalierung, 1)); /* Abschnitt  */
  --schrift-xl: calc(26px   * var(--schrift-skalierung, 1));  /* Seitentitel*/
  --schrift-betrag: calc(24px * var(--schrift-skalierung, 1));

  /* ---- Abstände: 4er-Raster --------------------------------------------
     ANGEWENDET, WO DER WERT SCHON AUF DEM RASTER LAG -- und nur dort.

     Gezählt am 06.08.2026: ZWANZIG verschiedene Abstandswerte auf 164
     Stellen in style.css und tafel.css. 53 davon liegen exakt auf dem
     Raster (4/8/12/20/32/52) und tragen jetzt einen Namen. Die übrigen 61
     (5, 6, 7, 9, 10, 11, 13, 14, 16, 18, 24, 28, 44, 60) tun es nicht.

     Sie sind BEWUSST nicht eingerastet. 6 → 8 an zwanzig Stellen und
     10 → 8 an zwölf ist keine Umbenennung, sondern eine sichtbare
     Layoutänderung auf jedem Screen — und die gehört vor Augen, nicht in
     ein Skript. Ein Schritt, der nur Namen vergibt, darf nichts verrücken;
     sonst weiß beim nächsten Fehler niemand, ob die Farbe oder der Abstand
     schuld war.

     Wer neu baut, nimmt diese Stufen. Die 61 Literale bleiben sichtbar
     stehen, bis jemand mit einem Bildschirm daneben entscheidet.           */
  --abstand-1:  4px;
  --abstand-2:  8px;
  --abstand-3: 12px;
  --abstand-4: 20px;
  --abstand-5: 32px;
  --abstand-6: 52px;

  /* ---- Form ------------------------------------------------------------
     Rams: Zurückhaltung. Vorher 9/12/16 px und ein zweilagiger weicher
     Schatten. Großzügige Rundungen, Pillenformen und geschwungene Linien
     wurden in der Konzeptphase getestet und ausdrücklich VERWORFEN — sie
     wirkten verspielt.

     --schatten behält seinen Namen und bekommt einen neuen Wert: ein
     Schatten, der eine Linie ist. So mussten die 24 Aufrufstellen nicht
     angefasst werden, unter ihnen .driver-popover in beiden Anwendungen.

     AB 12.08.2026: NULL. Til: „Radius auf 0."
     ------------------------------------------------------------------------
     Die drei Stufen standen auf 2/3/4 px -- der Rest einer Rundung, als
     „Zurückhaltung" gedacht. Til hat entschieden, dass auch der weg ist: die
     Vorgabe aus tilly-aicher.html heißt nichts Rundes, und 3 px sind eine
     halbe Ausnahme, die man auf jedem Bildschirm sieht, ohne sie benennen zu
     können.

     Die Namen bleiben, und das ist Absicht: 190 Aufrufstellen in beiden
     Anwendungen wollen keine Umbenennung, und wer morgen eine Kante doch
     wieder brechen will, ändert einen Wert und nicht 190 Zeilen. Ein Token,
     das 0 ist, ist kein toter Code -- es ist die Entscheidung, sichtbar an
     einer Stelle.

     Was NICHT mitgeändert wurde: die vierzehn echten Kreise (border-radius
     50 % an Statuspunkten, Kopfbildern, dem Rundgangs-Zeiger). Ein Punkt ist
     ein Zeichen und keine gebrochene Ecke; ob er ein Quadrat werden soll, ist
     eine eigene Frage -- die Konzeptstudie zeichnet ihre Farbfelder quadratisch,
     entschieden ist es nicht.                                                */
  --radius-klein: 0;
  --radius:       0;
  --radius-gross: 0;
  --schatten: 0 0 0 1px var(--farbe-flaeche-rand);

  /* Die Funktionsfarbe am linken Rand. --strich-schwach gilt für die vier
     Töne unter 3:1: mehr Fläche gleicht fehlenden Kontrast zum Teil aus. */
  --strich:         3px;
  --strich-schwach: 4px;

  /* ---- Breiten ---------------------------------------------------------
     Gestaffelt nach INHALTSTYP, nicht nach Bildschirm: eine Textzeile über
     ~90 Zeichen liest sich schlechter, egal wie viel Platz daneben frei ist.
     Die Umbruchpunkte selbst (700/900/1400/1900/2400) stehen in
     DESIGNSYSTEM.md — @media kann keine CSS-Variablen lesen.

     560 px und nicht 62ch: ein zeichenbasiertes Maß wäre das schönere
     Argument (es wüchse mit der Schrift), aber es käme bei Inter in 15 px
     auf rund 496 px und verschmälerte damit jede Formularseite um 64 px.
     Das ist eine Gestaltungsänderung, keine Benennung — und sie gehört
     nicht in einen Schritt, der nur Namen vergibt.                         */
  /* Je Inhaltstyp drei Stufen. Die Tabelle in DESIGNSYSTEM.md §5.2 bildet
     genau diese Zeilen ab -- ein Wert, ein Ort.

     Die oberen zwei Stufen fehlten bis zum 06.08.2026 (Paket 11): style.css
     setzte je Zeile nur die erste um. Auf einem 27-Zoll-Schirm blieb eine
     Liste damit auf 880 px stehen und nutzte 36 % der Flaeche -- gemessen
     auf 2560 px. Das Dokument beschrieb die Staffel, gebaut war sie nicht.

     Fliesstext bekommt KEINE weiteren Stufen, und das ist der Grund fuer die
     ganze Staffelung: eine Textzeile ueber ~90 Zeichen liest sich schlechter,
     egal wie viel Platz daneben frei ist. */
  --breite-text:   560px;

  --breite-liste:       880px;   /* ab 1200 */
  --breite-liste-1900: 1040px;
  --breite-liste-2400: 1120px;

  --breite-raster:      1200px;  /* ab 1400 */
  --breite-raster-1900: 1440px;
  --breite-raster-2400: 1760px;

  --breite-akte:        1500px;  /* ab 1500 */
  --breite-akte-1900:   1760px;
  --breite-akte-2400:   2100px;
}

/* =========================================================================
   Der Fokusring
   =========================================================================
   Til, 06.08.2026 (Paket 5). Bis dahin gab es im Portal GENAU ZWEI
   Fokusregeln -- fuer .nebenlink und button.nebenlink. Alles andere,
   also jeder Knopf, jedes Eingabefeld, jede Auswahl und jeder Verweis,
   bekam den Standardring des Browsers.

   Gemessen auf /meine-daten: am Knopf 1 px, am Eingabefeld 3 px, beide in
   einer Farbe, die der Browser sich selbst aussucht. tillY Termine hatte
   die Regel laengst (basis.html) -- zwei Anwendungen, ein Fokusring, zwei
   Antworten.

   WARUM SIE IN DER TOKEN-DATEI STEHT UND NICHT IN style.css
     Sie ist die einzige Datei, die ALLE DREI Oberflaechen laden: das
     Portal, den Kalender und die Patienten-Terminseite. style.css laedt
     tillY Termine nicht -- eine Fokusregel dort galt fuer die Kachelleiste
     des Kalenders nicht, und gemessen bekamen deren Verweise weiter den
     1-px-Standardring des Browsers.

     Eine Regel in einer Token-Datei ist ein Bruch mit ihrem Namen. Die
     Alternative waere dieselbe Regel an drei Stellen -- und die laufen
     auseinander, genau wie es die Farben getan haben.

   :where() haelt die Spezifitaet auf NULL. Damit gewinnt jede vorhandene
   Regel weiter, und niemand muss beim Hinzufuegen einer eigenen erst diese
   hier ueberbieten.

   --farbe-fokus und nicht --farbe-text: ein Ring in Textfarbe ist von einer
   Kontur nicht zu unterscheiden. Er soll SAGEN, wo die Tastatur steht.

   :focus-visible und nicht :focus: sonst bekommt jeder Mausklick einen Ring,
   und der wird dann als Stoerung empfunden und irgendwann abgeschaltet --
   fuer alle, auch fuer die, die ihn brauchen.

   Das gilt fuer Knoepfe und Verweise. FELDER folgen einer eigenen Regel,
   direkt unter dieser -- warum, steht dort.
   ========================================================================= */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--farbe-fokus);
  outline-offset: 2px;
}
/* FELDER: :focus-within und nicht :focus-visible -- gemessen, nicht gewaehlt.
   ------------------------------------------------------------------------
   Zwei Messungen, beide am 06.08.2026 auf /termin/patient an den beiden
   Datumsfeldern der Terminsuche. Beide Male ging es um denselben Nutzer:
   den, der mit der Tastatur navigiert.

   ERSTENS, gegen :focus-visible. Chrome laesst :focus-visible bei
   <input type="date"> beim TABBEN nicht greifen: die Tastatur wandert durch
   die inneren Segmente (Tag, Monat, Jahr), document.activeElement bleibt das
   Feld, aber element.matches(':focus-visible') ist false. Die Felder bekamen
   als einzige Elemente der Seite keinen Ring.

   Bei einem FELD ist das ohnehin richtig: ein Ring um das Feld, in das man
   gerade schreibt, stoert niemanden -- anders als bei einem Knopf, wo ein
   Ring nach jedem Mausklick als Fehler gelesen wird.

   ZWEITENS, gegen :focus. Ein Datumsfeld hat einen Tabstopp MEHR, als es von
   aussen aussieht: nach Tag, Monat und Jahr kommt der Kalenderknopf, und der
   liegt im Shadow-DOM des Feldes. An diesem Stopp verliert das Feld selbst
   :focus (gemessen: matches(':focus') === false), waehrend
   document.activeElement unveraendert darauf zeigt -- Chrome zielt den Fokus
   auf den Host um. Mit :focus blitzte der Ring an jedem vierten Tabdruck
   weg. Genau dieser Zustand war schwer zu sehen, weil jedes Werkzeug, das
   ueber activeElement geht, ihn als "dasselbe Feld wie eben" wegkuerzt.

   :focus-within deckt beides ab: es matcht immer, wenn :focus matcht, und
   zusaetzlich, solange der Fokus IM Element steht. Fuer input, select und
   textarea gibt es keinen Unterschied ausser diesem -- sie haben im
   Lichtbaum keine Kinder, die Fokus nehmen koennten.

   Der Ring rueckt nach INNEN: das Feld traegt schon einen eigenen Rand, und
   ein Ring aussen liesse es in seiner Zeile sichtbar auseinanderspringen.

   Wortgleich zu tilly-termine/templates/basis.html -- zwei Anwendungen,
   ein Fokusring. */
:where(input, select, textarea):focus-within {
  outline: 2px solid var(--farbe-fokus);
  outline-offset: -1px;
  border-color: var(--farbe-akzent);
}

/* ===========================================================================
   Bereich → Funktionsfarbe
   ===========================================================================
   Die Zuordnung steht an GENAU EINER Stelle. Getragen wird sie von einem
   Datenattribut, nicht von Klassen — aus drei Gründen:

     1. Die Backend-Leiste wird zur Laufzeit gebaut (globale-suche.js) und
        setzt dort ohnehin schon kachel.dataset.ziel. Ein zweites
        dataset.bereich ist eine Zeile und kein neues Konzept.
     2. Der Bereichsschlüssel gehört in BACKEND_BEREICHE, wo schon symbol,
        titel, kachel und kurz stehen. Eine zweite Liste wäre nach der
        zweiten Änderung verschieden.
     3. --strich-farbe ERBT. Ein data-bereich an <main class="tafel-inhalt">
        färbt alle Karten darunter richtig, ohne dass jede es einzeln nennt.
        Das ist mit Klassen nicht zu haben und der eigentliche Grund.
   ------------------------------------------------------------------------ */
[data-bereich] { --strich-farbe: var(--farbe-flaeche-rand); }  /* Rückfall */

/* Ebene 1 -- die vier Kategorien der Navigationsleiste. */
[data-bereich="praxisablauf"]   { --strich-farbe: var(--kategorie-praxisablauf); }
[data-bereich="kommunikation"]  { --strich-farbe: var(--kategorie-kommunikation); }
[data-bereich="verwaltung"]     { --strich-farbe: var(--kategorie-verwaltung); }
[data-bereich="finanzen"]       { --strich-farbe: var(--kategorie-finanzen); }

/* Ebene 2 -- die Bereiche. Der Schlüssel ist derselbe wie in
   BACKEND_BEREICHE (globale-suche.js) und in symbole.js: EIN Wort trägt
   Farbe, Zeichnung und Platz in der Leiste. */
[data-bereich="dashboard"]      { --strich-farbe: var(--bereich-start); }
[data-bereich="termine"]        { --strich-farbe: var(--bereich-termine); }
[data-bereich="posteingang"]    { --strich-farbe: var(--bereich-posteingang); }
[data-bereich="archiv"]         { --strich-farbe: var(--bereich-archiv); }
[data-bereich="wartend"]        { --strich-farbe: var(--bereich-wartend); }
[data-bereich="abgleich"]       { --strich-farbe: var(--bereich-abgleich); }
[data-bereich="zahlung"]        { --strich-farbe: var(--bereich-zahlung); }
[data-bereich="terminal"]       { --strich-farbe: var(--bereich-karte); }
[data-bereich="vereinbarungen"] { --strich-farbe: var(--bereich-signatur); }

/* Unterfunktionen ohne eigene Entwurfsfarbe -- Ton im Farbton ihrer
   Kategorie, damit man im aufgeklappten Flyout sieht, wohin sie gehören. */
[data-bereich="akte"]           { --strich-farbe: var(--bereich-akte); }
[data-bereich="dsgvo"]          { --strich-farbe: var(--bereich-dsgvo); }
[data-bereich="aufnahme"]       { --strich-farbe: var(--bereich-aufnahme); }
[data-bereich="recall"]         { --strich-farbe: var(--bereich-recall); }
[data-bereich="bugreports"]     { --strich-farbe: var(--bereich-bugreports); }
[data-bereich="mahnwesen"]      { --strich-farbe: var(--bereich-mahnwesen); }
[data-bereich="labor"]          { --strich-farbe: var(--bereich-labor); }

/* Das Patientenportal. Eigene Schlüssel und nicht dieselben wie oben: die
   Werte stehen in EINER Tabelle, und "termine" kann darin nicht zweierlei
   bedeuten. Der Vorsatz "portal-" macht am Element sichtbar, welche der
   beiden Anwendungen gemeint ist -- ohne dass man dafür die Klasse oder den
   Vorfahren heranziehen müsste, was die Vererbung von --strich-farbe wieder
   kaputtmachen würde.

   DREI zeigen bewusst auf ein Backend-Token: dieselbe Sache, dieselbe
   Farbe. ZWEI dürfen es nicht -- warum, steht oben bei den Portaltönen. */
[data-bereich="portal-termine"]    { --strich-farbe: var(--bereich-termine); }
[data-bereich="portal-rechnungen"] { --strich-farbe: var(--bereich-zahlung); }
[data-bereich="portal-nachricht"]  { --strich-farbe: var(--bereich-posteingang); }
[data-bereich="portal-therapie"]   { --strich-farbe: var(--bereich-portal-therapie); }
[data-bereich="portal-unterlagen"] { --strich-farbe: var(--bereich-portal-unterlagen); }
[data-bereich="portal-dokumente"]  { --strich-farbe: var(--bereich-portal-dokumente); }
[data-bereich="portal-anamnese"]   { --strich-farbe: var(--bereich-portal-anamnese); }
[data-bereich="portal-daten"]      { --strich-farbe: var(--bereich-portal-daten); }

/* --strich-schwach gibt es nicht mehr als Regel: die vier Töne unter 3:1
   waren eine Eigenheit der Wada-Palette. In der Aicher-Palette hält JEDER
   Bereichston 3:1 -- geprüft von farben_ableiten.py --pruefe. Das Token
   selbst bleibt für den Fall, dass wieder einer darunter fällt. */


/* ===========================================================================
   HÖHEN FÜR KNÖPFE UND ABZEICHEN — drei Stufen, keine vierte
   ===========================================================================
   Til, 10.08.2026: "leg dafür eine gemeinsame Button/Badge-Basiskomponente mit
   fixen Höhen-Tokens an (z. B. sm/md/lg), statt Höhen einzeln pro Stelle zu
   setzen."

   WAS DER ANLASS WAR, GEMESSEN
     In EINER Kopfzeile standen vier Höhen nebeneinander: 44 px (Vorgangsknopf),
     40 px (Suchfeld), 34 px (Konto, Zahnrad), 23 px (Rollenabzeichen) — dazu
     fünf verschiedene Polsterwerte und zwei Radien. Über das ganze Portal
     gerechnet: 65 Regeln für Knöpfe und Abzeichen, davon 23 mit eigener Höhe
     oder eigenem Polster. Jede einzeln plausibel, zusammen kein Raster.

   WARUM DREI UND NICHT MEHR
     Weil jede weitere Stufe die Frage "welche denn hier?" schwerer macht, und
     weil sich alles Vorhandene auf drei abbilden liess:
       lg  44 px — die Tippgrösse. Alles, was am iPad getroffen werden muss:
                   Kopfzeile, primäre Handlungen. Die Zahl ist nicht neu, sie
                   steht schon in tafel.css als Begründung für die Kachelhöhe.
       md  34 px — der Regelfall in Listen und Karten: "Ansehen", "Drucken",
                   "Zuordnen". Bisher der häufigste Ist-Wert.
       sm  26 px — Abzeichen und Chips, die nichts auslösen, sondern etwas
                   sagen. Vorher zwischen 23 und 30.

   DAS POLSTER GEHÖRT DAZU
     Eine Höhe ohne Polster ist halb geregelt: bei fixer Höhe entscheidet das
     seitliche Polster, ob zwei Knöpfe nebeneinander gleich aussehen. Deshalb
     je Stufe ein Wert, und die Höhe kommt aus `height`, nicht aus
     `padding-block` — sonst verschiebt eine andere Schriftgrösse sie wieder.

   NICHT BETROFFEN
     Der Hilfe-Knopf (rund, 34 px, eigene Geometrie) und die Kachelleiste: die
     Kachel ist kein Knopf in einer Reihe, sondern eine Fläche in einer Spalte.
   ------------------------------------------------------------------------ */
:root {
  --knopf-hoehe-lg: 44px;
  --knopf-hoehe-md: 34px;
  --knopf-hoehe-sm: 26px;

  --knopf-polster-lg: 0 16px;
  --knopf-polster-md: 0 14px;
  --knopf-polster-sm: 0 10px;
}
