/* ============================================================================
   Squaring Design Tokens — Direction A ("Modern Ledger")
   GH-625 (GH-622 Phase 4) · Stage 2 — token definitions
   ----------------------------------------------------------------------------
   WHAT: The single source of truth for every visual VALUE in the platform —
         colors, type, radius, elevation, density, layout dimensions.
   HOW IT WORKS (two-layer architecture, plan D1/D2):
     Tier 1  primitives  (--sq-*)     = the raw Direction A palette, mode-agnostic.
     Tier 2  semantic    (--color-*)  = what templates + Tailwind consume.
                                         Dark mode RE-BINDS the semantic tier;
                                         primitives never change.
     Layer B tailwind.config (Stage 3) references the semantic tier via var().

   WHY plain CSS (not a Tailwind layer): these are custom properties + @font-face
   only — zero Tailwind directives — so this file is <link>-able TODAY under the
   CDN, which is what lets Stage 2-4 ship even if the CLI cutover (Stage 5) splits
   off. It lives in SERVED static deliberately (plan §6).

   ⚠️ DEFINE-ONLY (plan D4/D5): defining a token here is harmless. This file does
   NOT wire anything onto base.html / global selectors, and the existing 39
   semantic-state vars (--txn/--alert/--health/--recon/--balance) are NOT touched
   — they re-value in Phase 5, per surface. Adding these tokens changes ZERO
   existing screens.

   Refs: memory-bank/projects/cloud-platform/features/GH-622/tokens/plan.md
         …/tokens/token-reconciliation.md  ·  …/workspace/design.md (token table)
         DD-008 / DD-009 / DD-015 (GH-711: dark = "Iron Gall", supersedes DD-010's
         neutral-charcoal base + DD-011's chrome inversion; see the .dark block below)
   ============================================================================ */


/* ----------------------------------------------------------------------------
   FONTS — self-hosted (DD-009; plan §6 font delivery)
   Production CSP is `font-src: 'self'` (ADR 044/047) — Google Fonts is BLOCKED,
   so the families are vendored locally. Ship the foundries' pre-built static
   woff2 UNMODIFIED + each family's OFL.txt: Spectral & IBM Plex carry OFL
   Reserved Font Names, so a re-subsetted build would legally require renaming.

   The 11 .woff2 binaries + 3 OFL.txt ARE vendored in apps/ui/static/ui/fonts/
   (see that dir's README for provenance); the font-integrity test
   (tests/pure/test_design_tokens.py) asserts each @font-face src exists with a
   valid woff2 header and each family ships its OFL. @font-face url()s resolve
   relative to THIS file (../fonts/…). Weights are the selection used by the hero
   mockups; don't add weights we don't use.
   ---------------------------------------------------------------------------- */

/* Spectral — headings + ALTA display numbers */
@font-face { font-family:'Spectral'; font-style:normal; font-weight:400; font-display:swap;
  src:url("../fonts/spectral-400.5a23effd12c4.woff2") format('woff2'); }
@font-face { font-family:'Spectral'; font-style:italic; font-weight:400; font-display:swap;
  src:url("../fonts/spectral-400-italic.3d97213549de.woff2") format('woff2'); }
@font-face { font-family:'Spectral'; font-style:normal; font-weight:500; font-display:swap;
  src:url("../fonts/spectral-500.f9d5da50ce73.woff2") format('woff2'); }
@font-face { font-family:'Spectral'; font-style:normal; font-weight:600; font-display:swap;
  src:url("../fonts/spectral-600.1c7c57f43cc8.woff2") format('woff2'); }

/* Geist — UI + dense tabular amounts (DD-009) */
@font-face { font-family:'Geist'; font-style:normal; font-weight:400; font-display:swap;
  src:url("../fonts/geist-400.3233d2229417.woff2") format('woff2'); }
@font-face { font-family:'Geist'; font-style:normal; font-weight:500; font-display:swap;
  src:url("../fonts/geist-500.57994472c4fa.woff2") format('woff2'); }
@font-face { font-family:'Geist'; font-style:normal; font-weight:600; font-display:swap;
  src:url("../fonts/geist-600.c8489d436490.woff2") format('woff2'); }
@font-face { font-family:'Geist'; font-style:normal; font-weight:700; font-display:swap;
  src:url("../fonts/geist-700.a5aaa810e22a.woff2") format('woff2'); }

/* IBM Plex Mono — available (not chosen for amounts; DD-009) */
@font-face { font-family:'IBM Plex Mono'; font-style:normal; font-weight:400; font-display:swap;
  src:url("../fonts/ibm-plex-mono-400.b51685c998a0.woff2") format('woff2'); }
@font-face { font-family:'IBM Plex Mono'; font-style:normal; font-weight:500; font-display:swap;
  src:url("../fonts/ibm-plex-mono-500.91abacd323ba.woff2") format('woff2'); }
@font-face { font-family:'IBM Plex Mono'; font-style:normal; font-weight:600; font-display:swap;
  src:url("../fonts/ibm-plex-mono-600.7d69bd02da7b.woff2") format('woff2'); }


/* ============================================================================
   TIER 1 — PRIMITIVES (--sq-*)
   The raw Direction A palette: a lean, mode-AGNOSTIC, colour-named set of brand/
   status/light-surface swatches. GH-711 (DD-015) removed the old mode-named dark
   surface/text primitives — per-mode dark VALUES now live as LITERALS in the .dark
   assignment below, not as named primitives. Never reference these directly in
   templates — go through the semantic --color-* tier (the seam).
   ============================================================================ */
:root {
  /* ── Modern Ledger PRIVATE palette (Layer 3). Mode-AGNOSTIC, colour-named
     swatches reused across roles. Templates NEVER touch these — only the --color-*
     semantic tier (the seam). Per-mode VALUES live in the :root/.dark assignment
     below, as refs to these swatches OR as literals; NO primitive name carries a
     mode tag (that's what forced renames before — GH-711). Dark (Iron Gall) values
     that aren't reused are inlined as literals in .dark, not named here. ── */

  /* warm-paper light surfaces */
  --sq-paper:            #F7F4ED;   /* light raised cards / topbar / base rows */
  --sq-paper-deep:       #E9E2D3;   /* light page (sits deeper than its cards) */
  --sq-white:            #FFFFFF;   /* light alt-row stripe (an ACCENT, not the field) */
  --sq-hairline:         #E0D8C6;   /* light card/panel edge hairline */
  --sq-hairline-2:       #EDE6D6;   /* light softer inner hairline (+ island text rule) */

  /* brand: forest + bronze (DD-008) */
  --sq-forest:           #1F4733;   --sq-forest-bright: #5BB088;  /* primary; bright = dark mode */
  --sq-forest-spine:     #1E4A37;   /* light chrome "spine" */
  --sq-bronze:           #8A7649;   /* light accent (dark accent = gilt, inlined in .dark) */

  /* chrome accents */
  --sq-parchment:        #E5DCC6;   /* parchment accent: dark action tray + dark inverse island */
  --sq-parchment-tray:   #E7DDC4;   /* light action tray */
  --sq-logo-cream:       #CABB94;   /* chrome logo ink (cream — both modes) */
  --sq-chrome-edge:      #163829;   /* light chrome sub-parts (dark values inlined in .dark) */
  --sq-chrome-hover:     #24573F;
  --sq-chrome-ink:       #E7E0CF;
  --sq-chrome-ink-2:     #9DB4A4;

  /* semantic-status hues (DD-003: red reserved for genuine risk) */
  --sq-positive:         #2F6B4F;   --sq-positive-bright: #62B58C;
  --sq-warning:          #855A12;   --sq-warning-bright:  #E0B45F;   /* light is AA-safe */
  --sq-risk:             #A3302A;   --sq-risk-bright:     #E8786F;
  --sq-positive-bg:      #E4EDE5;   --sq-warning-bg:      #F1E7CF;   --sq-risk-bg: #F3DFDB; /* light soft tints */

  /* info / selection / focus: muted slate-blue (GH-625 Q1; DD-003 in-charter).
     AA-checked (light #3C5A74 = 6.58:1 on paper; dark #8AAEC9 = 8.44:1 on ink). */
  --sq-slate:            #3C5A74;   --sq-slate-bright:    #8AAEC9;

  /* matching-interaction row-highlight FILLS — MODE-STABLE light islands (GH-630):
     in dark mode the selected row keeps this light fill + flips to island text
     (--color-on-selection-* below) so it LIFTS off the ink rather than going dark-on-dark. */
  --sq-anchor:           #BEE3DE;   /* teal — the row being matched FROM (anchor) */
  --sq-candidate:        #CFD3F2;   /* indigo — candidate / selected partner row */

  /* type families (DD-009) */
  --sq-font-serif: 'Spectral', Georgia, 'Times New Roman', serif;
  --sq-font-ui:    'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --sq-font-mono:  'IBM Plex Mono', 'SF Mono', 'Cascadia Code', Consolas, monospace;
}


/* ============================================================================
   TIER 2 — SEMANTIC TOKENS (--color-*) — LIGHT (default)
   What templates + tailwind.config consume. Each references a Tier-1 primitive.
   ============================================================================ */
:root {
  /* surfaces */
  --color-page:            var(--sq-paper-deep);
  --color-surface:         var(--sq-paper);
  --color-surface-stripe:  var(--sq-white);
  --color-hairline:        var(--sq-hairline);
  --color-row-rule:        #ECE4D3;                                      /* GH-669 per-row "ledger rule" (light; consistency w/ dark) */
  --color-hover:           #EDE9DF;                                      /* static fallback */
  --color-hover:           color-mix(in srgb, #211E17 5%, var(--color-surface));  /* row/control hover (GH-630): subtle ink-over-surface */
  --elevation-card:        none;                                         /* light cards lift via border, not shadow (GH-711) */

  /* text */
  --color-text:            #211E17;
  --color-text-2:          #6B6354;

  /* brand */
  --color-primary:         var(--sq-forest);
  --color-accent:          var(--sq-bronze);

  /* chrome — light spine; stays GREEN in dark too (DD-015 dropped the DD-011 inversion) */
  --color-chrome:          var(--sq-forest-spine);
  --color-chrome-logo:     var(--sq-logo-cream);
  --color-tray:            var(--sq-parchment-tray);

  /* status — hue + soft background tint (for badges/alerts/bands) */
  --color-positive:        var(--sq-positive);    --color-positive-bg: var(--sq-positive-bg);
  --color-warning:         var(--sq-warning);     --color-warning-bg:  var(--sq-warning-bg);
  --color-risk:            var(--sq-risk);        --color-risk-bg:     var(--sq-risk-bg);
  --color-info:            var(--sq-slate);
  --color-info-bg:         #E1E2DE;  /* static fallback for engines without color-mix() */
  --color-info-bg:         color-mix(in srgb, var(--sq-slate) 12%, var(--sq-paper));  /* derived slate tint */

  /* GH-630: SOLID status fills for loud/active controls (e.g. active match-status
     filter pills). Deliberately mode-STABLE (the dark light-mode hues, NOT the
     bright dark-mode variants) so `--color-on-status` (white) stays legible in both
     modes — a flipping solid would put white on a light hue. Distinct from the soft
     `*-bg` tints above (badges/bands). */
  --color-positive-solid:  var(--sq-positive);
  --color-warning-solid:   var(--sq-warning);
  --color-risk-solid:      var(--sq-risk);
  --color-info-solid:      var(--sq-slate);
  --color-on-status:       #FFFFFF;

  /* GH-630: INVERSE neutral surface — high-emphasis selected controls (active
     "all" filter), toasts, tooltips. Flips by mode (.dark below) so it always
     contrasts the page. `inverse` is the surface, `on-inverse` the text. */
  --color-inverse:         #211E17;
  --color-on-inverse:      var(--sq-paper);

  /* secondary hairline (softer inner rules, e.g. table rows) */
  --color-hairline-2:      var(--sq-hairline-2);

  /* matching-interaction row highlights (reconciliation surfaces) */
  --color-anchor:          var(--sq-anchor);      /* the row being matched FROM */
  --color-candidate:       var(--sq-candidate);   /* its candidate matches */

  /* GH-711: dark-mode "light island" CONTENT tokens (mode-stable, defined once).
     The selected-row FILL is --color-anchor/-candidate (light, mode-stable); these
     give its TEXT + STATUS the matching light values so base.html touches only
     --color-* (no raw --sq-* leak). 2 carry design value (text/-2); the rest are
     pass-through aliases of the kept palette, needed in dark because the .dark
     status hues are the -bright variants, which are wrong on a light fill. */
  --color-on-selection-text:        #211E17;
  --color-on-selection-text-2:      #6B6354;
  --color-on-selection-hairline:    var(--sq-hairline-2);
  --color-on-selection-risk:        var(--sq-risk);      --color-on-selection-risk-bg:     var(--sq-risk-bg);
  --color-on-selection-warning:     var(--sq-warning);   --color-on-selection-warning-bg:  var(--sq-warning-bg);
  --color-on-selection-positive:    var(--sq-positive);  --color-on-selection-positive-bg: var(--sq-positive-bg);

  /* GH-676: the row whose detail is open in the bottom drawer. Side-keyed so the
     ring hue ties the row to its drawer side (bank→info, book→primary). Aliases
     resolve live, so they track the underlying token across light/dark AND a theme
     can re-point them independently of --color-info / --color-primary. */
  --color-row-open-bank:   var(--color-info);
  --color-row-open-book:   var(--color-primary);

  /* chrome sub-parts (sidebar/topbar); dark values are literals in .dark (DD-015, no inversion) */
  --color-chrome-edge:     var(--sq-chrome-edge);
  --color-chrome-hover:    var(--sq-chrome-hover);
  --color-chrome-ink:      var(--sq-chrome-ink);
  --color-chrome-ink-2:    var(--sq-chrome-ink-2);

  /* affordances */
  --color-focus:           var(--sq-slate);          /* keyboard focus / selection ring */
  --color-scrim:           rgb(0 0 0 / 0.40);         /* modal/overlay backdrop */
}


/* ============================================================================
   TIER 2 — DARK MODE RE-BIND (.dark)
   Only the semantic bindings change; primitives are constant. Toggled by the
   `.dark` class on <html> (base.html preload script + localStorage 'sq-dark').
   ============================================================================ */
/* ── DARK = modern-ledger "IRON GALL" (GH-711). The surface is the INK the ledger
   is written in — a cool desaturated blue-black — not a dimmed material. The ledger
   identity survives via four things: green BINDING (chrome, NO parchment inversion —
   supersedes DD-011), brightened GILT, Spectral SERIF numerals, and small PARCHMENT
   accents (action tray, inverse island). Iron Gall dark values that aren't reused
   are LITERALS here (no mode-named primitives). Supersedes DD-010 (neutral charcoal). ── */
.dark {
  /* surfaces — iron-gall ink */
  --color-page:            #10141B;   /* deepest ink (page) */
  --color-surface:         #1A2029;   /* lifted cards / panels / topbar */
  --color-surface-stripe:  #2A3340;   /* alt-row stripe — CALIBRATED (GH-669): row→stripe gap
                                         ~0.017 clears the ~0.005-0.01 monitor flare floor; the
                                         old #23271F gave ~0.005 (muddy/invisible). */
  --color-hairline:        #2B333F;   /* card/panel edges (cool, structural) */
  --color-row-rule:        #232A33;   /* GH-669 per-row soft hairline (cool); pairs with stripe */
  --color-hover:           #232A35;                                      /* static fallback */
  --color-hover:           color-mix(in srgb, #E8ECEF 7%, var(--color-surface));  /* hover lightens ink */

  /* text — cool warm-white ink */
  --color-text:            #E8ECEF;
  --color-text-2:          #A2A9B2;

  /* brand — primary stays bright forest; accent is gilt (brightened for ink) */
  --color-primary:         var(--sq-forest-bright);
  --color-accent:          #D8B36A;   /* gilt */

  /* chrome — NO inversion: binding stays GREEN in dark (Iron Gall; supersedes DD-011) */
  --color-chrome:          #16352A;   /* forest binding, dark value */
  --color-chrome-logo:     var(--sq-logo-cream);
  --color-tray:            var(--sq-parchment);     /* parchment accent kept for the action tray */

  /* status — bright hue + dark ink-tinted band; positive shifts cooler on ink */
  --color-positive:        #5CC0A0;                   --color-positive-bg: #15302A;
  --color-warning:         var(--sq-warning-bright);   --color-warning-bg:  #2C2815;
  --color-risk:            var(--sq-risk-bright);      --color-risk-bg:     #2C1C20;
  --color-info:            var(--sq-slate-bright);
  --color-info-bg:         #1E2A33;  /* static fallback for engines without color-mix() */
  --color-info-bg:         color-mix(in srgb, var(--sq-slate-bright) 16%, var(--color-surface));

  /* solid status fills + --color-on-status are NOT re-declared — they keep their
     mode-stable :root values so white text stays legible (GH-630). */

  /* GH-676: row-open ring tracks the dark side hues via the live --color-* aliases. */
  --color-row-open-bank:   var(--color-info);
  --color-row-open-book:   var(--color-primary);

  /* inverse / islands — PARCHMENT (the surviving paper accent): active tab, toasts, tooltips */
  --color-inverse:         var(--sq-parchment);
  --color-on-inverse:      #10141B;

  /* secondary hairline = the warm faint GILT "ledger rule" (totals / section rules) */
  --color-hairline-2:      #26241B;

  /* anchor/candidate FILLS are NOT re-declared — they stay the light island fill; the
     row's TEXT/STATUS flip via --color-on-selection-* in the base.html island rule. */

  /* chrome sub-parts — on the green binding (cream ink, deep forest edges) */
  --color-chrome-edge:     #0F2A20;
  --color-chrome-hover:    #1E4434;
  --color-chrome-ink:      #D6E0D2;
  --color-chrome-ink-2:    #7C9082;

  --color-focus:           var(--sq-slate-bright);
  --color-scrim:           rgb(0 0 0 / 0.62);          /* deeper scrim on ink */

  /* card elevation — lift the work off the ink (light is `none`) */
  --elevation-card:        0 4px 16px rgb(0 0 0 / 0.50), inset 0 1px 0 rgb(255 255 255 / 0.045);
}


/* ============================================================================
   NON-COLOR SCALES — mode-agnostic (:root only)
   These are the "look + feel + density + dimensions" ceiling (plan D3).
   All DEFINE-ONLY here. Stage 3 (tailwind.config) MAY reference radius/type/
   elevation verbatim (zero visual change). Spacing/density and most dimensions
   are NOT wired into Tailwind's core utilities — doing so would repaint every
   p-/m-/gap- across all 46 templates (a global-wiring repaint, plan D5). They
   activate per-component in Phase 5.
   ============================================================================ */
:root {
  /* — type scale (verbatim: existing dense core + Spectral/ALTA display steps) — */
  --text-2xs:  0.65rem;    /* load-bearing density size (116 usages) */
  --text-xs:   0.75rem;
  --text-sm:   0.875rem;
  --text-base: 1rem;
  --text-lg:   1.125rem;
  --text-xl:   1.25rem;
  --text-2xl:  1.5rem;     /* display steps — Spectral headings / ALTA numbers */
  --text-3xl:  1.875rem;
  --text-4xl:  2.25rem;

  /* — radius (verbatim current Tailwind values; Direction A tuning = Phase 5) — */
  --radius-sm:   0.25rem;  /* "rounded" DEFAULT (107 usages) */
  --radius-md:   0.375rem;
  --radius-lg:   0.5rem;
  --radius-xl:   0.75rem;
  --radius-pill: 9999px;   /* "rounded-full" */

  /* — elevation (verbatim Tailwind shadow values; Direction A ladder tuned Phase 5) — */
  --elevation-0:  none;
  --elevation-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --elevation-md: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --elevation-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  --elevation-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);

  /* — density knob (D3): 1 = comfortable (default). Phase-5 components compute
       padding as calc(base * var(--density)); compact mode sets ~0.875. Defined
       here as the single lever; per-component spacing tokens land with their
       components in Phase 5 (not fabricated speculatively now). — */
  --density: 1;

  /* — layout dimensions. AUTHORITATIVE as of GH-627 R1: base.html drives the
       sidebar width from these tokens via the data-sq-collapsed attribute (CSS,
       not JS pixel literals). Change the width here and the shell follows. — */
  --size-sidebar:           14rem;     /* expanded */
  --size-sidebar-collapsed: 3.5rem;    /* collapsed */
  --size-shell-min:         1280px;    /* shell min-width (was min-w-[1280px]) */
  --size-gutter:            1rem;      /* surface gutter between framed panes (design.md) */
  --size-drawer:            260px;     /* GH-676: docked transaction-detail drawer height.
                                          page.html caps it at min(var(--size-drawer), 40vh)
                                          so short viewports degrade gracefully. */
}
