/* COLOR — sampled directly from the True North mark.
   Forest pine + copper ridge-faces + antique-gold star, on warm cream.
   Base palette first, then semantic aliases. Use the aliases in components. */
:root {
  /* ---- Base: greens ---- */
  --tnb-pine: #2F4A30;        /* primary brand green (logo facets) */
  --tnb-pine-deep: #26402A;   /* darker surface / dark backgrounds */
  --tnb-pine-darker: #20351F; /* deepest panel (honest-take wells) */
  --tnb-pine-live: #7fae7f;   /* "live/fresh" green — ON DARK ONLY (freshness dot, data-type post marker). Fails as text on paper. */

  /* ---- Base: warm accents ---- */
  --tnb-copper: #B97A4E;      /* base copper — borders/badges/large-bold ONLY (3.07:1, fails body text) */
  --tnb-copper-dk: #985A33;   /* copper TEXT on light/paper — links, eyebrows, labels (4.76:1 ✅ WCAG 1.4.3) */
  --tnb-copper-light: #C99268;
  --tnb-gold: #C0A368;        /* antique gold — the star, fine lines (fill-only on light) */

  /* ---- Base: neutrals (warm) ---- */
  --tnb-ink: #1B1A12;         /* near-black, warm (wordmark) */
  --tnb-paper: #F4EFE3;       /* warm cream page */
  --tnb-sand: #E6DCC6;        /* tint / data-tag fill */
  --tnb-white: #ffffff;       /* card surface */
  --tnb-stone-700: #33392f;   /* body text on light */
  --tnb-stone-500: #6f6a60;   /* muted text */
  /* NOTE: WCAG AA (4.5:1 on white/paper) squeezes the light-grey text tiers into a
     razor band, so 300 and 400 collapsed to one value (2026-07-06). They read as a
     single "faint label" tone now; use stone-500 when you want a step darker. */
  --tnb-stone-400: #706b61;   /* faint label text — AA on white/paper (was #8a857a, 3.2:1) */
  --tnb-stone-300: #706b61;   /* = stone-400 (collapsed for AA; was #9a948a, 3.0:1) */

  /* ══ ⛔ THE SAND RULE — no MUTED token is legible on sand. This is structural, not a
     coincidence, and it has now been discovered three times because it was never written down.
     Sand costs ~0.7:1 against paper, and every muted token clears 4.5 on paper by <0.3 — so the
     whole muted tier lands under AA the moment it sits on the tint:

                    white   paper   sand
        stone-500    5.38    4.69   ⛔3.95
        stone-400/300 5.30   4.62   ⛔3.89
        copper-dk    5.46    4.76   ⛔4.01
        stone-700   11.88   10.36     8.72  ✅
        ink         17.45   15.21    12.81  ✅
        pine         9.80    8.54     7.19  ✅

     ON SAND, USE: ink · stone-700 · pine · or an explicit `-on-sand` variant below.

     THIS WAS ALREADY KNOWN, AND THAT IS THE POINT. The 2026-07-06 WCAG sweep (BACKLOG QA-008)
     states it almost verbatim — "#e6dcc6 is dark enough that even copper-dk/stone-500 fell to
     ~3.9–4.0:1" — and then fixed it as an ENUMERATED LIST of the sand containers that existed
     that day (.about-band--sand · .quickanswer · .lane-strip · .ctable thead · .disambig · .nap),
     plus one token. A list cannot cover a container invented later, so the .ig-node kit (ADR-0016,
     ten days on) walked straight back in and shipped 3.95:1 on the two labels carrying its
     graphic's meaning. Nothing caught it: axe-core went in as a devDep "so the audit is
     re-runnable" and NO RUNNER WAS EVER WRITTEN (FEEDBACK #30 — a gate with no callers is a
     document). Enumerating what you know and skipping the rest is FEEDBACK #31, and this is its
     fourth sighting: copper-dk (tokenised) → .ctable thead th (an override parked ~690 lines from
     the rule it rescues) → the QA-008 container list → .ig-node.
     So this is written as a RULE, not a list, and `tokens-contrast.test.js` runs on every
     `pnpm test` — it asserts every ratio printed above to ±0.01 against the real hex values, so
     the table cannot rot, and it asserts the muted tier still FAILS on sand: if a palette change
     ever made it pass, the test breaks and someone re-reads this rule instead of inheriting it
     blindly.
     ⚠️ KNOW WHAT THAT TEST DOES *NOT* COVER, or it becomes the next false assurance: it gates
     token VALUES, and all four failures above were USAGES — nobody ever changed a hex, they
     painted a muted token onto a sand surface. A fifth component doing exactly that passes
     `pnpm test` green. Reading the RENDERED page is the only thing that catches it, and that
     runner is BACKLOG QA-008, still open. Until it exists, this rule's enforcement is a human
     reading this comment. ══ */
  --tnb-copper-dk-on-sand: #854e2b;  /* copper-dk fails on the sand tint (4.0:1); this passes (4.94:1). Do NOT use copper-dk as text on sand. */
  --tnb-stone-500-on-sand: #635E55;  /* stone-500 fails on the sand tint (3.95:1); this passes (4.73:1). Do NOT use stone-500/400/300 as text on sand. */
  --tnb-line: #E3DBCB;        /* hairline border — decorative dividers only (1.2:1, NOT for control boundaries) */
  --tnb-line-control: #8a857a; /* control/input border — 3.1:1 on paper for WCAG 1.4.11 non-text contrast */
  --tnb-line-soft: #ECE6DA;   /* softer hairline / dividers */

  /* ---- On-dark tints (text over pine) ---- */
  --tnb-on-dark: #F4EFE3;
  --tnb-on-dark-muted: #9fb0a4;   /* sage, for meta on dark */
  --tnb-on-dark-cream: #d9cfbb;   /* warm body on dark */

  /* ---- Semantic aliases ---- */
  --color-bg: var(--tnb-paper);
  --color-surface: var(--tnb-white);
  --color-surface-tint: var(--tnb-sand);
  --color-surface-dark: var(--tnb-pine-deep);
  --color-surface-darker: var(--tnb-pine-darker);

  --color-text: var(--tnb-stone-700);
  --color-text-strong: var(--tnb-ink);
  --color-text-muted: var(--tnb-stone-500);
  --color-text-faint: var(--tnb-stone-300);

  --color-primary: var(--tnb-pine);
  --color-accent: var(--tnb-copper);
  --color-accent-text: var(--tnb-copper-dk);   /* copper accent as readable text on light (WCAG-safe) */
  --color-accent-fine: var(--tnb-gold);

  --color-border: var(--tnb-line);
  --color-border-soft: var(--tnb-line-soft);

  --color-data: var(--tnb-pine);            /* number text */
  --color-data-bg: var(--tnb-sand);         /* data-tag fill */
}
