/* ═══════════════════════════════════════════════════════════════════════════
   TOKENS — die einzige Quelle für Farbe, Fläche, Maß und Bewegung
   ═══════════════════════════════════════════════════════════════════════════

   Wird NACH core.css geladen — das ist wichtig:

     <link rel="stylesheet" href="css/core.css?v=…">
     <link rel="stylesheet" href="css/tokens.css?v=…">   ← hier
     <link rel="stylesheet" href="css/icons.css?v=…">
     …

   core.css deklariert die Legacy-Tokens (--bg1, --txm, --purple …) in einem
   eigenen :root-Block. Bei gleicher Spezifität gewinnt die spätere
   Deklaration; lädt tokens.css davor, bleiben die alten Werte stehen und die
   Alias-Bridge tut nichts. Sobald der :root-Block aus core.css entfernt ist,
   wird die Reihenfolge gleichgültig.

   In allen fünf Entrypoints mit externen Stylesheets:
   index.html · admin.html · mieter-portal.html · handwerker-portal.html ·
   eigentuemer-portal.html

   Der Alias-Block am Ende ist der Grund, warum diese Datei allein schon
   den Großteil der App umfärbt: von 3.909 Inline-Styles im JS referenzieren
   2.166 bereits var(--…). Werte wechseln, Namen bleiben — nichts muss
   angefasst werden.

   Referenz für alle Zahlenwerte: docs/design/redesign-mockup.html
   Begründungen: docs/design/REDESIGN-IMPLEMENTATION.md
   ═══════════════════════════════════════════════════════════════════════════ */

:root {

  /* ── Flächenleiter · Dark ─────────────────────────────────────────────────
     Warmes Graphit, Farbton ~30°, Sättigung 4-6 %. Vorher war alles
     #12151e — Farbton 224°, Sättigung 25 %, also blaustichiges Slate.
     Blaustichiges Slate plus Violett IST die generierte Palette.

     L*-Stufen von ~4 Einheiten, damit die Leiter überhaupt wahrnehmbar ist:
     vorher hatten Rail, Topbar, Sidebar und Content identische Luminanz.       */
  --s-rail:      #0f0e0d;   /* Nav-Rail — dunkelste Fläche, tritt zurück      */
  --s-canvas:    #141312;   /* body, Modul-Hintergrund                        */
  --s-bar:       #181716;   /* Topbar, Sticky-Tabellenköpfe, Tab-Leisten      */
  --s-panel:     #1c1b19;   /* Listen-Sidebar                                 */
  --s-content:   #1e1d1b;   /* Hauptinhalt — größte Fläche, deshalb hellste   */
  --s-raised:    #252321;   /* Cards, KPI-Tiles, Formularsektionen, Modals    */
  --s-overlay:   #2b2926;   /* Dropdowns, Toasts, Tooltips                    */
  --s-input:     #1a1918;   /* Eingabefelder auf --s-raised                   */
  --s-hover:     #2b2926;   /* Zeilen-/Item-Hover                             */
  --s-selected:  #332f2b;   /* ausgewählte Zeile — neutral, NICHT eingefärbt  */
  --s-sunken:    #101010;   /* Codeblöcke, Diagramm-Wannen, Fortschritt-Bahn  */

  /* ── Text · Dark ──────────────────────────────────────────────────────────
     Solide Hexe statt Alpha. Der alte --txm: rgba(232,230,225,.36) ergab
     auf 10px-Uppercase rund 2,90:1 — das war der Lesbarkeits-Bug.
     Regel: maximal drei Textebenen pro Komponente. --t-4 ist keine
     Textfarbe, sondern ein Zustand.                                           */
  --t-1:   #f2efeb;   /* Fließtext, Werte, Titel        · 14-16:1             */
  --t-2:   #b3ada6;   /* Unterzeilen, Metadaten          ·  7,0-8,4:1         */
  --t-3:   #948d85;   /* Captions, Tabellenköpfe         ·  4,8-5,7:1         */
  --t-4:   #6b655f;   /* NUR deaktiviert, nie Information                     */
  --t-inv: #131211;   /* Text auf hellen Füllungen                            */

  /* ── Linien ───────────────────────────────────────────────────────────────
     Solide statt Alpha, damit sie auf jeder Fläche identisch aussehen.       */
  --line:        #2a2724;
  --line-strong: #3a3632;   /* Input-Rahmen, Tabellenkopf-Linie, Trenner      */
  --bw: 1px;
  /* Die 1px-Innenkante ist es, die eine Card im Dark-Theme erhaben wirken
     lässt. Drop-Shadows leisten das nicht — siehe --sh-1.                    */
  --line-inset:  inset 0 1px 0 rgba(255,255,255,.045);

  /* ── Marke ────────────────────────────────────────────────────────────────
     Petrol. Sparsam: Akzent erscheint nur als Identität oder Ortsmarkierung,
     nie als Text, nie als große Fläche. Erlaubt, abschließend:
     Logo · Rail-Aktiv-Balken 3×18px · Tab-Unterstrich 2px · Zeilenkante 2px ·
     Fokusring · genau ein gefüllter CTA (Login) · Chart-Serie 1.             */
  --brand:        #0f5c6b;   /* rein — Logo auf hellem Grund, Füllung         */
  --brand-ink:    #58c2d6;   /* aufgehellt — für dunkle Flächen               */
  /* Indikatorfarbe ≠ Markenfarbe. Petrol pur als 3px-Balken auf --s-content
     ergibt 2,22:1, also unsichtbar. Im Dark-Theme muss der Indikator die
     aufgehellte Variante nehmen (dann 8,10:1). Gleiches Prinzip wie
     frontend/img/brand/valtio-lockup-dark.svg.                               */
  --brand-mark:   var(--brand-ink);
  --brand-fill:   #0f5c6b;   /* weiß darauf = 7,60:1                          */
  --brand-fill-h: #0b4854;
  --brand-ring:   rgba(15,92,107,.34);

  /* ── Semantik · Dark ──────────────────────────────────────────────────────
     Vier Slots je Bedeutung. `tint` ist ein VORBERECHNETER Hex, kein Alpha —
     nur so komponiert ein Badge auf jeder Fläche identisch. Der alte
     .vb-red (rgba(239,68,68,.12) mit color:#dc2626) kam in Dark auf 3,05:1.  */
  --ok-ink: #4ade80;  --ok-fill: #15803d;  --ok-tint: #16251c;  --ok-line: #245334;
  --wa-ink: #fbbf24;  --wa-fill: #b45309;  --wa-tint: #2a2116;  --wa-line: #5a4419;
  --da-ink: #ff5f6d;  --da-fill: #c8102e;  --da-tint: #2b1a1c;  --da-line: #5e2429;
  /* Info liegt bei ~226° statt ~201°: Petrol (~190°) wäre sonst nur 11°
     entfernt und Primary-Button und Info-Badge würden als dieselbe Farbe
     gelesen. 36° Abstand sind genug.                                          */
  --in-ink: #93b4fd;  --in-fill: #1e40af;  --in-tint: #171b28;  --in-line: #2c3a63;

  /* ── Kategoriepunkte ──────────────────────────────────────────────────────
     Kategorien (Mieter, Eigentümer, …) dürfen keine gefüllte Semantikfarbe
     belegen, sonst konkurrieren Kategorie und Status in derselben Zeile.
     Deshalb: neutrales Badge + 6px-Punkt. Farbtöne über den Farbkreis
     gespreizt, keiner nahe an Petrol (~190°).                                */
  --cat-mieter:       #5b8def;   /* 218° Blau      */
  --cat-eigentuemer:  #c9922e;   /*  40° Amber     */
  --cat-handwerker:   #cf5f3a;   /*  16° Orangerot */
  --cat-firma:        #8a8f99;   /*      Kühlgrau  */
  --cat-versorger:    #4a9d5f;   /* 137° Grün      */
  --cat-versicherung: #8b7fd4;   /* 250° Violett   */
  --cat-behoerde:     #a86fa0;   /* 310° Magenta   */
  --cat-sonstiges:    #8d867e;   /*      Warmgrau  */

  /* ── Primary-Button ───────────────────────────────────────────────────────
     Akzentgefüllt (Entscheidung vom 30.07.2026).
     ACHTUNG White-Label: Tenants setzen `akzentfarbe` frei. --pri-fg wird
     deshalb in auth.js aus der Luminanz der Tenant-Farbe berechnet, nicht
     hier festgelegt. Ohne das fallen 3 von 6 Testfarben durch AA.            */
  --pri-bg:   var(--brand-fill);
  --pri-fg:   #ffffff;
  --pri-bg-h: var(--brand-fill-h);
  --pri-bg-a: var(--brand-fill-h);

  /* ── Spacing ──────────────────────────────────────────────────────────────
     Zu fegen: 1, 3, 5, 7, 9, 11, 13, 15, 18, 21, 22, 26, 28, 36.
     Mapping: 1|3→2|4 · 5→4|6 · 7→6|8 · 9→8|10 · 11→10|12 · 13→12|14 ·
              15→14|16 · 18→16|20 · 26|28→24 · 36→32                          */
  /* Tokenname = Pixelwert. Kein Kopfrechnen, keine Verwechslung.
     4px-Schritte sind der Regelfall. 6/10/14px sind zugelassene
     2px-Zwischenschritte für die INNENabstände kleiner Controls — dort ist
     8px zu eng und 12px zu weit. Gemessen kommen sie 1.401× vor, während
     die echte Willkür (5/3/7/9/11/13px) bei ~490 liegt.                     */
  --sp-2:   2px;   /* optische Icon-Korrekturen              */
  --sp-4:   4px;
  --sp-6:   6px;   /* Innenabstand Badge, kleiner Button     */
  --sp-8:   8px;
  --sp-10: 10px;   /* Innenabstand Input, Menüeintrag        */
  --sp-12: 12px;
  --sp-14: 14px;   /* Innenabstand großer Button            */
  --sp-16: 16px;
  --sp-20: 20px;  --sp-24: 24px;  --sp-32: 32px;
  --sp-40: 40px;  --sp-48: 48px;  --sp-64: 64px;

  /* ── Typografie ───────────────────────────────────────────────────────────
     Basis 12px → 13px. 12px war der Grund, warum überhaupt 7,5-11,5px-Größen
     nötig wurden: alles war von einer zu kleinen Basis herunterskaliert.
     IBM Plex Sans hat eine kleinere x-Höhe als DM Sans, der scheinbare
     Zuwachs liegt bei ~4 %.

     Gelöscht: 7,5 · 8,5 · 9 · 9,5 · 10,5 · 11,5 · 12,5 · 14 · 16 · 20 · 24 ·
     26 · 32. Mapping: 14→15 · 16→15|18 · 20→18|22 · 24|26→22|28              */
  --font-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --fs-1: 11px;   /* Captions, Tabellenköpfe, Badges, Zähler */
  --fs-2: 12px;   /* Unterzeilen, Metadaten, dichte Zellen   */
  --fs-3: 13px;   /* BASIS — Text, Zellen, Buttons, Inputs   */
  --fs-4: 15px;   /* Card-Titel, Abschnitts-Überschriften    */
  --fs-5: 18px;   /* Ansichts- und Modal-Titel               */
  --fs-6: 22px;   /* Name im Detail-Kopf                     */
  --fs-7: 28px;   /* KPI-Werte                               */

  --lh-none:   1;      --lh-tight:  1.25;
  --lh-snug:   1.4;    --lh-normal: 1.5;

  --ls-tight: -0.011em;   /* ab 18px         */
  --ls-0:      0;         /* 13-15px         */
  --ls-wide:   0.005em;   /* 11-12px         */
  --ls-caps:   0.06em;    /* nur Großbuchst. */

  /* Gewichte. 400 ist der neue Default — vorher kam es genau 1× vor,
     während 600 113× auftrat. Deshalb wirkte alles gleich laut.
     400 Text, Zellen, Unterzeilen, Badges · 500 Labels, Tabellenköpfe,
     Nav · 600 Card-/Ansichtstitel, Buttons, aktiver Tab, Zeilentitel ·
     700 ausschließlich KPI-Werte und der Name im Detail-Kopf.                */
  --fw-normal: 400;  --fw-medium: 500;  --fw-semi: 600;  --fw-bold: 700;

  /* ── Radien ───────────────────────────────────────────────────────────────
     Vier Stufen statt 4/6/7/8/10/12/16/20px.                                 */
  --r-1: 4px;    /* Badges, Tags, kleine Inputs, Diagrammbalken */
  --r-2: 6px;    /* Buttons, Inputs, Selects, Icon-Buttons      */
  --r-3: 8px;    /* Cards, Dropdowns, Toasts                    */
  --r-4: 12px;   /* Modals, Login-Card                          */
  --r-full: 999px;  /* NUR Avatare, Zähler, Statuspunkte        */

  /* ── Schatten ─────────────────────────────────────────────────────────────
     Im Dark-Theme bekommen Cards KEINEN Schatten: ein rgba(0,0,0,.35) über
     #1e1d1b verschiebt die Luminanz um <0,004 — unsichtbar. Und der weiche
     Schwebe-Look ist selbst ein KI-Tell. Stattdessen Flächenstufe + Linie +
     --line-inset. Overlays bekommen echte Schatten, weil sie die Ebene
     brechen müssen; im Dark zusätzlich einen Haarlinien-Ring, weil der
     Schatten allein die Kante nicht trägt.                                    */
  --sh-1: none;
  --sh-2: 0 8px 20px rgba(0,0,0,.55), 0 0 0 1px rgba(0,0,0,.65), var(--line-inset);
  --sh-3: 0 24px 56px rgba(0,0,0,.68), 0 0 0 1px rgba(0,0,0,.70), var(--line-inset);
  --sh-focus: 0 0 0 3px var(--brand-ring);

  /* ── Bewegung ─────────────────────────────────────────────────────────────
     Der globale `*, *::before, *::after { transition: … }`-Selektor in
     core.css:114-116 wird gelöscht: er macht jeden Hover träge und erzwingt
     die `svg,canvas,.toast{transition:none!important}`-Notbremse zwei Zeilen
     darunter. Ersatz: Transitions je Komponente.                             */
  --t-fast: 120ms;   /* Hover, Farbe            */
  --t-base: 180ms;   /* Dropdown, Panel         */
  --t-slow: 260ms;   /* Modal, Drawer, Rail     */
  --ease-out:    cubic-bezier(.2,.7,.35,1);
  --ease-in-out: cubic-bezier(.4,0,.2,1);

  /* ── Dichte ───────────────────────────────────────────────────────────────
     User-Präferenz, umschaltbar wie Dark/Light. localStorage-Key
     valtio_density, data-density auf <html>. Der virtuelle Scroller in
     kontakte.js MUSS --row-h auslesen statt `const H = 62`.                  */
  --row-h:    52px;   /* Listenzeile, zwei Textzeilen (Kontakte)          */
  --row-h-lg: 62px;   /* Listenzeile, drei Textzeilen (Aufgaben: Titel,
                         Unterzeile, Badge-Reihe)                        */
  --cell-h:   38px;   /* Tabellenzelle                                   */
  /* Vertikaler Innenabstand einer Listenzeile. Nötig, weil die meisten
     Listen KEINE feste Höhe setzen: sie wachsen mit ihrem Inhalt, und ein
     min-height greift dort nie. Nur Kontakte und Aufgaben bekommen vom
     virtuellen Scroller eine feste Inline-Höhe. Ohne dieses Token wirkte
     die Dichte-Einstellung sichtbar nur in diesen beiden Listen.          */
  --row-pad:  10px;
  /* Avatar/Icon-Kachel in Listenzeilen. Muss mitskalieren: eine feste 40px-
     Kachel in einer 40px-Zeile berührt beide Kanten, und die Zeile wirkt
     gequetscht — der Textblock braucht gemessen nur 33px, die Kachel war
     der Engpass.                                                          */
  --row-avatar: 34px;

  /* ── Z-Index ──────────────────────────────────────────────────────────────
     Unverändert aus core.css übernommen. Nicht anfassen — daran hängen
     Modals, Panels und Toasts. Bekannte Umgehung: core.css:741 und :820
     hardcoden 1000/1001 für die Mobile-Nav.                                  */
  --z-topbar: 20;        --z-nav-rail: 100;     --z-dropdown: 700;
  --z-user-menu: 1000;   --z-modal: 2000;       --z-hilfe-overlay: 2500;
  --z-hilfe-panel: 2600; --z-toast: 9999;

  /* Native Controls einfärben — betrifft Checkbox, Radio, Range, Progress
     und die Auswahlmarkierung. Kommt heute genau 2× im Projekt vor.          */
  accent-color: var(--brand-mark);
  color-scheme: dark;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LIGHT
   Im Light-Theme ist der Inhalt die HELLSTE Fläche — genau umgekehrt zu Dark.
   ═══════════════════════════════════════════════════════════════════════════ */
[data-theme="light"], html.light-mode {
  --s-rail:     #f0eeec;   --s-canvas:   #f4f2f0;   --s-bar:      #faf9f8;
  --s-panel:    #faf9f8;   --s-content:  #ffffff;   --s-raised:   #ffffff;
  --s-overlay:  #ffffff;   --s-input:    #ffffff;
  --s-hover:    #f4f2f0;   --s-selected: #eceae7;   --s-sunken:   #f0eeec;

  --t-1: #1b1917;  --t-2: #57534e;  --t-3: #78716c;  --t-4: #a8a29e;
  --t-inv: #ffffff;

  --line: #e6e2de;  --line-strong: #cfc9c2;  --line-inset: none;

  --brand-ink:  #0d4f5c;
  --brand-mark: var(--brand);   /* hier trägt die reine Marke: 7,60:1 */

  --ok-ink: #15803d;  --ok-fill: #15803d;  --ok-tint: #eaf6ee;  --ok-line: #bfe0cb;
  --wa-ink: #b45309;  --wa-fill: #b45309;  --wa-tint: #fdf3e6;  --wa-line: #f0d9b4;
  --da-ink: #c8102e;  --da-fill: #c8102e;  --da-tint: #fdecee;  --da-line: #f4c6cd;
  --in-ink: #1e40af;  --in-fill: #1e40af;  --in-tint: #eef1fc;  --in-line: #c3ccf0;

  /* Light bekommt einen echten, winzigen Schatten auf Cards. */
  --sh-1: 0 1px 2px rgba(28,25,23,.06);
  --sh-2: 0 8px 20px rgba(28,25,23,.10), 0 1px 2px rgba(28,25,23,.06);
  --sh-3: 0 24px 48px rgba(28,25,23,.16), 0 2px 6px rgba(28,25,23,.08);

  color-scheme: light;
}

/* ═══════════════════════════════════════════════════════════════════════════
   DICHTE
   ═══════════════════════════════════════════════════════════════════════════ */
/* Die Zeilenhöhen sind aus dem gemessenen Inhalt abgeleitet, nicht frei
   gewählt. Eine zweizeilige Kontaktzeile braucht 34px Text (Titel 17px +
   Unterzeile 16px, gemessen im Browser). Der eigentliche Engpass war aber
   die Avatar-Kachel: fest 40px, in einer 40px-Zeile also randbündig — genau
   das sah gequetscht aus. Sie skaliert jetzt mit.

   Rechnung je Stufe — max(Avatar, Text) + 2 × Innenabstand ≤ Zeilenhöhe:

     kompakt   max(28, 34) + 2×4  = 42  ≤ 44   2px Reserve
     standard  max(34, 34) + 2×8  = 50  ≤ 52   2px Reserve
     komfort   max(40, 34) + 2×10 = 60  ≤ 64   4px Reserve

   --row-h-lg liegt jeweils 12px darüber: die Aufgabenzeile trägt eine
   dritte Zeile mit Badges.                                                */
[data-density="kompakt"]  { --row-h: 44px; --row-h-lg: 56px; --cell-h: 30px; --row-pad:  4px; --row-avatar: 28px; }
[data-density="standard"] { --row-h: 52px; --row-h-lg: 64px; --cell-h: 38px; --row-pad:  8px; --row-avatar: 34px; }
[data-density="komfort"]  { --row-h: 64px; --row-h-lg: 76px; --cell-h: 48px; --row-pad: 10px; --row-avatar: 40px; }

/* ═══════════════════════════════════════════════════════════════════════════
   ALIAS-BRIDGE  —  Legacy-Namen zeigen auf die neuen Werte
   ═══════════════════════════════════════════════════════════════════════════

   Das ist der Hebel: 2.166 der 3.909 Inline-Styles im JS sagen bereits
   var(--…). Nur 85 enthalten einen rohen Hex. Solange die Namen leben,
   färbt sich mehr als die Hälfte der App ohne eine einzige Codeänderung um.

   Diese Aliase bleiben, bis der letzte Altname aus frontend/js/ verschwunden
   ist. `node scripts/design-lint.mjs --legacy` zählt, wie viele noch da sind.
   ═══════════════════════════════════════════════════════════════════════════ */
:root, [data-theme="light"], html.light-mode {
  /* Flächen */
  --bg:        var(--s-canvas);
  --bg1:       var(--s-content);
  --bg2:       var(--s-raised);
  --bg3:       var(--s-overlay);
  --bg4:       var(--s-selected);
  --card-bg:   var(--s-raised);
  --bsub:      var(--s-panel);
  --input-bg:  var(--s-input);

  /* Text — hier steckt der größte Einzelgewinn: --txm war Alpha und
     unlesbar, ist jetzt ein solider Hex mit 4,8:1.                  */
  --tx:  var(--t-1);
  --txs: var(--t-2);
  --txm: var(--t-3);

  /* Linien */
  --border:  var(--line);
  --border2: var(--line-strong);

  /* Farben. --purple wird neutral: 111 JS- und 77 CSS-Referenzen
     verlieren damit auf einen Schlag ihre Violett-Bindung.
     --amber war der White-Label-Slot; auth.js schreibt die Tenant-
     Akzentfarbe künftig nach --brand, nicht mehr hierhin.           */
  /* --purple ist ersetzt: Flächen → --brand-fill, Rahmen und Text →
     --brand-mark. Der Alias bleibt nur als Netz für Stellen, die später
     dazukommen; er zeigt auf einen neutralen Ton, nicht auf den Akzent. */
  --purple:      var(--t-2);
  --accent:      var(--brand);
  --accent-blue: var(--t-2);
  --brand-red:   var(--brand);
  --red:    var(--da-ink);   --danger: var(--da-ink);
  --green:  var(--ok-ink);   --amber:  var(--wa-ink);
  --blue:   var(--in-ink);   --teal:   var(--ok-ink);
  --orange: var(--wa-ink);   --amber-dark: var(--wa-fill);

  /* Schrift — --font-display ist entfallen: es war wortgleich mit
     --font-body, und beide mit dem, was body vererbt. */
  --font-body:    var(--font-sans);
  --mono:         var(--font-mono);

  /* Radien */
  --r-xs: var(--r-1);  --r-sm: var(--r-2);  --r-md: var(--r-3);
  --r-lg: var(--r-4);  --r-xl: var(--r-4);

  /* Schatten */
  --shadow:            var(--sh-2);
  --card-shadow:       var(--sh-1);
  --shadow-popup:      var(--sh-2);
  --shadow-panel:      var(--sh-2);
  --shadow-dialog:     var(--sh-3);
  --shadow-dialog-lg:  var(--sh-3);

  /* Gradienten werden flach. Die Namen bleiben, damit die 35 Fundstellen
     nicht sofort angefasst werden müssen — sie liefern jetzt eine Farbe. */
  --grad-cta:  var(--brand);
  --grad-main: var(--brand);
}
