/* ═══════════════════════════════════════════════════════════════════════════
   VALORY · UNIFIED DESIGN TOKENS
   Single source of truth for web colour. Replaces theme.css + tokens.css +
   calm_amber_{session,mentor,profile}.css.

   Palette is transcribed from the mobile app's src/theme/tokens.ts
   ("old library": warm cream paper carried by espresso brown; dark is a
   candlelit study with a champagne-caramel carrier). NEVER orange/amber on
   beige — that combination is explicitly rejected on both surfaces.

   SCOPE OF THIS FILE: colour only. Shape, motion and type keep their existing
   web values on purpose — mobile forces Verdana as a portability fallback,
   not as a brand choice, and the web's Fraunces/Sora pairing is stronger.

   STRUCTURE
     §1  Core palette (the 17 mobile tokens) — dark
     §2  Core palette — light
     §3  Web alias layer  (--surface-0 / --fg-primary / --accent …)
     §4  Legacy semantic bridge (was theme.css "PHASE 2 BRIDGE")
     §5  Raw ramps — THE FIX: the old indigo/violet/slate ramps re-pointed
     §6  Auth namespace
     §7  Study-session (--ss-*) namespace
     §8  Feature one-offs (chat / circle / social / profile)
     §9  Gradients + forged-gem tier ladder (from mobile gems.tsx)
     §10 Shape · motion · type — UNCHANGED from the previous tokens.css

   Mode mechanism is deliberately unchanged: :root is dark, [data-theme="light"]
   is light, exactly as before. Only the values moved. Flipping the default to
   follow the OS is a separate, one-line decision (see §2 note).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── §1 · CORE PALETTE — DARK (default) ───────────────────────────────── */
:root,
[data-theme="dark"] {
  color-scheme: dark;

  /* --_bg is a PRIVATE literal. Do not alias anything to --background and
     then back again: templates/base.html declares `--background: var(--bg-base)`,
     so if --bg-base also read var(--background) the pair would form a custom-
     property cycle, which CSS resolves to the guaranteed-invalid value — both
     compute to EMPTY and the page loses its background entirely. Every legacy
     background alias in §4 reads --_bg directly for that reason. */
  --_bg:               #100E0C;
  --background:        var(--_bg);
  --surface:           #1B1815;
  --surface-elevated:  #272119;
  --surface-muted:     #272119;   /* equals elevated in dark, by design */

  --text:              #F4EDE1;
  --text-faint:        #857A6B;

  --primary:           #E3B583;   /* champagne-caramel, the dark carrier */
  --primary-text:      #26190D;
  --accent-deep:       #C08E58;

  --border:            #372F26;
  --border-strong:     #544838;

  --success:           #9DBE85;
  --danger:            #E08A72;
  --info:              #96B4CD;
  --warning-soft:      #CBA96B;
  --warning-strong:    #C98D5B;

  /* rgb triplets for rgba() consumers */
  --background-rgb:       16, 14, 12;
  --surface-rgb:          27, 24, 21;
  --surface-elevated-rgb: 39, 33, 25;
  --text-rgb:            244, 237, 225;
  --primary-rgb:         227, 181, 131;
  --danger-rgb:          224, 138, 114;
}

/* ── §2 · CORE PALETTE — LIGHT ────────────────────────────────────────── */
/* To make the web follow the OS like mobile does, add:
     @media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) { … } }
   Deliberately NOT done here — it would flip every existing user's theme,
   which is a behaviour change, not a colour change. */
[data-theme="light"] {
  color-scheme: light;

  --_bg:               #F3EDE2;
  --background:        var(--_bg);
  --surface:           #FBF8F1;
  --surface-elevated:  #FFFDF8;
  --surface-muted:     #E6DECF;

  --text:              #2A2118;
  --text-faint:        #998A75;

  --primary:           #6B4A2F;   /* espresso, the light carrier */
  --primary-text:      #F9F4EA;
  --accent-deep:       #4A3220;

  --border:            #E3DACA;
  --border-strong:     #C9BDA6;

  --success:           #5F7A4A;
  --danger:            #9E3B2F;
  --info:              #4E6E8A;
  --warning-soft:      #8F6E3A;
  --warning-strong:    #8A4F2E;

  --background-rgb:      243, 237, 226;
  --surface-rgb:         251, 248, 241;
  --surface-elevated-rgb: 255, 253, 248;
  --text-rgb:             42, 33, 24;
  --primary-rgb:         107, 74, 47;
  --danger-rgb:          158, 59, 47;
}

/* ═══ EVERYTHING BELOW IS MODE-AGNOSTIC — it aliases onto §1/§2 ═══════════ */

/* ── §3 · WEB ALIAS LAYER ─────────────────────────────────────────────────
   The names the previous tokens.css exposed. Mobile's tokens.ts already
   documents each of its tokens with these exact CSS names, so this layer is
   pure aliasing — no new values. */
:root {
  --surface-0:         var(--background);
  --surface-1:         var(--surface);
  --surface-2:         var(--surface-elevated);
  --surface-sunken:    var(--surface-muted);

  --fg-primary:        var(--text);
  --fg-secondary:      var(--text-muted);
  --fg-muted:          var(--text-faint);
  --fg-on-accent:      var(--primary-text);

  --accent:            var(--primary);
  --accent-hover:      var(--accent-deep);
  --accent-soft:       color-mix(in srgb, var(--primary) 10%, transparent);
  --accent-glow:       color-mix(in srgb, var(--primary) 32%, transparent);
  --border-accent:     color-mix(in srgb, var(--primary) 42%, transparent);

  --color-success:     var(--success);
  --color-danger:      var(--danger);
  --color-danger-dk:   color-mix(in srgb, var(--danger) 80%, #000);
  --color-critical:    var(--danger);
  --color-warning-soft:   var(--warning-soft);
  --color-warning-strong: var(--warning-strong);

  /* text-muted is referenced both as a core token and a bridge name */
  --text-muted:        var(--text-secondary-raw, #BEB2A0);
}
/* :root[…] specificity bump (same idiom as the --bs-*-rgb block below):
   without it the plain `:root` on the next line ties this selector at
   (0,1,0) and wins on source order, leaving light mode with the dark
   beige — unreadable secondary text on light surfaces. */
:root[data-theme="light"] { --text-muted: #6B5D4C; }
:root, [data-theme="dark"] { --text-muted: #BEB2A0; }

/* ── §4 · LEGACY SEMANTIC BRIDGE ──────────────────────────────────────────
   Carried over from theme.css's "PHASE 2 BRIDGE". These are the highest-
   traffic names in the codebase (--text-on-primary 936 refs, --card-bg 710,
   --border-color 609, --primary 585, --text-primary 510), so they must keep
   resolving or half the app goes undefined. */
:root {
  --page-bg:           var(--_bg);   /* --_bg, NOT --background — see §1 */
  --bg-base:           var(--_bg);   /* --_bg, NOT --background — see §1 */
  --card-bg:           var(--surface);
  --bg-card:           var(--surface);
  --bg-surface:        var(--surface);
  --surface-main:      var(--surface);
  --surface-bg:        var(--surface);
  --bg-card-alt:       var(--surface-elevated);
  --bg-input:          var(--surface-muted);
  --bg-hover:          var(--accent-soft);
  --bg-active:         var(--accent-soft);

  --surface-violet:    var(--surface);
  --surface-violet-2:  var(--surface-elevated);
  --surface-blue:      var(--surface);
  --surface-blue-soft: var(--surface);
  --surface-chat:      var(--surface);
  --surface-mint:      var(--surface);
  --surface-amber:     var(--accent-soft);
  --soft-violet-panel: var(--surface-elevated);
  --soft-amber-panel:  var(--accent-soft);

  --text-primary:      var(--text);
  --text-secondary:    var(--text-muted);
  --text-on-brand:     var(--primary-text);
  --text-on-primary:   var(--primary-text);
  --text-on-accent:    var(--primary-text);
  --text-indigo-white: var(--text);
  --text-light-blue:   var(--info);
  --text-mint:         var(--success);
  --text-violet-soft:  var(--text-muted);
  --text-ss-btn:       var(--primary-text);

  --border-color:      var(--border);
  --border-default:    var(--border);
  --border-subtle:     var(--border);
  --border-soft:       var(--border);
  --border-hover:      var(--border-strong);
  --border-dark:       var(--border-strong);
  --border-violet:     var(--border);
  --border-mint:       var(--border);
  --border-amber:      var(--border-accent);

  --primary-hover:     var(--accent-deep);
  --primary-light:     color-mix(in srgb, var(--primary) 22%, transparent);
  --accent-light:      color-mix(in srgb, var(--primary) 22%, transparent);
  --accent-indigo:     var(--primary);
  --mint:              var(--success);

  --badge-fallback-bg: var(--surface-muted);
  --badge-fallback-fg: var(--text);
  --dark-overlay-rgb:  var(--background-rgb);
  --white:             var(--surface-elevated);  /* never pure white */
  --black:             var(--background);
}

/* ── §5 · RAW RAMPS — THE ACTUAL FIX ──────────────────────────────────────
   These are why the web still looked indigo/violet/navy while tokens.css said
   "amber". The old palette's raw colour ramps were never migrated — they were
   still literal (--slate-900:#0f172a, --violet-500:#8b5cf6,
   --grad-tier-1: purple→magenta→pink). ~400 references across the app.
   Re-pointed by ROLE, not by name. */
:root {
  /* neutral ramp (was slate = cold navy-grey) */
  --slate-900:   var(--background);
  --slate-800:   var(--surface);
  --slate-400:   var(--text-faint);
  --slate-300:   var(--text-muted);
  --slate-200:   var(--border-strong);

  /* accent ramp (was violet / indigo) */
  --violet-600:  var(--accent-deep);
  --violet-500:  var(--primary);
  --violet-400:  color-mix(in srgb, var(--primary) 70%, var(--surface));
  --violet-300:  color-mix(in srgb, var(--primary) 45%, var(--surface));
  --indigo-600:  var(--accent-deep);
  --indigo-500:  var(--primary);
  --indigo-400:  color-mix(in srgb, var(--primary) 70%, var(--surface));

  /* info ramp (was sky / blue) */
  --sky-500:     var(--info);
  --sky-400:     var(--info);
  --sky-300:     color-mix(in srgb, var(--info) 70%, var(--surface));
  --sky-200:     color-mix(in srgb, var(--info) 45%, var(--surface));
  --sky-100:     color-mix(in srgb, var(--info) 22%, var(--surface));
  --blue-500:    var(--info);
  --blue-400:    var(--info);
  --blue-300:    color-mix(in srgb, var(--info) 70%, var(--surface));
  --blue-200:    color-mix(in srgb, var(--info) 45%, var(--surface));
  --blue-50:     color-mix(in srgb, var(--info) 12%, var(--surface));

  /* success ramp (was green / emerald) */
  --green-700:   color-mix(in srgb, var(--success) 80%, #000);
  --green-600:   color-mix(in srgb, var(--success) 88%, #000);
  --green-500:   var(--success);
  --green-300:   color-mix(in srgb, var(--success) 60%, var(--surface));
  --green-100:   color-mix(in srgb, var(--success) 20%, var(--surface));
  --emerald-600: color-mix(in srgb, var(--success) 88%, #000);
  --emerald-500: var(--success);
  --emerald-400: color-mix(in srgb, var(--success) 78%, var(--surface));
  --emerald-300: color-mix(in srgb, var(--success) 60%, var(--surface));
  --emerald-50:  color-mix(in srgb, var(--success) 12%, var(--surface));

  /* danger ramp (was red) */
  --red-800:     color-mix(in srgb, var(--danger) 78%, #000);
  --red-400:     var(--danger);
  --red-300:     color-mix(in srgb, var(--danger) 70%, var(--surface));
  --red-200:     color-mix(in srgb, var(--danger) 45%, var(--surface));
  --red-100:     color-mix(in srgb, var(--danger) 22%, var(--surface));

  /* warning ramp (was amber / yellow / orange) */
  --amber-400:   var(--warning-soft);
  --yellow-400:  var(--warning-soft);
  --orange-500:  var(--warning-strong);
}

/* ── §6 · AUTH NAMESPACE ──────────────────────────────────────────────────
   The auth pages carried a private navy palette (--auth-surface-a-rgb was
   12,22,44). Re-pointed onto the core so login matches the rest. */
:root {
  --auth-surface:          var(--surface);
  --auth-surface-soft:     var(--surface-muted);
  --auth-surface-strong:   var(--surface-elevated);
  --auth-input-bg:         var(--surface-muted);
  --auth-border:           var(--border);
  --auth-border-soft:      var(--border);
  --auth-text:             var(--text);
  --auth-text-muted:       var(--text-muted);
  --auth-text-subtle:      var(--text-faint);
  --auth-accent:           var(--primary);
  --auth-accent-strong:    var(--accent-deep);
  --auth-accent-wash:      var(--accent-soft);
  --auth-focus-ring:       var(--border-accent);
  --auth-danger:           var(--danger);
  --auth-success:          var(--success);
  --auth-warning:          var(--warning-strong);
  --auth-shadow-color:     rgba(var(--background-rgb), 0.45);
  --auth-shadow:           0 8px 24px -4px var(--auth-shadow-color);

  --auth-surface-a-rgb:    var(--surface-rgb);
  --auth-surface-b-rgb:    var(--surface-elevated-rgb);
  --auth-surface-wash-rgb: var(--background-rgb);
  --auth-input-bg-rgb:     var(--surface-elevated-rgb);
  --auth-hero-b-rgb:       var(--primary-rgb);
  --auth-edit-shadow-rgb:  var(--background-rgb);
}

/* ── §7 · STUDY-SESSION NAMESPACE ─────────────────────────────────────────
   --ss-* powered the calm_amber_session bundle (card gradient stop 1 was
   30,27,60 — purple-navy). Now espresso. */
:root {
  --ss-shell-bg1:       var(--background);
  --ss-shell-bg2:       var(--surface);
  --ss-card-bg1:        var(--surface);
  --ss-card-bg2:        var(--surface-elevated);
  --ss-input-bg:        var(--surface-muted);
  --ss-quote-bg:        var(--surface-elevated);
  --ss-resources-bg:    var(--surface-elevated);

  --ss-shell-bg1-rgb:      var(--background-rgb);
  --ss-shell-bg2-rgb:      var(--surface-rgb);
  --ss-card-bg1-rgb:       var(--surface-rgb);
  --ss-card-bg2-rgb:       var(--surface-elevated-rgb);
  --ss-input-bg-rgb:       var(--surface-elevated-rgb);
  --ss-quote-bg-rgb:       var(--surface-elevated-rgb);
  --ss-resources-bg-rgb:   var(--surface-elevated-rgb);
  --ss-surface-rgb:        var(--surface-rgb);
  --ss-surface-strong-rgb: var(--surface-elevated-rgb);
  --ss-cta-break-bg-rgb:   var(--primary-rgb);
}

/* ── §8 · FEATURE ONE-OFFS ────────────────────────────────────────────── */
:root {
  --chat-surface-bg:         var(--surface);
  --chat-bubble-incoming-bg: var(--surface-elevated);
  --chat-bubble-outgoing:    var(--primary);
  --circle-card-bg:          var(--surface);
  --circle-chat-bg:          var(--surface);
  --social-card-bg:          var(--surface);
  --profile-panel-border:    var(--border);
  --profile-panel-shadow:    0 8px 24px -4px rgba(var(--background-rgb), 0.35);
  --request-form-shell-bg:   var(--surface);
  --request-form-input-bg:   var(--surface-muted);
}

/* ── §9 · GRADIENTS + FORGED-GEM TIER LADDER ──────────────────────────────
   Gradients derive from the accent. The gem ladder is the one saturated
   element in the system — a fixed brand asset copied from the mobile app
   (src/profile/components/gems.tsx), not a free palette. */
:root {
  --grad-accent: linear-gradient(135deg, var(--primary), var(--accent-deep));
  --grad-cta:    linear-gradient(135deg, var(--primary), var(--accent-deep));
  --grad-body:   linear-gradient(180deg, var(--background), var(--surface));
  --grad-hero:   linear-gradient(160deg, var(--surface), var(--background));
  --amber-surface-gradient:  linear-gradient(135deg, var(--surface), var(--surface-elevated));
  --violet-surface-gradient: linear-gradient(135deg, var(--surface), var(--surface-elevated));

  /* ── Forged-gem material ladder ───────────────────────────────────────
     Ported verbatim from the mobile app (valory-mobile/docs/tokens.css §6,
     source src/profile/components/gems.tsx). A student's level renders as a
     material, low → high: graphite (ore) → silver → gold → sapphire →
     emerald → ruby. These are FIXED brand elements and are deliberately the
     ONLY saturated colours in the system — mobile's own note is "Metals sit
     still and sheen; gems breathe, and ruby heartbeats. Do not recolor or
     substitute them." Mode-independent: identical in light and dark.
     The glows are part of the ladder, not decoration. */
  --gem-graphite-from: #37304B;  --gem-graphite-to:   #221C34;
  --gem-graphite-text: #C9C2DC;  --gem-graphite-glow: transparent;

  --gem-silver-1: #F2F5FA;  --gem-silver-2: #C6CDD9;
  --gem-silver-3: #8C95A3;  --gem-silver-4: #B7BFCC;
  --gem-silver-text: #2B3240;  --gem-silver-glow: rgba(140, 150, 165, 0.5);

  --gem-gold-1: #FFF3C4;  --gem-gold-2: #F2C94C;
  --gem-gold-3: #B8860B;  --gem-gold-4: #E0AC2F;
  --gem-gold-text: #4A3208;  --gem-gold-glow: rgba(242, 201, 76, 0.55);

  --gem-sapphire-from: #2C5FD6;  --gem-sapphire-to: #0A1A52;
  --gem-sapphire-highlight: #BBD4FF;  --gem-sapphire-text: #FFFFFF;
  --gem-sapphire-glow: rgba(58, 110, 235, 0.55);

  --gem-emerald-from: #1FA86A;  --gem-emerald-to: #053723;
  --gem-emerald-highlight: #A9F2CB;  --gem-emerald-text: #FFFFFF;
  --gem-emerald-glow: rgba(31, 168, 106, 0.6);

  --gem-ruby-from: #D9203F;  --gem-ruby-to: #42030F;
  --gem-ruby-highlight: #FFB0BE;  --gem-ruby-text: #FFFFFF;
  --gem-ruby-glow: rgba(230, 30, 75, 0.7);

  /* Legacy tier names the web already uses, now fed by the ladder above. */
  --grad-tier-1: linear-gradient(135deg, var(--gem-graphite-from), var(--gem-graphite-to));
  --grad-tier-2: linear-gradient(135deg, var(--gem-silver-1), var(--gem-silver-2) 45%, var(--gem-silver-3));
  --grad-tier-3: linear-gradient(135deg, var(--gem-gold-1), var(--gem-gold-2) 45%, var(--gem-gold-3));
  --tier-1-fg:   var(--gem-graphite-text);
  --tier-2-fg:   var(--gem-silver-text);
  --tier-3-fg:   var(--gem-gold-text);
  --grad-name-t1: var(--grad-tier-1);
  --grad-name-t2: var(--grad-tier-2);
  --grad-name-t3: var(--grad-tier-3);
}

/* ── §10 · SHAPE · MOTION · TYPE — UNCHANGED ──────────────────────────────
   Carried over verbatim from the previous tokens.css. The radius and type
   scales already matched mobile exactly (6/10/16/pill and 12/14/16/20/26/34),
   because tokens.ts was transcribed from this file in the first place. */
:root {
  --radius-sm:   6px;
  --radius-md:  10px;
  --radius-lg:  16px;
  --radius-full: 9999px;

  --space-4: 16px;
  --space-5: 20px;

  --font-display: 'Fraunces', Georgia, serif;
  --font-body:    'Sora', system-ui, -apple-system, sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, monospace;

  --text-sm:  14px;
  --text-2xl: 26px;
  --leading-normal: 1.55;
  --weight-regular: 400;
  --weight-medium:  500;
  --weight-bold:    700;

  --duration-fast: 120ms;
  --duration-base: 200ms;
  --duration-slow: 320ms;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --container-max: 1200px;

  /* Shadow COLOUR, not a whole shadow. The previous tokens.css shipped
     --shadow-md as a complete shadow, and 579 declarations used it in the
     colour slot (`box-shadow: 0 0 0 3px var(--shadow-md)`) which is invalid
     CSS and silently dropped — 35 of those are focus rings. Both forms are
     provided here so neither shape breaks. */
  --shadow-color: rgba(var(--background-rgb), 0.45);
  --shadow-sm: 0 1px 2px  0    var(--shadow-color);
  --shadow-md: 0 8px 24px -4px var(--shadow-color);
  --shadow-lg: 0 20px 48px -8px var(--shadow-color);
  --glow-accent: 0 0 24px var(--accent-glow);
}

/* ── §11 · ABSORBED BUNDLE NAMESPACES ─────────────────────────────────────
   Names previously owned by calm_amber_{session,mentor,profile}.css,
   coffee_creme_chrome.css and the older theme.css aliases. These bundles were
   already warm — they were the closest thing the web had to the mobile brand —
   so they collapse onto the core cleanly.

   Worth noting what this replaces: --accent-purple alone carried SIX different
   values across the old files, from #8b5cf6 (literal purple) to #E5A340
   (amber). That is the mess this file exists to end. */
:root {
  /* legacy accent aliases */
  --accent-purple:      var(--primary);
  --accent-purple-lt:   color-mix(in srgb, var(--primary) 70%, var(--surface));
  --accent-purple-dk:   var(--accent-deep);
  --accent-purple-dkr:  color-mix(in srgb, var(--accent-deep) 80%, #000);
  --accent-sky:         var(--info);
  --accent-cyan:        var(--info);
  --violet-900:         var(--accent-deep);
  --amber:              var(--warning-soft);
  --amber-500:          var(--warning-soft);
  --amber-600:          var(--warning-strong);
  --amber-deep:         var(--warning-strong);
  --gold:               var(--warning-soft);
  --blue:               var(--info);
  --blue-accent:        var(--info);
  --warning:            var(--warning-strong);
  --color-warning:      var(--warning-strong);
  --color-success-alt:  var(--success);
  --fg:                 var(--text);
  --primary-deep:       var(--accent-deep);
  --primary-gradient:   var(--grad-accent);
  --brand-gradient:     var(--grad-accent);
  --dark-overlay:       rgba(var(--background-rgb), 0.62);
  --stack-accent:       var(--primary);
  --stack-accent-soft:  var(--accent-soft);
  --vhero-ring-color:   var(--border-accent);
  --vhero-ring-glow:    var(--accent-glow);

  /* --cc-* · coffee-creme chrome */
  --cc-espresso:        var(--accent-deep);
  --cc-parchment:       var(--surface);
  --cc-ink-cream:       var(--surface-elevated);
  --cc-oat:             var(--surface-muted);
  --cc-honey:           var(--warning-soft);
  --cc-gold-leaf:       var(--warning-soft);
  --cc-burnt-amber:     var(--warning-strong);
  --cc-pale-terracotta: color-mix(in srgb, var(--danger) 55%, var(--surface));
  --cc-warm-olive:      var(--success);
  --cc-t4-fill:         var(--primary);
  --cc-shadow:          var(--shadow-md);

  /* --ca-* · calm-amber bundles */
  --ca-amber-strong:    var(--primary);
  --ca-amber-soft:      var(--accent-soft);
  --ca-amber-soft-2:    color-mix(in srgb, var(--primary) 16%, transparent);
  --ca-amber-heading:   var(--text);
  --ca-amber-line:      var(--border);
  --ca-amber-aura:      var(--accent-glow);
  --ca-amber-ring-a:    var(--border-accent);
  --ca-amber-ring-b:    var(--accent-glow);
  --ca-glow-lamp:       var(--accent-glow);
  --ca-glow-lamp-2:     color-mix(in srgb, var(--primary) 18%, transparent);
  --ca-bar-top:         var(--border-strong);
  --ca-bar-bot:         var(--border);
  --ca-cta-bg:          var(--primary);
  --ca-cta-bg-hover:    var(--accent-deep);
  --ca-cta-hover:       var(--accent-deep);
  --ca-cta-border:      var(--border-accent);
  --ca-cta-fill:        var(--primary);
  --ca-cta-text:        var(--primary-text);
  --ca-cta-shadow:      var(--shadow-md);
  --ca-cta-shadow-hover: var(--shadow-lg);
  --ca-goal-bg:         var(--surface-elevated);
  --ca-goal-bg-2:       var(--surface-muted);
  --ca-goal-border:     var(--border);
  --ca-goal-fg:         var(--text);
  --ca-ok-bg:           color-mix(in srgb, var(--success) 14%, var(--surface));
  --ca-ok-border:       color-mix(in srgb, var(--success) 40%, var(--surface));
  --ca-ok-text:         var(--success);
  --ca-tier-bg:         var(--surface-elevated);
  --ca-tier-border:     var(--border);
  --ca-tier-gem:        var(--warning-soft);
  --ca-tier-text:       var(--text);

  /* --gc-* · goal card */
  --gc-bg:          var(--surface-elevated);
  --gc-fg:          var(--text);
  --gc-border:      var(--border);
  --gc-primary:     var(--primary);
  --gc-eyebrow:     var(--warning-soft);
  --gc-tagline:     var(--text-muted);
  --gc-arrow:       var(--primary);
  --gc-aura:        var(--accent-glow);
  --gc-shadow:      var(--shadow-md);
  --gc-pill-bg:     color-mix(in srgb, var(--primary) 14%, transparent);
  --gc-pill-bd:     var(--border-accent);
  --gc-pill-fg:     var(--primary);
  --gc-trophy-a:    var(--warning-soft);
  --gc-trophy-b:    var(--warning-strong);
  --gc-trophy-rim:  var(--border-accent);
  --gc-trophy-fg:   var(--primary-text);
}

/* ── §12 · BOOTSTRAP BRIDGE ───────────────────────────────────────────────
   Bootstrap 5.3.3 loads from a CDN at templates/base.html:246 — AFTER this
   file — so its utility and component classes cannot be reached by anything
   above. That is why "Weekly Study Time" rendered Bootstrap green (#198754,
   class `text-success`) and "LEVEL III" rendered Bootstrap link-blue
   (#0D6EFD) while every token on the page was already espresso.

   Bootstrap 5.3 is fully custom-property driven, so it does not need to be
   removed — it needs to be POINTED at the palette. This block does that.
   It covers the 598 `btn` and 228 `modal` usages plus every text, bg and
   border utility in one place.
   (Never write an asterisk-slash pair inside a CSS comment — it closes the
   comment early and the parser then eats the rule that follows. That is
   exactly what happened here on the first attempt.)

   Selector is :root:root — the repeat doubles specificity to (0,2,0) so it
   beats Bootstrap's own :root (0,1,0) regardless of stylesheet order. A plain
   :root here silently LOSES, because Bootstrap loads later and ties. */
:root:root {
  --bs-body-bg:            var(--_bg);
  --bs-body-color:         var(--text);
  --bs-emphasis-color:     var(--text);
  --bs-secondary-color:    var(--text-muted);
  --bs-tertiary-color:     var(--text-faint);
  --bs-body-bg-rgb:        var(--background-rgb);
  --bs-body-color-rgb:     var(--text-rgb);

  --bs-primary:            var(--primary);
  --bs-secondary:          var(--text-muted);
  --bs-success:            var(--success);
  --bs-danger:             var(--danger);
  --bs-warning:            var(--warning-strong);
  --bs-info:               var(--info);
  --bs-light:              var(--surface-elevated);
  --bs-dark:               var(--_bg);

  --bs-link-color:         var(--primary);
  --bs-link-hover-color:   var(--accent-deep);
  --bs-link-color-rgb:     var(--primary-rgb);

  --bs-border-color:       var(--border);
  --bs-border-color-translucent: var(--border);
  --bs-secondary-bg:       var(--surface-muted);
  --bs-tertiary-bg:        var(--surface);

  --bs-btn-color:          var(--primary-text);
  --bs-btn-bg:             var(--primary);
  --bs-btn-border-color:   var(--primary);
}

/* The *-rgb triplets Bootstrap's utilities actually consume:
   `.text-success` compiles to rgba(var(--bs-success-rgb), var(--bs-text-opacity)),
   so overriding --bs-success alone would have left it green. */
:root:root, :root[data-theme="dark"] {
  --bs-primary-rgb: 227, 181, 131;
  --bs-success-rgb: 157, 190, 133;
  --bs-danger-rgb:  224, 138, 114;
  --bs-info-rgb:    150, 180, 205;
  --bs-warning-rgb: 203, 169, 107;
  --bs-light-rgb:    39,  33,  25;
  --bs-dark-rgb:     16,  14,  12;
}
:root[data-theme="light"]:root {
  --bs-primary-rgb: 107,  74,  47;
  --bs-success-rgb:  95, 122,  74;
  --bs-danger-rgb:  158,  59,  47;
  --bs-info-rgb:     78, 110, 138;
  --bs-warning-rgb: 143, 110,  58;
  --bs-light-rgb:   255, 253, 248;
  --bs-dark-rgb:     42,  33,  24;
}
