/* ============================================================
   DEELIAR DESIGN TOKENS — Single Source of Truth
   ------------------------------------------------------------
   This file is the canonical token layer for the whole frontend.
   It MUST be loaded as the FIRST stylesheet in every <head> so
   that all subsequent CSS (styles.css, hub.css, design-system.css,
   page-specific sheets, theme-presets.css) can reference these
   custom properties.

   Tokens were consolidated from styles.css :root (the previous
   de-facto source). styles.css still carries a copy for now;
   that duplicate will be removed in the merge phase once every
   page links this file.

   ── Token-layer priority (highest wins) ──────────────────────
     1. Instance / hub branding inline <style>   (per-tenant, in <head>)
     2. Style-preset vars (--style-*)            (theme.js)
     3. theme-presets.css shell vars             (--deeliar-shell-*)
     4. tokens.css  :root                        (THIS FILE — base)

   ── Competing token systems to be aliased onto these tokens ──
   (mapped in the merge phase, NOT yet — listed here for tracking):
     next-edition-2.css   ~150 vars
     year-3000.css        ~47 vars
     theme-presets.css    ~29 vars (--deeliar-shell-*)
     hub.css              ~26 vars
     hub-home.css         (--hh-radius ...)   -> var(--radius-md)
     app-hub-dashboard..  (--dh-radius ...)   -> var(--radius-md)
     app-hubs-marketplace (--hm-radius ...)   -> var(--radius-md)
     hub-admin-overmake   (--haom-radius ...) -> var(--radius-md)
   ============================================================ */

:root {
  --primary: #6366f1;
  --primary-dark: #4f46e5;
  --primary-light: #818cf8;
  --primary-bg: rgba(99,102,241,0.1);
  --accent: #22d3ee;
  --dark: #e2e8f0;
  --dark-700: #0f0f1a;
  --dark-600: #94a3b8;
  --bg-body: #0a0a12;
  --bg-card: #12121e;
  --bg-card-hover: #1a1a2e;
  --bg-elevated: #16162a;
  --border-color: rgba(255,255,255,0.08);
  --border-hover: rgba(99,102,241,0.4);
  --text-primary: #f1f5f9;
  --text-secondary: #94a3b8;
  --text-muted: #64748b;
  --gray-500: #64748b;
  --gray-400: #94a3b8;
  --gray-300: rgba(255,255,255,0.12);
  --gray-200: rgba(255,255,255,0.08);
  --gray-100: rgba(255,255,255,0.05);
  --gray-50: #0e0e1a;
  --white: #f1f5f9;
  --success: #34d399;
  --danger: #f87171;
  --warning: #fbbf24;
  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.3);
  --shadow: 0 4px 6px -1px rgba(0,0,0,0.4), 0 2px 4px -2px rgba(0,0,0,0.3);
  --shadow-md: 0 10px 15px -3px rgba(0,0,0,0.5), 0 4px 6px -4px rgba(0,0,0,0.4);
  --shadow-lg: 0 20px 40px -8px rgba(0,0,0,0.6);
  --shadow-xl: 0 25px 50px -12px rgba(0,0,0,0.7);
  --transition: 0.2s ease;

  /* ── Z-Index Tokens ────────────────────────────────────── */
  --z-base: 1;
  --z-dropdown: 10;
  --z-sticky: 85;
  --z-sidebar: 90;
  --z-topbar: 100;
  --z-banner: 200;
  --z-navbar: 1000;
  --z-drawer: 2000;
  --z-modal-backdrop: 5000;
  --z-modal: 9999;
  --z-overlay: 10000;
  --z-toast: 10001;
  --z-cookie: 99998;
  --z-loading: 99999;

  /* ════════════════════════════════════════════════════════════
     2035 DESIGN SYSTEM TOKENS (additive — does not break legacy)
     Used by design-system.css (.ds-* components) and the modern
     auth pages. All previous tokens above remain valid aliases.
     ════════════════════════════════════════════════════════════ */

  /* ── Color scales ── */
  --indigo-50:  #eef0ff;
  --indigo-100: #dde0ff;
  --indigo-200: #bcc1ff;
  --indigo-300: #969cff;
  --indigo-400: #7c80f7;
  --indigo-500: #6366f1;
  --indigo-600: #5052e6;
  --indigo-700: #4040c4;
  --indigo-800: #2f2f95;
  --indigo-900: #1f1f6b;

  --violet-300: #c4b5fd;
  --violet-400: #a78bfa;
  --violet-500: #8b5cf6;
  --violet-600: #7c3aed;

  --cyan-300: #67e8f9;
  --cyan-400: #22d3ee;
  --cyan-500: #06b6d4;

  --slate-50:  #f5f7fb;
  --slate-100: #e9ecf3;
  --slate-200: #cdd2e0;
  --slate-300: #a4abc1;
  --slate-400: #7c849a;
  --slate-500: #555c72;
  --slate-600: #3a4055;
  --slate-700: #262a3b;
  --slate-800: #161a2a;
  --slate-900: #0a0c1a;
  --slate-950: #06060f;

  /* ── Surfaces (2035 default = aurora-dark) ── */
  --ds-bg:           #06060f;
  --ds-bg-2:         #0c0d1c;
  --ds-surface:      rgba(20, 22, 38, 0.72);
  --ds-surface-2:    rgba(28, 30, 50, 0.78);
  --ds-surface-3:    rgba(40, 44, 70, 0.82);
  --ds-glass:        rgba(255, 255, 255, 0.04);
  --ds-glass-strong: rgba(255, 255, 255, 0.07);

  /* ── Text ── */
  --ds-text:         #f4f5fb;
  --ds-text-muted:   #aab1c8;
  --ds-text-subtle:  #6b7390;
  --ds-text-on-accent: #ffffff;

  /* ── Borders & hairlines ── */
  --ds-border:       color-mix(in srgb, var(--ds-text) 10%, transparent);
  --ds-border-strong:color-mix(in srgb, var(--ds-text) 18%, transparent);
  --ds-border-accent:color-mix(in srgb, var(--primary) 38%, transparent);

  /* ── Semantic accents (alias of legacy + clearer roles) ── */
  --ds-accent:       var(--primary);
  --ds-accent-2:     var(--primary-light);
  --ds-accent-3:     var(--accent);
  --ds-success:      var(--success);
  --ds-warning:      var(--warning);
  --ds-danger:       var(--danger);

  /* ── Spacing scale (4px base) ── */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-7:  32px;
  --space-8:  40px;
  --space-9:  48px;
  --space-10: 64px;
  --space-11: 80px;
  --space-12: 96px;

  /* ── Radii (extended) ── */
  --radius-xs:  6px;
  --radius-md:  14px;
  --radius-2xl: 28px;
  --radius-pill: 999px;

  /* ── Shadows (layered + accent glow) ── */
  --shadow-xs:  0 1px 2px rgba(4, 5, 14, 0.4);
  --shadow-soft: 0 12px 30px -16px rgba(4, 5, 14, 0.55);
  --shadow-2xl: 0 36px 80px -28px rgba(4, 5, 14, 0.75);
  --shadow-glow-primary: 0 22px 60px -22px color-mix(in srgb, var(--primary) 65%, transparent);
  --shadow-glow-accent:  0 22px 60px -22px color-mix(in srgb, var(--accent) 60%, transparent);

  /* ── Typography ── */
  --font-display: "Inter Tight", "Inter", "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono:    "JetBrains Mono", "SF Mono", ui-monospace, Menlo, Consolas, monospace;
  --text-xs:   0.75rem;
  --text-sm:   0.875rem;
  --text-base: 1rem;
  --text-md:   1.0625rem;
  --text-lg:   1.25rem;
  --text-xl:   1.5rem;
  --text-2xl:  1.875rem;
  --text-3xl:  2.375rem;
  --text-4xl:  3rem;
  --text-5xl:  clamp(2.5rem, 4.5vw + 1rem, 4rem);
  --leading-tight: 1.18;
  --leading-snug:  1.35;
  --leading-base:  1.55;
  --leading-loose: 1.75;
  --tracking-tight:  -0.02em;
  --tracking-display:-0.025em;
  --tracking-wide:    0.04em;

  /* ── Motion ── */
  --ease-spring:   cubic-bezier(0.22, 1, 0.36, 1);
  --ease-standard: cubic-bezier(0.32, 0.72, 0.24, 1);
  --duration-fast: 140ms;
  --duration-base: 220ms;
  --duration-slow: 360ms;
}

/* ── Light theme override ─────────────────────── */
[data-theme="light"] {
  --bg-body: #f5f5fa;
  --bg-card: #ffffff;
  --bg-card-hover: #f0f0f6;
  --bg-elevated: #ffffff;
  --border-color: rgba(0,0,0,0.1);
  --border-hover: rgba(99,102,241,0.5);
  --text-primary: #1e1e2e;
  --text-secondary: #4a4a6a;
  --text-muted: #6b7280;
  --dark: #1e1e2e;
  --dark-700: #f5f5fa;
  --dark-600: #4a4a6a;
  --gray-500: #6b7280;
  --gray-400: #9ca3af;
  --gray-300: rgba(0,0,0,0.1);
  --gray-200: rgba(0,0,0,0.06);
  --gray-100: rgba(0,0,0,0.03);
  --gray-50: #f9f9fc;
  --white: #1e1e2e;
  --shadow-sm: 0 1px 2px rgba(0,0,0,0.06);
  --shadow: 0 4px 6px -1px rgba(0,0,0,0.08), 0 2px 4px -2px rgba(0,0,0,0.06);
  --shadow-md: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.08);
  --shadow-lg: 0 20px 40px -8px rgba(0,0,0,0.12);
  --shadow-xl: 0 25px 50px -12px rgba(0,0,0,0.15);

  /* ── 2035 design system — light overrides ── */
  --ds-bg:           #f6f7fb;
  --ds-bg-2:         #eceff7;
  --ds-surface:      rgba(255, 255, 255, 0.92);
  --ds-surface-2:    rgba(255, 255, 255, 0.96);
  --ds-surface-3:    #ffffff;
  --ds-glass:        rgba(255, 255, 255, 0.7);
  --ds-glass-strong: rgba(255, 255, 255, 0.85);
  --ds-text:         #1b1d2a;
  --ds-text-muted:   #4d5266;
  --ds-text-subtle:  #7a809a;
  --ds-border:       color-mix(in srgb, var(--ds-text) 12%, transparent);
  --ds-border-strong:color-mix(in srgb, var(--ds-text) 22%, transparent);
  --ds-border-accent:color-mix(in srgb, var(--primary) 38%, transparent);
  --shadow-xs:   0 1px 2px rgba(20, 25, 50, 0.08);
  --shadow-soft: 0 14px 34px -22px rgba(20, 25, 50, 0.25);
  --shadow-2xl:  0 36px 80px -28px rgba(20, 25, 50, 0.22);
  --shadow-glow-primary: 0 18px 50px -22px color-mix(in srgb, var(--primary) 50%, transparent);
  --shadow-glow-accent:  0 18px 50px -22px color-mix(in srgb, var(--accent) 50%, transparent);
}

/* ============================================================
   FARBBRUECKE — Paket-Palette (theme-presets.css) -> Hub-Variablen
   ------------------------------------------------------------
   WARUM ES DIESEN BLOCK GIBT (Befund 20.08.2026)
   Auf hub.crafthoster.com sahen ALLE 24 Designs gleich aus. Der Grund ist
   eine Namensluecke, keine fehlende Farbe: theme-presets.css setzt die
   Palette auf PAKET-Namen (--bg, --text, --surface, --accent …), das CSS
   dieses Wirts liest HUB-Namen (--bg-body 2x, --text-primary 36x,
   --primary 60x, --bg-card 15x — und var(--bg) NULL mal). Bis d48bd450
   uebersetzte die hub-eigene theme.js dazwischen; jener Commit ersetzte
   theme.js durch die Paket-Fassung, die Bruecke fiel ersatzlos weg.

   WARUM IN CSS UND NICHT IN JS
   Ein Skript, das vor dem ersten Bildaufbau Variablen schreibt, muss
   SYNCHRON laufen — sonst blitzt die falsche Farbe auf. Genau daran haengen
   tests/test_hub_home_qa.py::test_frontend_non_blocking und
   tests/test_hub_script_defer.py::test_most_scripts_are_deferred: ausser
   theme.js darf kein Skript den ersten Bildaufbau blockieren. CSS-Variablen
   werden LAZY aufgeloest — die Uebersetzung kostet hier also kein einziges
   Skript und keine Millisekunde Renderzeit. Und tokens.css ist eine
   WIRTSDATEI: der naechste Rollout aus action_bar_all kann sie nicht
   mitnehmen. Genau daran ist d48bd450 gescheitert.

   WARUM `:root[data-style-preset]` UND NICHT EINFACH `:root`
   GEMESSEN, nicht ueberlegt: mit `--bg-body: var(--bg, #0a0a12)` im
   :root-Block oben kam am echten <body> `#06060e` heraus — weder Preset-
   noch Rueckfallwert. tokens.css ist naemlich NICHT das letzte Wort ueber
   diese Namen; drei spaetere Schichten deklarieren sie erneut mit
   Festwerten, alle auf `:root` und damit bei GLEICHER Spezifitaet spaeter
   in der Quelle:
       app/static/css/hub.css:16          :root { --bg-body: #06060e; … }
       app/static/css/next-edition-2.css:63  :root, html[…="next-edition-2"], …
       app/templates/hub/_branding.html:53   <style> :root { --bg-body: … }
   Spezifitaet schlaegt Quellreihenfolge. `:root[data-style-preset]` ist
   (0,2,0) und gewinnt damit gegen jedes `:root` (0,1,0) — egal wie spaet es
   kommt. Es verliert weiterhin gegen einen Inline-Stil am Element, also
   gegen die Mandanten-/Instanz-Schicht: das ist die in diesem Kopf
   dokumentierte Token-Rangfolge, und es ist STRENGER als die alte
   JS-Bruecke, die per element.style ALLES ueberschrieb.

   WARUM DAS ATTRIBUT ALS SCHALTER
   Ohne aktives Design greift der Block gar nicht — die Seite steht dann auf
   exakt den Werten wie vor dieser Reparatur. Das Attribut setzt theme.js
   (und vorgezogen das fruehe Kopf-Skript aus app/action_bar_markup.py),
   zusammen mit theme-presets.css aus demselben Kopf-Markup.

   WARUM UEBERALL EIN RUECKFALLWERT STEHT
   Ein `var(--bg)` auf ein UNDEFINIERTES --bg macht die Deklaration
   "invalid at computed-value time" — die Variable waere dann garantiert
   ungueltig und `background: var(--bg-body)` fiele auf transparent zurueck,
   nicht auf den Festwert. Die Rueckfallwerte sind deshalb woertlich die
   Werte aus dem :root-Block oben. Gemessen ausgeloest werden sie nie:
   theme-presets.css kommt aus demselben Kopf-Markup wie das Attribut.
   Die --style-*-Achse traegt bewusst KEINEN Rueckfall — sie ist ohne Paket
   nirgends definiert, und das war auch vor der Bruecke schon so.

   NIE ZURUECKSCHREIBEN, WAS WIR LESEN: gelesen werden ausschliesslich
   Paket-Namen, geschrieben ausschliesslich Hub-Namen. Beide Mengen sind
   disjunkt — sonst uebernaehme sich der Block beim naechsten Wechsel selbst.
   Nachweis: qa/nachweis_stilbruecke.py misst getComputedStyle am echten
   <body> ueber mehrere Designs und beide Modi.
   ============================================================ */
:root[data-style-preset] {
  /* ── 1. Die --style-*-Achse ──────────────────────────────────
     Das eigene CSS dieses Wirts liest sie 108x (hub-home.css,
     app-hub-dashboard.css, instance-landing.css, app-hubs-marketplace.css,
     hub-admin-overmake.css), das Paket setzt sie nirgends — reine
     Wirtssache, also hier. */
  --style-bg:              var(--bg);
  --style-bg-2:            var(--bg-2);
  --style-surface:         var(--surface);
  --style-surface-2:       var(--surface-2);
  --style-text:            var(--text);
  --style-muted:           var(--muted);
  --style-accent:          var(--accent);
  --style-accent-2:        var(--accent-2);
  --style-accent-3:        var(--accent-3);
  --style-accent-contrast: var(--accent-contrast);
  --style-border:          var(--border);
  --style-shadow:          var(--shadow);
  --style-soft-shadow:     var(--soft-shadow);
  --style-radius:          var(--radius);
  --style-radius-lg:       var(--radius-lg);
  --style-button-radius:   var(--button-radius);

  /* ── 2. Die Hub-Achse aus dem :root-Block oben ───────────────
     Das ist die Haelfte, die seit d48bd450 fehlte. Zuordnung und
     Reihenfolge stammen aus der geloeschten theme.js
     (_buildPresetTokenMap, Stand d48bd450~1) — uebernommen, nicht neu
     erfunden, sonst waere es ein anderer Hub. */
  --bg-body:        var(--bg, #0a0a12);
  --bg-surface:     var(--bg-2, #0e0e1a);
  --bg-card:        var(--surface, #12121e);
  --bg-card-hover:  var(--surface-2, #1a1a2e);
  --bg-elevated:    var(--surface-2, #16162a);
  --card-bg:        var(--surface, #12121e);
  --text-primary:   var(--text, #f1f5f9);
  --text-secondary: var(--muted, #94a3b8);
  --text-muted:     var(--muted, #64748b);
  --primary:        var(--accent, #6366f1);
  --primary-dark:   var(--accent, #4f46e5);
  --primary-light:  var(--accent-2, #818cf8);
  --primary-bg:     color-mix(in srgb, var(--accent, #6366f1) 14%, transparent);
  --primary-glow:   color-mix(in srgb, var(--accent, #6366f1) 18%, transparent);
  --accent-light:   var(--accent-2, #818cf8);
  --border-color:   var(--border, rgba(255,255,255,0.08));
  --border-hover:   color-mix(in srgb, var(--accent, #6366f1) 45%,
                      var(--border, rgba(255,255,255,0.08)));
  --glass:          color-mix(in srgb, var(--surface, #12121e) 58%, transparent);
  /* --dark/--white sind hier SCHRIFT-Namen, keine Flaechen (:root oben:
     --dark: #e2e8f0). Sie bekommen deshalb den Textton, nicht den Grund —
     genau so stand es in der alten Tabelle. */
  --dark:           var(--text, #e2e8f0);
  --dark-700:       var(--bg, #0f0f1a);
  --dark-600:       var(--muted, #94a3b8);
  --gray-500:       var(--muted, #64748b);
  --gray-400:       var(--muted, #94a3b8);
  --gray-300:       var(--border, rgba(255,255,255,0.12));
  --gray-200:       var(--border, rgba(255,255,255,0.08));
  --gray-100:       color-mix(in srgb, var(--surface-2, #1a1a2e) 70%, transparent);
  --gray-50:        var(--surface-2, #0e0e1a);
  --white:          var(--text, #f1f5f9);
  --shadow-sm:      var(--soft-shadow, 0 1px 2px rgba(0,0,0,0.3));
  --shadow-md:      var(--shadow, 0 10px 15px -3px rgba(0,0,0,0.5), 0 4px 6px -4px rgba(0,0,0,0.4));
  --shadow-lg:      var(--shadow, 0 20px 40px -8px rgba(0,0,0,0.6));
  --shadow-xl:      var(--shadow, 0 25px 50px -12px rgba(0,0,0,0.7));
  --radius-sm:      var(--radius, 6px);
  --radius-xl:      var(--radius-lg, 24px);

  /* ── 3. Die --ds-*-Achse (default-2035.css) ──────────────────
     Aus einer Messung heraus, nicht aus Vollstaendigkeitsdrang: nach den
     ersten beiden Achsen blieb /impressum bei rgb(6, 6, 15) stehen, fuer
     JEDES der sechs gemessenen Designs. Gleiche Bauart wie --bg-body:
         default-2035.css:61  body:not(.auth-page) { background: …
                                var(--ds-bg, #06060f); color: var(--ds-text); }
     Diese Regel gewinnt auf allen Seiten ohne .hub-home-page, also auf den
     meisten. Die AKZENT-Seite von --ds-* haengt schon an var(--primary)/
     var(--accent) und folgt damit von selbst; hart standen nur Flaeche und
     Schrift. Genau die stehen hier — mehr nicht.

     --ds-border/--ds-border-strong bleiben bewusst UNGESETZT: sie sind
     color-mix(… var(--ds-text) …) und folgen, sobald --ds-text stimmt. Was
     sich selbst herleitet, soll man nicht zusaetzlich festnageln. */
  --ds-bg:            var(--bg, #06060f);
  --ds-bg-2:          var(--bg-2, #0c0d1c);
  --ds-surface:       var(--surface, rgba(20, 22, 38, 0.72));
  --ds-surface-2:     var(--surface-2, rgba(28, 30, 50, 0.78));
  --ds-surface-3:     var(--surface-2, rgba(40, 44, 70, 0.82));
  --ds-glass:         color-mix(in srgb, var(--surface, rgba(20, 22, 38, 0.72)) 58%, transparent);
  --ds-glass-strong:  color-mix(in srgb, var(--surface-2, rgba(28, 30, 50, 0.78)) 78%, transparent);
  --ds-text:          var(--text, #f4f5fb);
  --ds-text-muted:    var(--muted, #aab1c8);
  --ds-text-subtle:   var(--muted, #6b7390);
  --ds-text-on-accent: var(--accent-contrast, #ffffff);
}

/* ============================================================
   COMPONENT TOKENS — one canonical look per reusable element
   ------------------------------------------------------------
   The makeover's single source of truth so the SAME element
   (card / input / badge / modal) looks identical on every page.
   Page-specific classes (.dash-card, .ha-stat-card, .ho-card,
   .hub-app-badge, .ia-input …) reference these instead of
   hardcoding radius / padding / surface / shadow.
   Values track the modern dashboard skin. Both themes inherit
   them (they derive from the theme-aware base tokens above).
   ============================================================ */
:root {
  /* ── Cards ── (values match the modern dashboard skin = the standard;
       radius follows the same tenant preset chain as the skin's --dh-radius) ── */
  --card-radius:        var(--deeliar-shell-radius, var(--style-radius, var(--radius)));
  --card-padding:       22px;
  --card-padding-sm:    var(--space-4);                /* 16px (dense cards) */
  --card-bg:            var(--bg-card);
  --card-border:        1px solid var(--border-color);
  --card-shadow:        var(--shadow-soft);
  --card-hover-shadow:  var(--shadow-md);
  --card-hover-border:  var(--border-hover);
  --card-hover-transform: translateY(-3px);
  --card-transition:    transform 0.22s var(--ease-standard),
    box-shadow 0.22s var(--ease-standard),
    border-color 0.22s var(--ease-standard),
    background-color 0.22s var(--ease-standard);
  --card-surface:       var(--ds-surface, rgba(20, 22, 38, 0.72));
  --card-border-color:  var(--ds-border-strong, rgba(255,255,255,0.12));

  /* ── Buttons ── (one canonical look for ALL button classes) */
  --btn-radius:         var(--deeliar-shell-button-radius, var(--radius-pill));
  --btn-padding:        10px 22px;
  --btn-padding-sm:     8px 16px;
  --btn-padding-lg:     14px 32px;
  --btn-font:           var(--font-body);
  --btn-font-size:      0.95rem;
  --btn-font-size-sm:   0.86rem;
  --btn-font-size-lg:   1.02rem;
  --btn-font-weight:    600;
  --btn-min-h:          var(--tap-min, 44px);          /* WCAG touch target */
  --btn-min-h-sm:       36px;
  --btn-min-h-lg:       52px;
  --btn-transition:     var(--duration-fast) var(--ease-spring);

  --btn-primary-bg:     linear-gradient(135deg,
    color-mix(in srgb, var(--primary) 92%, white 8%),
    color-mix(in srgb, var(--primary-light, #818cf8) 92%, var(--accent) 8%));
  --btn-primary-fg:     #ffffff;
  --btn-primary-shadow:  var(--shadow-glow-primary);

  --btn-outline-bg:     var(--ds-glass, rgba(255,255,255,0.04));
  --btn-outline-fg:     var(--ds-text, var(--text-primary));
  --btn-outline-border: var(--ds-border-strong, rgba(255,255,255,0.16));

  --btn-ghost-bg:       transparent;
  --btn-ghost-fg:       var(--ds-text-muted, var(--text-secondary));
  --btn-ghost-border:   transparent;

  --btn-danger-bg:      color-mix(in srgb, var(--danger) 18%, transparent);
  --btn-danger-fg:      color-mix(in srgb, var(--danger) 90%, white);
  --btn-danger-border:  color-mix(in srgb, var(--danger) 45%, transparent);

  /* ── Form inputs ── */
  --input-radius:       var(--radius);                 /* 10px */
  --input-padding:      10px 14px;
  --input-bg:           rgba(255,255,255,0.04);
  --input-border:       1px solid var(--border-color);
  --input-focus-border: var(--primary);
  --input-focus-ring:   0 0 0 3px var(--primary-bg);

  /* ── Badges / status pills ── */
  --badge-radius:       var(--radius-pill);
  --badge-padding:      4px 10px;
  --badge-font:         0.72rem;

  /* ── Modals / overlays ── */
  --modal-radius:       var(--radius-lg);
  --modal-max-w:        min(480px, calc(100vw - 24px));
  --modal-backdrop:     rgba(4, 5, 14, 0.6);
  --modal-pad:          var(--space-6);
  --modal-surface:      var(--ds-surface-2, rgba(28, 30, 50, 0.92));
  --modal-border:       1px solid var(--ds-border-strong, rgba(255,255,255,0.14));
  --modal-shadow:       var(--shadow-2xl);
  /* ── Close buttons ── */
  --close-size:         34px;
  --close-radius:       var(--radius);
  --close-bg:           var(--ds-glass, rgba(255,255,255,0.04));
  --close-fg:           var(--ds-text-muted, rgba(241,245,249,0.6));
  --close-hover-bg:     var(--ds-glass-strong, rgba(255,255,255,0.08));
  --close-hover-fg:     var(--ds-text, #fff);

  /* ── Toggle switches ── */
  --toggle-w:           44px;
  --toggle-h:           24px;
  --toggle-knob:        18px;
  --toggle-on:          var(--primary, #6366f1);
  --toggle-off:         var(--ds-glass-strong, rgba(255,255,255,0.12));
  --toggle-knob-color:  #f1f5f9;

  /* ── Empty states ── */
  --empty-pad:          var(--space-9, 48px) var(--space-6, 24px);
  --empty-fg:           var(--ds-text-subtle, rgba(241,245,249,0.35));
  --empty-icon-size:    2.5rem;

  /* ── Spinners ── */
  --spinner-size:       24px;
  --spinner-border-w:   2px;
  --spinner-color:      var(--primary, #6366f1);
  --spinner-track:      var(--ds-border, rgba(99,102,241,0.2));

  /* ── Touch / a11y ── */
  --tap-min:            44px;                           /* WCAG touch target */
}

[data-theme="light"] {
  --card-bg:        #ffffff;
  --input-bg:       rgba(20, 25, 50, 0.03);
  --modal-backdrop: rgba(20, 25, 50, 0.45);
}
