/* Blackbird Web HQ -- design tokens (Campaign 020.0, Section 10).
   Near-black graphite layered surfaces, restrained semantic accents,
   system-ui for UI chrome, monospace for data values. Per-product accent
   tokens exist so Vector can re-theme later without touching this file's
   structure -- only the accent-vector value differs from accent-blackbird. */

/* =====================================================================
   BLACKBIRD INTELLIGENCE HQ -- WHOLE-SITE CAMPAIGN, PACK 1 (2026-09)
   TYPEFACES
   =====================================================================
   Self-hosted, latin-subset, variable-weight files (48KB + 31KB), served
   from /static/fonts with the same cache-busting the sheets use. No
   third-party request at render time. `font-display: swap` so a slow
   connection paints system text first and never blocks a draft board.
   Inter carries the UI; JetBrains Mono carries every data value, rank,
   stamp and provenance line. Both fall through to the system stacks the
   product shipped with, so a glyph outside the latin subset (a league
   name with an emoji, say) still renders. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/static/fonts/inter-latin.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: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/static/fonts/jetbrains-mono-latin.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 (graphite ramp, no pure black) ---
     BLACKBIRD VISUAL IDENTITY PACK (UX-V1) RETUNE. The ramp keeps its
     structure, its names and its ORDER -- every consumer is unchanged --
     but each step was re-cut for two reasons the owner's own review
     named: the base was not deep enough to make a lit panel read as lit,
     and the whole ramp was hue-neutral gray, which is why a page of
     cards read as "a dark admin dashboard" rather than as Blackbird.
     Every step now carries a faint violet-graphite bias (the same hue
     family as the brand accent), and the gaps BETWEEN steps are wider so
     page < card < raised < hover is visible depth instead of a guess.
     Contrast against --bb-text-primary IMPROVED at every step. */
  --bb-bg: #08090e;
  --bb-bg-elevated: #0f1219;
  --bb-surface: #13161f;
  --bb-surface-raised: #1a1e29;
  --bb-surface-hover: #212635;
  --bb-border: #282e40;
  --bb-border-subtle: #1e222e;
  --bb-border-strong: #3a4058;

  /* --- text ---
     UX-V1: secondary/tertiary were both retuned UPWARD. `#6b7284` on the
     card surface measured ~3.6:1 -- under the 4.5:1 body-text floor, and
     the single most common complaint shape in the owner's review ("gray
     on gray soup"). Both now clear 4.5:1 on every surface in the ramp
     above. Nothing got dimmer. */
  --bb-text-primary: #edeff4;
  --bb-text-secondary: #b0b7c8;
  /* Lifted once more after the contrast test in `tests/web/test_visual_
     identity_system.py` measured the first retune at 4.36:1 against
     `--bb-surface-hover` -- the row-hover band, i.e. exactly the state a
     dense board spends most of its life in. 4.88:1 now, on every surface
     in the ramp. */
  --bb-text-tertiary: #8b93a6;
  --bb-text-inverse: #0b0d11;

  /* --- brand / per-product accents --- */
  /* UX CORRECTION CAMPAIGN (approved mock): purple IS the Blackbird
     proprietary layer now. The old dominant blue moves to
     --bb-accent-data below — interaction/data, not identity. The two
     purples stay deliberately distinct: Blackbird is a deeper, more
     saturated violet; Vector keeps its lighter lavender namespace and
     --bb-proprietary keeps its muted ultraviolet for the BB// insight
     badge. Never collapse the three. */
  --bb-accent-blackbird: #8c66f2;
  --bb-accent-blackbird-bg: rgba(140, 102, 242, 0.13);
  --bb-accent-vector: #b18cf0;
  --bb-accent-vector-bg: rgba(177, 140, 240, 0.12);

  /* Electric blue: standard interaction + neutral data visualization.
     This is the OLD --bb-accent-blackbird value, demoted from identity
     to instrumentation. Charts, data readouts, informational focus. */
  --bb-accent-data: #5b9bf0;
  --bb-accent-data-bg: rgba(91, 155, 240, 0.12);
  --bb-accent-data-border: rgba(91, 155, 240, 0.35);

  /* Active product's own accent -- pages set this per product; defaults
     to Blackbird's accent so any page that forgets to opt in still gets
     a sane accent rather than an unstyled one. */
  --bb-accent: var(--bb-accent-blackbird);
  --bb-accent-bg: var(--bb-accent-blackbird-bg);

  /* --- semantic accents (muted, desaturated -- badges/deltas/stamps only) --- */
  --bb-positive: #57ab7d;
  --bb-positive-bg: rgba(87, 171, 125, 0.13);
  --bb-positive-border: rgba(87, 171, 125, 0.35);

  --bb-caution: #cf9e4e;
  --bb-caution-bg: rgba(207, 158, 78, 0.13);
  --bb-caution-border: rgba(207, 158, 78, 0.35);

  --bb-negative: #cc6b62;
  --bb-negative-bg: rgba(204, 107, 98, 0.13);
  --bb-negative-border: rgba(204, 107, 98, 0.35);

  --bb-info: #5f9fd6;
  --bb-info-bg: rgba(95, 159, 214, 0.13);
  --bb-info-border: rgba(95, 159, 214, 0.35);

  --bb-neutral: #8991a3;
  --bb-neutral-bg: rgba(137, 145, 163, 0.12);
  --bb-neutral-border: rgba(137, 145, 163, 0.3);

  /* Post-V1 Signature Visual Identity Pack, Part 3/57: Blackbird's OWN
     proprietary-insight accent -- rare, restrained ultraviolet. This is
     a DISTINCT hue/value from --bb-accent-vector above: Vector is a
     separate, locked PRODUCT with its own accent namespace, and this
     token must never collide with or substitute for it. Reserved for
     "BB// PROPRIETARY INSIGHT" callouts only -- never a generic
     link/button color. See `partials/ui.html`'s `proprietary_insight`
     macro for the one place this is meant to be used. */
  --bb-proprietary: #9d6fd6;
  --bb-proprietary-bg: rgba(157, 111, 214, 0.12);
  --bb-proprietary-border: rgba(157, 111, 214, 0.35);

  /* --- typography --- */
  /* PACK 1 (2026-09): Inter / JetBrains Mono lead; the system stacks the
     product shipped with remain as the fallback tail. */
  --bb-font-ui: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --bb-font-mono: "JetBrains Mono", ui-monospace, "Cascadia Code", "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;

  --bb-fs-micro: 0.6875rem;
  --bb-fs-sm: 0.8125rem;
  --bb-fs-base: 0.9375rem;
  --bb-fs-md: 1.0625rem;
  --bb-fs-lg: 1.3125rem;
  --bb-fs-xl: 1.75rem;
  --bb-fs-2xl: 2.25rem;

  /* --- spacing scale --- */
  --bb-space-1: 4px;
  --bb-space-2: 8px;
  --bb-space-3: 12px;
  --bb-space-4: 16px;
  --bb-space-5: 24px;
  --bb-space-6: 32px;
  --bb-space-7: 48px;

  /* --- radius / shadow / motion --- */
  --bb-radius-sm: 4px;
  --bb-radius-md: 8px;
  --bb-radius-lg: 12px;
  --bb-radius-pill: 999px;

  --bb-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
  --bb-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
  --bb-shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.55);

  --bb-transition-fast: 120ms ease;
  --bb-transition-base: 200ms ease;

  --bb-topbar-height: 56px;
  --bb-nav-width: 224px;
  --bb-drawer-width: 320px;

  /* ===================================================================
     INTELLIGENCE HQ UI/UX OVERHAUL -- CAMPAIGN PACK 1
     ===================================================================
     Everything above this line is the 020.0 ramp and is UNCHANGED: it is
     load-bearing for every existing surface. Everything below is an
     ADDITIVE naming layer -- semantic roles that point at the same ramp,
     so a component can say "section title" or "raised surface" instead of
     re-deciding a pixel size at each call site. No value above was
     retuned; no page had to change to keep looking the way it did.

     Identity: near-black graphite, covert/intelligence atmosphere,
     dense but not cluttered, premium front office. Explicitly NOT neon
     gamer UI, not generic SaaS, not military cosplay, not a crypto
     dashboard, not an ESPN clone. Restraint is the brand.
     ================================================================ */

  /* --- surface roles (aliases onto the ramp above) --- */
  --bb-surface-page: var(--bb-bg);
  --bb-surface-chrome: var(--bb-bg-elevated);
  --bb-surface-card: var(--bb-surface);
  --bb-surface-elevated: var(--bb-surface-raised);

  /* --- typography scale (roles, not sizes) --- */
  --bb-fs-display: var(--bb-fs-2xl);
  --bb-fs-page-title: var(--bb-fs-xl);
  --bb-fs-section-title: var(--bb-fs-lg);
  /* PACK 1 (2026-09): the in-page section head sits BETWEEN the page
     title and a card caption -- its own step, so a page reads as
     title > section > card > label instead of three near-equal weights. */
  --bb-fs-section-head: 1.125rem;
  --bb-fs-card-title: var(--bb-fs-md);
  --bb-fs-body: var(--bb-fs-base);
  --bb-fs-small: var(--bb-fs-sm);
  --bb-font-numeric: var(--bb-font-mono);

  --bb-fw-regular: 400;
  --bb-fw-medium: 500;
  --bb-fw-semibold: 600;
  --bb-fw-bold: 700;

  --bb-tracking-label: 0.12em;
  --bb-tracking-tight: -0.01em;
  --bb-leading-tight: 1.2;
  --bb-leading-body: 1.5;

  /* --- table density --- */
  --bb-row-pad-y: var(--bb-space-2);
  --bb-row-pad-x: var(--bb-space-3);
  --bb-row-pad-y-compact: 5px;
  --bb-row-pad-y-relaxed: var(--bb-space-3);

  /* --- layout --- */
  --bb-contextbar-height: 44px;
  /* GRAND REIMAGINATION, PHASE 1 (2026-09): 1560 -> 1720. The cap is
     NOT the fix for dead desktop space -- the page compositions in
     `hq.css` section 22 are -- but a flagship screen composed for a
     large monitor must be allowed to reach one. Binds only above ~2300px
     of viewport with both rails docked; centres when it does. */
  --bb-content-max: 1720px;
  /* GRAND REIMAGINATION, PHASE 1B (2026-09): the cap is RETIRED as the
     thing that decides the canvas. `.bb-page` now fills its column at
     every width (hq.css section 24), and the wide-desktop compositions
     in that section decide what the extra tracks are for. The token
     stays declared for the one consumer that still reads it (the
     completed War Room's centred record flow). */
  --bb-tap-min: 40px;

  /* --- focus ring (Part 19: never color alone, always a visible ring) --- */
  /* UX-V1: the ring's outer stop is the BRIGHT purple, which is what
     makes it survive on top of an already-purple active surface (the
     old ring used the base accent and vanished on `.is-active` nav). */
  --bb-focus-ring: 0 0 0 2px var(--bb-bg), 0 0 0 4px rgb(var(--bb-purple-bright-rgb));

  /* ===================================================================
     INTELLIGENCE HQ ATMOSPHERE LAYER (Visual Overhaul, approved mock)
     ===================================================================
     ADDITIVE ONLY. The graphite ramp above is untouched. These tokens
     exist so glow, gradient and texture are system decisions, not
     per-page hex values. The identity contract still holds: covert
     near-black base, blue as the dominant accent -- the mock's added
     punch comes from CONTROLLED light (soft glows, one signature
     blue->violet gradient, a faint grid texture), never from new
     saturated fills.

     `--bb-grad-signal` is the ONE brand gradient (hero rules, focal
     accents). It runs blue->violet; the violet stop is a BRAND light
     effect and deliberately distinct in role from --bb-proprietary,
     which remains reserved for the BB// insight badge alone. */

  /* --- glows (soft outer light; decorative, never a meaning carrier) ---
     Accent glow follows the brand purple; data glow keeps the electric
     blue for instrumentation surfaces. */
  /* UX-V1: these two now route through the one purple channel token
     (see the identity block below) and were opened up a stop -- the
     mock's glow read as a rumour at 0.20 on the old, lighter base. */
  --bb-glow-accent: 0 0 28px rgb(var(--bb-purple-rgb) / 0.26);
  --bb-glow-accent-strong: 0 0 40px rgb(var(--bb-purple-rgb) / 0.40);
  --bb-glow-data: 0 0 24px rgba(91, 155, 240, 0.18);
  --bb-glow-positive: 0 0 20px rgba(87, 171, 125, 0.22);
  --bb-glow-negative: 0 0 20px rgba(204, 107, 98, 0.22);
  --bb-glow-caution: 0 0 20px rgba(207, 158, 78, 0.22);
  --bb-glow-violet: 0 0 24px rgba(157, 111, 214, 0.20);

  /* --- gradients ---
     The ONE brand gradient now leads with the Blackbird purple and
     resolves into the data blue — identity first, instrumentation
     second, matching the approved mock's light direction. */
  /* UX-V1: the signal gradient now OPENS on the bright purple rather
     than the base purple, so a 2px hairline of it actually reads as
     light at 1px-2px heights; the blue tail is unchanged in role. */
  --bb-grad-signal: linear-gradient(90deg, #ac8dff 0%, #8c66f2 34%, #7d8af2 68%, #5b9bf0 100%);
  --bb-grad-hero: linear-gradient(180deg, rgb(var(--bb-purple-rgb) / 0.12) 0%, rgb(var(--bb-purple-rgb) / 0.04) 34%, transparent 72%);
  --bb-grad-panel-accent: linear-gradient(180deg, rgb(var(--bb-purple-rgb) / 0.13), transparent 62%);
  --bb-grad-topbar: linear-gradient(180deg, #161924 0%, #0d1017 100%);
  /* Balance-meter track: give-side red through neutral to receive-side
     green. A DRAWING surface only -- the certified lean/verdict words
     always sit beside it. */
  --bb-grad-balance: linear-gradient(90deg,
      rgba(204, 107, 98, 0.55) 0%, rgba(204, 107, 98, 0.18) 32%,
      rgba(137, 145, 163, 0.15) 50%,
      rgba(87, 171, 125, 0.18) 68%, rgba(87, 171, 125, 0.55) 100%);

  /* --- panel grid texture (faint blueprint lines behind hero panels) ---
     Tinted toward the brand purple so the intelligence-map texture reads
     as the proprietary layer, not generic blueprint blue. */
  --bb-texture-grid:
      linear-gradient(rgba(140, 102, 242, 0.05) 1px, transparent 1px),
      linear-gradient(90deg, rgba(140, 102, 242, 0.05) 1px, transparent 1px);
  --bb-texture-grid-size: 28px 28px;

  /* ===================================================================
     BLACKBIRD VISUAL IDENTITY PACK -- UX-V1 ("PURPLE IS THE SIGNATURE")
     ===================================================================
     ADDITIVE. Nothing above this line was renamed or removed; the only
     changes above are the ramp/text retunes annotated in place.

     WHY THIS BLOCK EXISTS. The atmosphere layer above introduced glow
     and one gradient, but every purple value in `hq.css` was written as
     a LITERAL `rgba(140, 102, 242, x)` -- eleven of them, at six
     different alphas, none of them adjustable and none of them named.
     That is a second, undocumented colour system living inside the
     first. This block is the single purple source of truth: one channel
     triple, and every tint/border/glow derived from it by name.

     THE CONTRACT THIS BLOCK KEEPS. Strongest purple is reserved for
     exactly five roles, everywhere in the product:
       1. PRIMARY ACTION        (the one verb a surface wants)
       2. CURRENT CONTEXT       (where am I / which league / whose pick)
       3. BLACKBIRD RECOMMENDATION (Blackbird's own opinion surfaces)
       4. ACTIVE SELECTION      (nav, tab, filter, row, card)
       5. SIGNATURE BRAND MOMENT (mark, rails, page identity)
     Purple is NEVER a semantic carrier: good/bad/warning stay green/
     red/amber, and the Part 19 "never colour alone" contract is
     untouched -- every rule that tints something still ships a glyph,
     a word, a rail or a border shape beside it.
     ================================================================ */

  /* --- every palette colour, ALSO as raw channels ---
     The ramp/semantic/brand values above stay the single source of
     truth; these are the SAME colours expressed as `R G B` triples so a
     rule can compose an arbitrary alpha (`rgb(var(--x-rgb) / 0.22)`)
     without a stylesheet ever writing a literal colour again. Adding a
     colour means adding it in BOTH forms, here, and nowhere else --
     `identity.css` contains zero literal colour values as a result, and
     `tests/web/test_visual_identity_system.py` pins that. */
  --bb-ink-rgb: 0 0 0;
  --bb-paper-rgb: 255 255 255;
  --bb-positive-rgb: 87 171 125;
  --bb-caution-rgb: 207 158 78;
  --bb-negative-rgb: 204 107 98;
  --bb-info-rgb: 95 159 214;
  --bb-neutral-rgb: 137 145 163;
  --bb-proprietary-rgb: 157 111 214;
  --bb-data-rgb: 91 155 240;
  /* The off-canvas sheet scrim: near-black, faintly cool. */
  --bb-scrim: rgb(4 4 8 / 0.66);

  /* --- the one purple, as channels --- */
  --bb-purple-rgb: 140 102 242;
  --bb-purple-bright-rgb: 172 141 255;
  --bb-purple-deep-rgb: 83 47 196;

  --bb-purple: rgb(var(--bb-purple-rgb));
  --bb-purple-bright: rgb(var(--bb-purple-bright-rgb));
  --bb-purple-deep: rgb(var(--bb-purple-deep-rgb));

  /* Tints, in one ordered ladder. `wash` is ambient light; `soft` is a
     filled state; `fill` is an active/selected state. */
  --bb-purple-wash: rgb(var(--bb-purple-rgb) / 0.05);
  --bb-purple-soft: rgb(var(--bb-purple-rgb) / 0.12);
  --bb-purple-fill: rgb(var(--bb-purple-rgb) / 0.20);
  --bb-purple-border: rgb(var(--bb-purple-rgb) / 0.30);
  --bb-purple-border-strong: rgb(var(--bb-purple-rgb) / 0.55);
  --bb-purple-rail: linear-gradient(180deg, rgb(var(--bb-purple-bright-rgb)), rgb(var(--bb-purple-rgb)) 55%, rgb(var(--bb-purple-deep-rgb)));

  /* --- glow ladder (decorative light; never a meaning carrier) --- */
  --bb-glow-purple-sm: 0 0 0 1px rgb(var(--bb-purple-rgb) / 0.10), 0 2px 14px rgb(var(--bb-purple-rgb) / 0.14);
  /* PACK 1 (2026-09): both mid/large blooms stepped down. Light is a
     hierarchy instrument here, and at the old alphas every lit panel
     read as equally lit -- the opposite of hierarchy. */
  --bb-glow-purple: 0 0 0 1px rgb(var(--bb-purple-rgb) / 0.12), 0 4px 24px rgb(var(--bb-purple-rgb) / 0.15);
  --bb-glow-purple-lg: 0 0 0 1px rgb(var(--bb-purple-rgb) / 0.18), 0 8px 40px rgb(var(--bb-purple-rgb) / 0.22);
  /* The CTA's own light: a tight seat shadow plus a purple bloom. */
  --bb-glow-cta: 0 1px 0 rgb(var(--bb-paper-rgb) / 0.16) inset, 0 2px 10px rgb(var(--bb-purple-deep-rgb) / 0.55), 0 0 22px rgb(var(--bb-purple-rgb) / 0.30);
  --bb-glow-cta-hover: 0 1px 0 rgb(var(--bb-paper-rgb) / 0.22) inset, 0 4px 16px rgb(var(--bb-purple-deep-rgb) / 0.62), 0 0 34px rgb(var(--bb-purple-rgb) / 0.45);

  /* --- surface elevation (depth without more borders) ---
     Each level pairs a TOP-LIT hairline (the inset white line that makes
     a dark panel read as a physical face) with an outer drop. This is
     what replaces "another 1px border" as the way a card says it is
     above the page. */
  --bb-elev-1: 0 1px 0 rgb(var(--bb-paper-rgb) / 0.030) inset, 0 1px 2px rgb(var(--bb-ink-rgb) / 0.45);
  --bb-elev-2: 0 1px 0 rgb(var(--bb-paper-rgb) / 0.045) inset, 0 4px 18px rgb(var(--bb-ink-rgb) / 0.50);
  --bb-elev-3: 0 1px 0 rgb(var(--bb-paper-rgb) / 0.060) inset, 0 12px 40px rgb(var(--bb-ink-rgb) / 0.60);

  /* --- surface faces (the subtle top-to-bottom light every panel gets) --- */
  --bb-face-card: linear-gradient(180deg, rgb(var(--bb-paper-rgb) / 0.022), rgb(var(--bb-paper-rgb) / 0) 96px);
  --bb-face-raised: linear-gradient(180deg, rgb(var(--bb-paper-rgb) / 0.035), rgb(var(--bb-paper-rgb) / 0) 120px);
  --bb-face-intel: linear-gradient(180deg, rgb(var(--bb-purple-rgb) / 0.10), rgb(var(--bb-purple-rgb) / 0.02) 40%, transparent 72%);
  --bb-face-control: linear-gradient(180deg, #232838, #1a1e29);
  --bb-face-control-hover: linear-gradient(180deg, #2b3247, #212635);

  /* --- primary action: deep purple, WHITE text ---
     The old primary button was the flat `--bb-accent` with DARK text --
     correct on contrast (5.2:1) and wrong on presence: dark-on-lavender
     is the one purple treatment that cannot look premium.

     White on purple is the look, and the contrast floor is met by
     DARKENING THE GROUND rather than by dimming the label. #8158e8 is
     the lightest stop in the rest gradient at 4.67:1 against white, and
     #8459ea the lightest in the hover gradient at 4.57:1 -- both clear
     the 4.5:1 normal-text floor, and `tests/web/test_visual_identity_
     system.py` recomputes both rather than trusting this comment.

     HOVER IS DELIBERATELY BARELY LIGHTER. Lightening a purple far
     enough to *feel* like a hover would drop white text under the
     floor, so the hover reads through LIGHT instead: a brighter border
     and a much stronger bloom (`--bb-glow-cta-hover`). */
  --bb-cta: linear-gradient(180deg, #8158e8, #6338d4 62%, #5730c4);
  --bb-cta-hover: linear-gradient(180deg, #8459ea, #6739d8 62%, #5b32c9);
  --bb-cta-text: #ffffff;
  --bb-cta-border: rgb(var(--bb-purple-bright-rgb) / 0.55);

  /* --- Blackbird geometry ---
     `wing` is the signature asymmetric rule: bright at the leading edge,
     dissolving to nothing -- the 2D reduction of the emblem's swept
     wing. It is the one recurring brand gesture: page heads, section
     titles, nav group labels, intelligence panels and board bars all
     draw it, at different scales.
     `hatch` is the classified/terminal texture for intelligence panels;
     deliberately fainter than the existing blueprint `grid`. */
  --bb-wing: linear-gradient(90deg,
      rgb(var(--bb-purple-bright-rgb)) 0%,
      rgb(var(--bb-purple-rgb)) 22%,
      rgb(var(--bb-purple-rgb) / 0.35) 52%,
      transparent 100%);
  --bb-wing-short: linear-gradient(90deg, rgb(var(--bb-purple-bright-rgb)), rgb(var(--bb-purple-rgb) / 0.15));
  --bb-texture-hatch: repeating-linear-gradient(135deg,
      rgb(var(--bb-purple-rgb) / 0.035) 0 1px,
      transparent 1px 9px);

  /* --- ambient page light (Part T) ---
     Three very low-opacity radials painted ONCE on a fixed, non-scrolling
     pseudo-element (see `identity.css`) so the app background is a lit
     room rather than a flat fill, at zero scroll cost. */
  --bb-ambient:
      radial-gradient(1100px 620px at 12% -8%, rgb(var(--bb-purple-rgb) / 0.10), transparent 62%),
      radial-gradient(900px 520px at 96% 4%, rgb(var(--bb-data-rgb) / 0.07), transparent 60%),
      radial-gradient(1200px 800px at 50% 108%, rgb(var(--bb-purple-deep-rgb) / 0.10), transparent 62%);

  /* --- focus (Part V: a ring, never a hue swap) --- */
  --bb-focus-ring-purple: 0 0 0 2px var(--bb-bg), 0 0 0 4px rgb(var(--bb-purple-bright-rgb)), 0 0 18px rgb(var(--bb-purple-rgb) / 0.55);

  /* ===================================================================
     WHOLE-SITE CAMPAIGN, PACK 2 (2026-09) -- THE BACKGROUND-MARK SEAM
     ===================================================================
     The approved Command Center mock carries an oversized, very faint
     insignia behind its hero and its intel rail. The owner does NOT
     want the mock's aircraft silhouette, and the final production logo
     is still being chosen -- so this is a SEAM, not a design: one token
     holding the LOCKED Concept #8 mark (three nested forward-swept
     blades, purple seam innermost) as a data URI, read
     by `.bb-watermark` (hq.css) and the flagship `.bb-icard--primary`
     face. Swapping the chosen logo in later is a one-line change HERE.
     Opacity is applied by the consumer and stays under 0.06: the mark
     is atmosphere behind data, never an illustration competing with it. */
  --bb-brand-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 128 112'%3E%3Cpath d='M2 44 L120 6 L30 102 L40 86 L100 18 L22 48 Z' fill='%23e7e9ee'/%3E%3Cpath d='M26 56 L96 26 L48 90 L52 78 L82 34 L40 60 Z' fill='%23e7e9ee' opacity='0.75'/%3E%3Cpath d='M44 64 L80 38 L54 76 L56 70 L74 42 L50 66 Z' fill='%23ac8dff'/%3E%3C/svg%3E");

  /* ===================================================================
     GRAND REIMAGINATION, PHASE 1B (2026-09) -- THE ENVIRONMENT LAYER
     ===================================================================
     ADDITIVE. The owner's reaction to the Phase 1 production build was
     "this still looks like the same Blackbird": purple was an accent on
     a graphite dashboard, the shell was a thin list beside a thin bar,
     and a 2560px monitor showed a 1720px column with black on either
     side. These tokens are the palette the environment layer composes
     from -- purple as LIGHT IN THE ROOM (environmental gradients, edge
     lighting, seams, slabs), never as a coat of paint on every card.
     Every value derives from the channel triples above; no new hue. */
  /* PHASE 2A (2026-09) -- THE AMBIENT RETUNE. The broad, passive purple
     (the room ambient, the shell/drawer/topbar/contextbar washes, the
     hero and lead-surface radials, the zone wash, the environmental
     glow) steps back roughly ten percent RELATIVE, so the ground reads
     graphite-first with purple as light through it. Every high-value
     purple moment -- active nav, the CTA, the ring, the tactical slab,
     the War Room -- keeps its exact value. */

  /* --- the environmental purple: large, soft, directional --- */
  --bb-env-shell: linear-gradient(180deg,
      rgb(var(--bb-purple-rgb) / 0.18) 0%,
      rgb(var(--bb-purple-rgb) / 0.07) 22%,
      rgb(var(--bb-purple-deep-rgb) / 0.035) 60%,
      rgb(var(--bb-purple-deep-rgb) / 0.09) 100%);
  --bb-env-topbar: linear-gradient(90deg,
      rgb(var(--bb-purple-rgb) / 0.27) 0%,
      rgb(var(--bb-purple-rgb) / 0.09) 26%,
      rgb(var(--bb-purple-deep-rgb) / 0.03) 55%,
      rgb(var(--bb-data-rgb) / 0.07) 100%);
  --bb-env-contextbar: linear-gradient(90deg,
      rgb(var(--bb-purple-rgb) / 0.14) 0%,
      rgb(var(--bb-purple-rgb) / 0.045) 34%,
      transparent 68%);
  --bb-env-drawer: linear-gradient(180deg,
      rgb(var(--bb-purple-rgb) / 0.14) 0%,
      rgb(var(--bb-purple-rgb) / 0.045) 30%,
      transparent 60%,
      rgb(var(--bb-purple-deep-rgb) / 0.07) 100%);
  --bb-env-hero: radial-gradient(900px 420px at 0% 0%, rgb(var(--bb-purple-rgb) / 0.38), transparent 62%),
      radial-gradient(700px 360px at 100% 100%, rgb(var(--bb-purple-deep-rgb) / 0.30), transparent 60%),
      linear-gradient(115deg, rgb(var(--bb-purple-deep-rgb) / 0.23) 0%, transparent 48%, rgb(var(--bb-data-rgb) / 0.06) 100%);
  /* The hero's diagonal light beam: a soft directional streak crossing
     the graphite, brightest at its core, dissolving both ways. */
  --bb-env-beam: linear-gradient(112deg,
      transparent 34%,
      rgb(var(--bb-purple-bright-rgb) / 0.10) 44%,
      rgb(var(--bb-paper-rgb) / 0.07) 49%,
      rgb(var(--bb-purple-bright-rgb) / 0.12) 54%,
      rgb(var(--bb-purple-rgb) / 0.04) 62%,
      transparent 72%);
  --bb-env-lead: radial-gradient(520px 260px at 0% 0%, rgb(var(--bb-purple-rgb) / 0.27), transparent 64%),
      linear-gradient(180deg, rgb(var(--bb-purple-rgb) / 0.09), transparent 55%);
  --bb-env-zone: linear-gradient(90deg, rgb(var(--bb-purple-rgb) / 0.08), rgb(var(--bb-purple-rgb) / 0.02) 40%, transparent 70%);
  --bb-env-tactical: linear-gradient(90deg, rgb(var(--bb-purple-rgb) / 0.22) 0%, rgb(var(--bb-purple-rgb) / 0.08) 38%, rgb(var(--bb-purple-deep-rgb) / 0.05) 100%);
  --bb-env-warroom: radial-gradient(1400px 700px at 8% -10%, rgb(var(--bb-purple-rgb) / 0.30), transparent 60%),
      radial-gradient(1100px 600px at 100% 100%, rgb(var(--bb-purple-deep-rgb) / 0.26), transparent 60%),
      radial-gradient(900px 500px at 50% 50%, rgb(var(--bb-purple-deep-rgb) / 0.06), transparent 70%);
  --bb-env-simulation: radial-gradient(1400px 700px at 8% -10%, rgb(var(--bb-data-rgb) / 0.16), transparent 60%),
      radial-gradient(1100px 600px at 100% 100%, rgb(var(--bb-purple-deep-rgb) / 0.20), transparent 60%);

  /* --- the stronger ambient room (replaces --bb-ambient's read) --- */
  --bb-ambient-strong:
      radial-gradient(1400px 760px at 0% -6%, rgb(var(--bb-purple-rgb) / 0.20), transparent 60%),
      radial-gradient(1000px 560px at 100% 2%, rgb(var(--bb-data-rgb) / 0.08), transparent 58%),
      radial-gradient(1600px 900px at 55% 110%, rgb(var(--bb-purple-deep-rgb) / 0.18), transparent 62%);

  /* --- seams and edge light --- */
  --bb-seam: linear-gradient(90deg, rgb(var(--bb-purple-bright-rgb) / 0.9), rgb(var(--bb-purple-rgb) / 0.5) 40%, rgb(var(--bb-purple-rgb) / 0.08) 100%);
  --bb-seam-soft: linear-gradient(90deg, rgb(var(--bb-purple-rgb) / 0.55), rgb(var(--bb-purple-rgb) / 0.10) 60%, transparent);
  --bb-seam-vertical: linear-gradient(180deg, rgb(var(--bb-purple-bright-rgb) / 0.9), rgb(var(--bb-purple-rgb) / 0.35) 50%, transparent);
  --bb-edge-light: inset 0 1px 0 rgb(var(--bb-paper-rgb) / 0.06), inset 1px 0 0 rgb(var(--bb-purple-rgb) / 0.18);
  --bb-edge-light-strong: inset 0 1px 0 rgb(var(--bb-paper-rgb) / 0.08), inset 0 0 0 1px rgb(var(--bb-purple-rgb) / 0.22);

  /* --- surface faces for the new surface roles --- */
  --bb-face-slab: linear-gradient(180deg, rgb(var(--bb-paper-rgb) / 0.035), rgb(var(--bb-paper-rgb) / 0.008) 60%, rgb(var(--bb-ink-rgb) / 0.10));
  --bb-face-instrument: linear-gradient(180deg, rgb(var(--bb-purple-rgb) / 0.14), rgb(var(--bb-purple-rgb) / 0.04) 45%, rgb(var(--bb-ink-rgb) / 0.18) 100%);
  --bb-face-inset: linear-gradient(180deg, rgb(var(--bb-ink-rgb) / 0.22), rgb(var(--bb-ink-rgb) / 0.06));
  --bb-face-nav-active: linear-gradient(90deg, rgb(var(--bb-purple-rgb) / 0.55) 0%, rgb(var(--bb-purple-rgb) / 0.28) 45%, rgb(var(--bb-purple-rgb) / 0.10) 100%);
  --bb-face-nav-flagship: linear-gradient(90deg, rgb(var(--bb-purple-rgb) / 0.07), transparent 70%);
  --bb-texture-diagonal: repeating-linear-gradient(-32deg,
      rgb(var(--bb-paper-rgb) / 0.018) 0 1px,
      transparent 1px 22px);
  --bb-texture-scan: repeating-linear-gradient(0deg,
      rgb(var(--bb-purple-rgb) / 0.04) 0 1px,
      transparent 1px 4px);

  /* --- glow ladder additions --- */
  --bb-glow-env: 0 0 0 1px rgb(var(--bb-purple-rgb) / 0.27), 0 12px 48px rgb(var(--bb-purple-deep-rgb) / 0.31), 0 0 80px rgb(var(--bb-purple-rgb) / 0.12);
  --bb-glow-nav-active: 0 0 24px rgb(var(--bb-purple-rgb) / 0.35), inset 0 0 0 1px rgb(var(--bb-purple-bright-rgb) / 0.35);
  --bb-glow-ring: drop-shadow(0 0 14px rgb(var(--bb-purple-rgb) / 0.75)) drop-shadow(0 0 32px rgb(var(--bb-purple-rgb) / 0.35));

  /* --- typography additions: hierarchy pushed harder --- */
  --bb-fs-label: 0.75rem;
  --bb-fs-display-xl: clamp(2.6rem, 3.3vw, 4.5rem);
  --bb-fs-instrument: 2.1rem;
  --bb-tracking-wide: 0.2em;

  /* --- shell proportions at the four desktop tiers ---
     1366 compact workstation / 1440 standard desktop / 1920 expanded
     command center / 2560 full HQ. The chrome grows with the canvas so
     the rails read as working columns, and the content well fills what
     is left -- there is no centred cap any more. */
  --bb-nav-width-wide: 272px;
  --bb-nav-width-hq: 300px;
  --bb-drawer-width-wide: 400px;
  --bb-drawer-width-hq: 460px;

  /* --- mobile shell (UX correction campaign) --- */
  --bb-bottomnav-height: 56px;
  --bb-safe-top: env(safe-area-inset-top, 0px);
  --bb-safe-bottom: env(safe-area-inset-bottom, 0px);
  --bb-safe-left: env(safe-area-inset-left, 0px);
  --bb-safe-right: env(safe-area-inset-right, 0px);

  /* ===================================================================
     FABLE PACK 01 (2026-09) -- THE SHARED VISUAL SYSTEM
     ===================================================================
     The first true design pass. Everything above stays declared (every
     consumer keeps resolving), but the DIRECTION changes here and the
     later sheets (`hq.css` section 36, `identity.css` section 19) read
     these tokens:

       NEUTRAL SURFACES CARRY THE PRODUCT.
       SEMANTIC COLOUR CARRIES MEANING.
       PURPLE CARRIES BLACKBIRD.

     Purple is identity, selection, active/focused state and the rare
     signature moment. It is no longer the light in the room: the
     environmental washes, seams, glows and textures the Phase 1B layer
     painted onto every chrome surface step back to graphite. The
     `--bb-env-*` / `--bb-ambient-*` tokens are retuned IN PLACE below
     (same names, far quieter values) so `identity.css` section 17 keeps
     compiling while the room goes dark.

     Corner radii tighten one step across the board (4/8/12 -> 3/6/8).
     Radii are read by hundreds of rules through the three tokens, so
     the whole product tightens without a single selector changing.
     See `docs/FABLE_VISUAL_SYSTEM.md`.
     ================================================================ */

  /* --- radius: relatively small corners, everywhere --- */
  --bb-radius-xs: 2px;
  --bb-radius-sm: 3px;
  --bb-radius-md: 6px;
  --bb-radius-lg: 8px;

  /* --- LIVE / TACTICAL: cyan, never purple, never green ---
     Green stays positive/favourable/confirmed. Cyan is "this is
     happening now" -- a live game, a live poll, a tactical readout.
     Distinct in hue from `--bb-info` (blue, informational) so the two
     never read as one. Contrast on `--bb-surface`: ~9:1. */
  --bb-live: #3fcbe3;
  --bb-live-rgb: 63 203 227;
  --bb-live-bg: rgb(var(--bb-live-rgb) / 0.12);
  --bb-live-border: rgb(var(--bb-live-rgb) / 0.38);
  --bb-live-strong: rgb(var(--bb-live-rgb) / 0.70);
  --bb-glow-live: 0 0 0 2px rgb(var(--bb-live-rgb) / 0.20), 0 0 10px rgb(var(--bb-live-rgb) / 0.55);

  /* --- ATTENTION: amber, the "look at this before it locks" tone.
     Aliased so the Lineup Radar / Next to Lock work can say
     "attention" without deciding a hue of its own. Urgent attention
     escalates to `--bb-negative`. */
  --bb-attention: var(--bb-caution);
  --bb-attention-rgb: var(--bb-caution-rgb);
  --bb-attention-bg: var(--bb-caution-bg);
  --bb-attention-border: var(--bb-caution-border);

  /* --- THREE FRESHNESS SEMANTICS, three token families ---
     DATA FRESHNESS           how old is the fact              -> `.bb-fresh`
     NEW INTELLIGENCE         Blackbird observed something new -> `.bb-newmark` (purple)
     RECOMMENDATION VALIDITY  is this call still good          -> `.bb-validity[data-state]`
     They are different questions and must never share one badge. */
  --bb-new: var(--bb-purple-bright);
  --bb-new-rgb: var(--bb-purple-bright-rgb);
  --bb-new-bg: rgb(var(--bb-purple-rgb) / 0.16);
  --bb-new-border: rgb(var(--bb-purple-rgb) / 0.45);
  --bb-validity-valid: var(--bb-text-secondary);
  --bb-validity-expiring: var(--bb-caution);
  --bb-validity-expired: var(--bb-negative);
  --bb-validity-unknown: var(--bb-text-tertiary);

  /* --- TYPOGRAPHY ROLES (font shorthand; `font: var(--bb-type-x)`) ---
     Roles, not sizes: a template says what a line IS. Inter carries
     prose; JetBrains Mono carries every number, stamp, label and code.
     Dense data stays readable: nothing in the authenticated app is
     marketing-sized -- the largest role is the live score / decision. */
  --bb-type-brand: 700 0.9375rem/1 var(--bb-font-mono);
  --bb-type-page-title: 650 1.5rem/1.15 var(--bb-font-ui);
  --bb-type-live: 700 2.25rem/1 var(--bb-font-mono);
  --bb-type-decision: 700 1.375rem/1.1 var(--bb-font-ui);
  --bb-type-section: 600 1rem/1.25 var(--bb-font-ui);
  --bb-type-card: 600 0.9375rem/1.3 var(--bb-font-ui);
  --bb-type-value: 600 1.125rem/1.1 var(--bb-font-mono);
  --bb-type-metric: 500 0.875rem/1.2 var(--bb-font-mono);
  --bb-type-body: 400 0.875rem/1.5 var(--bb-font-ui);
  --bb-type-helper: 400 0.8125rem/1.45 var(--bb-font-ui);
  --bb-type-meta: 400 0.75rem/1.4 var(--bb-font-ui);
  --bb-type-evidence: 400 0.75rem/1.4 var(--bb-font-mono);
  --bb-type-label: 600 0.6875rem/1 var(--bb-font-mono);
  --bb-type-chip: 600 0.6875rem/1 var(--bb-font-mono);
  --bb-tracking-brand: 0.12em;
  --bb-tracking-chip: 0.04em;
  /* The label step tightens (0.75 -> 0.6875) so a label never competes
     with the value it captions; the page title and section head come
     down to app scale (1.75/1.125 -> 1.5/1). */
  --bb-fs-label: 0.6875rem;
  --bb-fs-page-title: 1.5rem;
  --bb-fs-section-head: 1rem;

  /* --- CONTROL HEIGHTS (desktop density; touch floors are separate) --- */
  --bb-control-sm: 28px;
  --bb-control-md: 34px;
  --bb-control-lg: 40px;
  /* The touch floor rises to the platform floor (44). It is read only
     inside coarse-pointer / phone contexts, so desktop density is
     untouched. */
  --bb-tap-min: 44px;

  /* --- SHELL GEOMETRY (read by hq.css section 36) ---
     A compact top: 52px bar + 40px context strip = 92px of chrome on
     desktop (was 116). The rail is 232px at the reference desktop and
     never wider than 264. */
  --bb-shell-topbar: 52px;
  --bb-shell-contextbar: 40px;
  --bb-shell-lwstrip: 26px;
  --bb-rail-width: 232px;
  --bb-rail-width-wide: 248px;
  --bb-rail-width-hq: 264px;
  --bb-rail-row: 34px;
  --bb-rail-row-flagship: 38px;
  --bb-nav-width-wide: var(--bb-rail-width-wide);
  --bb-nav-width-hq: var(--bb-rail-width-hq);
  --bb-drawer-width-wide: 360px;
  --bb-drawer-width-hq: 400px;

  /* --- BREAKPOINTS (documentation tokens; a media query cannot read a
     custom property, so the numbers are restated in the sheets and
     pinned by `tests/web/test_touch_targets.py`) ---
       1200  the intel drawer becomes a sheet (tablet tier)
        900  the phone tier: rail becomes a sheet, bottom nav appears
        620  phone portrait: priority columns collapse, two-row context
       1440 / 1680 / 2300  rail and drawer widen with the canvas */
  --bb-bp-drawer: 1200px;
  --bb-bp-phone: 900px;
  --bb-bp-portrait: 620px;

  /* --- THE ROOM, DARKENED ---
     One faint purple radial at the top-left corner is the only ambient
     light left. Everything that used to be a wash on a chrome surface
     is now transparent, so the graphite ramp does the layering. */
  --bb-ambient: radial-gradient(900px 480px at 0% -10%, rgb(var(--bb-purple-rgb) / 0.07), transparent 62%);
  --bb-ambient-strong: var(--bb-ambient);
  --bb-env-shell: linear-gradient(180deg, transparent, transparent);
  --bb-env-topbar: linear-gradient(90deg, transparent, transparent);
  --bb-env-contextbar: linear-gradient(90deg, transparent, transparent);
  --bb-env-drawer: linear-gradient(180deg, transparent, transparent);
  --bb-env-hero: linear-gradient(180deg, rgb(var(--bb-purple-rgb) / 0.05), transparent 60%);
  --bb-env-beam: linear-gradient(112deg, transparent, transparent);
  --bb-env-lead: linear-gradient(180deg, rgb(var(--bb-purple-rgb) / 0.05), transparent 55%);
  --bb-env-zone: linear-gradient(90deg, transparent, transparent);
  --bb-env-tactical: linear-gradient(90deg, rgb(var(--bb-live-rgb) / 0.08), transparent 60%);
  --bb-texture-diagonal: linear-gradient(0deg, transparent, transparent);
  --bb-texture-hatch: linear-gradient(0deg, transparent, transparent);
  --bb-texture-scan: linear-gradient(0deg, transparent, transparent);
  --bb-texture-grid: linear-gradient(0deg, transparent, transparent);
  --bb-glow-env: var(--bb-elev-2);
  --bb-glow-nav-active: none;
  --bb-face-nav-active: linear-gradient(90deg, rgb(var(--bb-purple-rgb) / 0.20), rgb(var(--bb-purple-rgb) / 0.08));
  --bb-face-nav-flagship: linear-gradient(90deg, transparent, transparent);
  --bb-face-instrument: var(--bb-face-control);
  --bb-face-intel: linear-gradient(180deg, rgb(var(--bb-purple-rgb) / 0.07), transparent 48%);
  --bb-grad-topbar: linear-gradient(180deg, var(--bb-bg-elevated), var(--bb-bg-elevated));
  --bb-glow-purple-sm: none;
  --bb-glow-purple: 0 0 0 1px rgb(var(--bb-purple-rgb) / 0.18);
  --bb-glow-purple-lg: 0 0 0 1px rgb(var(--bb-purple-rgb) / 0.24), 0 6px 24px rgb(var(--bb-ink-rgb) / 0.40);
  --bb-glow-cta: 0 1px 0 rgb(var(--bb-paper-rgb) / 0.12) inset, 0 1px 2px rgb(var(--bb-ink-rgb) / 0.45);
  --bb-glow-cta-hover: 0 1px 0 rgb(var(--bb-paper-rgb) / 0.16) inset, 0 2px 8px rgb(var(--bb-purple-deep-rgb) / 0.45);
  --bb-edge-light: inset 0 1px 0 rgb(var(--bb-paper-rgb) / 0.05);
  --bb-edge-light-strong: inset 0 1px 0 rgb(var(--bb-paper-rgb) / 0.06);
  --bb-seam: linear-gradient(90deg, var(--bb-border-strong), var(--bb-border-subtle));
  --bb-seam-soft: linear-gradient(90deg, var(--bb-border), transparent);
  --bb-seam-vertical: linear-gradient(180deg, var(--bb-border-strong), transparent);
  /* The wing stays: it is the one recurring brand gesture. */
}

/* Vector product surfaces (used only on pages rendered under the Vector
   accent, e.g. /vector) swap the active accent tokens -- never define a
   second copy of the base ramp above. */
[data-bb-product="vector"] {
  --bb-accent: var(--bb-accent-vector);
  --bb-accent-bg: var(--bb-accent-vector-bg);
}
