/* =============================================================================
   ÜBERNOMMEN aus design-system/traveto/tokens.css — NICHT VON HAND ÄNDERN.
   Quelle ist das Design-System; hier liegt nur ein Spiegel, damit das Theme
   ohne den Nachbarordner deploybar ist. Ändern heißt: dort ändern, dann
   »bash deploy/sync-design-system.sh« und committen.
   ============================================================================= */
/* =============================================================================
   TRAVETO — Design-System
   Token-Layer (Single Source of Truth)

   Leitbild: "Leinen und Bougainvillea."
   Der Grund ist sonnenwarmes Leinen — ein Sandton, auf dem ein Reisefoto und
   eine helle Kartenkachel liegen koennen, ohne kuehl zu werden. Die Schrift
   ist Kastanie, ein tiefes warmes Braun, nie #000. Genau EINE Aktionsfarbe
   traegt das System: Bluete — das Magenta der Bougainvillea. Sie ist Knopf,
   Kartenpin und Route in einem.

   Es gibt genau EIN Theme, und es ist hell: eine Palette, ein Satz
   Kontrastpaare, eine Kartenkachel. Keine Umschaltung, keine Farbe hinter
   einer Media Query (die einzige hier ist prefers-reduced-motion, und sie
   setzt nur Dauern), keine Dunkelmodus-Variante irgendeiner Farbe. Die Flaechenleiter hat sehr
   wohl Stufen — was es nicht gibt, ist ein zweites Theme.
   Die Karte ist immer hell.

   Ebenen:
     1. Primitives  --tv-*   rohe Werte, nie direkt in Komponenten benutzen
     2. Semantik    --*      Rolle statt Farbe: --text, --bg, --action, ...
     3. Dichte      [data-density="compact"] fuer die App, Default = Marketing

   Regel: jede Farbe, die gezeichnet wird, ist als Hex-Token deklariert.
   Alpha kommt ausschliesslich in Schatten vor. Kontrastwerte: PALETTE.md.
   ============================================================================= */

:root {
  /* ---------------------------------------------------------------------------
     1. PRIMITIVES — Farbe

     Leinen — die Flaechenleiter. EINE Familie, fuenf helle Flaechen: sonnen-
     warmer Sand. Die vier tragenden Stufen laufen auf Ton 26 Grad mit Buntheit
     16; die hellste steht dicht unter Weiss und kann dort weder die Buntheit
     noch den Ton halten (Buntheit 4, Ton 30 Grad) — was sie traegt, ist die
     RICHTUNG: Lab a* positiv, Lab b* niedrig (+1,2). Genau diese Richtung
     grenzt gegen Goings gelbliche Creme ab, nicht die Helligkeit. Lab b* liegt
     ueber die ganze Leiter zwischen +1,2 und +4,6. Benachbarte Stufen liegen
     4,6 bis 5,9 L*-Punkte auseinander und sind deshalb ohne Trennlinie
     voneinander zu unterscheiden (≥ 1,13 : 1).

     Die Bedingungen fuer eine unbunte Flaeche sind: Buntheit hoechstens
     20/255, Farbton in der warmen Haelfte (20-80 Grad), Lab b* hoechstens
     +5,5 — Goings Creme liegt bei +6,8, unsere Flaechen laufen der Richtung
     entgegen. Eine ΔE-Schwelle gegen die Creme gibt es NICHT mehr: eine
     Mindestentfernung von einem Beinahe-Weiss heisst zwangslaeufig "nicht
     beinahe weiss" und verbietet damit jedes helle Weiss. Die ΔE-Werte stehen
     in PALETTE.md als Information, nicht als bestandene Schwelle.

     Deshalb hat dieses System ein lichtes Ende: --tv-linen-0 steht auf
     L* 99,4 und damit 1,2 Punkte ueber dem gemessenen Landton einer hellen Basiskachel
     (L* 98,2). In Runde 7 war der Abstand 0,6 Punkte — rechnerisch gewonnen,
     mit dem Auge nicht. Die Leiter steht jetzt an ihrer eigenen Decke: die
     hellste warme Flaeche (Ton 20-80 Grad, Buntheit 3-20, a* positiv,
     0 < b* <= +5,5, kein reines Weiss) liegt auf L* 99,43, unsere auf 99,41.
     Die hellste Flaeche des Blatts gehoert uns.
     --------------------------------------------------------------------------- */
  --tv-linen-0:   #FFFDFB;   /* L* 99,4 · Buntheit  4 · Ton 30 Grad · a* +0,3 · b* +1,2
                                DAS LICHTE ENDE. Flaeche: schwebendes Panel ueber der
                                Karte, Dialog, Kopfbereich der Seite.
                                Schrift: auf der Umkehrflaeche und auf der Aktionsflaeche. */
  --tv-linen-50:  #F4EBE4;   /* L* 93,6 · Buntheit 16 · Ton 26 Grad · b* +4,5
                                Flaeche: Karte, Panel, Kartenausschnitt. */
  --tv-linen-100: #E7DED7;   /* L* 89,0 · Buntheit 16 · Ton 26 Grad · b* +4,5 — Seitengrund */
  --tv-linen-150: #DAD1CA;   /* L* 84,4 · Buntheit 16 · Ton 26 Grad · b* +4,6 — Sektionsband */
  --tv-linen-200: #CDC4BD;   /* L* 79,7 · Buntheit 16 · Ton 26 Grad · b* +4,6
                                Flaeche: Feldfuellung, Zebrazeile, inaktive Pille.
                                Schrift: Sekundaertext auf der Umkehrflaeche (7,69 : 1). */
  --tv-linen-300: #8A7F78;   /* L* 54,0 — ruhiger Innentrenner (dekorativ, >= 2:1 auf allen
                                fuenf hellen Flaechen) und die Linie auf der Umkehrflaeche */
  --tv-linen-400: #695E58;   /* L* 40,8 — Haarlinie, >= 3:1 auf ALLEN fuenf hellen Flaechen */
  --tv-linen-500: #584F49;   /* L* 34,3 — starke Kontur */

  /* Kastanie — Schrift und die dunkle Umkehrflaeche. Tiefes warmes Braun,
     kein Schwarz, kein Teal. */
  --tv-kastanie:       #271F1B;   /* L* 12,5 — Fliesstext und Ueberschrift */
  --tv-kastanie-soft:  #473B35;   /* L* 25,9 — Sekundaertext UND Platzhalter (>= 4,5:1) */
  --tv-kastanie-faint: #897970;   /* L* 52,0 — NUR die Beschriftung inaktiver Bedienelemente
                                     auf der versenkten Fuellung (2,43:1); nie Fliesstext */
  --tv-kastanie-plane: #382E29;   /* L* 19,9 — Umkehrflaeche: Fusszeile, dunkler Block */

  /* Bluete — die EINE Aktionsfarbe, das Magenta der Bougainvillea.
     Als Punkt und als Route auf jeder hellen Basiskarte eindeutig. Drei getrennte
     Stufen: Fuellung, Text, Hover. Keine zwei tragen denselben Wert. */
  --tv-bluete:       #A80F4E;   /* L* 36,4 — gefuellte Flaeche, Kartenpin, Route */
  --tv-bluete-text:  #7E0938;   /* L* 26,5 — Bluete als Text, Link, Icon, Randstrich */
  --tv-bluete-hover: #691130;   /* L* 22,4 — Hover, EIGENE Stufe zwischen Text und Tief */
  --tv-bluete-tief:  #5C062A;   /* L* 18,2 — Gedrueckt, fuer Flaeche wie Text */
  --tv-bluete-hauch: #E6A3BA;   /* L* 73,9 — Markierung HINTER TEXT, Auswahl, Textselektion.
                                   Sie IST eine gefuellte Flaeche: eine kleine, hinter Text,
                                   in Pillenform. So steht sie in PALETTE.md Paragraph 4. */
  /* DER HAUCH BRAUCHT DIESELBEN DREI STUFEN WIE DIE FUELLUNG. Er hatte nur
     eine: die ausgewaehlte Etappenzeile trug ihn in Ruhe, im Hover und
     gedrueckt — der Craft-Kritiker hat 620 von 620 berechneten Eigenschaften
     identisch gemessen und die Ausschnittsfotos bitgleich. Eine Zeile, die
     ausgewaehlt ist, verlor damit jede Rueckmeldung auf die Maus.
     Gerechnet in CIELab D65 aus dem Hauch: gleicher Ton (a* 28,1), gleiche
     Buntheit, nur L* tiefer. Tinte bleibt auf beiden bei ≥ 4,5 : 1. */
  --tv-bluete-hauch-hover: #D694AB; /* L* 68,3 · dL* 5,6 · Tinte darauf 5,46 : 1 */
  --tv-bluete-hauch-tief:  #C7869C; /* L* 63,0 · dL* 10,9 · Tinte darauf 4,60 : 1 */

  /* Status — klein und selten. Deklarierte Formen: gefuellter Punkt (Kreis,
     12px), Randstrich 3px, eingefaerbtes Wort, Zustands-Pille (1px Kontur,
     24px hoch, 12px Versalien), konturierter Knopf in einer Statusfarbe.
     Die letzten beiden sind nach Stueck 2 bzw. 3 dazugekommen und standen
     bisher nur in PALETTE.md — diese Datei war beim Nachtragen ausgelassen.
     Nie eine Flaeche hinter Inhalt.

     Erfolg und Fehler liegen auf derselben Helligkeitsstufe (L* 30,1 / 30,0)
     und trennen sich ueber den Ton: 122 Grad gegen 11 Grad, Gruen gegen
     Ziegelrot, gegenueberliegende Haelften des Farbkreises. Bei der Warnung
     traegt der Ton allein nicht: 44 Grad gegen 11 Grad ist zu wenig, um zwei
     12px-Punkte auf einen Blick zu trennen — beide wurden zu braunen Flecken,
     und die alte Warnung (Ton 41, Buntheit 85) verschmolz zusaetzlich mit dem
     sandfarbenen Grund (Ton 26). Die Warnung trennt deshalb ueber HELLIGKEIT
     und BUNTHEIT: L* 38,2 gegen 30,0 und Buntheit 116 gegen 105. Die gleiche
     Helligkeit fuer alle drei war eine elegante Idee; sie verliert bei 12
     Pixeln gegen die Lesbarkeit. Keiner der drei traegt Magenta — der
     kritische Fall Fehler gegen --tv-bluete-text steht bei ΔE 29,2. */
  --tv-pinie:      #2A4F2B;   /* Erfolg  — Kiefernwald, kuehles Dunkelgruen.
                                 L* 30,1 · Buntheit  37 · Ton 122 Grad */
  --tv-bernstein:  #745500;   /* Warnung — Bernstein, gesaettigtes Gold.
                                 L* 38,2 · Buntheit 116 · Ton  44 Grad */
  --tv-terrakotta: #7F2A16;   /* Fehler  — Terrakotta, orange-seitiges Ziegelrot.
                                 L* 30,0 · Buntheit 105 · Ton  11 Grad */

  /* Fremdmaterial, kein Markenton: der gemessene Landton einer hellen
     Basiskachel. Er steht hier, weil er auf dem Blatt gezeichnet wird und weil
     jede gezeichnete Farbe ein deklariertes Token sein muss.

     Seine Rolle, so formuliert, dass sie das Gezeichnete deckt: dieses System
     WAEHLT ihn nie als Flaeche — er erscheint ausschliesslich dort, wo die
     Karte selbst gezeigt wird, und bringt seine Helligkeit von aussen mit. Wo
     er erscheint, ist er aber sehr wohl ein Grund: eine Karte traegt
     Beschriftung, im Produkt Ortsnamen, auf dem Spezimen ihren eigenen Namen
     und Hexwert. Sekundaertext, Fliesstext und die starke Kontur auf ihm sind
     deshalb als Kontrastpaare ausgewiesen wie auf jeder eigenen Flaeche.
     Form: wie jede Systemflaeche, 20 px Radius und Haarlinie. Die frueher hier
     stehende Sonderform "scharfe Ecken, 2 px --line-strong" ist zurueckgenommen
     (KARTE.md) — die gezeigte Kartenflaeche ist keine fremde Kachel mehr. */
  --tv-kachel-hell:   #FAFAF8;   /* L* 98,2 — Landton, gemessen */
  --tv-kachel-wasser: #D4DADC;   /* L* 86,7 — Wasser, gemessen. 70 % der Flaeche. */
  --tv-kachel-gruen:  #EEF3EE;   /* L* 95,4 — Gruenflaeche, gemessen */
  --tv-kachel-weg:    #F6F6F5;   /* L* 96,9 — helle Strasse, gemessen */
  /* Diese vier sind Fremdwerte und Messmaterial, keine Markentoene. Sie stehen
     hier aus demselben Grund wie der Landton: sie werden auf dem Kartenblatt als
     Vergleichsstreifen gezeichnet, und jede gezeichnete Farbe ist ein Token. */

  /* ---------------------------------------------------------------------------
     1b. PRIMITIVES — Raum, Radius, Zeit

     Die Leiter beginnt bei 8. Darunter gibt es EINE Stufe: 4 px, die Fuge
     zwischen zwei Zeilen desselben Gedankens (Etikett und Titel). Sie stand
     bis Runde 20 auf sechs Blaettern als 2, 6 oder 10 px roh im Blatt — neun
     Werte liefen an der Leiter vorbei. Eine Leiter, deren unterste Stufe zu
     grob ist, wird nicht benutzt, sondern umgangen.
     --------------------------------------------------------------------------- */
  --tv-space-0: 4px;
  --tv-space-1: 8px;
  --tv-space-2: 16px;
  --tv-space-3: 24px;
  --tv-space-4: 32px;
  --tv-space-5: 40px;
  --tv-space-6: 48px;
  --tv-space-7: 56px;
  --tv-space-8: 64px;
  --tv-space-10: 80px;
  --tv-space-13: 104px;

  /* Genau zwei substanzielle Radien. Pille fuer alles Klickbare und fuer
     alles, was wie ein Bedienelement geformt ist (Chip, Markierung hinter
     Text, Farbprobe); 20px fuer alles Flaechige. Der Kreis ist eine Form
     (Avatar, Statuspunkt), keine dritte Radiusentscheidung. Einen vierten
     Wert gibt es nicht; das Spezimen zaehlt seine Radien selbst aus. */
  --tv-radius-control: 999px;
  --tv-radius-surface: 20px;
  --tv-radius-circle:  50%;

  /* ---------- Ebenen ---------------------------------------------------------
     EINE LEITER, UND SIE FAENGT UEBER LEAFLET AN.
     Das System hatte keine: base.css setzte 800 an der Kartentafel mit einem
     Kommentar daneben, der Leaflets Ebenen aufzaehlt, und die Anwendung nannte
     --z-modal und --z-overlay, die es nirgends gab (sie loesten zu nichts auf,
     also lag der Dialog auf `auto`). Zwei Stellen, zwei Verfahren, eine Zahl
     von Hand.

     Leaflet vergibt bis 700 (tilePane 200, overlayPane 400, shadowPane 500,
     markerPane 600, tooltipPane 650, popupPane 700). Wer darueber liegen will,
     faengt deshalb bei 800 an — mit z-index 1 lag die Tafel unter den Kacheln,
     und das ist genau so passiert. */
  --z-karte-auflage: 800;   /* Tafel, Legende: liegt AUF der Karte */
  --z-leiste:        900;   /* Kopfleiste, Fussnavigation */
  --z-schleier:      1000;  /* Verdunkelung hinter einem Dialog */
  --z-dialog:        1010;  /* Dialog, Menue, Auswahlliste */
  --z-hinweis:       1020;  /* Kurzhinweis, Sprechblase — ueber allem */

  /* ---------- Verdunkelung ---------------------------------------------------
     WAS HINTER EINEM DIALOG LIEGT, IST KASTANIE — NICHT SCHWARZ.
     Das System hatte dafuer nichts, und die Anwendung half sich selbst:
     rgba(0,0,0,.85) hinter dem Bildbetrachter und eine lokale Variable hinter
     den Dialogen. Reines Schwarz ist auf warmem Leinen der eine Grauton, den
     diese Palette nirgends fuehrt.
     Zwei Dichten, weil sie zwei Aufgaben haben: hinter einem Dialog soll man
     sehen, wo man war; hinter einem Bild soll nichts ablenken. */
  --schleier:      rgba(39, 31, 27, 0.55);
  --schleier-tief: rgba(39, 31, 27, 0.88);

  --tv-dur-fast: 140ms;
  --tv-dur-base: 220ms;
  --tv-dur-slow: 400ms;
  --tv-ease:     cubic-bezier(0.2, 0, 0, 1);
  --tv-ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /* ---------------------------------------------------------------------------
     2. SEMANTIK — Farbe
     --------------------------------------------------------------------------- */
  --bg-float:      var(--tv-linen-0);         /* das lichte Ende: schwebendes Panel,
                                                 Dialog, Kopfbereich */
  --bg-raised:     var(--tv-linen-50);        /* Karte, Panel, Kartenausschnitt */
  --bg:            var(--tv-linen-100);       /* Seitengrund */
  --bg-band:       var(--tv-linen-150);       /* Sektionsband */
  --bg-sunken:     var(--tv-linen-200);       /* Feldfuellung, Zebrazeile, inaktive Pille */
  --bg-inverse:    var(--tv-kastanie-plane);  /* Fusszeile, geschlossener Block */

  --text:           var(--tv-kastanie);
  --text-muted:     var(--tv-kastanie-soft);   /* auch Platzhalter */
  --text-disabled:  var(--tv-kastanie-faint);  /* NUR inaktive Bedienelemente,
                                                  ausschliesslich auf --bg-sunken */
  /* linen-0 traegt zwei deklarierte Rollen: Flaeche (oben) und Schrift auf
     dunklem Grund. linen-200 ebenso: versenkte Flaeche und Sekundaertext auf
     der Umkehrflaeche. Beide Rollen stehen in PALETTE.md Paragraph 4. */
  --text-inverse:       var(--tv-linen-0);
  --text-inverse-muted: var(--tv-linen-200);
  --text-on-action:     var(--tv-linen-0);

  --action:        var(--tv-bluete);
  --action-text:   var(--tv-bluete-text);
  /* Ruhe, Hover und Gedrueckt sind DREI Stufen. Der Fehler ist zweimal
     aufgetreten und beide Male anders herum:
       Stueck 2, Runde 5 — Hover und Gedrueckt zeigten beide --tv-bluete-tief.
       Stueck 3, Runde 6 — Hover und TEXT zeigten beide --tv-bluete-text; damit
         aenderte a:hover nichts, und foundation.html druckte darunter den Satz
         "Keine zwei tragen denselben Wert".
     Repariert wurde beim ersten Mal die eine Kollision, ohne zu pruefen, ob die
     Reparatur eine zweite erzeugt. Hover hat jetzt eine eigene Stufe. */
  --action-hover:  var(--tv-bluete-hover);  /* #691130, L* 22,4 · Papier darauf 12,01 : 1 */
  --action-press:  var(--tv-bluete-tief);   /* #5C062A, L* 18,2 · Papier darauf 13,66 : 1 */
  --action-wash:   var(--tv-bluete-hauch);
  --action-wash-hover: var(--tv-bluete-hauch-hover);
  --action-wash-press: var(--tv-bluete-hauch-tief);

  /* GEDRUECKT DARF SICH NICHT AUF BEWEGUNG STUETZEN. Der Zustand trug den
     Unterschied zum Hover als translateY(1px) — und genau den nimmt
     prefers-reduced-motion zurueck. Alle drei Kritiker haben unabhaengig
     gemessen, dass Hover und Gedrueckt unter "reduce" an mehreren Elementen
     zusammenfielen, an der Zeile bitgleich. Wer Bewegung abschaltet, darf
     nicht den Zustand mit abschalten.
     Der Schatten ist die zweite, bewegungsfreie Marke: die Flaeche wird
     konkav. Er gilt in JEDER Bewegungseinstellung, der Versatz nur ohne. */
  --press-inset: inset 0 2px 4px rgba(56, 46, 41, 0.30);

  --success:       var(--tv-pinie);
  --warning:       var(--tv-bernstein);
  --danger:        var(--tv-terrakotta);

  /* Struktur — solide Linien, keine Alphawerte.
     --line traegt Information: FELDRAND, Tabellenregel, Kontur. Das ist die
     einzige Farbe, die einen Feldrand zeichnet; an keiner Stelle des Systems
     steht dafuer ein anderer Wert. Sie erreicht auf ALLEN fuenf hellen
     Flaechen mindestens 3:1 (6,19 / 5,34 / 4,74 / 4,17 / 3,66).
     --line-strong ist die staerkere Kontur mit ZWEI benannten Aufgaben: das
     AUSGEWAEHLTE Bedienelement und die Kontur eines konturierten Knopfes. Sie ist die
     einzige Linie, die 2px stark gezeichnet wird (--border-outline).
     foundation.html und PALETTE.md nannten bis Runde 7 nur EINE Aufgabe: beim
     Streichen der Fremdmaterial-Sonderform ist die zweite mit verschwunden,
     obwohl sie ein anderer Fall ist. Vier Fundstellen, zwei Antworten.
     --line-soft ist dekorativ und nie alleiniger Traeger einer Information;
     er haelt seine 2:1 auf allen fuenf hellen Flaechen (3,84 / 3,31 / 2,94 /
     2,59 / 2,27).

     KEINE Linie trennt zwei Flaechen voneinander: jedes Flaechenpaar, das auf
     dem Blatt aneinandergrenzt, erreicht ≥ 1,10 : 1 aus dem Farbwechsel
     allein. Das Blatt erhebt diese Paare selbst aus dem gerenderten Dokument,
     statt sie zu behaupten. */
  --line:         var(--tv-linen-400);
  --line-soft:    var(--tv-linen-300);
  --line-strong:  var(--tv-linen-500);
  --line-inverse: var(--tv-linen-300);

  --focus-ring: var(--tv-bluete-text);
  /* DER RING BRAUCHT ZWEI FASSUNGEN, WEIL ES ZWEI GRUENDE GIBT.
     Der Ring liegt mit 3 px Versatz AUSSERHALB der Pille — seine Nachbarfarbe
     ist also der Bandgrund, nicht der Knopf. Auf den hellen Gruenden traegt
     --focus-ring auf den hellen Gruenden von --focus-ring/--bg-sunken 6,16 : 1
     bis --focus-ring/--bg-float 10,43 : 1; auf dem Tintenband
     --focus-ring/--bg-inverse 1,25 : 1, und dort sitzt die letzte Handlung der
     Seite. Die helle Fassung traegt dort --focus-ring-hell/--bg-inverse
     13,01 : 1.
     HIER STAND "7,0 bis 9,0" — eine Spanne, die weder unten noch oben stimmte
     und die kein Waechter nachrechnen konnte, weil sie kein Paar nannte. Seit
     Stueck 4, Runde 8 faellt eine einstellige Verhaeltniszahl ohne
     Schrankenwort durch: als Messung ist sie zu grob geschrieben. */
  --focus-ring-hell: var(--tv-linen-0);

  /* Karte / Geodaten. Welcher Dienst die Kacheln liefert, ist offen und keine
     Designfrage (KARTE.md) — die Waermeregel gilt fuer jede helle Basiskarte. */
  /* DIE KACHELN KOMMEN VON OPENSTREETMAP UND WERDEN BEHANDELT.
     Der Anbieter ist OpenStreetMap: kostenlos und ohne Schluessel. Die zuvor
     eingebundenen CARTO-Kacheln (dark_all, ohne Schluessel) werden seit einer
     Aenderung bei CARTO mit "API KEY REQUIRED" bedruckt ausgeliefert.
     Roh ist OSM fuer diese Palette zu laut. Gemessen AM AUSGELIEFERTEN BLATT
     (Kachelbereich von karte.html, 1080 x 521 px, C* je Pixel in CIELab D65):
     roh mittlere Buntheit 15,5 und 44,5 in den lautesten Prozent, behandelt
     8,2 und 22,4.
     HIER STANDEN 6,4 UND 16,6. Diese Zahlen galten einer zweiten Stufe — einem
     leinenfarbenen Schleier ueber den Kacheln —, die nie gezeichnet hat
     (base.css zog ihre SVG auf 0 x 0) und deshalb ersatzlos gestrichen ist.
     Gemessen hatte ich sie in einem eigenen Pruefaufbau ohne base.css. Wer eine
     Zahl nicht am ausgelieferten Blatt erhebt, misst seine Absicht.
     Ebenfalls gestrichen: der Satz "nichts auf der Karte ist bunter als der
     Leinengrund (C* 16)". Die 16 ist die RGB-Spanne des Leinentons, seine
     Buntheit in CIELab ist 4,89 — zwei Skalen gleichgesetzt. Richtig ist:
     die Behandlung halbiert die Buntheit der Kacheln, und die Bluete als Route
     und Marke bleibt mit Abstand das Bunteste im Bild. */
  --map-kachel-filter:  saturate(.55) sepia(.10) contrast(.96);
  /* HIER STANDEN --map-tiles UND --map-tile-base und sind entfernt: der eine
     war eine Zeichenkette ohne Leser, der andere ein Fremdwert ohne Verwendung. */
  --map-paper:         var(--tv-linen-50);  /* Flaeche, in der die Karte sitzt */
  --map-pin:           var(--tv-bluete);
  --map-pin-selected:  var(--tv-kastanie);
  /* Die dritte Pin-Rolle heisst "Pruefen" und traegt die Warnfarbe. Sie hiess bis
     Stueck 2, Runde 4 --map-pin-planned und stand auf linen-500 (Grau), waehrend
     beide Blaetter Bernstein zeichneten und PALETTE.md Bernstein behauptete. Der
     alte Name kollidierte ausserdem mit dem Etappenzustand "Geplant", der KEINE
     Statusfarbe traegt. */
  --map-pin-pruefen:   var(--tv-bernstein);
  --map-route:         var(--tv-bluete);
  --map-route-luecke: var(--tv-linen-400);

  /* --- Kartenwaerme, festgelegt nach Messung an echtem Kachelmaterial ---------
     Eine helle Basiskarte ist zu rund 70 % Wasser, sobald eine Kueste im Bild ist, und dieses
     Wasser (#D4DADC) liegt 2,3 L* dunkler und 6,2 b* kuehler als unser Grund —
     Kontrast 1,07 : 1. Zu aehnlich, um sich abzusetzen; zu andersfarbig, um
     dazuzugehoeren. Die Kachel wird deshalb um 14 % mit dem Sandgrund
     ueberblendet und um 2,5 % aufgehellt. Wasser steigt damit auf L* 88,90 und
     b* -1,0: dieselbe Helligkeit wie der Grund, Kuehle groesstenteils weg.
     In Produktion gehoert das in den Kartenstil selbst, nicht
     als Filter ins Frontend. Der Filter unten ist die Notloesung, wenn der Stil
     noch nicht steht. Messung und Vergleich: karte.html */
  /* HIER STAND DER FARBSATZ DER GEZEICHNETEN KARTE — elf Token: die
     14-%-Waermeregel (--map-warm-mix/-with/-lift), --map-water-warmed und die
     sechs Kartenrollen --map-land, --map-water, --map-green, --map-road,
     --map-road-casing, --map-building.
     Sie waren Zielwerte fuer einen Kartenstil, den es nie gab, und faerbten
     nach der Umstellung auf OpenStreetMap-Kacheln nachweislich nichts mehr:
     null Verwendungen ueber alle Blaetter, Stile und Skripte. Zwei von ihnen
     trugen denselben Wert unter zwei Namen.
     Was die Kacheln wirklich tragen, misst karte.html am ausgelieferten Blatt;
     was das System darauf legt, sind --map-pin*, --map-route* und der Filter. */
  --map-pin-pruefen:   var(--tv-bernstein);
  --map-route:         var(--tv-bluete);
  --map-route-luecke: var(--tv-linen-400);

  /* --- Kartenwaerme, festgelegt nach Messung an echtem Kachelmaterial ---------
     Eine helle Basiskarte ist zu rund 70 % Wasser, sobald eine Kueste im Bild ist, und dieses
     Wasser (#D4DADC) liegt 2,3 L* dunkler und 6,2 b* kuehler als unser Grund —
     Kontrast 1,07 : 1. Zu aehnlich, um sich abzusetzen; zu andersfarbig, um
     dazuzugehoeren. Die Kachel wird deshalb um 14 % mit dem Sandgrund
     ueberblendet und um 2,5 % aufgehellt. Wasser steigt damit auf L* 88,90 und
     b* -1,0: dieselbe Helligkeit wie der Grund, Kuehle groesstenteils weg.
     In Produktion gehoert das in den Kartenstil selbst, nicht
     als Filter ins Frontend. Der Filter unten ist die Notloesung, wenn der Stil
     noch nicht steht. Messung und Vergleich: karte.html */
  --map-warm-mix:      14%;
  --map-warm-with:     var(--tv-linen-100);
  --map-warm-lift:     1.025;
  --map-water-warmed:  #DCE0E1;   /* L* 88,90 · b* -0,96 · Akzent darauf 5,55 : 1 */

  /* --- Die Karte hat einen eigenen Farbsatz ----------------------------------
     Der System-Kritiker hat zu Recht beanstandet, dass das Kartengruen als
     gefuellte Farbe ohne Token und ohne Rolle auftrat. Eine Karte ist aber keine
     Oberflaeche, die sich aus den Flaechentokens speisen laesst: sie hat eigene
     Bedeutungen (Land, Wasser, Gruenflaeche, Strasse), und die muessen benannt
     sein, damit ein Kartenstil sie setzen kann. Werte aus der 14-%-Waermeregel,
     Diese vier sind ZIELWERTE fuer einen Kartenstil, nicht das Ergebnis der
     14-%-Regel. Der Kommentar behauptete das bis Runde 5 und war fuer drei von
     vier Werten falsch: angewandt auf Land ergaebe die Regel L* 99,0 statt 93,0,
     auf Gruen 96,5 statt 89,5, auf Strasse 98,0 statt der damaligen 94,3. Die Regel beschreibt,
     wie ein zu kuehler Wasserton auf die Helligkeit des Grundes gebracht wird;
     die uebrigen drei Rollen sind gesetzt, damit die Karte als eigene Flaeche
     liest. Nur --map-water folgt der Regel unmittelbar. */
  --map-land:   #F0EAE4;   /* L* 93,00 · b* +3,62 — 1,11 : 1 gegen --bg.
                              Lag bis Runde 5 bitgleich auf --bg und damit auf
                              1,00 : 1 — genau der Fall, den KARTE.md im eigenen
                              Befund als "zu aehnlich zum Absetzen" verwirft. */
  --map-water:  #DCE0E1;   /* L* 88,90 — gewaermtes Wasser */
  --map-green:  #DCE3D8;   /* L* 89,4 — gewaermte Gruenflaeche */
  /* Die Strassenfassung und der Siedlungsblock werden gezeichnet und waren bis
     Runde 9 die einzigen zwei Farben der Kartenflaeche ohne Token — 6,5 % der
     Flaeche, gegen die eigene Regel "jede Farbe, die gezeichnet wird, ist als
     Hex-Token deklariert". Sie kamen mit der Fassung in Runde 8 dazu. */
  --map-road-casing: #DFD7D3;   /* L* 86,50 · 1,19 : 1 gegen --map-land */
  --map-building:    #E6DDD4;   /* Siedlungsblock */
  --map-road:   #FDF8F1;   /* L* 97,78 · 1,13 : 1 gegen --map-land.
     Hier stand #F2EEE9 (L* 94,27) — 1,27 Punkte ueber dem Land und damit
     unsichtbar. Aufgefallen erst, als die Kartenflaeche in Runde 7 auf die
     deklarierten Tokens umgefaerbt wurde: vorher war sie ein Erzeugnis, das
     seine eigenen, hellen Strassen mitbrachte (gemessen 9,65 Punkte ueber
     ihrem Land) und die Deklaration nie einloeste. Ein Token, das nichts
     einfaerbt, wird nicht falsch — es wird nur nicht bemerkt. */

  /* ---------------------------------------------------------------------------
     2b. SEMANTIK — Typografie
     Drei variable Familien, drei getrennte Aufgaben:
       Bricolage Grotesque — Display und Ueberschriften. Grotesk mit Tintenfallen
                             und echter opsz-Achse; laut, aber keine Zierschrift.
       Archivo             — Fliesstext und Bedienoberflaeche. Gothic-Werkschrift
                             mit Weitenachse, verwandt mit Wegweiserschrift.
       JetBrains Mono      — Daten und deklarierte Werte: Koordinaten,
                             Distanzen, Zeiten, IDs, Hexwerte, Tokennamen,
                             CSS-Werte und Messzahlen. Nie Fliesstext, nie
                             Ueberschrift, nie ein Wort ohne Zahl oder
                             Kennung daneben — Rollennamen, Schriftnamen und
                             Regeln laufen in Archivo.
     Regel: letter-spacing bleibt ueberall `normal`. Einzige Ausnahme: .t-over.
     --------------------------------------------------------------------------- */
  --font-display: "Bricolage Grotesque", "Archivo", ui-sans-serif, system-ui,
                  "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-text:    "Archivo", ui-sans-serif, system-ui, -apple-system,
                  "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo,
                  Consolas, monospace;

  /* Optische Groesse und Weite pro Ueberschriftenstufe — echte Achsen,
     kein Skalieren. Die Ueberschriften laufen schmal: das ist die Sprache
     von Fahrplaenen und Wegweisern, und es ist der deutlichste Abstand
     zu jeder normalbreiten Grotesk. Schmal ist eine Breitenachse, keine
     Sperrung: letter-spacing bleibt normal. */
  --opsz-display: 96;
  --opsz-h1: 72;
  --opsz-h2: 48;
  --opsz-h3: 32;
  --wdth-display: 78;
  --wdth-heading: 88;

  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;

  /* Knopf — zwei Hoehen als Rang, nicht als Geschmack. Bis Stueck 3, Runde 6
     stand der Knopf nur lokal in den Blaettern; die 44er Hoehe war ein
     Inline-Attribut ohne Deklaration. Siehe base.css .t-knopf. */
  /* Schwebende Tafel auf der Kartenflaeche — siehe base.css .t-tafel */
  --tafel-einzug:  24px;
  --tafel-breite: 300px;

  --knopf-hoehe:         52px;   /* die eine primaere Handlung einer Ansicht */
  --knopf-hoehe-klein:   44px;   /* jede weitere Handlung */
  --knopf-polster:       30px;
  --knopf-polster-klein: 22px;
  --weight-bold:     700;
  /* Der Displayrang. Bis Runde 15 stand 800 als rohe Zahl in base.css — der
     EINZIGE Rangwert ohne Token, und zwar in der Datei, die alle Blaetter
     teilen, waehrend .t-h1/.t-h2/.t-h3 daneben var(--weight-*) benutzen. */
  --weight-black:    800;

  /* Skala. Genau DREI laufende Groessen unter 24px: 16 / 14 / 12.
     Body traegt den Fliesstext, Detail die Tabellenzelle und die Hilfszeile,
     Caption die Metazeile und die Bildunterschrift.
     Display 88px zu Fliesstext 16px ist Faktor 5,5.

     Lead (25px) ist AUSSCHLIESSLICH DER EINLEITUNGSABSATZ — der Absatz, der
     einen Abschnitt eroeffnet. Bis Runde 7 stand hier "ZWISCHENUEBERSCHRIFT UND
     EINLEITUNGSABSATZ: h3, Kartentitel, Dialogtitel"; das widerspricht bar.md M1
     ("ein Grad traegt genau einen Rang: 25 px ist der Absatz und nur der
     Absatz, 30 px die Zwischenueberschrift und nur sie") und war seit Runde 5c
     auf keinem der sechs Blaetter mehr gezeichnet. Der Widerspruch stand nur
     noch in der Deklaration — genau dort, wo ihn niemand sieht.
     Lead IST eine laufende Groesse im Sinn von M1 (es setzt Absaetze); das
     Referenzmaß sind drei, die Obergrenze vier, und mit 25/16/14/12 stehen wir
     auf vier. Der Satz "setzt nie einen Absatz"
     stand hier seit Stueck 2, Runde 5 und ist nach Stueck 3 gestrichen: ein
     Einleitungsabsatz auf dieser Stufe ist die klassische Rolle der Groesse. Hier stand bis
     Stueck 2, Runde 4 "kommt hoechstens zweimal pro Seite vor" — das war eine
     Zusage aus Stueck 1, die kein Blatt eingeloest hat und die auch keinen
     Zweck erfuellt: eine Zwischenueberschrift darf so oft vorkommen wie es
     Abschnitte gibt. Was M1 zaehlt, sind laufende Groessen, nicht Stufen.

     Was die Blaetter in Runde 4 tatsaechlich zeichneten: elf laufende Groessen
     auf einem Blatt, darunter 15px als haeufigste — ein Wert, der in dieser
     Skala nie stand. Alle Blaetter sind seither auf 12/14/16 plus die Stufen
     25/30/38/56/88 gesetzt. */
  --text-caption-size: 12px;  --text-caption-lh: 1.42;
  --text-detail-size:  14px;  --text-detail-lh:  1.50;
  --text-body-size:    16px;  --text-body-lh:    1.65;
  --text-lead-size:    25px;  --text-lead-lh:    1.44;
  /* KEINE KLAMMER DARF AUF DEN GRAD DARUNTER FALLEN.
     Bis Runde 16 war der Boden jeder Klammer der Wert ihres Nachbarn: h2 fiel
     auf 30px — den Grad von h3 — und h1 auf 38px, den oberen Anschlag von h2.
     Unter 910 px Fensterbreite standen h3 und h2 damit in DERSELBEN Groesse und
     unterschieden sich nur noch in der opsz-Achse (32 gegen 48): ein Grad, zwei
     Schnitte, also genau der Befund, den Pruefung (8) sucht — sie lief nur nie
     bei einer Breite, bei der die Klammer nicht gesaettigt ist.
     Die Leiter behaelt ihre Stufen jetzt bis 800 px hinunter: 30 / 33 / 41 / 52. */
  --text-h3-size:      30px;  --text-h3-lh:      1.24;
  --text-h2-size:      clamp(33px, 3.3vw, 38px);  --text-h2-lh: 1.12;
  --text-h1-size:      clamp(41px, 5.2vw, 56px);  --text-h1-lh: 1.05;
  --text-display-size: clamp(52px, 8.4vw, 88px);  --text-display-lh: 0.96;

  /* Kleines Versalien-Label — die EINZIGE Stelle mit Sperrung. */
  --text-over-size: 12px;  --text-over-ls: 0.09em;

  /* Datenzeile (mono). Laeuft auf der Detailstufe, fuegt keine Groesse hinzu. */
  --text-data-size: 14px;  --text-data-lh: 1.50;

  /* ---------------------------------------------------------------------------
     2c. SEMANTIK — Form, Hoehe, Rhythmus (Default = Marketing)
     --------------------------------------------------------------------------- */
  --radius-control: var(--tv-radius-control);  /* Klickbares, Chip, Markierung, Probe */
  --radius-surface: var(--tv-radius-surface);  /* alles Flaechige */
  --radius-circle:  var(--tv-radius-circle);   /* Avatar, Statuspunkt */

  /* Zwei Strichstaerken, beide ganzzahlig. 1,5px war eine Zusage, die kein
     Bildschirm einloest: der Browser zeichnet daraus 1px. Was hier steht, ist
     deshalb der Wert, der auch gezeichnet wird. */
  --border-hairline: 1px;   /* --line und --line-soft */
  --border-outline:  2px;   /* --line-strong: Kontur des ausgewaehlten
                               Bedienelements, konturierter Knopf */

  /* Zwei Schatten, beide aus der Schriftfarbe abgedunkelt. Alpha ist hier der
     einzige zulaessige Nicht-Hex-Wert: ein Schatten ist keine Flaeche,
     sondern eine Abdunklung des Grundes. */
  --shadow-whisper: rgba(39, 31, 27, 0.10) 0 1px 2px, rgba(39, 31, 27, 0.10) 0 3px 10px -4px;
  --shadow-float:   rgba(39, 31, 27, 0.14) 0 2px 4px, rgba(39, 31, 27, 0.22) 0 14px 34px -12px;

  /* DER SATZSPIEGEL. Bis Runde 12 stand hier 1200 px und base.css las ihn —
     und alle SECHS Blaetter ueberschrieben .page lokal mit 1260/90 (foundation
     mit 1160/40, was dieselbe sichtbare Spalte 180..1260 ergibt). Ein Wert in
     der geteilten Datei, den kein Blatt benutzt, ist keine Regel, sondern eine
     Attrappe. Die Regel steht jetzt einmal in base.css und wird ueber diese
     zwei Token PARAMETRIERT statt neu deklariert. */
  --page-max:  1260px;
  --page-rand: 90px;
  --prose-max: 62ch;
  --section-gap:   var(--tv-space-10);  /* 80px */
  --card-padding:  var(--tv-space-4);   /* 32px */
  --element-gap:   var(--tv-space-2);   /* 16px */
  --kopf-luft:     var(--tv-space-5);   /* 40px, Untergrenze ueber h2/h3 */
  --band-luft:     var(--tv-space-5);   /* 40px, Einleitungszeile -> Bauteil */
  /* Bauteiltitel -> sein Text. Bis Runde 15 trug derselbe Titelschnitt drei
     Abstaende: 29,19 / 13,19 / 7,19 px Tinte zu Tinte, Verhaeltnis 4,1 zu 1. */
  --titel-luft:    var(--tv-space-1);   /* 8px */
  --band-polster:  var(--tv-space-10);  /* 80px, oben und unten am Sektionsband */

  color-scheme: light;
}

/* -----------------------------------------------------------------------------
   3. DICHTE — "compact" fuer die Planungs-App

   Gleiche Farben, gleiche Formen, gleiche Sperrungsregel — engerer Rhythmus.
   Die drei laufenden Lesegroessen (16 / 14 / 12) bleiben UNVERAENDERT: ueber
   einer Karte ist Lesbarkeit wichtiger als Dichte. Was sich verdichtet, sind
   die Ueberschriften, die Abstaende und die Bedienhoehen.
   ----------------------------------------------------------------------------- */
[data-density="compact"] {
  --text-lead-size:    19px;  --text-lead-lh:    1.45;
  --text-h3-size:      21px;  --text-h3-lh:      1.28;
  --text-h2-size:      24px;  --text-h2-lh:      1.20;
  --text-h1-size:      30px;  --text-h1-lh:      1.12;
  --text-display-size: 40px;  --text-display-lh: 1.05;

  --opsz-display: 40;
  --opsz-h1: 32;
  --opsz-h2: 26;
  --opsz-h3: 21;
  --wdth-display: 84;
  --wdth-heading: 92;

  --section-gap:   var(--tv-space-4);   /* 32px */
  --card-padding:  var(--tv-space-3);   /* 24px */
  --element-gap:   var(--tv-space-1);   /* 8px */
  --kopf-luft:     var(--tv-space-3);   /* 24px */
  --band-luft:     var(--tv-space-3);   /* 24px */
  --titel-luft:    var(--tv-space-1);   /* 8px */
  --band-polster:  var(--tv-space-4);   /* 32px */
  /* DIE BEDIENHOEHE IST DIE KNOPFHOEHE — es gibt nur eine Familie.
     Bis Runde 10 standen hier --control-height/--control-padding-x neben
     --knopf-hoehe/--knopf-polster: gleiche Hoehe (52), verschiedenes Polster
     (28 gegen 30), und in dieser Dichtestufe auch verschiedene Hoehe. Das
     Blatt, das den Knopf definiert, zeichnete ihn dadurch 4 px schmaler als
     das Bauteil.
     In der dichten Stufe faellt der RANG weg, nicht das Mass: eine
     Planungsflaeche unterscheidet ihre Handlungen durch Fuellung, nicht durch
     Groesse. Beide Raenge laufen deshalb auf der zweiten Stufe der Regelleiter
     (44/22) — keine neue Zahl, eine vorhandene. */
  --knopf-hoehe:         44px;
  --knopf-hoehe-klein:   44px;
  --knopf-polster:       22px;
  --knopf-polster-klein: 22px;
  --page-max: none;
}

/* -----------------------------------------------------------------------------
   4. BEWEGUNG
   ----------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  :root {
    --tv-dur-fast: 1ms;
    --tv-dur-base: 1ms;
    --tv-dur-slow: 1ms;
  }
}

/* -----------------------------------------------------------------------------
   DER SEITENRAND SCHRUMPFT MIT.
   90 px sind auf einem 1440-px-Fenster eine Rinne und auf einem 320-px-Fenster
   die halbe Seite: gemessen blieben dort 140 px = 43,7 % fuer den Inhalt, und
   der Fliesstext brach nach zwei Woertern um. Bis Stueck 4, Runde 7 nahm genau
   EIN Blatt (foundation) den Rand lokal zurueck; die anderen fuenf standen mit
   90 px da, waehrend dieselbe Runde ihre Raster schmal gemacht hat. Die Spalten
   schmal und die Rinne breit ist kein schmales Raster.
   ----------------------------------------------------------------------------- */
@media (max-width: 900px) {
  :root { --page-rand: 24px; }
}
