/* ===========================================================================
   PMA Ops — Design System "JUNTA"        backend/static/css/tokens.css
   Layer 1 + 2: Kaskaden-Ordnung, Marken-Primitive, semantische Tokens.
   Hand-gepflegt. Kein Build-Schritt, kein Präprozessor, kein CDN.
   Vollständige Spezifikation: docs/DESIGN-SYSTEM.md
   ===========================================================================

   DIE FÜNF INVARIANTEN. Wer eine davon bricht, bricht das ganze System —
   es wirkt nur deshalb wie eine Entscheidung, weil es ausnahmslos gilt.

   1  FUGE       Jede Trennung zwischen zwei Flächen ist `var(--joint)` (2px)
                 in `--grout`. Eine 1px-Haarlinie als EINZIGE Trennung zweier
                 Blöcke ist ein Bug — sie verschwindet in der Sonne.
                 1px ist nur INNERHALB von /ops-Tabellen erlaubt.
   2  RADIUS     `border-radius` darf ausschließlich `var(--r-edge)` (2px),
                 `var(--r-chip)` (999px) oder `0` sein. Die Pille ist für
                 Status RESERVIERT: etwas Rundes bedeutet immer „Zustand“.
                 Fotos sind nie gerundet (Rechteck = Beweis).
   3  SCHATTEN   `box-shadow` kennt genau VIER erlaubte Formen, alle mit
                 Blur-Radius 0: `var(--lift)`, `none`, ein `inset …`-Streifen
                 und der äußere Fokusring `0 0 0 Npx var(--focus-halo)`.
                 Kein Blur, keine Transluzenz, kein backdrop-filter, kein Glas.
                 Max. ZWEI `--lift`-Elemente pro Screen.
   4  MONO       `--f-data` markiert DATEN: Zahlen, Beträge, IDs, Deltas,
                 Lizenz-/Permit-Nummern, Zeitstempel — und die
                 Großbuchstaben-Labels, die unmittelbar eine Zahl betiteln
                 (`.data-label`, Ledger-Spaltenköpfe, `.stat__l`).
                 Fließtext, Überschriften und Bildunterschriften NIE in Mono.
                 `.eyebrow` (allgemeines Abschnittslabel) ist deshalb --f-body.
   5  FARBE      Farbe steht nie allein. Jeder Zustand trägt Form (Glyph),
                 Wort und Farbe. Die semantische Trias (--ok/--warn/--crit/
                 --wait) liegt außerhalb von `@layer tenant` und ist NICHT
                 mandantenfähig — eine Firma mit roter Marke darf nie mit
                 „crítico“ kollidieren.

   Durchgesetzt durch tests/test_css_invariants.py (siehe DESIGN-SYSTEM.md §12).

   ---------------------------------------------------------------------------
   WARUM KEIN light-dark()
   Das System hat VIER Zustände, nicht zwei: `:root` (hell), OS-dunkel,
   explizit dunkel, und `[data-mode="sol"]` (Außenmodus auf /owner — keine
   Theme-Präferenz, sondern eine Sichtbedingung). `light-dark()` löst genau
   zwei auf und kann den vierten nicht ausdrücken. Dokumentierter Fallback:
   jedes Token wird zuerst auf blankem `:root` deklariert und in den drei
   Override-Blöcken NUR neu definiert. Ein Token, das nur in einem Override
   existiert, ist der klassische stille Unlesbar-Bug.
   =========================================================================== */

@layer reset, tokens, base, layout, components, pages, utilities, tenant;

@layer tokens {

  /* =========================================================================
     LAYER 1 · MARKEN-PRIMITIVE (pro Mandant überschreibbar)
     Jinja2 gibt für die Org genau diese Tokens in einem <style>-Block in
     <head> aus, gewrappt in `@layer tenant`. Siehe DESIGN-SYSTEM.md §11.
     Komponenten lesen NIE Layer 1 — nur die semantischen Tokens darunter.
     ========================================================================= */
  :root {
    --brand-h: 183;          /* Azulejo-Grünspan — nur für color-mix-Ableitungen */
    --brand-c: 0.085;        /* Chroma. Beide sind Dokumentation + Hover-Ableitung, */
                             /* nie Grundlage für Text-Kontrast (der ist hand-gesetzt). */
    --brand-logo: url("/static/org/pma/logo.svg");
  }

  /* =========================================================================
     LAYER 2 · SEMANTISCHE TOKENS — HELL (Basis-Deklaration, blankes :root)
     ========================================================================= */
  :root {
    color-scheme: light;

    /* --- Flächen: Estrich, gesetzte Fliese, Wanne, Fuge --------------------
       Warmgrau-mineralisch (Farbton ~75°, sehr geringe Sättigung), damit der
       Grund gewählt und nicht als Default-Off-White wirkt.                  */
    --ground:       #EFEEE9;   /* Seitengrund (unversiegelter Zementestrich) */
    --tile:         #FFFFFF;   /* jede erhobene Fläche (die gesetzte Fliese)  */
    --tile-sunk:    #E6E4DC;   /* Wanne: Inputs, Saldo-Zeile, Terrazzo-Grund  */
    --grout:        #D0CCC0;   /* DIE FUGE. Trägt nie Text.                   */
    --grout-deep:   #B3AE9F;   /* der harte Versatz unter --lift              */
    --line-control: #7E7A6E;   /* interaktive Grenze (Input, Chip, Ghost-Btn) */

    /* --- Tinte -------------------------------------------------------------
       Es gibt KEINE dritte, schwächere Textstufe. --ink-2 ist die schwächste
       Textfarbe im ganzen System und sie ist AAA. Kein Grau-auf-Grau.       */
    --ink:   #16150F;
    --ink-2: #4A483F;

    /* --- Marken-Akzent: Azulejo-Grünspan (mandantenfähig) ----------------- */
    --accent:      #08534F;
    --accent-ink:  #FFFFFF;
    --accent-line: #0A6B67;    /* nur Nicht-Text: Linien, Ticks, Unterstriche */
    --accent-soft: #DCEBE8;    /* die EINZIGE getönte Fläche: „Tu parte“      */

    /* --- Semantische Trias + Warten — NICHT mandantenfähig ---------------- */
    --ok:   #115427;  --ok-fill:   #D6E9DA;  --ok-ink:   #FFFFFF;
    --warn: #6B4500;  --warn-fill: #F7E4B3;  --warn-ink: #FFFFFF;
    --crit: #8C1C15;  --crit-fill: #F6DAD6;  --crit-ink: #FFFFFF;
    --wait: #334C63;  --wait-fill: #DCE6EE;  --wait-ink: #FFFFFF;

    /* --- Fokus ist Tinte, nie Marke ---------------------------------------
       White-Label-Entscheidung: der Ring darf mit keinem Mandanten-Farbton
       kollidieren und ist auf beiden Gründen die höchstmögliche Kontrastfarbe.
       --focus-halo wird pro Fläche neu gesetzt (siehe components.css).      */
    --focus:      #16150F;
    --focus-halo: #FFFFFF;

    /* --- LQIP: ein Terrazzo-Feld, kein graues Kästchen -------------------- */
    --terrazzo-base: #E4E1D6;
    --terrazzo-chip: #C3BFAF;
    --terrazzo-tint: #A9C5C0;

    /* --- Schrift ----------------------------------------------------------
       Drei Schnitte, vier Dateien, ~63 KB, selbst gehostet, subset `latin`
       (deckt ñ á é í ó ú ü ¿ ¡ ab — latin-ext ist Verschwendung).
       Archivo erscheint AUSSCHLIESSLICH in 800. Kein 700-Schnitt existiert;
       `font-synthesis-weight: none` in base.css verhindert das Faken.      */
    --f-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
    --f-body:    "Source Sans 3", ui-sans-serif, system-ui, "Segoe UI", sans-serif;
    --f-data:    "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

    /* --- Typskala ---------------------------------------------------------
       Jeder Preferred-Wert trägt einen rem-Anteil → 200 % Zoom funktioniert
       (WCAG 1.4.4). Nirgends ein reines vw-clamp.                          */
    --step--2: clamp(0.75rem,   0.735rem + 0.08vw, 0.8125rem);  /* 12.1 → 12.9 */
    --step--1: clamp(0.875rem,  0.85rem  + 0.11vw, 0.9375rem);  /* 14.0 → 15.0 */
    --step-0:  clamp(1.0625rem, 1.03rem  + 0.16vw, 1.1875rem);  /* 17.1 → 19.0 */
    --step-1:  clamp(1.25rem,   1.19rem  + 0.28vw, 1.4375rem);  /* 20.1 → 23.0 */
    --step-2:  clamp(1.5rem,    1.38rem  + 0.55vw, 1.9375rem);  /* 24.1 → 30.0 */
    --step-3:  clamp(1.875rem,  1.64rem  + 1.05vw, 2.75rem);    /* 30.2 → 41.4 */
    --step-4:  clamp(2.5rem,    1.95rem  + 2.6vw,  4.25rem);    /* 41.0 → 68.0 */

    --lh-display: 1.06;
    --lh-tight:   1.15;
    --lh-body:    1.55;
    --lh-data:    1.35;
    --track-label: 0.1em;   /* Versal-Labels */
    --track-cap:   0.08em;  /* kurze Versal-Labels */

    /* --- Form -------------------------------------------------------------- */
    --joint:  2px;     /* der EINZIGE Trennwert im System                    */
    --r-edge: 2px;     /* gebrochene Kante einer Bullnose-Fliese             */
    --r-chip: 999px;   /* NUR STATUS                                          */

    /* Harter Versatz, null Blur. Begründet durch die Sichtbedingung, nicht
       durch Geschmack: Streulicht löscht zuerst den weichen Schatten und
       zuletzt den harten Versatz. Richtungsabhängig → siehe [dir="rtl"].   */
    --lift: 3px 3px 0 var(--grout-deep);

    /* --- Raum: 8px-Modul mit 4px-Halbschritt, benannt nach Rolle ---------- */
    --sp-1: 4px;    /* Abstand innerhalb eines Chips                 */
    --sp-2: 8px;    /* Label → Wert, Icon → Text                     */
    --sp-3: 12px;   /* Zeileninnenraum, Tabellenzelle padding-block  */
    --sp-4: 16px;   /* Panel-Padding mobil, Abstand verwandter Zeilen */
    --sp-5: 24px;   /* Panel-Padding ≥40rem, Abstand im Stack        */
    --sp-6: 32px;   /* Abschnittsrhythmus innerhalb einer Fläche     */
    --sp-7: 48px;   /* zwischen großen Abschnitten                   */
    --sp-8: 64px;   /* über dem Footer, unter dem letzten Block      */
    --gutter: clamp(16px, 4vw, 40px);

    --tap:    48px;  /* interne Untergrenze jedes Controls. WCAG 2.5.8 nennt
                        24px — das ist der gesetzliche Boden, nicht das Ziel. */
    --tap-lg: 56px;  /* die eine Primäraktion in der Daumenleiste            */
    --measure: 65ch;

    /* --- Bewegung ---------------------------------------------------------- */
    --dur-press: 90ms;    /* der Knopf setzt sich in den Estrich             */
    --dur-ui:    160ms;   /* Sheet, Toast, Indicator                          */
    --ease: cubic-bezier(.2, 0, 0, 1);

    /* --- z-Index: fünf Stufen, sonst keine ------------------------------- */
    --z-base:     0;
    --z-raised:   10;   /* sticky Tab-Leiste, sticky Tabellenkopf            */
    --z-header:   20;   /* App-Leiste                                        */
    --z-thumbbar: 30;   /* Daumenleiste unten                                */
    --z-sheet:    40;   /* Sheet / Modal                                     */
    --z-toast:    50;   /* Toast-Region                                      */
  }

  /* -------------------------------------------------------------------------
     Flächen-Anhebung der Grundschrift.
     Das Portal liest eine 60-jährige Eigentümerin einhändig auf dem Telefon,
     /owner liest der Contractor im Schatten. Beide bekommen eine Stufe mehr
     als die öffentliche Website — nicht erst im Sonnenmodus.
     ------------------------------------------------------------------------- */
  :root[data-surface="portal"],
  :root[data-surface="owner"] {
    --step-0: clamp(1.125rem, 1.09rem + 0.16vw, 1.25rem);   /* 18.0 → 20.0 */
  }

  /* -------------------------------------------------------------------------
     /ops — Svens Debug-Fenster. Null Webfont-Bytes: „sieht aus wie das OS“
     ist hier ein Feature. Nur Mono bleibt, weil /ops fast nur Daten zeigt.
     Spart ~49 KB auf der Fläche, auf der Identität nichts wert ist.
     ------------------------------------------------------------------------- */
  :root[data-surface="ops"] {
    --f-display: ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
    --f-body:    ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
    --f-data:    ui-monospace, "Cascadia Mono", Consolas, "Roboto Mono", monospace;
    --step-0:    clamp(0.9375rem, 0.92rem + 0.08vw, 1rem);  /* 15.0 → 16.0 */
    --tap:       40px;   /* Desktop-Konsole, Maus, Dichte ist der Zweck */
  }

  /* -------------------------------------------------------------------------
     DUNKEL (OS-Präferenz). Abgesichert, damit eine explizite Hell-Wahl
     gewinnt. Redefiniert NUR Tokens, nie Komponenten.
     ------------------------------------------------------------------------- */
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]):not([data-mode="sol"]) {
      color-scheme: dark;
      --ground: #131311;  --tile: #1E1E1A;  --tile-sunk: #0E0E0C;
      --grout: #38372F;   --grout-deep: #4C4A40;  --line-control: #6E6C5E;
      --ink: #F4F3EE;     --ink-2: #B7B4A9;
      --accent: #58D2BE;  --accent-ink: #0C1413;
      --accent-line: #6FE0CC;  --accent-soft: #0F2E2C;
      --ok:   #56D07E;  --ok-fill:   #10331D;  --ok-ink:   #0C1413;
      --warn: #FFC53D;  --warn-fill: #332400;  --warn-ink: #1A1200;
      --crit: #FF8577;  --crit-fill: #3B1512;  --crit-ink: #160B09;
      --wait: #9DBCD4;  --wait-fill: #16242E;  --wait-ink: #0A1218;
      --focus: #F4F3EE;  --focus-halo: #131311;
      --terrazzo-base: #26251F; --terrazzo-chip: #3E3C33; --terrazzo-tint: #2B4A46;
    }
  }

  /* DUNKEL (explizit) — damit der Umschalter auch in die andere Richtung gewinnt. */
  :root[data-theme="dark"] {
    color-scheme: dark;
    --ground: #131311;  --tile: #1E1E1A;  --tile-sunk: #0E0E0C;
    --grout: #38372F;   --grout-deep: #4C4A40;  --line-control: #6E6C5E;
    --ink: #F4F3EE;     --ink-2: #B7B4A9;
    --accent: #58D2BE;  --accent-ink: #0C1413;
    --accent-line: #6FE0CC;  --accent-soft: #0F2E2C;
    --ok:   #56D07E;  --ok-fill:   #10331D;  --ok-ink:   #0C1413;
    --warn: #FFC53D;  --warn-fill: #332400;  --warn-ink: #1A1200;
    --crit: #FF8577;  --crit-fill: #3B1512;  --crit-ink: #160B09;
    --wait: #9DBCD4;  --wait-fill: #16242E;  --wait-ink: #0A1218;
    --focus: #F4F3EE;  --focus-halo: #131311;
    --terrazzo-base: #26251F; --terrazzo-chip: #3E3C33; --terrazzo-tint: #2B4A46;
  }

  /* -------------------------------------------------------------------------
     SONNENMODUS — vierte Palette, nur /owner. Keine Theme-Präferenz, sondern
     eine Sichtbedingung: Telefon, Mittag, Miami, staubiges Display.
     Jeder Wert ≥ 7:1 mit Reserve für Streulicht-Aufhellung.
     Eingeschaltet per Server-Cookie → Jinja2 stempelt `data-mode="sol"` auf
     <html> (kein Flash, keine JS-Abhängigkeit). Siehe DESIGN-SYSTEM.md §10.3.
     ------------------------------------------------------------------------- */
  :root[data-mode="sol"] {
    color-scheme: dark;
    --ground: #0C0C0A;  --tile: #191916;  --tile-sunk: #000000;
    --grout: #3A382F;   --grout-deep: #565347;  --line-control: #7A7868;
    --ink: #FFFFFF;     --ink-2: #C2BFB4;
    --accent: #5FD8C4;  --accent-ink: #06100E;
    --accent-line: #7BE6D4;  --accent-soft: #10312E;
    --ok:   #56D07E;  --ok-fill:   #0D2D18;  --ok-ink:   #06100E;
    --warn: #FFC53D;  --warn-fill: #332400;  --warn-ink: #1A1200;
    --crit: #FF8577;  --crit-fill: #35120F;  --crit-ink: #160B09;
    --wait: #9DBCD4;  --wait-fill: #101C25;  --wait-ink: #0A1218;
    --focus: #FFFFFF;  --focus-halo: #0C0C0A;
    --terrazzo-base: #1A1915; --terrazzo-chip: #34322A; --terrazzo-tint: #1E3A36;

    /* Ein Versatzschatten ist auf Fast-Schwarz unsichtbar → Mechanismus
       tauschen, nicht nur die Farbe: der Lift wird zur doppelten Kontur. */
    --lift: 0 0 0 2px var(--ink);

    --step-0: clamp(1.1875rem, 1.15rem + 0.16vw, 1.3125rem);  /* 19.0 → 21.0 */
  }

  /* -------------------------------------------------------------------------
     RTL. `--lift` ist gerichtet (Licht fällt von links oben). Ein zweiter
     Mandant außerhalb ES/EN kippt hier das Token, nicht die Komponenten.
     ------------------------------------------------------------------------- */
  :root[dir="rtl"]:not([data-mode="sol"]),
  [dir="rtl"] :root:not([data-mode="sol"]) {
    --lift: -3px 3px 0 var(--grout-deep);
  }
}

/* ===========================================================================
   KONTRASTTABELLE — gemessen, nicht geschätzt. WCAG 2.2, sRGB.
   Alle Textpaare liegen über 7:1 (AAA), alle UI-Grenzen über 3:1 (1.4.11).
   Es gibt im System keine Textfarbe unter 7:1. Das ist die Durchsetzung von
   „kein dünnes Grau-auf-Grau“ auf Token-Ebene statt per Review-Disziplin.

   HELL                          auf --ground  auf --tile   auf --tile-sunk
   --ink      #16150F               15.74           18.29        14.68
   --ink-2    #4A483F                7.89            9.17         7.36
   --accent   #08534F                7.66            8.90         7.14
   --ok       #115427                7.79            9.05         7.27
   --warn     #6B4500                7.30            8.48         6.81*
   --crit     #8C1C15                7.89            9.16         7.36
   --wait     #334C63                7.68            8.92         7.16
   * --warn steht nie auf --tile-sunk; auf --warn-fill sind es 8.10:1.

   HELL, Füllungen (Text auf Fläche)
   --accent-ink #FFF auf --accent   #08534F        8.90
   --ink        auf --accent-soft   #DCEBE8       14.88
   --accent     auf --accent-soft   #DCEBE8        7.12
   #2B1D00      auf --warn-fill     #F7E4B3       13.06
   --ok-ink     #FFF auf --ok       #115427        9.05
   --crit-ink   #FFF auf --crit     #8C1C15        9.16
   --wait-ink   #FFF auf --wait     #334C63        8.92

   HELL, Nicht-Text (WCAG 1.4.11, Schwelle 3:1)
   --line-control #7E7A6E auf --ground             3.69
   --line-control #7E7A6E auf --tile               4.29
   --grout        #D0CCC0 auf --tile               1.41  ← NUR Fuge, nie Grenze
   --grout-deep   #B3AE9F auf --tile               1.93  ← nur Versatz

   DUNKEL                        auf --ground  auf --tile
   --ink      #F4F3EE               16.74          15.05
   --ink-2    #B7B4A9                8.19           8.05  (korrigiert: 8.05 auf tile)
   --accent   #58D2BE               10.08           9.06
   --ok       #56D07E                9.49           8.54
   --warn     #FFC53D               11.79          10.60
   --crit     #FF8577                7.86           7.07
   --wait     #9DBCD4                9.36           8.42
   --line-control #6E6C5E auf --tile               3.36  (Nicht-Text)
   --accent-ink #0C1413 auf --accent #58D2BE      10.11

   SONNE (data-mode="sol")       auf --ground  auf --tile
   --ink      #FFFFFF               19.56          17.62
   --ink-2    #C2BFB4               11.80          10.63
   --accent   #5FD8C4               12.53          11.29
   --ok       #56D07E                9.99           9.00
   --warn     #FFC53D               12.41          11.18
   --crit     #FF8577                8.27           7.45
   --wait     #9DBCD4                9.85           8.87
   --line-control #7A7868 auf --tile               4.10  (Nicht-Text)

   Die Testdatei tests/test_css_invariants.py prüft, dass jedes auf blankem
   :root deklarierte Property auch in allen drei Override-Blöcken vorkommt —
   genau der stille Fehler, den ein vergessenes Token erzeugt.
   =========================================================================== */

/* ===========================================================================
   LAYER 1 · PRO MANDANT — die letzte Schicht. Kein !important im System.
   Jinja2 rendert für die aktive Org einen <style>-Block in <head>:

     <style>@layer tenant{   (schließendes Tag unten escaped,
       :root{ --accent:#08534F; --accent-ink:#FFFFFF;
              --accent-line:#0A6B67; --accent-soft:#DCEBE8;
              --brand-h:183; --brand-c:.085 }
       :root[data-theme="dark"], :root[data-mode="sol"]{ … }
       @media (prefers-color-scheme:dark){
         :root:not([data-theme="light"]):not([data-mode="sol"]){ … } }
     }<\/style> — damit dieser Kommentar das Element nicht beendet,
                      falls die Datei je inline eingebettet wird)

   Regeln beim Onboarding eines zweiten Mandanten (DESIGN-SYSTEM.md §11):
   - Die vier Akzentwerte sind HAND-GESETZT und mit gemessenem Kontrast
     dokumentiert. Keine abgeleitete Farbe trägt je Text.
   - Mindest-Farbtonabstand 25° in oklch zu jedem bestehenden Mandanten,
     sonst wirkt White-Label bei zwei Kunden nebeneinander dünn. Zusätzlich
     darf der Neutral-Farbton (--ground/--tile) mit variiert werden.
   - --ok/--warn/--crit/--wait bleiben IMMER außerhalb dieser Schicht.
   =========================================================================== */
@layer tenant {
  /* absichtlich leer — wird zur Laufzeit von Jinja2 gefüllt */
}
