/* THE FORENSIC THEME, as pd ships it: VENDORED from platinumdigital src/index.css at origin/main 82ef5cb4b (2026-10-21), verbatim
   except as noted. Change the theme in pd, then re-vendor (scripts/vendor-theme.md); never edit a value here.
   - the self-hosted faces (SS-10022), paths pointed at ./fonts/;
   - the :root token layer (SS-10019 and later), unlayered here (pd keeps it in @layer base);
   - the toggle motion tokens (SS-11012);
   - .label-mono (SPEC §4 micro-label);
   - html / body base, the crown (SS-10020, body::before) and the hairline default border (pd @layer base). */

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('./fonts/IBMPlexMono-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('./fonts/IBMPlexMono-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('./fonts/IBMPlexMono-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('./fonts/Poppins-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('./fonts/Poppins-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('./fonts/Poppins-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('./fonts/Poppins-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* ---- surfaces ---------------------------------------- */
  --background: 222 40% 4%;          /* #070910 */
  --foreground: 216 30% 96%;         /* #f4f6fa */
  --card: 217 25% 10%;               /* #131820 — was `transparent` (spec §9.2) */
  --card-foreground: 216 30% 96%;
  --popover: 220 26% 8%;
  --popover-foreground: 216 30% 96%;

  /* Hairline borders. Components apply their own alpha
     (glassmorphism.css uses /0.4 and /0.65). */
  --border: 216 14% 34%;
  --input: 217 22% 14%;
  /* [SS-10905] SPEC §3's ONE hairline: `1px solid rgba(255,255,255,.09)` (SPEC.md:70-74). The default border colour of every element
     (the base rule at the end of this layer), so a bare Tailwind `border` is the hairline, not preflight's gray-200. A full colour, not
     an H S% L triplet: read it as var(--hairline). --border keeps its value: glassmorphism.css reads it (ADDENDUM-2026-10-11 §8). */
  --hairline: rgba(255, 255, 255, .09);
  /* [SS-10906] SPEC §3 'Hairline hover' (ADDENDUM-2026-10-11 §8.1: "it gets a name, not the palette literal border-white/20") */
  --hairline-hover: rgba(255, 255, 255, .2);

  /* ---- primary: BLUE = action + current location -------- */
  /* A1 2026-08-25 (operator, measured-beats-specified — SS-10023 precedent):
     61% measures 4.453:1 for normal text on --card (#131820), 0.047 under AA.
     62% measures 4.643:1. Re-derived here rather than taken on trust; the
     contrast implementation was validated against WCAG canonicals first
     (white/black = 21.000, #767676 on white = 4.542). */
  --primary: 221 100% 62%;           /* #3d7bff — was 61% (#3a78ff), sub-AA */
  --primary-foreground: 222 84% 10%; /* #04122e — dark text on blue */
  /**
   * [SS-10259] ⛔ THE "THIS IS INTERACTIVE" TOKEN — ONE VALUE, THREE JOBS.
   * Sampled from the operator's reference (2026-09-22, `Screenshot … 12.19.35 PM.png`) at three
   * independent places, all identical: the ALBUM cell text, the GENRE cell text, and the `Decide`
   * button's border AND label — `#85aaf9` in every one. A fourth use, "Auto-filled from search",
   * measures the same. ⇒ It is not three blues that happen to match; it is one signal meaning
   * "you can act on this", and three literals would drift the first time one was touched.
   *
   * ⚠️ SAME HUE AS `--primary` (221), LIGHTER AND LESS SATURATED: 91%/75% against 100%/62%.
   * `--primary` (#3d7bff) is the FILL blue and is too dark for body text on this ground; this is
   * its text-weight tint. Related, deliberately — not interchangeable.
   */
  --interactive: 221 91% 75%;        /* #85aaf9 — measured, not chosen */

  /**
   * ⛔ [SS-10259] TWO TOKENS AT ONE VALUE, AND THE DUPLICATION IS DELIBERATE AND RECORDED.
   *
   * `hsl(218 100% 74%)` = `#7aabff` was a LITERAL repeated **9 times** in `reviewLedger.css`,
   * painting ~210 elements live. ⚠️ It is not one colour doing one job — it is TWO meanings that
   * came to share a value by accident:
   *
   *   --primary-ink   the readable INK on a PRIMARY-TINTED surface. Four sites share one exact
   *                   structure: `background: hsl(var(--primary)/.1–.18)` +
   *                   `border: hsl(var(--primary)/.5–.6)` + this colour as text —
   *                   `.cbx-spec[checked]`, `.step.is-current`, `.btn-outline`, `.pbtn.is-active`
   *                   (plus the current step's dot, the same state as a mark).
   *   --suggested     a ROW STATE: "the lookup proposed this". `.gly-sug`, `.t-sug`, `.v-sug`.
   *                   A claim about a row, not about an affordance.
   *
   * ⛔ ONE TOKEN FOR BOTH WOULD CONFLATE THEM — the error refused when `.v-sug` was kept off
   * `--interactive`, at nine times the scale. **Splitting them is the point; the shared value is
   * the accident.**
   *
   * ⚠️ AND BOTH DELIBERATELY KEEP THE LITERAL'S EXACT VALUE. This change is a REFACTOR: not one
   * pixel moves. Reconciling `--primary-ink` against `--interactive` (#85aaf9, ΔH 3° ΔS 9pp — a
   * near-identical blue for an arguably-identical job) is a VISIBLE change across ~210 elements
   * on a screen the operator has been ruling frame by frame. **That is his decision and it is
   * open — do not fold it in as tidying.**
   */
  --primary-ink: 218 100% 74%;       /* #7aabff — ink on a primary tint; value preserved verbatim */
  --suggested:   218 100% 74%;       /* #7aabff — "the lookup proposed this"; value preserved verbatim */
  --ring: 221 100% 62%;

  /* ---- verdict colors ---------------------------------- */
  --success: 153 100% 44%;           /* #00e07a — verified only */
  --warning: 42 89% 64%;             /* #f5c451 — headline metrics */
  --destructive: 7 88% 63%;          /* #f4614f */
  --destructive-foreground: 216 30% 96%;

  --secondary: 217 22% 16%;
  --secondary-foreground: 216 30% 96%;
  --muted: 217 20% 18%;
  --muted-foreground: 216 12% 65%;   /* #9ba4b0 — DERIVED from the rendered
                                        value, not copied. The previous hex
                                        here was wrong and misled two lanes
                                        into bad arithmetic. */
  /* SS-10042 Q1 (operator-ruled): the dim text tier. The ticket routed 56
     text-gray-500 sites here, but no such token existed — SS-10019 declared
     every other tier and skipped this one. Minted to preserve the three-tier
     hierarchy; AC7's "four semantic plus neutrals" covers a neutral.
     DELIBERATELY BELOW AA: 3.13:1 on the composited card (#0E121A), DERIVED
     here from rendered values. It is for dim/tertiary text, placeholders and
     empty states ONLY. Never put anything load-bearing on it. */
  --muted-dim: 216 13% 40%;          /* #5a6474 — 3.13:1, sub-AA BY DESIGN */

  --accent: 217 22% 16%;
  --accent-foreground: 216 30% 96%;

  /* ---- chart series ------------------------------------ */
  /* --chart-2 retargeted off the old Spotify green (was 142 76% 55%)
     to --warning per D1, ratified 2026-08-25: its four rendered
     sites are measured headline values, not verdicts. */
  --chart-1: 217 91% 65%;
  --chart-2: 42 89% 64%;             /* = --warning (D1 2026-08-25) */
  --chart-3: 38 92% 65%;
  --chart-4: 280 65% 75%;
  --chart-5: 340 75% 70%;
  /* SS-10042 A1 (PM-ruled, OPERATOR-ACCEPTED 2026-08-25): 6/7/8 were exposed in
     tailwind.config.ts as hard-coded literals but never declared here, so
     hand-written hsl(var(--chart-7)) resolved to nothing. Declared now.
     --chart-7 is RETARGETED off its lime literal (142 69% 58%) — the same green
     D1 removed from --chart-2 and --ai-success — onto the existing cyan, which is
     absent from chart-1..5 and avoids --perf-good's amber. Zero consumers, so the
     move renders identically. Hue reuse across families is normal here: this cyan
     also serves --ai-info and --rights-sync (cf. --rights-sync's own D1 note),
     exactly as 217-blue serves four. Do NOT de-duplicate them. */
  --chart-6: 16 100% 66%;            /* coral */
  --chart-7: 199 89% 48%;            /* cyan, = --ai-info (was lime — D1) */
  --chart-8: 270 95% 75%;            /* violet, = --ai-secondary */

  /* ---- AI Music family --------------------------------- */
  /* --ai-success retargeted off green (was 142 76% 45%) to --success
     per D1, ratified 2026-08-25. Zero consumers; semantic name is a verdict. */
  --ai-primary: 217 91% 60%;
  --ai-secondary: 270 95% 75%;
  --ai-success: 153 100% 44%;        /* = --success (D1 2026-08-25) */
  --ai-warning: 48 96% 53%;
  --ai-danger: 0 84% 60%;
  --ai-info: 199 89% 48%;

  /* ---- license status ---------------------------------- */
  /* Each status owns a hue. Consumed by SS-10023's status cards.
     The first three are aliases, not new statuses: src/lib/colors.ts:8-15
     already equates licensed=active, unlicensed=critical, pending=warning.
     They exist so tailwind.config.ts's `license` scale can drop its literals. */
  --license-active: 153 100% 44%;    /* #00e07a — was 142 76% 45% (D1) */
  --license-critical: 7 88% 63%;     /* #f4614f */
  --license-warning: 42 89% 64%;     /* #f5c451 */
  --license-suspended: 254 100% 77%; /* #a78bff */
  --license-expired: 216 12% 60%;    /* #8d96a5 — corrected SS-10042; the old
                                        #8b95a8 was the same wrong hex copied
                                        onto a DIFFERENT value (65% vs 60%). */
  --license-archived: 222 100% 68%;  /* #5c8cff */
  --license-draft: 187 70% 59%;      /* #4dcfe0 — [SS-10543] ruled by oros-design-theme 2026-09-24: cyan, 34° from licensed green, 35° from Archived, 34° from --interactive */
  --license-licensed: 153 100% 44%;  /* alias of --license-active */
  --license-unlicensed: 7 88% 63%;   /* alias of --license-critical */
  --license-pending: 42 89% 64%;     /* alias of --license-warning */

  /* ---- rights tiers ------------------------------------ */
  /* Categorical, not verdicts — no green. master/sync/performance/mechanical
     minted here at the literal values tailwind.config.ts:87-95 already held,
     so the scale can reference tokens without inventing a hue.
     D1 2026-08-25: --rights-indie collapses onto --rights-independent
     (indie IS independent — a duplicate concept, not a distinction), and
     --rights-sync takes the existing cyan, the one cool hue no categorical
     family uses. */
  --rights-major: 217 91% 65%;
  --rights-indie: 280 65% 75%;       /* alias of --rights-independent (D1 2026-08-25) */
  --rights-independent: 280 65% 75%;
  --rights-master: 280 65% 75%;
  --rights-sync: 199 89% 48%;        /* cyan, = --ai-info (D1 2026-08-25) */
  --rights-performance: 38 92% 65%;
  --rights-mechanical: 340 75% 70%;

  /* ---- catalog DNA clusters ---------------------------- */
  /* high/medium/low minted here at the literal values
     tailwind.config.ts:98-100 already held. D1 2026-08-25: --cluster-high
     takes the existing orange, giving the intensity ramp
     high=orange -> medium=yellow -> low=pink -> minimal=grey.
     Red stays reserved for negative findings. */
  --cluster-genre: 217 91% 65%;
  --cluster-emotion: 270 95% 75%;
  --cluster-theme: 340 75% 70%;
  --cluster-influence: 38 92% 65%;
  --cluster-high: 38 92% 65%;        /* orange, = --chart-3 (D1 2026-08-25) */
  --cluster-medium: 48 96% 65%;
  --cluster-low: 340 75% 70%;

  /* ---- performance indicators -------------------------- */
  /* --perf-excellent RULED 2026-08-26 (SS-10043 D4, operator): green -> CYAN.
     The D1 deferral pointed at SS-10021, which CLOSED without ruling the
     three-band scale, so the "DEFERRED" comment had gone stale and was
     pointing at a finished ticket.
     Ruling: the scale now reads COOL -> HOT (cyan / amber / red) across
     (>80 excellent / >60 good / else poor). That removes the green without
     colliding with --perf-good's amber, which is what blocked D1.
     A performance band is a MEASUREMENT, not a verdict — and green is
     verdict-only app-wide from 2026-08-26 (D6). Contrast: this is the same
     cyan as --ai-info and --chart-7. */
  --perf-excellent: 199 89% 48%;     /* cyan, = --ai-info (was 142 69% 58%) */
  --perf-good: 48 96% 53%;
  --perf-poor: 0 84% 60%;

  /* ---- genealogy node backgrounds ---------------------- */
  /* --node-final KEEPS GREEN — RULED 2026-08-26 (SS-10043 D4, operator).
     Not an oversight and no longer a deferral: it marks the CONFIRMED
     TERMINAL DERIVATION in the genealogy tree, which is a verdict, so green
     is correct here rather than borrowed. This is the half of D4 that did
     NOT move; --perf-excellent above is the half that did. */
  --node-bg: 222 47% 11%;
  --node-border: 215 27% 17%;
  --node-hover: 215 16% 25%;
  --node-selected: 270 95% 75%;
  --node-final: 142 76% 36%;         /* verdict green, D4-ruled 2026-08-26 */

  /* ---- sidebar / drawer -------------------------------- */
  /* Defined for the first time. tailwind.config.ts:65-74 has mapped eight
     classes onto these since forever; nothing defined them, so they resolved
     to nothing. Note the consumer named in the ticket
     (src/components/ui/sidebar.tsx) has no importer — the rendered sidebar is
     src/components/dashboard/Sidebar.tsx and reads none of these. Defining
     them fixes a latent bug and changes nothing on screen. */
  --sidebar-background: 220 34% 6%;
  --sidebar-foreground: 216 20% 82%;
  --sidebar-primary: 221 100% 62%;   /* A1 — tracks --primary */
  --sidebar-primary-foreground: 222 84% 10%;
  --sidebar-accent: 217 22% 14%;
  --sidebar-accent-foreground: 216 30% 96%;
  --sidebar-border: 216 14% 30%;
  --sidebar-ring: 221 100% 62%;      /* A1 — tracks --primary */

  /* ---- declared exemptions ----------------------------- */
  /* NOT new hues. AC7 holds, and here is the arithmetic:
     #f4614f converts to 7 88% 63%, which IS --destructive exactly.
     The gradient's top stop #f88676 is 7 90% 72% — the same hue, lighter.
     One red at two lightnesses, not a fifth colour.

     TOKEN-SHAPE WARNING: --destructive-fill holds a COMPLETE
     linear-gradient(), not an `H S% L%` triplet like every other token
     in this block. Consume it as `background: var(--destructive-fill)`.
     Wrapping it in hsl() the way you would any neighbour will break it. */
  --destructive-fill: linear-gradient(180deg, hsl(7 90% 72%) 0%, hsl(var(--destructive)) 100%);
  --destructive-fill-foreground: 8 79% 9%;  /* #2b0a05 */

  /* The document-surface family. A statement is a printed document that
     happens to be displayed on screen, so the white card is the correct
     metaphor, and printed documents are exempt from the dark remap
     (ADDENDUM-2026-08-25): the usage statement (usage/statement, SS-10719)
     and client briefs. Declared here so the exemption lives in the token
     layer instead of surviving as unexplained neutral escapes.
     [SS-11054] PREVIOUS: named revenue/LicenseRoyaltyStatement.tsx +
     revenue/UsageDetailSchedule.tsx (deleted with the unrouted /revenue
     page) and read "DECLARED, NOT YET APPLIED", stale since SS-10719.
     src/pages/NotFound.tsx:15 bg-gray-100 is NOT covered: that one is an
     oversight, not a document, and goes dark under SS-10030. */
  --document-surface: 0 0% 100%;            /* white */
  --document-foreground: 221 39% 11%;       /* ~#111827 */

  /* A3 2026-08-25 (operator): print-style inks for the white statement
     surfaces. Hue and saturation held from the globals; only lightness drops,
     so these are the SAME FOUR HUES at a darker value — a scoped family like
     --document-surface, not new colours. AC7 holds.

     Every ratio below was COMPUTED HERE against white, not taken on trust.
     The contrast implementation was validated against WCAG canonicals first
     (white/black = 21.000, #767676 on white = 4.542, #949494 = 3.033).

     The upstream starting values (26.8 / 32.1 / 47.9 / 57.7) are MINIMUMS
     sitting on the 4.5:1 cliff, not targets, and rounding UP fails on all
     four (27% -> 4.431, 33% -> 4.299, 48% -> 4.492, 58% -> 4.444). Integer
     FLOORS are minted, independently confirmed here and matching the
     semantics lane's table hex-for-hex.

     --document-warning is 31%, not the 32% floor. PM ruling 2026-08-25: 32%
     cleared by only +0.014, an order of magnitude thinner than its three
     siblings, and this arc has already been burned twice by cliff-edge
     values (SS-10023's 0.85 alpha, and the four round-ups above). The
     operator accepted the darkened-family APPROACH with the olive reading
     flagged for screenshot review; the specific integer is implementation.
     31% costs a darkening nobody can see and buys margin-class consistency:
     all four now clear by +0.126 to +0.289. */
  --document-success: 153 100% 26%;         /* #008549 — 4.72:1 on white (+0.218) */
  --document-warning: 42 89% 31%;           /* #956b09 — 4.79:1 on white (+0.289) */
  --document-destructive: 7 88% 47%;        /* #e1270e — 4.67:1 on white (+0.169) */
  --document-primary: 221 100% 57%;         /* #2469ff — 4.63:1 on white (+0.126) */

  /* SS-10042 AC4 (operator-ruled 2026-08-25): the document family's NEUTRAL
     tiers. SS-10019 declared the surface, the foreground and four inks, but the
     statements also use a strong tier, a muted tier, borders and subtle fills —
     roughly 80 sites with no token to land on. Wiring only surface+foreground
     would have satisfied AC4's letter while leaving the exemption 80%
     unexplained, which is the exact state the exemption exists to prevent.
     Minted as NEUTRALS; AC7's "four semantic plus neutrals" covers them.

     Every ratio below is DERIVED against the white document surface, not
     asserted, using the same implementation the inks were checked with
     (validated first on the WCAG canonicals: white/black = 21.000,
     #767676 on white = 4.542).

     The two non-text tiers land BYTE-IDENTICAL to the literals they replace
     (#e5e7eb = gray-200, #f9fafb = gray-50), and the text tiers match their
     predecessors' contrast to two decimals — so this is a faithful
     translation, not a restyle. --document-muted deliberately carries margin
     rather than sitting on the 4.5 cliff (the arc has been burned twice by
     cliff-edge values); its 4.83:1 is also exactly what gray-500 measured. */
  --document-strong: 221 20% 28%;           /* #394256 — 10.06:1 on white (was gray-700, 10.31) */
  --document-muted: 221 13% 47%;            /* #687287 —  4.83:1 on white (= gray-500's 4.83) */
  --document-border: 221 13% 91%;           /* #e5e7eb — non-text; identical to gray-200 */
  --document-subtle: 221 20% 98%;           /* #f9fafb — non-text; identical to gray-50 */
}

/* the toggle motion (pd src/index.css, its second :root block; SS-11012, ADDENDUM §25), for seg.css */
:root {
  --motion-duration-toggle: 800ms;
  --motion-ease-toggle: cubic-bezier(0.22, 1, 0.36, 1);
}

.label-mono {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
}

html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; background-color: hsl(var(--background)); }
body { background: transparent; color: hsl(var(--foreground)); }
/* SS-10020: the crown, pinned to the viewport (SPEC §7; ADDENDUM-2026-09-12 §1.3), pd src/index.css:572-597, VERBATIM. Vendored
   2026-10-23 for the docs AND the sign-in door together (the operator's tap: "Flat now, crown both later"). Safe here as in pd: no
   stacking context sits between body and the page, and neither html nor body carries an overflow that would clip it. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background-image: radial-gradient(
    125% 78% at 50% -10%,
    #1c2340 0%,
    #0c1019 50%,
    #070910 100%
  );
  background-repeat: no-repeat;
  background-size: cover;
  pointer-events: none;
}
*, ::before, ::after { border-color: var(--hairline); }
