/* ============================================================================
   Self-hosted brand fonts (L-01 design tokens & assets).
   Geist (body / UI sans) — Vercel's open-source sans, bundled in /static/fonts/
   so the brand works offline and is not CDN-dependent. Material Icons (the
   classic filled icon font) is self-hosted from the same dir. Playfair Display
   and JetBrains Mono continue to load via the page-level Google Fonts <link>.
   Paths are relative to this file (app_services/static/css/ -> ../fonts/).
   ============================================================================ */
@font-face { font-family: 'Geist'; src: url('../fonts/Geist-Regular.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Geist'; src: url('../fonts/Geist-Medium.woff2') format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Geist'; src: url('../fonts/Geist-SemiBold.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'Geist'; src: url('../fonts/Geist-Bold.woff2') format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: 'Material Icons'; src: url('../fonts/material-icons-v145.ttf') format('truetype'); font-weight: normal; font-style: normal; font-display: swap; }

:root {
    /* Brand Palette */
    --forest-green: #0F2F24;
    --forest-mid: #1B4D3E;
    --forest-mist: #1F4538;     /* CTA hover fill — mistier/lighter than forest-mid */
    --burnished-gold: #C5A059;
    --warm-linen: #EFE7D6;
    --deep-green-black: #0F2F24;
    --cads-theme-color-ink: var(--forest-green);

    /* Stone neutral — chat user-bubbles / contextual chips */
    --stone: #E4E0D8;

    /* Accessible Gold — accent-only on warm linen; keep small/body text on darker tokens.
       Raw brand constant, declared ONCE here and never redefined per
       [data-theme] (fix (review-r1), 2026-09-04: reverts the R-CSS-2/R-CSS-3
       2026-09-03 rounds, which had darkened this to #735C23 in :root and
       added [data-theme="dark"] plus an OS-dark-mode media-query redefinition
       to #D4B472 -- both broke the theme_contrast gate's committed contract
       that --gold-accessible/--primary are theme-invariant raw constants,
       declared exactly once, resolving text-gold/text-gold-accessible in
       light to ~3.68:1 on Aged Linen -- under the 4.5:1 body-text floor by
       design (gold-accessible alone is an accent-only token, not meant to
       clear AA for small/body text on this canvas; see the shell-scoped
       .bg-primary-nested overrides below for the passing case). --burnished
       -gold above is untouched -- borders/icons/dots stay #C5A059. Dark-
       theme legibility for `.text-gold`/`.text-gold-accessible` is handled
       by the shell-scoped `[data-theme="dark"] .gp-shell .text-gold-accessible`
       (etc.) rules further below, which remap to --burnished-gold directly
       -- NOT by redefining this token itself. */
    --gold-accessible: #856A28;

    /* WCAG-AA contrast tokens for warm-linen (#EFE7D6) surfaces */
    --text-muted: #4A5C54;           /* 5.8:1 — AA small + large */
    --text-subtle: #6B7A73;          /* 3.7:1 — AA large/decorative only (≥18.67px bold / 24px regular) */
    --text-muted-on-inverse: #C8C4BC; /* on dark/forest backgrounds */

    /* Status Colors */
    --status-error: #991B1B;
    --status-success: #1B4D3E;
    --status-warning: #C5A059;

    /* Disclosure-callout colors — semantic-status exception to the
       gold-accent-only rule, reserved for disclosed-assumption callouts
       (e.g. an unprovisioned fee-rate plug) and their corrected/resolved
       counterpart. Crimson, not pink; signal green, not jade or near-black.
       Distinct from --status-error/--status-success above, which cover
       generic form/validation states. */
    --status-disclosure-alert: #B3261E;
    --status-disclosure-alert-fg: #7A1913;
    --status-disclosure-resolved: #1F7A4D;
    --status-disclosure-resolved-fg: #145C39;

    /* Tinted Neutrals (forest-hued, never pure gray) */
    --neutral-50: oklch(0.985 0.003 155);
    --neutral-100: oklch(0.97 0.004 155);
    --neutral-200: oklch(0.92 0.006 155);
    --neutral-300: oklch(0.87 0.008 155);
    --neutral-400: oklch(0.70 0.01 155);
    --neutral-500: oklch(0.55 0.012 155);
    --neutral-600: oklch(0.45 0.014 155);
    --neutral-700: oklch(0.35 0.016 155);
    --neutral-800: oklch(0.25 0.018 155);
    --neutral-900: oklch(0.18 0.02 155);

    /* Motion */
    --ease-institutional: cubic-bezier(0.16, 1, 0.3, 1);
    --duration-micro: 200ms;
    --duration-page: 400ms;

    /* Semantic foreground / background aliases.
       Light = console/report canvas; dark = marketing/sidebar shell. */
    --bg-dark: var(--forest-green);
    --bg-light: var(--warm-linen);
    --fg-on-dark: var(--warm-linen);
    --fg-on-light: var(--forest-green);
    --fg-muted-on-dark: color-mix(in srgb, var(--warm-linen) 60%, transparent);
    --fg-muted-on-light: color-mix(in srgb, var(--forest-green) 70%, transparent);
    --rule-gold: color-mix(in srgb, var(--burnished-gold) 30%, transparent); /* ghost border */

    /* Type families */
    --font-display: 'Playfair Display', Georgia, serif;          /* H1–H3, hero moments */
    --font-body: 'Geist', system-ui, sans-serif;                 /* UI, prose, buttons, labels */
    --font-mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', monospace; /* ledger / numerics */

    /* Type scale (px) + line-heights */
    --text-display: 60px;  --lh-display: 1.05;
    --text-h1: 40px;       --lh-h1: 1.1;
    --text-h2: 30px;       --lh-h2: 1.15;
    --text-h3: 22px;       --lh-h3: 1.25;
    --text-lg: 18px;       --lh-lg: 1.55;
    --text-base: 16px;     --lh-base: 1.6;
    --text-sm: 14px;       --lh-sm: 1.5;
    --text-xs: 12px;       --lh-xs: 1.4;
    --text-2xs: 10px;      --lh-2xs: 1.3;

    /* Radii — machined edges, not bubbles */
    --radius-tight: 2px;   /* micro — counter badges, small chips */
    --radius: 2px;         /* DEFAULT — cards, buttons, controls (CDS canon: 2px) */
    --radius-pill: 2px;    /* DEPRECATED 2026-06-25: pill shapes banned per JTP directive. Use --radius (2px). */

    /* Spacing — clamp-based so density holds across breakpoints */
    --space-xs: clamp(0.5rem, 0.5vw, 0.75rem);
    --space-sm: clamp(1rem, 1vw, 1.5rem);
    --space-md: clamp(2rem, 3vw, 3rem);
    --space-lg: clamp(4rem, 5vw, 6rem);
    --space-xl: clamp(6rem, 8vw, 10rem);

    /* Elevation — structural, gold-tinted, never puffy */
    --shadow-card: 0 10px 25px -5px rgba(197, 160, 89, 0.25);
    --shadow-panel: 0 4px 12px -2px rgba(15, 47, 36, 0.15);
    --shadow-modal: 0 20px 60px -10px rgba(5, 18, 14, 0.40);

    /* ────────────────────────────────────────────────────────────────────
       THEMEABLE SEMANTIC SURFACE TOKENS (Wave-0 LIGHT/DARK theme system).
       The GP-portal CONTENT area resolves its surfaces/text through these
       vars so flipping [data-theme] re-skins the console without per-template
       edits. The forest-green SIDEBAR is an explicit brand anchor and does
       NOT consume these tokens (it stays forest in both themes).
       Defaults here = LIGHT (warm-linen console). [data-theme="dark"] below
       overrides them. Never reference raw hex in GP content — use these.
       ──────────────────────────────────────────────────────────────────── */
    --surface-canvas: #E7D9BC;             /* Aged Linen page background — locked 2026-08-19; doc-confirmed
                                               canonical light console page ground per JTP B3 ruling 2026-09-03,
                                               resolving the recon-design-noise.md "needs investigation" flag */
    --surface-elevated: #EDE2C7;           /* Raised cards / panels / headers — locked 2026-08-19; single-sourced
                                               into design-tokens.css's --color-card-bg (JTP G ruling 2026-09-03) */
    --surface-sunken: #DFD2B2;             /* Table stripes / inset wells / mats — locked 2026-08-19 */
    --surface-text: var(--forest-green);   /* primary body / heading text */
    --surface-text-muted: var(--text-muted);
    --surface-text-subtle: var(--text-subtle);
    --surface-border: var(--rule-gold);    /* hairline rules / card borders */
    --surface-gold: var(--gold-accessible);/* accent text/icon (AA on canvas) */
    --surface-hover: #DFD2B2;              /* Piece 6 pocket 3 hover-raise — same value as --surface-sunken today ("slightly deeper linen"); see .cds-hover-raise below */
    /* P8 feed-hygiene (2026-08-20): status-error text (e.g. `.text-error-600`,
       Street freshness bar "Unavailable") had no dark-mode remap — the raw
       Tailwind color-mix reads at ~1.4:1 on the dark surface-elevated card
       (invisible). Light default reuses the existing --status-error token
       (already AA on --surface-elevated-light, no new hex). */
    --surface-status-error: var(--status-error);
    /* t_f8dbea1c (2026-09-25): keyboard focus ring for every shared
       :focus-visible rule (components.css .cds-button / .cds-card--interactive
       / .cds-toggle / .cds-fab / .cds-suggestion-chip, and .theme-toggle /
       .chrome-icon-btn below). Was raw gold (#C5A059) in both themes --
       live-measured 1.80:1 on the GP Sign out row and 1.76:1 on the Aged
       Linen page, under the WCAG 2.2 SC 1.4.11 3:1 non-text floor. Light =
       forest (10.4-11.8:1 on the linen grounds); dark = gold (5.88:1 on the
       page, 3.92:1 on the card -- the dark look is unchanged). References the
       raw brand constants, never redefines them. Permanently-forest grounds
       reset it to gold -- see .cds-forest-ground below. */
    --surface-focus-ring: var(--forest-green);
    /* t_007ace1e: GP wizard progress bar tokens (WCAG 2.2 SC 1.4.11 non-text contrast >= 3:1).
       Light theme uses forest-green for current/completed (10.36:1 on Aged Linen)
       and text-subtle for upcoming track (3.21:1 vs fill, 3.23:1 on Aged Linen).
       Dark theme uses warm-linen for current/completed (11.75:1 on Hunter Green)
       and text-subtle for upcoming track (3.67:1 vs fill, 3.21:1 on Hunter Green).
       All three pairs (filled vs track, filled vs surface, track vs surface) achieve
       >= 3:1 contrast in both light and dark. Zero inline hex; conforms to CDS Ruling F. */
    --surface-progress-current: var(--forest-green);
    --surface-progress-completed: var(--forest-green);
    --surface-progress-upcoming: var(--text-subtle);
}

/* Explicit light selector (mirrors :root defaults; lets a forced
   [data-theme="light"] win over the prefers-color-scheme mirror below). */
[data-theme="light"] {
    --surface-canvas: #E7D9BC;
    --surface-elevated: #EDE2C7;
    --surface-sunken: #DFD2B2;
    --surface-text: var(--forest-green);
    --surface-text-muted: var(--text-muted);
    --surface-text-subtle: var(--text-subtle);
    --surface-border: var(--rule-gold);
    --surface-gold: var(--gold-accessible);
    --surface-hover: #DFD2B2;
    --surface-status-error: var(--status-error);
    --cads-theme-color-ink: var(--forest-green);
    --surface-focus-ring: var(--forest-green);
    --surface-progress-current: var(--forest-green);
    --surface-progress-completed: var(--forest-green);
    --surface-progress-upcoming: var(--text-subtle);
    color-scheme: light;
}

/* DARK theme — deep green-black PAGE, forest-mid CARDS, linen TEXT, gold as a
   thin accent only (never large gold fills). Driven by an explicit toggle
   ([data-theme="dark"]) OR by OS preference when the user has not chosen light. */
[data-theme="dark"] {
    --surface-canvas: var(--forest-green);                     /* #0F2F24 — Hunter-Green PAGE ground */
    --surface-elevated: var(--forest-mid);                     /* #1B4D3E — cards */
    --surface-sunken: color-mix(in srgb, var(--forest-mid) 30%, var(--forest-green)); /* ratified well, between page+card */
    --surface-text: var(--warm-linen);
    --surface-text-muted: var(--text-muted-on-inverse);        /* #C8C4BC */
    --surface-text-subtle: color-mix(in srgb, var(--warm-linen) 45%, transparent);
    --surface-border: color-mix(in srgb, var(--burnished-gold) 85%, transparent); /* coordinator 2026-09-03, adversary round: raised again from 60% -- 60% measured 3.02:1 on the page ground but only 2.33:1 on the forest-mid card, failing the 3:1 non-text-UI floor where most of these hairlines actually render; 85% clears 4.65:1 on page / 3.27:1 on card, both with real margin */
    --surface-gold: var(--burnished-gold);                     /* gold readable on dark */
    --surface-hover: color-mix(in srgb, var(--forest-mid) 30%, var(--forest-green)); /* Piece 6 pocket 3 hover-raise — "slightly lighter forest", same blend as --surface-sunken */
    --cads-theme-color-ink: #F9F8F6;
    /* fix (review-r1), 2026-09-04: the R-CSS-2/R-CSS-3 (2026-09-03) root-
       level dark redefinition of the accessible-gold custom property
       (previously #D4B472 here) is removed -- it violated the
       theme_contrast gate's committed contract that --gold-accessible is a
       raw brand constant declared ONCE in :root (see
       that declaration's comment above). Dark-theme legibility for
       `.text-gold-accessible` is handled by the shell-scoped
       `[data-theme="dark"] .gp-shell .text-gold-accessible` (etc.) rules
       further below, which remap to --burnished-gold directly, matching
       --surface-gold above -- not by redefining this token. */
    color-scheme: dark;

    /* Disclosure-callout colors (dark) — accent tokens (border/icon/fg) only,
       per V7a; never a status WORD colored red/green on dark ground.
       V2a, 2026-09-03 (post-T0): -alert #E8877E (pink band) -> brick
       #C0453B; -alert-fg #F3B8B1 (pink band, was the #1 pink hit in the
       pre-T0 scan) -> linen #F9F8F6; -resolved / -resolved-fg de-jaded to
       leaf green / linen, matching design-tokens.css --color-status-ok.
       R-CSS-3 adversary round (2026-09-03): brick #C0453B itself failed the
       3:1 non-text floor as a border/icon accent -- 2.86:1 on the dark page,
       1.91:1 on the forest-mid card. Replaced with #B88D89 (same ~5deg
       brick hue, desaturated to S=25%/L=63% -- under the 30% pink-band
       saturation threshold so it stays out of the pink band): 4.96:1 on
       page / 3.31:1 on card, both clearing 3:1. */
    --status-disclosure-alert: #B88D89;
    --status-disclosure-alert-fg: #F9F8F6;
    --status-disclosure-resolved: #8FCB6B;
    --status-disclosure-resolved-fg: #F9F8F6;

    /* P8 feed-hygiene: status-error text on dark surfaces. --status-error
       itself (#991B1B) measures ~1.16:1 on --surface-elevated dark (forest-mid)
       — reuse --status-disclosure-alert-fg (now linen #F9F8F6, ~9.09:1 on
       forest-mid, per V7a: dark status text is linen, not red) instead of
       adding another red hex to the palette. */
    --surface-status-error: var(--status-disclosure-alert-fg);

    /* t_f8dbea1c: focus ring stays gold on dark (see the :root declaration). */
    --surface-focus-ring: var(--burnished-gold);
    --surface-progress-current: var(--warm-linen);
    --surface-progress-completed: var(--warm-linen);
    --surface-progress-upcoming: var(--text-subtle);
}

/* theme-follow-os: sanctioned (Piece 6 / L10 — JTP ruling 20260820,
   dark-mode = follow-OS: this @media(prefers-color-scheme) mirror of the
   [data-theme="dark"] token block is the DELIBERATE mechanism, not a leak.
   L10 allow-lists exactly this block by this marker; any NEW
   @media(prefers-color-scheme) rule elsewhere in this file fails without
   one.) */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --surface-canvas: var(--forest-green);                 /* #0F2F24 — Hunter-Green PAGE ground */
        --surface-elevated: var(--forest-mid);
        --surface-sunken: color-mix(in srgb, var(--forest-mid) 30%, var(--forest-green)); /* ratified well */
        --surface-text: var(--warm-linen);
        --surface-text-muted: var(--text-muted-on-inverse);
        --surface-text-subtle: color-mix(in srgb, var(--warm-linen) 45%, transparent);
        --surface-border: color-mix(in srgb, var(--burnished-gold) 85%, transparent); /* coordinator 2026-09-03, adversary round: raised from 60%, mirrors the [data-theme="dark"] block fix above (this @media mirror keeps its own literal per L10 doctrine) */
        --surface-gold: var(--burnished-gold);
        /* fix (review-r1), 2026-09-04: mirrors the [data-theme="dark"]
           block's removal of the --gold-accessible redefinition above --
           this @media mirror no longer carries its own copy either. */
        --surface-hover: color-mix(in srgb, var(--forest-mid) 30%, var(--forest-green));
        /* V7a/V2a, 2026-09-03 (post-T0): was #F3B8B1 (pink band); mirrors the
           [data-theme="dark"] block's --status-disclosure-alert-fg -> linen
           fix above (this @media mirror can't reference that var directly,
           per L10 doctrine, so the literal is kept in sync by hand). */
        --surface-status-error: #F9F8F6;
        --surface-focus-ring: var(--burnished-gold);
        --surface-progress-current: var(--warm-linen);
        --surface-progress-completed: var(--warm-linen);
        --surface-progress-upcoming: var(--text-subtle);
        color-scheme: dark;
    }

    /* t_f8dbea1c / review-r2: preserve gold focus ring on nested surfaces in OS-dark mirror */
    :root:not([data-theme="light"]) :is(.bg-background-light, [class*="bg-background-light"], .bg-linen,
        .bg-white, .bg-canvas, .setting-card, .cds-card, .cads-card,
        .cads-bg-surface, .bg-surface-elevated) {
        --surface-focus-ring: var(--burnished-gold);
    }
}

/* unscoped-body: grandfathered (Piece 6 / L11 — MSG-Intern-to-EA-lightmode-
   inverse-and-small-lints-20260820.md, structural leak (b): the app's
   product default is JTP-ruled "follow-OS" (dark-mode = follow-OS; see the
   sanctioned @media block above and its mirror below), so this unscoped
   dark-forest body default stays as the pre-choice/no-JS-yet ground for
   every page until a shell class (.cloud-public / .gp-shell / .lp-shell /
   base_partners.html's own patch) repaints it light. Retiring it (making
   light the unscoped default, scoping dark instead) is explicitly OUT of
   this lane's scope — the parent token-remap packet's PRIORITY + ORDERING
   TRAP applies here too: retiring this before the rebind fixes land would
   flip latent sites live-broken. L11 allow-lists exactly this one block by
   this marker; any NEW unscoped `body { ... color|background ... }` block
   elsewhere in this file fails without one.) */
body {
    background-color: var(--forest-green);
    color: var(--warm-linen);
    font-family: 'Geist', system-ui, sans-serif;
}

/* Piece 6 pocket 3 hover token (.cds-hover-raise): a per-theme "hover raise"
   background for elements that used the dark-canvas hover:bg-background-light
   idiom — invisible on light (bg-background-light is aliased to the page
   canvas token itself, so "hover to become canvas-colored" is a no-op) and
   semantically wrong on dark too (see MSG-Intern-to-EA-lightmode-inverse-
   and-small-lints-20260820.md pocket 3, 37 sites). --surface-hover is
   themed above (light: #DFD2B2, the same "deeper linen" value as
   --surface-sunken; dark: the same forest-mid/forest-green blend as
   --surface-sunken, i.e. "slightly lighter forest") — deliberately reusing
   the sunken formula rather than inventing new hex values, since a hover
   raise and an inset well are the same visual weight, one step off canvas
   in either direction. No !important: this file is loaded unlayered and
   already wins over Tailwind's @layer utilities without one (matches this
   file's established pattern elsewhere), and omitting it lets a more
   specific override win if a future page needs one. */
.cds-hover-raise {
    transition: background-color var(--duration-micro, 150ms) var(--ease-institutional, ease);
}
.cds-hover-raise:hover {
    background-color: var(--surface-hover);
}

h1, h2, h3, h4, h5, h6 {
    font-family: 'Playfair Display', serif;
    color: inherit;
}

/* ============================================================================
   GLOBAL TEXT SELECTION — JTP ruling, CoS Task 2 (2026-08-05): default browser
   selection blue is off-brand everywhere on the site. Restrained burnished-
   gold highlight with forest-green text. This reuses the exact
   text-primary-on-gold pairing this codebase already audits and ships
   elsewhere (5.88:1, AA — see tests/unit/test_composer_contrast.py and
   tests/unit/test_w4_contrast_checker.py::
   test_contrast_ratio_matches_composer_known_values). Both --burnished-gold
   and --forest-green are raw brand constants (never redefined per
   [data-theme], see :root above), so ONE flat rule is correct and legible in
   both light and dark theme without a themed override — no matter which
   surface (light card or dark canvas) the selected text sits on, the
   highlight itself always paints gold-with-forest-text.
   ============================================================================ */
::selection {
    background-color: var(--burnished-gold);
    color: var(--forest-green);
}
::-moz-selection {
    background-color: var(--burnished-gold);
    color: var(--forest-green);
}

/* Federal Reserve Chic Utility Classes */

.text-gold {
    color: var(--burnished-gold);
}

.text-gold-accessible {
    color: var(--gold-accessible);
}

/* Fix (review-r1), 2026-09-04: --gold-accessible (#856A28) alone measures
   ~3.68:1 against the light canvas (under the 4.5:1 body-text floor by
   design, see the token's own :root comment) and ~2.82:1 against the dark
   canvas -- neither theme clears AA on its own for a consumer with no
   shell wrapper. These two unscoped (no shell requirement) class-level
   overrides cover every `.text-gold-accessible` consumer sitewide, not
   just the gp-shell/console-shell/lp-shell/portal-shell/cloud-public
   shells that already carry their own DARK-theme remaps further below
   (those stay more specific and still win where they apply). Restores the
   same #735C23 (light) / burnished-gold (dark) split the CUSTOM PROPERTY
   itself briefly (and, per the gate's own committed contract, incorrectly)
   carried across the R-CSS-2/R-CSS-3 rounds -- as class-level overrides
   instead of a per-theme redefinition of the now theme-invariant
   --gold-accessible custom property. */
[data-theme="light"] .text-gold-accessible {
    color: #735C23 !important;
}
[data-theme="dark"] .text-gold-accessible {
    color: var(--burnished-gold) !important;
}

/* Fix (R-DL, 2026-09-03): theme-invariant literal for contexts that must
   stay at the light-optimized accessible-gold value regardless of page
   theme -- the ground it sits on never flips with the theme (e.g. a fixed
   dark card), so it must keep #735C23 even where the light-theme override
   above wouldn't apply (unscoped shell contexts still resolve theme
   normally; this is for elements that need the light value in BOTH
   themes). Named token replaces a raw text-[#735C23] bracket utility
   (chat_panel.html Retry button on a theme-static ground). */
.text-gold-accessible-static {
    color: #735C23;
}

.text-forest {
    color: var(--forest-green);
}

.text-linen {
    color: var(--warm-linen);
}

/* Fix (R-TC residue batch r1b5, 2026-09-03): a small readable-ink pair for
   spans/badges where NEITHER existing single gold/ink token clears 4.5:1
   in BOTH themes against their ground -- first hit on
   console/components/macros.html's agent badges and console/
   sessions_table_partial.html's session-state badges (both a small
   `bg-gold/10` pill: unregistered/stale/agent-name labels), then reused
   for console/crm/account.html's role badge (same `bg-gold/10` pill) and
   the `bg-linen` "days" badges on console/crm/analytics.html,
   console/crm/campaign_detail.html and console/crm/company_detail.html
   (`.console-shell .bg-linen` remaps to the dark `--surface-elevated` card
   in dark theme, per the block above at ~L1130, so `.text-gold-accessible`
   there is light-tuned only: ~5.2:1 light, ~3.9:1 dark). In every one of
   these cases `.text-forest` (forest-green) reads well on the LIGHT
   version of the ground but is illegible once that ground goes dark
   (forest-on-forest), and `.text-on-primary` (near-white) is the exact
   reverse -- no single existing token spans both. `dark:`-variant
   Tailwind classes do NOT help either: this gate's `extract_text_colors`
   explicitly skips any class containing ":", so a `dark:text-X` pairing
   is invisible to it even though it renders correctly in a real browser --
   the base class alone must carry both themes. This small dedicated pair
   does that, unscoped (no shell requirement, so it works identically
   whether the consuming template resolves a shell or not -- several of
   the ones above have no `{% extends %}` and so resolve to shell=None):
   forest-green ink by default (light canvas), swapped to on-primary once
   `[data-theme="dark"]` flips the canvas dark -- mirroring the shape of
   every other paired override in this file. */
.text-ink-adaptive {
    color: var(--forest-green);
}
[data-theme="dark"] .text-ink-adaptive {
    color: var(--color-on-primary, #EFE7D6);
}

/* Shell-scoped contrast overrides for the GP / CRM chrome.
   These preserve the legacy token names while forcing readable contrast
   inside the marked shell wrappers.

   FIX (P2 light-mode sweep, 2026-08-03, SCORE-08/B2-Q1): the sidebar wrapper
   in base_gp.html/nav_gp.html renders `bg-background-light` in LIGHT theme
   and `dark:bg-primary` (forest) in DARK theme — i.e. the sidebar surface
   itself flips with the theme, it is not a fixed-forest brand anchor. The
   `.text-text-dark` nav-link color below is the light/cream color Tailwind's
   `--color-text-dark` token defines for use ON a dark surface. Previously
   this whole block applied UNCONDITIONALLY (no [data-theme] scoping), so in
   LIGHT theme every inactive sidebar nav link/subtitle rendered cream text
   (#EFE7D6) on the cream sidebar background (#EFE7D6) — contrast ratio 1.0,
   completely invisible except for the single active item (which gets its
   own gold highlight). Scoped to [data-theme="dark"] here (where the
   sidebar surface really is dark) and paired with a [data-theme="light"]
   counterpart below that gives `.text-text-dark` a readable dark/forest
   color on the light sidebar surface, mirroring the existing
   `.gp-shell .text-primary` forest-green fallback pattern used elsewhere in
   this file. */
[data-theme="dark"] .gp-shell .text-text-dark,
[data-theme="dark"] .console-shell .text-text-dark {
    color: var(--warm-linen) !important;
}

[data-theme="dark"] .gp-shell .text-text-dark\/60,
[data-theme="dark"] .console-shell .text-text-dark\/60 {
    color: color-mix(in srgb, var(--warm-linen) 60%, transparent) !important;
}

/* Fix (R-CSS-3, 2026-09-03): generalised beyond the single /60 step above --
   templates also author `.text-text-dark/70` (nav subtitles at another
   weight), plus /80 added proportionally for family completeness, matching
   the `.text-primary/NN` opacity-step pattern used elsewhere in this file.
   Same warm-linen dark-surface base, just a different color-mix percentage.
   R-CSS-3 adversary round (2026-09-03): /40 and /50 members were dropped
   from this family (both here and in the LIGHT counterpart below) -- no
   opacity percentage in that range clears the 4.5:1 text floor against
   either the dark sidebar ground (#0F2F24: /40 measures 3.13:1, /50
   measures 4.06:1) or the light one (#EFE7D6: /40 measures 2.28:1, /50
   measures 2.90:1). Only /60/70/80, which do clear 4.5:1, remain. */
[data-theme="dark"] .gp-shell .text-text-dark\/70,
[data-theme="dark"] .console-shell .text-text-dark\/70 {
    color: color-mix(in srgb, var(--warm-linen) 70%, transparent) !important;
}

[data-theme="dark"] .gp-shell .text-text-dark\/80,
[data-theme="dark"] .console-shell .text-text-dark\/80 {
    color: color-mix(in srgb, var(--warm-linen) 80%, transparent) !important;
}

/* LIGHT-mode counterpart — the sidebar surface is cream in light theme, so
   `.text-text-dark` (and its /60 subtitle variant) need the readable
   forest-green ink instead of the dark-surface cream color above. The /60
   subtitle uses the pre-existing WCAG-AA `--text-muted` token (5.8:1 on
   warm-linen) rather than a raw 60%-opacity forest blend (~3.8:1) so nav
   subtitles ("Fund Overview", "LPs & Onboarding", ...) clear AA-small too. */
[data-theme="light"] .gp-shell .text-text-dark,
[data-theme="light"] .console-shell .text-text-dark {
    color: var(--forest-green) !important;
}

[data-theme="light"] .gp-shell .text-text-dark\/60,
[data-theme="light"] .console-shell .text-text-dark\/60 {
    color: var(--text-muted) !important;
}

/* Fix (R-CSS-3, 2026-09-03): generalised beyond the single /60 step above --
   see the DARK-mode comment on the matching block for why (/70 is
   template-authored, /80 added proportionally for family completeness).
   The light-sidebar surface pairs each step with the same forest-green
   color-mix math the unscoped `.text-primary/NN` family uses elsewhere in
   this file, rather than the flat --text-muted token (which is a single
   AA-tuned value, not a percentage scale).
   R-CSS-3 adversary round (2026-09-03): /40 and /50 members dropped here
   too -- against the light sidebar ground (#EFE7D6) /40 measures 2.28:1
   and /50 measures 2.90:1, both under the 4.5:1 text floor. /70 and /80
   remain the only new light-theme !important additions in this family;
   both clear 4.5:1, so they stay as the sanctioned family-completion fix
   alongside the pre-existing /60. */
[data-theme="light"] .gp-shell .text-text-dark\/70,
[data-theme="light"] .console-shell .text-text-dark\/70 {
    color: color-mix(in srgb, var(--forest-green) 70%, transparent) !important;
}

[data-theme="light"] .gp-shell .text-text-dark\/80,
[data-theme="light"] .console-shell .text-text-dark\/80 {
    color: color-mix(in srgb, var(--forest-green) 80%, transparent) !important;
}

/* ============================================================================
   Sidebar active-nav row — LOCKED aged-linen treatment (JTP ruling, aged-linen
   proof-page tagging 2026-08-19 + dashboard-chrome batch 2026-08-20).
   Replaces the rejected `bg-gold/10 text-gold` wash — JTP called it a
   "yellow haze" (Aug 17) and "too piss yellow" / "puke green" (Aug 18-19) —
   with the gold LEFT RAIL only (unchanged, `border-l-2 border-gold`) plus a
   barely-there linen-tint fill at the exact locked value,
   rgba(231,217,188,.09). Ink stays the SAME readable color the inactive rows
   already use (`.text-text-dark`, which the shell-scoped override above
   resolves to forest-green ink on the light sidebar and warm-linen ink on
   the dark/forest sidebar) — active reads as a quiet raise, not a hue
   change, so it needs no separate per-theme branch of its own. One class,
   applied by nav_gp.html, instead of 17 copies of `bg-gold/10 text-gold`. */
.gp-nav-active {
    background-color: rgba(231, 217, 188, 0.09);
}
/* t_f8dbea1c (audit C5): the fill above is 1.00:1 against the light sidebar,
   so the rail IS the current-page cue -- and raw gold (#C5A059) measured
   1.80:1 on the #E4DCCB sidebar, under the WCAG 2.2 SC 1.4.11 3:1 floor.
   --gold-accessible keeps the rail gold at 3.77:1 (3.76:1 on the row fill).
   Out-specifies `.border-gold` without !important. Light only: dark keeps
   the [data-theme="dark"] .gp-shell [class*="border-gold"] remap below
   (#AD9153 -- 3.86:1 / 4.79:1). */
[data-theme="light"] .gp-shell .gp-nav-active {
    border-left-color: var(--gold-accessible);
}

/* t_dd982e02: GP filter chips keyboard focus ring routed onto the theme-aware
   --surface-focus-ring token (forest in light, gold in dark) with a 2px offset.
   The 2px offset space of the card background separates the focus ring from the
   chip fill, ensuring >=3:1 contrast against both the chip fill and the adjacent
   card in light and dark for selected and unselected chips. */
.gp-shell .gp-txn-chips > button:focus-visible,
.gp-shell main button[aria-pressed]:focus-visible {
    outline: 2px solid var(--surface-focus-ring);
    outline-offset: 2px;
}

/* t_dd982e02 (Round 3): in light theme, forest-filled selected chips (aria-pressed="true")
   and the primary CTA button ("New Capital Call", scoped via [data-testid="transactions-page-actions"])
   have fill #0F2F24.
   A two-tone focus indicator combines:
   1. A 2px inner ring (box-shadow) using var(--burnished-gold) (#C5A059)
      reaching 5.88:1 contrast against the #0F2F24 chip/button fill (>= 3:1).
   2. A 2px outer outline using var(--surface-focus-ring) (#0F2F24) with 2px offset
      reaching 11.23:1 contrast against the adjacent linen card grounds (>= 3:1).
   WCAG 1.4.11 / 2.4.7 is satisfied against both chip fill and adjacent card. */
[data-theme="light"] .gp-shell .gp-txn-chips > button[aria-pressed="true"]:focus-visible,
[data-theme="light"] .gp-shell main button[aria-pressed="true"]:focus-visible,
[data-theme="light"] .gp-shell [data-testid="transactions-page-actions"] .cds-button--primary:focus-visible,
html:not([data-theme="dark"]) .gp-shell .gp-txn-chips > button[aria-pressed="true"]:focus-visible,
html:not([data-theme="dark"]) .gp-shell main button[aria-pressed="true"]:focus-visible,
html:not([data-theme="dark"]) .gp-shell [data-testid="transactions-page-actions"] .cds-button--primary:focus-visible {
    outline: 2px solid var(--surface-focus-ring);
    outline-offset: 2px;
    box-shadow: 0 0 0 2px var(--burnished-gold);
}

/* GP / Console shell fallback for the `text-primary` utility family.
   `text-primary` resolves to forest green (--color-primary === --forest-green,
   both #0F2F24) and is legible only on the light GP/console surfaces (bg-white /
   bg-background-light). When the compiled Tailwind asset is stale or unbuilt at
   runtime the utility is absent and these headings inherit the warm-linen body
   color, disappearing on light cards — the live regression on /gp/investors
   ("LP Command Insights"), /gp/backstage ("Income Statement", company name),
   /gp/audit-source ("Reports") and most of /gp/composer.

   These higher-specificity (0,2,0) rules restore the SAME value Tailwind emits,
   so they are a no-op when the utility is present and corrective when it is
   missing. They mirror the existing global .text-forest / .text-linen / .text-gold
   fallbacks above, which is why text-forest headings (e.g. the GP page h1 element) never
   vanished while text-primary headings did.

   CC6-2 (2026-07-07) — extended to .console-shell. console/base_console.html's
   page-header h1 (class=text-primary, rendered on a bg-[#F9F8F6] band inside
   the console-shell's bg-background-light canvas — e.g. ops/admin_gl_viewer.html
   "Live General Ledger") hits the SAME unlayered `h1..h6 { color: inherit }`
   trap: the h1 IS a heading element, so the unlayered rule targets it directly
   and always beats the layered `.text-primary` utility, leaving it to inherit
   the unlayered `body { color: var(--warm-linen) }` default and vanish on the
   near-white header band. Unlike the partners/CC4-4 fix (where <body> itself
   carried `text-primary` and a compound `.cloud-public.bg-linen` body rule was
   the right lever), console-shell's <body> carries no text color utility at
   all — the bug lives on descendant `.text-primary` headings, structurally
   identical to the pre-existing GP-shell case this block already fixes. So the
   coherent minimal extension is mirroring `.console-shell` into this SAME
   established `.gp-shell`/`.console-shell` fallback family (already paired for
   `.text-text-dark` / `.bg-background-light` two blocks above), not a new
   compound-body-class mechanism. The base rule is kept as its OWN standalone
   block (rather than comma-joined) so the pre-existing
   `tests/unit/test_template_alignment.py::test_conductive_css_defines_text_primary_shell_fallback`
   regex contract — which requires `.gp-shell .text-primary {` to appear as an
   exact, non-comma-joined selector — keeps passing unmodified. STALE NOTE
   (coordinator, 2026-09-03): this comment originally said console-shell had
   no [data-theme="dark"] canvas flip at all, so no dark-mode override was
   needed for THIS specific .text-primary rule. That premise no longer holds
   -- .console-shell now DOES get the full dark canvas treatment (page,
   elevated surfaces, text-primary family, border-gold, etc. — see the
   `.gp-shell .bg-background-light, ... .console-shell .bg-background-light`
   block further below and T23b's proof that console pages inherit the
   base.html theme toggle). The conclusion for THIS particular rule still
   holds though: `.text-primary` (forest-green) is a light-surface fallback
   only, and dark mode's own `.text-primary` remap lives in its own
   [data-theme="dark"] block elsewhere in this file, so no paired override
   belongs here — just the "no canvas flip exists" framing was wrong. */
.gp-shell .text-primary {
    color: var(--forest-green) !important;
}
.console-shell .text-primary {
    color: var(--forest-green) !important;
}

/* Fix (gate_theme_contrast.py precision fix, 2026-08-20): SAME
   unlayered-h1..h6-beats-layered-Tailwind-utility trap as the two
   .text-primary fallbacks immediately above, but for `.lp-shell` — which
   never got the equivalent fallback even though `.lp-shell` DOES have a
   [data-theme="dark"] `.text-primary` remap further below (~L1475). The
   improved gate's new heading-inherit model (a heading with no unlayered
   protective rule for a theme/shell is INERT — the type-selector always
   beats the layered utility) surfaced this as a real, previously-invisible
   LIGHT-theme regression across nearly every LP-portal page (base_lp.html's
   Concierge panel header, lp/dashboard.html, lp/share_center.html,
   lp/fund_wiring.html, lp/library.html, lp/profile.html, lp/my_accounts.html,
   lp/delegates.html, lp/capital_activity.html, lp/fund_detail.html,
   lp/import.html, stage_door/capital_account.html, ...): `<h2 class=
   "text-primary">` headings render on the light bg-background-light LP
   canvas but, absent this rule, inherit the unlayered `body { color:
   var(--warm-linen) }` default and vanish (measured ~1.13:1). Mirrors the
   established `.gp-shell`/`.console-shell` fallback exactly — own
   standalone block (not comma-joined), same value. */
.lp-shell .text-primary {
    color: var(--forest-green) !important;
}

/* Fix (CoS sweep remediation, 2026-08-05): SAME unlayered-h1..h6-beats-
   layered-Tailwind-utility trap as the .text-primary fallback immediately
   above, but for `.text-muted` — which never got the equivalent fallback.
   Confirmed live: gp/partials/backstage_gp_liquidity.html's h4.text-muted
   labels ("Probability of Full Liquidity", "Carry Estimate Range", "Risk
   Indicators", "Liquidity Year Distribution" — /gp/backstage) measured
   color EXACTLY equal to the warm-linen card background (ratio 1:1,
   invisible): the `h1,h2,h3,h4,h5,h6 { color: inherit }` rule above targets
   the h4 element directly and — being unlayered CSS vs. Tailwind's
   @layer-wrapped utilities — always wins regardless of specificity, so the
   h4 inherits `body { color: var(--warm-linen) }` instead of the compiled
   `.text-muted` utility's `#4A5C54`. --text-muted is a theme-invariant raw
   constant (line 31 above), so one flat rule (mirroring the .text-primary
   fallback's shape) is correct in both themes; dark theme already has its
   own separate [data-theme="dark"] .text-muted override further below
   (line ~730) which is unaffected by this addition. */
.gp-shell .text-muted {
    color: var(--text-muted) !important;
}
.console-shell .text-muted {
    color: var(--text-muted) !important;
}

/* Fix (R-CSS-3, tc_codemod_residue.json heading-inherits-shell-color, 2026-09-03):
   SAME unlayered-h1..h6-beats-layered-Tailwind-utility trap as the
   .text-primary / .text-muted fallbacks immediately above, but for
   `.text-on-primary` -- which console templates apply directly (no `dark:`
   prefix) to headings inside a `bg-forest text-on-primary` body_class
   (console/index.html, console/access_requests.html, console/proof.html,
   console/sessions.html). Only `.console-shell` is added here: the finding
   list names console templates exclusively for this rule, no `.gp-shell`
   template hits heading-inherits-shell-color for text-on-primary. */
.console-shell .text-on-primary {
    color: var(--color-on-primary, #EFE7D6) !important;
}

/* Fix (R-TC residue batch r1b5, 2026-09-03): console/access_requests.html,
   console/index.html, console/proof.html and console/sessions.html each
   override `body_class` outright (`bg-forest text-on-primary antialiased`),
   which had silently dropped the shared `.console-shell` marker
   base_console.html's own default body_class carries -- so every existing
   `.console-shell`-scoped fallback in this file (`.text-on-primary`,
   `.text-primary`, `.text-muted`, `.text-gold`, `.text-forest-mid`, ...),
   including the `.console-shell .text-on-primary` rule immediately above
   (added for these SAME four templates by an earlier batch), never actually
   matched their real <body>. Restored here (`console-shell` re-added to
   each of the four templates' own body_class override) rather than worked
   around, since these are real, load-bearing fallbacks, not just this
   rule's problem. `.console-shell` carries no styling of its own anywhere
   in this file (grep-verified: always a compound-selector scope hook, never
   a bare `.console-shell { ... }` rule), so restoring it is a pure
   scope-fix with no other side effect.

   `.text-ink` itself still had no such fallback. It resolves
   `--cads-theme-color-ink` -> `--color-primary` (forest-green) in LIGHT
   theme, `#F9F8F6` (near-white) in DARK -- i.e. it is supposed to track
   the shell's own canvas, light or dark. Restoring exactly that value (the
   SAME one Tailwind's own compiled `.text-ink` utility would already
   render, were it not defeated by the unlayered h1..h6 trap) is safe
   everywhere `.text-ink` appears in a console-shell page: a no-op on the
   ordinary light-canvas usage across the rest of the console (crm/*,
   sessions_table_partial.html, components/macros.html, the
   email_engagement/newsletter_builder/factory_model_split partials, ...),
   and corrective on every text-ink heading this same trap was silently
   defeating (index.html's CRM/Funds/Insights/Mission Control/About card
   titles included -- those sit on a `bg-linen/5` card, i.e. a light
   ground, where forest-green ink is the CORRECT reading, not an inversion). */
.gp-shell .text-ink,
.console-shell .text-ink,
.lp-shell .text-ink,
.portal-shell .text-ink {
    color: var(--cads-theme-color-ink) !important;
}

/* Fix (R-TC residue batch r1b5, 2026-09-03): the restoration immediately
   above is wrong for exactly one case on these same four pages -- the
   headline itself ("Access requests" / "Dashboard" / "Mission Control" /
   "Orchestration Sessions") sits directly on the pages' `bg-forest` fill,
   which -- unlike the shell's normal canvas -- does NOT flip with the
   theme: it is the SAME dark fill in both LIGHT and DARK mode. In LIGHT
   theme `--cads-theme-color-ink` is forest-green, the same hue as the fill
   itself, so the restoration above still renders it invisible (measured
   ~1.13:1) there specifically. Each of the four templates' own headline
   wrapper `<div>` (containing only the eyebrow label, the h1, and -- on
   access_requests.html -- the "Reviewing as" line; NOT the card grid,
   table, or any other content) picked up an explicit, redundant-but-honest
   `bg-forest` class of its own (visually a no-op -- the div already shows
   through to the same forest fill either way) so this second rule can
   select purely on real, in-file ancestry, scoped narrowly to just that
   wrapper: `.bg-forest .text-ink` matches only the headline (and, on
   access_requests.html, the "Reviewing as" span already fixed to
   `.text-gold` -- this rule and that class don't overlap). Declared AFTER
   the restoration rule above so normal CSS/gate tie-break (equal
   specificity, later source order wins) picks THIS value for the headline
   even though `.console-shell .text-ink` also technically matches it. */
.bg-forest .text-ink {
    color: var(--color-on-primary, #EFE7D6) !important;
}

/* Fix (card t_fk_a1d1e0f2): status text on fixed .bg-forest panels must clear
   WCAG AA (>= 4.5:1) in both light and dark themes. In light mode, default
   text-status-success (#1B4D3E) and text-status-error (#991B1B) are tuned for
   linen and fail contrast on forest (1.5:1 and 1.7:1).
   Remap .bg-forest status text to compliant dark-ground tokens:
   - success: leaf green #8FCB6B (7.52:1 on #0F2F24)
   - error: alert brick #B88D89 (4.96:1 on #0F2F24) */
.bg-forest .text-status-success {
    color: #8FCB6B !important;
}
.bg-forest .text-status-error {
    color: #B88D89 !important;
}

/* Fix (R-TC residue batch r1b3, 2026-09-03): SAME unlayered-h1..h6-beats-
   layered-Tailwind-utility trap as the `.console-shell .text-on-primary`
   fallback immediately above, extended to `.cloud-public` -- two
   cloud-public marketing headings sit directly on an OPAQUE forest
   (`bg-primary`) fill and used `text-ink` to try to read on it
   (cloud/request_access.html "Application Received" h3 + "Request
   Access" h3, ground `bg-primary`). `text-ink` resolves to
   `--cads-theme-color-ink`, which is forest-green in light -- i.e. the
   SAME hue as the fill it sits on, invisible regardless of the h1..h6
   trap; swapped to `text-on-primary` at the call sites for exactly this
   reason. `text-on-primary` (`--color-on-primary`, static warm-linen,
   defined once for both themes -- see its definition comment in
   input.css) is the correct token for text/icons on a forest fill in
   BOTH themes; this rule makes that render on cloud-public headings
   instead of silently inheriting via the unlayered h1..h6 rule.
   NOTE: investor_reporting.html's "Before Conductive" h4 step labels sit
   on a TRANSLUCENT `bg-primary/40` fill, not this opaque one -- the
   heaviest available ink (forest-green, this shell's ambient/heading-
   inert approximation already gives that exact color) only reaches
   3.70:1 there, under the 4.5:1 floor; no existing text token clears it
   on that blended ground without a new/darker color decision or
   restructuring the panel to an opaque fill, so that finding is left
   unresolved (see the batch r1b3 commit notes) rather than papered over
   here. */
.cloud-public .text-on-primary {
    color: var(--color-on-primary, #EFE7D6) !important;
}

.gp-shell .text-primary\/0,  .console-shell .text-primary\/0  { color: color-mix(in srgb, var(--forest-green) 0%,  transparent) !important; }
.gp-shell .text-primary\/15, .console-shell .text-primary\/15 { color: color-mix(in srgb, var(--forest-green) 15%, transparent) !important; }
.gp-shell .text-primary\/20, .console-shell .text-primary\/20 { color: color-mix(in srgb, var(--forest-green) 20%, transparent) !important; }
.gp-shell .text-primary\/25, .console-shell .text-primary\/25 { color: color-mix(in srgb, var(--forest-green) 25%, transparent) !important; }
.gp-shell .text-primary\/30, .console-shell .text-primary\/30 { color: color-mix(in srgb, var(--forest-green) 30%, transparent) !important; }
.gp-shell .text-primary\/35, .console-shell .text-primary\/35 { color: color-mix(in srgb, var(--forest-green) 35%, transparent) !important; }
.gp-shell .text-primary\/40, .console-shell .text-primary\/40 { color: color-mix(in srgb, var(--forest-green) 40%, transparent) !important; }
.gp-shell .text-primary\/45, .console-shell .text-primary\/45 { color: color-mix(in srgb, var(--forest-green) 45%, transparent) !important; }
.gp-shell .text-primary\/50, .console-shell .text-primary\/50 { color: color-mix(in srgb, var(--forest-green) 50%, transparent) !important; }
.gp-shell .text-primary\/55, .console-shell .text-primary\/55 { color: color-mix(in srgb, var(--forest-green) 55%, transparent) !important; }
.gp-shell .text-primary\/60, .console-shell .text-primary\/60 { color: color-mix(in srgb, var(--forest-green) 60%, transparent) !important; }
.gp-shell .text-primary\/65, .console-shell .text-primary\/65 { color: color-mix(in srgb, var(--forest-green) 65%, transparent) !important; }
.gp-shell .text-primary\/70, .console-shell .text-primary\/70 { color: color-mix(in srgb, var(--forest-green) 70%, transparent) !important; }
.gp-shell .text-primary\/75, .console-shell .text-primary\/75 { color: color-mix(in srgb, var(--forest-green) 75%, transparent) !important; }
.gp-shell .text-primary\/80, .console-shell .text-primary\/80 { color: color-mix(in srgb, var(--forest-green) 80%, transparent) !important; }
.gp-shell .text-primary\/85, .console-shell .text-primary\/85 { color: color-mix(in srgb, var(--forest-green) 85%, transparent) !important; }
.gp-shell .text-primary\/90, .console-shell .text-primary\/90 { color: color-mix(in srgb, var(--forest-green) 90%, transparent) !important; }

/* FIX (P2 light-mode sweep, 2026-08-03, B1 Defect 3 / SCORE-19..22 / B2-Q1
   token-level fix, not a call-site edit): the low-opacity `.text-primary/NN`
   steps above are a raw alpha blend of forest-green over the light warm-linen
   canvas. Below ~/65 that blend drops under WCAG AA 4.5:1 (measured:
   /25≈1.6:1, /40≈2.3:1, /50≈2.9:1, /60≈3.8:1 — matching the muted
   timestamps/source-tags/helper-copy the sweep found washed out across The
   Street and every other GP page using this shared muted-text utility;
   /70 and above already clear ≥5.0:1 and are left byte-unchanged). Rather
   than hand-edit the hundreds of templates using these classes, raise the
   TOKEN: in light theme, remap every sub-AA opacity step to the existing
   `--surface-text-muted` token, which already resolves to the dedicated
   WCAG-AA `--text-muted` (#4A5C54, 5.8:1 on warm-linen) color defined above
   for exactly this purpose. Mirrors the pre-existing dark-mode remap
   (`[data-theme="dark"] .gp-shell .text-primary\/45,... { color:
   var(--surface-text-muted) }` further below) — same mechanism, opposite
   theme. Higher specificity than the base (0,2,0) fallback rules directly
   above wins this override in light theme; dark theme and both themes' /70+
   steps are untouched. */
[data-theme="light"] .gp-shell .text-primary\/15,
[data-theme="light"] .console-shell .text-primary\/15,
[data-theme="light"] .gp-shell .text-primary\/20,
[data-theme="light"] .console-shell .text-primary\/20,
[data-theme="light"] .gp-shell .text-primary\/25,
[data-theme="light"] .console-shell .text-primary\/25,
[data-theme="light"] .gp-shell .text-primary\/30,
[data-theme="light"] .console-shell .text-primary\/30,
[data-theme="light"] .gp-shell .text-primary\/35,
[data-theme="light"] .console-shell .text-primary\/35,
[data-theme="light"] .gp-shell .text-primary\/40,
[data-theme="light"] .console-shell .text-primary\/40,
[data-theme="light"] .gp-shell .text-primary\/45,
[data-theme="light"] .console-shell .text-primary\/45,
[data-theme="light"] .gp-shell .text-primary\/50,
[data-theme="light"] .console-shell .text-primary\/50,
[data-theme="light"] .gp-shell .text-primary\/55,
[data-theme="light"] .console-shell .text-primary\/55,
[data-theme="light"] .gp-shell .text-primary\/60,
[data-theme="light"] .console-shell .text-primary\/60,
[data-theme="light"] .gp-shell .text-primary\/65,
[data-theme="light"] .console-shell .text-primary\/65 {
    color: var(--surface-text-muted) !important;
}

/* FIX (W2-D3, ux-gapclose 2026-08-06, JTP "select-all in PowerPoint" finding):
   `bg-primary/10` (Tailwind literal 10%-alpha forest-green) is a fixed,
   theme-blind fill used for the dashboard's "metric unavailable" skeleton
   chips (dashboard.html, 11 occurrences). Correct/near-invisible on the dark
   canvas it was tuned for; on the light/cream canvas it renders as a flat
   gray-green box. Light-mode-only override to the design system's own
   "inert/recessed surface" token — dark mode is untouched. */
[data-theme="light"] .gp-shell .bg-primary\/10,
[data-theme="light"] .console-shell .bg-primary\/10 {
    background-color: var(--surface-sunken) !important;
}

/* FIX (same sweep, B1 Defect 3): sidebar section headers (HOME / CAPITAL /
   FINANCIALS / INTELLIGENCE / Workspaces / Help & Account) and the
   "Conductive Admin" logo wordmark use the raw `.text-gold` utility
   (`--burnished-gold` #C5A059), which measures ~2.0:1 on the warm-linen
   sidebar in light theme — well under AA. Swap to the token this repo
   already designates for exactly this ("WCAG AA text gold",
   tailwind.config.js `gold-accessible: '#856A28'`), which measures ~4.1:1 —
   AA for large/bold text and a large improvement over the 2.0:1 original.
   Mirrors the pre-existing dark-mode direction of this same swap
   (`[data-theme="dark"] .gp-shell .text-gold-accessible { color:
   var(--surface-gold) }` further below bumps the accessible variant BACK UP
   to full burnished gold once the dark canvas makes it safe again). */
[data-theme="light"] .gp-shell .text-gold,
[data-theme="light"] .console-shell .text-gold {
    color: var(--gold-accessible) !important;
}

/* Fix (CoS sweep remediation, 2026-08-05): the .text-gold -> --gold-accessible
   swap above (documented right above) is correct for gold text sitting
   directly on the light warm-linen canvas, but it also caught .text-gold
   nested inside a .bg-primary dark-forest chip/pill (e.g. gp/measure.html's
   Deliverables-tab fund filters, "All Funds"/"All · N" buttons) — there the
   accessible-gold substitution is WRONG: raw gold on the dark .bg-primary
   fill measures 5.88:1 (good), the forced accessible variant only 2.82:1
   (fails AA for this small text). Verified live via authenticated Playwright
   capture of /gp/measure?tab=deliverables, light theme, 2026-08-05. Higher
   specificity (extra .bg-primary class) restores raw gold inside any
   .bg-primary-scoped widget without touching the general sidebar-text fix
   above. */
[data-theme="light"] .gp-shell .bg-primary.text-gold,
[data-theme="light"] .gp-shell .bg-primary .text-gold,
[data-theme="light"] .console-shell .bg-primary.text-gold,
[data-theme="light"] .console-shell .bg-primary .text-gold {
    color: var(--color-gold) !important;
}

/* Fix (R-TC residue batch r1b5, 2026-09-03): SAME nested-chip exception as
   the .bg-primary block immediately above, but for `.bg-forest` --
   console/access_requests.html and console/sessions.html put their table
   header cells' `.text-gold` (swapped from `.text-gold-accessible`, see
   this batch's commit) directly on a `<tr class="bg-forest">` row, and
   `--color-forest`/`--color-primary` are the same #0F2F24 fill, so the
   identical failure applies: the sidebar-text swap above forces
   `--gold-accessible` (2.26:1 on this dark row), but raw gold measures
   5.88:1 (good) -- the accessible substitution is wrong here for the same
   reason it is wrong on `.bg-primary`. Written WITHOUT a `.gp-shell`/
   `.console-shell` prefix (unlike the `.bg-primary` pair above) because
   these two templates override `body_class` outright (dropping the shared
   `.console-shell` marker -- see the `.text-ink` fix a few blocks above)
   so a shell-prefixed selector would never match their real `<body>`;
   `.bg-forest .text-gold` alone matches the real `<tr class="bg-forest">`
   ancestor directly, in any shell or none. */
[data-theme="light"] .bg-forest.text-gold,
[data-theme="light"] .bg-forest .text-gold {
    color: var(--color-gold) !important;
}

/* Piece 6 pocket 2 (MSG-Intern-to-EA-lightmode-inverse-and-small-lints
   -20260820.md): the exact same .text-gold -> --gold-accessible swap above,
   mirrored onto .lp-shell. .gp-shell/.console-shell got this fix in the CoS
   sweep (2026-08-05); .lp-shell never did, so raw text-gold (#C5A059,
   ~2.4:1 on warm-linen) has shipped unfixed on 52 sites / 21 files under
   templates/lp/ (chips/badges/icons — lp/funds, lp/dashboard,
   lp/share_center, lp/capital_activity, lp/fund_wiring, lp/import,
   lp/library, lp/fund_detail, etc.) despite .lp-shell already carrying a
   full DARK-mode remap family a few hundred lines below (search
   "[data-theme=\"dark\"] .lp-shell .text-gold-accessible"). This closes the
   light-mode half of that same shell's remap, same value, same technique,
   same L4/L5-in-the-lint-menu shape as the block above it. */
[data-theme="light"] .lp-shell .text-gold {
    color: var(--gold-accessible) !important;
}

/* Same nested-chip exception as the .gp-shell/.console-shell block above:
   .text-gold sitting on a .bg-primary dark-forest chip/pill inside
   .lp-shell (e.g. active-filter pills) must stay raw gold, not the
   accessible variant, for the identical contrast reason documented at the
   .gp-shell .bg-primary .text-gold rule above. */
[data-theme="light"] .lp-shell .bg-primary .text-gold {
    color: var(--color-gold) !important;
}

/* Composer disabled controls — readable disabled state without whole-button opacity.
   The composer's Generate/Distribute (gold) and Edit/Send-to-Lawyer (linen)
   `.composer-action` controls previously used `disabled:opacity-50`, which
   composites BOTH the text and the surface ~50% over the linen card and
   collapses apparent contrast to ~2:1 (the always-disabled Distribute button is
   the worst case). The templates now drop that opacity utility; these rules
   force full opacity and mute only the *surface* of disabled controls, keeping
   full-strength forest text well above WCAG AA.

   Scoped to .gp-shell .gp-composer-shell .composer-action so no other GP page's
   disabled buttons change, and using compiled/built-in CSS only (no dependency
   on Tailwind `disabled:bg-*` utilities that may be absent from output.css). */
.gp-shell .gp-composer-shell .composer-action:disabled,
.gp-shell .gp-composer-shell .composer-action[disabled] {
    opacity: 1 !important;
    cursor: not-allowed;
    color: var(--forest-green) !important;
}
.gp-shell .gp-composer-shell .composer-action.bg-gold:disabled,
.gp-shell .gp-composer-shell .composer-action.bg-gold[disabled] {
    background-color: color-mix(in srgb, var(--burnished-gold) 45%, var(--warm-linen)) !important;
}
.gp-shell .gp-composer-shell .composer-action.bg-background-light:disabled,
.gp-shell .gp-composer-shell .composer-action.bg-background-light[disabled] {
    background-color: color-mix(in srgb, var(--burnished-gold) 12%, var(--warm-linen)) !important;
    border-color: color-mix(in srgb, var(--burnished-gold) 30%, var(--warm-linen)) !important;
}

.bg-forest {
    background-color: var(--forest-green);
}

.bg-linen {
    background-color: var(--warm-linen);
}

.stripe-trust-mark-surface {
    background-color: var(--warm-linen) !important;
}

.border-gold {
    border-color: var(--burnished-gold);
}

.fed-card {
    background-color: var(--warm-linen);
    color: var(--forest-green);
    border: 1px solid var(--burnished-gold);
    border-radius: var(--radius);
    box-shadow: 0 10px 25px -5px rgba(197, 160, 89, 0.25); /* Gold shadow */
}

.fed-btn {
    background-color: var(--forest-green);
    color: var(--warm-linen);
    border: 1px solid var(--burnished-gold);
    border-radius: var(--radius);
    padding: 0.5rem 1rem;
    font-family: 'Geist', system-ui, sans-serif;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    cursor: pointer;
    transition: all 0.3s ease;
}

.fed-btn:hover {
    background-color: var(--burnished-gold);
    color: var(--forest-green);
}

.gold-divider {
    border-top: 1px solid var(--burnished-gold);
    opacity: 0.3;
}

/* Financial Typography */
.tabular-nums {
    font-family: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', monospace;
    font-variant-numeric: tabular-nums;
}

/* Material Icons base — the system icon font (classic filled set), self-hosted
   above. Use ligature names: <span class="material-icons">dashboard</span>.
   Single-color: forest on light, gold for accents/active. */
.material-icons {
    font-family: 'Material Icons';
    font-weight: normal;
    font-style: normal;
    font-size: 24px;
    line-height: 1;
    letter-spacing: normal;
    text-transform: none;
    display: inline-block;
    white-space: nowrap;
    direction: ltr;
    -webkit-font-feature-settings: 'liga';
    font-feature-settings: 'liga';
    -webkit-font-smoothing: antialiased;
}

/* HTMX Loading Indicators */
.htmx-indicator {
    display: none;
}
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
    display: inline-flex;
}

/* PD13 — Brand-aligned status indicators.
   DEPRECATED 2026-06-25: pill-shape (border-radius: 9999px) removed per JTP directive.
   Use rounded-sm (2px) status chips instead. border-radius now 2px.
   Use in place of Tailwind bg-{red,amber,blue,emerald,green}-{100..900} pills
   on non-CRM admin/public surfaces. */
.pill {
    display: inline-flex;
    align-items: center;
    padding: 0.125rem 0.5rem;
    border-radius: 2px;
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1rem;
    border: 1px solid transparent;
}
.pill-error {
    background-color: color-mix(in srgb, var(--status-error) 18%, var(--forest-green));
    /* V7a, 2026-09-03 (post-T0): was literal #F5C6C6 (H0 S70 L87 -- pink
       band) coloring the WORD on a dark forest-green ground. The token stays
       on background/border; the word goes linen, matching .pill-info /
       .pill-neutral below. */
    color: var(--warm-linen);
    border-color: color-mix(in srgb, var(--status-error) 60%, transparent);
}
.pill-warning {
    background-color: color-mix(in srgb, var(--burnished-gold) 18%, var(--forest-green));
    color: var(--burnished-gold);
    border-color: color-mix(in srgb, var(--burnished-gold) 40%, transparent);
}
.pill-success {
    background-color: color-mix(in srgb, var(--forest-mid) 35%, var(--forest-green));
    /* V2a/V7a, 2026-09-03 (post-T0): was literal #B5D8C5 (H147 S31 L78 --
       jade band) coloring the WORD on a dark forest-green ground. Matches
       .pill-info / .pill-neutral below. */
    color: var(--warm-linen);
    border-color: color-mix(in srgb, var(--forest-mid) 70%, transparent);
}
.pill-info {
    background-color: color-mix(in srgb, var(--warm-linen) 8%, var(--forest-green));
    color: var(--warm-linen);
    border-color: color-mix(in srgb, var(--burnished-gold) 30%, transparent);
}
.pill-neutral {
    background-color: color-mix(in srgb, var(--warm-linen) 5%, transparent);
    color: var(--warm-linen);
    border-color: color-mix(in srgb, var(--burnished-gold) 20%, transparent);
}
/* Light-surface variants for cards over linen backgrounds */
.pill-on-light-success {
    background-color: color-mix(in srgb, var(--forest-mid) 12%, var(--warm-linen));
    color: var(--forest-green);
    border-color: color-mix(in srgb, var(--forest-mid) 40%, transparent);
}
.pill-on-light-warning {
    background-color: color-mix(in srgb, var(--burnished-gold) 20%, var(--warm-linen));
    color: var(--gold-accessible);
    border-color: color-mix(in srgb, var(--burnished-gold) 50%, transparent);
}
.pill-on-light-error {
    background-color: color-mix(in srgb, var(--status-error) 12%, var(--warm-linen));
    color: var(--status-error);
    border-color: color-mix(in srgb, var(--status-error) 40%, transparent);
}
.pill-on-light-neutral {
    background-color: color-mix(in srgb, var(--forest-green) 6%, var(--warm-linen));
    color: var(--forest-green);
    border-color: color-mix(in srgb, var(--forest-green) 15%, transparent);
}

/* Disclosed-assumption callout block (e.g. K-1 fee math computed from the
   unprovisioned 2% default rate). A block, not prose — icon + bold headline
   + one line + a CTA. Semantic-status exception to gold-only accents; uses
   the --status-disclosure-alert tokens above. Reused by the corrected/
   resolved variant with --status-disclosure-resolved. */
.fee-disclosure-callout {
    border-color: var(--status-disclosure-alert);
    background-color: color-mix(in srgb, var(--status-disclosure-alert) 8%, var(--warm-linen));
}
.fee-disclosure-callout__icon,
.fee-disclosure-callout__headline,
.fee-disclosure-callout__cta {
    color: var(--status-disclosure-alert-fg);
}
.fee-disclosure-callout__cta:hover {
    color: var(--status-disclosure-alert);
}

.fee-disclosure-callout--resolved {
    border-color: var(--status-disclosure-resolved);
    background-color: color-mix(in srgb, var(--status-disclosure-resolved) 8%, var(--warm-linen));
}
.fee-disclosure-callout--resolved .fee-disclosure-callout__icon,
.fee-disclosure-callout--resolved .fee-disclosure-callout__headline,
.fee-disclosure-callout--resolved .fee-disclosure-callout__cta {
    color: var(--status-disclosure-resolved-fg);
}
.fee-disclosure-callout--resolved .fee-disclosure-callout__cta:hover {
    color: var(--status-disclosure-resolved);
}

/* Scrollbar styling to match theme */
::-webkit-scrollbar {
    width: 8px;
}
::-webkit-scrollbar-track {
    background: var(--warm-linen);
}
::-webkit-scrollbar-thumb {
    background: var(--burnished-gold);
    border-radius: var(--radius);
}

/* ============================================================================
   CADS Token Utility Classes — Foundation Layer (wave4e)
   Semantic `.cads-*` classes that expose brand CSS custom properties.
   GP templates migrate from ad-hoc Tailwind to these classes incrementally.
   SOURCE OF TRUTH: the :root block above. Never use hardcoded hex here.
   ============================================================================ */

/* -- Surfaces ---------------------------------------------------------------- */
.cads-bg-canvas        { background-color: var(--surface-canvas); }
.cads-bg-surface       { background-color: var(--bg-light); }
.cads-bg-surface-dark  { background-color: var(--bg-dark); }
.cads-bg-surface-sunken { background-color: var(--surface-sunken); }
.cads-bg-primary       { background-color: var(--forest-green); }
.cads-bg-primary-mid   { background-color: var(--forest-mid); }

/* -- Foreground -------------------------------------------------------------- */
.cads-text-on-light    { color: var(--fg-on-light); }
.cads-text-on-dark     { color: var(--fg-on-dark); }
.cads-text-muted       { color: var(--fg-muted-on-light); }
.cads-text-muted-dark  { color: var(--fg-muted-on-dark); }
.cads-text-gold        { color: var(--burnished-gold); }
.cads-text-gold-aa     { color: var(--gold-accessible); }

/* -- Borders ----------------------------------------------------------------- */
.cads-border-gold      { border-color: var(--burnished-gold); }
.cads-border-rule      { border-color: var(--rule-gold); }

/* -- Elevation --------------------------------------------------------------- */
.cads-shadow-card      { box-shadow: var(--shadow-card); }
.cads-shadow-panel     { box-shadow: var(--shadow-panel); }
.cads-shadow-modal     { box-shadow: var(--shadow-modal); }

/* -- Geometry ---------------------------------------------------------------- */
.cads-rounded          { border-radius: var(--radius); }
.cads-rounded-tight    { border-radius: var(--radius-tight); }

/* ============================================================================
   GP PORTAL — DARK THEME CONTENT FLIP (Wave-0 Pass-2 LIGHT/DARK system)
   ----------------------------------------------------------------------------
   These rules re-skin the GP console CONTENT area when the document carries
   [data-theme="dark"]. They are scoped to .gp-shell so NO public/marketing or
   CRM-console page is affected, and they are DARK-ONLY so the LIGHT theme (and
   every existing contrast/template test) is byte-for-byte unchanged.

   What flips:  page canvas, cards/panels/headers, tables, primary + muted text,
                hairline borders, inputs.
   What stays:  the forest-green SIDEBAR + mobile drawer + Ryan trigger
                (.bg-primary / .bg-forest on chrome) — the brand anchor.

   Surfaces resolve through the --surface-* tokens defined in :root /
   [data-theme="dark"] above. Specificity (0,2,0)+ and !important match the
   existing .gp-shell .text-primary fallbacks so these win over utility classes
   whether or not the compiled Tailwind asset is fresh.
   ============================================================================ */

/* Page canvas — the GP shell's outer wrappers use bg-background-light. In dark
   this becomes the deep green-black PAGE. (Sidebar bg-primary is NOT matched.)
   The compound `.gp-shell.bg-background-light` selector also covers the case
   where the shell element itself carries the canvas class (the base_gp <body>),
   not just descendant wrappers.
   R-CSS-3 adversary round (2026-09-03): the .console-shell arm of this rule
   (and its /30, /40 opacity-step siblings below) was reverted -- it
   contradicted the still-live "No console cream-forcer" contract asserted by
   tests/gp_portal/test_lane_a_designsystem.py::
   test_conductive_css_surface_tokens_and_dark_rules. Console shell keeps its
   pre-existing (non-canvas-forced) dark background-light behavior. */
[data-theme="dark"] .gp-shell .bg-background-light,
[data-theme="dark"] .gp-shell.bg-background-light,
[data-theme="dark"] .gp-shell .cads-bg-canvas,
[data-theme="dark"] .console-shell .cads-bg-canvas {
    background-color: var(--surface-canvas) !important;
}

/* Dropzone hover & opacity handling in dark mode (fixes 294-site white fog / hover flash) */
[data-theme="dark"] .gp-shell .hover\:bg-background-light:hover,
[data-theme="dark"] .console-shell .hover\:bg-background-light:hover {
    background-color: var(--surface-elevated) !important;
}
[data-theme="dark"] .gp-shell .bg-background-light\/30 {
    background-color: color-mix(in srgb, var(--surface-elevated) 30%, transparent) !important;
}
[data-theme="dark"] .gp-shell .bg-background-light\/40 {
    background-color: color-mix(in srgb, var(--surface-elevated) 40%, transparent) !important;
}

/* Elevated surfaces — cards, the page header bar, the AI/drill panels, toasts,
   mobile header/bottom-nav, modal sheets. All authored as bg-white / bg-linen.
   In dark they become forest-mid cards that read above the page. */
[data-theme="dark"] .gp-shell .bg-white,
[data-theme="dark"] .gp-shell .bg-linen,
[data-theme="dark"] .gp-shell .cads-bg-surface,
[data-theme="dark"] .gp-shell .fed-card,
[data-theme="dark"] .console-shell .bg-white,
[data-theme="dark"] .console-shell .bg-linen,
[data-theme="dark"] .console-shell .cads-bg-surface,
[data-theme="dark"] .console-shell .fed-card {
    background-color: var(--surface-elevated) !important;
    color: var(--surface-text);
}

/* Primary content text — text-primary / text-forest headings and body copy
   flip to warm linen. (Overrides the light .gp-shell .text-primary rule above
   via equal specificity + later source order.)
   R-CSS-4 (2026-09-04): .text-primary\/90 (defined light-only at ~line 702
   as a raw 90%-opacity forest-green blend, one step up from the /85 top of
   the muted family below) never had a dark remap at all -- it fell through
   to the light rule and rendered forest-on-forest (console CRM email-events
   "Delivered" badge, contact_email_events.html). 90% opacity reads as
   effectively full-strength body copy, not muted secondary text, so it
   joins this 100%-target group (var(--surface-text)) rather than the
   /40-/85 muted family below. */
[data-theme="dark"] .gp-shell .text-primary,
[data-theme="dark"] .gp-shell .text-forest,
[data-theme="dark"] .gp-shell .text-primary\/90,
[data-theme="dark"] .gp-shell .cads-text-on-light,
[data-theme="dark"] .console-shell .text-primary,
[data-theme="dark"] .console-shell .text-forest,
[data-theme="dark"] .console-shell .text-primary\/90,
[data-theme="dark"] .console-shell .cads-text-on-light {
    color: var(--surface-text) !important;
}

/* Muted/secondary text (forest-at-opacity utilities) → readable linen-muted.
   P8 feed hygiene (2026-08-20): added .console-shell to the .text-muted /
   .cads-text-muted selectors — the Street freshness bar's "Stale" state
   (components/_street_freshness_bar.html) renders in both .gp-shell
   (gp/partials/street_feed.html) and .console-shell
   (console/partials/street_feed.html), and .text-muted is now load-bearing
   there (see below), so both shells need the same dark remap. */
[data-theme="dark"] .gp-shell .text-primary\/40,
[data-theme="dark"] .gp-shell .text-primary\/50,
[data-theme="dark"] .gp-shell .text-primary\/60,
[data-theme="dark"] .gp-shell .text-primary\/70,
[data-theme="dark"] .gp-shell .text-primary\/75,
[data-theme="dark"] .gp-shell .text-primary\/80,
[data-theme="dark"] .gp-shell .text-primary\/85,
[data-theme="dark"] .console-shell .text-primary\/40,
[data-theme="dark"] .console-shell .text-primary\/50,
[data-theme="dark"] .console-shell .text-primary\/60,
[data-theme="dark"] .console-shell .text-primary\/70,
[data-theme="dark"] .console-shell .text-primary\/75,
[data-theme="dark"] .console-shell .text-primary\/80,
[data-theme="dark"] .console-shell .text-primary\/85,
[data-theme="dark"] .gp-shell .text-muted,
[data-theme="dark"] .gp-shell .cads-text-muted,
[data-theme="dark"] .console-shell .text-muted,
[data-theme="dark"] .console-shell .cads-text-muted {
    color: var(--surface-text-muted) !important;
}

/* Fix (CoS sweep remediation, 2026-08-05): `.text-subtle` (defined once at
   line 32 above as the theme-invariant raw brand constant `--text-subtle:
   #6B7A73`, and applied via app_services/static/src/input.css:134-135) was
   never remapped in this dark-override block, so it stayed forest-muted-on-
   forest and vanished on the dark canvas (gp/measure.html,
   gp/partials/backstage_gp_liquidity.html, gp/reports_legacy, etc). The
   theme-aware sibling `--surface-text-subtle` already exists and is
   correctly dark-aware (see lines 125/138/153/174) — reuse it here, same
   pattern as the .text-muted rule directly above. */
[data-theme="dark"] .gp-shell .text-subtle,
[data-theme="dark"] .console-shell .text-subtle {
    color: var(--surface-text-subtle) !important;
}

/* Secondary text authored at the OTHER forest-opacity steps that the block
   above did not enumerate (/45 /55 /65). On the light console these read as
   readable secondary copy; without a dark remap they stay forest-on-forest and
   vanish. Same linen-muted target, DARK-ONLY + .gp-shell-scoped, light theme
   byte-for-byte unchanged. (Closes GP-core dark contrast debt: stat-card
   subtext, fund KPIs, drop-zone help, txn subtitles.) */
[data-theme="dark"] .gp-shell .text-primary\/45,
[data-theme="dark"] .gp-shell .text-primary\/55,
[data-theme="dark"] .gp-shell .text-primary\/65,
[data-theme="dark"] .console-shell .text-primary\/45,
[data-theme="dark"] .console-shell .text-primary\/55,
[data-theme="dark"] .console-shell .text-primary\/65 {
    color: var(--surface-text-muted) !important;
}

/* Faint caption/metadata text (forest at /15 /20 /25 /30 /35). These are the
   lowest tier of the light hierarchy; map to the dimmer linen-subtle token so
   the type hierarchy is preserved while staying legible on the dark ground. */
[data-theme="dark"] .gp-shell .text-primary\/15,
[data-theme="dark"] .gp-shell .text-primary\/20,
[data-theme="dark"] .gp-shell .text-primary\/25,
[data-theme="dark"] .gp-shell .text-primary\/30,
[data-theme="dark"] .gp-shell .text-primary\/35,
[data-theme="dark"] .console-shell .text-primary\/15,
[data-theme="dark"] .console-shell .text-primary\/20,
[data-theme="dark"] .console-shell .text-primary\/25,
[data-theme="dark"] .console-shell .text-primary\/30,
[data-theme="dark"] .console-shell .text-primary\/35 {
    color: var(--surface-text-subtle) !important;
}

/* Gold accent text — the bright burnished gold reads fine on dark, so let the
   AA-on-light accent (gold-accessible) bump back up to gold-400, not plain
   burnished gold: `var(--surface-gold)`/`--burnished-gold` (#C5A059)
   measures only 3.92:1 on the forest-mid card, under the 4.5:1 body-text
   floor per the R-CSS-3 comment further above in this file; gold-400
   (#D4B472) clears 4.85:1 on forest-mid / 7.28:1 on page.
   Fix (review-r1), 2026-09-04: was `var(--gold-accessible)`, which relied
   on that custom property itself being redefined to #D4B472 in dark theme
   -- removed per the gate's committed contract that --gold-accessible is a
   theme-invariant raw constant (see its :root declaration). Literal here
   instead, matching the `.cloud-public .text-gold-accessible` rule above
   (not `var(--color-gold-400)`: that custom property lives in input.css's
   @theme, not this file's own scope, and L10 doctrine keeps dark literals
   hand-synced rather than reaching across files). */
[data-theme="dark"] .gp-shell .text-gold-accessible,
[data-theme="dark"] .console-shell .text-gold-accessible {
    color: #D4B472 !important;
}

/* Generated brand/status text utilities that are safe on light linen need the
   same dark GP-shell remap as text-primary/text-forest. Without this scoped
   override, Tailwind v4 generated forest/status utilities render forest-on-
   forest in GP dark mode. */
[data-theme="dark"] .gp-shell .text-forest-mid,
[data-theme="dark"] .gp-shell .text-status-success,
[data-theme="dark"] .console-shell .text-forest-mid,
[data-theme="dark"] .console-shell .text-status-success {
    color: var(--surface-text) !important;
}

/* Coordinator 2026-09-03 (T4/T4b theme_contrast fingerprints): `.text-status-success`
   here wins over the shared text-forest-mid/text-status-success rule directly
   above (same specificity, later in the cascade). `--gold-accessible`
   measured only 2.82:1 on the page ground for warning text, so per the
   brief's fallback this uses `--burnished-gold` instead (5.88:1 page /
   3.92:1 card). `.text-status-error` is intentionally NOT remapped here to
   a colored red -- V7a already ruled dark-mode red is an accent
   (dot/border/tint), never the words, and the existing
   `--surface-status-error` remap two blocks below already resolves to ink
   (#F9F8F6), satisfying that ruling.

   R-CSS-3 (2026-09-03) correction: the success-text leg above originally
   read `color: var(--color-status-ok)` (leaf green #8FCB6B on the words
   themselves) -- that put the hue on the WORDS, which V7a reserves for
   dots/borders/icons only (see V2a: leaf green is for those, not text).
   Retuned to ink (#F9F8F6) below, matching how .text-status-error already
   resolves via --surface-status-error. `.border-status-success` and
   `.bg-status-success` (dot/icon-well use) keep the leaf-green hue per
   V2a -- added just below. */
[data-theme="dark"] .gp-shell .text-status-success,
[data-theme="dark"] .console-shell .text-status-success {
    color: #F9F8F6 !important;
}
[data-theme="dark"] .gp-shell .border-status-success,
[data-theme="dark"] .console-shell .border-status-success {
    border-color: #8FCB6B !important;
}
/* .bg-status-success covers small dot/icon-well uses (status dots, avatar
   wells) by default. Two known large-fill sites -- admin/panels/kill-switch.html's
   toggle button and console/crm/tasks.html's "Done" buttons (bg-status-success
   + text-white), gp/transactions.html's filter pills (bg-status-success +
   text-on-primary) -- get a 22% tint instead so white/on-primary text over
   the fill keeps working; solid leaf green under white text fails contrast. */
[data-theme="dark"] .gp-shell .bg-status-success,
[data-theme="dark"] .console-shell .bg-status-success {
    background-color: #8FCB6B !important;
}
[data-theme="dark"] .gp-shell .bg-status-success.text-white,
[data-theme="dark"] .console-shell .bg-status-success.text-white,
[data-theme="dark"] .gp-shell .bg-status-success.text-on-primary,
[data-theme="dark"] .console-shell .bg-status-success.text-on-primary {
    background-color: color-mix(in srgb, #8FCB6B 22%, transparent) !important;
}
/* R-CSS-3 (2026-09-03): --burnished-gold measured only 3.92:1 on the
   forest-mid card, under the 4.5:1 body-text floor -- gold-400 (#D4B472)
   clears 4.85:1 on forest-mid / 7.28:1 on the page ground. Literal (not
   var(--color-gold-400)): that token lives in input.css's @theme, outside
   this file's own scope. */
[data-theme="dark"] .gp-shell .text-status-warning,
[data-theme="dark"] .console-shell .text-status-warning {
    color: #D4B472 !important;
}

/* P8 feed hygiene (2026-08-20): `.text-error-600` (Tailwind --color-error-600
   #A33232, input.css) had no dark-theme remap. Measured on the dark
   --surface-elevated card (forest-mid #1B4D3E) it renders at ~1.4:1 —
   effectively invisible. This is load-bearing on the Street freshness bar's
   "Unavailable" state, where the leading-dot orb was removed and plain text
   is now the ONLY signal (see components/_street_freshness_bar.html). Same
   .gp-shell/.console-shell scoping as the text-primary/text-subtle remaps
   above; targets the new --surface-status-error token (5.65:1 on dark,
   6.45:1 on light — see :root/[data-theme] definitions).

   `.text-status-error` (raw --status-error #991B1B, conductive.css :root)
   joins this same remap: market_feed.html's OWN top-of-feed freshness bar
   (a separate, older markup block from the shared
   components/_street_freshness_bar.html partial fixed above — both render
   an "Unavailable" state) uses `.text-status-error` for the identical
   purpose and had the identical gap — no dark remap at all, 5.96:1 light /
   1.74:1 dark on the theme canvas. Same target token, same fix, since both
   classes carry the same semantic meaning (status-error text) even though
   they resolve from different --color-* names. */
/* R-CSS-3 (2026-09-03): `.text-error-500` (--color-error-500 #AF4D4D) and
   `.text-error-700` (--color-error-700 #991B1B, same base hex as
   --status-error) had no dark remap -- same invisible-on-forest-mid gap as
   .text-error-600/.text-status-error above. Same target token, same fix. */
[data-theme="dark"] .gp-shell .text-error-600,
[data-theme="dark"] .console-shell .text-error-600,
[data-theme="dark"] .gp-shell .text-error-500,
[data-theme="dark"] .console-shell .text-error-500,
[data-theme="dark"] .gp-shell .text-error-700,
[data-theme="dark"] .console-shell .text-error-700,
[data-theme="dark"] .gp-shell .text-error-800,
[data-theme="dark"] .console-shell .text-error-800,
[data-theme="dark"] .gp-shell .text-status-error,
[data-theme="dark"] .console-shell .text-status-error {
    color: var(--surface-status-error) !important;
}

/* Fix (R-GP re-review card t_fk_d6ab7847): In dark mode, AML exception queue
   error states pair text-error-700 with bg-error-50 / border-error-200 to
   guarantee accessible contrast (>= 4.5:1) while communicating error and
   avoiding global unscoped overrides. */
[data-theme="dark"] #aml-exception-queue [data-testid="aml-exception-load-error"] p.text-error-700,
[data-theme="dark"] #aml-exception-queue [data-testid="aml-screening-history-error"] {
    color: var(--status-error) !important;
}

/* Fix (R-TC residue batch r1b5, 2026-09-03): the dark override immediately
   above assumes the usual case -- a status-error surface that itself flips
   to a dark card in dark theme, so the near-white `--surface-status-error`
   swap is what stays readable on it. console/crm/company_detail.html's
   inline "Add New Contact" validation banner breaks that assumption: it
   sits on `bg-error-50 border-error-200`, a light alert-tint pair with NO
   dark-theme remap of its own (unlike `bg-status-error`/the disclosure-
   callout surfaces), so its ground stays the SAME light pink-tan in BOTH
   themes (measured identical, ~#E6D3C3, in this gate's own light/dark
   ground resolution). The blanket swap above still fires here, though,
   leaving the banner text at ~1.37:1 on a ground that never actually went
   dark. Restores the ORIGINAL (light-theme, --color-error-700 #991B1B)
   value for the one ancestor context where the swap's premise is false --
   higher specificity (extra `.bg-error-50` class) wins over the general
   rule above without touching the normal (correct) case elsewhere. */
[data-theme="dark"] .bg-error-50.text-error-700,
[data-theme="dark"] .bg-error-50 .text-error-700 {
    color: #991B1B !important;
}

/* Fix (R-TC residue batch r3b2, 2026-09-03): SAME `bg-error-50`-never-flips-
   dark exception as the `.text-error-700` override immediately above, but
   for `.text-error-600` -- gp/backstage.html's QuickBooks "Disconnect"
   button (`text-error-600 dark:text-on-primary` on `bg-error-50
   border-error-500/40`) hits the blanket `[data-theme="dark"] .gp-shell
   .text-error-600` swap above, which lands `--surface-status-error`
   (near-white, tuned for a ground that actually goes dark) on this
   never-flipping light ground -- 1.37:1. The template's own `dark:
   text-on-primary` attempt is a layered Tailwind utility, so it loses to
   the unlayered blanket rule regardless (same reason the r1b5 fix above
   leaves company_detail.html's dead `dark:text-on-primary` in place rather
   than removing it). Restores the theme-invariant `--color-error-600`
   literal for this one non-flipping-ground ancestor context, same
   mechanism as the `.text-error-700` override above. */
[data-theme="dark"] .bg-error-50.text-error-600,
[data-theme="dark"] .bg-error-50 .text-error-600 {
    color: var(--color-error-600) !important;
}

/* Fix (R-TC residue batch r1b7, 2026-09-03): console/crm/tasks.html's
   Overdue Tasks banner heading (`h3.text-error-800` inside `bg-error-50
   border-error-200`) hits heading-inherits-shell-color in BOTH themes --
   `.gp-shell`/`.console-shell` never got a base (theme-unscoped)
   `.text-error-800` fallback (only the dark-remap block above exists), so
   the unlayered `h1..h6 { color: inherit }` rule wins outright in light,
   leaving the heading at the ambient body color (1.18:1). Mirrors the
   `.gp-shell .text-primary` / `.console-shell .text-primary` base-fallback
   pattern (standalone, non-comma-joined blocks) with the theme-invariant
   `--color-error-800` literal (#821717, 6.94:1 on this banner's own
   `bg-error-50` #E6D3C3 ground in EITHER theme -- see the .bg-error-50
   `.text-error-700` note above for why this ground never flips dark). */
.gp-shell .text-error-800 {
    color: var(--color-error-800) !important;
}
.console-shell .text-error-800 {
    color: var(--color-error-800) !important;
}

/* Fix (R-TC residue batch r1b7, 2026-09-03): SAME `bg-error-50`-never-flips-
   dark exception as the `.text-error-700` rule immediately above, but for
   `.text-error-800` -- once the base fallback two blocks up un-hijacks the
   heading from `h1..h6 { color: inherit }`, the general dark blanket
   further above (`[data-theme="dark"] .console-shell .text-error-800`,
   same 3-class specificity) would still win on source order and swap in
   `--surface-status-error` (near-white, tuned for a ground that actually
   goes dark) against this banner's still-light ground -- 1.37:1. Restores
   the theme-invariant `--color-error-800` literal for this one
   non-flipping-ground ancestor context, same mechanism as the
   `.text-error-700` override above. */
[data-theme="dark"] .bg-error-50 .text-error-800 {
    color: var(--color-error-800) !important;
}

/* R-CSS-3 (2026-09-03): `.bg-error-100` (--color-error-100 #E0C2B4) had no
   dark remap anywhere in the file -- on the forest-mid card the pale tan
   fill and the ink text inside it (console/crm/merge_preview.html's "Loser
   (will be deleted)" badge, gp/backstage.html, gp/voice_sessions.html, and
   several console/crm badge sites all pair it with text-error-600/700/800)
   both read wrong against dark. V7a tint ceiling: 22% mix of brick (#C0453B,
   the dark status-error accent, outside the pink band) over transparent.
   Badge text inside is covered by the .text-error-600/700/800/.text-status-
   error ink rule directly above -- .text-error-800 (console/crm badges,
   macros.html Lead Score badge + generic badge() macro, contact_email_events
   .html "Bounced" pill) was added to that remap in the R-CSS-3 adversary
   round (2026-09-03) after this new dark bg-error-100 fill made the
   un-remapped literal --color-error-800 (#821717) essentially invisible
   against it (~1.1:1). */
[data-theme="dark"] .gp-shell .bg-error-100,
[data-theme="dark"] .console-shell .bg-error-100 {
    background-color: color-mix(in srgb, #C0453B 22%, transparent) !important;
}

/* Fix (CoS sweep remediation, 2026-08-05): the /40 and /70 opacity-variant
   remap above missed `.text-forest-mid/80`, which
   app_services/templates/gp/partials/market_feed.html's `provenance_rail`
   macro uses for the "Live" badge. In dark theme that class fell through to
   Tailwind's raw color-mix (forest-mid at 80% opacity) rendered on the dark
   forest card behind it — measured ratio 1.38:1 (invisible). Add \/80 to the
   selector list, same declaration and same --surface-text-muted target as
   its /40 and /70 siblings in the same class family. */
[data-theme="dark"] .gp-shell .text-forest-mid\/40,
[data-theme="dark"] .gp-shell .text-forest-mid\/70,
[data-theme="dark"] .gp-shell .text-forest-mid\/80,
[data-theme="dark"] .console-shell .text-forest-mid\/40,
[data-theme="dark"] .console-shell .text-forest-mid\/70,
[data-theme="dark"] .console-shell .text-forest-mid\/80 {
    color: var(--surface-text-muted) !important;
}

/* Hairline borders — gold-at-low-opacity rules get a touch more presence on the
   darker field so card edges stay legible. Covers border-gold + the /NN variants
   and divide-gold table row rules. */
[data-theme="dark"] .gp-shell [class*="border-gold"],
[data-theme="dark"] .console-shell [class*="border-gold"] {
    border-color: var(--surface-border) !important;
}
[data-theme="dark"] .gp-shell [class*="divide-gold"] > :not([hidden]) ~ :not([hidden]),
[data-theme="dark"] .console-shell [class*="divide-gold"] > :not([hidden]) ~ :not([hidden]) {
    border-color: var(--surface-border) !important;
}
/* V7 (status-tag border invisibility): border-forest/NN + border-mist/NN had
   no dark remap anywhere in the file (grep confirmed 0 hits before this
   package). status_tag.html's non-error tones and several table/card
   dividers author these classes; give them the same visible linen-tinted
   edge treatment as border-gold above.
   Residual round (2026-09-03): raised 20% -> 45% -- 20% measured ~1.6-1.7:1
   against the raised dark card/page, still under the 1.5:1 floor's margin of
   safety; 45% measures ~3.2:1 on card / ~4.2:1 on page. */
[data-theme="dark"] .gp-shell [class*="border-forest"],
[data-theme="dark"] .console-shell [class*="border-forest"],
[data-theme="dark"] .gp-shell [class*="border-mist"],
[data-theme="dark"] .console-shell [class*="border-mist"] {
    border-color: color-mix(in srgb, #F9F8F6 45%, transparent) !important;
}

/* Table zebra / sunken wells — common Tailwind neutral stripes inside the GP
   shell sit on the elevated card; nudge them to the sunken token so striping
   stays visible without going pure-white. */
[data-theme="dark"] .gp-shell .bg-gray-50,
[data-theme="dark"] .gp-shell .bg-gray-100,
[data-theme="dark"] .gp-shell .bg-neutral-50,
[data-theme="dark"] .gp-shell .bg-neutral-100,
[data-theme="dark"] .gp-shell .bg-stone-50,
[data-theme="dark"] .gp-shell .cads-bg-surface-sunken,
[data-theme="dark"] .console-shell .bg-gray-50,
[data-theme="dark"] .console-shell .bg-gray-100,
[data-theme="dark"] .console-shell .bg-neutral-50,
[data-theme="dark"] .console-shell .bg-neutral-100,
[data-theme="dark"] .console-shell .bg-stone-50,
[data-theme="dark"] .console-shell .cads-bg-surface-sunken {
    background-color: var(--surface-sunken) !important;
}

/* Form controls in the content area — inputs/selects/textarea authored for the
   light console default to forest text on white. On the dark card surface, give
   them the sunken fill + linen text so values stay visible. (Forest-on-forest
   chrome inputs, e.g. the Ryan compose bar, are unaffected — they aren't white.)

   SCOPED TO TEXT-LIKE INPUTS ONLY: checkbox and radio inputs are explicitly
   excluded here so the browser renders them natively in dark mode without
   background-color interference. If checkbox/radio appearance is desired, use
   accent-color on those elements separately. */
[data-theme="dark"] .gp-shell input[type="text"],
[data-theme="dark"] .gp-shell input[type="email"],
[data-theme="dark"] .gp-shell input[type="number"],
[data-theme="dark"] .gp-shell input[type="search"],
[data-theme="dark"] .gp-shell input[type="tel"],
[data-theme="dark"] .gp-shell input[type="password"],
[data-theme="dark"] .gp-shell input[type="url"],
[data-theme="dark"] .gp-shell input[type="date"],
[data-theme="dark"] .gp-shell input[type="datetime-local"],
[data-theme="dark"] .gp-shell input[type="month"],
[data-theme="dark"] .gp-shell input[type="week"],
[data-theme="dark"] .gp-shell input[type="time"],
[data-theme="dark"] .gp-shell input:not([type]),
[data-theme="dark"] .gp-shell select,
[data-theme="dark"] .gp-shell textarea,
[data-theme="dark"] .console-shell input[type="text"],
[data-theme="dark"] .console-shell input[type="email"],
[data-theme="dark"] .console-shell input[type="number"],
[data-theme="dark"] .console-shell input[type="search"],
[data-theme="dark"] .console-shell input[type="tel"],
[data-theme="dark"] .console-shell input[type="password"],
[data-theme="dark"] .console-shell input[type="url"],
[data-theme="dark"] .console-shell input[type="date"],
[data-theme="dark"] .console-shell input[type="datetime-local"],
[data-theme="dark"] .console-shell input[type="month"],
[data-theme="dark"] .console-shell input[type="week"],
[data-theme="dark"] .console-shell input[type="time"],
[data-theme="dark"] .console-shell input:not([type]),
[data-theme="dark"] .console-shell select,
[data-theme="dark"] .console-shell textarea {
    background-color: var(--surface-sunken) !important;
    color: var(--surface-text) !important;
}
[data-theme="dark"] .gp-shell ::placeholder,
[data-theme="dark"] .console-shell ::placeholder {
    color: var(--text-muted-on-inverse) !important;
}

/* Excel import preview checkboxes: forest green in light theme (11.23:1 on linen),
   burnished gold in dark theme (3.92:1 on forest-mid card, resolving P1 contrast).
   Scoped to .gp-shell #excel-import-preview .preview-checkbox per lead directive (2026-09-13). */
.gp-shell #excel-import-preview .preview-checkbox {
    accent-color: var(--forest-green);
}
[data-theme="dark"] .gp-shell #excel-import-preview .preview-checkbox {
    accent-color: var(--burnished-gold);
}

/* ── DarkGlassPurge (campaign conductive-cloud-ui-20260620) ──────────────────
   Kill the translucent "glass" bars on dark GP surfaces. The widget toolbar
   header bars, the Intelligence-Highlights signal cards, and the Concierge CTA
   all paint with bg-background-light/{50,60,70} opacity utilities that the
   dark .gp-shell remap above does NOT cover (it only remaps the solid
   .bg-background-light). On the forest canvas those opacity tints read as
   washed-out frosted glass. Convert them to SOLID forest-mid (#1B4D3E,
   --surface-elevated) with a ghost-gold border + subtle shadow, per the
   "kill glass on content cards" ruling. Dark-only — light mode is byte-unchanged. */
[data-theme="dark"] .gp-shell .bg-background-light\/50,
[data-theme="dark"] .gp-shell .bg-background-light\/60,
[data-theme="dark"] .gp-shell .bg-background-light\/70 {
    background-color: var(--surface-elevated) !important; /* #1B4D3E solid forest-mid */
}
/* Decision-001 = B (JTP, 2026-06-24): thin gold outline + soft shadow on ALL dark GP
   surfaces — the widget toolbar header bars (/50) AND the content cards (/60,/70) — so
   each reads as a crisp, lifted card. 1px shorthand forces a visible hairline even where
   the utility set no border-width (the toolbar bars). */
[data-theme="dark"] .gp-shell .bg-background-light\/50,
[data-theme="dark"] .gp-shell .bg-background-light\/60,
[data-theme="dark"] .gp-shell .bg-background-light\/70 {
    border: 1px solid var(--surface-border) !important;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.28) !important;
}
/* In-card section-header strips & table heads — stay quiet in dark mode (transparent fill + bottom border only, no box border or shadow) */
[data-theme="dark"] .gp-shell div.bg-background-light\/50.border-b,
[data-theme="dark"] .gp-shell div.bg-background-light\/60.border-b,
[data-theme="dark"] .gp-shell div.bg-background-light\/70.border-b,
[data-theme="dark"] .gp-shell th.bg-background-light\/50,
[data-theme="dark"] .gp-shell th.bg-background-light\/60,
[data-theme="dark"] .gp-shell thead.bg-background-light {
    background-color: transparent !important;
    border-top: none !important;
    border-left: none !important;
    border-right: none !important;
    border-bottom: 1px solid var(--surface-border) !important;
    box-shadow: none !important;
}
/* De-wash the Concierge CTA so it reads as a real action, not a ghost. */
[data-theme="dark"] .gp-shell .bg-background-light\/70.text-primary\/50 {
    color: var(--surface-text) !important;
}

/* ============================================================================
   GP PORTAL — LIGHT THEME SURFACE LADDER (P2 fix, 2026-08-03, SCORE-24)
   ----------------------------------------------------------------------------
   Light mode had NO elevation ladder: cards/panels authored as bg-white /
   bg-linen / cads-bg-surface / fed-card fell through to their raw Tailwind/CSS
   values (#EFE7D6 warm-linen, byte-identical to the page canvas in the common
   bg-linen case) — measured DeltaL* 0.00, contrast 1.00, 1 real surface
   cluster page-wide (depth-recon-20260803: TOKEN-RECON.md + CAPTURE-
   REPORT.md). Dark mode already has a real ladder via the
   [data-theme="dark"] .gp-shell block above (surface-canvas ->
   surface-elevated); this is its light-mode counterpart — same class family,
   same --surface-* tokens, opposite theme, zero template edits (every
   selector below already exists in the shipped markup).

   LADDER (mirrors dark's forest ladder; brand-true; DESIGN-BRIEF-light-
   surface-ladder-20260803.md):
     L-1 sunken — sidebar / mobile nav drawer:  #E4DCCB (deeper linen; nav
                  plane visibly behind the content field. Was #E6DCC2 until
                  the 2026-08-05 de-olive hue retune below — same L*, canvas
                  hue/chroma; see the dated update note near the rule.)
     L0  canvas — page field:                   var(--surface-canvas) (byte-unchanged)
     L1  cards  — company cards, signal .nc-item cards, magazine/panel
                  surfaces:                      var(--surface-elevated) #F7F1E2
                  + forest-tinted border/shadow (never black)
   CHIPS never share their parent surface's fill (see below).
   Scoped to .gp-shell + [data-theme="light"] only — dark mode is untouched;
   this section adds NEW selectors, it does not edit anything above.

   2026-08-05 UPDATE (JTP order via CoS-Sheldon, "fairway" warmth taste
   override): L1 --surface-elevated retuned from #FBFAF7 -> #F7F1E2 (a
   warmer, less-white card fill). This SHRINKS the card-vs-canvas luminance
   delta from the original DeltaL* 6.43 (measured PR 5683) toward ~3.4 —
   deliberately, JTP's call, not a defect. Depth is compensated by moving
   MORE of the separation duty onto the edge: every L1 boundary below gets a
   stronger forest-tinted border (0.16 -> 0.22 alpha) and a more visible
   forest-tinted shadow (0.10/0.07 -> 0.14/0.10 alpha) so the card still
   visibly floats on the #EFE7D6 canvas. Chips (previously #F7F1E2, now
   identical to the new card fill) are retuned to a deeper warm tone
   (#EBDFC5) below so a chip never shares its parent card's fill. Dark mode
   is untouched (byte-identical; verified via pixel diff). */

/* L1 — card/panel fill. Mirrors the [data-theme="dark"] .gp-shell .bg-white/
   .bg-linen/.cads-bg-surface/.fed-card rule above, same class family,
   opposite theme. Deliberately does NOT touch .bg-background-light — that
   utility is shared by the page canvas itself (base_gp.html:15,42) as well
   as card markup on ~44 other GP templates, so remapping it here would also
   repaint the canvas (DESIGN BRIEF hard constraint #3). bg-white/bg-linen/
   cads-bg-surface/fed-card are already card-only classes distinct from the
   canvas class, so this is safe at the token level. */
/* Residual round (2026-09-03, EDIT SET 3a): this !important border-color
   governs every .cads-bg-surface/.bg-white/.bg-linen/.fed-card card sitewide
   in .gp-shell light theme -- it always wins over a card's own
   `border-gold/NN` utility (chat_panel.html's welcome icon + input-area
   borders measured #c1bea6 on #ede2c7, 1.34-1.46:1, an INVISIBLE-band
   finding; same root cause hit gp/dashboard.html and gp/transactions.html
   cards). No template-level class swap can fix this -- confirmed via CDP
   CSS.getMatchedStylesForNode, plan4-R-T1.md. Raised 20% -> 45%, mirroring
   the identical 20%->45% fix already applied to the dark-theme
   border-forest/border-mist wildcard a few hundred lines above (20%
   measured under the 1.5:1 floor's margin of safety here too): 45% measures
   ~2.5:1 on the #EDE2C7 card, clearing the floor with real margin. */
[data-theme="light"] .gp-shell .bg-white,
[data-theme="light"] .gp-shell .bg-linen,
[data-theme="light"] .gp-shell .cads-bg-surface,
[data-theme="light"] .gp-shell .fed-card {
    background-color: var(--surface-elevated) !important; /* #EDE2C7, locked 2026-08-19 */
    border-color: rgba(15, 47, 36, 0.45) !important;
    box-shadow: inset 0 1px 0 rgba(247, 241, 226, 0.65), 0 1px 2px rgba(15, 47, 36, 0.22), 0 3px 8px rgba(15, 47, 36, 0.10) !important;
}

/* Piece 6 pocket 4 (MSG-Intern-to-EA-lightmode-inverse-and-small-lints
   -20260820.md): admits bg-background-light CARDS to the ladder above —
   the comment on the block above this one still stands for the BARE
   `.bg-background-light` utility (still deliberately untouched: it is the
   page-canvas class on base_gp.html:16,43 / base_lp.html:13,23 /
   base_marketing.html:6, and it is also reused on ~28 form controls —
   input/select/textarea — that must not get a card shadow). The selector
   below is narrower on purpose: `div.bg-background-light.border` only
   matches a <div> that ALSO carries the plain `.border` utility alongside
   `.bg-background-light` — the existing "bordered card" idiom already used
   ~789 times across gp/transactions.html, gp/dashboard.html,
   gp/account.html, gp/backstage_journal.html, gp/audit_source.html, etc.
   (`class="... rounded border ... bg-background-light border-gold/NN"`).
   The tag qualifier (div only) excludes every input/select/textarea/button
   sharing the class pair; the .border co-occurrence excludes both canvas
   wrappers (verified via grep: neither carries `.border`) and the ~134
   non-card bg-background-light uses (table bodies, hover-only variants,
   unbordered stat tiles) that don't fit the card pattern. Same technique as
   the block above — background-color + border-color OVERRIDE + box-shadow,
   never a second `border` declaration — so a card that already renders its
   own `border` (border-gold/NN gives it color, `.border` gives it width)
   does not double up; verified via before/after light-mode screenshot on a
   bg-background-light card page (see Piece 6 BUILDER return). Included
   .lp-shell too: LP fund-detail stat tiles use the same
   `rounded bg-background-light` pattern (no `.border` today, so unaffected
   by THIS rule, but future bordered LP cards get the same ladder without a
   second edit). */
[data-theme="light"] .gp-shell div.bg-background-light.border,
[data-theme="light"] .console-shell div.bg-background-light.border,
[data-theme="light"] .lp-shell div.bg-background-light.border {
    background-color: var(--surface-elevated) !important; /* #EDE2C7, locked 2026-08-19 */
    border-color: rgba(15, 47, 36, 0.20) !important;
    box-shadow: inset 0 1px 0 rgba(247, 241, 226, 0.65), 0 1px 2px rgba(15, 47, 36, 0.22), 0 3px 8px rgba(15, 47, 36, 0.10) !important;
}

/* Drift-wave fix (2026-08-05): .cds-button--secondary (components.css) sets
   `background: transparent` with no !important, so on paper the
   .cads-bg-surface !important rule above already wins the cascade — but
   Tailwind v4 compiles components.css into a lower-priority @layer than this
   plain stylesheet, and per CSS cascade-layer rules a normal (non-!important)
   declaration in a LATER, higher-priority layer still loses to this file's
   un-layered rule EXCEPT where build tooling reorders layers unexpectedly.
   Observed defect: gp/transactions.html "Export" and "New Distribution"
   buttons (cds-button--secondary + cads-bg-surface, the only 3 template hits
   for that combo repo-wide: transactions.html x2, investors.html x1) render
   stark white instead of the warm --surface-elevated fill. Naming the exact
   combo here — same selector shape as every other rule in this ladder —
   removes any ambiguity instead of relying on layer-order behavior. #B1-fix. */
[data-theme="light"] .gp-shell .cds-button--secondary.cads-bg-surface {
    background-color: var(--surface-elevated) !important;
    border-color: rgba(15, 47, 36, 0.22) !important;
}

/* Signal cards (.nc-item, The Score / gp/portfolio_news.html +
   gp/partials/news_cards_live.html) carry no shared bg-* utility at all
   today — transparent list rows differentiated only by a border-bottom
   divider, nested inside an L1 company card (.bg-linen above). Give each its
   own L1 boundary (border + shadow; no separate fill — it already sits on
   the elevated card behind it) so a signal reads as its own block in any
   view-mode (Magazine / Cards / List / Headlines). Deliberately does not
   touch padding/margin — that stays owned by portfolio_news.html's local
   .score-mode-* density rules. */
[data-theme="light"] .gp-shell .nc-item {
    border: 1px solid rgba(15, 47, 36, 0.22);
    border-radius: var(--radius);
    background-color: var(--surface-elevated);
    box-shadow: 0 1px 2px rgba(15, 47, 36, 0.14), 0 3px 10px rgba(15, 47, 36, 0.10);
}

/* portfolio_news.html's own "Cards" view-mode local style
   (.score-mode-cards .nc-item) hardcodes background: var(--warm-linen) + a
   gold border — the SAME flat-surface bug in a nested location, and
   theme-invariant (no existing dark-mode override for it), so it is
   corrected here at higher specificity rather than edited in the template
   (editing that unconditional rule would also repaint dark mode, which uses
   the identical --warm-linen value there today). */
[data-theme="light"] .gp-shell .score-mode-cards .nc-item {
    background-color: var(--surface-elevated) !important;
    border-color: rgba(15, 47, 36, 0.22) !important;
}

/* L-1 sunken — sidebar + mobile nav drawer. These are the only two elements
   carrying the literal Tailwind class token `dark:bg-primary` (verified: 2
   hits, base_gp.html:117,231 — compiled via this repo's Tailwind v4
   `@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"]
   *));`, input.css:20, so the token is a real, functioning marker, not dead
   CSS) — a stable, pre-existing selector that uniquely identifies "the nav
   plane" without a new template class, distinct from the mobile header/
   content top bars which share bg-background-light but are NOT marked
   dark:bg-primary. Deeper than canvas so the rail visibly sits behind the
   content field (brief: "nav plane visibly behind the content field").
   Sidebar nav text is already forest-on-light (P2 SCORE-08/B2-Q1 fix
   above); forest-on-#E4DCCB measures ~10.6:1, comfortably >=4.5:1 AA
   (verified — stronger than the ~11.75:1 it already had on plain canvas,
   since #E4DCCB is darker than #EFE7D6).

   2026-08-05 UPDATE (JTP order via CoS-Sheldon, "de-olive the sidebar" taste
   fix): #E6DCC2 read green-yellow/khaki against the #EFE7D6 canvas — the two
   were NOT hue-matched (canvas Lab a/b = -0.14/9.24, LCh hue 90.9°, chroma
   9.24; old sidebar Lab a/b = -0.83/14.01, LCh hue 93.4°, chroma 14.03 — the
   extra chroma at a slightly rotated hue is what read as olive). Retuned
   deterministically in CIE LCh (D65, sRGB): kept the sidebar's own L*
   87.923 (the darkness/sunken role is untouched — depth ladder unchanged)
   and swapped in the CANVAS's hue angle (90.9°) and chroma (9.24), then
   converted back to sRGB. Result #E4DCCB — its R-G/G-B channel gaps (8/17)
   now match the canvas's warm balance (8/17) exactly, vs the old sidebar's
   disproportionate 10/26. DeltaL* vs canvas: old 3.92, new 3.88 — the
   sunken step is preserved within rounding. Contrast recomputed, not
   assumed: forest-on-#E4DCCB = 10.60:1 (was 10.59:1 on #E6DCC2) — AA/AAA
   headroom unchanged. Dark mode is untouched (this selector is
   [data-theme="light"]-scoped only; dark sidebar stays the forest-green
   brand anchor per the var-fallthrough architecture above). */
[data-theme="light"] .gp-shell [class*="dark:bg-primary"] {
    background-color: #E4DCCB !important;
}

/* CHIPS — per brief: WATCHLIST/MANUAL badge, rank #1 pill, score pill,
   filter chips, window chips. A chip never shares its parent surface's
   fill. Status-meaningful chips (coverage badge, score-tier badge) keep
   their existing forest-mid/gold text+border tone — that IS the signal —
   but get a real solid fill distinct from the card behind them (already
   var(--surface-elevated)) instead of an 8–10%-alpha tint that read as
   almost invisible. Originally used the same #F7F1E2 chip tone as the L1
   card fill rather than a pure-white fill — this repo's design_linter.py
   hard-bans the pure-white hex triplet (scripts/design_linter.py:24), and
   #F7F1E2 measured a real ~3 L* step off the then-card-fill #FBFAF7,
   satisfying "never shares its parent surface's fill" without a banned
   value. 2026-08-05 UPDATE (JTP taste override, CoS-Sheldon): the L1 card
   fill itself moved TO #F7F1E2 (see the surface-ladder block above), so
   chips are retuned one more step deeper/warmer to #EBDFC5 — L* ~89.1 vs
   the new card's L* ~95.2 (delta ~6.1, a stronger step than the original
   chip-vs-card delta) and still forest-family warm, not a banned pure
   white/black. Purely informational chips (rank pill, inactive filter/
   window buttons) had NO fill of their own at all — transparent, showing
   the parent card/group color through — so they get the same dedicated
   chip tone. Active/selected filter+window state (.bg-primary) is left
   alone per the brief ("ACTIVE/SELECTED: unchanged"). */
[data-theme="light"] .gp-shell [data-testid="score-coverage-badge"],
[data-theme="light"] .gp-shell [data-testid="score-badge"] {
    background-color: #EBDFC5 !important;
}
[data-theme="light"] .gp-shell [data-testid="score-rank-pill"],
[data-theme="light"] .gp-shell [data-testid^="score-date-preset-"]:not(.bg-primary) {
    background-color: #EBDFC5 !important;
    border-color: rgba(15, 47, 36, 0.20) !important;
    color: var(--forest-green) !important;
}
[data-theme="light"] .gp-shell [data-testid="score-fire-filter"] button:not(.bg-primary) {
    background-color: #EBDFC5 !important;
    color: var(--forest-green) !important;
}

/* ============================================================================
   GP DASHBOARD / TUNING ROOM — "DARK ISLAND" WIDGET LIGHTING (P2 fix,
   2026-08-03, SCORE-25)
   ----------------------------------------------------------------------------
   _resonance_widget.html ("Your Fund Summary" / IMPROVE THIS SUMMARY) and
   _progressive_unlock_cards.html (the GP Dashboard onboarding ladder,
   data-widget-id="progressive-unlock") author their ENTIRE panel — container,
   toolbar, metadata rows, section list — as literal inline `style="..."`
   using the raw dark-brand values (var(--forest-green) background,
   var(--warm-linen)/rgba(249,248,246,*) text) with no [data-theme] branch at
   all, so the widget renders as a solid dark-forest card regardless of the
   page theme. In light mode this is a large hardcoded dark panel sitting
   inside an otherwise light page. Same root cause, same visible symptom, in
   tuning_room.html's "What is the Tuning Room?" hero card (Tailwind
   `from-primary to-forest-mid` gradient, always at the top of the page).

   FIX SHAPE — inline custom-property indirection, CSS-first:
   Every literal color the widgets set is rewritten in the template as
   `var(--rw-token, <original literal>)` — the SECOND argument is the exact
   original value, so with no light-theme rule present (dark / no data-theme)
   the var() resolves to the identical original literal and dark mode is
   BYTE-IDENTICAL. This block is the ONLY place `--rw-*` is ever assigned,
   scoped to [data-theme="light"], and it is what gives light mode a real
   value. Where the widget already referenced an EXISTING theme-aware token
   by name (var(--warm-linen) for text, var(--burnished-gold) for full-
   strength text/icon color) the template was pointed at var(--surface-text)
   / var(--surface-gold) directly instead of a new --rw- token — those two
   already resolve to the exact prior literal in dark (surface-text: warm-
   linen, surface-gold: burnished-gold under [data-theme="dark"]) and to a
   real AA-checked light value under [data-theme="light"]
   (surface-gold = --gold-accessible #856A28, "accent-only on warm linen" per
   its own definition comment) — no new indirection needed for those two.

   Left INTENTIONALLY unchanged (small dark accents / hidden-by-default
   surfaces, not "full panels"):
   - Both widgets' primary CTA buttons (resonance-improve-cta,
     progressive-unlock-cta) — solid forest-green + gold-border buttons,
     covered by test_gp_resonance_widget_template.py's exact-hex assertions.
   - The resonance "Improve This Summary" wizard/stepper modal
     (x-show="resonanceOpen", hidden until clicked — not part of the
     always-visible page render this defect report describes).
   - Low-alpha gold/blue rgba(...) icon and border decoration (already a
     faded accent by design in both themes; not text-contrast-bearing). */
[data-theme="light"] .gp-shell [data-widget-id="resonance"],
[data-theme="light"] .gp-shell [data-widget-id="progressive-unlock"] {
    --rw-surface: var(--surface-elevated);                 /* #F7F1E2 — L1 card fill, JTP taste override 2026-08-05 (was #FBFAF7, PR 5683) */
    --rw-border: rgba(15, 47, 36, 0.22);                   /* depth-compensated L1 card border, 2026-08-05 (was 0.16) */
    --rw-toolbar-border: rgba(15, 47, 36, 0.10);
    --rw-toolbar-bg: rgba(15, 47, 36, 0.04);               /* forest-tinted wash, not a flat fill */
    --rw-row-border-15: rgba(15, 47, 36, 0.10);
    --rw-row-border-12: rgba(15, 47, 36, 0.10);
    --rw-section-bg: rgba(15, 47, 36, 0.03);
    --rw-text-85: var(--surface-text);                     /* near-primary body copy */
    --rw-text-70: var(--surface-text-muted);
    --rw-text-60: var(--surface-text-muted);
    --rw-text-50: var(--surface-text-muted);
    --rw-text-45: var(--surface-text-muted);              /* uppercase micro-labels */
    --rw-text-35: var(--surface-text-muted);
    --rw-text-30: var(--surface-text-muted);
    --rw-card-ready-bg: rgba(15, 47, 36, 0.05);
    /* SCORE-36 (P2 light-mode recheck, 2026-08-04): the progressive-unlock
       LOCKED cards (needs_data/blocked) sat at 2-3.5% forest tint over the
       #FBFAF7 --rw-surface container — nearly imperceptible, reading as
       stark-white cards indistinguishable from their own container, with
       --rw-text-35 (--surface-text-subtle, ~3.7:1, documented "AA large/
       decorative only") on top for the description + blocked-badge label —
       normal-size text below the 4.5:1 AA floor. Ready cards were unaffected
       (already on --surface-text/--surface-text-muted, both >=4.5:1) and are
       intentionally left untouched here so ready-vs-locked stays visually
       distinct. Fix: give locked cards a warm-chip tone
       established sitewide for "a chip never shares its parent
       surface's fill" (see the CHIPS block above, ~L936) instead of a
       near-invisible dark-tint fraction, and route their secondary text to
       --surface-text-muted via a new --rw-unlock-locked-text token instead
       of the shared --rw-text-35 (kept alone so this fix cannot touch the
       unrelated resonance-widget usage of --rw-text-35). Dark mode is
       untouched: every template var() keeps its original literal as the
       fallback, so with no [data-theme="light"] rule in play dark renders
       byte-identical.
       2026-08-05 UPDATE (JTP taste override, CoS-Sheldon): the L1 card fill
       (--rw-surface, feeding this widget's own container) moved to
       #F7F1E2, the SAME tone these locked cards previously used — so the
       chip color here moves one step further to #EBDFC5 (the sitewide new
       chip tone, see CHIPS block) to keep locked cards visibly distinct
       from their own container. --surface-text-muted on #EBDFC5 measures
       ~5.39:1 (was ~5.79:1 on #F7F1E2), still comfortably >=4.5:1 AA —
       verified in tests/unit/test_progressive_unlock_light_mode_contrast.py. */
    --rw-card-needsdata-bg: #EBDFC5;
    --rw-card-blocked-bg: #EBDFC5;
    --rw-card-border-ready: rgba(15, 47, 36, 0.22);
    --rw-card-border-other: rgba(15, 47, 36, 0.22);
    --rw-blocked-badge-bg: rgba(15, 47, 36, 0.08);
    --rw-blocked-badge-border: rgba(15, 47, 36, 0.18);
    --rw-unlock-locked-text: var(--surface-text-muted);    /* SCORE-36: locked-card desc + blocked-badge text, >=4.5:1 */
    --rw-needsdata-badge-text: #1D4ED8;                    /* accessible blue, was --stone (not theme-aware) */
    box-shadow: 0 1px 2px rgba(15, 47, 36, 0.14), 0 3px 10px rgba(15, 47, 36, 0.10) !important;
}

[data-theme="dark"] .gp-shell [data-widget-id="resonance"],
[data-theme="dark"] .gp-shell [data-widget-id="progressive-unlock"] {
    --rw-text-70: var(--surface-text-muted);
    --rw-text-60: var(--surface-text-muted);
    --rw-text-50: var(--surface-text-muted);
    --rw-text-45: var(--surface-text-muted);
    --rw-text-35: var(--surface-text-muted);
    --rw-text-30: var(--surface-text-muted);
    --rw-unlock-locked-text: var(--surface-text-muted);
}

/* Round 9: /gp/score .text-gold-accessible coverage badges contrast (both themes >= 4.5:1) */
[data-theme="light"] .gp-shell .bg-gold\/10.text-gold-accessible,
[data-theme="light"] .gp-shell .bg-gold\/10 .text-gold-accessible,
[data-theme="light"] .gp-shell [data-testid*="coverage-badge"][class*="text-gold-accessible"] {
    color: #68531F !important;
}

[data-theme="dark"] .gp-shell .bg-gold\/10.text-gold-accessible,
[data-theme="dark"] .gp-shell .bg-gold\/10 .text-gold-accessible,
[data-theme="dark"] .gp-shell [data-testid*="coverage-badge"][class*="text-gold-accessible"] {
    color: #DEC38B !important;
}

/* tuning_room.html "What is the Tuning Room?" hero — a Tailwind gradient
   card (from-primary to-forest-mid + text-background-light), not an inline-
   style widget, so it is neutralized as a compound-class selector instead
   of via --rw- indirection. Unique in the template (only this card combines
   these three classes), so no template edit is needed at all. */
[data-theme="light"] .gp-shell .bg-gradient-to-br.from-primary.to-forest-mid {
    background-image: none !important;
    background-color: var(--surface-elevated) !important;
    color: var(--surface-text) !important;
    border: 1px solid rgba(15, 47, 36, 0.22);
    box-shadow: 0 1px 2px rgba(15, 47, 36, 0.14), 0 3px 10px rgba(15, 47, 36, 0.10);
}
[data-theme="light"] .gp-shell .bg-gradient-to-br.from-primary.to-forest-mid .text-background-light\/60 {
    color: var(--surface-text-muted) !important;
}
[data-theme="light"] .gp-shell .bg-gradient-to-br.from-primary.to-forest-mid .bg-background-light\/5 {
    background-color: rgba(15, 47, 36, 0.04) !important;
}

/* DARK mirror of the block above (P0/(a), 2026-08-20). Root cause: input.css's
   `@theme inline` rebinds --color-background-light -> --surface-canvas, and
   dark theme sets --surface-canvas to forest-green #0F2F24, so every literal
   `text-background-light` on this card renders canvas-on-canvas — invisible
   against the from-primary(#0F2F24)-to-forest-mid(#1B4D3E) gradient. Unlike
   the light neutralizer, dark mode KEEPS the gradient (only the light
   version flattens to a solid card) and only re-points text/chip-fill color,
   per the founding spec's gradient hero look. Gold icons (.text-gold,
   .bg-gold/20) are untouched — they were never on the broken token chain.
   Contrast (WCAG relative-luminance, computed against both gradient stops
   and their midpoint ~#153E31 — see the sync-harness's
   scripts.validate_cds_conformance and this task's screenshot proof):
     --surface-text (warm-linen #EFE7D6, h2 + card base) >= 7.84:1 (worst
       case is on the #1B4D3E stop; 11.75:1 on #0F2F24; 9.67:1 at midpoint)
     --surface-text-muted (#C8C4BC, body copy + 3 chip labels, used at FULL
       opacity rather than /60 — an alpha-blended linen would fail the floor
       on this dark background) >= 5.55:1 (worst case #1B4D3E; 8.32:1 on
       #0F2F24; 6.84:1 at midpoint)
   Both comfortably clear the 4.5:1 AA floor. */
[data-theme="dark"] .gp-shell .bg-gradient-to-br.from-primary.to-forest-mid {
    color: var(--surface-text) !important;
}
[data-theme="dark"] .gp-shell .bg-gradient-to-br.from-primary.to-forest-mid .text-background-light\/60 {
    color: var(--surface-text-muted) !important;
}
[data-theme="dark"] .gp-shell .bg-gradient-to-br.from-primary.to-forest-mid .bg-background-light\/5 {
    background-color: rgba(239, 231, 214, 0.10) !important;
}
/* theme-follow-os: sanctioned (Piece 6 / L10 — same JTP follow-OS ruling as
   the mirror block above; this is the gradient-hero's OS-media mirror, the
   second of the "2 live today" sanctioned occurrences the packet counted.) */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .gp-shell .bg-gradient-to-br.from-primary.to-forest-mid {
        color: var(--surface-text) !important;
    }
    :root:not([data-theme="light"]) .gp-shell .bg-gradient-to-br.from-primary.to-forest-mid .text-background-light\/60 {
        color: var(--surface-text-muted) !important;
    }
    :root:not([data-theme="light"]) .gp-shell .bg-gradient-to-br.from-primary.to-forest-mid .bg-background-light\/5 {
        background-color: rgba(239, 231, 214, 0.10) !important;
    }
}

/* The GP theme-toggle control itself (sidebar footer + mobile header). */
.gp-theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--burnished-gold) 45%, transparent);
    color: var(--burnished-gold);
    border-radius: var(--radius);
    transition: background-color var(--duration-micro) var(--ease-institutional),
                color var(--duration-micro) var(--ease-institutional);
}
.gp-theme-toggle:hover {
    background-color: color-mix(in srgb, var(--burnished-gold) 15%, transparent);
}
/* Defense-in-depth 44px tap target regardless of utility-class availability. */
.gp-theme-toggle {
    min-width: 44px;
    min-height: 44px;
    flex-shrink: 0;
}
/* Show the sun icon in dark (to switch→light), moon in light (to switch→dark). */
.gp-theme-toggle .icon-sun { display: none; }
.gp-theme-toggle .icon-moon { display: inline-block; }
[data-theme="dark"] .gp-theme-toggle .icon-sun { display: inline-block; }
[data-theme="dark"] .gp-theme-toggle .icon-moon { display: none; }

/* ============================================================================
   Theme toggle (CDS light/dark) — shared source of truth.
   Used by the base shell's persistent chrome control (public / auth / portal /
   error) and, via [data-theme-toggle] + window.toggleTheme(), by the GP and LP
   sidebar/mobile chrome controls. Ghost treatment: transparent background, gold
   hairline border, neutral text (forest on light / linen on dark) — gold is an
   accent only, surfacing on hover/focus, never the resting text color. The one
   exception is the GP sidebar Sign-out row (canon P, 2026-09-03: "only Sign out
   keeps the gold outline"), pinned back to gold via its data-testid below —
   Notifications, the real light/dark switcher, and every other .theme-toggle
   consumer render neutral like Account. Accent border only, never a fill.
   ============================================================================ */
.theme-toggle-chrome {
    position: fixed;
    top: max(1rem, env(safe-area-inset-top));
    right: max(1rem, env(safe-area-inset-right));
    z-index: 40;
}
.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 44px;
    min-width: 44px;
    padding: 0 0.75rem;
    cursor: pointer;
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--burnished-gold) 45%, transparent);
    color: var(--forest-green);
    border-radius: var(--radius);
    font-family: 'Geist', system-ui, sans-serif;
    font-size: 0.8125rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    line-height: 1;
    transition: background-color var(--duration-micro) var(--ease-institutional),
                color var(--duration-micro) var(--ease-institutional),
                border-color var(--duration-micro) var(--ease-institutional);
}
.theme-toggle:hover {
    background-color: color-mix(in srgb, var(--burnished-gold) 15%, transparent);
    /* R-CSS-3 adversary round (2026-09-03): --gold-accessible (#735C23) only
       reaches 4.22:1 against this hover state's own composited background on
       the light PAGE ground (the 15% gold tint over light_page = #E2D0AD) --
       under the 4.5:1 text floor, though it clears 4.5:1 on both card
       grounds. #6E571F is the same hue darkened one step further: 4.55:1 on
       the page composite, and still clears both cards. Local to this hover
       state only -- the shared --gold-accessible token is untouched. */
    color: #6E571F;
}
.theme-toggle:focus-visible {
    outline: 2px solid var(--surface-focus-ring);
    outline-offset: 2px;
}
.theme-toggle__icon { font-size: 18px; }
/* Show the moon in light (target = dark) and the sun in dark (target = light). */
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: inline-block; }
[data-theme="dark"] .theme-toggle { color: var(--warm-linen); }
/* R-CSS-3 adversary round (2026-09-03): --burnished-gold only reaches
   3.22:1 against this hover state's own composited background on the dark
   CARD ground (the 15% gold tint over forest-mid = #345942) -- under the
   4.5:1 text floor, though it clears 4.5:1 on the dark page composite.
   #E0C48A (same gold hue, lightened) reaches 4.69:1 on the card composite
   and 6.65:1 on the page composite. Literal (not var(--color-gold-400)):
   that custom property lives in input.css's @theme, outside this file's own
   scope, per L10 doctrine. */
[data-theme="dark"] .theme-toggle:hover { color: #E0C48A; }
[data-theme="dark"] .theme-toggle .icon-sun { display: inline-block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }
/* GP sidebar Sign-out row: canon P keeps this one .theme-toggle consumer gold
   (Account/Notifications are neutral). Attribute selector out-specifies the
   base rule above without an !important. */
.theme-toggle[data-testid="gp-signout-trigger"] { color: #735C23; }
[data-theme="dark"] .theme-toggle[data-testid="gp-signout-trigger"] { color: var(--burnished-gold); }
/* Target-state text label pre-paint sync when head bootstrap restores dark mode
   before body controls parse. Icons swap above; this covers the visible label. */
html[data-theme="dark"] [data-theme-toggle-label] {
    visibility: hidden;
    position: relative;
}
html[data-theme="dark"] [data-theme-toggle-label]::after {
    content: "Light";
    visibility: visible;
    position: absolute;
    left: 0;
    top: 0;
}
@media (prefers-reduced-motion: reduce) {
    .theme-toggle { transition: none; }
}

/* ============================================================================
   W1 mobile header chrome — production robustness at ~390px phone portrait and
   smaller. Shared by the public/auth base header, the GP shell mobile topbar,
   and the LP shell mobile topbar. Goals: no horizontal scroll, no squashed
   hamburger/menu controls, reachable auth/account/theme/close controls, every
   chrome control a 44px-effective tap target, and safe-area-aware insets in
   light and dark modes. These rules do not depend on the Tailwind JIT being
   warm — they are plain CSS so the chrome stays robust even if a utility class
   is purged.
   ============================================================================ */

/* The sticky chrome bar itself. `overflow-x: clip` confines any over-wide child
   to the bar instead of scrolling the whole page, and the safe-area insets keep
   the bar clear of notches/Dynamic Island and curved edges. `viewport-fit=cover`
   is already set on <meta name="viewport"> in base.html. */
.chrome-bar {
    overflow-x: clip;
    padding-top: env(safe-area-inset-top);
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
}
/* The flex row inside the bar must be allowed to shrink its children so the
   brand block yields space before the controls are pushed off-screen. */
.chrome-bar__row {
    min-width: 0;
    max-width: 100%;
}

/* Brand/title cluster: shrinks (flex-shrink:1) and truncates instead of forcing
   the row wider than the viewport, which is the root cause of the ~390px
   overflow and the controls drifting off-screen. */
.chrome-brand {
    min-width: 0;
    flex-shrink: 1;
    overflow: hidden;
}
.chrome-brand__text {
    min-width: 0;
    overflow: hidden;
}
.chrome-brand__title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Every icon-only chrome control (hamburger/menu, AI panel, drawer close): a
   guaranteed 44x44 tap target that never shrinks below the floor. Replaces the
   previous `p-2` (~32-40px) icon buttons that failed the 44px requirement. */
.chrome-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    min-width: 44px;
    min-height: 44px;
    border-radius: var(--radius);
    transition: background-color var(--duration-micro) var(--ease-institutional),
                color var(--duration-micro) var(--ease-institutional);
}
.chrome-icon-btn:hover {
    background-color: color-mix(in srgb, var(--burnished-gold) 12%, transparent);
}
.chrome-icon-btn:focus-visible {
    outline: 2px solid var(--surface-focus-ring);
    outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
    .chrome-icon-btn { transition: none; }
}

/* .cds-harp-on-forest (gold recolor filter on the forest sidebar harp) removed
   per JTP A2 ruling 2026-09-03: WRONG — the drawn harp (A1) stays as drawn on
   every surface, no gold-on-forest recolor. TPL-CHROME removes the class usage
   from base_lp.html and components/brand/_logo.html. */

/* ============================================================================
   LP shell dark theme — the LP shell chrome (page header, AI panel, toasts) uses
   the same bg-background-light / text-primary / border-gold utility vocabulary as
   the GP shell. Mirror the .gp-shell content recoloring so the LP theme toggle
   actually flips LP shell content light/dark instead of being a no-op. Scoped to
   .lp-shell so no public / marketing / portal surface is affected. The LP sidebar
   stays forest in both themes (text-text-dark is already linen), so it is not
   matched here — only the linen content canvas and elevated chrome flip.
   ============================================================================ */
[data-theme="dark"] .lp-shell .bg-background-light,
[data-theme="dark"] .lp-shell.bg-background-light {
    background-color: var(--surface-canvas) !important;
}
[data-theme="dark"] .lp-shell .bg-white,
[data-theme="dark"] .lp-shell .bg-linen {
    background-color: var(--surface-elevated) !important;
    color: var(--surface-text);
}
[data-theme="dark"] .lp-shell .text-primary,
[data-theme="dark"] .lp-shell .text-forest {
    color: var(--surface-text) !important;
}
[data-theme="dark"] .lp-shell .text-primary\/40,
[data-theme="dark"] .lp-shell .text-primary\/50,
[data-theme="dark"] .lp-shell .text-primary\/60,
[data-theme="dark"] .lp-shell .text-primary\/70,
[data-theme="dark"] .lp-shell .text-primary\/80 {
    color: var(--surface-text-muted) !important;
}
/* Faint caption/metadata text (forest at /15 /20 /25 /30 /35) — mirrors the
   .gp-shell rule above. Without this, LP dark-mode note icons (text-primary/20,
   text-primary/30 in lp/dashboard.html and lp/partials/_musicbook_notes.html)
   go unstyled/invisible on the dark ground. */
[data-theme="dark"] .lp-shell .text-primary\/15,
[data-theme="dark"] .lp-shell .text-primary\/20,
[data-theme="dark"] .lp-shell .text-primary\/25,
[data-theme="dark"] .lp-shell .text-primary\/30,
[data-theme="dark"] .lp-shell .text-primary\/35 {
    color: var(--surface-text-subtle) !important;
}
[data-theme="dark"] .lp-shell .text-gold-accessible {
    color: var(--surface-gold) !important;
}
[data-theme="dark"] .lp-shell [class*="border-gold"] {
    border-color: var(--surface-border) !important;
}

/* H3 finding 2 -- .lp-shell shell-parity gaps closed against the .gp-shell/
   .console-shell reference set (2026-09-03). */
[data-theme="dark"] .lp-shell .text-primary\/45,
[data-theme="dark"] .lp-shell .text-primary\/55,
[data-theme="dark"] .lp-shell .text-primary\/65 {
    color: var(--surface-text-muted) !important;
}
[data-theme="dark"] .lp-shell .text-muted,
[data-theme="dark"] .lp-shell .cads-text-muted {
    color: var(--surface-text-muted) !important;
}
[data-theme="dark"] .lp-shell .text-subtle {
    color: var(--surface-text-subtle) !important;
}
[data-theme="dark"] .lp-shell .text-forest-mid,
[data-theme="dark"] .lp-shell .text-status-success {
    color: var(--surface-text) !important;
}
[data-theme="dark"] .lp-shell .text-forest-mid\/40,
[data-theme="dark"] .lp-shell .text-forest-mid\/70,
[data-theme="dark"] .lp-shell .text-forest-mid\/80 {
    color: var(--surface-text-muted) !important;
}
/* R-CSS-3 (2026-09-03): mirrors the gp/console .text-error-500/.text-error-700
   fix above -- same gap, same target token.
   R-CSS-3 adversary round (2026-09-03): .text-error-800 added, mirroring
   the gp-shell/console-shell fix -- same un-remapped-against-dark-fill gap. */
[data-theme="dark"] .lp-shell .text-error-600,
[data-theme="dark"] .lp-shell .text-error-500,
[data-theme="dark"] .lp-shell .text-error-700,
[data-theme="dark"] .lp-shell .text-error-800,
[data-theme="dark"] .lp-shell .text-status-error {
    color: var(--surface-status-error) !important;
}
/* R-CSS-3 (2026-09-03): mirrors the gp/console .bg-error-100 fix above --
   see that block's comment. */
[data-theme="dark"] .lp-shell .bg-error-100 {
    background-color: color-mix(in srgb, #C0453B 22%, transparent) !important;
}
/* Coordinator 2026-09-03 (T4/T4b): same status-text remap as gp/console
   above -- .text-status-success wins over the shared text-forest-mid rule
   two blocks up (later in cascade, same specificity). See that block's
   comment for the contrast numbers / V7a error rationale.
   R-CSS-3 (2026-09-03) correction: retuned success-text from leaf green to
   ink (#F9F8F6) -- see the gp/console block's R-CSS-3 comment. */
[data-theme="dark"] .lp-shell .text-status-success {
    color: #F9F8F6 !important;
}
[data-theme="dark"] .lp-shell .border-status-success {
    border-color: #8FCB6B !important;
}
[data-theme="dark"] .lp-shell .bg-status-success {
    background-color: #8FCB6B !important;
}
[data-theme="dark"] .lp-shell .bg-status-success.text-white,
[data-theme="dark"] .lp-shell .bg-status-success.text-on-primary {
    background-color: color-mix(in srgb, #8FCB6B 22%, transparent) !important;
}
/* R-CSS-3 adversary round (2026-09-03): matches the gp-shell/console-shell
   fix above -- --burnished-gold measured only 3.92:1 on the forest-mid
   card, under the 4.5:1 body-text floor; gold-400 (#D4B472) clears 4.85:1. */
[data-theme="dark"] .lp-shell .text-status-warning {
    color: #D4B472 !important;
}
[data-theme="dark"] .lp-shell [class*="border-forest"],
[data-theme="dark"] .lp-shell [class*="border-mist"] {
    border-color: color-mix(in srgb, #F9F8F6 45%, transparent) !important;
}
[data-theme="dark"] .lp-shell input[type="text"],
[data-theme="dark"] .lp-shell input[type="email"],
[data-theme="dark"] .lp-shell input[type="number"],
[data-theme="dark"] .lp-shell input[type="search"],
[data-theme="dark"] .lp-shell input[type="tel"],
[data-theme="dark"] .lp-shell input[type="password"],
[data-theme="dark"] .lp-shell input[type="url"],
[data-theme="dark"] .lp-shell input[type="date"],
[data-theme="dark"] .lp-shell input[type="datetime-local"],
[data-theme="dark"] .lp-shell input[type="month"],
[data-theme="dark"] .lp-shell input[type="week"],
[data-theme="dark"] .lp-shell input[type="time"],
[data-theme="dark"] .lp-shell input:not([type]),
[data-theme="dark"] .lp-shell select,
[data-theme="dark"] .lp-shell textarea {
    background-color: var(--surface-sunken) !important;
    color: var(--surface-text) !important;
}
[data-theme="dark"] .lp-shell ::placeholder {
    color: var(--text-muted-on-inverse) !important;
}

/* ============================================================================
   PORTAL DARK MODE (.portal-shell) — H3 finding 2: no .portal-shell selector
   existed anywhere in the codebase; app_services/templates/portal/wallet.html
   and velvet_rope.html extend base.html with no shell class at all, so the
   dark-mode toggle is currently a no-op on those pages. This block is a
   full mirror of the .gp-shell reference set, scoped to a brand-new
   `.portal-shell` class family. It is CSS-complete but INERT until a
   template team adds class="...portal-shell" to those two templates' body
   tag -- see this package's report for the handoff (out of this package's
   owner_files/forbidden_files scope; template edits belong to T1-T6). */
[data-theme="dark"] .portal-shell .bg-background-light,
[data-theme="dark"] .portal-shell.bg-background-light {
    background-color: var(--surface-canvas) !important;
}
[data-theme="dark"] .portal-shell .bg-white,
[data-theme="dark"] .portal-shell .bg-linen,
[data-theme="dark"] .portal-shell .cads-bg-surface,
[data-theme="dark"] .portal-shell .fed-card {
    background-color: var(--surface-elevated) !important;
    color: var(--surface-text);
}
/* R-CSS-4 (2026-09-04): .text-primary\/90 joins the 100%-target group here,
   same rationale as the .gp-shell/.console-shell fix above -- 90% opacity
   reads as full-strength body copy, not the /40-/85 muted family below. */
[data-theme="dark"] .portal-shell .text-primary,
[data-theme="dark"] .portal-shell .text-forest,
[data-theme="dark"] .portal-shell .text-primary\/90,
[data-theme="dark"] .portal-shell .cads-text-on-light {
    color: var(--surface-text) !important;
}
[data-theme="dark"] .portal-shell .text-primary\/40,
[data-theme="dark"] .portal-shell .text-primary\/50,
[data-theme="dark"] .portal-shell .text-primary\/60,
[data-theme="dark"] .portal-shell .text-primary\/70,
[data-theme="dark"] .portal-shell .text-primary\/75,
[data-theme="dark"] .portal-shell .text-primary\/80,
[data-theme="dark"] .portal-shell .text-primary\/85,
[data-theme="dark"] .portal-shell .text-muted,
[data-theme="dark"] .portal-shell .cads-text-muted {
    color: var(--surface-text-muted) !important;
}
[data-theme="dark"] .portal-shell .text-subtle {
    color: var(--surface-text-subtle) !important;
}
[data-theme="dark"] .portal-shell .text-primary\/45,
[data-theme="dark"] .portal-shell .text-primary\/55,
[data-theme="dark"] .portal-shell .text-primary\/65 {
    color: var(--surface-text-muted) !important;
}
[data-theme="dark"] .portal-shell .text-primary\/15,
[data-theme="dark"] .portal-shell .text-primary\/20,
[data-theme="dark"] .portal-shell .text-primary\/25,
[data-theme="dark"] .portal-shell .text-primary\/30,
[data-theme="dark"] .portal-shell .text-primary\/35 {
    color: var(--surface-text-subtle) !important;
}
[data-theme="dark"] .portal-shell .text-gold-accessible {
    color: var(--surface-gold) !important;
}
[data-theme="dark"] .portal-shell .text-forest-mid,
[data-theme="dark"] .portal-shell .text-status-success {
    color: var(--surface-text) !important;
}
[data-theme="dark"] .portal-shell .text-forest-mid\/40,
[data-theme="dark"] .portal-shell .text-forest-mid\/70,
[data-theme="dark"] .portal-shell .text-forest-mid\/80 {
    color: var(--surface-text-muted) !important;
}
/* R-CSS-3 (2026-09-03): mirrors the gp/console .text-error-500/.text-error-700
   fix above -- same gap, same target token.
   R-CSS-3 adversary round (2026-09-03): .text-error-800 added, mirroring
   the gp-shell/console-shell fix -- same un-remapped-against-dark-fill gap. */
[data-theme="dark"] .portal-shell .text-error-600,
[data-theme="dark"] .portal-shell .text-error-500,
[data-theme="dark"] .portal-shell .text-error-700,
[data-theme="dark"] .portal-shell .text-error-800,
[data-theme="dark"] .portal-shell .text-status-error {
    color: var(--surface-status-error) !important;
}
/* R-CSS-3 (2026-09-03): mirrors the gp/console .bg-error-100 fix above --
   see that block's comment. */
[data-theme="dark"] .portal-shell .bg-error-100 {
    background-color: color-mix(in srgb, #C0453B 22%, transparent) !important;
}
/* Coordinator 2026-09-03 (T4/T4b): same status-text remap as gp/console/lp
   above -- see that block's comment for contrast numbers / V7a rationale.
   R-CSS-3 (2026-09-03) correction: retuned success-text from leaf green to
   ink (#F9F8F6) -- see the gp/console block's R-CSS-3 comment. */
[data-theme="dark"] .portal-shell .text-status-success {
    color: #F9F8F6 !important;
}
[data-theme="dark"] .portal-shell .border-status-success {
    border-color: #8FCB6B !important;
}
[data-theme="dark"] .portal-shell .bg-status-success {
    background-color: #8FCB6B !important;
}
[data-theme="dark"] .portal-shell .bg-status-success.text-white,
[data-theme="dark"] .portal-shell .bg-status-success.text-on-primary {
    background-color: color-mix(in srgb, #8FCB6B 22%, transparent) !important;
}
/* R-CSS-3 adversary round (2026-09-03): matches the gp-shell/console-shell
   fix above -- --burnished-gold measured only 3.92:1 on the forest-mid
   card, under the 4.5:1 body-text floor; gold-400 (#D4B472) clears 4.85:1. */
[data-theme="dark"] .portal-shell .text-status-warning {
    color: #D4B472 !important;
}
[data-theme="dark"] .portal-shell [class*="border-gold"] {
    border-color: var(--surface-border) !important;
}
[data-theme="dark"] .portal-shell [class*="divide-gold"] > :not([hidden]) ~ :not([hidden]) {
    border-color: var(--surface-border) !important;
}
[data-theme="dark"] .portal-shell [class*="border-forest"],
[data-theme="dark"] .portal-shell [class*="border-mist"] {
    border-color: color-mix(in srgb, #F9F8F6 45%, transparent) !important;
}
[data-theme="dark"] .portal-shell .bg-gray-50,
[data-theme="dark"] .portal-shell .bg-gray-100,
[data-theme="dark"] .portal-shell .bg-neutral-50,
[data-theme="dark"] .portal-shell .bg-neutral-100,
[data-theme="dark"] .portal-shell .bg-stone-50,
[data-theme="dark"] .portal-shell .cads-bg-surface-sunken {
    background-color: var(--surface-sunken) !important;
}
[data-theme="dark"] .portal-shell input[type="text"],
[data-theme="dark"] .portal-shell input[type="email"],
[data-theme="dark"] .portal-shell input[type="number"],
[data-theme="dark"] .portal-shell input[type="search"],
[data-theme="dark"] .portal-shell input[type="tel"],
[data-theme="dark"] .portal-shell input[type="password"],
[data-theme="dark"] .portal-shell input[type="url"],
[data-theme="dark"] .portal-shell input[type="date"],
[data-theme="dark"] .portal-shell input[type="datetime-local"],
[data-theme="dark"] .portal-shell input[type="month"],
[data-theme="dark"] .portal-shell input[type="week"],
[data-theme="dark"] .portal-shell input[type="time"],
[data-theme="dark"] .portal-shell input:not([type]),
[data-theme="dark"] .portal-shell select,
[data-theme="dark"] .portal-shell textarea {
    background-color: var(--surface-sunken) !important;
    color: var(--surface-text) !important;
}
[data-theme="dark"] .portal-shell ::placeholder {
    color: var(--text-muted-on-inverse) !important;
}

/* .cds-chip RETIRED 2026-09-03 per R3 ruling: no template callers remain
   (chat_panel.html now uses .cds-suggestion-chip instead — grep across
   app_services/templates/ confirms zero remaining .cds-chip references).
   Kept in place (not deleted) because tests/unit/test_chat_panel_rendering.py
   ::test_cds_chip_light_mode_uses_linen_family_not_flat_stone and
   ::test_cds_chip_border_is_gold_not_forest_green still extract and assert on
   this rule's declarations directly from this stylesheet. Deleting the rule
   turns those tests red (ValueError: substring not found) since nothing else
   in this package owns that test file. Remove this rule only alongside an
   update to that test file's assertions — do not delete one without the
   other. */
.cds-chip {
    background: #EBDFC5;
    color: var(--forest-green, #0F2F24);
    border: 1px solid var(--surface-border);
    transition: background 150ms ease, border-color 150ms ease;
}
.cds-chip:hover {
    background: color-mix(in srgb, #EBDFC5 80%, #C5A059 20%);
}
[data-theme="dark"] .gp-shell .cds-chip,
[data-theme="dark"] .lp-shell .cds-chip {
    background: var(--surface-elevated);
    color: var(--warm-linen, #EFE7D6);
}
[data-theme="dark"] .gp-shell .cds-chip:hover,
[data-theme="dark"] .lp-shell .cds-chip:hover {
    background: color-mix(in srgb, var(--warm-linen) 15%, var(--surface-elevated));
}


/* ── cds-button--ghost (D-P2-003) — transparent button with ghost-gold border ── */
.cds-button--ghost {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    background: transparent;
    border: 1px solid var(--rule-gold, rgba(197,160,89,0.30));
    color: var(--forest-green, #0F2F24);
    border-radius: var(--radius, 2px);
    transition: background 150ms ease;
    cursor: pointer;
}
.cds-button--ghost:hover {
    background: color-mix(in srgb, var(--burnished-gold, #C5A059) 8%, transparent);
}
[data-theme="dark"] .gp-shell .cds-button--ghost,
[data-theme="dark"] .lp-shell .cds-button--ghost,
[data-theme="dark"] .console-shell .cds-button--ghost,
[data-theme="dark"] .portal-shell .cds-button--ghost,
[data-theme="dark"] .cloud-public .cds-button--ghost {
    color: var(--warm-linen, #EFE7D6);
    border-color: var(--surface-border);
}

/* Fix (R-TC residue batch r1b4, 2026-09-03): a close/dismiss button that
   pairs `.cds-button--ghost` (unlayered, sets `color: var(--forest-green)`
   above in LIGHT theme, no shell scope needed) with the `text-on-primary`
   utility -- e.g. components/_drawer.html's close button inside a `bg-forest`
   header, components/explainer_banner.html's dismiss button on a forest
   gradient. `.cds-button--ghost` is unlayered CSS; `text-on-primary` is a
   layered Tailwind utility, so the SAME "unlayered beats layered regardless
   of specificity" trap documented for the h1..h6 fallbacks and
   `.console-shell .text-on-primary` / `.cloud-public .text-on-primary`
   above applies here too -- forest-green-on-forest-fill measured 1.13:1 in
   light theme. Dark theme already passes (11.75:1) via the
   `[data-theme="dark"] .<shell> .cds-button--ghost` block immediately
   above, which is why this fix is unscoped (no shell prefix, no
   `[data-theme="dark"]` guard) rather than folded into that block: both of
   this rule's call sites are shell-agnostic components with no guaranteed
   `.gp-shell`/`.lp-shell`/etc. ancestor, and the two-class selector
   (0,2,0) already beats the plain `.cds-button--ghost` (0,1,0) rule above
   in light theme without disturbing the more specific dark-theme block. */
.cds-button--ghost.text-on-primary {
    color: var(--color-on-primary, #EFE7D6) !important;
}
.cds-button--ghost.bg-primary {
    background-color: var(--forest-green) !important;
}

/* R-VIS (2026-09-04): `.cds-button--ghost` and `.theme-toggle` both declare
   their own unlayered `background: transparent`. gate_theme_contrast.py's
   ground resolution treats ANY same-element unlayered background rule
   (custom-bg) as authoritative and self-inclusive -- it stops walking up
   the ancestor chain the moment it finds one, even when that rule's value
   ("transparent") can't be resolved to an actual color, so it falls back to
   the page CANVAS instead of compositing through to the real ancestor fill.
   Three call sites genuinely sit on the permanently-forest `bg-primary`
   sidebar/header (never re-themed) but carry `.cds-button--ghost` or
   `.theme-toggle` directly on themselves, so the scanner never sees that
   forest ancestor: console/base_console.html's Conductive Concierge
   sidebar-footer button, and partners/base_partners.html's desktop +
   mobile theme-toggle buttons. `.cds-forest-ground`, placed FIRST in each
   of those three elements' class list (custom-bg class matching is
   first-in-list-wins, not specificity-ranked), gives the scanner a
   resolvable ground before it ever reaches the transparent-background
   class. Painting the exact same `--color-primary` forest fill the
   ancestor already provides is a real declaration, not a scanner-only
   shim, so it is visually a no-op in both themes (this brand anchor never
   flips) while making ground resolution correct. */
.cds-forest-ground {
    background-color: var(--color-primary);
}

/* t_f8dbea1c: --surface-focus-ring is forest in light, which would vanish
   (1:1) on the permanently-forest brand grounds that never re-theme -- the
   .cds-forest-ground controls above, forest hero/section/row fills
   (.bg-primary / .bg-forest), and the bg-primary <body> of non-.cloud-public
   pages (base.html default, cloud/directory_home.html, directory/login.html).
   Controls on those grounds keep the gold ring (5.88:1 on #0F2F24).
   Bounded so controls themselves (:not(button)...) do not pick up the reset
   when carrying bg-primary on linen, .cloud-public body is excluded (repainted
   linen in light), and nested light surfaces re-establish the light forest token. */
:is(.bg-primary, .bg-forest):not(.cloud-public):not(button):not(a):not(input):not(select):not(textarea):not(.cds-button):not([role="button"]),
.cds-forest-ground {
    --surface-focus-ring: var(--burnished-gold);
}

/* Light surfaces nested under a forest ancestor re-establish the light forest token
   so buttons and interactive controls on linen/canvas/elevated grounds clear >= 3:1. */
:is(.bg-background-light, [class*="bg-background-light"], .bg-linen, .bg-white, .bg-canvas, .setting-card, .cds-card, .cads-card, .cads-bg-surface, .bg-surface-elevated) {
    --surface-focus-ring: var(--forest-green);
}

/* Explicit dark theme keeps gold focus ring (OS-dark mirror counterpart is in the sanctioned @media block above). */
[data-theme="dark"] :is(.bg-background-light, [class*="bg-background-light"], .bg-linen, .bg-white, .bg-canvas, .setting-card, .cds-card, .cads-card, .cads-bg-surface, .bg-surface-elevated) {
    --surface-focus-ring: var(--burnished-gold);
}

/* ── cds-suggestion-chip (D-P2-002) — canonical alias used by _chat_suggestion_chip.html ── */
.cds-suggestion-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.375rem 0.875rem;
    font-size: 0.75rem;
    font-family: var(--font-body, sans-serif);
    white-space: nowrap;
    flex-shrink: 0;
    min-height: 2rem;
    border-radius: 2px;
    border: 1px solid color-mix(in srgb, var(--burnished-gold, #C5A059) 40%, transparent);
    background: var(--stone, #E4E0D8);
    color: var(--forest-green, #0F2F24);
    cursor: pointer;
    transition: background 150ms ease, border-color 150ms ease;
}
.cds-suggestion-chip:hover {
    background: color-mix(in srgb, var(--burnished-gold, #C5A059) 10%, var(--stone, #E4E0D8));
    border-color: color-mix(in srgb, var(--burnished-gold, #C5A059) 65%, transparent);
}
.cds-suggestion-chip__icon {
    flex-shrink: 0;
    color: currentColor;
    opacity: 0.7;
}
.cds-suggestion-chip__label {
    line-height: 1.4;
}
[data-theme="dark"] .gp-shell .cds-suggestion-chip,
[data-theme="dark"] .lp-shell .cds-suggestion-chip {
    background: var(--surface-elevated);
    color: var(--warm-linen, #EFE7D6);
    border-color: var(--surface-border);
}
[data-theme="dark"] .gp-shell .cds-suggestion-chip:hover,
[data-theme="dark"] .lp-shell .cds-suggestion-chip:hover {
    background: color-mix(in srgb, var(--warm-linen) 12%, var(--surface-elevated));
}

/* ============================================================================
   PUBLIC / PRE-AUTH DARK MODE (.cloud-public) — Wave-0 theme parity for the
   conductive.cloud marketing + pre-auth surfaces. The public pages author the
   same bg-background-light / bg-linen / bg-white / text-primary / text-forest
   utility vocabulary as the GP/LP shells but were NOT scoped into any dark-mode
   recolor, so the persistent [data-theme] toggle was a visual no-op on /,
   /login, /request-access, /pricing, /about, /features, /solutions, /support.
   This mirrors the proven .gp-shell / .lp-shell recoloring, scoped strictly to
   .cloud-public (applied on the base_cloud + base_marketing <body>) so no GP,
   LP, portal, biz, or error surface is touched. !important is required because
   the compiled Tailwind asset (/assets/tailwind.css) loads AFTER conductive.css.
   The forest-green hero/landing surfaces (bg-primary / bg-forest) are an
   explicit brand anchor and are intentionally NOT recolored — they stay forest
   in both themes, exactly like the GP/LP sidebar anchor.
   ============================================================================ */

/* Page canvas — the marketing body uses bg-background-light; the cloud base body
   uses bg-primary. In dark both become the deep green-black PAGE ground. */
[data-theme="dark"] .cloud-public.bg-background-light,
[data-theme="dark"] .cloud-public.bg-primary {
    background-color: var(--surface-canvas) !important;
    color: var(--surface-text);
}

/* LIGHT page canvas — SYSTEMIC theme-flip root fix (2026-06-26, JTP P0). The
   unlayered base `body { background-color: var(--forest-green) }` rule (≈L162)
   beats the layered Tailwind bg-primary / bg-background-light utility on every
   public body, so in LIGHT mode the page ground stayed forest #0F2F24 — the
   [data-theme] toggle was a visual no-op on 13 public pages (/solutions,
   /pricing, /privacy, /terms, /security, /support, /request-access, /features,
   /regulatory, /pulse-investors, /solutions/api|document-vault|investor-reporting).
   This is the exact mirror of the [data-theme="dark"] canvas rule above: restore
   the warm-linen PAGE ground + forest text in light, satisfying the JTP
   "light default + dark toggle" public contract. The compound .cloud-public.bg-*
   selector matches ONLY the <body> element (both classes co-located), so inner
   forest hero `<section class="bg-primary">` brand anchors — which carry .bg-primary
   WITHOUT .cloud-public — stay forest in both themes, exactly as intended. */
[data-theme="light"] .cloud-public.bg-background-light,
[data-theme="light"] .cloud-public.bg-primary {
    background-color: var(--surface-canvas) !important;  /* warm-linen #EFE7D6 */
    color: var(--surface-text);                          /* forest-green #0F2F24 */
}

/* Partners public shell (CC4-4) — light-mode ghost-heading fix. partners/
   base_partners.html authors its own `bg-linen` canvas (not `bg-background-light`
   / `bg-primary`), so the compound selector above never matched it: body's color
   was governed solely by the unlayered `body { color: var(--warm-linen) }` /
   `h1..h6 { color: inherit }` rules, which always beat the layered Tailwind
   `.text-primary` utility on the <body> (native CSS cascade layers beat
   specificity), leaving headings at ~1.09:1 contrast on the near-linen ground.
   Scoped to the compound `.cloud-public.bg-linen` class — verified (2026-07-07)
   that partners/base_partners.html is the ONLY template using that combination,
   so this cannot affect any other surface. Gated to non-dark so the pre-existing
   (correct) dark-mode look — linen text on the forest canvas from the unscoped
   defaults above — is left untouched, per JTP: this is a light-mode-only fix,
   not a theme-toggle fix. */
.cloud-public.bg-linen {
    color: var(--forest-green);
}
[data-theme="dark"] .cloud-public.bg-linen {
    color: var(--warm-linen);
}

/* Auth dark ground exception — /login and /signup must keep the body on the
   Hunter Green ramp instead of dropping to near-black. Their centered
   auth panel already renders a lighter inner bg-primary ramp, so restoring the
   body to forest keeps the page within the official dark-ground posture without
   changing the broader cloud-public dark-mode system. */
[data-theme="dark"] .cloud-public.cloud-auth-public.bg-primary {
    background-color: var(--forest-green) !important;
}

/* Elevated surfaces — page sections and cards authored as bg-white / bg-linen /
   bg-background-light. In dark they become forest-mid cards that read above the
   page ground. */
[data-theme="dark"] .cloud-public .bg-white,
[data-theme="dark"] .cloud-public .bg-linen,
[data-theme="dark"] .cloud-public .bg-background-light {
    background-color: var(--surface-elevated) !important;
    color: var(--surface-text);
}

/* Sunken inset wells (table stripes / faint primary tints) → sunken token. */
[data-theme="dark"] .cloud-public .bg-primary\/5,
[data-theme="dark"] .cloud-public .bg-gray-50,
[data-theme="dark"] .cloud-public .bg-gray-100,
[data-theme="dark"] .cloud-public .bg-neutral-50 {
    background-color: var(--surface-sunken) !important;
}

/* Primary content text — text-primary / text-forest headings + body flip to
   warm linen so they read on the dark ground/cards.
   R-CSS-4 (2026-09-04): .text-primary\/90 joins the 100%-target group here,
   same rationale as the .gp-shell/.console-shell fix above -- 90% opacity
   reads as full-strength body copy, not the /40-/85 muted family below. */
[data-theme="dark"] .cloud-public .text-primary,
[data-theme="dark"] .cloud-public .text-forest,
[data-theme="dark"] .cloud-public .text-primary\/90,
[data-theme="dark"] .cloud-public .cads-text-on-light {
    color: var(--surface-text) !important;
}

/* Muted/secondary text (forest-at-opacity utilities) → readable linen-muted. */
[data-theme="dark"] .cloud-public .text-primary\/40,
[data-theme="dark"] .cloud-public .text-primary\/50,
[data-theme="dark"] .cloud-public .text-primary\/60,
[data-theme="dark"] .cloud-public .text-primary\/65,
[data-theme="dark"] .cloud-public .text-primary\/70,
[data-theme="dark"] .cloud-public .text-primary\/75,
[data-theme="dark"] .cloud-public .text-primary\/80,
[data-theme="dark"] .cloud-public .text-primary\/85,
[data-theme="dark"] .cloud-public .text-muted,
[data-theme="dark"] .cloud-public .cads-text-muted {
    color: var(--surface-text-muted) !important;
}

/* AA-on-light gold accent text bumps up to gold-400 on dark, not raw
   burnished gold: `var(--surface-gold)`/`var(--burnished-gold)` (#C5A059)
   measures only 3.92:1 on the forest-mid card, under the 4.5:1 body-text
   floor per the R-CSS-3 comment two blocks above this one; gold-400
   (#D4B472) clears 4.85:1 on forest-mid / 7.28:1 on page.
   Fix (review-r1), 2026-09-04: was `var(--gold-accessible)`, which relied
   on that custom property itself being redefined to #D4B472 in dark theme
   -- removed per the gate's committed contract that --gold-accessible is a
   theme-invariant raw constant (see its :root declaration). Literal here
   instead (not `var(--color-gold-400)`): that custom property is defined
   in input.css's @theme, not in this file's own scope, and L10 doctrine
   keeps dark literals hand-synced rather than reaching across files.
   Scoped to .cloud-public only; other shells' analogous rules are untouched
   here (out of this batch's file list). */
[data-theme="dark"] .cloud-public .text-gold-accessible {
    color: #D4B472 !important;
}

/* Coordinator 2026-09-03 (T4/T4b): .cloud-public previously had NO dark
   remap at all for the status-text utilities -- same gap the other four
   shells (gp/console/lp/portal) already closed further above. Same
   contrast numbers / V7a rationale (error stays linen-neutral, an accent
   is never the words on dark; success/warning carry their own hue). */
/* R-CSS-3 (2026-09-03) correction: retuned success-text from leaf green to
   ink (#F9F8F6) -- see the gp/console block's R-CSS-3 comment (matches this
   shell's own .text-status-error -> --color-ink treatment just below). */
[data-theme="dark"] .cloud-public .text-status-success {
    color: #F9F8F6 !important;
}
[data-theme="dark"] .cloud-public .border-status-success {
    border-color: #8FCB6B !important;
}
[data-theme="dark"] .cloud-public .bg-status-success {
    background-color: #8FCB6B !important;
}
[data-theme="dark"] .cloud-public .bg-status-success.text-white,
[data-theme="dark"] .cloud-public .bg-status-success.text-on-primary {
    background-color: color-mix(in srgb, #8FCB6B 22%, transparent) !important;
}
/* R-CSS-3 adversary round (2026-09-03): matches the gp-shell/console-shell
   fix above -- --burnished-gold measured only 3.92:1 on the forest-mid
   card, under the 4.5:1 body-text floor; gold-400 (#D4B472) clears 4.85:1. */
[data-theme="dark"] .cloud-public .text-status-warning {
    color: #D4B472 !important;
}
/* R-CSS-3 (2026-09-03): mirrors the gp/console/lp/portal .text-error-500/
   .text-error-700 fix above -- same gap, this shell's own existing target
   token (--color-ink, matching .text-status-error just above).
   R-CSS-3 adversary round (2026-09-03): .text-error-800 added, mirroring
   the gp-shell/console-shell fix -- same un-remapped-against-dark-fill gap. */
[data-theme="dark"] .cloud-public .text-error-500,
[data-theme="dark"] .cloud-public .text-error-700,
[data-theme="dark"] .cloud-public .text-error-800,
[data-theme="dark"] .cloud-public .text-status-error {
    color: var(--color-ink) !important;
}
/* R-CSS-3 (2026-09-03): mirrors the gp/console .bg-error-100 fix above --
   see that block's comment. */
[data-theme="dark"] .cloud-public .bg-error-100 {
    background-color: color-mix(in srgb, #C0453B 22%, transparent) !important;
}

/* Public marketing chrome — the sticky nav uses Tailwind bg-linen/95 (opacity
   variant). That utility is NOT matched by the .bg-linen recolor above, so in
   dark mode the bar stayed warm-linen while descendant .text-primary flipped to
   warm-linen text → light-on-light illegibility. Recolor the entire .chrome-bar
   as one forest-mid surface so flipped nav/brand tokens read at AA (≥4.5:1). */
[data-theme="dark"] .cloud-public .chrome-bar {
    background-color: color-mix(in srgb, var(--surface-elevated) 95%, transparent) !important;
    color: var(--surface-text);
}

/* Hairline gold borders/dividers gain a touch more presence on the dark field. */
[data-theme="dark"] .cloud-public [class*="border-gold"] {
    border-color: var(--surface-border) !important;
}
[data-theme="dark"] .cloud-public [class*="divide-gold"] > :not([hidden]) ~ :not([hidden]) {
    border-color: var(--surface-border) !important;
}

/* V13: the theme toggle (border-gold/45) sits inside a shell's own
   wildcard-remapped border-gold rule above (0,3,0) with !important. Its own
   surface-border remap already lifted (see the 60% raise above), but the
   toggle -- including the icon-only phone width -- needs a distinct, more
   visible linen outline than the generic hairline, since it is a persistent
   interactive control, not a passive divider. This selector's specificity
   (0,3,1 element+attr on top of the class list) plus !important wins over
   every shell wildcard rule above, including this file's own. Covers every
   [data-theme-toggle] button (base.html chrome, GP sidebar/mobile, LP
   header) via the shared `.theme-toggle` class + attribute selector. */
html[data-theme="dark"] body .theme-toggle[data-theme-toggle] {
    /* fix (R-VIS-r1 verify, 2026-09-04): the R-VIS swap to var(--gold-accessible)
       (#856A28) traded one invisibility bug for a worse, wider one. #856A28 only
       clears 2.82:1 on --surface-canvas dark (#0F2F24) and 1.88:1 on
       --surface-elevated dark (#1B4D3E, the "card" tone GP/mobile toggles also
       render over) -- both under the 3:1 non-text/UI-component floor this file
       enforces everywhere else (see --surface-border's own >=3:1 target two
       screens up). That regressed every [data-theme-toggle] instance that
       genuinely sits on a real dark canvas/card: base.html default chrome,
       GP sidebar/mobile, LP header, components/nav.html, and (via the new
       .cds-forest-ground fill added alongside this fix) partners' own desktop
       toggle.
       No live template was found where the toggle persists on a light canvas
       while html carries [data-theme="dark"]: every shell that renders
       [data-theme-toggle] either gets the full dark-canvas CSS treatment
       (.gp-shell / .console-shell / .lp-shell / .portal-shell / .cloud-public
       -- see the STALE NOTE on .console-shell a few screens up, which already
       retracted the "no dark flip" premise for that shell) or renders on a
       permanently-dark bg-primary chrome regardless of theme (base.html's own
       default body_class, cloud/directory_home.html, directory/login.html,
       mc/base.html, partners/base_partners.html). So the "13 pages whose
       chrome never flips to dark" premise this rule was swapped in for does
       not hold against the current tree; restoring the prior, dark-ground-
       proven value is the correct fix rather than a global swap.
       A single solid color cannot clear 3:1 on BOTH the light canvas
       (~#EFE7D6-family, relative luminance ~0.80) AND the dark card
       (#1B4D3E, ~0.059) simultaneously: the light floor caps a candidate's
       luminance at ~0.235, the card floor requires >=~0.277 -- the two
       requirements do not overlap for any single opaque token. If a page
       with a genuinely non-flipping light chrome under [data-theme="dark"]
       turns up, the correct fix is a scoped, higher-specificity override
       for that shell alone (mirroring the .cds-forest-ground pattern
       above), not another global swap of this rule.
       Reverting to color-mix(in srgb, var(--warm-linen) 50%, transparent):
       this exact value was the last proven-safe state (R-CSS-3 adversary
       round, 2026-09-03) -- 4.06:1 on the dark page ground, 3.21:1 on the
       dark card ground, both clearing the 3:1 floor with margin (recomputed
       here via the same sRGB-average method the deleted comment used, to
       3 significant figures). */
    border-color: color-mix(in srgb, var(--warm-linen) 50%, transparent) !important;
}
/* .theme-toggle-chrome's control already carries [data-theme-toggle] (verified
   in base.html), so the rule above already covers it; no separate class-only
   rule needed (one would apply outside the dark scope and be wrong in light). */

/* V13 light-mode companion (residual round, 2026-09-03): the same toggle's
   Tailwind border-gold/45 and mobile-collapsed border-linen/20 utilities bake
   to ~1.15-1.21:1 / ~1.18:1 against Aged Linen -- both under the 1.5:1
   invisible floor. This selector (element+attr specificity, same shape as
   the dark rule above) wins over whichever utility class landed on the
   button and replaces it with a full-strength gold hairline, regardless of
   which of the two invisible utility classes is present. `:not([data-theme="dark"])`
   also catches pages where the dark attribute failed to apply (residual-
   worklist's "dark" rows that measured colour==background==Aged Linen).
   R-CSS-3 adversary round (2026-09-03): the raw --burnished-gold hairline
   this comment called "the canon hairline JTP accepted" actually measured
   ~1.8-2.0:1 across the light grounds -- under the 3:1 non-text-UI floor
   despite the comment's own framing. Reusing var(--gold-accessible) (the
   light-mode darkened-gold token this same round already retuned for text
   use, #735C23) instead of raw --burnished-gold clears 4.58:1 / 5.20:1 /
   4.96:1 across the three light grounds, with large margin, while staying
   on-brand with this round's other "accessible gold" retunes. This is a
   sanctioned new light-theme !important addition for this pass, alongside
   the cads-bg-surface border-color scoping. */
html[data-theme="light"] body .theme-toggle[data-theme-toggle],
html:not([data-theme="dark"]) body .theme-toggle[data-theme-toggle] {
    border-color: var(--gold-accessible) !important;
}

/* Dark-flip public hero gradients. The .bg-* recolors above match background-color
   only, not the gradient --tw-gradient-from / --tw-gradient-to vars, so heroes stayed
   light in dark mode (linen H1 invisible). Re-point the linen / background-light
   gradient stop vars to the dark surface ramp. */
[data-theme="dark"] .cloud-public .from-background-light { --tw-gradient-from: var(--surface-canvas) !important; }
[data-theme="dark"] .cloud-public .to-background-light   { --tw-gradient-to:   var(--surface-canvas) !important; }
[data-theme="dark"] .cloud-public .from-linen            { --tw-gradient-from: var(--surface-elevated) !important; }
[data-theme="dark"] .cloud-public .to-linen              { --tw-gradient-to:   var(--surface-elevated) !important; }

/* ----------------------------------------------------------------------------
   Mobile legibility for the persistent top-right chrome theme toggle. At narrow
   widths the transparent toggle can visually collide with page copy beneath it.
   A subtle surface backdrop keeps the control legible without introducing the
   banned gold fill. Desktop is unchanged.
   ---------------------------------------------------------------------------- */
@media (max-width: 767px) {
    .theme-toggle-chrome .theme-toggle {
        background-color: color-mix(in srgb, var(--surface-canvas) 78%, transparent);
    }
}

/* ----------------------------------------------------------------------------
   Public marketing chrome theme toggle — light-mode legibility on linen nav.
   Gold-only treatment can fall below 4.5:1 on bg-linen/95; forest text +
   stronger hairline keeps label + icon readable without a gold fill.
   ---------------------------------------------------------------------------- */
.cloud-public .chrome-bar .theme-toggle {
    color: var(--forest-green);
    border-color: color-mix(in srgb, var(--forest-green) 35%, transparent);
}
.cloud-public .chrome-bar .theme-toggle:hover {
    color: var(--gold-accessible);
    background-color: color-mix(in srgb, var(--forest-green) 8%, transparent);
}
[data-theme="dark"] .cloud-public .chrome-bar .theme-toggle {
    color: var(--burnished-gold);
    border-color: color-mix(in srgb, var(--burnished-gold) 45%, transparent);
}
[data-theme="dark"] .cloud-public .chrome-bar .theme-toggle:hover {
    color: var(--warm-linen);
    background-color: color-mix(in srgb, var(--burnished-gold) 15%, transparent);
}

/* ----------------------------------------------------------------------------
   Request access form — CDS surface tokens on the forest hero. Avoids warm-linen
   input text on linen cards and off-palette card fills in dark mode.
   ---------------------------------------------------------------------------- */
.request-access-page .request-access-form {
    background-color: var(--surface-elevated) !important;
    color: var(--surface-text);
    border-color: var(--surface-border) !important;
}
.request-access-page .request-access-field {
    color: var(--surface-text);
    border-bottom-color: color-mix(in srgb, var(--surface-text) 35%, transparent) !important;
}
.request-access-page .request-access-field:focus {
    border-bottom-color: var(--burnished-gold) !important;
}
.request-access-page .request-access-label {
    color: var(--text-muted);
}
.request-access-page .request-access-field:focus + .request-access-label,
.request-access-page .request-access-field:not(:placeholder-shown) + .request-access-label {
    color: var(--gold-accessible);
}
.request-access-page .request-access-field option {
    color: var(--surface-text);
    background-color: var(--surface-elevated);
}

/* ============================================================================
   PUBLIC PAGE OVERFLOW CONTAINMENT (LANE-ROOT — overflow-fix 2026-06-26)
   Safety lock + reusable code-block scroll utility for .cloud-public surfaces.
   CDS frozen: geometry-only containment rules, no color/font changes.
   Other lanes: apply class="cloud-code-scroll" on <pre> (or a wrapper) instead
   of ad-hoc overflow utilities.
   ============================================================================ */

/* Page-level horizontal scroll lock — clip (not hidden) preserves sticky chrome. */
html:has(body.cloud-public) {
    overflow-x: clip;
}
body.cloud-public {
    overflow-x: clip;
}

/* Reusable code block scroll container. Apply to <pre> or wrap <pre><code>.
   Keeps white-space:pre formatting; only the box scrolls horizontally. */
.cloud-code-scroll,
pre.cloud-code-scroll {
    overflow-x: auto;
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
    white-space: pre;
}
.cloud-code-scroll code,
pre.cloud-code-scroll code {
    white-space: pre;
}

/* Codex-BLOCKER-1 fix: [overflow-wrap:anywhere] arbitrary class is NOT in compiled
   output.css; provide it directly so long filenames/strings wrap instead of relying
   on the .cloud-public clip. Geometry-only; CDS-safe. (overflow-fix 2026-06-26) */
.\[overflow-wrap\:anywhere\] { overflow-wrap: anywhere; }

/* Drill provenance breadcrumb — horizontal scroll on narrow viewports (D1 2026-06-27) */
.drill-breadcrumb-scroll {
    overflow-x: auto;
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}
.drill-breadcrumb-scroll::-webkit-scrollbar {
    height: 4px;
}
.drill-breadcrumb-scroll::-webkit-scrollbar-thumb {
    background-color: color-mix(in srgb, var(--color-gold, #C5A059) 35%, transparent);
    border-radius: 2px;
}

/* ── CADS Tabulator theme — BackOffice Expense Ledger only (AMEND2 2026-08-17)
   Scoped to #expense-ledger-section so the vendor tabulator.min.css keeps
   serving any future unscoped instance. The ID in every selector out-ranks
   all vendor rules (specificity, not load order — conductive.css loads
   before the vendor sheet). The html:not([data-theme="dark"]) guard leaves
   the tabulator_midnight skin in charge of dark mode. Target look = the
   on-brand #expense-fallback-table in the same section: linen surface,
   gold hairlines, uppercase Geist headers, mono tabular-nums amounts. */
html:not([data-theme="dark"]) #expense-ledger-section .tabulator {
    background: transparent;
    border: none;
    font-family: var(--font-body);
    color: var(--forest-green);
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-header {
    background: var(--warm-linen);
    border-bottom: 1px solid color-mix(in srgb, var(--burnished-gold) 25%, transparent);
    color: var(--forest-green);
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-header .tabulator-col {
    background: transparent;
    border-right: none;
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-header .tabulator-col .tabulator-col-title {
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
    padding: 0.25rem 0;
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover {
    background: color-mix(in srgb, var(--burnished-gold) 10%, transparent);
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-header .tabulator-col .tabulator-col-sorter,
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-sorter .tabulator-arrow {
    color: var(--gold-accessible);
    border-bottom-color: var(--gold-accessible);
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-tableholder {
    background: transparent;
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-tableholder .tabulator-table {
    background: transparent;
    color: var(--forest-green);
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-row {
    background: transparent;
    border-bottom: 1px solid color-mix(in srgb, var(--burnished-gold) 12%, transparent);
    min-height: 0;
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-row.tabulator-row-even {
    background: transparent; /* no vendor zebra — hairlines carry the rhythm */
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-row:hover,
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-row.tabulator-row-even:hover {
    background: color-mix(in srgb, var(--burnished-gold) 8%, transparent);
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-row .tabulator-cell {
    border-right: none;
    padding: 0.75rem 1rem;
    font-size: 0.875rem;
    color: var(--forest-green);
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-row .tabulator-cell.tabular-nums {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-placeholder .tabulator-placeholder-contents {
    color: var(--text-muted);
    font-family: var(--font-body);
    font-size: 0.875rem;
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-footer {
    background: var(--warm-linen);
    border-top: 1px solid color-mix(in srgb, var(--burnished-gold) 25%, transparent);
    color: var(--forest-green);
    font-family: var(--font-body);
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-footer .tabulator-footer-contents {
    background: transparent;
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-footer .tabulator-page,
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-footer .tabulator-page-size {
    background: var(--warm-linen);
    border: 1px solid color-mix(in srgb, var(--burnished-gold) 45%, transparent);
    border-radius: 0.25rem;
    color: var(--forest-green);
    font-size: 0.75rem;
    padding: 0.25rem 0.625rem;
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-footer .tabulator-page:not(.disabled):hover {
    background: color-mix(in srgb, var(--burnished-gold) 15%, transparent);
    color: var(--forest-green);
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-footer .tabulator-page.active {
    background: var(--forest-green);
    border-color: var(--forest-green);
    color: var(--warm-linen);
}
[data-theme="dark"] #expense-ledger-section .tabulator .tabulator-footer .tabulator-page.active,
[data-theme="dark"] .tabulator .tabulator-footer .tabulator-page.active {
    background: var(--surface-primary-mid, #1A4D3E) !important;
    border-color: var(--burnished-gold) !important;
    color: var(--warm-linen) !important;
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-footer .tabulator-page.disabled {
    opacity: 0.35; /* dimmed but still a visible bordered control */
    color: var(--forest-green);
}
html:not([data-theme="dark"]) #expense-ledger-section .tabulator .tabulator-footer .tabulator-paginator > label {
    color: color-mix(in srgb, var(--forest-green) 70%, transparent);
    font-size: 0.75rem;
}

/* Tuning Room hero: ensure .trh has opaque forest background in both themes */
.gp-shell .trh {
    background-color: var(--forest-green) !important;
}
.gp-shell .trh-door-caption,
.gp-shell .trh-privacy,
.gp-shell [data-testid="privacy-disclosure"] {
    color: var(--warm-linen) !important;
}
.gp-shell .trh .text-gold,
.gp-shell .trh .text-gold-accessible {
    color: #D4B472 !important;
}

.gp-shell .text-on-primary\/70,
.console-shell .text-on-primary\/70 {
    color: color-mix(in srgb, var(--color-on-primary, #EFE7D6) 85%, transparent) !important;
}

/* WCAG AA contrast remediation: ensure normal-sized text (< 18.66px bold / < 24px regular)
   authored with .text-subtle achieves >= 4.5:1 contrast in both light and dark themes */
.gp-shell .text-subtle.font-body,
.gp-shell .text-subtle.text-xs,
.gp-shell .text-subtle.text-sm,
.gp-shell .text-subtle.font-display.text-sm,
.gp-shell .text-subtle.font-display.text-xs,
.gp-shell .font-body .text-subtle,
.gp-shell .text-xs .text-subtle,
.gp-shell .text-sm .text-subtle,
.gp-shell th.text-subtle {
    color: var(--text-muted) !important;
}
[data-theme="dark"] .gp-shell .text-subtle.font-body,
[data-theme="dark"] .gp-shell .text-subtle.text-xs,
[data-theme="dark"] .gp-shell .text-subtle.text-sm,
[data-theme="dark"] .gp-shell .text-subtle.font-display.text-sm,
[data-theme="dark"] .gp-shell .text-subtle.font-display.text-xs,
[data-theme="dark"] .gp-shell .font-body .text-subtle,
[data-theme="dark"] .gp-shell .text-xs .text-subtle,
[data-theme="dark"] .gp-shell .text-sm .text-subtle,
[data-theme="dark"] .gp-shell th.text-subtle {
    color: var(--surface-text-muted) !important;
}

/* Message composer contenteditable placeholder contrast */
.gp-shell [contenteditable]:empty::before,
.gp-shell .empty\:before\:text-primary\/60:empty::before {
    color: var(--text-muted) !important;
}
[data-theme="dark"] .gp-shell [contenteditable]:empty::before,
[data-theme="dark"] .gp-shell .empty\:before\:text-primary\/60:empty::before {
    color: var(--surface-text-muted) !important;
}

/* ============================================================================
   GP wizard progress bar segments (WCAG 2.2 SC 1.4.11 non-text contrast >= 3:1)
   t_007ace1e: Eliminates raw gold fills on wizard progress bars (CDS Ruling F).
   ============================================================================ */
.gp-progress-bar__segment {
    flex: 1 1 0%;
    height: 0.25rem;
    border-radius: var(--radius-sm, 2px);
    transition: all 300ms ease;
}
.gp-progress-bar__segment--upcoming {
    background-color: var(--surface-progress-upcoming);
}
.gp-progress-bar__segment--completed {
    background-color: var(--surface-progress-completed);
}
.gp-progress-bar__segment--current {
    background-color: var(--surface-progress-current);
}

