/* ============================================================================
   CYBERDISE — DESIGN SYSTEM · Track A: Foundation tokens
   Model: PALETTE (raw brand values) → ROLES (semantic) → components use ROLES only.
   Components must NEVER reference --cd-* palette vars or raw hex — only role tokens.
   Source of truth for palette: Brand-Messaging-Standard2026 (brandbook, canonical CI).
   Signature gradient values: taken from the actual logo SVG (the "neon ibex").
   ========================================================================== */

/* ------------------------------------------------------------------ FONTS -- */
/* Changa self-hosted (display / titles / accent / eyebrows), WITHOUT its Arabic half. Made from
   the Google Fonts TTFs: pyftsubset --unicodes="U+0000-05FF,U+1E00-1EFF,U+2000-25FF,U+FB00-FB04"
   --layout-features='*' --flavor=woff2. */
@font-face { font-family:"Changa"; font-weight:300; font-style:normal; font-display:swap;
  src:url("./assets/fonts/Changa-Light.woff2") format("woff2"); }
@font-face { font-family:"Changa"; font-weight:400; font-style:normal; font-display:swap;
  src:url("./assets/fonts/Changa-Regular.woff2") format("woff2"); }
@font-face { font-family:"Changa"; font-weight:500; font-style:normal; font-display:swap;
  src:url("./assets/fonts/Changa-Medium.woff2") format("woff2"); }
@font-face { font-family:"Changa"; font-weight:600; font-style:normal; font-display:swap;
  src:url("./assets/fonts/Changa-SemiBold.woff2") format("woff2"); }
@font-face { font-family:"Changa"; font-weight:700; font-style:normal; font-display:swap;
  src:url("./assets/fonts/Changa-Bold.woff2") format("woff2"); }
@font-face { font-family:"Changa"; font-weight:800; font-style:normal; font-display:swap;
  src:url("./assets/fonts/Changa-ExtraBold.woff2") format("woff2"); }
/* Body = Open Sans (brandbook, replaced Source Sans 2025-04). Production: self-host.
   Preview pulls it from Google Fonts via a <link> in the HTML; system-ui is the fallback. */

:root {
  /* ============================ LAYER 1 · PALETTE (raw brand) ============= */
  /* Main colours — brandbook canonical (HEX = exact RGB from Design Standards). */
  --cd-teal:     #67B1A7;   /* Growth · Focus · Ambition            */
  --cd-purple:   #4E147C;   /* Imagination · Royalty · Justice — brand anchor */
  --cd-magenta:  #A12C86;   /* Positive emotions · Creativity       */
  --cd-pink:     #E059A0;   /* Compassion · Passion                 */
  --cd-yellow:   #F2D668;   /* Warmth · Positivity · Happiness      */
  --cd-orange:   #EA5E35;   /* Energy · Warmth · Success            */

  /* Purple ramp (primary brand hue).
     ELF STUFEN, wie jede Rampe hier. Bis 06.08. fehlten 600 und 400 — nicht aus einem
     Grund, sondern weil die Rampen beim Anlegen (22.07.) von Hand mit genau den Stufen
     geschrieben wurden, die damals gebraucht waren. Das faellt erst auf, wenn jemand
     nach einer greift, die es nicht gibt. Seither gilt: alle Rampen tragen dieselben
     elf Stufen, auch ungenutzte — eine Luecke kostet nichts, eine fehlende Stufe kostet
     eine Suche. Die zwei neuen sind die Mitte ihrer Nachbarn. */
  --cd-purple-950:#1A0730;
  --cd-purple-900:#2A0C4E;
  --cd-purple-800:#3A0F63;
  --cd-purple-700:#4E147C;  /* = base --cd-purple */
  --cd-purple-600:#5C218D;
  --cd-purple-500:#6B2E9E;
  --cd-purple-400:#8855B1;
  --cd-purple-300:#A47CC4;
  --cd-purple-200:#C9AEDE;
  --cd-purple-100:#E7DAF1;
  --cd-purple-50: #F5EFFA;

  /* Neutrals — NEUTRAL, nicht violett getoent (Noel, 06.08.2026).
     Historie, weil sie den Wert erklaert: bis dahin trug die Reihe absichtlich einen
     Violettstich, «damit die Grautoene in der Marke sitzen, nicht daneben» — eine
     Entscheidung von uns, nicht des Kunden. Im Brandbook stehen genau sechs Farben und
     kein Grau. Statt eine ZWEITE Neutralreihe danebenzustellen (das war der erste Anlauf
     und eine Gabelung im System) traegt diese eine Reihe neutrale Werte.
     Elf Stufen statt neun: 800 und 600 schliessen die Luecken, die beim Belegen der
     Rollen auffielen.
     ⚠ --cd-ink bleibt violett-stichig. Er ist die Bezugsfarbe, gegen die ALLE
     abgeleiteten Rampen mischen (teal-900, magenta-700, pink-800 …) — ihn zu
     neutralisieren faerbte die halbe Palette um. Ausserdem traegt er die fixen
     dunklen Flaechen (Code-Block, Call-out). Der Uebergang Grau ↔ ink ist unkritisch:
     beide sind so dunkel, dass der Abstand bei 9 von 255 liegt. */
  --cd-ink:      #16101E;   /* near-black, purple-cast — Marken-Schwarz, bewusst getoent */
  --cd-gray-950: #101416;
  --cd-gray-900: #1B2124;
  --cd-gray-800: #2A3236;
  --cd-gray-700: #3E484C;
  --cd-gray-600: #566165;
  /* 500 traegt --text-muted und ist die einzige Stufe, die beim Neutralisieren NICHT
     eins zu eins uebernommen wurde. Der neutrale Wert #6E797D ist heller als der alte
     und faellt auf getoenter Flaeche auf 4.16:1 — unter die AA-Schwelle fuer Fliesstext,
     und genau dort sitzen Lead-Absaetze und Bildunterschriften. Abgedunkelt auf 5.30:1
     (weiss: 5.70:1) und damit wertgleich zum alten Stand.
     Derselbe Fehler ist hier schon einmal passiert: #7A7288 erreichte 4.2:1 und musste
     auf #6B6379 abgedunkelt werden. */
  --cd-gray-500: #5F686C;
  --cd-gray-400: #939C9F;
  --cd-gray-300: #B9C0C2;
  --cd-gray-200: #D7DBDC;
  --cd-gray-100: #EAEDED;
  --cd-gray-50:  #F5F7F7;

  --cd-white:    #FFFFFF;
  --cd-offwhite: #FAF8FC;

  /* Secondary-hue ramps — DERIVED from the canonical bases (base = 500), NOT brandbook
     values. Light 50–100 steps give calm, near-white alternative backgrounds (Palo:
     überwiegend helles Design → Verläufe nur sparsam, Flächen aus der 50er-Reihe).
     Dark steps mix toward --cd-ink so shades stay inside the brand, never neutral black. */
  --cd-teal-950: color-mix(in srgb, var(--cd-teal) 18%, var(--cd-ink));
  --cd-teal-900: color-mix(in srgb, var(--cd-teal) 30%, var(--cd-ink));
  --cd-teal-800: color-mix(in srgb, var(--cd-teal) 46%, var(--cd-ink));
  --cd-teal-700: color-mix(in srgb, var(--cd-teal) 64%, var(--cd-ink));
  --cd-teal-600: color-mix(in srgb, var(--cd-teal) 82%, var(--cd-ink));
  --cd-teal-500: var(--cd-teal);
  --cd-teal-400: color-mix(in srgb, var(--cd-teal) 70%, #fff);
  --cd-teal-300: color-mix(in srgb, var(--cd-teal) 46%, #fff);
  --cd-teal-200: color-mix(in srgb, var(--cd-teal) 28%, #fff);
  --cd-teal-100: color-mix(in srgb, var(--cd-teal) 15%, #fff);
  --cd-teal-50:  color-mix(in srgb, var(--cd-teal)  8%, #fff);

  --cd-magenta-950: color-mix(in srgb, var(--cd-magenta) 18%, var(--cd-ink));
  --cd-magenta-900: color-mix(in srgb, var(--cd-magenta) 30%, var(--cd-ink));
  --cd-magenta-800: color-mix(in srgb, var(--cd-magenta) 46%, var(--cd-ink));
  --cd-magenta-700: color-mix(in srgb, var(--cd-magenta) 64%, var(--cd-ink));
  --cd-magenta-600: color-mix(in srgb, var(--cd-magenta) 82%, var(--cd-ink));
  --cd-magenta-500: var(--cd-magenta);
  --cd-magenta-400: color-mix(in srgb, var(--cd-magenta) 70%, #fff);
  --cd-magenta-300: color-mix(in srgb, var(--cd-magenta) 46%, #fff);
  --cd-magenta-200: color-mix(in srgb, var(--cd-magenta) 28%, #fff);
  --cd-magenta-100: color-mix(in srgb, var(--cd-magenta) 15%, #fff);
  --cd-magenta-50:  color-mix(in srgb, var(--cd-magenta)  8%, #fff);

  --cd-pink-950: color-mix(in srgb, var(--cd-pink) 18%, var(--cd-ink));
  --cd-pink-900: color-mix(in srgb, var(--cd-pink) 30%, var(--cd-ink));
  --cd-pink-800: color-mix(in srgb, var(--cd-pink) 46%, var(--cd-ink));
  --cd-pink-700: color-mix(in srgb, var(--cd-pink) 64%, var(--cd-ink));
  --cd-pink-600: color-mix(in srgb, var(--cd-pink) 82%, var(--cd-ink));
  --cd-pink-500: var(--cd-pink);
  --cd-pink-400: color-mix(in srgb, var(--cd-pink) 70%, #fff);
  --cd-pink-300: color-mix(in srgb, var(--cd-pink) 46%, #fff);
  --cd-pink-200: color-mix(in srgb, var(--cd-pink) 28%, #fff);
  --cd-pink-100: color-mix(in srgb, var(--cd-pink) 15%, #fff);
  --cd-pink-50:  color-mix(in srgb, var(--cd-pink)  8%, #fff);

  /* Signature gradient — the logo/pattern "neon ibex" stops (patterns share these
     exact stops, so pattern SVGs composite seamlessly over the gradient). */
  --cd-grad-teal:   #1EB8C2;   /* rgb(30,184,194)  */
  --cd-grad-pink:   #EE3288;   /* rgb(238,50,136)  */
  --cd-grad-purple: #662D91;   /* rgb(102,45,145)  */
  /* Axis: bottom-left dark violet → top-right turquoise (matches the ibex). */
  --cd-gradient-signature: linear-gradient(to top right,
      var(--cd-grad-purple) 0%, var(--cd-grad-pink) 50%, var(--cd-grad-teal) 100%);
  /* Duoton: DIESELBE Achse und dieselben Endpunkte wie der Signatur-Verlauf, nur ohne
     den Pink-Stopp in der Mitte. Ein Beschnitt der Marke, kein Fremdkoerper. */
  --cd-gradient-duo: linear-gradient(to top right,
      var(--cd-grad-purple) 0%, var(--cd-grad-teal) 100%);
  --cd-gradient-warm: linear-gradient(120deg, var(--cd-yellow) 0%, var(--cd-orange) 100%);
  /* Soft/airy variant — stops mixed toward white: brighter, less saturated. For large
     decorative fills behind patterns (hero art, sections), where full sat reads too heavy.
     --gradient-soften = % of full colour retained (100% = original, lower = softer/whiter). */
  --gradient-soften: 98%;
  --cd-gradient-signature-soft: linear-gradient(to top right,
      color-mix(in srgb, var(--cd-grad-purple) var(--gradient-soften), #fff) 0%,
      color-mix(in srgb, var(--cd-grad-pink)   var(--gradient-soften), #fff) 50%,
      color-mix(in srgb, var(--cd-grad-teal)   var(--gradient-soften), #fff) 100%);

}

/* ============================ LAYER 2 · ROLES (semantic) ================= */
/* Components consume ONLY these. Default = light theme (brand is bright-first;
   brandbook discourages the white logo, so dark surfaces are the exception).

   Der Selektor listet .on-light / [data-theme="light"] mit, damit dieselben Werte
   auch als RÜCKWEG dienen: ein heller Kasten INNERHALB eines .on-dark-Bereichs.
   Bewusst derselbe Block statt einer zweiten Kopie — zwei Listen driften
   auseinander, sobald jemand nur eine anfasst.

   Warum das ohne Reihenfolge-Trick funktioniert: Custom Properties vererben.
   Deklariert ein Nachkomme sie selbst, gewinnt er immer gegen den geerbten Wert
   des Vorfahren — Spezifität entscheidet nur zwischen Regeln am GLEICHEN Element.
   Einzige Ausnahme: .on-light und [data-theme="dark"] zusammen auf demselben
   Element — dort gewinnt data-theme (Attribut schlägt Klasse). Nicht mischen. */
:root, .on-light, [data-theme="light"] {
  /* Der Themenwechsel setzt color SELBST. Sonst erben Nachkommen den berechneten
     Farbwert des Vorfahren — Variablen aendern daran nichts, und dunkler Text landet
     auf dunklem Grund. Frueher wurde das pro Stelle mit einer Inline-Farbe zugedeckt. */
  color: var(--text);

  /* Surfaces */
  --surface:          var(--cd-white);
  --surface-raised:   var(--cd-white);
  --surface-sunken:   var(--cd-gray-100);
  --surface-muted:    var(--cd-gray-50);
  --surface-inverse:  var(--cd-gray-900);   /* dark section */
  --surface-brand:    var(--cd-teal-900);
  /* Die abwechselnden hellen Bänder. Sie tragen RHYTHMUS, keine Aussage — darum eine
     einzige getönte Familie und ein Neutralton, nicht drei Markentöne. Die Namen sind
     historisch: eine Rolle umzubenennen heisst, jeden Aufruf mitzuziehen.
     Default bleibt weiss/sunken; Verlauf nur noch Signatur-Moment. */
  --surface-teal:     var(--cd-teal-50);
  --surface-magenta:  var(--cd-teal-100);
  --surface-pink:     var(--cd-gray-100);

  /* Atmosphaeren-Glows (Hero, Signatur-Band). Eigene Rolle, weil sie STAERKER als eine
     Flaeche toenen duerfen: sie liegen geblurrt hinter allem und tragen die
     Cursor-Bewegung. 50er war auf Weiss so blass, dass die Bewegung unsichtbar blieb;
     100er (15% Farbe) bleibt hell, macht sie aber lesbar. */
  --glow-teal:        var(--cd-teal-100);
  --glow-magenta:     var(--cd-teal-50);
  --glow-neutral:     var(--cd-gray-100);

  /* Text */
  --text:             var(--cd-gray-900);   /* 16.3:1 auf weiss · 15.1:1 auf sunken */
  --text-muted:       var(--cd-gray-600);   /*  6.4:1 auf weiss ·  5.9:1 auf sunken */
  --text-strong:      var(--cd-gray-950);
  --text-on-brand:    var(--cd-white);   /* 10.8:1 auf teal-900 */
  --text-inverse:     var(--cd-gray-50);
  --text-inverse-muted: var(--cd-gray-300);

  /* Borders / lines */
  --border:           var(--cd-gray-200);   /* Haarstrich, dekorativ */
  --border-strong:    var(--cd-gray-500);
  --border-inverse:   color-mix(in srgb, var(--cd-gray-300) 24%, transparent);
  /* Rand von BEDIENELEMENTEN — Eingabefeld, Auswahl, Kaestchen, Umriss-Knopf, Filter-Chip.
     Eigene Rolle, weil hier eine Pflicht gilt, die fuer Trennlinien NICHT gilt: WCAG 1.4.11
     verlangt 3:1 fuer alles, was ein Bedienelement erst als solches erkennbar macht. Der
     Rand IST beim Eingabefeld die einzige Kennzeichnung — faellt er weg, sieht man nicht,
     wo man klicken kann. Gemessen (Rand gegen --surface):
       --border         1.39:1   --border-strong  1.85:1   --border-control  5.70:1
     Darum nicht --border-strong hochziehen: der traegt Zierlinien (Zitatstrich, Diagramm-
     Konturen, Chip-Hover), die dunkler sofort schwer wirken. Zwei Pflichten, zwei Rollen. */
  --border-control:   var(--cd-gray-500);

  /* Accent — Teal führt: Fläche, Icon, Grafik. --accent-2 ist der zweite Ton und steht
     sparsam (sekundäre Aktion, einzelne Auszeichnungen). */
  --accent:           var(--cd-teal-700);   /* weisse Schrift darauf: 5.0:1 */
  --accent-hover:     var(--cd-purple-700);
  --accent-contrast:  var(--cd-white);
  /* Schriftfarbe im HOVER. Eigene Rolle, weil der Hover die Flaeche wechseln darf und
     die Schrift dann mitmuss — hell bleibt sie weiss, die Flaeche wird nur dunkler. */
  --accent-hover-contrast: var(--accent-contrast);
  --accent-2:         var(--cd-purple-700);   /* Schrift auf weiss: 12.2:1 */
  --accent-2-hover:   var(--cd-purple-800);
  /* Schrift und Rand des Umriss-Knopfs. Eigene Rolle: im Dunkeln erreicht --accent-2 nach
     WCAG 2 zwar 5.5:1, wirkt als Knopfschrift aber matt (APCA ~Lc 42) — nur der Knopf zieht an. */
  --accent-2-outline: var(--cd-purple-700);
  --accent-2-soft:    color-mix(in srgb, var(--cd-purple-700) 8%, transparent);
  /* Linkschrift im Hover. Nicht --accent-hover: das ist eine FLAECHE und im Dunkeln ein
     dunkles Teal, als Schrift auf dunklem Grund 3.7:1. */
  --link-hover:       var(--cd-purple-700);
  /* Eigene Rolle fuer die sekundaere FLAECHE. Grund: --accent-2 traegt zwei Jobs — Schrift
     (Eyebrow, Pflichtfeld-Stern, Feed-Kategorie) UND Knopffuellung. Im Dunkeln muss die
     Fuellung ausweichen, damit sie sich von der primaeren Flaeche trennt; die Schrift darf
     das nicht mitmachen. Ein Job, ein Token. Hell sind beide identisch. */
  --accent-2-surface:       var(--cd-purple-700);
  --accent-2-surface-hover: var(--cd-purple-800);
  --accent-soft:      var(--cd-teal-50);   /* Toenung hinter Akzent-Inhalt */

  /* Das Plättchen hinter einem Icon — eigenes Paar, weil die Tinte der FLÄCHE folgen muss
     und nicht dem Thema. --accent-soft allein reicht nicht: es ist als leise Tönung auf
     hellem Grund getunt und liegt auf einem dunklen Band 1.25:1 über dem Band, das
     Plättchen verschwindet. Muster wie --marker-active/--marker-active-contrast. */
  --icon-plate:       var(--accent-soft);
  --icon-plate-ink:   var(--accent);

  /* Highlight — die Auszeichnung, die selten und laut ist: «Recommended»-Fähnchen,
     Badges, Datenspitzen. Nie als grosse Fläche. */
  --highlight:        var(--cd-purple-700);
  --highlight-strong: var(--cd-purple-800);
  --highlight-contrast: var(--cd-white);   /* 12.2:1 auf --highlight */

  /* Frosted Glass — Overlay-Flächen, die über Pattern, Verlauf oder Bild liegen
     (Hero-Feature-Cards, Live-Pill). Nur dort einsetzen, wo wirklich etwas dahinterliegt —
     auf einer flachen Fläche ist Glas reine Dekoration. */
  --glass-surface:  color-mix(in srgb, var(--cd-white) 72%, transparent);
  --glass-border:   color-mix(in srgb, var(--cd-gray-200) 70%, transparent);
  --glass-blur:     16px;
  --glass-saturate: 1.3;
  /* Zwei Haelften, einzeln benannt: der Schlagschatten trennt die Glasflaeche vom
     Grund, die Innenlichtkante zeichnet ihre OBERKANTE nach. Wo zwei Glasflaechen
     buendig aneinanderstossen — gescrollte Leiste plus offenes Mega-Panel — ist die
     Oberkante der unteren keine Kante mehr, sondern eine Naht mitten in der Flaeche.
     Dort wird nur --glass-shadow-drop gesetzt. */
  --glass-shadow-drop: 0 1px 0 color-mix(in srgb, var(--cd-purple-900) 10%, transparent);
  --glass-shadow-edge: inset 0 1px 0 color-mix(in srgb, var(--surface-raised) 65%, transparent);
  --glass-shadow:   var(--glass-shadow-drop);
  /* Die EINE Glasflaeche, die ueber allem liegt: die gescrollte Kopfleiste. nav.css
     komponiert diese Rolle mit --glass-shadow-edge — kein `none`, weil der Wert in einer
     Komma-Liste steht und dort die ganze Deklaration samt Innenlichtkante wegwerfen
     wuerde. Eigener Token, weil eine Komponente nie direkt in die Palette greift. */
  --glass-shadow-brand: var(--glass-shadow-drop);

  /* Measure — Zeilenlaenge. Gehoert IMMER ans Textelement, nie an dessen Container:
     ch misst in der Schriftgroesse des Elements, an dem es steht. Eine Breite am
     Container trifft Titel und Fliesstext mit demselben Pixelwert — der Dokument-Hero
     lief so auf 10,5 Zeichen pro Titelzeile, waehrend derselbe Kasten beim kleiner
     gesetzten Hero 19 Zeichen ergab. Am Element gesetzt skaliert die Breite dagegen
     mit der fluiden Typografie mit. */
  --measure-display:  20ch;   /* grosse Titel — 2-3 Zeilen sind das Ziel */
  --measure-lede:     34ch;   /* Absatz direkt unter dem Titel */
  --measure-body:     62ch;   /* Fliesstext, klassischer Lesewert */

  /* Supportive */
  --teal:             var(--cd-teal-700);   /* calm/trust accent, charts, tags */
  --focus-ring:       var(--cd-teal-700);   /* 5.0:1 auf weiss */
  --gradient:         var(--cd-gradient-duo);
  --gradient-soft:    var(--cd-gradient-duo);
  /* Verlauf für TEXT (background-clip:text) — bewusst ein anderer als --gradient.
     Der Signatur-Verlauf endet in Türkis; als Schrift auf Weiss erreicht dieses Ende
     nur 2.4:1. Die Schrift traegt darum EINEN dunklen Ton über die ganze Länge, als
     Verlauf notiert, weil die Komponente background-clip:text setzt und dafür einen
     Verlauf braucht. Flächen: --gradient. Schrift: --gradient-text. */
  --gradient-text:    linear-gradient(var(--cd-teal-900), var(--cd-teal-900));
  /* Schattenfarbe als Rolle — Komponenten sollen kein --cd-* anfassen. Dunkel: Schwarz,
     weil durchscheinende Farbe auf dunklem Grund verschwindet. */
  --shadow-tint:      var(--cd-gray-900);

  /* Diagramm-Verlauf: die drei Stopps, die die Bento-Diagramme INNEN benutzen. Als
     Rolle, weil ein SVG mit festen Hex-Werten dem Dunkelmodus nicht folgen kann — die
     Diagramme leuchteten darum im Dunkeln unveraendert weiter. Drei Stopps statt einer Verlaufsrolle, weil ein SVG-Verlauf seine Stopps
     einzeln braucht; ein CSS-`linear-gradient()` passt dort nicht hinein. */
  --graphic-grad-from: var(--cd-grad-purple);
  --graphic-grad-mid:  color-mix(in srgb, var(--cd-grad-purple) 50%, var(--cd-grad-teal));
  --graphic-grad-to:   var(--cd-grad-teal);

  /* Pattern overlays — image + placement config. Components: .has-pattern + .pattern-<corner>,
     select motif via --pattern.
     Ausrichtung bestimmt die Ecke — die gelieferten P2/P3 tragen ein rotate(180) um den
     viewBox-Mittelpunkt, sind also das Logo-Teil kopfüber. Weil der Verlauf via
     gradientUnits="userSpaceOnUse" INNERHALB dieser Gruppe sitzt, dreht sich die
     Verlaufsachse mit: gedreht = Türkis unten, upright = Türkis oben.
     Seit 26.07. wird NICHT mehr gedreht — es gelten nur die upright-Fassungen:
       upright (*-up)        P2 → unten links   ·  P3 → unten rechts   ·  P4 → unten rechts
     Die Gegenkante kommt über .pattern-flip (spiegeln), nicht über ein gedrehtes Motiv. */
  /* ⚠ --pattern-2 und --pattern-3 zeigen auf die GEDREHTEN Lieferdateien und sind seit dem
     Kundenreview 26.07. (B18) nicht mehr zu verwenden. Sie bleiben nur stehen, damit alter
     Code nicht auf ein undefiniertes var() laeuft (eine kaputte var() killt die ganze
     Deklaration). Neuer Code nimmt ausschliesslich die *-up-Fassungen und spiegelt. */
  --pattern-2:     url("./assets/pattern/pattern-2.svg");      /* DEPRECATED — gedreht */
  --pattern-3:     url("./assets/pattern/pattern-3.svg");      /* DEPRECATED — gedreht */
  --pattern-2-up:  url("./assets/pattern/pattern-2-up.svg");   /* upright → unten links */
  --pattern-3-up:  url("./assets/pattern/pattern-3-up.svg");   /* upright → unten rechts */
  --pattern-4:     url("./assets/pattern/pattern-4.svg");
  --pattern-bleed: -2rem;    /* how far the motif bleeds past its anchored edges */
  --pattern-scale: 122%;     /* motif height vs container (override per block if needed) */
  /* Deckkraft des Motivs als Rolle. Bisher stand die 1 in pattern.css — die einzige
     Stellschraube, mit der das Muster zurueckgenommen werden kann, lag damit in der
     Komponente statt im System. */
  --pattern-opacity: .55;

  /* ---- Musterflaeche: Motivfarbe kommt aus dem Token, nicht mehr aus dem Asset ----
     Das SVG wird zur MASKE, die Farbe liegt darunter (dieselbe Technik wie beim
     Logo-Band). Damit ist die Musterfarbe stellbar; vorher standen die
     drei Signatur-Stopps als Hex IM Asset und keine Umbelegung erreichte sie.

     ⚠ Warum je Motiv ein EIGENER Verlauf und nicht schlicht --gradient: die vier
     Motive sind Ausschnitte DESSELBEN Verlaufs, aber an voellig verschiedenen Stellen.
     Nachgerechnet aus gradientTransform und viewBox der Lieferdateien, als Anteil der
     Verlaufslaenge:
        pattern-2-up  0.74 … 1.08  (Mauve → Tuerkis)
        pattern-3-up  0.22 … 0.60  (Violett → Pink)
        pattern-4     0.14 … 0.76  (Violett → Pink)
     Ein gemeinsames --gradient wuerde also alle drei sichtbar umfaerben. Die Werte
     unten bilden den heutigen Ausschnitt exakt nach: Winkel aus der Verlaufsachse,
     Stopps auf die Motivbox umgerechnet (Prozente ausserhalb 0–100 % sind gewollt —
     der sichtbare Teil ist ein Ausschnitt, der Rest liegt neben der Box).
     EINE gemeinsame Stellschraube gibt es trotzdem: --pattern-fill. Ist sie gesetzt,
     gilt sie fuer ALLE Motive (pattern.css liest sie mit diesen Werten als Rueckfall).

     --*-ratio ist das Seitenverhaeltnis der viewBox. Die Musterflaeche traegt es als
     aspect-ratio, weil ein Verlauf — anders als ein Bild — kein Eigenmass hat: ohne
     die Angabe wuerde `auto` auf die volle Sektionsbreite aufziehen und der Verlauf
     saesse quer statt auf dem Motiv. */
  --pattern-2-up-fill: linear-gradient(31.45deg,
      var(--cd-grad-purple) -217.8%, var(--cd-grad-pink) -59.1%, var(--cd-grad-teal) 76.1%);
  --pattern-2-up-ratio: 21 / 37;
  --pattern-3-up-fill: linear-gradient(31.45deg,
      var(--cd-grad-purple) -58.0%, var(--cd-grad-pink) 83.5%, var(--cd-grad-teal) 204.0%);
  --pattern-3-up-ratio: 26 / 40;
  --pattern-4-fill: linear-gradient(31.45deg,
      var(--cd-grad-purple) -23.1%, var(--cd-grad-pink) 64.8%, var(--cd-grad-teal) 139.7%);
  --pattern-4-ratio: 49 / 60;
  /* gedrehte Lieferdatei (DEPRECATED wie --pattern-3): Box und Achse drehen zusammen */
  --pattern-3-fill: linear-gradient(211.45deg,
      var(--cd-grad-purple) -58.0%, var(--cd-grad-pink) 83.5%, var(--cd-grad-teal) 204.0%);
  --pattern-3-ratio: 26 / 40;

  /* Status (derived toward brand where possible).
     Werte sind auf AA gegen die HELLEN Flaechen gerechnet — .ok/.bad erscheinen als
     kleiner Fettdruck (step--1) in Do/Don't-Listen und Specimen-Captions, dort gilt
     4.5:1, nicht 3:1. Die dunklen Gegenstuecke stehen im Dark-Block. */
  /* Haken in Feature-Listen tragen --success, sind aber AUSZEICHNUNG und kein Status.
     Ein eigenes Gruen stand direkt neben dem Akzent-Teal, nah genug, dass es nicht als
     eigene Farbe las, sondern als Fehler. Darum in der Teal-Familie; Fehler bleibt rot. */
  --success:          var(--cd-teal-800);   /* weisse Schrift darauf: 7.5:1 */
  --warning:          var(--cd-orange);
  --danger:           #C22C41;   /* 5.5:1 auf weiss · 5.1:1 auf --surface-sunken */

  /* ============================ TYPOGRAPHY ============================== */
  --font-display: "Changa", "Trebuchet MS", system-ui, sans-serif;
  --font-body:    "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  /* Monospace — Token-Namen, Wertetabellen, Code-Auszeichnung im Fliesstext.
     War über ein Dutzend Mal als var(--mono) referenziert, aber nie definiert:
     die betroffenen Stellen fielen still auf --font-body zurück und sahen dann
     wie Fliesstext aus statt wie Code. Systemschriften, kein Webfont-Download. */
  --mono:         ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* Fluid modular scale (~1.25 major third), clamped mobile→desktop. */
  /* Fussnoten-Stufe. Bewusst NICHT die 1.25er Stufe unter --step--1 (das wären
     10-11px und damit zu klein für Fliesstext) — ein kleinerer Schritt (~1.125),
     der bei 11.4-12.6px landet. Nur für Nebentexte, die man lesen können muss,
     aber nicht lesen soll: Backlink im Fuss, Bild-Credits. Nie für Fliesstext. */
  --step--2: clamp(0.71rem, 0.69rem + 0.10vw, 0.79rem);
  --step--1: clamp(0.80rem, 0.77rem + 0.15vw, 0.89rem);
  --step-0:  clamp(1.00rem, 0.96rem + 0.20vw, 1.13rem);  /* body */
  --step-1:  clamp(1.25rem, 1.18rem + 0.36vw, 1.50rem);
  --step-2:  clamp(1.56rem, 1.44rem + 0.62vw, 2.00rem);
  --step-3:  clamp(1.95rem, 1.75rem + 1.02vw, 2.67rem);
  --step-4:  clamp(2.44rem, 2.11rem + 1.64vw, 3.55rem);
  --step-5:  clamp(3.05rem, 2.53rem + 2.60vw, 4.74rem);
  --step-6:  clamp(3.82rem, 3.00rem + 4.05vw, 6.31rem);   /* hero */

  --leading-tight: 1.05;
  --leading-snug:  1.2;
  --leading-body:  1.6;
  --tracking-eyebrow: 0.22em;
  --tracking-tight: -0.02em;

  /* ============================ SPACE · RADIUS · SHADOW ================= */
  --rhythm: 0.5rem;   /* baseline unit (8px) — the space scale + line-heights are multiples */
  --lead:   1.5rem;   /* base leading = 3× rhythm = one baseline-grid row; headings use multiples */
  --space-3xs: 0.25rem; --space-2xs: 0.5rem; --space-xs: 0.75rem;
  --space-sm: 1rem;     --space-md: 1.5rem;  --space-lg: 2.5rem;
  --space-xl: 4rem;     --space-2xl: 6rem;   --space-3xl: 9rem;

  /* ---- ROLLEN: Sektions-Rhythmus ------------------------------------------
     Die Schriftstufen oben sind fluid, die Space-Skala ist es NICHT — und das ist
     richtig: ein Abstand ZWISCHEN zwei Zeilen soll nicht mit dem Fenster wandern.
     Der Abstand einer ganzen SEKTION schon: 6rem oben und unten sind auf 1440px
     Rhythmus und auf 390px ein Drittel des Bildschirms voller Nichts.
     Darum drei Rollen, die genau diese eine Aufgabe tragen — die --space-Skala
     bleibt unangetastet, sie ist das Abstands-Vokabular aller Komponenten.
     Alle drei Klammern erreichen ihr Maximum bei 1280px — der Breite, in der die
     Parity-Referenz aufgenommen wird (tests/parity, 1280x900). Ab dort rendert die Seite
     wertgleich zu vorher: die Referenz und die Fallstudien-Aufnahmen bleiben gueltig,
     ohne dass ein Bild neu eingefroren werden muss. */
  --pad-section: clamp(2.75rem, 1.5rem + 5.625vw, var(--space-2xl));  /* Band oben/unten */
  --pad-card:    clamp(2rem, 0.5rem + 6.875vw, var(--space-2xl));     /* Innenpolster der Inset-Karte */
  --pad-inset:   clamp(var(--space-md), 3.125vw, var(--space-lg));    /* Grund um die Inset-Karte */

  /* Hoehe der klebenden Leiste im schmalen Umbruch. Oberkante fuer ALLES, was sich
     darunter anlegt: die Menue-Flaeche und die Produktwahl der Matrix. Getrennt
     gepflegt liefen die Werte auseinander, und eines der beiden laege dann unter der
     Leiste oder liesse einen Streifen Seite durchblitzen. */
  --nav-h-narrow: 3.5rem;
  /* Hoehe der Leiste, im schmalen Umbruch = --nav-h-narrow (breakpoint.css). Ein Hero
     zuoberst laeuft um genau diesen Wert unter die transparente Leiste. */
  --nav-h: 4.75rem;

  /* Freiraum unter der klebenden Kopfleiste — EIN Wert fuer alles, was sich an ihr
     ausrichtet: Sprungziele (scroll-margin) und mitklebende Spalten wie das
     Inhaltsverzeichnis. Vorher stand die Rechnung dreimal wortgleich in drei Dateien,
     und eine Aenderung an der Leistenhoehe haette zwei davon vergessen.
     Die Leiste ist rund 4,75rem hoch; der Rest ist Luft, damit der Inhalt nicht am
     Schlagschatten klebt. */
  --header-clear: calc(var(--space-2xl) + var(--space-lg));

  --radius-sm: 6px; --radius-md: 12px; --radius-lg: 20px; --radius-xl: 32px;
  --radius-pill: 999px;

  /* ---- ROLLEN: Radius ------------------------------------------------------
     Komponenten greifen NUR auf diese Rollen, nie auf die Groessen darueber —
     dieselbe Regel wie bei Farbe. Vorher stand --radius-pill direkt am Knopf UND
     an den kreisrunden Marken; «Knopf auf 7px» haette die Punkte zu Quadraten
     gemacht. Als zwei Rollen ist jede Aufgabe einzeln stellbar. */
  --radius-control: 7px;   /* Knopf, Nav-Link, Tag, Badge, Status-Pille */
  --radius-round:   var(--radius-pill);  /* kreisrunde Marken: Haken, Punkte, Spinner */
  --radius-panel:   10px;   /* Karten, Menueflaeche, Code-Block, Medien */
  --radius-inset:   7px;   /* Flaechen INNERHALB einer Karte */
  --radius-chip:    6px;   /* Icon-Plaettchen */
  --radius-field:   4px;   /* Formularfelder, Inline-Code */
  --radius-hero:    14px;   /* Inset-Karte einer ganzen Sektion */

  /* ---- ROLLEN: Schriftgewicht ---------------------------------------------
     Vorher standen 60 nackte Zahlen in den Komponenten. Wichtig ist die Trennung
     von `heading` und `label`: sie machen verschiedene Arbeit — Titel gegenueber
     kleiner Auszeichnung. Als ein Wert waren sie nicht trennbar. */
  --weight-display: 600;   /* grosse Zahlen und Initialen */
  --weight-heading: 500;   /* Titel jeder Stufe */
  --weight-label:   600;   /* kleine Auszeichnung, Versalien, Marken */
  --weight-ui:      500;   /* Knopf, Navigation, Formularbeschriftung, Eyebrow */
  --weight-body:    400;  /* Fliesstext */

  /* Tiefe entsteht als HAARSTRICH, nicht als Wurf: eine Linie unter der Flaeche
     trennt, ohne die Seite zu polstern. */
  --shadow-sm: 0 1px 0 color-mix(in srgb, var(--cd-gray-950) 8%, transparent);
  --shadow-md: 0 1px 0 color-mix(in srgb, var(--cd-gray-950) 10%, transparent);
  --shadow-lg: 0 2px 0 color-mix(in srgb, var(--cd-gray-950) 12%, transparent);
  /* Verlaufs-Glow — Duoton aus den Signatur-Stopps, fuer hervorgehobene Kaesten
     (Preis-Spalte, Featured Card) und den Primaer-Hover.
     Die beiden Farbschichten sind VERSETZT, nicht uebereinander: Pink nach links,
     Tuerkis nach rechts, entlang derselben Achse wie der Signatur-Verlauf. Lagen sie
     beide bei x=0, deckte das kraeftigere Pink das Tuerkis zu und der «Verlaufs»-Glow
     war in Wahrheit ein einfarbiger rosa Ring. */
  --shadow-glow: -14px 12px 30px -10px color-mix(in srgb, var(--cd-grad-pink) 58%, transparent),
                  16px 14px 34px -10px color-mix(in srgb, var(--cd-grad-teal) 50%, transparent);
  /* Derselbe Duoton fuer GROSSE Flaechen. Der Unterschied ist der senkrechte Versatz:
     beim kleinen Element schiebt er den Schein nach unten und wirkt wie Tiefe, an einem
     seitenbreiten Band legt er einen farbigen SAUM an die Unterkante — der liest sich
     als Rahmen, nicht als Schein. Darum hier 0 senkrecht: die Farbe sitzt links und
     rechts, wo die Kante ohnehin ausserhalb des Blicks liegt.
     FARBLICH IDENTISCH zum Knopf-Glow (Noel, 06.08.) — dieselben Stopps, dieselben
     Anteile. Der Unterschied ist ausschliesslich die Geometrie: kein senkrechter
     Versatz, groesserer Weichzeichner, staerker eingezogen. */
  --shadow-glow-area: -18px 0 60px -22px color-mix(in srgb, var(--cd-grad-pink) 58%, transparent),
                       20px 0 64px -22px color-mix(in srgb, var(--cd-grad-teal) 50%, transparent);
  /* ZUSTANDS-Glow — dieselbe Optik, andere AUFGABE: er markiert etwas dauerhaft
     (Gewinnerspalte, offene FAQ, aktive Station, hervorgehobene Karte), waehrend
     --shadow-glow die Antwort auf den Zeiger ist. Zwei Aufgaben an EINER Rolle liessen
     sich nicht getrennt entscheiden: der Signatur-Verlauf brachte sieben Dauerflaechen
     mit, die davon laut wurden. */
  --shadow-glow-state: -14px 12px 30px -10px color-mix(in srgb, var(--cd-grad-teal) 52%, transparent),
                        16px 14px 34px -10px color-mix(in srgb, var(--cd-teal-700) 30%, transparent);
  /* Ruhiger dunkler Wurf fuer ein Element, das AUF einer Signaturflaeche liegt — der
     Knopf in der lauten Kachel, im Blog-CTA, im grossen Band. Dort traegt die Flaeche
     schon den farbigen Schein; ein zweiter Glow legte Farbe auf Farbe. Eigene Rolle und
     nicht --shadow-lg, weil der Karten-Schatten ein Haarstrich ist — hier braucht es
     echte Tiefe, sonst sieht man auf der dunklen Kachel gar nichts. */
  --shadow-raise: 0 14px 30px -12px color-mix(in srgb, var(--cd-ink) 55%, transparent);

  /* Die EINE Ausnahme vom Haarstrich: die Hero-Floats bewegen sich unterschiedlich schnell,
     und erst ein echter Wurf macht aus dem Tempounterschied Tiefe. Die vier Stufen wirken
     GLEICH STARK und unterscheiden sich nur in der Weichheit — ein enger Wurf verschwindet
     halb unter der Karte, ein weiter verteilt sich, darum steigt die Deckkraft nicht mit der
     Weichheit. Gemessen am gerenderten Bild, nicht geschaetzt. Namen = Tempostufen (motion.ts). */
  --shadow-float-low:    0 8px 15px -7px color-mix(in srgb, var(--shadow-tint) 28%, transparent);
  --shadow-float-medium: 0 11px 18px -4px color-mix(in srgb, var(--shadow-tint) 27%, transparent);
  --shadow-float-high:   0 24px 27px -11px color-mix(in srgb, var(--shadow-tint) 26%, transparent);
  --shadow-float-front:  0 19px 31px -6px color-mix(in srgb, var(--shadow-tint) 57%, transparent);

  /* ---- ROLLEN: Dekoration -------------------------------------------------
     Tiefe, die bisher inline in den Komponenten zusammengesetzt war. Aufgenommen
     wird nur, was TIEFE ist. Haarstrich-Insets (Tabellenkante, Feld-Fehlerkante,
     Matrix-Trennung) sind LINIEN, keine Schatten — sie bleiben in der Komponente,
     sonst loescht ein flacher Schatten sie mit. */
  /* Das Mega-Panel traegt keinen Wurf: Tiefe entsteht hier über Flaeche und Rand, wie
     bei --shadow-sm bis --shadow-lg. Eigene Rolle und nicht `none` an der Komponente,
     damit sie wieder belegbar bleibt. */
  --shadow-overlay: none;
  /* Ring um eine Marke, die auf einer durchlaufenden Linie sitzt (Zeitleisten-
     Station). Er traegt die Grundflaeche und stanzt die Linie hinter der Marke frei —
     Tiefe, keine Trennlinie. ⚠ Wie --glass-shadow enthaelt er eine Rolle und wird
     darum im Dark-Block WIEDERHOLT: var() in einer Custom Property wird am
     deklarierenden Element ersetzt, nicht am benutzenden. */
  --ring-marker: 0 0 0 .3rem var(--surface);
  /* Die AKTIVE Marke einer Folge (Zeitleisten-Station, aktive Zickzack-Karte). Bewusst
     eine eigene Rolle und nicht --accent: die aktive Station sagt «hier stehst du» und
     muss sich von der ruhenden unterscheiden, ohne dass die Komponente in die Palette
     greift. */
  --marker-active: var(--cd-teal-700);
  /* Die Schrift AUF der aktiven Marke. Eigene Rolle, weil sie an der FLAECHE haengt und
     nicht am Thema: --marker-active kehrt im Dunkeln auf eine helle Teal-Stufe, und dann
     muss die Schrift darauf dunkel werden. */
  --marker-active-contrast: var(--cd-white);

  /* Glow-Stopps des Call-outs als Rolle. Vorher standen sie als Palette in
     callout.css und waren damit nicht stellbar. */
  --callout-glow-a: var(--cd-grad-purple);
  --callout-glow-b: var(--cd-grad-teal);

  /* ---- ROLLEN: Bewegung ---------------------------------------------------
     Dauern, die bisher als nackte Zahl in der Animation-Kurzschreibweise standen.
     Gestellt wird hier, nicht in der Komponente.
     prefers-reduced-motion schaltet die Animationen weiterhin in der Komponente ab —
     das ist eine Zugaenglichkeitsregel, keine Gestaltungsstufe. */
  --marquee-duration:    90s;   /* Logo-Laufband, eine volle Umrundung */
  --glow-drift-duration: 44s;   /* Hero-Glows, ein Hin- oder Rueckweg (alternate) */
  --glow-opacity:        .45;   /* Deckkraft der Hero-Glow-Flaechen */

  --container: 76rem;
  --pattern-fill: var(--cd-gradient-duo);
}

/* ============================ DARK THEME (exception, not default) ========= */
/* Use sparingly. NOTE: brandbook says avoid the white logo ("melting candle");
   on dark surfaces prefer the colour logo or the ibex symbol — see foundation. */
:root[data-theme="dark"], .on-dark {
  color: var(--text);
  /* Grundfläche und die darauf liegenden Flächen sind NEUTRAL gestuft: der Akzent soll
     auf ihnen wirken, statt mit einer getönten Fläche zu konkurrieren. Die Staffelung
     entsteht über die Helligkeit der Stufen, nicht über Farbe. */
  --surface:          var(--cd-gray-950);
  --surface-raised:   var(--cd-gray-900);
  --surface-sunken:   color-mix(in srgb, var(--cd-gray-950) 82%, #000);
  --surface-muted:    var(--cd-gray-800);
  --surface-inverse:  var(--cd-gray-50);
  --surface-brand:    var(--cd-teal-800);
  /* Gegenstücke zur 50er-Reihe. Ohne sie blitzt ein abwechselnder Abschnitt im
     Dunkelmodus grellweiss auf, weil die hellen Tints unverändert durchschlagen.
     Gleiche Rolle, gleiche Aufgabe: minimal getönte Variante der Grundfläche. */
  --surface-teal:     color-mix(in srgb, var(--cd-teal) 12%, var(--cd-gray-950));
  --surface-magenta:  color-mix(in srgb, var(--cd-teal) 20%, var(--cd-gray-950));
  --surface-pink:     var(--cd-gray-800);
  /* Glows auf Dunkel: gegen die Grundfläche gemischt, damit sie leuchten statt
     aufzuhellen. */
  --glow-teal:        color-mix(in srgb, var(--cd-teal) 26%, var(--cd-gray-950));
  --glow-magenta:     color-mix(in srgb, var(--cd-teal) 14%, var(--cd-gray-950));
  --glow-neutral:     color-mix(in srgb, var(--cd-gray-300) 12%, var(--cd-gray-950));

  --text:             var(--cd-gray-100);   /* 15.6:1 auf surface · 13.7:1 auf raised */
  --text-muted:       var(--cd-gray-300);   /* 10.0:1 auf surface */
  --text-strong:      var(--cd-white);
  --text-on-brand:    var(--cd-white);

  --border:           color-mix(in srgb, var(--cd-gray-300) 18%, transparent);
  --border-strong:    var(--cd-gray-400);   /* 6.6:1 auf surface */
  /* Im Dunkeln ist der Befund schaerfer: die durchscheinenden Raender kamen auf 1.03:1
     und 1.05:1 — Eingabefelder waren praktisch randlos. Deckender Grauwert statt Mischung,
     6.61:1 gegen die dunkle Flaeche. Gleiche Rolle, gleiche Pflicht wie im Hell-Block. */
  --border-control:   var(--cd-gray-400);

  --accent:           var(--cd-teal-300);   /* Flaeche, dunkler Text: 12.5:1 */
  --accent-hover:     var(--cd-teal-700);
  --accent-contrast:  var(--cd-gray-950);
  --accent-soft:      color-mix(in srgb, var(--cd-teal) 14%, var(--cd-gray-950));
  /* Neutraler Weiss-Schleier statt einer Akzent-Tönung: das Plättchen liegt auf dem dunklen
     Band UND auf der dunklen Karte darin, und nur ein Aufhellen trägt auf beiden. 18% messen
     1.55:1 gegen inverse und 1.58:1 gegen statement — genug, damit es als Plättchen liest.
     Die Tinte ist fix Weiss, nicht --accent: der Akzent färbt hier auch Text, und auf dem
     Markenband stünde Teal auf Teal. */
  --icon-plate:       color-mix(in srgb, var(--cd-white) 18%, transparent);
  --icon-plate-ink:   var(--cd-white);
  /* Nur die FLAECHE kippt, nicht der Textakzent — siehe Kommentar bei --accent-2-surface
     im hellen Block. Die sekundaere Flaeche muss sich im Dunkeln von der primaeren
     trennen, sonst ist die Rangfolge der drei Stufen nicht mehr ablesbar; --accent-2
     selbst faerbt auch TEXT (Eyebrows, Pflichtfeld-Stern, Feed-Kategorien) und braucht
     dort die hellere Stufe. Ein Job, ein Token. */
  --accent-2-surface:       var(--cd-purple-500);
  --accent-2-surface-hover: var(--cd-purple-300);
  --highlight:        var(--cd-purple-300);
  --highlight-contrast: var(--cd-gray-950);
  /* Status muss mitkippen: die hellen Fassungen erreichten auf Ink nur 3.5 bzw. 4.0:1.
     Do/Don't-Listen und Specimen-Captions stehen auch in dunklen Kästen. */
  --success:          var(--cd-teal-300);   /* 9.2:1 auf --surface · 8.2:1 auf --surface-raised */
  --danger:           #F08897;   /* 7.7:1 auf --surface · 6.9:1 auf --surface-raised */
  /* Schatten auf Dunkel brauchen Schwarz, nicht Violett — siehe --shadow-tint. */
  --shadow-tint:      #000;
  /* Verlaufs-Schrift auf Dunkel: dieselbe Logik umgekehrt — der dunkle Ton verschwindet,
     also die helle Teal-Stufe. */
  --gradient-text:    linear-gradient(var(--cd-teal-300), var(--cd-teal-300));
  /* Glas auf Dunkel: getönte Fläche statt aufgehellter, Rand aus der hellen Grau-Stufe,
     Schatten braucht Schwarzanteil — durchscheinende Farbe verschwindet sonst. */
  --glass-surface:  color-mix(in srgb, var(--cd-gray-800) 62%, transparent);
  --glass-border:   color-mix(in srgb, var(--cd-gray-300) 18%, transparent);
  --glass-shadow-drop: 0 1px 0 rgba(0,0,0,.55);
  --glass-shadow-edge: inset 0 1px 0 color-mix(in srgb, var(--cd-purple-200) 14%, transparent);
  --glass-shadow:   var(--glass-shadow-drop);
  /* Die gescrollte Kopfleiste komponiert diese Rolle mit --glass-shadow-edge (nav.css).
     Derselbe Haarstrich wie der Drop — kein `none`, weil der Wert in einer Komma-Liste
     steht und dort die ganze Deklaration samt Innenlichtkante wegwerfen wuerde. */
  --glass-shadow-brand: var(--glass-shadow-drop);
  /* Glow auf Dunkel. Vorher war das Pink gegen SCHWARZ gemischt und lag deckungsgleich
     unter dem Tuerkis — der Duoton war damit weg. Neu: dieselbe versetzte Anordnung wie
     auf Hell, aber mit den 700er-Stufen (Farbe zu Ink gemischt) statt der Neon-Stopps.
     Auf einer dunklen Flaeche traegt schon ein gedaempfter Ton; die hellen Stopps
     leuchteten dort wie Neon. Schwarz bleibt als Erdung darunter. */
  --shadow-glow: -14px 14px 30px -12px color-mix(in srgb, var(--cd-magenta-700) 78%, transparent),
                  16px 14px 34px -12px color-mix(in srgb, var(--cd-teal-700) 60%, transparent),
                  0 22px 52px -14px rgba(0,0,0,.65);
  --shadow-glow-area: -18px 0 60px -22px color-mix(in srgb, var(--cd-magenta-700) 78%, transparent),
                       20px 0 64px -22px color-mix(in srgb, var(--cd-teal-700) 60%, transparent);
  --shadow-glow-state: -14px 14px 30px -12px color-mix(in srgb, var(--cd-teal-700) 70%, transparent),
                        16px 14px 34px -12px color-mix(in srgb, var(--cd-teal-700) 45%, transparent),
                        0 22px 52px -14px rgba(0,0,0,.65);
  /* Auf Dunkel traegt eine getoente Mischung nicht — Schwarz, kraeftiger als auf Hell. */
  --shadow-raise: 0 14px 30px -12px rgba(0,0,0,.7);
  /* Auf Dunkel traegt der Wurf weniger weit: der Grund ist selbst fast schwarz (Helligkeit 19
     von 255), ein schwarzer Schatten kann dort hoechstens rund zehn Punkte abdunkeln. Gleiche
     Geometrie, rund doppelte Deckkraft — mehr gibt die Flaeche nicht her. */
  --shadow-float-low:    0 8px 15px -7px rgba(0,0,0,.59);
  --shadow-float-medium: 0 11px 18px -4px rgba(0,0,0,.55);
  --shadow-float-high:   0 24px 27px -11px rgba(0,0,0,.53);
  --shadow-float-front:  0 19px 31px -6px rgba(0,0,0,.95);
  /* Wortgleiche Wiederholung, kein anderer Entwurf: beide Rollen sind aus anderen
     Rollen zusammengesetzt (--text-strong/--accent bzw. --surface), und die werden am
     DEKLARIERENDEN Element ersetzt. Ohne diese Zeilen truege das Mega-Panel im Dunkeln
     den hellen Schatten und der Stationsring die weisse Grundflaeche — genau die Falle,
     wegen der --glass-shadow hier ebenfalls doppelt steht. */
  --shadow-overlay: none;
  --ring-marker: 0 0 0 .3rem var(--surface);
  --text-inverse: var(--cd-gray-900);
  --text-inverse-muted: var(--cd-gray-600);
  --border-inverse: color-mix(in srgb, var(--cd-gray-900) 20%, transparent);
  --accent-hover-contrast: var(--cd-white);
  --accent-2: var(--cd-purple-300);   /* Schrift auf surface: 5.5:1 */
  --accent-2-hover: var(--cd-purple-200);
  --accent-2-outline: var(--cd-purple-200);
  --accent-2-soft: color-mix(in srgb, var(--cd-purple-200) 14%, transparent);
  --link-hover: var(--cd-purple-200);
  --focus-ring: var(--cd-teal-300);
  --shadow-sm: 0 1px 0 rgba(0,0,0,.5);
  --shadow-md: 0 1px 0 rgba(0,0,0,.55);
  --shadow-lg: 0 2px 0 rgba(0,0,0,.6);
  --marker-active: var(--cd-teal-300);
  --marker-active-contrast: var(--cd-gray-950);
  --teal: var(--cd-teal-300);
  --highlight-strong: var(--cd-purple-200);
  --callout-glow-a: var(--cd-grad-purple);
  --callout-glow-b: var(--cd-grad-teal);
}

/* Die Markenkarte ist heller als --surface, gegen das die dunklen Rollen gemessen sind.
   Sitzt mit .on-dark auf derselben Karte und gewinnt nur, weil der Block danach steht. */
.on-brand {
  --text-muted:       var(--cd-gray-200);   /* 5.4:1 auf --surface-brand */
  --border-control:   var(--cd-gray-300);   /* 4.1:1 auf --surface-brand */
}
