/* ═══════════════════════════════════════════════════════════════════════════
   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, plus the type face. Shape and motion keep
   their existing web values. Type is one face everywhere: Manrope
   (owner ruling 2026-09-30, reversing the earlier Fraunces/Sora pairing).
   The face is loaded from jsdelivr (@fontsource-variable/manrope) by base.html;
   the CSP allows cdn.jsdelivr.net and NOT fonts.googleapis.com.

   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;
  --brand-wordmark:    #F1E4CB;   /* the logo's "valory"; the icon never changes */

  --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;

  /* ── Answer Key Creator form controls (--akc-*) ──────────────────────────
     The builder is a large editable table and the palette had NO form-control
     tokens: every `input`/`focus`/`placeholder`/`disabled`/`invalid` string in
     the old tokens.css is comment prose, not a declaration. Namespaced like
     --auth-* / --ss-*, so nothing global changes. */
  --akc-field-bg:       #16130F;   /* sits INSIDE --surface-2, one step down */
  --akc-field-border:   #4A4034;
  --akc-field-focus:    #E3B583;   /* == --primary, stated so focus never drifts */
  --akc-field-invalid:  #E08A72;   /* == --danger */
  --akc-placeholder:    #7A6E5F;
  --akc-disabled-bg:    #1F1B16;
  --akc-disabled-fg:    #6B6153;
}

/* ── §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;
  --brand-wordmark:    #2A1E16;   /* the logo's "valory"; the icon never changes */

  --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;

  /* --akc-* light values. Same roles, same order as §1. */
  --akc-field-bg:       #FFFDF8;   /* lighter than --surface-muted behind it */
  --akc-field-border:   #C9BDA6;
  --akc-field-focus:    #6B4A2F;   /* == --primary */
  --akc-field-invalid:  #9E3B2F;   /* == --danger */
  --akc-placeholder:    #9B8D78;
  --akc-disabled-bg:    #EDE6D8;
  --akc-disabled-fg:    #9B8D78;
}

/* ═══ 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);

  /* Pure aliases, and they live HERE rather than in §13 because they are not
     student-specific: they are the names a converted page uses for "the
     theme's card" and "the theme's edge". 151 declarations across
     student/settings and student/daily_checklist read them. While they were
     declared only under `body.vly-warm`, a page rendered without that class
     would have dropped all 151 at once and lost every surface and border it
     has — a two-line safety net against a total failure. §13 no longer
     redeclares them. */
  --vly-card:          var(--surface-elevated);
  --vly-line:          var(--border-default);

  --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 {
  /* Owner ruling 2026-09-21: "remove the background-gradient … from both
     backgrounds and the buttons". These two names are read by 66
     declarations across 15 files, so flattening them here is the whole fix
     for every warm button gradient in the product — and the two were
     IDENTICAL, so nothing was distinguishing a CTA from an accent anyway.
     Checked before flattening: no consumer uses them in `background-image:`
     or behind `background-clip: text`, where a flat colour would be invalid
     or invisible. They stay as token names because 66 call sites read them. */
  --grad-accent: var(--primary);
  --grad-cta:    var(--primary);
  --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-6/7 added 2026-09-16 (My Classes rebuild). Nothing else in the
     tree references either, so defining them changes no existing page.
     --space-1/2/3 are STILL deliberately absent: answer_key.html and the two
     timing pages use them bare, and defining them here would start applying
     spacing those pages have never rendered with — owner ruling R9, filed not
     fixed. New code uses the fallback form, `var(--space-2, 8px)`. */
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 32px;
  --space-7: 48px;

  --font-display: 'Manrope Variable', 'Manrope', system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body:    'Manrope Variable', 'Manrope', system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono:    'Manrope Variable', 'Manrope', system-ui, -apple-system, "Segoe UI", sans-serif;

  /* --text-base, --text-3xl and --leading-tight added 2026-09-16; no other
     page references them. --text-xs and --text-lg stay absent for the same
     R9 reason as --space-1/2/3 above (answer_key.html uses them bare). */
  --text-sm:  14px;
  --text-base: 16px;
  --text-2xl: 26px;
  --text-3xl: 34px;
  --leading-tight:  1.2;
  --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);

  /* The last 6 names the scoped calm_amber palettes owned privately. Those
     files had ALREADY de-blued them (--cyan was #D89C3C, --violet #D89C3C —
     amber, not cyan), so this is not a new decision, just the same one made
     centrally. Decorative names join the accent family; the one genuinely
     semantic name keeps --info, which in the mobile palette is a muted
     blue-grey and is meant to stay that way. */
  --cyan:            var(--warning-soft);
  --violet:          var(--warning-soft);
  --accent-blue:     var(--primary);
  --accent-blue-dk:  var(--accent-deep);
  --color-info:      var(--info);

  /* The coffee-creme shade names the profile bundle used to own privately.
     All already warm, so these keep their exact hues rather than being
     flattened onto the core — they are a deliberate secondary ramp, and the
     tier/achievement chrome reads as muddy without the spread. */
  --cc-mahogany:       var(--accent-deep);
  --cc-deep-mahogany:  #4A1F0C;
  --cc-cinnamon:       #8E5A10;
  --cc-espresso-soft:  #5B4A30;
  --cc-stone-taupe:    #B8A476;
  --cc-faded-honey:    #EDD8A1;
  --cc-pale-honey:     #F2DFA6;
  --cc-pale-oat:       #E5DCC2;
  --cc-ivory:          #F6EFDB;
  --cc-olive-line:     #C4C783;
  --cc-pale-sage:      #E5E5BF;
  --cc-t4-border:      #2E2418;

  /* --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;
}

/* ── §13 · STUDENT-SURFACE WARM SCOPE ──────────────────────────────────────
   Owner ruling 2026-09-21: "fix the color theme. for both light and dark
   modules. No need for bluish shit like here."

   The palette was never blue. The student surface WALLPAPERS ITSELF in
   `var(--info)` — a semantic token, used as a surface fill in 343 background
   declarations across 42 templates. --info is #4E6E8A light / #96B4CD dark,
   and painting a card with it is what made every student page read as a
   hospital form beside the espresso mentor pages.

   This rebinds the blue family onto the carrier (--primary: #6B4A2F light,
   #E3B583 dark) for non-mentor viewers only, so --info stays a real
   informational blue everywhere it is used as a MEANING. Scope is
   `body.vly-warm`, set in templates/base.html for every viewer who is not a
   mentor; admin/ops and centers shells do not extend base.html at all.

   WHY THE ALIASES ARE REPEATED AND ARE NOT REDUNDANT. A var() inside a
   custom-property declaration is substituted on the element the declaration
   applies to. `:root { --accent-sky: var(--info) }` was already computed
   against the ROOT's --info, so body inherits a finished blue and overriding
   --info alone never reaches it. Re-declaring each alias here is the only
   thing that does. Regenerate the list with:

     grep -nE '^\s*--[a-z0-9-]+:\s*[^;]*var\(--info\)' static/css/valory-tokens.css

   That returns 17 names today, all of them below. An eighteenth belongs here.
   (--bs-info-rgb is the exception that looks like a counter-example: it is a
   var() READ on the element, not a declaration on :root, so a body-scoped
   value does reach .text-info / .bg-info.)                                   */
body.vly-warm{
  --info:            var(--primary);
  --color-info:      var(--primary);
  --text-light-blue: var(--primary);
  --accent-sky:      var(--primary);
  --accent-cyan:     var(--primary);
  --blue:            var(--primary);
  --blue-accent:     var(--primary);
  --sky-500:         var(--primary);
  --sky-400:         var(--primary);
  --sky-300:         color-mix(in srgb, var(--primary) 70%, var(--surface));
  --sky-200:         color-mix(in srgb, var(--primary) 45%, var(--surface));
  --sky-100:         color-mix(in srgb, var(--primary) 22%, var(--surface));
  --blue-500:        var(--primary);
  --blue-400:        var(--primary);
  --blue-300:        color-mix(in srgb, var(--primary) 70%, var(--surface));
  --blue-200:        color-mix(in srgb, var(--primary) 45%, var(--surface));
  --blue-50:         color-mix(in srgb, var(--primary) 12%, var(--surface));
  --bs-info:         var(--primary);
  --bs-info-rgb:     227, 181, 131;              /* dark  #E3B583 */
  /* templates/base.html declares these two on <html>, same substitution trap */
  --accent2:         var(--primary);
  --cyan:            var(--primary);

  /* The one NEW value. --accent-soft and --primary-light mix over
     `transparent`, so they composite against whatever sits behind them; this
     one is opaque, so its contrast against --text is a fixed number rather
     than a function of the card underneath it. */
  --vly-quiet: color-mix(in srgb, var(--primary) 12%, var(--surface));

  /* GRAPHITE ONLY — the ore, not a gem. The ladder above says "do not
     recolor or substitute", and that stands for silver, gold, sapphire,
     emerald and ruby: they are the product's one saturated brand element and
     they are untouched, here and in the mobile-parity block they were ported
     from. Graphite is the UNEARNED state, the slab a student sees before
     they have any level at all — so it is the state every pilot student is
     in on day one, and it was violet (#37304B → #221C34, ink #C9C2DC): two
     purple slabs in the middle of an espresso profile, which is precisely
     the "bluish" the owner named. An unlit stone should read as unlit stone
     in this palette. Scoped to student surfaces, like everything else here;
     mentor and admin see the ported ladder unchanged. */
  --gem-graphite-from: #3A3128;
  --gem-graphite-to:   #241D16;
  --gem-graphite-text: #D6C8B2;

  /* ── The surface job, which the rebind above does NOT fix ──────────────
     `--info` was doing two jobs in these templates: an ACCENT (a link, an
     icon, a focus ring) and a SURFACE (779 background declarations). The
     rebind above is right for the accent and wrong for the surface, and it
     was wrong BEFORE the rebind too, in the other direction — this is not a
     regression the espresso palette introduced:

       light, before:  color-mix(--info 70%, transparent) = 70% of #4E6E8A
                       over cream  ->  a slate-blue slab with dark ink on it
       light, after:   70% of #6B4A2F over cream          ->  a mud slab
       dark,  after:   70% of #E3B583 over #1B1815        ->  a champagne slab

     In all three the ink on the card is the loser: the daily checklist's
     streak NUMBER renders invisible in both themes today. A translucent
     accent is not a card in any palette.

     So a page whose surfaces are converted points its BACKGROUNDS at these
     two instead, which track the theme's own card rather than the accent —
     and its on-card ink moves to the neutral --text-* family in the same
     edit, or the strings vanish. Converted so far: student/my_course_profile,
     student/daily_checklist, student/settings, student/course_leaderboard.
     The rest of the list is in the slice README.

     THE TWO TOKENS THEMSELVES MOVED TO `:root` (see the alias layer above):
     they are theme aliases, not a student rebind, and scoping them here made
     every one of the 151 declarations that read them depend on a body class
     they have no reason to need. */
}
html[data-theme="light"] body.vly-warm{ --bs-info-rgb: 107, 74, 47; }

/* ── §14. The last blue on the student surface is the one nobody wrote ──────
   NOTHING in this app sets `accent-color`, so every native checkbox, radio,
   range and progress bar is painted by the BROWSER in the platform accent —
   which is blue. It survived the §13 rebind because it is not a colour the
   stylesheet ever names.

   Measured before writing this rule, across ten rendered student pages: 52
   such controls exist and all but THREE already set `appearance: none` and
   paint themselves, so this changes exactly the three that did not (the
   profile-visibility radios in Settings) and is inert everywhere else. It is
   here rather than on those three because the next unstyled control should
   not have to rediscover it.

   Scoped to `body.vly-warm` like everything else in this file: mentor and
   admin surfaces are untouched.                                            */
body.vly-warm input[type="checkbox"],
body.vly-warm input[type="radio"],
body.vly-warm input[type="range"],
body.vly-warm progress{
  accent-color: var(--primary);
}
