/* ═══════════════════════════════════════════════════════════════════════
   Stackz — canonical design tokens
   ─────────────────────────────────────────────────────────────────────
   ONE palette, ONE type system, ONE spacing scale for the whole app.

   Direction: "quiet institutional". The reference object is a custodial
   account statement — warm paper, hairline rules, ink-black type, figures
   set in tabular monospace and right-aligned. Colour is scarce on purpose:
   the only saturated hues in the product are gain, loss, and caution.
   Everything else is neutral so the numbers carry the page.

   HOW THIS FILE WORKS
   Section 1 defines the canonical `--sz-*` scale.
   Section 2 re-points every legacy token namespace at that scale.

   The app grew five parallel namespaces for the same concepts
   (--obs-*, --wealth-*, --color-cyber-*, --ink/--line/--brand, --text-*),
   and three stylesheets each redefined --obs-* with DIFFERENT values, so
   whichever loaded last silently won. That is why dark mode was tinted
   green and the primary button was lime.

   Aliasing rather than rewriting means ~3,000 existing declarations keep
   working untouched and the palette has exactly one source of truth.

   LOAD LAST — after dashboard.css / brokerage.css / wealth.css / theme.css.
   ═══════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────────────────
   1. CANONICAL SCALE
   ───────────────────────────────────────────────────────────────────── */

/* Dark is this app's default; `html.theme-light` is the override, set
   before first paint by the bootstrap in partials/head.html. Section 1
   therefore defines dark on :root and light further down. */
:root {
  /* ── Surfaces — warm charcoal, four steps, no tint ──────────────
     Not pure black: #000 behind a hairline rule makes the rule look
     like a rendering artefact rather than a drawn line. */
  --sz-paper:        #131211;  /* page ground                        */
  --sz-surface:      #1b1a18;  /* cards, panels                      */
  --sz-surface-2:    #232220;  /* inset wells, table stripes         */
  --sz-surface-3:    #2b2a27;  /* hover                              */
  --sz-surface-4:    #34322e;  /* pressed / active                   */

  /* ── Rules — hairlines, not boxes ───────────────────────────────── */
  --sz-rule:         #302e2b;  /* default separator                  */
  --sz-rule-soft:    #262421;  /* internal grouping                  */
  --sz-rule-strong:  #45423d;  /* section boundary, input border     */

  /* ── Ink — four steps is enough for any hierarchy ───────────────── */
  --sz-ink:          #f2f0eb;  /* headings, figures                  */
  --sz-ink-2:        #b8b5ad;  /* body                               */
  --sz-ink-3:        #a3a099;  /* labels, meta — 4.5:1 on --sz-surface */
  --sz-ink-4:        #979389;  /* faintest text tier — still 4.5:1     */

  /* ── Data colour — the ONLY saturated hues in the product ───────── */
  --sz-pos:          #56bd88;  /* gain                               */
  --sz-neg:          #e4796b;  /* loss                               */
  --sz-caution:      #cba455;  /* stale data, breached guardrail     */
  --sz-info:         #86a8d8;  /* neutral annotation                 */

  /* Tinted washes — backgrounds for the above. Kept very low alpha so
     a table full of them still reads as a table, not a heat map. */
  --sz-pos-wash:     rgba(86,189,136,0.11);
  --sz-neg-wash:     rgba(228,121,107,0.11);
  --sz-caution-wash: rgba(203,164,85,0.12);
  --sz-info-wash:    rgba(134,168,216,0.11);

  /* Categorical comparison palette for allocations and multi-series charts.
     This chart-only blue/orange/gray sequence is adapted from Tableau's
     color-blind palette, then contrast-adjusted for this surface. Hue and
     value both separate adjacent marks; direct labels remain authoritative.
     Never use a category slot to imply gain, loss, or caution. */
  --sz-cat-1:        #5f9ed1;
  --sz-cat-2:        #ffbc79;
  --sz-cat-3:        #ababab;
  --sz-cat-4:        #ff800e;
  --sz-cat-5:        #a2c8ec;
  --sz-cat-6:        #898989;
  --sz-cat-7:        #cfcfcf;
  --sz-cat-8:        #c85200;

  /* ── Brand — the mark and focus rings only. Never a data colour. ── */
  --sz-brand:        #56bd88;
  --sz-brand-ink:    #0c1a13;  /* text on a brand fill               */
  --sz-brand-wash:   rgba(86,189,136,0.11);

  /* ── Action — primary controls are ink, not colour ──────────────── */
  --sz-action:       #f2f0eb;
  --sz-action-ink:   #171613;
  --sz-action-hover: #d9d6cf;

  /* ── Focus — one ring, used everywhere, always visible ──────────── */
  --sz-focus:        #56bd88;
  --sz-focus-ring:   0 0 0 2px var(--sz-paper), 0 0 0 4px var(--sz-focus);

  /* ── Type ────────────────────────────────────────────────────────
     One superfamily in three roles. IBM Plex is drawn for technical
     documents: Sans has real tabular figures, Mono is legible at 11px
     for dense tables, Serif supplies the annual-report register on
     page titles. Replaces four unrelated families (Manrope, Inter,
     Fraunces, JetBrains Mono) that shared no proportions. */
  --sz-font-text:    'IBM Plex Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --sz-font-num:     'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --sz-font-display: 'IBM Plex Serif', ui-serif, Georgia, serif;

  /* Type scale — restrained. Institutional pages do not need 9 sizes. */
  --sz-text-display: 2.5rem;   /* 40px — page title, one per page     */
  --sz-text-h1:      1.75rem;  /* 28px                                */
  --sz-text-h2:      1.25rem;  /* 20px — section heading              */
  --sz-text-h3:      0.9375rem;/* 15px — card heading                 */
  --sz-text-body:    0.875rem; /* 14px                                */
  --sz-text-sm:      0.8125rem;/* 13px                                */
  --sz-text-meta:    0.75rem;  /* 12px — as-of lines, captions        */
  --sz-text-micro:   0.6875rem;/* 11px — table labels. FLOOR. */

  --sz-leading-tight: 1.15;
  --sz-leading-snug:  1.35;
  --sz-leading-body:  1.55;
  --sz-tracking-label: 0.06em; /* compact uppercase production labels */
  --sz-tracking-table: 0.05em; /* responsive table row labels          */

  /* Figures are always tabular so columns align and digits do not
     jitter as live prices tick. */
  --sz-num-feat: "tnum" 1, "lnum" 1;

  /* ── Space — 4px base, no arbitrary values ──────────────────────── */
  --sz-1:  4px;
  --sz-2:  8px;
  --sz-3:  12px;
  --sz-4:  16px;
  --sz-5:  20px;
  --sz-6:  24px;
  --sz-8:  32px;
  --sz-10: 40px;
  --sz-12: 48px;
  --sz-16: 64px;

  /* ── Page container ──────────────────────────────────────────────
     ONE content width for the whole product. The app previously used
     1080 / 1120 / 1152 / 1180 / 1240 / 1260 / 1280 across different pages,
     so the left and right edges moved as you navigated — the single biggest
     reason the surfaces read as separate custom pages rather than one app. */
  --sz-container: 1200px;
  --sz-gutter: var(--sz-6);

  /* The investor control center is intentionally wider than document pages:
     a performance series, decision rail, and position table must coexist
     without compressing financial figures. These remain product tokens so
     the dashboard never grows its own ad-hoc spacing namespace. */
  --sz-dashboard-container: 1680px;
  --sz-dashboard-rail: 248px;
  --sz-dashboard-dock: 64px;
  --sz-dashboard-command: 680px;
  --sz-dashboard-command-results: 520px;
  --sz-dashboard-scope: 220px;
  --sz-dashboard-brief: clamp(280px, 18vw, 340px);
  --sz-dashboard-chart: 360px;
  --sz-dashboard-map: 320px;
  --sz-dashboard-chart-compact: 240px; /* supporting analytics panels */
  --sz-dashboard-accent: 2px;

  /* ── Radius — four values total ─────────────────────────────────── */
  --sz-r-sm:   4px;   /* inputs, chips, buttons */
  --sz-r-md:   8px;   /* cards                  */
  --sz-r-lg:   12px;  /* modals, large panels   */
  --sz-r-full: 999px; /* avatars, status dots   */

  /* ── Elevation — restrained. Rules do the separating, not shadows. */
  --sz-shadow-sm: 0 1px 2px rgba(0,0,0,0.4);
  --sz-shadow-md: 0 2px 6px rgba(0,0,0,0.45), 0 1px 2px rgba(0,0,0,0.3);
  --sz-shadow-lg: 0 24px 56px rgba(0,0,0,0.62), 0 2px 8px rgba(0,0,0,0.4);

  /* ── Motion — short, and switched off under reduced-motion ─────── */
  --sz-ease:      cubic-bezier(0.2, 0, 0.13, 1);
  --sz-dur-fast:  120ms;
  --sz-dur:       180ms;
  --sz-blur:      14px;
  --sz-disabled-opacity: 0.58;
  --sz-motion-pressed-scale: 0.995;

  /* Shared sticky chrome geometry. This is a layout contract rather
     than general spacing: the reusable product nav is exactly 56px. */
  --sz-nav-height: 56px;

  --sz-scrim: rgba(8,8,7,0.72);
  --sz-print-paper: #ffffff;
  --sz-print-ink: #000000;

  color-scheme: dark;
}

/* ─── Light ──────────────────────────────────────────────────────────
   Warm paper rather than #fff, so the white cards sitting on it have
   something to separate against without needing a shadow. Gain/loss
   darken here rather than reusing the dark-mode values, which would
   drop to ~2:1 on paper and fail contrast. */
html.theme-light {
  --sz-paper:        #faf9f7;
  --sz-surface:      #ffffff;
  --sz-surface-2:    #f4f3f0;
  --sz-surface-3:    #eceae6;
  --sz-surface-4:    #e2dfda;

  --sz-rule:         #e6e3de;
  --sz-rule-soft:    #efedea;
  --sz-rule-strong:  #d3cfc8;

  --sz-ink:          #1b1a17;
  --sz-ink-2:        #55524b;
  --sz-ink-3:        #66635c;  /* labels, meta — 4.5:1 on --sz-surface */
  --sz-ink-4:        #74716a;  /* faintest text tier — still 4.5:1     */

  --sz-pos:          #0e7245;
  --sz-neg:          #a52f22;
  --sz-caution:      #8a6516;
  --sz-info:         #2b4b78;

  --sz-pos-wash:     rgba(14,114,69,0.08);
  --sz-neg-wash:     rgba(165,47,34,0.08);
  --sz-caution-wash: rgba(138,101,22,0.10);
  --sz-info-wash:    rgba(43,75,120,0.08);

  --sz-cat-1:        #006ba4;
  --sz-cat-2:        #c85200;
  --sz-cat-3:        #595959;
  --sz-cat-4:        #1f4e6b;
  --sz-cat-5:        #7a410f;
  --sz-cat-6:        #898989;
  --sz-cat-7:        #343434;
  --sz-cat-8:        #6f462b;

  --sz-brand:        #12664a;
  --sz-brand-ink:    #ffffff;
  --sz-brand-wash:   rgba(18,102,74,0.08);

  --sz-action:       #1b1a17;
  --sz-action-ink:   #faf9f7;
  --sz-action-hover: #35322c;

  --sz-focus:        #12664a;
  --sz-focus-ring:   0 0 0 2px var(--sz-paper), 0 0 0 4px var(--sz-focus);

  --sz-shadow-sm: 0 1px 2px rgba(27,26,23,0.05);
  --sz-shadow-md: 0 2px 6px rgba(27,26,23,0.06), 0 1px 2px rgba(27,26,23,0.04);
  --sz-shadow-lg: 0 24px 56px rgba(27,26,23,0.16), 0 2px 8px rgba(27,26,23,0.07);

  --sz-scrim: rgba(27,26,23,0.55);

  color-scheme: light;
}

/* ─────────────────────────────────────────────────────────────────────
   2. LEGACY ALIASES
   Every namespace the app already ships now resolves to the scale above.
   Nothing below introduces a new value — these are pointers only.
   ───────────────────────────────────────────────────────────────────── */

/* These are pointers, so one set of declarations serves both themes —
   custom properties resolve at the point of use and pick up whichever
   --sz-* value won on <html>.

   Both selectors are required for specificity, not for theming. The
   legacy files declare these names at BOTH `:root` (0,1,0) and
   `html.theme-light` (0,1,1). A bare `:root` here would lose to the
   latter in light mode, so the light-weight selector is matched
   exactly and won on load order instead. */
:root,
html.theme-light {
  /* ── obs-* — dashboard, brokerage, wealth all wrote this namespace ── */
  --obs-bg:          var(--sz-paper);
  --obs-surface:     var(--sz-surface);
  --obs-card:        var(--sz-surface);
  --obs-raised:      var(--sz-surface-2);
  --obs-inset:       var(--sz-surface-2);
  --obs-border:      var(--sz-rule);
  --obs-border-md:   var(--sz-rule);
  --obs-border-hi:   var(--sz-rule-strong);

  --obs-text-1:      var(--sz-ink);
  --obs-text-2:      var(--sz-ink-2);
  --obs-text-3:      var(--sz-ink-3);
  --obs-text-4:      var(--sz-ink-4);

  --obs-brand:       var(--sz-brand);
  --obs-brand-soft:  var(--sz-brand-wash);
  --obs-brand-dim:   var(--sz-brand-wash);
  --obs-brand-glow:  var(--sz-brand-wash);

  /* The old palette spent eight hues on semantic roles that only ever
     needed three. Violet/blue/purple/orange all collapse onto the
     neutral or caution ramp so a screen cannot light up like a toy. */
  --obs-green:       var(--sz-pos);
  --obs-green-soft:  var(--sz-pos-wash);
  --obs-red:         var(--sz-neg);
  --obs-red-soft:    var(--sz-neg-wash);
  --obs-amber:       var(--sz-caution);
  --obs-amber-soft:  var(--sz-caution-wash);
  --obs-orange:      var(--sz-caution);
  --obs-orange-soft: var(--sz-caution-wash);
  --obs-blue:        var(--sz-info);
  --obs-blue-soft:   var(--sz-info-wash);
  --obs-ai:          var(--sz-info);
  --obs-ai-soft:     var(--sz-info-wash);
  --obs-purple:      var(--sz-info);
  --obs-purple-soft: var(--sz-info-wash);

  --obs-shadow-sm:   var(--sz-shadow-sm);
  --obs-shadow-md:   var(--sz-shadow-md);
  --obs-shadow-lg:   var(--sz-shadow-lg);

  /* ── wealth-* — the income/dividend surfaces ────────────────────── */
  --wealth-bg:          var(--sz-paper);
  --wealth-panel:       var(--sz-surface);
  --wealth-panel-soft:  var(--sz-surface-2);
  --wealth-ink:         var(--sz-ink);
  --wealth-muted:       var(--sz-ink-3);
  --wealth-faint:       var(--sz-ink-4);
  --wealth-line:        var(--sz-rule);
  --wealth-line-strong: var(--sz-rule-strong);
  --wealth-accent:      var(--sz-brand);
  --wealth-accent-ink:  var(--sz-brand-ink);
  --wealth-positive:    var(--sz-pos);
  --wealth-negative:    var(--sz-neg);
  --wealth-warning:     var(--sz-caution);
  --wealth-shadow:      var(--sz-shadow-lg);
  --wealth-shadow-soft: var(--sz-shadow-md);
  /* 24px/17px radii were the largest in the app and made income cards
     read as a separate product. Pulled onto the shared scale. */
  --wealth-radius-lg:   var(--sz-r-lg);
  --wealth-radius-md:   var(--sz-r-md);

  /* ── color-cyber-* — Tailwind utility palette (bg/text/border-cyber-*) */
  --color-cyber-bg:      var(--sz-paper);
  --color-cyber-surface: var(--sz-surface);
  --color-cyber-card:    var(--sz-surface);
  --color-cyber-border:  var(--sz-rule);
  --color-cyber-dim:     var(--sz-ink-4);
  --color-cyber-muted:   var(--sz-ink-3);
  --color-cyber-green:   var(--sz-pos);
  --color-cyber-red:     var(--sz-neg);
  --color-cyber-amber:   var(--sz-caution);
  --color-cyber-orange:  var(--sz-caution);
  --color-cyber-cyan:    var(--sz-info);
  --color-cyber-blue:    var(--sz-info);
  --color-cyber-purple:  var(--sz-info);
  --color-cyber-magenta: var(--sz-info);
  --color-cyber-neon:    var(--sz-brand);

  /* ── ink / line / brand — landing, legal, coach ─────────────────── */
  --ink:          var(--sz-ink);
  --line:         var(--sz-rule);
  --line-soft:    var(--sz-rule-soft);
  --line-strong:  var(--sz-rule-strong);
  --brand:        var(--sz-brand);
  --brand-soft:   var(--sz-brand-wash);
  --brand-deep:   var(--sz-brand);
  --brand-bright: var(--sz-brand);
  --primary-brand:var(--sz-brand);
  --accent-gold:  var(--sz-caution);
  --acid:         var(--sz-brand);
  --muted:        var(--sz-ink-3);
  --muted-2:      var(--sz-ink-4);
  --faint:        var(--sz-ink-4);
  --panel:        var(--sz-surface);
  --panel-2:      var(--sz-surface-2);
  --panel-3:      var(--sz-surface-3);
  --page-bg:      var(--sz-paper);
  --positive:     var(--sz-pos);
  --success:      var(--sz-pos);
  --success-soft: var(--sz-pos-wash);
  --warning:      var(--sz-caution);
  --warning-soft: var(--sz-caution-wash);
  --gold:         var(--sz-caution);
  --accent-gold:  var(--sz-caution);
  --accent-gold-soft: var(--sz-caution-wash);

  /* ── generic text/surface/base — base_styles.html and friends ───── */
  --bg:               var(--sz-paper);
  --bg2:              var(--sz-surface-2);
  --card:             var(--sz-surface);
  --surface:          var(--sz-surface);
  --surface-panel:    var(--sz-surface);
  --surface-soft:     var(--sz-surface-2);
  --surface-elevated: var(--sz-surface);
  --border:           var(--sz-rule);
  --border-soft:      var(--sz-rule-soft);
  --text:             var(--sz-ink);
  --text-primary:     var(--sz-ink);
  --text-2:           var(--sz-ink-2);
  --text-secondary:   var(--sz-ink-2);
  --text-3:           var(--sz-ink-3);
  --text-muted:       var(--sz-ink-3);
  --text-inverse:     var(--sz-action-ink);
  --page-bg:          var(--sz-paper);
  --panel-3:          var(--sz-surface-3);
  --txt:              var(--sz-ink);
  --txt2:             var(--sz-ink-2);
  --txt3:             var(--sz-ink-3);
  --green:            var(--sz-pos);
  --red:              var(--sz-neg);
  --danger:           var(--sz-neg);
  --blue:             var(--sz-info);
  --cyan:             var(--sz-info);
  --purple:           var(--sz-info);
  --magenta:          var(--sz-info);
  --orange:           var(--sz-caution);

  /* ── fonts — collapse every alias onto the one superfamily ──────── */
  --sans:         var(--sz-font-text);
  /* The legacy `--display` / `--font-display` names are applied to every
     section heading, kicker and panel label across the app — dozens per
     screen. Pointing them at the serif put four or five serif headings on
     one page, which is the opposite of restraint. They resolve to the text
     face; the serif is opt-in via .sz-display on the single page title. */
  --display:      var(--sz-font-text);
  --mono:         var(--sz-font-num);
  --font-display: var(--sz-font-text);
  --font-body:    var(--sz-font-text);
  --font-mono:    var(--sz-font-num);

  /* ── glass — used by the public site chrome ─────────────────────── */
  --site-glass-bg:     var(--sz-surface);
  --site-glass-border: var(--sz-rule);

  --brokerage-rail:    var(--sz-paper);
  --brokerage-control: var(--sz-surface-2);
  --brokerage-radius:  var(--sz-r-md);
}

/* ─────────────────────────────────────────────────────────────────────
   3. GLOBAL BASE
   ───────────────────────────────────────────────────────────────────── */

/* One family everywhere. The dashboard hard-coded 'Manrope' on body and
   every heading, which is why it never matched the other pages. */
body,
body.dashboard-shell,
.dashboard-shell h1, .dashboard-shell h2, .dashboard-shell h3,
.dashboard-shell h4, .dashboard-shell h5, .dashboard-shell h6 {
  font-family: var(--sz-font-text);
}

body,
body.dashboard-shell {
  background: var(--sz-paper);
  color: var(--sz-ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Page titles carry the serif. Used once per page, nowhere else. */
.sz-display,
.dashboard-page-title {
  font-family: var(--sz-font-display);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: var(--sz-leading-tight);
}

/* Anything that is a figure gets tabular mono. Applied broadly on
   purpose: a price that shifts width when it ticks is a bug. */
.stat-number, .sz-num, .num,
[class*="tabular"], [class*="font-mono"],
td[class*="text-right"], th[class*="text-right"] {
  font-family: var(--sz-font-num);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: var(--sz-num-feat);
}

/* ── Shared product surfaces ───────────────────────────────────────
   Component implementations live in components.css; this file only defines
   their shared material and typography values. */
/* Gain/loss. Sign is carried by colour AND a leading +/- so the
   distinction survives greyscale printing and colour-blindness. */
.sz-pos, .text-pos { color: var(--sz-pos); }
.sz-neg, .text-neg { color: var(--sz-neg); }
.sz-flat            { color: var(--sz-ink-3); }

/* ── Focus — one visible ring, never removed ─────────────────────── */
:focus-visible {
  outline: none;
  box-shadow: var(--sz-focus-ring);
  border-radius: var(--sz-r-sm);
}

/* ── Scrollbars — 3px hairlines were effectively invisible ───────── */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--sz-rule-strong);
  border-radius: var(--sz-r-full);
  border: 3px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--sz-ink-4); background-clip: content-box; }

/* ── Selection ───────────────────────────────────────────────────── */
::selection { background: var(--sz-brand-wash); color: var(--sz-ink); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
