/* =========================================================================
   MALERPLUS • DARK CONTRACT — DER ZENTRALE DESIGNVERTRAG
   Vorgang MP-20260908-001 · 08.09.2026
   -------------------------------------------------------------------------
   Marcel 08.09.: "Kein kosmetisches Nachbessern, sondern ein vollstaendiger,
   systematischer Rebuild des Dark-Mode-Designsystems." Zielbild: Apple Pro,
   Linear, Raycast — ruhig, praezise, hochwertig. Kein reines Schwarz, kein
   Neon, kein Gaming-Look.

   WARUM ES DIESE DATEI GIBT — DER GEMESSENE BEFUND
   -------------------------------------------------------------------------
   dark-mode.css hat 6422 Zeilen und 1412 !important. Das ist keine
   Nachlaessigkeit, sondern die Folge eines Architekturfehlers:

     In public/index.html steht dark-mode.css an Position 130 von 173.
     43 Stylesheets laden DANACH — darunter die groessten Modul-Dateien
     (mp-baustellen-golden-v2 197 KB, mp-aufmass-golden 140 KB,
     mp-list-workspaces-golden). Sie tragen ihre eigenen, hellen Farben.

   Bei gleicher Spezifitaet gewinnt die spaeter geladene Regel. Dark Mode
   konnte gegen 43 nachfolgende Dateien nur mit !important bestehen — und
   jeder neue Fall brauchte ein neues !important. So entsteht eine
   Patch-Sammlung, und genau die soll hier enden.

   DIE LOESUNG — EIN VERTRAG STATT VIELER PATCHES
   -------------------------------------------------------------------------
   Diese Datei wird als LETZTE Datei der Kette geladen. Sie definiert die
   Theme-Tokens final. Damit gilt:

     Jede Komponente, die einen Token benutzt, ist automatisch migriert.
     Es braucht dafuer keine einzige komponentenspezifische Regel mehr.

   Sie definiert die Tokens auf DERSELBEN Ebene wie alle anderen
   (:root bzw. html.dark) und gewinnt allein durch die Ladereihenfolge —
   bewusst OHNE !important auf Variablen. Ein !important auf einer Variablen
   wuerde jede spaetere Feinjustierung pro Komponente unmoeglich machen.

   AUFBAU
     1. Die Tiefenhierarchie (Ebene 0-4) als Rohpalette
     2. Der semantische Vertrag — die Namen, die Komponenten benutzen sollen
     3. Legacy-Bruecke — die gewachsenen Token-Namen zeigen auf 1. und 2.
     4. Graphite als eigenstaendige, waermere Variante
     5. Light-Ergaenzung — nur fehlende Namen, KEINE Aenderung bestehender Werte

   LIGHT MODE
     Marcels Vorgabe: "Der bestehende Light Mode darf durch diese Arbeiten
     nicht beschaedigt werden." Deshalb aendert Abschnitt 5 keinen einzigen
     bestehenden Light-Wert. Er ergaenzt ausschliesslich Namen, die es im
     Light-Theme bisher gar nicht gab, damit Komponenten gefahrlos auf den
     neuen Vertrag umgestellt werden koennen.
   ========================================================================= */


/* =========================================================================
   1. TIEFENHIERARCHIE — DIE ROHPALETTE (DARK)
   -------------------------------------------------------------------------
   Dark Mode darf nicht aus einer einzigen dunklen Flaeche bestehen.
   Fuenf Ebenen, bewusst mit KLEINEN Helligkeitsschritten. Die Trennung
   entsteht aus dem Zusammenspiel von Flaeche + feiner Kante, nicht aus
   grossen Kontrastspruengen und nicht aus dicken Schatten.

   Gewaehlter Grundton: ein sehr leicht kuehl-neutrales Anthrazit.
   NICHT #000000 (haerteste Kante zum Content, wirkt billig) und nicht der
   bisherige blaustichige Ton #141922, der neben den neutralen Karten der
   Module als eigene Farbfamilie auffiel.
   ========================================================================= */
/* ⚠ NACHGEBESSERT am 08.09. nach Marcels Screenshots.
   Die erste Fassung stand auf #0d0f12 / #171b21 — nur rund zehn
   RGB-Punkte zwischen Grund und Karte. Rechnerisch waren das saubere
   Ebenen, auf dem Monitor verschwammen sie zu EINER schwarzen Flaeche.
   Genau das schliesst der Auftrag aus ("Dark Mode darf nicht aus einer
   einzigen dunklen Flaeche bestehen").

   Die Schritte sind jetzt groesser: der Grund geht tiefer, die
   Arbeitsflaeche kommt hoeher. Zwischen Ebene 0 und Ebene 2 liegen 16
   statt 10 Punkte, und die Kante traegt sichtbar mit. Es bleibt bewusst
   bei kleinen Spruengen zwischen den oberen Ebenen — Tiefe soll aus dem
   Zusammenspiel von Flaeche und Kante entstehen, nicht aus Kontrast. */
html.dark {
  /* Ebene 0 — der App-Grund, die tiefste Flaeche */
  --mp-l0:  #0a0b0e;
  /* Ebene 1 — Workspace / Hauptinhaltsflaeche */
  --mp-l1:  #0f1116;
  /* Ebene 2 — Cards, Panels, Sidebars: die Arbeitsflaeche */
  --mp-l2:  #1a1f27;
  /* Ebene 3 — Dialoge, Dropdowns, Popover: liegt ueber allem */
  --mp-l3:  #232932;
  /* Ebene 4 — die naechste Stufe innerhalb eines Dialogs */
  --mp-l4:  #2e353f;

  /* Zustandsschleier. Bewusst als Weiss-Transparenz statt fester Farbe:
     So bleibt ein Hover auf JEDER Ebene gleich stark wahrnehmbar, ohne
     dass fuer jede Ebene ein eigener Hover-Wert gepflegt werden muss. */
  --mp-veil-hover:    rgba(255,255,255,.045);
  --mp-veil-active:   rgba(255,255,255,.075);
  --mp-veil-selected: rgba(43,176,255,.14);
}


/* =========================================================================
   2. DER SEMANTISCHE VERTRAG (DARK)
   -------------------------------------------------------------------------
   Diese Namen sind das, was Komponenten benutzen sollen. Sie beschreiben
   die FUNKTION, nicht die Farbe — deshalb ueberleben sie einen Farbwechsel.
   ========================================================================= */
html.dark {

  /* ---- Flaechen ------------------------------------------------------- */
  --mp-bg:            var(--mp-l0);
  --mp-bg-elevated:   var(--mp-l3);
  --mp-surface-1:     var(--mp-l1);
  --mp-surface-2:     var(--mp-l2);
  --mp-surface-3:     var(--mp-l3);
  --mp-surface-4:     var(--mp-l4);
  --mp-surface-hover: var(--mp-veil-hover);
  --mp-surface-active:var(--mp-veil-active);
  --mp-selected:      var(--mp-veil-selected);
  --mp-hover:         var(--mp-veil-hover);

  /* ---- Kanten ---------------------------------------------------------
     Im Dunkeln traegt eine feine helle Kante die Abgrenzung, die im Hellen
     ein Schatten traegt. Deshalb Weiss-Transparenz statt Grauwert: die
     Kante passt sich damit jeder darunterliegenden Ebene an. */
  --mp-border:        rgba(255,255,255,.09);
  --mp-border-strong: rgba(255,255,255,.16);
  --mp-divider:       rgba(255,255,255,.07);

  /* ---- Text -----------------------------------------------------------
     Kein reines Weiss als Flaechentext: #f4f6f8 statt #ffffff nimmt dem
     Schriftbild die Ueberschaerfe, ohne Lesbarkeit zu kosten.
     Gemessen gegen Ebene 2 (#171b21):
       text        #f4f6f8  → 15.3:1
       secondary   #a8b0bb  →  7.4:1
       muted       #79818d  →  4.1:1  (nur fuer Grossschrift/Nichttext)
       disabled    #5a626c  →  2.7:1  (bewusst: muss als AUS erkennbar sein) */
  --mp-text:           #f4f6f8;
  --mp-text-secondary: #a8b0bb;
  /* Zweimal nachgemessen und zweimal korrigiert — die eigene Palette war
     selbst eine Fehlerquelle:
       #79818d  4.39:1 gegen Ebene 2  → unter dem Mindestwert 4.5:1
       #848d9a  4.86:1 gegen Ebene 2, aber nur 4.5:1 gegen Ebene 3 und
                darunter auf Ebene 4 — muted steht aber auch dort.
       #8b94a1  5.4:1 gegen Ebene 2, 4.9:1 gegen Ebene 4  → traegt ueberall
     und bleibt trotzdem klar zurueckgenommen. */
  --mp-text-muted:     #8b94a1;
  --mp-text-disabled:  #5a626c;
  --mp-text-on-accent: #ffffff;
  --mp-placeholder:    #6b727d;

  /* ---- Akzent ---------------------------------------------------------
     Das MalerPlus-Blau #2bb0ff bleibt die Aktionsfarbe (Marcels Vorgabe).
     Auf dunklem Grund wird es minimal angehoben, damit Text darauf und
     die Farbe selbst genug Leuchtkraft behalten, ohne ins Neon zu kippen. */
  --mp-accent:        #3bb8ff;
  --mp-accent-hover:  #5cc6ff;
  --mp-accent-active: #1fa4f5;
  --mp-accent-soft:   rgba(43,176,255,.14);
  --mp-accent-ring:   rgba(43,176,255,.45);
  --mp-accent-text:   #7dcdff;   /* Blau als SCHRIFT auf dunklem Grund */

  /* ---- Statusfarben ---------------------------------------------------
     Die hellen Abstufungen, weil die Vollfarben (#22c55e, #ef4444) auf
     dunklem Grund als Schrift unter 4.5:1 fallen. */
  --mp-success:       #4ade80;
  --mp-success-soft:  rgba(34,197,94,.15);
  --mp-warning:       #fbbf24;
  --mp-warning-soft:  rgba(245,158,11,.15);
  --mp-danger:        #f87171;
  --mp-danger-soft:   rgba(239,68,68,.15);
  --mp-info:          #60a5fa;
  --mp-info-soft:     rgba(59,130,246,.15);

  /* ---- Formularelemente -----------------------------------------------
     Das Eingabefeld liegt TIEFER als seine Umgebung, nicht hoeher. Ein
     eingelassenes Feld liest sich als beschreibbar; eine erhoehte Flaeche
     liest sich als Knopf. Im Light Mode uebernimmt Weiss diese Rolle. */
  --mp-input-bg:        rgba(0,0,0,.22);
  --mp-input-bg-hover:  rgba(0,0,0,.28);
  --mp-input-border:    rgba(255,255,255,.10);
  --mp-input-focus:     var(--mp-accent);
  --mp-input-ring:      var(--mp-accent-ring);
  --mp-input-text:      var(--mp-text);

  /* ---- Schatten -------------------------------------------------------
     Im Dunkeln traegt ein Schatten kaum — die Ebenentrennung kommt aus
     Flaeche und Kante. Die Schatten bleiben deshalb bewusst zurueckhaltend
     und dienen nur der Abloesung schwebender Elemente. */
  --mp-shadow-sm: 0 1px 2px rgba(0,0,0,.30);
  --mp-shadow-md: 0 4px 14px rgba(0,0,0,.38);
  --mp-shadow-lg: 0 16px 44px rgba(0,0,0,.50);

  /* ---- Glas -----------------------------------------------------------
     Nur fuer Dock, Navigation, Floating Toolbar und grosse Overlays.
     Nicht fuer Cards — der Content muss ruhig bleiben. */
  --mp-glass-bg:     rgba(22,27,34,.74);
  --mp-glass-border: rgba(255,255,255,.09);
  --mp-glass-blur:   18px;

  /* ---- Overlay / Scrim ------------------------------------------------ */
  --mp-overlay: rgba(0,0,0,.62);

  /* Browser-eigene Oberflaechen: Scrollbalken, Datepicker, Autofill. */
  color-scheme: dark;
}


/* =========================================================================
   3. LEGACY-BRUECKE — HIER PASSIERT DIE EIGENTLICHE MIGRATION
   -------------------------------------------------------------------------
   Die App benutzt heute gewachsene Token-Namen. Gemessen ueber alle 177
   Stylesheets, die tragenden nach Haeufigkeit:
       --mp-text 332x · --mp-card 295x · --text-primary 272x
       --mp-muted 196x · --mp-blue 149x · --border-soft 137x

   Statt 177 Dateien anzufassen, zeigen diese Namen ab hier auf den Vertrag.
   Das ist der Grund, warum dieser Rebuild ohne Massenaenderung auskommt:
   ein Wert an einer Stelle wirkt auf alle Stellen, die ihn schon benutzen.

   Das ist ausdruecklich KEINE blinde Ersetzung: jeder Name wurde einzeln
   seiner Funktion zugeordnet (Flaeche / Text / Kante / Zustand).
   ========================================================================= */
html.dark {

  /* ---- Flaechen ---- */
  --mp-bg-base:      var(--mp-l0);
  --app-bg:          var(--mp-l0);
  --bg:              var(--mp-l0);
  --mp-card:         var(--mp-l2);
  --mp-card-bg:      var(--mp-l2);
  --mp-bg-card:      var(--mp-l2);
  --mp-bg-surface:   var(--mp-l2);
  --mp-surface:      var(--mp-l2);
  --card-bg:         var(--mp-l2);
  --mp-card-header:  var(--mp-l3);
  --surface-2:       var(--mp-l3);
  --panel-bg:        var(--mp-l3);
  --bg-elevated:     var(--mp-l3);
  --mp-bg-card-hover:var(--mp-l3);
  --mp-bg-input:     var(--mp-input-bg);
  --glass-bg-solid:  var(--mp-l2);
  --dash-card-bg:    var(--mp-l2);
  --lk-card-bg:      var(--mp-l2);

  /* ---- Text ---- */
  --mp-text-primary:   var(--mp-text);
  --mp-text-main:      var(--mp-text);
  --mp-text-on-surface:var(--mp-text);
  --mp-color-text:     var(--mp-text);
  --text-primary:      var(--mp-text);
  --text:              var(--mp-text);
  --mp-muted:          var(--mp-text-secondary);
  --mp-text-sub:       var(--mp-text-secondary);
  --text-secondary:    var(--mp-text-secondary);
  --text-soft:         var(--mp-text-secondary);
  --muted:             var(--mp-text-muted);
  --text-muted:        var(--mp-text-muted);
  --text-disabled:     var(--mp-text-disabled);
  --text-on-accent:    var(--mp-text-on-accent);

  /* Die numerischen Textstufen laufen von hell (900) nach gedeckt (400).
     Im Dunkeln ist diese Skala invertiert — 900 ist die HELLSTE Schrift. */
  --mp-text-900: var(--mp-text);
  --mp-text-800: var(--mp-text);
  --mp-text-700: var(--mp-text-secondary);
  --mp-text-500: var(--mp-text-muted);
  --mp-text-400: var(--mp-text-muted);

  /* Die Grauskalen invertieren mit. Sie werden quer durch die App sowohl
     fuer Flaechen (50-300) als auch fuer Schrift (700-900) benutzt. */
  --neutral-50:  var(--mp-l0);  --gray-50:  var(--mp-l0);  --brand-50:  var(--mp-l0);
  --neutral-100: var(--mp-l1);  --gray-100: var(--mp-l1);  --brand-100: var(--mp-l1);
  --neutral-200: var(--mp-l3);  --gray-200: var(--mp-l3);  --brand-200: var(--mp-l3);
  --neutral-300: var(--mp-l4);  --gray-300: var(--mp-l4);  --brand-300: var(--mp-l4);
  --neutral-400: var(--mp-text-disabled); --gray-400: var(--mp-text-disabled); --brand-400: var(--mp-text-disabled);
  --neutral-500: var(--mp-text-muted);    --gray-500: var(--mp-text-muted);    --brand-500: var(--mp-text-muted);
  --neutral-600: var(--mp-text-secondary);--gray-600: var(--mp-text-secondary);--brand-600: var(--mp-text-secondary);
  --neutral-700: var(--mp-text-secondary);--gray-700: var(--mp-text-secondary);--brand-700: var(--mp-text-secondary);
  --neutral-800: var(--mp-text);          --gray-800: var(--mp-text);          --brand-800: var(--mp-text);
  --neutral-900: var(--mp-text);          --gray-900: var(--mp-text);          --brand-900: var(--mp-text);

  /* ---- Kanten ---- */
  --border-soft:      var(--mp-border);
  --border-subtle:    var(--mp-border);
  --border-default:   var(--mp-border-strong);
  --border-medium:    var(--mp-border-strong);
  --border:           var(--mp-border);
  --mp-border-subtle: var(--mp-border);
  --mp-border-default:var(--mp-border-strong);
  --mp-color-border:  var(--mp-border);
  --mp-hairline:      var(--mp-divider);
  --mp-border-2:      var(--mp-accent-ring);
  --border-accent:    var(--mp-accent-soft);
  --border-focus:     var(--mp-accent-ring);
  --card-border:      var(--mp-border);
  --dash-card-border: var(--mp-border);
  --mp-safe-border:   var(--mp-border);
  --mp-safe-border-2: var(--mp-border-strong);
  --av-border:        var(--mp-border);
  --am-line:          var(--mp-divider);
  --bs-line:          var(--mp-divider);
  --d-border:         var(--mp-border);

  /* ---- Akzent ---- */
  --mp-blue: var(--mp-accent);
  --blue:    var(--mp-accent);
  --accent:  var(--mp-accent);

  /* ---- Formular ---- */
  --input-bg:           var(--mp-input-bg);
  --input-border:       var(--mp-input-border);
  --input-border-focus: var(--mp-accent);
  --mp-check-bg:        var(--mp-input-bg);
  --mp-check-border:    var(--mp-border-strong);

  /* ---- Glas ---- */
  --mp-glass:        var(--mp-glass-bg);
  --mp-glass-a:      var(--mp-glass-bg);
  --mp-glass-2:      rgba(22,27,34,.60);
  --mp-glass-b:      rgba(22,27,34,.60);
  --glass-bg:        var(--mp-glass-bg);
  --glass-bg-light:  rgba(22,27,34,.60);
  --glass-border:    var(--mp-glass-border);
  --mp-glass-border: var(--mp-glass-border);
  --mp-safe-panel:   var(--mp-l2);
  --mp-safe-panel-2: var(--mp-l1);

  /* ---- Schatten ---- */
  --shadow-sm:       var(--mp-shadow-sm);
  --shadow-base:     var(--mp-shadow-md);
  --shadow-soft:     var(--mp-shadow-md);
  --shadow-card:     var(--mp-shadow-md);
  --shadow-medium:   var(--mp-shadow-md);
  --shadow-elevated: var(--mp-shadow-lg);
  --shadow-float:    var(--mp-shadow-lg);
  --shadow-strong:   var(--mp-shadow-lg);
  --shadow-deep:     var(--mp-shadow-lg);
  --mp-shadow-glow:  0 8px 24px rgba(43,176,255,.16);
  --card-shadow:     var(--mp-shadow-md);
  --dash-card-shadow:var(--mp-shadow-md);
  --lk-card-shadow:  var(--mp-shadow-md);
  --mp-safe-shadow:  var(--mp-shadow-md);
  --mp-safe-shadow-soft: var(--mp-shadow-sm);
  --mp-check-shadow: var(--mp-shadow-sm);

  /* ---- Status (Legacy-Namen) ---- */
  --status-success-light: var(--mp-success-soft);
  --status-warning-light: var(--mp-warning-soft);
  --status-danger-light:  var(--mp-danger-soft);
  --status-info-light:    var(--mp-info-soft);

  /* ---- Modulspezifische Kurznamen, die quer in der App auftauchen ---- */
  --d-text:      var(--mp-text);
  --d-muted:     var(--mp-text-secondary);
  --av-surface:  var(--mp-l2);
  --av-text:     var(--mp-text);
  --av-muted:    var(--mp-text-secondary);
  --am-text:     var(--mp-text);
  --am-secondary:var(--mp-text-secondary);
  --bs-ink:      var(--mp-text);
  --premium-edge-light: rgba(255,255,255,.06);

  /* Diese drei standen fuer "weisse Flaeche mit Deckkraft". Im Dunkeln
     muessen sie die dunkle Flaeche meinen, sonst leuchten sie auf. */
  --mp-white-75:      rgba(26,31,39,.75);
  --mp-slate-400-70:  rgba(255,255,255,.10);
  --mp-stroke-200-90: var(--mp-border-strong);
  --mp-planner-leer:  var(--mp-text-muted);
}


/* =========================================================================
   4. GRAPHITE — DIE WAERMERE VARIANTE
   -------------------------------------------------------------------------
   Graphite bleibt ein eigenstaendiges Theme, kein aufgehelltes Dark.
   Es erbt den GESAMTEN Vertrag aus Abschnitt 2 und 3 und tauscht nur die
   Rohpalette: neutral-warmes Graphit ohne Blaustich, iOS-nah, eine Spur
   heller. Weil alles auf --mp-l0..l4 zeigt, genuegen diese Zeilen.
   ========================================================================= */
/* ⚠ ZWEIMAL NACHGEBESSERT — Marcel 08.09.: "den Graphit Mode musst du noch
   mal richtig checken."

   Der erste Fehler war Nachlaessigkeit: Beim Spreizen der Dark-Palette habe
   ich Graphite blind mitgezogen und dabei ABGEDUNKELT (Grund von #1c1c1e
   auf #141416). Damit verlor es genau das, wofuer es da ist — es sah aus
   wie ein zweites Dark. Gemessen lagen html-Grund (L 0.110) und Karten
   (L 0.147) so dicht beieinander, dass die Flaechen ineinanderliefen.

   Graphite ist jetzt wieder die HELLERE, neutral-graue Variante in der
   klassischen iOS-Staffelung. Der Unterschied zu Dark ist damit ein
   doppelter und auf einen Blick erkennbar:

       Dark      #0a0b0e … #1a1f27   tief, leicht kuehl-blaeulich
       Graphite  #1c1c1e … #2c2c2e   heller, voellig neutral-grau

   Wer Dark waehlt, will Ruhe und Tiefe; wer Graphite waehlt, will eine
   hellere Oberflaeche ohne Farbstich. */
html.dark[data-theme="graphite"] {
  --mp-l0: #1c1c1e;
  --mp-l1: #242426;
  --mp-l2: #2c2c2e;
  --mp-l3: #3a3a3c;
  --mp-l4: #48484a;

  --mp-text:           #f5f5f7;
  --mp-text-secondary: #aeaeb2;
  --mp-text-muted:     #9e9ea3;
  --mp-text-disabled:  #636367;
  --mp-placeholder:    #7a7a80;

  --mp-glass-bg: rgba(44,44,46,.78);
  --mp-overlay:  rgba(0,0,0,.58);

  /* Die Statusfarben stammen aus der Dark-Palette und sind fuer deren
     tiefere Flaechen gerechnet. Auf den helleren Graphit-Flaechen fallen
     sie knapp unter den Mindestwert — gemessen 4.46:1 fuer --mp-info auf
     Ebene 3. Deshalb hier eine Stufe heller; die Bedeutung bleibt
     dieselbe, nur die Helligkeit folgt dem helleren Grund. */
  --mp-info:    #7ab8fc;
  --mp-success: #62e39a;
  --mp-warning: #ffcc4d;
  --mp-danger:  #ff8f8f;
}

/* Knoepfe im Planer tragen Slate-400 als Schrift — ein Wert fuer helle
   Flaechen. Auf Graphit-Ebene 3 ergibt das 4.43:1, knapp unter 4.5:1.
   Nur die Schriftfarbe, keine Flaeche. */
html.dark[data-theme="graphite"] #btnPlannerPrevWeek,
html.dark[data-theme="graphite"] #btnPlannerNextWeek,
html.dark[data-theme="graphite"] .mp-btn.btn-ghost.btn-sm {
  color: var(--mp-text-secondary) !important;
}


/* =========================================================================
   5. LIGHT — NUR ERGAENZUNG, KEINE AENDERUNG
   -------------------------------------------------------------------------
   Hier wird KEIN bestehender Light-Wert angefasst. Ergaenzt werden nur die
   Namen aus dem neuen Vertrag, die es im Light-Theme bisher nicht gab —
   damit eine Komponente auf den Vertrag umgestellt werden kann, ohne im
   Hellen ihren Wert zu verlieren.

   Die Werte spiegeln exakt das, was das Light-Theme heute schon zeigt
   (design-system.css, brand-master.css, mp-theme-tokens.css).
   ========================================================================= */
:root {
  --mp-surface-1:     #ffffff;
  --mp-surface-2:     #ffffff;
  --mp-surface-3:     #ffffff;
  --mp-surface-4:     #f8fafc;
  --mp-surface-hover: rgba(15,23,42,.035);
  --mp-surface-active:rgba(15,23,42,.06);
  --mp-hover:         rgba(15,23,42,.035);
  --mp-selected:      rgba(43,176,255,.10);

  --mp-border-strong: rgba(15,23,42,.14);
  --mp-divider:       rgba(15,23,42,.07);

  --mp-text-disabled: #94a3b8;
  --mp-placeholder:   #94a3b8;

  --mp-accent:        #2bb0ff;
  --mp-accent-hover:  #12a3f7;
  --mp-accent-active: #0d8fdb;
  --mp-accent-soft:   rgba(43,176,255,.10);
  --mp-accent-ring:   rgba(43,176,255,.40);
  --mp-accent-text:   #0b78b8;   /* Blau als Schrift auf Weiss: 4.6:1 */

  --mp-success:      #16a34a;
  --mp-success-soft: rgba(34,197,94,.12);
  --mp-warning:      #d97706;
  --mp-warning-soft: rgba(245,158,11,.14);
  --mp-danger:       #dc2626;
  --mp-danger-soft:  rgba(239,68,68,.10);
  --mp-info:         #2563eb;
  --mp-info-soft:    rgba(59,130,246,.10);

  --mp-input-bg:       #ffffff;
  --mp-input-bg-hover: #ffffff;
  --mp-input-border:   rgba(15,23,42,.16);
  --mp-input-focus:    var(--mp-accent);
  --mp-input-ring:     var(--mp-accent-ring);
  --mp-input-text:     #0f172a;

  --mp-shadow-sm: 0 1px 2px rgba(15,23,42,.06);
  --mp-shadow-md: 0 4px 14px rgba(15,23,42,.08);
  --mp-shadow-lg: 0 16px 44px rgba(15,23,42,.12);

  --mp-glass-bg:     rgba(255,255,255,.72);
  --mp-glass-border: rgba(15,23,42,.08);
  --mp-glass-blur:   18px;

  --mp-overlay: rgba(15,23,42,.42);
}


/* =========================================================================
   6. KOMPONENTEN-BRUECKE — DIE GEMESSENEN FLAECHEN
   -------------------------------------------------------------------------
   Abschnitt 3 migriert alles, was Tokens benutzt. Was bleibt, sind
   Komponenten mit HARTEN Farben in den drei grossen Modul-Stylesheets, die
   nach dark-mode.css laden und dabei !important benutzen:

       mp-baustellen-golden-v2.css   197 KB
       mp-aufmass-golden.css         140 KB
       mp-list-workspaces-golden.css

   Beispiel, stellvertretend fuer den Rest:
       mp-aufmass-golden.css:2489   background: rgba(255,255,255,.96) !important;

   GEMESSEN am 08.09.2026 auf Staging (Chrome, 1440x900, echter Login,
   13 Module durchgeklickt): 82 helle Flaechen ab 44x22px im dunklen Theme,
   verteilt auf 46 verschiedene Selektoren — aber nur auf ACHT
   Funktionsgruppen. Genau diese acht stehen hier, nach Funktion geordnet
   und ausschliesslich mit Token-Werten.

   Das ist bewusst KEINE Sammlung von Einzelfarben: kein Wert in diesem
   Abschnitt ist eine Farbe, jeder ist ein Verweis auf den Vertrag. Eine
   spaetere Aenderung der Palette zieht hier automatisch mit.

   WARUM HIER !important STEHT
   Die Quellregeln setzen selbst !important. Ohne Gegenwert gewinnt die
   Quelle, unabhaengig von der Ladereihenfolge. Der Alternativweg waere,
   drei Stylesheets von zusammen ueber 500 KB umzuschreiben, die BEIDE
   Themes bedienen — mit entsprechendem Regressionsrisiko fuer den Light
   Mode, den Marcel ausdruecklich geschuetzt sehen will. Deshalb hier, an
   einer Stelle, nachvollziehbar, und ausschliesslich unter html.dark.
   ========================================================================= */

/* --- 6.1 Modulkopf ------------------------------------------------------
   Der gemeinsame Kopf aller Modulansichten. Gemessen mit 169.316 px2 die
   groesste zusammenhaengende helle Flaeche ueberhaupt; er erschien in
   Kunden, Angeboten, Rechnungen, Baustellen, Stunden und Meine Zeiten. */
html.dark .view-header,
html.dark .mp-module-view-header,
html.dark .mp-karte-flaeche,
html.dark .mp-aufmass-hero,
html.dark .mp-bs-panel-head {
  background-color: var(--mp-surface-2) !important;
  border-color: var(--mp-border) !important;
}

/* --- 6.2 Seitenschienen und Werkzeugleisten -----------------------------
   #mpSideRail stand in ALLEN 13 gemessenen Modulen hell da — die einzelne
   groesste Wirkung dieses Abschnitts. Die Schiene traegt Glas, weil sie
   ueber dem Inhalt schwebt; die Listen-Spalte daneben ist eine Flaeche. */
/* Marcel 08.09.: "im Aufmass scheint was das Dock zu erhellen, in den
   anderen Modulen ist das nicht."

   Nachgemessen bei 2000px Breite, dunkles Theme:
       Kunden   #mpSideRail        rgba(26,31,39,.74)  blur(24px)
       Aufmass  #aufmassQuickDock  rgba(26,31,39,.76)  blur(26px)

   Es sind ZWEI verschiedene Leisten: im Aufmass erscheint die eigene
   Werkzeugschiene, nicht die allgemeine. Ihre Flaeche ist praktisch
   identisch — der Unterschied von .02 Deckkraft und 2px Unschaerfe ist
   nicht sichtbar. Was auffaellt, sind die groesseren und farbigeren
   Werkzeug-Symbole darin; die lassen die Leiste heller wirken, obwohl der
   Grund derselbe ist.

   Trotzdem gehoeren beide auf exakt denselben Wert — zwei Leisten mit
   derselben Aufgabe duerfen sich nicht um Zufallswerte unterscheiden.
   Das ist der Sinn eines Designvertrags. Die Symbole bleiben, wie sie
   sind: sie tragen Bedeutung. */
html.dark #mpSideRail,
html.dark #aufmassQuickDock {
  background-color: var(--mp-glass-bg) !important;
  border-color: var(--mp-glass-border) !important;
  -webkit-backdrop-filter: blur(var(--mp-glass-blur)) saturate(1.4) !important;
          backdrop-filter: blur(var(--mp-glass-blur)) saturate(1.4) !important;
}
html.dark .mp-rail-collapse,
html.dark .mp-rail-tab {
  background-color: var(--mp-surface-3) !important;
  color: var(--mp-text-secondary) !important;
  border-color: var(--mp-border) !important;
}
html.dark .mp-rail-collapse:hover,
html.dark .mp-rail-tab:hover {
  background-color: var(--mp-surface-4) !important;
  color: var(--mp-text) !important;
}
html.dark .mp-workspace-list-master,
html.dark .mp-aufmass-master {
  background-color: var(--mp-surface-1) !important;
  border-color: var(--mp-border) !important;
}

/* --- 6.3 Abschnitts-Navigation ------------------------------------------
   Dieselbe Funktion unter sieben verschiedenen Klassennamen, gewachsen je
   Modul. Alle rund 85.000 px2 reinweiss. Sie gehoeren zusammen und
   bekommen deshalb hier EINEN Wert. */
html.dark .mp-editor-section-nav,
html.dark .mp-aufmass-section-nav,
html.dark .mp-hours-section-nav,
html.dark .mp-my-hours-section-nav,
html.dark .mp-planner-golden-nav,
html.dark .pdc-section-nav,
html.dark .mp-settings-topnav,
html.dark .mp-settings-subnav,
html.dark .mp-editor-command-deck,
html.dark .mp-planner-golden-period {
  background-color: var(--mp-surface-2) !important;
  border-color: var(--mp-border) !important;
}

/* --- 6.4 Panels, Karten, Listenzeilen -----------------------------------
   Die Arbeitsflaechen der Module. .mp-customer-form-block war mit
   399.564 px2 die groesste Einzelflaeche der gesamten Messung. */
html.dark .mp-bs-panel,
html.dark .mp-customer-form-block,
html.dark .kunden-card,
html.dark .mp-pkarte,
html.dark .proj-radar-card,
html.dark .mp-record-month,
html.dark .mp-record-row,
html.dark .card-body {
  background-color: var(--mp-surface-2) !important;
  border-color: var(--mp-border) !important;
}
html.dark .mp-record-row:hover {
  background-color: var(--mp-surface-3) !important;
}
/* Die ausgewaehlte Zeile darf NICHT wie Hover aussehen — sonst weiss der
   Nutzer bei Mauszeiger auf einer anderen Zeile nicht mehr, was gewaehlt
   ist. Deshalb Blau-Schleier statt Weiss-Schleier. */
html.dark .mp-record-row.is-active,
html.dark .mp-record-row.is-selected,
html.dark .mp-record-row[aria-selected="true"] {
  background-color: var(--mp-selected) !important;
  border-color: var(--mp-accent-ring) !important;
}

/* --- 6.5 Suchzeilen -----------------------------------------------------
   Eingabeflaechen liegen tiefer als ihre Umgebung, nicht hoeher. */
html.dark .mp-list-search-row,
html.dark .search-wrap,
html.dark .pdc-project-search {
  background-color: var(--mp-input-bg) !important;
  border-color: var(--mp-input-border) !important;
}

/* --- 6.6 Aufklapper und Dropdown-Ausloeser ------------------------------
   Liegen ueber dem Inhalt, also Ebene 3. */
html.dark .mp-kunden-tools-trigger,
html.dark .mp-record-filter-menu-trigger,
html.dark .mp-dropdown-trigger,
html.dark .mp-bs-panel-link,
html.dark .dash-next-appointment-hint,
html.dark .mpe-context,
html.dark .mpe-action {
  background-color: var(--mp-surface-3) !important;
  color: var(--mp-text) !important;
  border-color: var(--mp-border) !important;
}
html.dark .mp-bs-panel-link:hover,
html.dark .mp-dropdown-trigger:hover,
html.dark .mpe-action:hover {
  background-color: var(--mp-surface-4) !important;
}

/* --- 6.7 Ueberschriften mit fest verdrahteter dunkler Farbe -------------
   Gemessen: h2 in rgb(23,32,51) und .kva-section-title in rgb(30,36,48) —
   dunkle Schrift auf dunklem Grund, Kontrast 1.18:1 und 1.23:1, also
   praktisch unsichtbar. Das ist kein Einzelfall einer Komponente, sondern
   die Regel "Ueberschriften tragen die Textfarbe des Themes", die im
   Dunkeln nie durchgesetzt wurde.

   Papier- und Druckansichten sind ausgenommen: dort ist dunkle Schrift auf
   weissem Blatt richtig, unabhaengig vom Theme. */
html.dark h1:not([class*="a4"]):not([class*="doc-"]),
html.dark h2:not([class*="a4"]):not([class*="doc-"]),
html.dark h3:not([class*="a4"]):not([class*="doc-"]),
html.dark .kva-section-title,
html.dark .mp-section-title,
html.dark .admin-card-title {
  color: var(--mp-text);
}
html.dark .mp-a4-huelle h1, html.dark .mp-a4-huelle h2, html.dark .mp-a4-huelle h3,
html.dark .kva-doc-sheet h1, html.dark .kva-doc-sheet h2, html.dark .kva-doc-sheet h3,
html.dark [data-theme-exempt] h1, html.dark [data-theme-exempt] h2, html.dark [data-theme-exempt] h3 {
  color: inherit;
}

/* --- 6.8 Knopfzustaende -------------------------------------------------
   Sekundaer- und Geisterknoepfe standen mit heller Schrift auf weisser
   Flaeche (gemessen 1.08:1 und 1.48:1). Ursache war die weisse Flaeche,
   nicht die Schrift — trotzdem braucht der Knopf eine eigene, definierte
   Flaeche, sonst haengt sein Aussehen davon ab, worauf er zufaellig liegt. */
html.dark .btn-secondary,
html.dark .mp-btn.btn-ghost,
html.dark button.secondary {
  background-color: var(--mp-surface-3) !important;
  color: var(--mp-text) !important;
  border-color: var(--mp-border-strong) !important;
}
html.dark .btn-secondary:hover,
html.dark .mp-btn.btn-ghost:hover,
html.dark button.secondary:hover {
  background-color: var(--mp-surface-4) !important;
}

/* Primaerknopf: die Markenfarbe bleibt (Marcels Vorgabe), aber der Text
   darauf wird dunkel.
   Gemessen: weisser Text auf dem hellen Markenblau ergab 2.32:1 — deutlich
   unter dem Mindestwert 4.5:1. Das Blau ist zu hell, um weisse Schrift zu
   tragen; es aufzudunkeln hiesse, die Marke zu aendern. Dunkler Text auf
   hellem Akzent ist der uebliche Weg (Linear, Raycast) und bringt den
   Kontrast auf ueber 9:1, ohne einen einzigen Markenwert anzufassen. */
html.dark .btn-primary,
html.dark .mp-aw__cta--primary {
  color: var(--mp-l0) !important;
  font-weight: 600;
}
html.dark .btn-primary svg,
html.dark .mp-aw__cta--primary svg { color: var(--mp-l0); }

/* --- 6.9 Statusfarben, die als Schrift zu dunkel blieben ---------------
   Gemessen: rgb(21,128,61) (Gruen-700) auf dunklem Grund = 3.45:1.
   Die Vollfarben sind fuer helle Flaechen gemacht; im Dunkeln braucht es
   die hellen Abstufungen aus dem Vertrag. */
html.dark .worker-status-badge.is-available,
html.dark .mp-krank-chip,
html.dark .is-status-ok { color: var(--mp-success) !important; }
html.dark .is-status-warn { color: var(--mp-warning) !important; }
html.dark .is-status-danger { color: var(--mp-danger) !important; }

/* --- 6.10 DIE HINTERGRUNDEBENE — DER GROESSTE EINZELNE BEFUND ----------
   Im Screenshot der ersten fertigen Fassung standen die grossen Karten
   milchig hellgrau da, und "Hallo, Marcel" war darauf kaum zu lesen. Die
   Zahlen hatten davon nichts gemeldet: der Flaechen-Scanner prueft
   background-color, die Ursache lag aber im background-IMAGE.

   Gemessen: #mpWallpaperLayer, 1440x900, also bildschirmfuellend, mit
       linear-gradient(rgb(154,163,176) 0%, rgb(195,201,210) 65%)

   Das ist kein Fehler, sondern ein Feature: der Nutzer waehlt in den
   Einstellungen einen Hintergrund (core/mp-wallpaper.js). Von den elf
   Voreinstellungen sind neun hell, und auch die Voreinstellung ohne
   eigene Wahl ist hell (#eaf3ff). Das `dunkel`-Kennzeichen dort steuert
   ausschliesslich die Schriftfarbe der Kacheln, NICHT das Theme.

   Weil die Karten der App halbtransparent sind, scheint diese helle
   Flaeche ueberall durch — und genau daher kam der Eindruck, der Dark
   Mode sei "nicht ausreichend": nicht aus den Karten, sondern aus dem,
   was hinter ihnen liegt.

   Die Wahl des Nutzers wird nicht verworfen, sondern dem Theme
   untergeordnet: Bei .12 Deckkraft bleibt die Farbstimmung des gewaehlten
   Hintergrunds erkennbar, waehrend die Flaeche selbst dunkel bleibt.
   Gerechnet fuer den hellsten Fall (#c3c9d2) ueber Ebene 0:
       0.12 * 195 + 0.88 * 13  =  35   →  Luminanz 0.13
   also auf dem Niveau von Ebene 3, nicht darueber. Dasselbe Verfahren
   traegt auch die Foto-Hintergruende, ohne dass es je Preset eine eigene
   Regel braucht. */
html.dark #mpWallpaperLayer {
  opacity: .12;
  filter: saturate(.8);
}

/* --- 6.11 WAS NUR MIT !important ZU ERREICHEN IST ----------------------
   Die letzten gemessenen Faelle haben zwei Ursachen, die eine normale
   Regel nicht erreicht:

   a) INLINE-STYLES AUS JAVASCRIPT
      modules/projekte/projekte.js:10407 schreibt
          '<strong style="color:#1e2430;...">'
      Ein Inline-Style schlaegt jede CSS-Regel ohne !important. Gemessen
      standen die KPI-Werte im Baustellen-Modul dadurch bei 1.06:1.

   b) ID-SPEZIFITAET IN BESTANDSREGELN
      mp-brand-unify.css:136 setzt
          #view-projekte .btn-primary { color:#ffffff !important }
      Gegen eine ID plus !important kommt `html.dark .btn-primary` nicht an.

   Beide Faelle sind hier eng begrenzt behandelt: nur unter html.dark, nur
   die betroffene Eigenschaft, und der Wert kommt aus dem Vertrag. Der
   nachhaltigere Weg waere, die Farben in projekte.js und die
   #view-*-Regeln in mp-brand-unify.css auf Tokens umzustellen; das ist
   als offener Punkt festgehalten und gehoert nicht in eine Nachtschicht,
   weil beide Dateien Geschaeftslogik bzw. die Markenbasis beruehren. */

/* a) KPI-Werte und Radar-Zahlen mit fest verdrahteter dunkler Schrift */
html.dark .mp-kpi-value,
html.dark #projRadarIst,
html.dark #projRadarPct,
html.dark .kpi-grand strong {
  color: var(--mp-text) !important;
  -webkit-text-fill-color: var(--mp-text) !important;
}
html.dark .mp-kpi-label,
html.dark .mp-kpi-hint {
  color: var(--mp-text-secondary) !important;
}

/* b) Primaerknopf: die #view-*-Regeln erzwingen weisse Schrift auf dem
      hellen Markenblau (gemessen 2.32:1). Die Markenfarbe bleibt, die
      Schrift darauf wird dunkel — siehe Begruendung in 6.8. */
html.dark #view-projekte .btn-primary,
html.dark #view-kva .btn-primary,
html.dark #view-rechnung .btn-primary,
html.dark #view-kunden .btn-primary,
html.dark #view-aufmass .btn-primary,
html.dark #view-baustellenchat .btn-primary,
html.dark #view-stundenuebersicht .btn-primary,
html.dark body .btn-primary {
  color: var(--mp-l0) !important;
  -webkit-text-fill-color: var(--mp-l0) !important;
}

/* Die Einstellungs-Navigation wird in core/mp-settings-menu.js gesetzt
   und blieb deshalb als einzige Modulnavigation weiss (gemessen 84.876 px2
   in zwei Leisten uebereinander). */
html.dark #mpSettingsNav,
html.dark #mpSettingsSubnav,
html.dark .mp-settings-topnav,
html.dark .mp-settings-subnav,
html.dark #mpeContext,
html.dark .mpe-context {
  background-color: var(--mp-surface-2) !important;
  border-color: var(--mp-border) !important;
  color: var(--mp-text) !important;
}

/* Statusfarben, die als Schrift zu dunkel bleiben. Die Vollfarben sind
   fuer helle Flaechen gemacht; im Dunkeln braucht es die hellen Stufen. */
/* Diese beiden brauchen ein body im Selektor: die Bestandsregeln stehen
   selbst mit `html.dark body ...` da, und bei gleicher Spezifitaet UND
   gleichem !important entscheidet wieder die Ladereihenfolge — die diese
   Datei fuer sich hat. */
html.dark body .dash-planner-week-badge,
html.dark body #dashPlannerWeekLabel {
  color: var(--mp-info) !important;
}
/* Das Status-Abzeichen brauchte drei Anlaeufe. Gemessen gewinnt
       #view-workerstatus .worker-status-badge.is-available { color:#15803d !important }
   also eine ID plus zwei Klassen — dagegen kommt weder `html.dark .x` noch
   `html.dark body .x` an. Erst mit derselben ID im Selektor greift die
   Regel. Gruen-700 ist fuer helle Flaechen gemacht und erreicht auf
   dunklem Grund nur 3.45:1. */
html.dark #view-workerstatus .worker-status-badge.is-available,
html.dark #view-workerstatus .worker-status-badge.is-available *,
html.dark body .worker-status-badge.is-available,
html.dark body .worker-status-badge.is-available * {
  color: var(--mp-success) !important;
}

/* --- 6.10b DIE APP-KACHELN TRAGEN KEINE EIGENE FLAECHE ------------------
   Marcel 08.09.: "Die App Kacheln duerfen keinen eigenen Rahmen haben."

   Gemessen auf dem Dashboard, `button.dash-core-tile.dash-launch-tile`:
       Dark      rgba(0,0,0,0)      transparent — richtig
       Graphite  rgb(44,44,46)      eigene Flaeche — falsch

   Die Kacheln liegen auf der grossen Launcher-Karte und sollen darin
   aufgehen: sichtbar sind das farbige Symbol und die Beschriftung, nicht
   ein Kasten um beides. In Graphite zog die Kachel die Kartenfarbe und
   bekam damit einen eigenen Rahmen — in Dark blieb sie zufaellig
   transparent, weil dort dieselbe Farbe mit dem Untergrund verschmolz.

   Beide Themes werden hier auf denselben, ausdruecklich gewollten Zustand
   festgelegt. Bewusst NUR innerhalb des Dashboard-Rasters
   (`.dash-core-grid`): dieselbe Klasse traegt auch die Knoepfe der
   Bottom-Nav, und die sind eine eigene, abgestimmte Komponente, die hier
   nicht angefasst wird. Die Symbole selbst (`.dash-launch-tile-icon`)
   behalten ihre Farbverlaeufe — sie sind die Orientierung im Raster. */
html.dark .dash-core-grid .dash-core-tile,
html.dark .dash-core-grid .dash-launch-tile,
html.dark .dashboard-launcher .dash-core-tile {
  background: transparent !important;
  background-color: transparent !important;
  border-color: transparent !important;
  box-shadow: none !important;
}
/* Der Hover darf weiter zeigen, worauf der Zeiger steht — aber als
   Schleier, nicht als Kasten. */
html.dark .dash-core-grid .dash-core-tile:hover,
html.dark .dash-core-grid .dash-launch-tile:hover {
  background-color: var(--mp-veil-hover) !important;
}

/* --- 6.11a BAUSTELLENPROFIT: KARTE UND STATUS-CHIPS ---------------------
   Der letzte Rest der Messreihe, in allen Viewports dasselbe Modul.

   Die Status-Chips tragen gesaettigte BEDEUTUNGSfarben auf leicht
   getoenten Flaechen (#0d7bc4 blau, #c2570f orange, #15803d gruen). Die
   Migration hat sie zu Recht in Ruhe gelassen — gesaettigte Farben sind
   Bedeutungstraeger. Fuer helle Flaechen sind sie aber richtig gewaehlt
   und auf dunklem Grund zu dunkel: gemessen 1.08:1 ("Geplant") bis
   3.82:1 ("Laufend"). Die Bedeutung bleibt, die Helligkeit wird
   themegerecht: dieselbe Farbfamilie in der hellen Abstufung. */
html.dark #view-profit-dashboard .pdc-overview-card,
html.dark .pdc-overview-card {
  background-color: var(--mp-surface-2) !important;
  border-color: var(--mp-border) !important;
}
html.dark #view-profit-dashboard .pdc-overview-status--laufend      { color: var(--mp-info)    !important; }
html.dark #view-profit-dashboard .pdc-overview-status--offen        { color: var(--mp-text-secondary) !important; }
html.dark #view-profit-dashboard .pdc-overview-status--geplant      { color: var(--mp-text-secondary) !important; }
html.dark #view-profit-dashboard .pdc-overview-status--pausiert     { color: var(--mp-warning) !important; }
html.dark #view-profit-dashboard .pdc-overview-status--abgeschlossen{ color: var(--mp-success) !important; }
html.dark #view-profit-dashboard .pdc-overview-card-kunde           { color: var(--mp-text-secondary) !important; }

/* ⚠ HIER STAND EIN FEHLGRIFF, BEWUSST NICHT WIEDERHOLEN.
   Der Sekundaerknopf "Neue Baustelle" erreicht in Graphite mit seinem
   Modulblau (--bs-blue: #118fd3) nur 4.4:1 — knapp unter 4.5:1. Der
   naheliegende Griff war, die --bs-*-Tokens im dunklen Theme auf die
   Vertragsfarben zu legen:

       --bs-blue: var(--mp-accent); --bs-good: var(--mp-success); …

   GEMESSEN wurde daraufhin eine Verschlechterung: Graphite fiel von
   0 Leaks / 1 Kontrastfehler auf 4 Leaks / 10 Kontrastfehler. Der Grund:
   diese Tokens tragen nicht nur Schrift, sondern auch FLAECHEN
   (Status-Tönungen der Baustellenkarten). Eine helle Statusfarbe als
   Flaeche ist im Dunkeln genau der Fehler, den dieser Rebuild beseitigt.

   Ein Token, der Schrift UND Flaeche bedient, laesst sich nicht in einem
   Zug umstellen — dafuer muesste er erst in zwei Tokens getrennt werden.
   Das ist eine Aenderung an der Modulbasis und gehoert nicht in eine
   Nachtschicht. Der Knopf bleibt deshalb bei 4.4:1 und steht als offener
   Punkt im Handoff. 4.4 statt 4.5 ist ein sichtbar kleinerer Schaden als
   vier helle Flaechen.

   Was stattdessen geht: NUR die Schriftfarbe der betroffenen Knoepfe, und
   nur in Graphite. Damit bleibt jede Flaeche unberuehrt, und der Token
   selbst wird nicht angefasst. Gemessen betrifft es genau diese drei
   Stellen (4.40:1 bis 4.49:1); mit dem Akzent des Vertrags stehen sie bei
   rund 6.5:1. */
html.dark[data-theme="graphite"] .mp-kq-addbtn {
  color: var(--mp-accent) !important;
}

/* "Neue Baustelle" — gemessen per CSS.getMatchedStylesForNode. Die
   gewinnende Regel steht in mp-list-workspaces-golden.css:

       html:not(#mpkk):not(#mpkk-2) body #view-projekte.mp-baustellen-golden #btnProjektNeu
         { color: var(--bs-blue) !important }

   Das sind VIER IDs (jedes :not(#…) zaehlt als ID) plus !important. Ein
   Zwei-ID-Versuch (v938) konnte nie greifen und ist deshalb wieder raus.

   Der Ausweg liegt in dem, was die Regel liest: var(--bs-blue). Wird
   --bs-blue auf dem Knopf SELBST definiert, gewinnt das ueber
   Vererbungsnaehe — derselbe Mechanismus, der bei den KPI-Werten gegen mich
   arbeitete, hier bewusst genutzt. Der Container behaelt seinen --bs-blue,
   die Status-Toenungen der Karten bleiben unberuehrt; nur dieser Knopf
   liest den Akzent. Der Knopf hat gemessen keine eigene Flaeche
   (background transparent), also faerbt das ausschliesslich Schrift. */
html.dark[data-theme="graphite"] #btnProjektNeu {
  --bs-blue: var(--mp-accent);
}

/* --- 6.11b DER STARTBILDSCHIRM — DER THEME-FLASH -----------------------
   Gefunden in der Messreihe auf iPad-Hochformat, wo die App laenger laedt:
   #mpSplash steht mit 786.432 px2, also bildschirmfuellend, in #f7faff da.

   Der Splash ist ein Inline-<style> im Kopf von index.html (Z. 1937) und
   hatte ueberhaupt keinen Dark-Zweig — kein einziger html.dark-Selektor.
   Er blitzt damit bei JEDEM App-Start im dunklen Theme weiss auf, bevor
   die Oberflaeche erscheint. Auf Desktop faellt es kaum auf, weil der
   Start schnell ist; auf dem Tablet und am Handy ist es der erste
   Eindruck. Genau das meint Marcels Punkt 26 ("keine sichtbaren Flashs
   eines falschen Themes").

   Kein !important noetig: der Inline-Block steht im Kopf VOR dieser Datei,
   die Spezifitaet ist gleich, die Ladereihenfolge entscheidet.
   Das Markenblau des Logos bleibt unangetastet. */
html.dark #mpSplash {
  background: var(--mp-l0);
}
html.dark #mpSplash .mpSplashBrush {
  background: var(--mp-l2);
  box-shadow:
    0 34px 86px rgba(0, 0, 0, .55),
    0 22px 54px rgba(43, 176, 255, .12),
    inset 0 1px 0 rgba(255, 255, 255, .06);
}
html.dark #mpSplash .mpSplashBrush::after {
  background: linear-gradient(145deg, rgba(255,255,255,.07), rgba(255,255,255,0) 44%, rgba(255,255,255,0));
}
html.dark #mpSplash h1,
html.dark #mpSplash .mpSplashTitle { color: var(--mp-text); }
html.dark #mpSplash p,
html.dark #mpSplash .mpSplashSub   { color: var(--mp-text-secondary); }

/* --- 6.11c DIE KI-KARTE IM HUB (K-564) ----------------------------------
   Lena Berger hat sie im Nachbau weiss auf weiss gemessen; die
   Nachbarsitzung bat um Bestaetigung in der echten App. Bestaetigt
   (tools/dark-mode/k564-echt.js, Hub per Schwebeknopf geoeffnet, echte
   KI-Frage gestellt), in Dark UND Graphite:

       .mp-hub-card-in   bg rgb(255,255,255)
       .mp-hub-il .v     color rgb(233,246,255)     → 1.05:1

   Zwei Ursachen, beide gemessen (CSS.getMatchedStylesForNode):
   1. Die Karte kommt aus einem injizierten Modul-Style
      (core/mp-dashboard-agent.js:239) mit `background:#fff` — ohne
      jede Dark-Variante.
   2. dark-mode.css:3673 setzt `html.dark .mp-sheet * { color: inherit }`.
      Der Wildcard nimmt der Karte ihre eigenen Schriftfarben (#334155,
      #0f172a) und laesst sie die helle Sheet-Schrift erben.
   Es ist also KEIN [class*=]-Treffer und NICHT die Farbmigration — die
   Wildcard-Regel traegt keinen Farbwert und wurde nie angefasst.

   Fuer Karte und Zeile reicht die Spezifitaet: `html.dark .mp-hub-il`
   (0,2,1) schlaegt den Sheet-Wildcard und den Modul-Style.

   NICHT fuer den Wert. Gemessen nach dem ersten Deploy (v940): der Wert
   las weiter Sekundaergrau. Gewinner laut CSS.getMatchedStylesForNode ist
   dark-mode.css:3720:

       html.dark span:not([class*="badge"]):not([class*="btn"])
                     :not([class*="icon"]):not(...)   { color: inherit }

   Ein Span-Wildcard mit ACHT :not()-Attributen — Spezifitaet (0,8,2).
   Jedes <span> der App erbt damit seine Farbe, es sei denn, seine Klasse
   enthaelt eines der acht Woerter. Der Wert ist ein <span class="v"> und
   erbt deshalb die Zeilenfarbe. Gegen (0,8,2) kommt keine sinnvolle
   Klassenkette an; das !important hier ist durch die Messung begruendet
   und gilt fuer genau diese eine Eigenschaft. Die Karte liegt IM Sheet,
   also Ebene 3, nicht Ebene 2. */
html.dark .mp-hub-card-in {
  background: var(--mp-surface-3);
  border-color: var(--mp-border);
}
html.dark .mp-hub-il,
html.dark .mp-hub-il .n { color: var(--mp-text-secondary); }
html.dark .mp-hub-il .v { color: var(--mp-text) !important; }
html.dark .mp-hub-il + .mp-hub-il { border-top-color: var(--mp-divider); }
/* Die Bestaetigungsbox daneben (#f0f9ff, Modul-Style :306) haette
   denselben Fehler, sobald sie erscheint — gleich mit erledigt. */
html.dark .mp-hub-confirm {
  background: var(--mp-accent-soft);
  border-color: var(--mp-accent-ring);
}
html.dark .mp-hub-cbtn--no {
  background: var(--mp-surface-4);
  color: var(--mp-text-secondary);
  border-color: var(--mp-border-strong);
}

/* --- 6.11d DAS FASSADEN-ERGEBNIS IM AUFMASS ------------------------------
   Marcel, 08.09. abends, Screenshot Fassade-Reiter: hellgraues Panel mit
   weisser Schrift, Dock hell. In der echten App gemessen (fassade-echt.js):
   `.aufmass-output .mp-kpi-wrap` traegt rgba(255,255,255,.72) aus
   legacy_styles/modules/aufmass.css:3858 und hat im Dunkeln KEINE
   Gegenregel — dark-mode.css:4905 deckt nur die Gruppen. Effektiv
   rgb(191,192,195), darauf Schrift rgb(244,246,248): die Schrift war
   migriert, die Flaeche nicht. Alpha .72 ist hier kein Glanzlicht, sondern
   das Panel selbst — der Grenzfall der .70-Schwelle. Der Hero liegt
   transparent auf dem Wrap; das Dock ist Glas ueber dem Panel, deshalb
   wurde es nur im Aufmass hell. Gilt fuer JEDEN Aufmass-Output, nicht nur
   Fassade. Ebenen: Wrap 2, Gruppe 3, Hover 4, Hero 3 mit Akzentrand.
   Rot/Gruen der -neg/-pos-Werte bleibt (mp-safe-style-patch.css:2280). */
html.dark #view-aufmass .aufmass-output .mp-kpi-wrap {
  background: var(--mp-surface-2) !important;
  border-color: var(--mp-border) !important;
  box-shadow: none !important;
}
html.dark #view-aufmass .aufmass-output .mp-kpi-group {
  background: var(--mp-surface-3) !important;
  border-color: var(--mp-border) !important;
  box-shadow: none !important;
}
html.dark #view-aufmass .aufmass-output .mp-kpi-group:hover {
  background: var(--mp-surface-4) !important;
}
html.dark #view-aufmass .aufmass-output .mp-kpi-hero {
  background: var(--mp-surface-3) !important;
  background-image: none !important;
  border-color: rgba(59,184,255,.32) !important;
  box-shadow: none !important;
}
html.dark #view-aufmass .aufmass-output .mp-kpi-hero .label,
html.dark #view-aufmass .aufmass-output .mp-kpi-head,
html.dark #view-aufmass .aufmass-output .mp-kpi-row > span {
  color: var(--mp-text-secondary) !important;
}
html.dark #view-aufmass .aufmass-output .mp-kpi-hero .value,
html.dark #view-aufmass .aufmass-output .mp-kpi-row:not(.mp-kpi-row-neg):not(.mp-kpi-row-pos) > strong {
  color: var(--mp-text) !important;
}

/* --- 6.13 DIE DOCKLEISTE IM AUFMASS — EIN HALB MIGRIERTER VERLAUF ---------
   Marcel, 08.09. abends: „auch in der Dockbar". Gemessen (dockbar-pseudo.js):
   die sichtbare Leiste ist `nav.bottom-nav::before`; im Aufmass gewinnt
   mp-baustellen-golden-v2.css:1850 `html body:has(#view-aufmass.view.active)
   nav.bottom-nav::before` — Spezifitaet (1,4,3), weil :has() die seines
   Arguments traegt. Ihr Verlauf `rgba(var(--mp-flaeche-rgb),.76) →
   rgba(247,249,252,.62)`: der erste Stop lag ueber der .70-Schwelle und
   wurde migriert, der zweite darunter und blieb Weiss — oben dunkel, unten
   rgb(145,147,150). Eine Schwelle je Farbstop zerreisst einen Verlauf;
   ein Verlauf ist EINE Flaeche. Dazu Rand rgba(255,255,255,.52).
   In allen anderen Modulen gewinnt mp-dock-glas.css:818 (Token, dunkel),
   traegt aber Rand rgba(255,255,255,.92) und Innenlicht .82 — im Dunkeln
   eine weisse Kontur. Beides hier, mit begruendetem !important gegen die
   !important-Quellen. Ebene: Glas ueber dem Grund. */
html.dark body nav.bottom-nav.bottom-nav::before {
  background: rgba(var(--mp-flaeche-2-rgb), .88) !important;
  border-color: rgba(255,255,255,.10) !important;
  box-shadow:
    0 1px 2px rgba(0,0,0,.30),
    0 14px 34px -20px rgba(0,0,0,.60),
    inset 0 1px 0 rgba(255,255,255,.07) !important;
}
html.dark body:has(#view-aufmass.view.active) nav.bottom-nav::before,
html.dark body.mp-view-aufmass nav.bottom-nav::before,
html.dark body.mp-view-view-aufmass nav.bottom-nav::before {
  background: linear-gradient(180deg,
    rgba(var(--mp-flaeche-2-rgb), .90),
    rgba(var(--mp-flaeche-rgb), .88)) !important;
  border-color: rgba(255,255,255,.10) !important;
}

/* --- 6.14 DAS TERMIN-SHEET (#mpTerminInfoOv) ----------------------------
   Marcel, 08.09. 19:4x (Handy): Fuss des Termin-Sheets weiss, „Bearbeiten"
   weiss auf weiss. Gemessen (termin-sheet.js): `.mti-actions` traegt
   rgba(255,255,255,.98) und `.mti-btn-edit` #fff aus dem INJIZIERTEN
   Modul-Style (JS, kein Dark-Zweig); die Schrift wird von
   dark-mode.css:3673 `[class$="-sheet"] *` auf inherit gezogen — die
   gleiche Mechanik wie K-564. JS-gesetzte Farben sind der offene Punkt
   aus §8; hier der erste Fall, den Marcel gesehen hat. Fuss = Ebene 2,
   Sekundaerknopf = Ebene 3, Primaer/Anruf behalten ihre Farbe. */
html.dark #mpTerminInfoOv .mti-actions {
  background: var(--mp-surface-2) !important;
  border-top-color: var(--mp-border) !important;
}
html.dark #mpTerminInfoOv .mti-btn:not(.mti-btn-nav):not(.mti-btn-call) {
  background: var(--mp-surface-3) !important;
  color: var(--mp-text) !important;
  border-color: var(--mp-border) !important;
}
html.dark #mpTerminInfoOv .mti-btn-edit {
  background: var(--mp-surface-3) !important;
  color: var(--mp-text) !important;
}

/* --- 6.15 DAS MATERIALFENSTER — NACHZUG FUER PRODUKTION (K-577) -----------
   09.09. frueh: der Dunkelmodus ging auf Produktion (v948), aber
   `material-katalog-fenster.css` blieb auf dem Prod-Byte, weil die Datei
   mit MP-20260907-007 (Struktur) untrennbar gemischt ist — ohne meine fuenf
   Farbzeilen. Auf Prod ist das Fenster im Dunkeln deshalb weiss. Statt die
   umstrittene Datei anzufassen, stehen die Werte hier: dieser Contract liegt
   auf Prod. Auf Staging (migrierte Datei) sind die Regeln redundant und
   ergeben dieselben Farben. Werte = das, was die Tokens dort liefern. */
html.dark #mpMaterialKatalogFenster .mp-mkf-tools > input {
  background: var(--mp-surface-3);
  color: var(--mp-text);
  border-color: var(--mp-border);
}
html.dark #mpMaterialKatalogFenster .mp-mkf-brands button {
  background: var(--mp-surface-3);
  color: var(--mp-text-secondary);
  border-color: var(--mp-border);
}
html.dark #mpMaterialKatalogFenster .mp-mkf-brands button.is-on {
  background: rgba(43,176,255,.16);
  color: var(--mp-accent);
  border-color: rgba(43,176,255,.40);
}
html.dark #mpMaterialKatalogFenster .mp-mkf-list {
  scrollbar-color: rgba(139,148,161,.52) transparent;
}
html.dark #mpMaterialKatalogFenster .mp-mkf-row {
  background: var(--mp-surface-2);
  border-color: var(--mp-border);
}
html.dark #mpMaterialKatalogFenster .mp-mkf-empty,
html.dark #mpMaterialKatalogFenster .mp-mkf-foot {
  color: var(--mp-text-muted);
}
html.dark #mpMaterialKatalogFenster .mp-mkf-edit {
  background: var(--mp-surface-3);
}
html.dark #mpMaterialKatalogFenster .mp-mkf-edit:hover {
  background: var(--mp-surface-4);
}

/* --- 6.16 DER MP_SHEET-FUSS — --mpsh-bg bleibt sonst IMMER WEISS (L-2026-
   09-08-Sheetfuss, L-2026-09-23-Ida-A) -------------------------------------
   core/mp-sheet-system.js/.css definieren --mpsh-bg/--mpsh-ink/--mpsh-muted/
   --mpsh-line/... NUR EINMAL in :root (#ffffff) — kein bisheriges Dark-
   Stylesheet ueberschreibt sie, obwohl .mp-usheet selbst (die Sheet-FLAECHE)
   laengst per dark-mode.css auf eine dunkle Ebene gefaerbt wird. Fuss, Tabs,
   Eingabefelder und der Toast dieses Systems haengen aber ALLE an genau
   diesen Tokens (z. B. `.mp-usheet-footer{background:var(--mpsh-bg)}`) —
   sie blieben deshalb als helle Inseln stehen, waehrend die Sheet-Flaeche
   darueber bereits dunkel war (gemessen 08.09.: .mp-usheet = rgb(26,31,39),
   .mp-usheet-footer = rgb(255,255,255) — Lena Berger, L-2026-09-08-
   Sheetfuss). Reine additive Token-Zuweisung, KEINE Strukturaenderung, KEIN
   Eingriff in mp-sheet-system.css/.js selbst — wirkt auf JEDES MP_SHEET im
   Haus (Bautagebuch-Interview, KVA-Sheets, Termin-Sheet usw.), nicht nur auf
   den Anlass (Bautagebuch-Interview-Fristmeldung, Ida Neumann Stufe 4,
   23.09.2026). --mpsh-bg auf Ebene 2 gesetzt — derselbe Ton, den .mp-usheet
   bereits traegt (gemessen), damit Fuss/Tabs/Felder nicht als eigene, davon
   abweichende Flaeche wirken. --mpsh-acc* (Markenblau) bewusst NICHT
   ueberschrieben — Marcels Vorgabe: Primaer-CTA bleibt in JEDEM Theme
   #2bb0ff. */
html.dark {
  --mpsh-bg:      var(--mp-l2);
  --mpsh-bg-soft: var(--mp-l3);
  --mpsh-ink:     var(--mp-text);
  --mpsh-ink-2:   var(--mp-text-secondary);
  --mpsh-muted:   var(--mp-text-muted);
  --mpsh-muted-2: var(--mp-text-disabled);
  --mpsh-line:    var(--mp-border);
  --mpsh-line-2:  var(--mp-divider);
}

/* --- 6.12 DER APP-GRUND -------------------------------------------------
   dark-mode.css:182 setzt `html.dark body { background-color:#141922 }` —
   den blaustichigen Ton des alten Systems. Gemessen stand er nach der
   Migration in allen dreizehn Modulen noch da, waehrend die Karten bereits
   auf den neuen Ebenen lagen: der Grund war heller und blaeulicher als die
   Flaechen darueber, also genau die Farbfamilien-Unstimmigkeit, die dieser
   Rebuild beseitigen soll.

   Der Grund gehoert auf Ebene 0. Die beiden sehr schwachen Lichtkegel
   bleiben — sie geben der Flaeche Tiefe, ohne sie aufzuhellen. */
html.dark body {
  background-color: var(--mp-l0) !important;
  background-image:
    radial-gradient(900px 500px at 80% 10%, rgba(255, 138, 61, .035), transparent 60%),
    radial-gradient(700px 500px at 10% 20%, rgba(43, 176, 255, .05), transparent 60%) !important;
  color: var(--mp-text);
}
/* Graphite braucht seine eigene Zeile: dark-mode.css:502 setzt
   `html.dark[data-theme="graphite"] body` — ein Attributselektor mehr und
   damit hoehere Spezifitaet als `html.dark body`. Gemessen stand der Grund
   dort weiter auf #1c1c1e, also auf Ebene 1 statt Ebene 0. */
html.dark[data-theme="graphite"] body {
  background-color: var(--mp-l0) !important;
  background-image:
    radial-gradient(900px 500px at 80% 10%, rgba(255, 138, 61, .03), transparent 60%),
    radial-gradient(700px 500px at 10% 20%, rgba(43, 176, 255, .04), transparent 60%) !important;
}


/* =========================================================================
   7. FLAECHEN-TOKENS ALS RGB-TRIPEL — DIE BRUECKE IN DIE MODUL-DATEIEN
   -------------------------------------------------------------------------
   WARUM ES DIESEN ABSCHNITT BRAUCHT
   Abschnitt 6 kommt an vielen Stellen nicht durch. Gemessen am 08.09.2026:
   nach dem Einbau von Abschnitt 6 blieben 74 von 82 hellen Flaechen stehen.
   Die Ursache ist NICHT die Ladereihenfolge, sondern die Spezifitaet — in
   mp-baustellen-golden-v2.css stehen Regeln wie

       html body:has(:is(#view-kva,#view-rechnung,...).view.active) #mpSideRail

   Gegen so etwas verliert `html.dark #mpSideRail` auch mit !important.
   Ein Wettruesten ueber immer laengere Selektoren waere genau die
   Patch-Sammlung, die hier abgeschafft werden soll.

   DER AUSWEG: DIE QUELLE TOKENISIEREN, OHNE SIE ZU VERAENDERN
   In den zwoelf grossen Modul-Stylesheets wurde in JEDER
   background-Deklaration nur der FARBTEIL durch einen Token ersetzt, der
   Alpha-Wert blieb unangetastet:

       background: rgba(255,255,255,.94)
       →  background: rgba(var(--mp-flaeche-rgb), .94)

   Weil --mp-flaeche-rgb im Light-Theme exakt "255,255,255" ist, rendert
   der Light Mode danach BITGENAU wie vorher — eine Light-Regression ist
   rechnerisch ausgeschlossen, nicht nur unwahrscheinlich. Im dunklen Theme
   zeigt derselbe Token auf die passende Ebene, und die Spezifitaet der
   Quellregel spielt keine Rolle mehr, weil sie jetzt selbst den richtigen
   Wert liefert.

   Nicht angetastet wurden: alles ausser background/background-color,
   Alpha unter .70 (Glanzlichter und Hover-Schleier — rgba(255,255,255,.06)
   auf einer Karte ist im Dunkeln genau richtig) und Regeln fuer Papier-
   und Druckansichten.

   DIE UEBERSETZUNG IST NICHT LINEAR
   Im Hellen heisst "abgesetzt" dunkler, im Dunkeln heisst es heller.
   Deshalb wandert Slate-50 nicht auf eine dunklere, sondern auf eine
   hellere Ebene — sonst verloere ein Hover-Zustand im Dunkeln genau die
   Wirkung, die er im Hellen hat.
   ========================================================================= */
:root {
  --mp-flaeche-rgb:   255, 255, 255;   /* Weiss      — Karten, Panels    */
  --mp-flaeche-2-rgb: 248, 250, 252;   /* Slate-50   — leicht abgesetzt  */
  --mp-flaeche-3-rgb: 241, 245, 249;   /* Slate-100  — deutlich abgesetzt*/
  --mp-grund-rgb:     246, 248, 251;   /* der App-Grund                  */
}
html.dark {
  --mp-flaeche-rgb:    26,  31,  39;   /* Ebene 2 (#1a1f27) */
  --mp-flaeche-2-rgb:  35,  41,  50;   /* Ebene 3 (#232932) */
  --mp-flaeche-3-rgb:  46,  53,  63;   /* Ebene 4 (#2e353f) */
  --mp-grund-rgb:      10,  11,  14;   /* Ebene 0 (#0a0b0e) */
}
html.dark[data-theme="graphite"] {
  --mp-flaeche-rgb:    44,  44,  46;   /* Ebene 2 (#2c2c2e) */
  --mp-flaeche-2-rgb:  58,  58,  60;   /* Ebene 3 (#3a3a3c) */
  --mp-flaeche-3-rgb:  72,  72,  74;   /* Ebene 4 (#48484a) */
  --mp-grund-rgb:      28,  28,  30;   /* Ebene 0 (#1c1c1e) */
}
