/* ============================================================================
 * revenant-ds.css — REVENANT / RECKON DESIGN SYSTEM (brand-specific extension).
 *
 * CONSOLIDATED (2026-08-24) onto the ecosystem-wide canonical file:
 * foundry/_shared/ds/global-tokens.css (D0 · "Land global-tokens.css +
 * Reckon→Revenant branding sweep"). That file now OWNS the shared mermaid-jewel
 * default (--paper/--ink/--accent triplet), the amber-vintage legacy skin, the
 * RetroFuture brand block, the one shared dark theme, the 5 jewel accents, and
 * the 6 font pairings — imported below rather than re-declared here.
 *
 * astro-retrofuture/public/vendor/css/revenant-ds.css is a SYMLINK to this file
 * (Astro's public/ dir is served statically, so the on-disk symlink keeps
 * `/vendor/css/revenant-ds.css` resolving with zero consumer changes).
 * revenant-proof-v2/main.jsx and revenant-proof-v1/src/main.jsx import this
 * path directly (bundled, not statically served, so no symlink needed there).
 * Do not hand-edit a copy; there is only this one file.
 *
 * WHAT THIS FILE STILL OWNS (kept — canonical does not cover these; they are
 * REVENANT-specific component/legacy-alias needs, not brand-identity colors):
 *   --accent-glow, --accent-fill/--on-accent-fill (the fill/ink pair bound
 *     together so the documented `background: var(--color-accent); color:
 *     var(--on-accent)` pairing stays legal — see the note below, kept
 *     verbatim from the 2026-07-29 contrast-fix investigation),
 *   --bronze/--sienna (legacy jewel aliases some call sites still read),
 *   --font-callout, --radius-*, --shadow-hard, --surface-2, --on-accent,
 *   --color-success-ink, --text/--muted/--rule (aliases the custody-proof
 *     widget already consumes),
 *   the helper classes .revenant-wordmark / .rv-brutal / .rv-rail / .ds-crumb
 *     (+ .ds-crumb-sep), the forest-metaphor --ds-leaf-.../--ds-bark-...
 *     /--ds-root-.../--ds-withered palette, and the page body ground rule.
 * ========================================================================== */

/* Same-directory import (NOT a repo-relative path): revenant-ds.css is BOTH
   bundled directly (revenant-proof-v1/v2 main.jsx, disk-relative resolution
   is fine there) AND served raw as a static file via the astro-retrofuture
   public/ symlink — a browser resolves this @import relative to the
   REQUESTED URL (/vendor/css/revenant-ds.css), not this file's location on
   disk. So a repo-relative '../../runtime/...' path 404s once deployed. Fix:
   a sibling global-tokens.css symlink lives next to this file in BOTH
   locations (brand/rev-design-system/global-tokens.css and
   .../public/vendor/css/global-tokens.css), each pointing at the one
   canonical foundry/_shared/ds/global-tokens.css — so './unified-
   tokens.css' resolves correctly in every context this file is loaded from. */
@import url('./global-tokens.css');

/* Brand fonts — IM Fell English (display/logo), EB Garamond (body), Jost (ui),
   Courier Prime (mono). Same faces reckon loads. SELF-HOSTED, zero CDN: the
   @font-face rules live in public/vendor/fonts/fonts.css (loaded from index.html),
   generated by scripts/vendor-fonts.mjs. The Google-Fonts @import was removed
   because the strict CSP blocks the CDN (networkidle hangs; faces fall back). */

:root {
  /* --accent-glow — now keyed to --accent which changes per theme/brand, never a fixed hex */
  --accent-glow:    rgba(10,112,82,0.24);  /* TODO: compute dynamically from --accent + rgba() */

  /* ── THE FILL/INK PAIR — bound together, never chosen from two sources ──
     MEASURED 2026-07-29 (lane rev-spa-apk-devil-audit): the DOCUMENTED pair
     `background: var(--color-accent); color: var(--on-accent)` is ILLEGAL on the
     live theme. `--on-accent` is #FFFFFF, derived ONCE globally; `--color-accent`
     measures #0E9E96 in the running app and is additionally OVERRIDDEN PER ROUTE
     (?view=vigil reskins it to amber). White on #0E9E96 = 3.31:1 — under the 4.5:1
     body floor. Eight call sites across six stylesheets used that exact pair
     (app.css, CorpusReader, KeyPackage, StoryWeave ×2, SystemMap, Whitepaper ×2),
     so this was never one component's bug.

     app.css:565 already diagnosed the CLASS of defect — "a fill and an ink chosen
     from two different sources" — and fixed ONE rule (.rp-nav-tab) by hand-binding
     it to --accent-dk. That fix was correct and unscalable: it left the TOKEN PAIR
     itself broken, so the next author who writes the documented pair reintroduces
     the failure without violating any rule.

     These two tokens ARE the pair, and are only ever used together. --accent-fill
     is pinned to the DARK end of the ramp — the end that can carry white ink — so a
     route may recolour --color-accent freely without touching this pair's legality.
     White on #06563E = 8.72:1. Defined once, so the next accent change is checked
     once instead of eight times. */
  --accent-fill:    var(--accent-dk, #06563E);
  --on-accent-fill: #FFFFFF;
  /* Legacy jewel aliases — now point at named tokens instead of hex */
  --bronze:         var(--garnet);       /* alias of garnet, was #7B2233 */
  --sienna:         var(--sapphire);     /* alias of sapphire, was #1E4E8C */

  --font-callout:   'IM Fell English SC', 'IM Fell English', Georgia, serif;

  --shadow-hard:    4px 4px 0 var(--ink);   /* funky brutalist offset block */

  /* ── Aliases → the var names the custody-proof widget already uses ─ */
  --surface-2:      var(--paper-deep);
  /* ON-ACCENT — the ink that goes ON TOP of a filled accent. CONSUMED in several places
     (Whitepaper.css, CustodyExplorer.css) and DEFINED NOWHERE until now: an undefined
     custom property does not fall back to a var()'s default when it resolves to an
     invalid value, so a button styled `color: var(--on-accent, #FFF)` rendered BLACK on
     dark emerald — 2.41:1 — while every rule looked correct. Measured 2026-07-29. */
  --on-accent:      #FFFFFF;
  /* Success as SMALL TEXT. --color-success is a FILL weight and measured 4.35:1 on the
     pale mint ground — under the 4.5 needed for normal text. */
  --color-success-ink: #1A5E33;
  --text:           var(--ink);
  --muted:          var(--ink-light);
  --rule:           1px solid var(--accent);
}

/* Page ground — parchment, ink-on-paper. */
body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
}

/* ── The REVENANT wordmark — IM Fell English, the reckon logo face ──────── */
.revenant-wordmark {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0.01em;
  color: var(--ink);
  line-height: 1;
}
.revenant-wordmark em,
.revenant-wordmark .rv-swash {
  font-style: italic;      /* IM Fell English italic carries genuine swashes */
  color: var(--color-accent-ink);
}
/* Small-caps callout variant (section headers, "VERIFIED WORK RECORD" etc.) */
.revenant-callout {
  font-family: var(--font-callout);
  letter-spacing: 0.04em;
  color: var(--ink-mid);
}

/* Brutalist funky card treatment — hard gold border + hard offset shadow.
   Opt-in: add class="rv-brutal" to any panel that should read as a stamped
   record rather than a soft card. */
.rv-brutal {
  background: var(--surface-raised);
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-hard);
}

/* ── DS RULE: sticky rail beside content, STATIC when the layout stacks ──────────────────────
   A "rail" (controls sidebar, filter column, tunables panel) is `position: sticky` ONLY while it
   sits BESIDE the content in a multi-column grid. The moment the grid collapses to ONE column
   (mobile / narrow), the rail stacks ABOVE the content — and its containing block becomes the
   full-height grid, so a sticky rail would pin itself over the copy that scrolls beneath it,
   leaving BOTH unreadable (the exact bug fixed on the scaling page). So: sticky above the stack
   breakpoint, static below it. Any collapsing-grid sidebar in this system must use `.rv-rail`
   (or mirror the rule) rather than a bare `position: sticky` — that is the design-system default.
   --rv-stack-bp documents the breakpoint (900px) the grid collapses at; keep the @media in sync.
   -------------------------------------------------------------------------------------------- */
:root { --rv-stack-bp: 900px; --rv-rail-top: 12px; }
.rv-rail { position: sticky; top: var(--rv-rail-top); align-self: start; }
@media (max-width: 900px) { .rv-rail { position: static; top: auto; } }

/* ── DS RULE: page identity lives INLINE WITH THE WORDMARK — never a second header bar ────────
   The nav shows the brand wordmark and, right beside it, the CURRENT PAGE — same face, same size,
   joined by a hairline "·". A page does NOT get its own title bar; "where am I" is answered once,
   in the logo row. The page name is the display face in accent ink so it reads as the page, not
   the brand. Apply `.ds-crumb` to the inline page name (the app's `.rp-nav-page-name` is this
   pattern). A live/status dot may sit before it. Enforced across REVENANT + reckon fronts.
   ------------------------------------------------------------------------------------------- */
/* The separator is an elegant vertical RULE (not a glyph) — a hairline between wordmark + page. */
.ds-crumb-sep { width: 2px; height: 1.05em; flex: none; border-radius: 1px; background: var(--border); align-self: center; }
.ds-crumb {
  font-family: var(--font-display); font-weight: 400; font-style: italic;
  letter-spacing: 0.01em; line-height: 1; color: var(--accent-dk, var(--accent));
  /* size EQUAL to the wordmark it sits beside — both use ONE fluid clamp(), never a smaller step */
}

/* ── Forest-metaphor palette — EXTENDS the DS, does not replace it ──────────────────────────────
 * Added for the Merkle leaf/branch/trunk/tree/forest explainer family (charter
 * merkle-forest-w3m-living-ledger). This is a NAMED, DURABLE token set — any future page that
 * draws the leaf/branch/trunk/tree/forest metaphor reuses these tokens and the reusable shape
 * generators in viz/forest-metaphor-kit.js, rather than re-deriving a one-off palette.
 *
 * Token → concept mapping (the metaphor is LITERAL, not abstract bars/charts):
 *   --ds-leaf-hunter    → deep foliage shading / leaf outline — the OLDER, settled growth of a tree
 *   --ds-leaf-emerald   → the living leaf body fill — a COC entry, freshly unfurled
 *   --ds-leaf-emerald-soft → pale canopy/foliage wash for backgrounds behind leaf clusters
 *   --ds-bark-pinecone  → trunk + branch stroke — the chain STRUCTURE a leaf attaches to
 *   --ds-bark-pinecone-dk → deeper bark shade (trunk base / shadow side of a branch)
 *   --ds-root-garnet    → the RARE, precious verification accent — a valid signature / the forest
 *                         root (canopy) glows garnet on update; this is the one color reserved for
 *                         "cryptographically confirmed," never used decoratively elsewhere
 *   --ds-root-garnet-soft → pale garnet wash for a root/canopy card background
 *   --ds-withered       → an INVALID / rejected leaf — desaturated, drooping, dead-leaf brown-gray;
 *                         the visual opposite of --ds-root-garnet (confirmed vs. refused)
 * All eight are tuned as separate light/dark pairs (not just an opacity shift) so the metaphor
 * reads with equal warmth in both themes. Extend this block — do not fork a second palette.
 * ------------------------------------------------------------------------------------------- */
:root {
  --ds-leaf-hunter:        #2f5d46;
  --ds-leaf-emerald:       #1f9d6b;
  --ds-leaf-emerald-soft:  #d8f2e6;
  --ds-bark-pinecone:      #5c4433;
  --ds-bark-pinecone-dk:   #3e2d21;
  --ds-root-garnet:        #7b2233;
  --ds-root-garnet-soft:   #f3dde1;
  --ds-withered:           #8a7a63;
}
/* This forest-metaphor palette stays IDENTICAL in light and dark (the metaphor's colors
   are not theme-dependent) — kept as an explicit pair rather than relying on inheritance,
   per the 2026-08-09 "dark mode is illegal on retrofuture" ruling that predates the
   canonical unify pass. NOTE (2026-08-24): global-tokens.css's own [data-theme="dark"]
   block is now explicitly sanctioned for ANY brand, RetroFuture included ("this palette
   is its own dark identity matured") — so paper/ink/accent DO now have a real dark
   variant via the @import above. That is the intended, current state; only this
   eight-token forest palette is deliberately pinned flat across both. */
:root[data-theme="dark"],
:root[data-theme="light"] {
  --ds-leaf-hunter:        #2f5d46;
  --ds-leaf-emerald:       #1f9d6b;
  --ds-leaf-emerald-soft:  #d8f2e6;
  --ds-bark-pinecone:      #5c4433;
  --ds-bark-pinecone-dk:   #3e2d21;
  --ds-root-garnet:        #7b2233;
  --ds-root-garnet-soft:   #f3dde1;
  --ds-withered:           #8a7a63;
}
