/* ============================================================
   ArchiOSK / B-Hive — Design Tokens

   The ONE controlled place for the visual character of the whole
   application: color, typography, spacing/density. Every other CSS
   file (main.css) and every template's inline style should reference
   these custom properties, never hardcode a raw hex/rem value that
   duplicates what a token already names - a value typed twice always
   drifts eventually (0.85rem/0.82rem/0.88rem all meant "small
   secondary text" before this file existed and consolidated them).

   Governing principle: tonal contrast first, chromatic contrast
   second. The interface is dominated by one quiet family of warm
   architectural neutrals (sand cotton canvas, alabaster/limestone
   surfaces, basalt-ink text). Color appears rarely, and only where
   it carries real information - the token NAMES below are what
   protect that discipline. They are named for MEANING (--seal-red,
   --machine-blue), never for raw appearance (no --red-500,
   --blue-3) - that is what stops a future "arbitrary styling" pass
   from quietly repainting human authority the same color as machine
   inference just because they happen to look similar. Add a new
   semantic color only when a new kind of information genuinely needs
   distinguishing, never as decoration:
     --bee-yellow   the BEEHIVE identity mark only (icon-level,
                    never spread across buttons/nav/cards)
     --seal-red     human authority / deliberate commitment - the
                    moment a consequential, approval-gated action is
                    taken (Apply, Issue RFI, an Approval Gate "Yes"),
                    never ordinary error/failure
     --machine-blue machine/system/reference (focus rings, links,
                    machine-generated Finding markers) - also given a
                    literal second life as the blueprint-grid backdrop
                    line, since this product's own visual metaphor
                    (a blueprint) is properly blue, not sand
     --highlight-orange the one current/active position in a lifecycle
                    or sequence - narrow and singular by design, not a
                    general-purpose "selected" color (ordinary list/nav
                    selection stays tonal)
     --accepted-green   accepted / confirmed
     --attention-amber  needs evidence / pending attention
     --failure-red      contradiction / failure - distinct from the
                    deeper --seal-red authority accent

   Type: Arial Nova Condensed (display + body) - condensed is the
         visual character; light weight where text is large enough to
         stay comfortably readable at that weight, regular weight
         everywhere else. IBM Plex Mono stays the mono/technical-
         register font - the prose-vs-identifiers/paths/logs
         distinction is load-bearing elsewhere. Arial Nova ships with
         Windows 11 / Microsoft 365; Arial Narrow and Arial are the
         condensed-then-plain fallback for systems without it.

   Named profiles/modes later (dark theme, a denser or roomier
   density, a high-contrast mode): a NEW file like this one,
   redefining these same token names with different values, swapped
   in base.html's <link> for whichever one is active - main.css and
   every template stay completely unchanged, because they only ever
   reference the names, never a raw value. Don't add a --density-scale
   calc() indirection or any other multi-mode machinery ahead of an
   actual second mode existing - that's solving a problem this project
   doesn't have yet. Verify any new or changed color pairing with
   tools/check_contrast.py before shipping it - contrast here is a
   floor, not a target (see --text-metadata below), and that discipline
   should survive a future palette change too, not just this one.
   ============================================================ */
:root {
    /* -- material scale (CLAUDE-POSTCAMEL-P02-ST1: Titanium) --------------
       This surface (the mode still internally identified as "light" -
       ref_suffix/mode_value unchanged, see base.html's own Appearance-
       matrix comment on why a label revision never renumbers the
       underlying choice) was originally a warm sand/parchment family
       (hue ~38-42deg, named Sand Cotton/Alabaster/Limestone/Desert
       Dust). Product-owner direction: replace it with a restrained,
       precise, premium-instrument "Titanium" character. A first pass
       kept the original warm hue anchor at lower saturation - live-
       browser review found that still read as parchment/sandstone, not
       titanium. Corrected to a genuinely COOL, near-neutral grey/steel/
       graphite family (hue anchor now ~200-210deg, a whisper of cool
       rather than the prior warm ~38-42deg) - no faux sheen, shine,
       chrome, reflection, or metallic texture anywhere (Surface Trust's
       own "borrow the principle - restraint, coherence, precision -
       never the literal skin"). A third pass widened the surface steps
       themselves (canvas/surface-primary unchanged - "do not darken the
       entire theme" - but surface-secondary/-hover/-selected/border/
       border-strong re-spaced into clearer, more evenly-graduated flat
       steps) so panel/nav/selected-row boundaries read as distinct
       machined layers instead of blurring into one another. A fourth
       pass then found the resulting surface was still too FAINT in its
       foreground, not its surface: text-secondary/-metadata/-disabled
       were all substantially darkened (text-primary was already dark
       enough) so labels, counts, placeholder/help copy, and menu text
       are comfortably legible in normal use, not merely AA-legal. A
       fifth pass, benchmarked explicitly against a familiar high-
       contrast light UI (ChatGPT's light theme) rather than a numeric
       floor, found even the fourth pass's values still read as "gray
       text on gray surfaces" at normal viewing distance - technically
       AA-legal is not the same as effortlessly readable. text-secondary/
       -metadata/-disabled were darkened again, materially closer to
       text-primary than before, so the app now leans on genuinely dark
       ink for anything a user actually reads, reserving lighter gray
       only for the truly decorative/disabled case - most pairings below
       clear 7:1+ (AAA), not just the 4.5:1 (AA) floor. text-primary's
       relationship to canvas is still what produces the letterpress/
       ink-on-metal quality - the single most load-bearing contrast
       pairing in the app, verified via tools/check_contrast.py and the
       full per-surface matrix in
       tests/test_p40vw8qa_theme_foreground_contrast.py after every one
       of these passes, unchanged in kind throughout. */
    --canvas: #EFF0F0;            /* Titanium Gray (lightest) - main app background */
    --surface-primary: #F8F9F9;   /* Titanium White - panels, cards, dialogs */
    --surface-secondary: #D8DADB; /* Steel Gray (mid) - nav surfaces, grouped controls */
    --surface-hover: #C6C8CA;     /* Steel Gray (hover) */
    --surface-selected: #BABCBE;  /* Steel Gray (deeper) - selected / current */
    --border: #8A8D8F;            /* Graphite (border) - quiet dividers, strengthened for clarity */
    --border-strong: #737679;     /* structural border where clarity is needed */
    /* Readability is the floor, not the target - every text token below
       is deliberately darker than WCAG AA's 4.5:1 minimum, not tuned to
       just clear it. --text-metadata must stay strictly quieter (lower
       contrast against --surface-primary) than --text-secondary
       (tests/test_p40vw8qa_theme_foreground_contrast.py's
       test_metadata_tier_still_visibly_dimmer_than_secondary_tier) even
       as both get darkened for readability - "quieter" is a relative,
       not absolute, requirement. --text-disabled (placeholder/help/
       disabled-control copy) is not covered by that ordering test but
       was darkened the most of the four in this pass - it had drifted
       faint enough in live use (~3-4:1 against panels) to read as
       nearly invisible, which is a readability defect even where a
       disabled/placeholder role would otherwise tolerate lower
       contrast. */
    --text-primary: #191B1C;      /* Graphite Ink - near-black */
    --text-secondary: #26282B;    /* Graphite Ink (secondary) - deliberately close to text-primary, not a mid-gray, per the ChatGPT-benchmarked fifth pass */
    --text-metadata: #323436;     /* Graphite (text) - timestamps, ids, labels - still clearly readable, not decorative; darkened to clear 4.5:1 against --surface-selected too, not just --canvas/--surface-primary (tests/test_p40vw8qa_theme_foreground_contrast.py checks every text tier against every surface layer), while staying strictly lighter/quieter than --text-secondary */
    --text-disabled: #454749;     /* Graphite (disabled) - dimmer than metadata, still clearly readable rather than merely "not illegible" - clears 4.5:1 against every surface layer including --surface-selected */

    /* -- identity + authority (used rarely, by design) -------------------- */
    --bee-yellow: #FFC400;
    --seal-red: #7A1911;
    --seal-red-tint: #F0D9D3;

    /* -- semantic operational colors (quiet, subordinate to the neutrals) - */
    --machine-blue: #235066;
    --machine-blue-tint: #DCE7EA;
    --highlight-orange: #AF571D;
    --highlight-orange-tint: #F8E2D3;
    --accepted-green: #2E5F38;
    --accepted-green-tint: #DCEADB;
    --attention-amber: #7A4A08;
    --attention-amber-tint: #F2E2C4;
    --failure-red: #8C2E22;
    --failure-red-tint: #F3DAD4;
    /* CLAUDE-P13: perspective-sensitive risk exposure (PerspectiveAssessment,
       polarity="risk") - a genuinely different meaning from both existing
       reds, so it gets its own value rather than reusing either: --seal-red
       is human authority/consequential commitment; --failure-red is a
       CONCLUDED verdict (a contradiction actually found). Risk is neither -
       it's a prospective, perspective-dependent exposure that may never
       become either one. Deliberately chosen with enough hue/lightness
       distance from both (verified in tools/check_contrast.py) that the
       three are never mistakable for each other at a glance, not just
       different in a color-picker. Opportunity reuses --accepted-green
       (positive valence already exists) rather than minting a second new
       hue - "risk" needed a genuinely new meaning; "opportunity" did not.
       Neutral/uncertain stays --attention-amber - already means "pending/
       uncertain," which fits perspective-neutral honestly enough not to
       need a fourth new token. */
    --risk-red: #A6371F;
    --risk-red-tint: #F5DCCF;

    /* CLAUDE-P40-DTAB1: curated Document-tab organizational accents -
       deliberately an ACCENT-only palette (a tab's own color never means
       anything by itself - Section 8's own "not the sole indication of
       active/selected/pinned/hidden/dirty/warning/authorization state"),
       so these are named for the color itself, not a meaning, unlike
       --seal-red/--failure-red/etc. above. Chosen with enough hue/
       lightness distance from --highlight-orange/--attention-amber/
       --failure-red/--risk-red that a tab accent is never mistakable for
       a warning/error state at a glance - verified in tools/
       check_contrast.py alongside every other accent pairing here, same
       "readability is the floor" discipline. No "neutral/default" token
       - Default Color means no tab-color styling applied at all, not a
       7th color. */
    --tabcolor-gold: #8A6D1F;
    --tabcolor-turquoise: #1B7A72;
    --tabcolor-lapis: #1F3F7A;
    --tabcolor-terracotta: #A34A26;
    --tabcolor-green: #3D6B2C;
    --tabcolor-purple: #6B3F7A;

    /* CLAUDE-P40-BRAND1: the Archiosk header brand mark/wordmark color -
       a separate token from --tabcolor-gold above despite both being
       "gold," since they mean different things (brand identity vs. a
       Document-tab organizational accent) and this file names tokens
       for meaning, not raw appearance. Strong bronze/dark, readable
       directly as a foreground stroke/text color against --canvas -
       --bee-yellow (the existing BEEHIVE identity-mark color, gateway-
       logo's own solid-fill badge) was considered and ruled out: it is
       already reserved for icon-level FILL use only (tokens.css's own
       header), and as a bright, highly-saturated yellow it would likely
       fail contrast used as a thin foreground line/text color directly
       on a light canvas - a different, incompatible role from a solid
       fill with dark text on top. */
    --brand-gold: #6B4E14;

    --font-display: "Arial Nova Cond", "Arial Narrow", Arial, sans-serif;
    --font-body: "Arial Nova Cond", "Arial Narrow", Arial, sans-serif;
    --font-mono: "IBM Plex Mono", monospace;

    /* -- type scale ---------------------------------------------------------
       Named for role, not just size, so a future pass can tell what a
       given step is FOR. Values match the most common raw sizes already
       in use (see the header note above) - this consolidates the
       0.82rem/0.85rem/0.88rem drift into one canonical --text-sm rather
       than changing how anything currently looks. */
    --text-2xs: 0.7rem;   /* uppercase letter-spaced micro-labels */
    --text-xs: 0.8rem;    /* mono details, badges, chips */
    --text-sm: 0.85rem;   /* the default secondary/metadata/body-detail size */
    --text-base: 0.9rem;  /* base running text where it needs to be explicit */
    --text-md: 1rem;      /* default control/body text */
    --text-lg: 1.1rem;    /* sub-headings (h2 inside a pane) */
    --text-xl: 1.5rem;    /* project-scale headings (Project Home h1) */
    --text-2xl: 1.8rem;   /* page-level headings (.dash-head h1) */
    --text-3xl: 2.2rem;   /* largest display headings */

    /* -- spacing scale --------------------------------------------------
       Same principle: named steps matching the values already in use
       throughout main.css, so migrating a rule to a token is a rename,
       not a value change. A future denser or roomier mode redefines
       these in its own file - components should never hardcode a
       margin/padding/gap value that one of these already names. */
    --space-1: 0.15rem;
    --space-2: 0.3rem;
    --space-3: 0.4rem;
    --space-4: 0.5rem;
    --space-5: 0.6rem;
    --space-6: 0.7rem;
    --space-7: 0.85rem;
    --space-8: 1rem;
    --space-9: 1.2rem;
    --space-10: 1.5rem;
    --space-11: 2rem;
    --space-12: 3rem;

    /* -- visual pressure (emphasis) ---------------------------------------
       A fourth token axis, alongside color/type/space: how much
       perceptual weight a piece of governed, still-fully-present
       content currently carries. Orthogonal to the semantic color
       grammar above - pressure never substitutes for or dims a
       semantic color; every --review-state-* / --evidence-* / verdict
       badge stays at full strength regardless of a --pressure-quiet-
       text class applied to surrounding neutral text, so "this has
       gone quiet" can never be mistaken for "this verdict is wrong" or
       "this needs approval." One step only - the unmarked default, and
       --pressure-quiet-text for governed content that has settled and
       isn't what the reviewer is presently engaged with (see
       routes/workspace.py's "Visual pressure" comment for the actual
       settled/old-news/not-currently-focused rule) - not a numeric
       scale, because nothing today needs more than one step down, and
       inventing more before something needs them is exactly the
       speculative machinery the density-scale note above already warns
       against. Aliases --text-metadata (an existing, already-contrast-
       verified value) rather than a new hex, under its own name so a
       future reader knows WHY it's applied here and not just that it
       happens to look the same as a metadata label. */
    --pressure-quiet-text: var(--text-metadata);
}

/* -- dark mode / "Black" (CLAUDE-P40-VW3; CLAUDE-P40-VW8-QA Approved
   Theme Set) - the --dark-* token PREFIX and the .appearance-dark
   CLASS NAME are deliberately left unchanged through TWO label
   revisions now ("Dark" -> "Graphite" -> "Black"): they are internal
   implementation names, not the user-facing label, and the product
   owner's own instruction was explicit that "a label or palette
   revision does not require renumbering when the control retains its
   theme-selection meaning" - the same rule this stage applied to
   keeping every underlying chat.selection-toolbar identifier in place
   through its own correction. See the Appearance-matrix templates for
   the actual "Black" label text.
   This file's own header above anticipated a dark theme as a SECOND
   FILE swapping the whole <link>, on the assumption a mode is global
   to the page. That assumption no longer holds: VW3 requires Menu,
   Lists, Display, Toolbox, and Chat to each independently carry any of
   the four appearance choices at the same time (e.g. Black Display
   with Light Lists). A page-wide file swap cannot express that; per-
   surface CSS custom-property SCOPING can - see static/css/main.css's
   own .appearance-dark rule, which redefines these same standard token
   names locally on whichever surface's own root element carries that
   class, so every existing component rule below (already written as
   var(--surface-primary) etc. throughout main.css) repaints correctly
   for free, with zero per-component changes.

   CLAUDE-P40-VW8-QA (Approved Theme Set, second correction): an
   intermediate version of this stage briefly repointed the principal
   background to #0E1116 ("Graphite" - neutral near-black, not pure
   black) - the product owner's own immediate follow-up correction
   explicitly rejected that: "Restore the original true-black
   appearance... Do not use Graphite... must appear flat and matte -
   not gray... or layered like glass." Canvas AND surface-primary are
   literal #000000 again, matching CLAUDE-P40-VW6's own original
   reasoning ("the page background is not genuinely black... use a
   genuine black background"). Layering (surface-secondary/hover/
   selected) and border steps are the SAME warm-toned values VW6
   originally verified (#252118/#373125/#50432B/#6E6349/#837454,
   unchanged) - explicitly named in the new spec as the reference every
   other dark theme's OWN layering now luminance-matches against (see
   tools/derive_theme_palettes.py), so Black stays the anchor, not one
   of three independently-tuned ramps. Text tiers use the shared warm
   off-white family (--dark-text-primary #E8E4DC, product-owner spec)
   instead of pure #FFFFFF - the one part of the interim Graphite
   revision that the follow-up correction explicitly KEPT ("Continue
   using readable warm off-white foreground text on the dark themes") -
   see this same value reused, unmodified, as --tint-text-primary/
   --forest-text-primary below (ONE shared dark-theme text family
   across all three dark choices, per spec, not three independently-
   tuned ones). --dark-text-metadata's ratio against --dark-text-primary
   is 0.77 (was 0.71 in the brief Graphite interim) specifically because
   it is the tightest pairing in the whole matrix - text-metadata
   against the ORIGINAL #50432B surface-selected, unchanged since VW6 -
   and every luminance-matched theme inherits that same margin by
   construction (see the tool's own docstring). text-disabled is
   deliberately exempt from the 4.5:1 floor, matching the pre-existing
   Light-mode precedent (WCAG does not require disabled/non-interactive
   text to clear normal-text contrast; "dimmer than metadata, never
   illegible" is the actual bar, unchanged from before this stage).

   CLAUDE-P40-VW8-QA (Theme Foreground Contrast Addendum, prior stage):
   tools/check_contrast.py itself only ever checked LIGHT pairings (the
   --text-* / --canvas / --surface-primary names it reads are the Light
   :root values; Dark/Tinted use differently-prefixed token names it
   never parsed). Auditing the full text-tier x surface-tier matrix
   for all three modes directly (same relative-luminance math, run by
   hand against every combination, not just canvas/surface-primary)
   surfaced two real sub-4.5:1 failures neither this script nor any
   prior stage's spot checks had caught: --dark-text-metadata on
   --dark-surface-selected (4.24:1) and --tint-text-metadata on
   --tint-surface-hover/-selected (4.09:1 / 3.46:1) - metadata-tier
   text sitting on the deepest/most saturated layering step in each
   mode. Both darkened/lightened just enough to clear 4.5:1 with a
   small margin (still visibly the dimmest of the three text tiers -
   see the full matrix in that stage's own checkpoint entry). */
:root {
    --dark-canvas: #000000;
    --dark-surface-primary: #000000;
    --dark-surface-secondary: #252118;
    --dark-surface-hover: #373125;
    --dark-surface-selected: #50432B;
    --dark-border: #6E6349;
    --dark-border-strong: #837454;
    --dark-text-primary: #E8E4DC;
    --dark-text-secondary: #C8BEAB;
    --dark-text-metadata: #BFB49D;
    --dark-text-disabled: #7E6F53;

    --dark-seal-red: #E5756C;
    --dark-seal-red-tint: #3A1A18;
    --dark-machine-blue: #7EB7D3;
    --dark-machine-blue-tint: #1E2D34;
    --dark-highlight-orange: #E59C6C;
    --dark-highlight-orange-tint: #392519;
    --dark-accepted-green: #8AC696;
    --dark-accepted-green-tint: #213124;
    --dark-attention-amber: #E5B26C;
    --dark-attention-amber-tint: #3B2C16;
    --dark-failure-red: #DD7F73;
    --dark-failure-red-tint: #361E1B;
    --dark-risk-red: #E4826D;
    --dark-risk-red-tint: #381F19;

    /* CLAUDE-P40-DTAB1: same rationale as the light-mode block above -
       identical values across all three dark themes (Black/Midnight
       Blue/Deep Forest), the same convention every other accent color
       in this file already follows. */
    --dark-tabcolor-gold: #D4AF37;
    --dark-tabcolor-turquoise: #4ECDC4;
    --dark-tabcolor-lapis: #6C9BF5;
    --dark-tabcolor-terracotta: #E08350;
    --dark-tabcolor-green: #7FBF6A;
    --dark-tabcolor-purple: #C08FE0;

    /* CLAUDE-P40-BRAND1: same rationale as the light-mode block above -
       identical across all three dark themes, the convention every
       other accent color in this file already follows. */
    --dark-brand-gold: #E3BA52;
}

/* "Midnight Blue" (CLAUDE-P40-VW8-QA, Approved Theme Set) - the
   --tint-* token prefix and .appearance-tinted class name are kept
   unchanged for the same "label/palette revision, not a renumbering"
   reason documented on the Black block above; only the values change.
   This REPLACES Tinted's previous identity outright rather than
   adjusting it: Tinted used to be a light, desaturated navy-grey (a
   daylight-mode variant, canvas #E9EEF6 - see the retired comment this
   replaces, kept in git history for whoever needs the prior design
   reasoning) and is now one of the three DARK appearance choices, a
   solid, visibly saturated deep navy (canvas #001426, product-owner
   spec - a second, stronger correction after an interim #0B1B2B
   attempt read as too close to neutral; "the blue and green must
   remain visibly deep, saturated, and solid" was explicit) - distinct
   in hue from Black's own warm-neutral base and Deep Forest's
   blue-green one, not "three nearly identical black themes" (the
   product owner's own explicit requirement). Surface/border steps are
   LUMINANCE-MATCHED (not raw-lightness-reprojected) to Black's own
   ramp at this theme's hue (tools/derive_theme_palettes.py's own
   docstring has the full reasoning for why luminance-matching, not
   lightness-matching, is required once saturation varies this much),
   which is also what keeps every dark theme's contrast guarantees
   identical by construction rather than independently re-verified per
   theme. Border/border-strong use a LOWER saturation (0.55/0.60) than
   the surface steps so an ordinary panel boundary stays quiet even
   against a vividly saturated background - see the panel-border-
   hierarchy correction this stage also made; "ensure divider colors do
   not become distracting in Midnight Blue or Deep Forest" was explicit
   there too. Text reuses the SAME shared warm-off-white family
   (--dark-text-primary #E8E4DC and its derived tiers) rather than
   inventing a second one - "derive the complete supporting palette
   from shared tokens" per spec. Accent colors below are intentionally
   the EXACT SAME values as Black's --dark-seal-red/etc. family (not
   independently re-picked): status meaning should read identically
   regardless of which dark appearance is active, and re-verification
   confirmed every one of them still clears 3:1 against this theme's
   own canvas. Duplicated here as literal values, not var()-aliased to
   --dark-*, only because every other mode family in this file is
   already self-contained the same way - a structural convention this
   stage preserves rather than introduces a cross-family reference
   pattern that doesn't exist anywhere else in this file. */
:root {
    --tint-canvas: #001426;
    --tint-surface-primary: #001426;
    --tint-surface-secondary: #002242;
    --tint-surface-hover: #003260;
    --tint-surface-selected: #004583;
    --tint-border: #2D679C;
    --tint-border-strong: #2F79BC;
    --tint-text-primary: #E8E4DC;
    --tint-text-secondary: #C8BEAB;
    --tint-text-metadata: #BFB49D;
    --tint-text-disabled: #7E6F53;

    --tint-seal-red: #E5756C;
    --tint-seal-red-tint: #3A1A18;
    --tint-machine-blue: #7EB7D3;
    --tint-machine-blue-tint: #1E2D34;
    --tint-highlight-orange: #E59C6C;
    --tint-highlight-orange-tint: #392519;
    --tint-accepted-green: #8AC696;
    --tint-accepted-green-tint: #213124;
    --tint-attention-amber: #E5B26C;
    --tint-attention-amber-tint: #3B2C16;
    --tint-failure-red: #DD7F73;
    --tint-failure-red-tint: #361E1B;
    --tint-risk-red: #E4826D;
    --tint-risk-red-tint: #381F19;

    /* CLAUDE-P40-DTAB1: same rationale as the light-mode block above -
       identical values across all three dark themes (Black/Midnight
       Blue/Deep Forest), the same convention every other accent color
       in this file already follows. */
    --tint-tabcolor-gold: #D4AF37;
    --tint-tabcolor-turquoise: #4ECDC4;
    --tint-tabcolor-lapis: #6C9BF5;
    --tint-tabcolor-terracotta: #E08350;
    --tint-tabcolor-green: #7FBF6A;
    --tint-tabcolor-purple: #C08FE0;
    --tint-brand-gold: #E3BA52;
}

/* "Deep Forest" (CLAUDE-P40-VW8-QA, Approved Theme Set) - the third
   dark appearance choice, new this stage (no prior identity to
   preserve, unlike Black/Midnight Blue above). Canvas #001A12
   (product-owner spec, a second, more saturated correction after an
   interim #10231E attempt), a deep, visibly saturated blue-green - the
   SAME luminance-matching derivation as Midnight Blue above
   (tools/derive_theme_palettes.py), shared warm-off-white text family,
   Black's accent-color values reused unmodified and re-verified at
   3:1 against this canvas, border/border-strong at reduced saturation
   for the same "quiet ordinary boundary" reason. Luminance-matching
   specifically exists because of THIS theme: a fully saturated green
   at the SAME raw HSL lightness as blue/neutral reaches a much higher
   relative luminance (WCAG's luminance formula weights green 0.7152
   vs blue's 0.0722), so naively reprojecting Black's raw lightness
   steps onto Forest's own hue at high saturation caused real 4.5:1
   failures (text-metadata dropped to 2.58:1 against the naive
   surface-selected) - solving for the LIGHTNESS THAT REPRODUCES Black's
   own luminance at each step, rather than reusing the lightness number
   itself, fixed this structurally rather than by hand-tuning one more
   special case (see the tool's own docstring for the full method). */
:root {
    --forest-canvas: #001A12;
    --forest-surface-primary: #001A12;
    --forest-surface-secondary: #00271B;
    --forest-surface-hover: #003928;
    --forest-surface-selected: #004F37;
    --forest-border: #217158;
    --forest-border-strong: #218466;
    --forest-text-primary: #E8E4DC;
    --forest-text-secondary: #C8BEAB;
    --forest-text-metadata: #BFB49D;
    --forest-text-disabled: #7E6F53;

    --forest-seal-red: #E5756C;
    --forest-seal-red-tint: #3A1A18;
    --forest-machine-blue: #7EB7D3;
    --forest-machine-blue-tint: #1E2D34;
    --forest-highlight-orange: #E59C6C;
    --forest-highlight-orange-tint: #392519;
    --forest-accepted-green: #8AC696;
    --forest-accepted-green-tint: #213124;
    --forest-attention-amber: #E5B26C;
    --forest-attention-amber-tint: #3B2C16;
    --forest-failure-red: #DD7F73;
    --forest-failure-red-tint: #361E1B;
    --forest-risk-red: #E4826D;
    --forest-risk-red-tint: #381F19;

    /* CLAUDE-P40-DTAB1: same rationale as the light-mode block above -
       identical values across all three dark themes (Black/Midnight
       Blue/Deep Forest), the same convention every other accent color
       in this file already follows. */
    --forest-tabcolor-gold: #D4AF37;
    --forest-tabcolor-turquoise: #4ECDC4;
    --forest-tabcolor-lapis: #6C9BF5;
    --forest-tabcolor-terracotta: #E08350;
    --forest-tabcolor-green: #7FBF6A;
    --forest-tabcolor-purple: #C08FE0;
    --forest-brand-gold: #E3BA52;
}

/* CLAUDE-P40-VW6: ONE fixed, mode-invariant divider color - deliberately
   NEVER redefined inside .appearance-dark/.appearance-tinted (unlike
   every other token above, which each scope DOES redefine). The
   workspace/Chat seam can have a different mode on each side (Dark
   workspace above a Light Chat, Tinted above Dark, etc.) - "relying on
   two backgrounds being different" to make that boundary visible fails
   whenever they're not, so this token exists specifically to stay
   legible against light/dark/tinted backgrounds AT ONCE, not to track
   whichever surface happens to render it. Verified via the same
   contrast script: 5.04:1 against the light surface, 4.00:1 against
   pure black, 4.02:1 against the tint surface - comfortably visible in
   every combination, not just the ones it happens to share a token
   with. */
:root {
    --divider-strong: #756B57;
    /* CLAUDE-P40-VW8-QA: the blueprint-grid backdrop line (static/css/
       main.css's own .blueprint-grid) - same "deliberately mode-
       invariant" reasoning as --divider-strong above: a fixed, z-index
       -1, 0.3-opacity brand watermark sitting BEHIND every panel's own
       opaque background, never a text/foreground color a reader parses
       against a specific surface, so it has no per-mode contrast
       requirement to satisfy - genuinely blue by design (see that
       rule's own comment), not an accidental hardcoded value. Named
       here instead of left as a raw hex in main.css purely so tokens.css
       stays the one place ANY shipped color value is defined, per this
       file's own header discipline - the value itself is unchanged. */
    --blueprint-grid-line: #5995C0;
}

/* CLAUDE-P40-VW7: Tag/Highlight swatch colors - services/case_workspace.py's
   own TAG_COLOR_PALETTE names, given values here (the store layer stays
   ignorant of presentation, per that file's own comment). Deliberately
   mode-invariant, like --divider-strong above, and for the same class of
   reason: these are never text, only a small bordered dot next to a tag
   name (.launcher-tag-swatch) or a color-picker radio swatch
   (.conv-tag-color-swatch) - a literal user-facing color CHOICE, the one
   deliberate exception to this file's "name for meaning, not raw
   appearance" rule (see header comment above), since the whole point of
   a tag color picker is picking a raw appearance. main.css always pairs
   these with a 1px border (var(--border-strong)) so the dot itself stays
   visible against any of the three canvas/surface colors, rather than
   needing six more dark/tinted variants to solve the same problem VW6's
   token-redefinition mechanism exists for. Independent of --bee-yellow
   and every semantic accent above - never spread the identity mark or an
   authority/status color into a decorative, user-assignable palette. */
:root {
    --tagcolor-yellow: #E0B400;
    --tagcolor-orange: #C97A2E;
    --tagcolor-red: #B23A2E;
    --tagcolor-green: #3E7D4A;
    --tagcolor-blue: #3B6EA5;
    --tagcolor-purple: #7A5AA6;
}
