/* ══════════════════════════════════════════════════
   v2 DESIGN TOKENS
   Destilliert aus 00_Daten/Redesign_Prototyp/index.html (:root, Zeile 15-136).
   Eigene Namen (--ms-*) statt --mkpi-* — v2 ist unser eigenes System, keine
   Alias-Bruecke zum Prototyp. Werte selbst sind 1:1 aus dem Prototyp
   uebernommen, ausser wo explizit als Ergaenzung markiert.
   ══════════════════════════════════════════════════ */
:root {
  /* --- Farben: Hintergruende --- */
  --ms-bg-primary: #FFFFFF;
  --ms-bg-secondary: #F5F5F7;
  /* Anmeldeseite: Grund der Formularseite und Farbe des Lichthofs darauf.
     Hell traegt sie keinen Hof — der Grund ist daher derselbe wie sonst,
     und die Hof-Farbe bleibt ungenutzt. */
  --ms-auth-bg: #F5F5F7;
  --ms-auth-glow-rgb: 56, 120, 200;
  --ms-bg-dark: #1D1D1F;
  --ms-bg-darker: #111111;
  --ms-bg-hero: #FFFFFF;

  /* --- Farben: Text --- */
  --ms-text-primary: #1D1D1F;
  --ms-text-secondary: #6E6E73;
  --ms-text-tertiary: #86868B;
  --ms-text-tertiary-rgb: 134, 134, 139;   /* Tint des neutralen Abzeichens (Status "erledigt") */
  /* Die `*-dark`-Stufen sind der Text AUF der abgesetzten Flaeche
     (--ms-bg-dark): Sprechblase, Meldungsband, aktiver Sortier-Chip,
     Diagramm-Reiter. In DIESER Fassung ist die Flaeche dunkel (#1D1D1F), der
     Text auf ihr also HELL. In der dunklen Fassung kehrt sich beides um —
     dort ist die Flaeche #E5E5EA und der Text dunkel; die Begruendung dafuer
     steht am Kopf jenes Blocks.

     BIS ZUM 2026-09-02 STAND HIER #1D1D1F, also derselbe Wert wie die
     Flaeche: Kontrast 1,0:1, Text unsichtbar. Betroffen war jede Stelle, die
     das Paar benutzt — Sprechblase (overlays.css), Meldungsband `.toast`
     (jede Flash-Meldung im hellen Modus), aktiver Sortier-Chip und
     Diagramm-Reiter (pages.css). Der Fehler kam aus der Website, wo `*-dark`
     die dunkle Textfassung FUER helle Baender meinte, nicht den Text auf
     einem dunklen Band; der Kommentar an dieser Stelle hat die alte Bedeutung
     mitgeschleppt. Aufgefallen ist es erst, als gekuerzte Firmennamen eine
     Sprechblase bekamen — bei den Symbolknoepfen hatte niemand hingesehen.
     bin/design-check prueft die drei Paarungen seither (KONTRASTPAARE);
     vorher stand dort nur die dunkle Fassung, und deshalb blieb es liegen. */
  --ms-text-primary-dark: #F5F5F7;
  --ms-text-secondary-dark: #A1A1A6;
  --ms-text-tertiary-dark: #8E8E93;

  /* --- Farben: Akzente & Interaktion ---
     Zu jeder Farbe, die als TINT-FLAECHE vorkommt, gehoert ein `*-rgb`-Begleiter.
     Grund: `rgba()` braucht Zahlen, keine Hex-Farbe — ohne diese Tokens stand die
     Farbe an jeder Tint-Stelle als Zahlentripel im Code (21x `rgba(0,114,227,…)`
     fuer den Akzent allein). Eine Farbaenderung haette dann jede dieser Stellen
     einzeln erwischen muessen, und Hex-Wert und Tripel waeren auseinandergelaufen.
     Die Website kennt das Muster nicht, weil sie keine Tint-Flaechen hat; myOFFICE
     loest es genauso (--mo-brand-rgb & Co.) und ist hier die Vorlage. */
  --ms-accent: #0072E3;
  --ms-accent-rgb: 0, 114, 227;
  /* Text und Symbole AUF einer gefuellten Signalflaeche — Knopf, aktiver Chip,
     ausgewaehlter Tag im Kalender, Balken der Zeitleiste.

     Eigener Name statt --ms-text-primary-dark: der heisst „Text auf der
     erhoehten dunklen Flaeche" (Kurzhinweis, Sprechblase) und kehrt sich im
     Dunkelmodus mit ihr um. Der Knopftext folgt aber der FUELLFARBE, nicht
     jener Flaeche — und die wird im Dunkelmodus heller statt dunkler.

     Reines Weiss, nicht #F5F5F7: auf dem Akzent sind das 4,65:1 statt 4,27:1
     und auf dem Erfolgsgruen 4,53:1 statt 4,16:1. Beide Werte lagen ueber AA,
     der hellere ist trotzdem der richtige — ein gefuellter Knopf soll seine
     Beschriftung klar tragen, und „fast weiss" liest sich als Versehen.
     Im Dunkelmodus kehrt es sich um (siehe dort). */
  --ms-on-accent: #FFFFFF;
  --ms-accent-hover: #0080F0;
  --ms-accent-active: #0064CC;
  --ms-link: #006AD6;
  /* Verweis auf der abgesetzten Flaeche — hell, aus demselben Grund wie die
     Textstufen darueber. Stand ebenfalls auf dem dunklen Wert (#005BB5,
     2,54:1 auf #1D1D1F); nirgends benutzt, deshalb war nichts zu sehen. */
  --ms-link-dark: #3D9FFF;
  --ms-gradient-start: #0072E3;
  --ms-gradient-end: #00B4A0;
  /* Ueber die Start-/End-Tokens, nicht ueber Hex: sonst aendert ein Anpassen von
     --ms-gradient-start den Verlauf nicht mit (so stand es hier zuvor). */
  --ms-gradient: linear-gradient(to right, var(--ms-gradient-start), var(--ms-gradient-end));
  --ms-icon-color: #00B4A0;
  --ms-icon-color-rgb: 0, 180, 160;
  /* Zustaende zum Tuerkis des Verlaufs — im Prototyp gibt es dafuer keine
     Werte, weil er das Tuerkis nur als Symbolfarbe einsetzt, nie als Flaeche
     mit Zustaenden. Fuer den Abschluss-Knopf (Schritt 7) ergaenzt. */
  --ms-teal: #00B4A0;
  /* Fuer die Tint-Flaeche des Abzeichens, wie --ms-accent-rgb bei .badge-info. */
  --ms-teal-rgb: 0, 180, 160;
  --ms-teal-hover: #00C9B3;
  --ms-teal-active: #009C8B;

  /* Deckkraft einer TINT-FLAECHE: der zarte Farbschleier hinter Abzeichen und
     Symbolplatten (Statusabzeichen, Symbolkachel im Assistenten). Als Token,
     weil dieselbe Absicht vorher mit drei verschiedenen Werten im Code stand
     (.06 / .08 / .10) — sichtbar wurde das nicht, aber es hiess, dass ein
     Nachschaerfen der Tint-Staerke an einem Dutzend Stellen einzeln passieren
     muesste. Gilt NICHT fuer Fokusringe, Zeilen-Hover und Schatten: die haben
     eigene, absichtlich andere Deckkraefte. */
  --ms-tint: 0.08;

  /* --- Farben: Oberflaechen & Borders --- */
  --ms-border-light: #E5E7EB;
  /* GLIEDERNDE Linie — Tabellenzeilen, Tabellenkopf, Werkzeugleiste.
     Nicht dasselbe wie --ms-border-light: das ist die KANTE einer Flaeche
     (Karte, Aufklappmenue, Dialog) und darf zart sein, weil Schatten und
     Fuellung die Flaeche ohnehin absetzen. Eine Zeilenlinie hat keine solche
     Hilfe — sie ist das einzige, was zwei Datensaetze trennt, und bei dreissig
     Zeilen entscheidet sie darueber, ob man der Zeile mit dem Auge folgen kann.
     --ms-border-light erreicht auf Weiss 1,24:1 und verschwindet dabei; dieser
     Wert kommt auf 1,56:1 und bleibt ruhig.

     Eine Deckkraftstufe von --ms-text-tertiary, kein neuer Farbwert — und
     dadurch in beiden Fassungen von selbst richtig (dunkel 1,93:1). Der erste
     Entwurf stand bei 0.28 und damit auf myOFFICE-Hoehe (1,23); das war
     sichtbar, aber zu leise.

     DIESER TON GILT AUCH FUER EINGABEFELDER: --ms-border-control ist ein Alias
     darauf. Eine Feldkante und eine Tabellenlinie sind dieselbe Sache — die
     zarte Linie, die etwas abgrenzt. Wer den Ton hier aendert, aendert beide;
     das ist Absicht.

     ERGAENZUNG, kein Widerspruch zur Website: mkpi.de hat keine Datentabellen
     und deshalb keinen Bedarf fuer diese Unterscheidung (designsystem.md 4.1). */
  --ms-border-divider: rgba(var(--ms-text-tertiary-rgb), 0.40);
  --ms-border-dark: rgba(0,0,0,0.12);   /* Rand auf dunkler Flaeche */

  /* Rand von EINGABEFELDERN — derselbe Ton wie die gliedernde Linie.

     ALIAS, kein zweiter Wert: eine Feldkante und eine Tabellenlinie sind beide
     „die zarte Linie, die etwas abgrenzt". Zwei Werte dafuer laufen frueher
     oder spaeter auseinander, ohne dass es jemand merkt. Der Name bleibt
     trotzdem eigen, damit ein Bauteil sagen kann, was es meint — dasselbe
     Muster wie --ms-valid, --ms-invalid und --ms-control-h.

     ENTSCHIEDEN AM 2026-09-01: der Rand ist dezent (1,56:1 auf Weiss) statt
     kontraststark (#86868B, 3,62:1). Das ist eine bewusste Abweichung von
     WCAG 1.4.11, die fuer die Begrenzung eines Bedienelements 3:1 verlangt.
     Die kontraststarke Fassung liess jedes Feld wie einen eingerahmten Kasten
     wirken; in einer Werkzeugleiste ueber ruhigen Daten war das Suchfeld
     dadurch das Lauteste auf der Seite.

     WAS DIE ANFORDERUNG JETZT TRAEGT: der Fokuszustand. Ein Feld, das bedient
     wird, traegt --ms-accent als Rand plus einen 3px-Schein — 4,65:1 auf Weiss,
     4,27:1 auf dem grauen Band. Dazu kennzeichnen Beschriftung, Platzhalter und
     beim Suchfeld die Lupe das Feld als beschreibbar. Was verloren geht, ist
     die Erkennbarkeit im RUHEZUSTAND bei eingeschraenktem Kontrastsehen; das
     ist der Preis und steht hier, damit er nicht vergessen wird.

     Gilt NICHT fuer Karten und Aufklappmenues — deren Kante ist
     --ms-border-light und darf zarter sein, weil Schatten und Fuellung die
     Flaeche ohnehin absetzen. */
  --ms-border-control: var(--ms-border-divider);
  /* Randton eines Bedienelements UNTER DEM ZEIGER.
     Das System hatte einen ruhenden Ton (--ms-border-control, 1,56:1) und
     einen Fokuston (--ms-accent, 4,65:1), aber keinen fuer den Hover — und
     genau deshalb griff `.btn-outline:hover` zu --ms-text-primary, also zum
     TEXTTON: 16,83:1 auf Weiss, praktisch Schwarz, und im Dunkelmodus 15,63:1,
     praktisch Weiss. Gemeldet als „die Outline ist zu dunkel", und zu Recht.

     DRITTE DECKKRAFTSTUFE DESSELBEN GRAUS, kein neuer Farbwert — dasselbe
     Mittel wie bei --ms-border-divider (0,40). 0,70 ist die kleinste Stufe,
     die unmissverstaendlich anders aussieht, und sie haelt die Ordnung
     ruhend < Hover < Fokus ein:

         ruhend  1,56:1 hell / 1,93:1 dunkel
         Hover   2,32:1 hell / 3,25:1 dunkel
         Fokus   4,65:1 hell

     Bei 0,80 kaeme der dunkle Hover auf 3,82:1 und damit dem Fokus so nahe,
     dass die Reihenfolge verwischt. Weil der Ausdruck kein eigenes
     Farbliteral hat, passt er sich der Fassung von selbst an
     (--ms-text-tertiary-rgb ist im Dunkelmodus ein anderer Wert) und braucht
     kein dunkles Gegenstueck — dieselbe Begruendung wie bei den beiden
     anderen Randtoenen. */
  --ms-border-control-hover: rgba(var(--ms-text-tertiary-rgb), 0.70);
  --ms-card-bg: #FFFFFF;
  /* Kartenfarbe als Zahlentripel — fuer Schleier, die eine Karte halb
     verdecken (gesperrte Produktkarte). Vorher stand dort rgba(255,255,255,…),
     das im Dunkelmodus als weisser Fleck ueber einer dunklen Karte laege. */
  --ms-surface-rgb: 255, 255, 255;
  /* Flacher Schatten fuer Flaechen, die sich nur eben abheben sollen
     (Tabellenkarten der Verwaltung). Die Website kennt nur den Kartenschatten;
     der ist fuer eine Datentabelle zu weich und zu gross. Wert aus dem
     Alt-Bundle (--ms-shadow-sm). */
  --ms-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
  --ms-card-shadow: 0 0 0 1px rgba(0,0,0,0.05), 0 1px 3px rgba(0,0,0,0.06), 0 4px 12px rgba(0,0,0,0.04);
  --ms-card-shadow-hover: 0 4px 12px rgba(0,0,0,0.08), 0 8px 24px rgba(0,0,0,0.06);

  /* --- Ueberlagerungs-Grund (Scrim) ---
     Der Grund UNTER jeder schwebenden Flaeche: Modal, Navigationsschublade,
     Arbeitsblatt, Suchpalette. Er dunkelt ab UND zeichnet weich — der
     Weichzeichner nimmt dem Hintergrund die Struktur und lenkt den Blick
     dadurch staerker auf den Dialog, als Abdunkeln allein es koennte.

     EIN Token fuer alle vier: vorher stand `rgba(0,0,0,0.4)` viermal hart in
     zwei Dateien (overlays.css einmal, shell.css dreimal) und kein einziges
     Mal ein Weichzeichner. Vier Kopien eines Wertes sind vier Gelegenheiten,
     ihn auseinanderlaufen zu lassen; myOFFICE hatte genau das hinter sich
     (.32/.40/.45/.50/.55) und hat es zentral geloest.

     Die Suchpalette bekommt bewusst weniger Weichzeichner: sie legt sich ueber
     die Arbeitsflaeche und soll sie nicht so weit zurueckdraengen wie ein
     Dialog, der eine Entscheidung verlangt.

     --ms-scrim-opaque gilt bei `prefers-reduced-transparency` (overlays.css):
     ohne Weichzeichner muss die Deckkraft die Trennung allein tragen. */
  --ms-scrim: rgba(0,0,0,0.40);
  --ms-scrim-opaque: rgba(0,0,0,0.62);
  --ms-scrim-blur: 4px;
  --ms-scrim-blur-soft: 2px;

  /* --- Farben: System-Feedback --- */
  --ms-success: #198754;
  --ms-success-rgb: 25, 135, 84;
  --ms-success-hover: #157347;
  --ms-success-muted: #D1E7DD;
  --ms-error: #FF3B30;
  --ms-error-rgb: 255, 59, 48;
  --ms-error-muted: #FFE5E3;
  --ms-warning: #FF9500;
  --ms-warning-rgb: 255, 149, 0;
  --ms-warning-muted: #FFF1DA;

  /* ---- Semantik als GROSSE KENNZAHL ----
     Die Zahl einer Kennzahlkachel (.stat-value, --ms-text-h2: 24px fett im
     dichten Profil, mindestens 28px im fluiden). Das ist Grossschrift nach
     WCAG 1.4.3 — dort genuegen 3:1 statt 4,5:1, und deshalb darf hier der
     Vollton stehen, wo er als Fliesstext verboten waere.

     DER NAME TRAEGT DIE BEDINGUNG. Diese Toene gelten NUR fuer eine grosse,
     fette Zahl. Wer sie fuer Fliesstext nimmt, unterschreitet AA — dann
     gehoeren die *-text-Stufen darunter hin.

     Drei sind Verweise und folgen ihrer Volltonfarbe in beide Fassungen. Nur
     das Orange braucht einen eigenen Wert: --ms-warning (#FF9500) erreicht auf
     Weiss 2,20:1 und verfehlt damit auch die 3:1 fuer Grossschrift — es ist
     die hellste Farbe des Systems. #C27100 ist derselbe Farbton (35 Grad) bei
     voller Saettigung, nur dunkler (Helligkeit 38 % statt 50 %) und kommt auf
     3,71:1. Es ist bewusst NICHT --ms-warning-text (#8A4B00): das liest sich
     als Braun und nicht als Warnung.

     Im Dunkelmodus entfaellt die Ausnahme — dort traegt der Vollton
     (#FF9F0A auf der Karte 8,28:1). Vorbild ist das Dashboard von myOFFICE,
     wo die Kachelzahl die Volltonfarbe traegt; seine eigenen Werte liegen
     dabei ueberwiegend unter AA (Blau #02A2FF: 2,76:1, verfehlt auch die
     3:1), deshalb sind die Toene hier nachgerechnet und nicht uebernommen. */
  --ms-figure-danger: var(--ms-error);
  --ms-figure-warning: #C27100;
  --ms-figure-success: var(--ms-success);
  --ms-figure-info: var(--ms-accent);

  /* ---- Semantik als LESBARER TEXT ----
     Zu jeder Statusfarbe der Textton, der auf ihrem Tint UND auf Weiss UND auf
     dem grauen Band AA erfuellt. Die Flaechenfarben selbst schaffen das nicht:
     --ms-success (#198754) kommt auf dem Band nur auf 4,16:1, --ms-error
     (#FF3B30) auf 3,26:1 — beide unter der Grenze von 4,5:1. Flaeche und Text
     fallen hier also auseinander, und genau deshalb braucht es eigene Tokens.
     Muster: HeroUI paart jede Flaeche mit ihrem `-foreground`.

     Gemessen (Weiss / Band / eigener Tint):
       #0F5132  9,36 / 8,60 / 7,21
       #B3261E  6,54 / 6,00 / 5,47
       #8A4B00  6,80 / 6,25 / 6,10
     Die Werte stehen in bin/design-check und werden bei jedem Durchlauf
     nachgerechnet.

     KORREKTUR 2026-08-31: hier stand zuvor #C77800 mit der Behauptung, es
     erfuelle AA. Nachgerechnet sind es 3,43 / 3,15 / 3,08 — es erfuellte AA
     NICHT. Der Wert war geschaetzt, nicht gerechnet. #8A4B00 ist derselbe Ton,
     den das Alt-Bundle an drei Stellen hartcodiert fuehrt; damit gibt es
     zugleich nur noch einen Wert statt zweier. */
  --ms-success-text: #0F5132;
  --ms-error-text:   #B3261E;
  --ms-warning-text: #8A4B00;
  /* Tuerkis als LESBARE Schrift. Der Markenton --ms-teal (#00B4A0) erreicht auf
     Weiss nur 2,61:1 und auf dem grauen Band 2,40:1 — als Flaechenfarbe hinter
     heller Schrift ist das eine bewusste Abweichung (siehe .btn-teal in
     buttons.css), als Schriftfarbe auf hellem Grund ist es keine.
     #007E70 ist derselbe Farbton abgedunkelt: 4,98:1 auf Weiss, 4,57:1 auf dem
     Band. Gebraucht wird er dort, wo Tuerkis einen Zustand BENENNT, nicht wo
     es eine Flaeche einfaerbt.

     Bis zum 2026-09-22 hatte er KEINEN Verwender, und das war kein Versehen:
     Tuerkis benennt seit dem 2026-09-16 keinen Zustand mehr. „Ausgewaehlt"
     trug es zuletzt an der Umrandung der Produktkarte; die steht jetzt auf
     --ms-success, weil das System nicht zwei gruenliche Toene fuer nahe
     verwandte Aussagen fuehren soll (Nachfrage des Betreibers).

     GENAU DESHALB IST ER JETZT DIE FARBE DER ARTIKELART (`.badge-teal`,
     data-display.css). Vier der fuenf Abzeichenfarben benennen einen Zustand —
     `info` „Hinweis", `success` „in Ordnung", `warning` „Aufmerksamkeit",
     `danger` „hier stimmt etwas nicht". Eine EINORDNUNG braucht eine Farbe,
     die nichts behauptet, und Tuerkis ist die einzige, die das noch kann.
     Aufgefallen ist die Luecke, als das Bestandsabzeichen gelb wurde und in
     derselben Zeile neben dem gelben „Verbrauchsartikel" stand.

     Wer Tuerkis als Schrift oder als bedeutungstragende Linie braucht, nimmt
     weiterhin diesen Wert und nicht --ms-teal. */
  --ms-teal-text:    #007E70;

  /* --- Typografie --- */
  --ms-font: 'Inter', 'Inter-Fallback', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  /* Fluid Type Scale */
  --ms-text-display: clamp(2.5rem, 1.8rem + 3vw, 4.5rem);
  --ms-text-h1: clamp(2.25rem, 1.5rem + 3vw, 3.75rem);
  --ms-text-h2: clamp(1.75rem, 1.3rem + 2vw, 3rem);
  --ms-text-h3: clamp(1.5rem, 1.2rem + 1.25vw, 2rem);
  --ms-text-h4: clamp(1.25rem, 1.1rem + 0.5vw, 1.5rem);
  --ms-text-body: clamp(1rem, 0.95rem + 0.2vw, 1.125rem);
  /* Einleitungssatz unter einer Ueberschrift (`.subline`, `.lead`) — die
     fluide Stufe der Website zwischen Fliesstext und h4. Stand bis zum
     2026-10-08 als Wert direkt in base.css. */
  --ms-text-lead: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
  /* Zwei FESTE Zwischenstufen zwischen Fliesstext und h4. Die Website hat sie
     nicht: ihre Groessen sind durchweg fluide, was fuer Marketing-Seiten
     richtig ist. In dichten Datenmasken braucht es dagegen einen festen
     Schritt — ein Kartentitel, der mit der Fensterbreite wandert, laesst
     Tabellenzeilen springen. Werte aus dem Alt-Bundle uebernommen
     (--ms-fs-lg/-md), das denselben Bedarf schon hatte. */
  --ms-text-lg: 1.125rem;
  --ms-text-md: 1rem;
  --ms-text-small: 0.875rem;
  --ms-text-caption: 0.75rem;
  /* Maschinennahe Werte in Festbreitenschrift (`code`): eine Spur kleiner
     als der Text, in dem sie stehen, weil Festbreitenzeichen bei gleicher
     Groesse breiter und dunkler wirken. RELATIV (em), damit der Wert in einer
     14px-Tabellenzeile und in 16px-Fliesstext gleich passt. */
  --ms-text-code: 0.9em;

  /* Schriftgewichte */
  --ms-weight-light: 200;
  --ms-weight-regular: 400;
  --ms-weight-medium: 500;
  --ms-weight-semibold: 600;
  --ms-weight-bold: 700;
  --ms-weight-extrabold: 800;

  /* --- Spacing: 8-Punkt-Rastersystem --- */
  /* 2px. Die kleinste Luecke des Systems: sie trennt Zeilen, die als EIN
     Block gelesen werden sollen — Eintraege einer Navigationsgruppe, Tage im
     Kalender, Zeiten in der Uhrzeitspalte. --ms-space-1 (4px) loest den Block
     schon in Einzelzeilen auf. Stand vor dem 8. September 2026 an sieben
     Stellen als harte 2px im Stylesheet. */
  --ms-space-05: 0.125rem; /* 2px */
  --ms-space-1: 0.25rem;   /* 4px */
  --ms-space-2: 0.5rem;    /* 8px */
  --ms-space-3: 0.75rem;   /* 12px */
  --ms-space-4: 1rem;      /* 16px */
  --ms-space-5: 1.5rem;    /* 24px */
  --ms-space-6: 2rem;      /* 32px */
  --ms-space-8: 3rem;      /* 48px */
  --ms-space-10: 4rem;     /* 64px */
  --ms-space-12: 5rem;     /* 80px */
  --ms-space-16: 6rem;     /* 96px */

  /* Responsive T-Shirt Spacing */
  --ms-space-xs:  clamp(0.125rem, 0.19vw + 0.08rem, 0.25rem);
  --ms-space-s:   clamp(0.25rem, 0.375vw + 0.15rem, 0.5rem);
  --ms-space-m:   clamp(0.5rem, 0.75vw + 0.35rem, 1rem);
  --ms-space-l:   clamp(0.75rem, 1.125vw + 0.5rem, 1.5rem);
  --ms-space-xl:  clamp(1.5rem, 2.25vw + 1rem, 3rem);
  --ms-space-xxl: clamp(3rem, 5vw + 1.5rem, 6rem);

  --ms-section-padding: clamp(4rem, 5vw + 1.5rem, 6rem);
  --ms-section-gap: clamp(2rem, 3vw + 0.5rem, 4rem);

  /* Content-Container */
  --ms-content-width: 1140px;
  --ms-content-wide: 1320px;
  --ms-content-narrow: 720px;
  /* Mindestbreite einer Karte im Artikelraster (`.product-grid`, pages.css).
     SIE STEHT HIER UND NICHT DORT, weil sie mit der Seitenbreite zusammen
     entschieden werden muss: bei `auto-fill` ist die Voreinstellung „mehr und
     schmaler", eine breitere Seite macht die Karten also von selbst kleiner.
     Der Wert wandert deshalb im Block fuer breite Schirme weiter unten mit. */
  --ms-product-card-min: 220px;
  --ms-content-medium: 800px;

  /* --- Button T-Shirt-Sizing --- */
  /* xs stand hier zunaechst mit selbst gewaehlten Werten (0.5/1rem, 2.5rem,
     0.875rem), weil die INLINE-`:root` der Prototyp-Seite die Groesse
     referenziert (.mkpi-btn-xs) ohne sie zu definieren. Die `mkpi-design.css`
     DANEBEN definiert sie sehr wohl — es war also keine Luecke, sondern eine
     nicht gelesene Datei. Korrigiert auf die Website-Werte: die Website setzt
     .mkpi-btn-xs fuer kompakte Aktionen in dichten Listen ein
     (components/messekalender.php), genau der Zweck, den die sechs
     Verwendungen im Assistenten haben. 28px Hoehe mit Text liegt ueber der
     WCAG-Mindesttrefferflaeche von 24px. */
  --ms-btn-xs-py: 0.25rem;     --ms-btn-xs-px: 0.75rem;     --ms-btn-xs-height: 1.75rem;     --ms-btn-xs-font: 0.8125rem;
  --ms-btn-s-py: 0.625rem;     --ms-btn-s-px: 1.25rem;      --ms-btn-s-height: 2.75rem;      --ms-btn-s-font: 1rem;
  --ms-btn-m-py: 0.75rem;      --ms-btn-m-px: 1.75rem;      --ms-btn-m-height: 3rem;         --ms-btn-m-font: 1rem;
  --ms-btn-l-py: 0.875rem;     --ms-btn-l-px: 2rem;         --ms-btn-l-height: 3.25rem;      --ms-btn-l-font: 1rem;
  --ms-btn-xl-py: 1rem;        --ms-btn-xl-px: 2.5rem;      --ms-btn-xl-height: 3.5rem;      --ms-btn-xl-font: 1.125rem;
  /* Wie die Website: aus dem Raster, nicht als eigener Zahlenwert. */
  --ms-btn-gap: var(--ms-space-2);

  /* Button-Defaults (L als Standard, wie im Prototyp) */
  --ms-btn-padding-y: var(--ms-btn-l-py);
  --ms-btn-padding-x: var(--ms-btn-l-px);
  --ms-btn-min-height: var(--ms-btn-l-height);

  /* Einheitliche Hoehe aller Bedienelemente, die in EINER Reihe nebeneinander
     stehen: Suchfeld, Datumsfelder, Knopf, nachgeordneter Verweis. Ohne einen
     gemeinsamen Wert bestimmt jedes Element seine Hoehe selbst aus Schriftgroesse
     und Innenabstand — gemessen waren es in der Werkzeugleiste der
     Produktuebersicht vier verschiedene (48 / 38 / 46 / 28px), wodurch die
     Mittellinien auseinanderfielen.

     Abgeleitet aus der kleinen Knopfgroesse und nicht als eigene Zahl, damit
     Feld und Knopf nicht auseinanderlaufen koennen. Die Website hat keinen
     solchen Token, weil sie keine Bedienreihen dieser Art kennt; myOFFICE loest
     es genauso (--mo-control-h). */
  /* --- Symbolgroessen ---
     Der Sprite zeichnet auf 24x24; die Anzeigegroesse bestimmt die Umgebung.
     Drei Stufen genuegen: in der Zeile mitlaufend (sm), Regelfall (md) und
     betont (lg). `em` und nicht `px`, damit ein Symbol neben kleinerem Text
     mitschrumpft — beim frueheren Zeichensatz ergab sich das von selbst,
     weil Zeichen an der Schriftgroesse hingen. */
  --ms-ico-sm: 0.875em;
  --ms-ico: 1em;
  --ms-ico-lg: 1.25em;
  /* Ein Zeichen, das einen Verweis anfuehrt — der Pfeil vor „zurueck", der
     Winkel hinter einem Textknopf —, eine Spur groesser als sein Text. Keine
     Stufe der Skala: sm und lg setzen ein Symbol sichtbar ab, dieses soll nur
     nicht kleiner WIRKEN als die Buchstaben daneben. Bis zum 2026-10-08 stand
     der Wert zweimal von Hand (buttons.css, pages.css). */
  --ms-ico-plus: 1.1em;

  --ms-control-h: var(--ms-btn-s-height);

  /* ---- Symbolschaltflaeche ----
     Ein Knopf, der NUR ein Symbol traegt: Stift, Kreuz, Zwischenablage. Er
     hatte im System vier verschiedene Groessen, keine davon aus der
     Knopfskala:

       .icon-btn         2.25rem (36px)   buttons.css  (seit 2026-09-10
                                                     in .icon-action aufgegangen)
       .panel-action     2rem    (32px)   data.css
       .detail-file-btn  32px               pages.css — nicht mal in rem
                                                     (ebenfalls abgeloest)
       .btn-close        1.5rem  (24px)   overlays.css

     Vier Groessen sind keine Entscheidung, sondern vier Gelegenheiten. Es gibt
     jetzt ZWEI, und beide haben einen Grund.

     REGELGROESSE = --ms-btn-s-height. Damit ist ein Symbolknopf exakt so hoch
     wie ein Eingabefeld, ein kleiner Knopf und alles andere in einer
     Bedienreihe (--ms-control-h kommt aus demselben Token). 44px ist zugleich
     die Groesse, die sich mit dem Finger sicher trifft.

     DICHTE GROESSE fuer Zeilen, in denen mehrere Symbolknoepfe nebeneinander
     in EINE Tabellenzeile muessen (Handlungsspalte einer Uebersicht, Kopfzeile
     eines Sammelabschnitts). 44px waeren dort hoeher als die Zeile selbst.
     Der Wert steht bewusst NICHT auf der Knopfskala — die naechste Stufe
     darunter waeren 28px, und drei Knoepfe zu 28px in einer Zeile sind
     schwerer zu treffen, als der gewonnene Platz wert ist. */
  --ms-icon-btn-h: var(--ms-btn-s-height);
  --ms-icon-btn-h-dense: 2rem;

  /* ---- AKTIONS-SYMBOL ----
     Ein Symbol, das eine Handlung IST: Stift, Papierkorb, Pfeil, Auge. Es
     traegt keinen Knopf um sich herum — kein Rahmen, kein Grund, keine
     Fuellung —, sondern steht frei in seiner Trefferflaeche. Bauform aus
     myOFFICE (`.mo-iconaction`, `--mo-ico` / `--mo-ico-hit`), Weisung des
     Betreibers am 2026-09-10.

     WARUM NICHT DER SYMBOLKNOPF DARUEBER. `--ms-icon-btn-h` bindet die
     Trefferflaeche an die KNOPFHOEHE, damit ein Symbolknopf so hoch ist wie
     ein Feld daneben. Fuer einen Knopf ist das richtig. Ein Aktions-Symbol
     steht aber nicht in einer Bedienreihe, sondern in einer Tabellenzeile
     oder einer Kartenecke — dort ist die Knopfhoehe zu viel, und die dichte
     Ausweichgroesse (32px) war zu wenig, um das Symbol darin wachsen zu
     lassen. Deshalb ein EIGENES Paar aus Flaeche und Glyphe.

     WARUM DIE GLYPHE FEST IST UND NICHT IN `em`. `--ms-ico` ist bewusst
     `1em`: ein Symbol IM TEXT soll mit seinem Text mitschrumpfen. Ein
     Aktions-Symbol steht neben keinem Text — es hing damit an der
     Schriftgroesse der Zelle, in der es zufaellig landete, und war in der
     Verwaltung (15px Zeilentext) kleiner als im Kundenbereich (16px). Genau
     das war der Anlass: die Symbole sollen groesser und ueberall gleich sein.
     18px in 36px Flaeche sind die Masse aus myOFFICE.

     DIE FLAECHE BLEIBT GROESSER ALS DIE GLYPHE, und das ist der Zweck: 36px
     erfuellen WCAG 2.5.8 (24x24) mit Reserve, waehrend das Symbol optisch
     leicht bleibt. Wer die Flaeche verkleinert, prueft die 24px nach. */
  --ms-action-ico: 1.125rem;   /* 18px Glyphe */
  --ms-action-hit: 2.25rem;    /* 36px Trefferflaeche */
  /* Abstand zwischen zwei Aktions-Symbolen in einer Reihe. */
  --ms-action-gap: var(--ms-space-1);

  /* Ruhe- und Hoverfarbe. Als Tokens und nicht im Bauteil ausgeschrieben,
     damit sich der Ton der Aktions-Symbole an EINER Stelle drehen laesst —
     das war die Weisung. Der Dunkelmodus braucht keine eigene Fassung: beide
     Werte zeigen auf Farbtokens, die dort schon umschlagen. */
  --ms-action-color: var(--ms-text-secondary);
  --ms-action-color-hover: var(--ms-text-primary);
  /* EIN SCHLEIER UND KEINE FLAECHENFARBE. Der erste Versuch nahm
     --ms-bg-secondary, so wie es `.icon-btn` tat. Im Hellen stimmt das; im
     DUNKELN ist dieser Wert (#121214) dunkler als die Karte, auf der die
     Zeile liegt (#1C1C1E) — der Hover sank ein, statt zu heben (im Browser
     gemessen am 2026-09-10). Ein Grauschleier aus --ms-text-tertiary-rgb
     dreht mit dem Modus mit: auf Weiss wird er zur hellen Toenung, auf der
     dunklen Karte zur Aufhellung. Dasselbe Verfahren wie bei
     --ms-border-divider. */
  --ms-action-bg-hover: rgba(var(--ms-text-tertiary-rgb), 0.14);

  /* Wie stark die Glyphe beim Ueberfahren waechst. Der Wert ist klein mit
     Absicht: eine Handlungsspalte hat drei bis vier Symbole nebeneinander,
     und jede Bewegung darin wird viermal gesehen. 1.12 ist sichtbar, ohne
     dass die Zeile zappelt; `1` schaltet die Bewegung ab, ohne dass eine
     Regel geaendert werden muss. Bei `prefers-reduced-motion` gilt sie
     ohnehin nicht (buttons.css). */
  --ms-action-scale-hover: 1.12;
  --ms-action-scale-active: 0.94;

  /* ---- Aussehen eines Bedienelements ----
     Rand, Radius, Fuellung und Fokusring eines Eingabefelds. Als Tokens und
     nicht je Bauteil ausgeschrieben, weil genau das schiefgegangen war: die
     Werkzeugleiste der Bestellliste zeigte vier Felder nebeneinander mit DREI
     verschiedenen Randstaerken (Suchfeld 1px, Auswahlfelder 1.5px,
     Datumsfelder 1px) — bei einem Rand aus halbdurchsichtigem Grau sieht eine
     andere Staerke wie eine andere FARBE aus, und genau so wurde es gemeldet.

     1.5px und nicht 1px: das ist der Wert der echten Formularfelder
     (.form-input/.form-select/.form-textarea) und des abgesetzten Knopfs
     (.btn-outline). Die Ausreisser waren die drei Filterfelder, nicht die
     Formulare — und ein Feld darf etwas fester stehen als die Trennlinie einer
     Tabelle, es ist ein Bedienelement und keine Gliederung.

     Wer ein neues Feld baut, setzt diese Werte NICHT selbst: der gemeinsame
     Regelsatz steht in forms.css, bin/design-check haelt ihn frei von
     Nachbauten. Siehe designsystem.md Abschnitt 6. */
  --ms-control-border-w: 1.5px;
  --ms-control-radius: var(--ms-radius-sm);
  --ms-control-bg: var(--ms-bg-primary);
  --ms-control-focus-ring: 0 0 0 3px rgba(var(--ms-accent-rgb), 0.12);

  /* SCHRIFTGROESSE EINES BEDIENELEMENTS (2026-09-09, Weisung des Betreibers:
     „Sobald es Formularfelder sind, soll dies identisch sein").

     Bis hierher hatte das System dazu keine Vorgabe — Abschnitt 6 des
     Designsystems liess die Groesse ausdruecklich frei („das Aussehen ist die
     Regel, die Groesse ist die Entscheidung"). Entschieden wurde sie deshalb
     Bauteil fuer Bauteil, und das Ergebnis war ein Feld mit 18px neben einem
     Datumsfeld mit 14px in derselben Maske. Gemessen im Assistenten Schritt 4:
     Auswahlfeld und Textfelder 18px, das Datumsfeld daneben 14px, der Knopf
     darunter 16px. Beim eigenen Auswahlfeld standen sogar drei Groessen in
     EINEM Bedienelement: Knopf 18, Suchfeld 18, Eintraege der Liste 14.

     WARUM 1rem (16px) UND NICHT --ms-text-body:
     1. Der Knopf sagt es laengst. `--ms-btn-s-font` ist 1rem und wird im
        dichten Profil NICHT neu gesetzt — ein Knopf ist in beiden Bereichen
        16px. Feld und Knopf teilen bereits die Hoehe (--ms-control-h, Regel 7);
        die Schrift war das fehlende Stueck derselben Kopplung.
     2. --ms-text-body ist FLUID (clamp 16-18px). Gemessen ergibt das 18px bei
        1440px Fensterbreite, 17,248px bei 1024 und 16,736px bei 768 —
        gebrochene Groessen, die sich beim Ziehen am Fenster aendern. Fuer
        Fliesstext ist das gewollt, fuer die Beschriftung eines Bedienelements
        nicht: sie ist Bedienoberflaeche, kein Lesetext.
     3. Unter 16px zoomt iOS Safari die Seite beim Hineintippen in ein Feld.
        Die 14px-Felder des Assistenten taten das, und der Assistent ist die
        Maske, die am ehesten am Telefon bedient wird.

     ZWEI BEREICHE, EIN WERT — vorerst. Kundenbereich und Verwaltung sind
     getrennte Oberflaechen mit eigenen Massen (tokens-dense.css), und dieses
     Token ist der Schalter, falls die Verwaltung enger werden soll: eine Zeile
     dort, und jedes Feld der Verwaltung folgt. Heute steht bewusst derselbe
     Wert, weil der Knopf in beiden Bereichen 16px ist und ein Feld daneben
     nicht anders sein soll. Die Trennung liegt in der HOEHE (44px zu 40/36px),
     nicht in der Schrift.

     WER EIN FELD BAUT, setzt keine eigene Groesse: der gemeinsame Regelsatz
     steht in forms.css, `bin/design-check` (`pruefe_feldschrift`) meldet jede
     abweichende Angabe. */
  --ms-control-font: var(--ms-text-md);

  /* ---- Textkuerzung ----
     Zeilenzahl, auf die Titel und Beschreibung einer Produktkarte gekuerzt
     werden. Als Token, weil das die Hoehe JEDER Karte im Raster bestimmt: die
     Zahl hier ist die einzige Stelle, an der man das Raster luftiger oder
     dichter macht. Ohne feste Zahl bestimmt der laengste Text die Hoehe der
     ganzen Reihe.

     Die Zeilen werden nicht nur gekappt, sondern auch RESERVIERT (siehe
     .text-clamp in base.css) — sonst waere eine Karte mit einzeiligem Namen
     flacher als ihre Nachbarn. Wo gekuerzt wurde, zeigt der Controller
     `text-overflow` den vollen Text als Sprechblase. */
  --ms-clamp-card-title: 1;

  /* --- Border-Radius --- */
  --ms-radius-sm: 8px;
  --ms-radius-md: 12px;
  --ms-radius-lg: 16px;
  --ms-radius-xl: 24px;
  --ms-radius-btn: 12px;
  --ms-radius-pill: 980px;

  /* --- Transitions --- */
  --ms-transition-fast: 150ms ease;
  --ms-transition-base: 200ms ease-in-out;
  --ms-transition-slow: 300ms ease-in-out;

  /* --- Icon-Dimensionen --- */
  --ms-icon-size-s: 1.5rem;   /* 24px */
  --ms-icon-size-m: 2rem;     /* 32px */
  --ms-icon-size-l: 3rem;     /* 48px */
  --ms-icon-size-xl: 4rem;    /* 64px */

  /* --- Feste Symbolgroessen (seit 2026-10-08) ---
     Fuer Behaelter, deren EINZIGER Inhalt ein Symbol ist (Kopfband,
     Navigationsspalte, Schliessen-Kreuz, Symbolplatten). `.ms-ico` misst in
     `em`, also ist die SCHRIFTGROESSE des Behaelters der Regler
     (Designsystem Abschnitt 21) — dort steht dann eines dieser Tokens und
     kein Wert von Hand. Neben Text gilt weiter die relative Skala oben
     (`--ms-ico-sm` … `--ms-ico-lg`), damit ein Symbol mit seinem Text
     mitwaechst. Jede Stufe hat genau einen Grund im Bestand; vorher standen
     diese Werte an zwoelf Stellen als rem-Zahlen. */
  --ms-glyph-xs: 0.75rem;     /* 12px — Aufklapp-Pfeil einer Rubrik, Info-Knopf auf der Karte */
  --ms-glyph-sm: 1rem;        /* 16px — Symbol einer Navigationszeile */
  --ms-glyph-md: 1.125rem;    /* 18px — Kopfband, Suchfeld der Schnellsuche */
  --ms-glyph-lg: 1.25rem;     /* 20px — Schliessen-Kreuz, Hinweisband, Schmalleiste */
  --ms-glyph-xl: 1.75rem;     /* 28px — halbe Breite der 56px-Platte im Bestaetigungsdialog */
  --ms-glyph-2xl: 2.5rem;     /* 40px — Haken auf der Abschlussseite des Assistenten */

  /* --- z-index-Stufen (Ergaenzung: im Prototyp nicht gebraucht, da kein
     echtes Overlay-System existiert — hier fuer Header/Dropdown/Modal/Toast
     einmal zentral festgelegt, damit nichts durcheinander stapelt) --- */
  --ms-z-header: 100;
  --ms-z-dropdown: 200;
  --ms-z-modal-backdrop: 300;
  --ms-z-modal: 310;
  --ms-z-toast: 400;
  --ms-z-tooltip: 500;
  /* AUFKLAPPFLAECHEN, DIE AM <body> HAENGEN — ueber dem Dialog.

     Auswahlliste (v2-select.js) und Kalender (v2-datepicker_controller.js)
     haengen nicht in ihrem Feld, sondern am <body>: in einer Karte oder
     Tabellenzelle mit `overflow` waeren sie sonst abgeschnitten. Damit
     verlieren sie aber den Stapelzusammenhang ihres Feldes — in einem Dialog
     (310) klappten sie auf 200 auf und verschwanden HINTER ihm. Man sah das
     Feld, klickte, und nichts geschah.

     Deshalb eine eigene Stufe zwischen Dialog und Meldungsstreifen: ueber
     jedem Dialog, unter Toast und Kurzhinweis. Sie gilt nur fuer
     losgeloeste Flaechen — ein Aufklappmenue, das in seinem Element bleibt,
     nimmt weiter --ms-z-dropdown. */
  --ms-z-detached: 320;

  /* --- Huelle: Masse ---
     Die Website hat weder Seitenleiste noch Arbeitsspalte; die Anwendung
     bekommt beides (designsystem.md, Abschnitt 8). 56px Kopfband stand bisher
     als Zahl in navigation.css UND admin.css — zwei Stellen fuer einen Wert.
     Die Rail ist 64px: ein 20px-Symbol plus beidseitig Luft aus dem
     8-Punkt-Raster, so breit wie noetig, um es sicher zu treffen. */
  --ms-topbar-h: 56px;
  --ms-nav-w: 248px;
  --ms-nav-w-rail: 64px;
  --ms-aside-w: 320px;
  /* Liste einer Master-Detail-Maske (Artikelverwaltung): links die Auswahl,
     rechts der Datensatz. EIGENES Token und nicht --ms-aside-w, obwohl der
     Startwert derselbe ist: die Arbeitsspalte traegt Kennzahlen und Verweise,
     diese Liste traegt Nummer und Bezeichnung. Wer das eine breiter braucht,
     soll dafuer nicht das andere verschieben.
     380px, nachgemessen und nicht geschaetzt: die laengste Artikelnummer im
     Bestand ist `KPMG-HR-Messepaket-01-02` (24 Zeichen), und daneben steht
     das Abzeichen der Artikelart („Bestandsartikel", 15 Zeichen). Bei 320px
     brach diese Zeile um und die Bezeichnung darunter gleich mit. 380px ist
     ein Vielfaches des 4-Punkt-Rasters und laesst beide Zeilen einzeilig. */
  --ms-md-list-w: 380px;

  /* Zweite Navigationsleiste der Einstellungen. EIGENES Token und nicht
     --ms-md-list-w: das ist eine Auswahlliste mit Artikelnummer und Abzeichen
     und deshalb 380px breit. Hier stehen acht Beschriftungen; die laengste ist
     „Bestandswarnungen" (17 Zeichen). 248px, derselbe Wert wie --ms-nav-w:
     zwei Navigationsleisten nebeneinander, die unterschiedlich breit sind,
     lesen sich als zwei verschiedene Dinge — sie sind aber dasselbe Ding auf
     zwei Ebenen. */
  --ms-settings-nav-w: 248px;

  /* Stufenfeld einer Rechtezeile (Rechte-Editor der Nutzergruppen). Als Token
     und nicht als Zahl in der Regel: es ist ein MASS DES SYSTEMS wie die
     Breite der Navigationsleisten darueber, und die Zeile soll es verwenden
     statt es zu erraten.

     160px, gerechnet und nicht geschaetzt: „Kein Zugriff" ist die laengste der
     drei Stufen in beiden Sprachen und misst 82px (bei 16px gemessen, in der
     Ersatzschrift — Inter ist schmaler, der Wert ist also eine Obergrenze).
     Dazu die Masse des Feldes selbst aus forms.css: 16px Polsterung links,
     40px rechts fuer den Auswahlpfeil, 2x1,5px Rand — zusammen 141px. 160px
     lassen der zweiten Sprache und einer spaeter laengeren Stufe Luft und
     liegen auf dem 8-Punkt-Raster.

     WOZU UEBERHAUPT EIN FESTES MASS: ohne es misst das Feld seinen GEWAEHLTEN
     Eintrag, und „Kein Zugriff" ist laenger als „Bearbeiten" — sechzehn Zeilen
     bekamen dadurch sechzehn verschiedene rechte Kanten, und ein Stufenwechsel
     verschob die Kante der Zeile (Betreiber, 2026-09-11). Dieselbe Falle wie
     beim Einheitenfeld der Artikelmaske. */
  --ms-perm-level-w: 10rem;

  /* Die Spur der Feldnamen in der Pruefteafel der Sammeluebersetzung
     (`.review-field`, data.css).

     HERGELEITET UND NICHT GEGRIFFEN: die laengste Beschriftung ist
     „Beschreibung" — zwoelf Zeichen, in der Ersatzschrift bei 13px
     (`--ms-text-caption`) rund 88px breit; Inter ist schmaler, der Wert ist
     also eine Obergrenze. Dazu der Spaltenabstand `--ms-space-4` (16px).
     8rem = 128px lassen der englischen Fassung („Closing text") und einem
     spaeter laengeren Feldnamen Luft und liegen auf dem 8-Punkt-Raster.

     WOZU EIN FESTES MASS: ohne es misst die Spalte ihren laengsten Eintrag,
     und der ist je Datenart verschieden — „Name" beim Artikel, „Einleitung"
     beim Set. Die deutschen und englischen Texte begaennen dann in jedem
     Block an einer anderen Stelle, obwohl man sie untereinander vergleicht.
     Dieselbe Ueberlegung wie bei `--ms-perm-level-w` darueber. */
  --ms-review-label-w: 8rem;

  /* Kante eines Bildfeldes in der Artikelgalerie. Als Token, weil dieselbe
     Reihe spaeter in der Set-Maske und in der Bestellansicht steht und dort
     dasselbe Mass haben muss. */
  --ms-image-tile: 7.5rem;

  /* --- Huelle: Farben der Navigationsspalte ---
     EIGENE Namen mit eigener Bedeutung, KEINE Verweise auf --ms-bg-dark:
     --ms-nav-bg heisst „Grund der Navigation", nicht „dunkel". Im Hellmodus
     ist er identisch mit --ms-bg-dark, im Dunkelmodus dunkler als der Grund
     der Seite — die Navigation setzt sich in beiden Faellen vom Umfeld ab,
     und genau das ist die Aussage, die der Name traegt.

     Warum dunkel und nicht hell: der Inhalt der Verwaltung sind weisse Karten
     auf --ms-bg-secondary. Eine helle Spalte daneben haette gegen beide fast
     keinen Kontrast und braeuchte eine Trennlinie, um als eigener Bereich
     lesbar zu sein. Die Werte sind keine neuen Farben: es sind die dunklen
     Textstufen und der dunkle Rand, die die Website fuer ihre dunklen Baender
     fuehrt. Gemessen: --ms-nav-text auf --ms-nav-bg 7,39:1. */
  --ms-nav-bg: #1D1D1F;
  --ms-nav-text: #A1A1A6;
  --ms-nav-on: #F5F5F7;
  --ms-nav-active: #FFFFFF;
  /* Rubriktitel und Fusszeile der Leiste: leiser als die Eintraege, aber
     lesbar — 5,86:1 auf --ms-nav-bg (AA fuer 12px-Versalien). */
  --ms-nav-muted: #98989D;
  --ms-nav-hover: rgba(255,255,255,0.07);
  --ms-nav-line: rgba(255,255,255,0.12);
  /* Warn- und Fehlerfarbe FUER DIE NAVIGATIONSSPALTE. Sie braucht eigene
     Werte, weil ihre Flaeche in BEIDEN Fassungen dunkel ist (#1D1D1F bzw.
     #000000): --ms-warning-text (#8A4B00) und --ms-error-text (#B3261E)
     erreichen dort nur 2,47:1 und 2,57:1 — der Sitzungszaehler waere in
     seiner letzten Minute unlesbar geworden. Die hellen Toene tragen auf
     beiden Flaechen (8,19:1 bzw. 5,97:1) und stehen deshalb in allen
     Fassungen gleich. */
  --ms-nav-warning: #FF9F0A;
  --ms-nav-critical: #FF6961;
  --ms-nav-active-bg: rgba(var(--ms-accent-rgb), 0.22);
  /* Das Kopfband des KUNDENbereichs (.header, navigation.css) ist Glas:
     durchscheinend, damit der Inhalt beim Rollen darunter durchschimmert.
     Stand bisher hart in navigation.css.

     NUR DORT. Das Kopfband der Verwaltung (.topbar, shell.css) traegt
     seit dem 2026-09-02 den Grund der Navigation und ist deckend —
     Begruendung an der Regel selbst, Designsystem Abschnitt 8. */
  --ms-topbar-bg: rgba(255,255,255,0.72);

  /* --- Kopfzeile eines Sammelabschnitts ---
     Die Abschnitte einer Stammdatenmaske (Adressen, Kontakte, Bestellungen)
     tragen eine dunkle Kopfzeile mit Titel, Zaehler, Suche und Handlungen.

     WARUM EIN EIGENER TON und nicht --ms-nav-bg: die Navigationsspalte ist die
     dunkelste Flaeche der Anwendung; eine Kopfzeile in derselben Farbe laese
     sich als zweites Navigationselement lesen, und im Dunkelmodus verschmaeleze
     sie mit dem Grund. #3A3A3C ist eine Stufe heller — dieselbe Rolle, die
     myOFFICE seinem Slate-Blau gibt, in unserem neutralen Grau.

     IN BEIDEN FASSUNGEN GLEICH: die Kopfzeile ist eine erhoehte Flaeche mit
     immer derselben Aufgabe. Hell hebt sie sich gegen die weisse Karte ab
     (11,35:1), dunkel gegen die dunkle Karte (1,50:1) — dort traegt zusaetzlich
     die Kante der Karte.

     Gemessen: Titel 10,42:1, gedaempfter Text 5,13:1. Der gedaempfte Ton ist
     NICHT --ms-text-secondary-dark (#A1A1A6): der erreicht auf dieser Flaeche
     nur 4,41:1 und verfehlt AA. Auf der Zaehler-Pille (weisser Schleier) steht
     deshalb der volle Titel-Ton, nicht der gedaempfte — 6,73:1 gegen 3,32:1. */
  --ms-panel-head: #3A3A3C;
  --ms-panel-head-on: #F5F5F7;
  --ms-panel-head-muted: #AEAEB2;
  --ms-panel-head-overlay: rgba(255,255,255,0.14);

  /* --- Feldrueckmeldung ---
     Pflichtfeld fehlt / Feld gueltig. ALIASE auf die Statusfarben, keine
     eigenen Werte: ein rotes Feld und ein rotes Abzeichen sollen dasselbe Rot
     tragen. Die eigenen Namen sind trotzdem noetig — ein Bauteil, das
     „ungueltig" meint, soll das auch sagen, nicht „Fehler". Wandern die
     Statusfarben (etwa im Dunkelmodus), wandern diese mit. */
  --ms-invalid: var(--ms-error);
  --ms-invalid-rgb: var(--ms-error-rgb);
  --ms-invalid-text: var(--ms-error-text);
  --ms-valid: var(--ms-success);
  --ms-valid-rgb: var(--ms-success-rgb);
  --ms-valid-text: var(--ms-success-text);

  /* ── Lager (seit 2026-09-07) ──
     Drei Masse des Regalrasters. Sie stehen hier und nicht im Bauteil, weil
     Regel 1 des Designsystems kein px im Bauteil zulaesst — und weil die
     Fachbreite die einzige Zahl ist, an der man das Raster verdichten wuerde,
     wenn ein Lager mehr Faecher je Reihe bekommt. */
  --ms-shelf-bay-w: 148px;
  --ms-shelf-cell-h: 44px;
  --ms-shelf-zone-w: 200px;
  --ms-scan-video-w: 480px;
  /* Hoehe der rollenden Vorschlagsliste, als Spanne: bevorzugt 52vh, aber nie
     hoeher als das Maximum und nie niedriger als das Minimum
     (`clamp()` in `.suggest-list--scroll`).

     DIE UNTERGRENZE IST KEIN SCHMUCK. Ohne sie faellt die Liste bei winziger
     Fensterhoehe auf fast nichts zusammen — nachgemessen in einem Fenster, das
     `100vh` als 0 meldete: `min(52vh, 420px)` ergab 0px, und die Liste war
     unsichtbar. Vier Zeilen sind das Mindeste, mit dem man auswaehlen kann. */
  --ms-suggest-min-h: 200px;
  --ms-suggest-max-h: 420px;

  /* Mengenfeld und Obergrenze einer Vorschlagszeile.
     ALS TOKEN UND NICHT ALS ZAHL IN DER REGEL, weil DREI Regeln sie brauchen:
     das Feld selbst, die Obergrenze daneben — und die rechte Spalte, deren
     Breite aus beiden GERECHNET wird. Nur mit fester Breite steht das Feld in
     allen Zeilen an derselben Stelle, und nur dann kann der Zustandssatz
     darunter linksbuendig zum Feld beginnen (Weisung des Betreibers,
     2026-09-09). Waere die Spalte inhaltsbreit, verschoebe ein langer Satz
     („Kein Platz — 440 liegen woanders") das Feld der Zeile. */
  --ms-suggest-qty-w: 5.5rem;
  --ms-suggest-max-w: 7rem;
}

/* ══════════════════════════════════════════════════
   BREITE SCHIRME: DIE SPROSSE, DIE BEIM PORTIEREN FEHLTE (2026-09-17)

   Gefragt hat der Betreiber, woher die 1140px kommen und ob sie heute noch
   richtig sind. Es ist Bootstraps `xl`-Sprosse — bei uns die letzte, bei
   Bootstrap seit 2021 nicht mehr. mkpi.de, von dem dieses Tokensystem stammt,
   setzt daneben ausdruecklich (ausgelesen aus der lebenden mkpi-design.css):

       @media (min-width: 1400px) {
         .container { max-width: var(--mkpi-content-wide); }   // 1320px
       }

   Uebernommen wurde beim Portieren die ZAHLENLISTE — `--ms-content-wide:
   1320px` steht seit je oben in :root —, nicht die Regel, die sie benutzt. Das
   Token war auf der Kundenseite unbenutzt. Hier steht es nach. Es ist also
   keine neue Entscheidung, sondern eine nachgeholte Zeile.

   WARUM NICHT MEHR. 1536x864 ist nach 1920x1080 die zweithaeufigste
   Desktopaufloesung (1920er Panel bei 125% Skalierung). Dort lassen 1320px
   108px Rand je Seite, 1400px nur 68px — und bei genau 1400px Fenster GAR
   KEINEN, denn Umschaltpunkt und Breite waeren dieselbe Zahl. 1440px lassen
   48px. Gemessen, nicht geschaetzt.

   WARUM NICHT WENIGER. 1280 (Tailwind, GitHub) ergibt in JEDEM unserer Raster
   dieselbe Spaltenzahl wie 1320; der Unterschied sind acht bis dreizehn Pixel
   je Karte. Wo die Messung nichts entscheidet, entscheidet die Herkunft.

   NUR DIE KUNDENSEITE — und `:not([data-density="dense"])` und NICHT
   `[data-density="fluid"]`: das fluide Merkmal steht am <body>, die Verwaltung
   setzt ihres am <html> (v2-ui.js zieht es beim Turbo-Wechsel nach, Zeile
   638). Auf dem <html> einer Kundenseite steht deshalb GAR KEIN Merkmal, und
   eine Regel auf "fluid" haette nie gegriffen. Die Verwaltung bleibt bei 100%.

   WAS SICH NICHT AENDERT: die Tippbreite. `.card:has(.form-group)` haelt jede
   Karte mit Eingabefeldern bei 800px (surfaces.css), und diese Regel haengt
   nicht am Massprofil — sie gilt im Kundenbereich schon heute.
   ══════════════════════════════════════════════════ */
@media (min-width: 1400px) {
  :root:not([data-density="dense"]) {
    --ms-content-width: var(--ms-content-wide);
    /* ZWEITE ENTSCHEIDUNG, gleiche Stelle: was das Artikelraster mit dem Platz
       macht. Bliebe die Mindestspalte bei 220px, zoege `auto-fill` hier eine
       FUENFTE Spalte ein und verschmaelerte jede Karte von 255 auf 235px —
       mehr Platz haette die Karten KLEINER gemacht, das Gegenteil der Weisung
       des Betreibers („nicht zu eng nebeneinander oder so klein"). Mit 260px
       bleiben es vier Spalten, jetzt 300px statt 255px breit.

       AN DER SPROSSE UND NICHT ALS EINE ZAHL FUER BEIDE PLATEAUS: ein einziger
       Wert muesste bei 1092px UND bei 1272px Flaeche vier Spalten ergeben, und
       das gaebe nur 250px — rechnerisch 4,07, also sieben Hundertstel ueber
       dem Umschlag auf drei Spalten. Zwei Werte an zwei Breiten haben beide
       Luft (4,57 und 4,56). Gemessen, nachdem 260px fuer beide Plateaus das
       schmale um eine Spalte gekostet hatte. */
    --ms-product-card-min: 260px;
  }
}

/* ══════════════════════════════════════════════════
   DUNKLE FASSUNG

   Dieselben Token, ein zweiter Wertesatz. Drei Bloecke, dieselbe Bauart wie
   in myOFFICE — uebernommen ist die STRUKTUR, kein Wert:

     :root                                   helle Fassung (oben)
     @media (prefers-color-scheme: dark)
       :root:not([data-theme="light"])       folgt dem Betriebssystem
     :root[data-theme="dark"]                ausdrueckliche Wahl schlaegt das
                                             System, in beide Richtungen

   Kein Bauteil bekommt eine Farbe innerhalb dieser Bloecke — hier stehen
   ausschliesslich Token-Werte. Wer eine Farbe in einem @media-Block
   deklariert, hat den Mechanismus zerbrochen, denn dann fehlt sie im jeweils
   anderen Zustand. bin/design-check prueft: jede Farbe des hellen Blocks hat
   ein dunkles Gegenstueck, und beide dunklen Bloecke sind wortgleich.

   JEDER WERT IST GERECHNET, nicht geschaetzt (Kontrastpaare in
   bin/design-check, KONTRASTPAARE_DUNKEL). Zwei Werte lassen sich nicht
   einfach spiegeln:

   - --ms-tint springt von 0,08 auf 0,20. Acht Prozent Farbschleier ueber
     Weiss sind deutlich sichtbar; dieselben acht Prozent ueber #1C1C1E sind
     praktisch unsichtbar — das Statusabzeichen verloere seine Flaeche.
   - Der Kartenschatten wird zur Kante. Auf dunklem Grund hebt ein Schatten
     nichts ab, er verschmiert nur. Eine 1px-Kante aus rgba(255,255,255,.08)
     traegt das Abheben, ein tiefer Schatten darunter die schwebenden Flaechen.

   Die -muted-Flaechen sind die Statusfarbe mit --ms-tint ueber der Karte
   (#1C1C1E), als Hex ausgerechnet, damit der Kontrast pruefbar bleibt.
   --ms-error-text ist NICHT --ms-error: #FF453A erreicht auf seinem eigenen
   Tint nur 3,95:1; #FF6961 kommt auf 4,77:1.

   DIE *-dark-TOKEN KEHREN SICH UM. --ms-bg-dark heisst nicht „dunkel",
   sondern „die Flaeche, die sich vom Umfeld abhebt": Kurzhinweis, Sprechblase,
   aktive Sortier-Chips. Auf dunklem Grund ist das eine HELLE Flaeche
   (#E5E5EA) — wie die Sprechblasen von macOS im Dunkelmodus. Entsprechend
   ist --ms-text-primary-dark („Text auf dieser Flaeche") hier dunkel.
   Das loest zugleich den Knopftext: #F5F5F7 auf dem dunklen Akzent #0A84FF
   erreichte 3,35:1; #1D1D1F erreicht 4,61:1. Ein heller Akzent braucht
   dunklen Text — Material 3 macht es im Dunkelmodus genauso (on-primary).
   Schwarz traegt nur die Navigation (--ms-nav-bg): sie ist die einzige
   Flaeche, die dunkler als der Grund sein SOLL, und hat eigene Token.

   color-scheme: dark schaltet Bildlaufleisten, Auswahllisten und die
   eingebaute Datumsauswahl des Browsers mit.
   ══════════════════════════════════════════════════ */
:root[data-theme="dark"] {
  color-scheme: dark;
  --ms-bg-primary: #1C1C1E;
  --ms-bg-secondary: #121214;
  /* Eigene, kuehle Flaeche statt #121214: auf dem neutralen Grau
     verschwindet der Lichthof, er braucht einen Blauanteil. */
  --ms-auth-bg: #0F1B2D;
  --ms-bg-dark: #E5E5EA;
  --ms-bg-darker: #F5F5F7;
  --ms-bg-hero: #FFFFFF;
  --ms-text-primary: #F5F5F7;
  --ms-text-secondary: #A1A1A6;
  --ms-text-tertiary: #8E8E93;
  --ms-text-tertiary-rgb: 142, 142, 147;
  --ms-text-primary-dark: #1D1D1F;
  --ms-text-secondary-dark: #5C5C61;
  --ms-text-tertiary-dark: #6E6E73;
  --ms-accent: #0A84FF;
  --ms-accent-rgb: 10, 132, 255;
  --ms-on-accent: #1D1D1F;
  --ms-accent-hover: #3D9FFF;
  --ms-accent-active: #0072E3;
  --ms-link: #3D9FFF;
  --ms-link-dark: #005BB5;
  --ms-gradient-start: #0A84FF;
  --ms-gradient-end: #2DD4C4;
  --ms-icon-color: #2DD4C4;
  --ms-icon-color-rgb: 45, 212, 196;
  --ms-teal: #2DD4C4;
  --ms-teal-rgb: 45, 212, 196;
  --ms-teal-hover: #5EE0D3;
  --ms-teal-active: #14B8A8;
  --ms-tint: 0.20;
  --ms-border-light: #2C2C2E;
  --ms-border-dark: rgba(0,0,0,0.12);
  --ms-card-bg: #1C1C1E;
  --ms-surface-rgb: 28, 28, 30;
  --ms-shadow-sm: 0 0 0 1px rgba(255,255,255,0.06);
  --ms-card-shadow: 0 0 0 1px rgba(255,255,255,0.08), 0 2px 10px rgba(0,0,0,0.5);
  --ms-card-shadow-hover: 0 0 0 1px rgba(255,255,255,0.12), 0 8px 24px rgba(0,0,0,0.6);
  /* Kraeftiger als in der hellen Fassung: 0,40 Schwarz ueber einem Grund
     von #121214 ist kaum ein Unterschied — der Scrim traegt dort nichts. */
  --ms-scrim: rgba(0,0,0,0.62);
  --ms-scrim-opaque: rgba(0,0,0,0.82);
  --ms-success: #30D158;
  --ms-success-rgb: 48, 209, 88;
  --ms-success-hover: #4ADE80;
  --ms-success-muted: #20402A;
  --ms-error: #FF453A;
  --ms-error-rgb: 255, 69, 58;
  --ms-error-muted: #492424;
  --ms-warning: #FF9F0A;
  /* Im Dunkeln traegt der Vollton die Kennzahl selbst — 8,28:1 auf der
     Karte. Die Ausnahme des hellen Blocks entfaellt hier. */
  --ms-figure-warning: var(--ms-warning);
  --ms-warning-rgb: 255, 159, 10;
  --ms-warning-muted: #49361A;
  --ms-success-text: #30D158;
  --ms-error-text: #FF6961;
  --ms-warning-text: #FF9F0A;
  /* Auf dunklem Grund ist der Markenton selbst schon lesbar (9,18:1 auf der
     Karte) — hier braucht es keinen zweiten Wert. */
  --ms-teal-text: var(--ms-teal);
  --ms-nav-bg: #000000;
  --ms-nav-text: #A1A1A6;
  --ms-nav-on: #F5F5F7;
  --ms-nav-active: #FFFFFF;
  --ms-nav-muted: #8E8E93;
  --ms-nav-hover: rgba(255,255,255,0.08);
  --ms-nav-line: rgba(255,255,255,0.12);
  /* Siehe Begruendung in der hellen Fassung: die Navigation ist immer dunkel. */
  --ms-nav-warning: #FF9F0A;
  --ms-nav-critical: #FF6961;
  --ms-nav-active-bg: rgba(var(--ms-accent-rgb), 0.22);
  --ms-topbar-bg: rgba(28,28,30,0.80);
  --ms-panel-head: #3A3A3C;
  --ms-panel-head-on: #F5F5F7;
  --ms-panel-head-muted: #AEAEB2;
  --ms-panel-head-overlay: rgba(255,255,255,0.14);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --ms-bg-primary: #1C1C1E;
    --ms-bg-secondary: #121214;
    /* Eigene, kuehle Flaeche statt #121214: auf dem neutralen Grau
       verschwindet der Lichthof, er braucht einen Blauanteil. */
    --ms-auth-bg: #0F1B2D;
    --ms-bg-dark: #E5E5EA;
    --ms-bg-darker: #F5F5F7;
    --ms-bg-hero: #FFFFFF;
    --ms-text-primary: #F5F5F7;
    --ms-text-secondary: #A1A1A6;
    --ms-text-tertiary: #8E8E93;
    --ms-text-tertiary-rgb: 142, 142, 147;
    --ms-text-primary-dark: #1D1D1F;
    --ms-text-secondary-dark: #5C5C61;
    --ms-text-tertiary-dark: #6E6E73;
    --ms-accent: #0A84FF;
    --ms-accent-rgb: 10, 132, 255;
    --ms-on-accent: #1D1D1F;
    --ms-accent-hover: #3D9FFF;
    --ms-accent-active: #0072E3;
    --ms-link: #3D9FFF;
    --ms-link-dark: #005BB5;
    --ms-gradient-start: #0A84FF;
    --ms-gradient-end: #2DD4C4;
    --ms-icon-color: #2DD4C4;
    --ms-icon-color-rgb: 45, 212, 196;
    --ms-teal: #2DD4C4;
    --ms-teal-rgb: 45, 212, 196;
    --ms-teal-hover: #5EE0D3;
    --ms-teal-active: #14B8A8;
    --ms-tint: 0.20;
    --ms-border-light: #2C2C2E;
    --ms-border-dark: rgba(0,0,0,0.12);
    --ms-card-bg: #1C1C1E;
    --ms-surface-rgb: 28, 28, 30;
    --ms-shadow-sm: 0 0 0 1px rgba(255,255,255,0.06);
    --ms-card-shadow: 0 0 0 1px rgba(255,255,255,0.08), 0 2px 10px rgba(0,0,0,0.5);
    --ms-card-shadow-hover: 0 0 0 1px rgba(255,255,255,0.12), 0 8px 24px rgba(0,0,0,0.6);
    /* Kraeftiger als in der hellen Fassung: 0,40 Schwarz ueber einem Grund
       von #121214 ist kaum ein Unterschied — der Scrim traegt dort nichts. */
    --ms-scrim: rgba(0,0,0,0.62);
    --ms-scrim-opaque: rgba(0,0,0,0.82);
    --ms-success: #30D158;
    --ms-success-rgb: 48, 209, 88;
    --ms-success-hover: #4ADE80;
    --ms-success-muted: #20402A;
    --ms-error: #FF453A;
    --ms-error-rgb: 255, 69, 58;
    --ms-error-muted: #492424;
    --ms-warning: #FF9F0A;
  /* Im Dunkeln traegt der Vollton die Kennzahl selbst — 8,28:1 auf der
     Karte. Die Ausnahme des hellen Blocks entfaellt hier. */
  --ms-figure-warning: var(--ms-warning);
    --ms-warning-rgb: 255, 159, 10;
    --ms-warning-muted: #49361A;
    --ms-success-text: #30D158;
    --ms-error-text: #FF6961;
    --ms-warning-text: #FF9F0A;
    /* Begruendung wie im Blockkopf: der Markenton traegt hier selbst. */
    --ms-teal-text: var(--ms-teal);
    --ms-nav-bg: #000000;
    --ms-nav-text: #A1A1A6;
    --ms-nav-on: #F5F5F7;
    --ms-nav-active: #FFFFFF;
    --ms-nav-muted: #8E8E93;
    --ms-nav-hover: rgba(255,255,255,0.08);
    --ms-nav-line: rgba(255,255,255,0.12);
    /* Siehe Begruendung in der hellen Fassung: die Navigation ist immer dunkel. */
    --ms-nav-warning: #FF9F0A;
    --ms-nav-critical: #FF6961;
    --ms-nav-active-bg: rgba(var(--ms-accent-rgb), 0.22);
    --ms-topbar-bg: rgba(28,28,30,0.80);
    --ms-panel-head: #3A3A3C;
    --ms-panel-head-on: #F5F5F7;
    --ms-panel-head-muted: #AEAEB2;
    --ms-panel-head-overlay: rgba(255,255,255,0.14);
  }
}
