/* =====================================================================
   BLACKBIRD INTELLIGENCE HQ -- UI/UX OVERHAUL, CAMPAIGN PACK 1
   =====================================================================
   The presentation layer for a FROZEN functional V1.

   Rules this file obeys, and that a future edit must keep obeying:

   1. NOTHING HERE COMPUTES A NUMBER. Every value a component draws was
      already produced by a certified backend view-model. CSS decides
      emphasis; it never decides meaning.
   2. NO COLOR-ONLY SIGNALS. Positive/negative/warning/edge/direction/
      trade-decision always ship a glyph or a word alongside the hue
      (Part 19). Every rule below that tints something has a sibling that
      draws a mark.
   3. NO NEW PALETTE. Every colour resolves through a token in
      `tokens.css`. This file introduces zero literal hex colours except
      the two print overrides at the bottom, which exist precisely
      because the app palette must NOT reach paper.
   4. ADDITIVE. `layout.css`/`components.css` are untouched behaviourally;
      this sheet loads last and refines. A page that opts into none of
      these classes renders exactly as it did before.
   ================================================================== */


/* =====================================================================
   0. ACCESSIBILITY FOUNDATION (Part 19)
   ================================================================== */

/* A visible focus ring on every interactive element. The app previously
   relied on the UA default, which is invisible against a graphite
   surface in several browsers. `:focus-visible` (not `:focus`) so mouse
   users never see a ring they did not ask for. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: none;
  box-shadow: var(--bb-focus-ring);
  border-radius: var(--bb-radius-sm);
}

/* Skip link -- the first tabbable thing on every shell page. */
.bb-skip-link {
  position: absolute;
  left: var(--bb-space-2);
  top: -100px;
  z-index: 100;
  padding: var(--bb-space-2) var(--bb-space-4);
  background: var(--bb-accent);
  color: var(--bb-text-inverse);
  font-weight: var(--bb-fw-semibold);
  border-radius: var(--bb-radius-md);
  transition: top var(--bb-transition-fast);
}
.bb-skip-link:focus {
  top: var(--bb-space-2);
  text-decoration: none;
}

/* Screen-reader-only text. Used wherever an icon/glyph carries meaning
   that sighted users read from position or colour. */
.bb-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}


/* =====================================================================
   1. GLOBAL SHELL -- GROUPED PRIMARY NAV (Part 4)
   =====================================================================
   The old nav was eleven undifferentiated primary links plus three
   utility links, all flat. It is now six labelled groups whose order is
   the product's own information architecture:
   HOME -> DECISIONS -> INTELLIGENCE -> TOOLS -> FIELD TERMINAL -> ACCOUNT.
   No href changed; no destination was removed. */

/* -------------------------------------------------------------------
   MOBILE NAV HEAD (DRAFT-WEEKEND CORRECTION PACK, Priority 6)
   The compact context line and the expandable pickers that replaced the
   three permanent full lists at the top of the mobile sheet. Rendered
   only inside `.bb-nav__mobile-only`, which is `display:none` above the
   phone tier -- these selectors therefore cost desktop nothing.
   ------------------------------------------------------------------- */
.bb-navctx {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--bb-space-2) var(--bb-space-3);
  min-height: var(--bb-tap-min);
  justify-content: center;
  border-bottom: 1px solid var(--bb-border);
  min-width: 0;
}
.bb-navctx__league {
  font-weight: 600;
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bb-navctx__meta {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bb-navpicker {
  border-bottom: 1px solid var(--bb-border);
}
.bb-navpicker__summary {
  display: flex;
  align-items: center;
  min-height: var(--bb-tap-min);
  padding: var(--bb-space-2) var(--bb-space-3);
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-secondary);
  cursor: pointer;
  list-style: none;
}
.bb-navpicker__summary::-webkit-details-marker {
  display: none;
}
.bb-navpicker__summary::after {
  content: "\25BE";
  margin-left: auto;
}
.bb-navpicker[open] > .bb-navpicker__summary::after {
  content: "\25B4";
}
.bb-navpicker__body {
  /* Bounded on purpose: a member with a dozen connected leagues gets a
     scrollable picker, never a sheet that grows without limit. */
  max-height: 40vh;
  overflow-y: auto;
}

/* -------------------------------------------------------------------
   COPYABLE CODE (DRAFT-WEEKEND CORRECTION PACK, Priority 7 add-on)
   The value gets its own box; the Copy control sits beside it and meets
   the same touch floor every other control in this app does. `flex-wrap`
   so a long invitation URL wraps the button below the box on a phone
   rather than overflowing the card.
   ------------------------------------------------------------------- */
.bb-copycode {
  display: flex;
  align-items: stretch;
  gap: var(--bb-space-2);
  flex-wrap: wrap;
  margin-top: var(--bb-space-2);
}
.bb-copycode__value {
  flex: 1 1 12rem;
  min-width: 0;
  min-height: var(--bb-tap-min);
  text-align: left;
  padding: var(--bb-space-2) var(--bb-space-3);
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface);
  color: var(--bb-text-primary);
  font-size: var(--bb-fs-sm);
  word-break: break-all;
  cursor: pointer;
}
.bb-copycode__value:hover {
  border-color: var(--bb-accent);
}
.bb-copycode__btn {
  flex: 0 0 auto;
  min-height: var(--bb-tap-min);
  min-width: 5.5rem;
}
.bb-copycode__btn.is-copied {
  border-color: var(--bb-positive);
  color: var(--bb-positive);
}
.bb-copycode__ack {
  flex: 0 0 auto;
  align-self: center;
  font-size: var(--bb-fs-micro);
  color: var(--bb-positive);
}

/* -------------------------------------------------------------------
   DRAFT GRADE CARD (DRAFT-WEEKEND CORRECTION PACK, P2)
   The letter is the result, so it is the only large thing here. `flex`
   with `min-width: 0` on the body so a long headline wraps instead of
   pushing the card wider than a 390px viewport; the explanation lives
   in a `<details>` and costs no vertical space until opened.
   ------------------------------------------------------------------- */
.bb-gradecard {
  display: flex;
  align-items: center;
  gap: var(--bb-space-3);
  min-width: 0;
}
.bb-gradecard__letter {
  flex: 0 0 auto;
  font-size: 2.75rem;
  line-height: 1;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--bb-accent);
}
.bb-gradecard__body {
  min-width: 0;
}
.bb-gradecard__headline {
  margin: 0;
  font-weight: 600;
}
.bb-gradecard__meta {
  margin: 2px 0 0;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}

.bb-navgroup {
  margin-bottom: var(--bb-space-4);
}
.bb-navgroup__label {
  display: block;
  padding: 0 var(--bb-space-3) var(--bb-space-1);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-navgroup__items {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* The nav item itself. Two lines: a label and (optionally) a one-phrase
   plain-English description of what the destination answers -- the
   single cheapest fix for "eleven names, no idea which one I want". */
.bb-navitem {
  display: flex;
  align-items: center;
  gap: var(--bb-space-2);
  min-height: var(--bb-tap-min);
  padding: var(--bb-space-2) var(--bb-space-3);
  border-radius: var(--bb-radius-md);
  border-left: 2px solid transparent;
  color: var(--bb-text-secondary);
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-medium);
  text-decoration: none;
  transition: background var(--bb-transition-fast), color var(--bb-transition-fast),
              border-color var(--bb-transition-fast);
}
.bb-navitem:hover {
  background: var(--bb-surface-hover);
  color: var(--bb-text-primary);
  text-decoration: none;
}
/* Current location: a filled surface, an accent rule AND an accent text
   colour, plus `aria-current="page"` in the markup. Three signals, so
   the answer to "where am I" never depends on hue alone. */
.bb-navitem.is-active {
  background: var(--bb-accent-bg);
  border-left-color: var(--bb-accent);
  color: var(--bb-accent);
  font-weight: var(--bb-fw-semibold);
}
.bb-navitem__text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.bb-navitem__label {
  line-height: var(--bb-leading-tight);
}
.bb-navitem__hint {
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-regular);
  color: var(--bb-text-tertiary);
  line-height: var(--bb-leading-tight);
}
.bb-navitem.is-active .bb-navitem__hint {
  color: var(--bb-text-secondary);
}
.bb-navitem__note {
  margin-left: auto;
  flex-shrink: 0;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  padding: 1px 6px;
  border-radius: var(--bb-radius-sm);
  background: var(--bb-neutral-bg);
  color: var(--bb-neutral);
}

/* Field Terminal is a Discord companion, not a web page. It is rendered
   as INFORMATION, never as a link that would 404. */
.bb-navnote {
  padding: var(--bb-space-2) var(--bb-space-3);
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  line-height: var(--bb-leading-body);
}
.bb-navnote strong {
  display: block;
  color: var(--bb-text-secondary);
  font-family: var(--bb-font-mono);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.05em;
  margin-bottom: 2px;
}

.bb-nav {
  padding-bottom: var(--bb-space-6);
}


/* =====================================================================
   2. GLOBAL CONTEXT BAR (Part 5)
   =====================================================================
   One persistent strip under the top bar carrying the answers to "which
   league, which format, which team, which season, is a draft live, how
   fresh is this". It reads from the EXISTING league-selection precedence
   (`pages._resolve_league_selection` / `resolve_league_aware_context`)
   and the EXISTING `active_draft` locator -- it resolves nothing of its
   own and issues no fetch of its own. */

/* A REAL LAYOUT BUG, FOUND BY REAL BROWSER MEASUREMENT.
   `layout.css` sets `.bb-main { overflow-x: hidden }`. An `overflow`
   other than `visible` makes an element a SCROLL CONTAINER, and a scroll
   container becomes the containing block for `position: sticky`
   descendants -- so the context bar was resolving `top: 56px` against
   `.bb-main` instead of the viewport, landing 80px down its own flow
   position and sitting directly on top of the page heading beneath it
   (measured in Chromium at 1440x1000: contextbar top 136, pagehead top
   134 -- the <h1> was covered on every page).

   `overflow-x: clip` clips exactly the same content but is NOT a scroll
   container, so sticky resolves against the viewport again. The wide
   data that actually needs to scroll sideways already scrolls inside
   its own `.bb-table-wrap`, and the mobile `minmax(0, 1fr)` track fix
   below stops the shell from over-widening in the first place. */
.bb-main {
  overflow-x: clip;
}

.bb-contextbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--bb-space-2) var(--bb-space-3);
  min-height: var(--bb-contextbar-height);
  padding: var(--bb-space-2) var(--bb-space-4);
  margin: calc(-1 * var(--bb-space-5)) calc(-1 * var(--bb-space-5)) var(--bb-space-5);
  background: var(--bb-bg-elevated);
  border-bottom: 1px solid var(--bb-border);
  position: sticky;
  top: var(--bb-topbar-height);
  z-index: 30;
}
.bb-contextbar__group {
  display: flex;
  align-items: center;
  gap: var(--bb-space-2);
  min-width: 0;
}
.bb-contextbar__spacer {
  flex: 1 1 auto;
}
.bb-contextbar__divider {
  width: 1px;
  align-self: stretch;
  margin: 2px 0;
  background: var(--bb-border);
}

/* A single context fact: a micro caption over its value. */
.bb-fact {
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 0;
  line-height: var(--bb-leading-tight);
}
.bb-fact__label {
  font-size: var(--bb-fs-micro);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-fact__value {
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 24ch;
}
.bb-fact__value--muted {
  color: var(--bb-text-tertiary);
  font-weight: var(--bb-fw-regular);
}

/* The league switcher/context switcher trigger inside the bar. */
.bb-ctxbtn {
  display: inline-flex;
  align-items: center;
  gap: var(--bb-space-2);
  min-height: 32px;
  padding: var(--bb-space-1) var(--bb-space-3);
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface);
  color: var(--bb-text-primary);
  font-family: var(--bb-font-ui);
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-semibold);
  cursor: pointer;
  text-align: left;
}
.bb-ctxbtn:hover {
  background: var(--bb-surface-hover);
  text-decoration: none;
}
.bb-ctxbtn--accent {
  border-color: var(--bb-accent);
  background: var(--bb-accent-bg);
  color: var(--bb-accent);
  font-family: var(--bb-font-mono);
}
.bb-ctxbtn__caret {
  color: var(--bb-text-tertiary);
  font-size: var(--bb-fs-micro);
}

/* The two sync controls (UX correction, Section 6): icon + label,
   sized like the bar's other controls. The htmx status span renders the
   per-league sync outcome inline, quietly. */
.bb-ctxsync {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
}
.bb-ctxsync svg {
  flex: none;
}
.bb-contextbar__syncstate {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-contextbar__syncstate:empty {
  display: none;
}

/* Messages V1: the topbar unread badge. The count is the signal; the
   brand purple marks it as Blackbird's own layer. */
.bb-topbar__messages {
  position: relative;
}
.bb-unread-badge {
  position: absolute;
  top: -2px;
  right: -4px;
  flex: 0 0 auto;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--bb-radius-pill);
  background: var(--bb-accent);
  color: var(--bb-text-inverse);
  font-family: var(--bb-font-mono);
  font-size: 10px;
  font-weight: var(--bb-fw-bold);
  line-height: 16px;
  text-align: center;
}
/* Draft Weekend DW-1: the same badge INSIDE a flex row (the primary
   nav's Messages item) rather than pinned to an icon's corner --
   `margin-left: auto` seats it at the row's end, where `.bb-navitem`'s
   own flex layout keeps it un-clipped at every nav width, including
   the mobile nav sheet. */
.bb-unread-badge--inline {
  position: static;
  margin-left: auto;
}

@media (max-width: 900px) {
  .bb-contextbar {
    margin: calc(-1 * var(--bb-space-3)) calc(-1 * var(--bb-space-3)) var(--bb-space-3);
    padding: var(--bb-space-2) var(--bb-space-3);
    position: static;
  }
  /* On a phone the bar keeps the identity facts and drops the decorative
     dividers -- never the freshness or the active-draft state, which are
     the two facts a draft-night user is actually here for. */
  .bb-contextbar__divider {
    display: none;
  }
  .bb-fact__value {
    max-width: 16ch;
  }
}


/* =====================================================================
   3. GLOBAL SEARCH PRESENTATION (Part 6)
   =====================================================================
   Presentation only. `blackbird_search` is untouched: same endpoint,
   same htmx trigger, same grouped PLAYERS/LEAGUES/FEATURES payload. */

.bb-search {
  position: relative;
}
.bb-search__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--bb-space-2);
  min-height: 32px;
  min-width: 200px;
  padding: var(--bb-space-1) var(--bb-space-3);
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface);
  color: var(--bb-text-tertiary);
  font-family: var(--bb-font-ui);
  font-size: var(--bb-fs-small);
  cursor: pointer;
  text-align: left;
}
.bb-search__trigger:hover {
  background: var(--bb-surface-hover);
  color: var(--bb-text-secondary);
}
.bb-search__glyph {
  color: var(--bb-text-tertiary);
}
.bb-search__kbd {
  margin-left: auto;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  padding: 1px 5px;
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-sm);
  color: var(--bb-text-tertiary);
  background: var(--bb-bg-elevated);
}
.bb-search__panel {
  position: absolute;
  top: 38px;
  right: 0;
  width: min(420px, 92vw);
  max-height: min(70vh, 560px);
  overflow-y: auto;
  padding: var(--bb-space-3);
  background: var(--bb-surface-raised);
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-lg);
  box-shadow: var(--bb-shadow-lg);
  z-index: 60;
}
.bb-search__hint {
  margin: var(--bb-space-2) 0 0;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}

/* One result row. Two lines, generous hit area, keyboard reachable. */
.bb-result {
  display: flex;
  align-items: center;
  gap: var(--bb-space-3);
  min-height: var(--bb-tap-min);
  padding: var(--bb-space-2) var(--bb-space-3);
  border-radius: var(--bb-radius-md);
  color: var(--bb-text-primary);
  text-decoration: none;
}
.bb-result:hover,
.bb-result:focus-visible {
  background: var(--bb-surface-hover);
  text-decoration: none;
}
.bb-result__text {
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 0;
}
.bb-result__label {
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-semibold);
  line-height: var(--bb-leading-tight);
}
.bb-result__sub {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  line-height: var(--bb-leading-tight);
}

@media (max-width: 900px) {
  .bb-search__trigger {
    min-width: 0;
  }
  .bb-search__trigger .bb-search__kbd,
  .bb-search__trigger .bb-search__text {
    display: none;
  }
  /* DW-3.2 WR-1K -- THE ONE FIXED MOBILE SURFACE THAT DID NOT RESERVE
     THE BOTTOM BAR.
     Global search is the phone's only path to a player who is not on the
     current board, and this panel IS that surface: below 900px the
     trigger sheds its label and its shortcut hint (above) and the panel
     goes full-bleed `fixed`.

     Its height budget subtracted only the TOP chrome. Every other fixed
     mobile surface in this app reserves the bottom too -- `.bb-main`
     pads by `--bb-bottomnav-height + --bb-safe-bottom`, and the nav and
     drawer sheets both pad by `--bb-safe-bottom` (`layout.css`). This
     one ran to the viewport floor, so its last result rows landed under
     the 56px bottom nav and, on a notched iPhone, under the home
     indicator. They were not merely covered: the panel is inside
     `.bb-topbar`'s `z-index: 60` stacking context and paints ABOVE the
     bar (z 40), so a tap in that strip hit a search result the user
     could barely see, while the primary nav underneath was unreachable
     for as long as the panel stayed open.

     Reserving both makes the panel's own `overflow-y: auto` scroller
     end where the bottom nav begins -- every result reachable, the bar
     never covered, and the same two tokens every sibling rule reads. */
  .bb-search__panel {
    position: fixed;
    top: calc(var(--bb-topbar-height) + var(--bb-space-2));
    left: var(--bb-space-2);
    right: var(--bb-space-2);
    width: auto;
    max-height: calc(
      100vh - var(--bb-topbar-height) - var(--bb-bottomnav-height) -
        var(--bb-safe-bottom) - var(--bb-space-4)
    );
    /* iOS Safari: dvh tracks the real viewport while the URL bar moves. */
    max-height: calc(
      100dvh - var(--bb-topbar-height) - var(--bb-bottomnav-height) -
        var(--bb-safe-bottom) - var(--bb-space-4)
    );
  }
}


/* =====================================================================
   4. PAGE STRUCTURE -- INTELLIGENCE HEADER / SECTION HEADER / ACTIONS
   ================================================================== */

/* UX CORRECTION: the cap only ever binds on very wide monitors (the
   main grid track is narrower than it everywhere else), and when it did
   bind it LEFT-ALIGNED the page and dumped the surplus on the right
   edge. Full width + auto margins: the workspace uses its column, and a
   bound cap centers. */
.bb-page {
  max-width: var(--bb-content-max);
  width: 100%;
  margin-inline: auto;
}

/* Intelligence Header: eyebrow, title, one-line subject, right-hand
   status rail. Replaces ~12 hand-rolled `bb-flex--between` header blocks
   that had drifted into three different spacings. */
.bb-pagehead {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--bb-space-3);
  margin-bottom: var(--bb-space-5);
  padding-bottom: var(--bb-space-3);
  border-bottom: 1px solid var(--bb-border-subtle);
}
.bb-pagehead__main {
  min-width: 0;
  flex: 1 1 320px;
}
.bb-pagehead__eyebrow {
  display: block;
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
  margin-bottom: 2px;
}
.bb-pagehead__title {
  margin: 0;
  font-size: var(--bb-fs-page-title);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: var(--bb-tracking-tight);
  line-height: var(--bb-leading-tight);
  color: var(--bb-text-primary);
}
.bb-pagehead__subject {
  margin: var(--bb-space-1) 0 0;
  font-size: var(--bb-fs-small);
  color: var(--bb-text-secondary);
  max-width: 78ch;
}
.bb-pagehead__rail {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--bb-space-2);
}

/* Section header: the one shape for "a labelled band of this page". */
.bb-sectionhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--bb-space-2);
  margin-bottom: var(--bb-space-3);
}
.bb-sectionhead__title {
  margin: 0;
  font-size: var(--bb-fs-card-title);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
  letter-spacing: var(--bb-tracking-tight);
}
.bb-sectionhead__note {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}

/* Action strip: the page's own verbs, in one predictable place. */
.bb-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--bb-space-2);
}
.bb-actions--end {
  justify-content: flex-end;
}
.bb-actions__spacer {
  flex: 1 1 auto;
}
/* Every action is at least a comfortable tap target on touch. */
.bb-actions .bb-btn {
  min-height: 34px;
}

/* Filter bar: the repeated "LABEL + pill buttons" pattern that was
   inline-styled on Rankings, Available Players and the Cheat Sheet. */
.bb-filterbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--bb-space-2);
  margin-bottom: var(--bb-space-3);
}
.bb-filterbar__label {
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}


/* =====================================================================
   5. INTELLIGENCE CARD / METRIC TILE / EVIDENCE ROW
   ================================================================== */

.bb-icard {
  background: var(--bb-surface-card);
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  padding: var(--bb-space-4);
  margin-bottom: var(--bb-space-4);
}
.bb-icard--flush {
  margin-bottom: 0;
}
.bb-icard--quiet {
  background: transparent;
  border-color: var(--bb-border-subtle);
}
.bb-icard--primary {
  position: relative;
  overflow: hidden;
  border-color: var(--bb-border-strong);
  background: var(--bb-surface-raised);
  box-shadow: var(--bb-shadow-sm);
}
/* Post-V1 Visual Fidelity Completion Pack, Part 4/58: a faint Blackbird
   mark watermark on flagship hero cards -- the SAME angular glyph as
   the shell's own mark, oversized and low-opacity, never covering
   content (it sits behind everything via z-index and the card's own
   padding keeps text clear of it in practice at normal card widths). */
.bb-icard--primary::before {
  content: "";
  position: absolute;
  top: -6%;
  right: -6%;
  width: 420px;
  height: 145px;
  z-index: 0;
  pointer-events: none;
  opacity: 0.05;
  /* UX correction campaign: the watermark is the NEW wide-wing emblem
     (same silhouette as the shell's mark), not the retired chevron. */
  background-image: var(--bb-brand-mark); /* PACK 2: the locked mark, via the one token */
  background-size: contain;
  background-repeat: no-repeat;
}
.bb-icard--primary > * {
  position: relative;
  z-index: 1;
}
.bb-icard__body {
  min-width: 0;
}
.bb-icard__foot {
  margin: var(--bb-space-3) 0 0;
  padding-top: var(--bb-space-2);
  border-top: 1px solid var(--bb-border-subtle);
  font-size: var(--bb-fs-small);
  color: var(--bb-text-secondary);
}

/* Metric grid. `bb-tile-row`'s hard 6-column grid forced the same
   inline `grid-template-columns` override onto five pages; this is that
   override, named once. */
.bb-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--bb-space-3);
}
.bb-metrics--tight {
  grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
}
.bb-metrics--wide {
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}

/* Emphasis on a tile that carries the page's headline reading. */
.bb-tile--lead {
  border-color: var(--bb-border-strong);
  background: var(--bb-surface-raised);
}
.bb-tile--lead .bb-tile__value {
  font-size: var(--bb-fs-2xl);
}
.bb-tile__foot {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}

/* Evidence row: key/value with the value right-aligned and monospaced.
   `.bb-evidence` already exists; these are the wrapping/stacking fixes a
   long reason string needed on a phone. */
.bb-evidence__value {
  min-width: 0;
  overflow-wrap: anywhere;
}
@media (max-width: 620px) {
  .bb-evidence__row {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }
  .bb-evidence__value {
    text-align: left;
  }
}

/* Disclosure for secondary evidence. One shape everywhere. */
.bb-disclosure {
  border: 1px solid var(--bb-border-subtle);
  border-radius: var(--bb-radius-md);
  background: var(--bb-bg-elevated);
  padding: var(--bb-space-2) var(--bb-space-3);
}
.bb-disclosure + .bb-disclosure {
  margin-top: var(--bb-space-2);
}
.bb-disclosure > summary {
  cursor: pointer;
  list-style: none;
  min-height: 28px;
  display: flex;
  align-items: center;
  gap: var(--bb-space-2);
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-secondary);
}
.bb-disclosure > summary::-webkit-details-marker {
  display: none;
}
.bb-disclosure > summary::before {
  content: "\25B8";
  color: var(--bb-text-tertiary);
  transition: transform var(--bb-transition-fast);
}
.bb-disclosure[open] > summary::before {
  transform: rotate(90deg);
}
.bb-disclosure[open] > summary {
  color: var(--bb-text-primary);
}
.bb-disclosure__body {
  padding-top: var(--bb-space-3);
}


/* =====================================================================
   6. IDENTITY BADGES -- RANK / POSITION / TIER / STATUS
   ================================================================== */

/* Rank badge. Monospaced and right-aligned so a column of them forms a
   readable numeric edge. */
.bb-rank {
  display: inline-flex;
  align-items: baseline;
  gap: 1px;
  font-family: var(--bb-font-numeric);
  font-weight: var(--bb-fw-bold);
  font-variant-numeric: tabular-nums;
  color: var(--bb-text-primary);
}
.bb-rank__hash {
  color: var(--bb-text-tertiary);
  font-weight: var(--bb-fw-regular);
  font-size: 0.85em;
}
.bb-rank--lead {
  font-size: var(--bb-fs-lg);
}

/* Position badge. Hue is a convenience; the LETTERS are the signal. */
.bb-pos {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  padding: 1px 6px;
  border-radius: var(--bb-radius-sm);
  border: 1px solid var(--bb-neutral-border);
  background: var(--bb-neutral-bg);
  color: var(--bb-neutral);
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.bb-pos--qb { border-color: var(--bb-info-border);     background: var(--bb-info-bg);     color: var(--bb-info); }
.bb-pos--rb { border-color: var(--bb-positive-border); background: var(--bb-positive-bg); color: var(--bb-positive); }
.bb-pos--wr { border-color: var(--bb-accent);          background: var(--bb-accent-bg);   color: var(--bb-accent); }
.bb-pos--te { border-color: var(--bb-caution-border);  background: var(--bb-caution-bg);  color: var(--bb-caution); }

/* Tier badge -- a grouping of an already-ordered board, never a score. */
.bb-tier {
  display: inline-flex;
  align-items: center;
  padding: 1px 7px;
  border-radius: var(--bb-radius-pill);
  border: 1px solid var(--bb-border-strong);
  background: var(--bb-bg-elevated);
  color: var(--bb-text-secondary);
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: 0.04em;
  white-space: nowrap;
}


/* =====================================================================
   7. DIRECTIONAL INDICATORS -- EDGE / DIRECTION / FRESHNESS (Part 19)
   =====================================================================
   Each of these pairs a glyph with a word or a number. Remove all colour
   from this stylesheet and every one of them still reads correctly. */

.bb-edge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 1px 6px;
  border-radius: var(--bb-radius-sm);
  border: 1px solid var(--bb-neutral-border);
  background: var(--bb-neutral-bg);
  color: var(--bb-neutral);
  font-family: var(--bb-font-numeric);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bb-edge--up   { border-color: var(--bb-positive-border); background: var(--bb-positive-bg); color: var(--bb-positive); }
.bb-edge--down { border-color: var(--bb-negative-border); background: var(--bb-negative-bg); color: var(--bb-negative); }
.bb-edge--flat { border-color: var(--bb-neutral-border);  background: var(--bb-neutral-bg);  color: var(--bb-neutral); }
.bb-edge--none {
  border-style: dashed;
  color: var(--bb-text-tertiary);
  background: transparent;
}

.bb-dir {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
}
.bb-dir__glyph {
  font-family: var(--bb-font-mono);
  color: var(--bb-text-tertiary);
}
.bb-dir--up .bb-dir__glyph   { color: var(--bb-positive); }
.bb-dir--down .bb-dir__glyph { color: var(--bb-negative); }

/* Freshness. ONE vocabulary across the app:
   LIVE / RECENT / STALE / NOT LIVE / UNAVAILABLE, each with a dot shape
   AND its word. Persisted injury status is NEVER "LIVE" -- it renders
   NOT LIVE, which is what it is. */
.bb-fresh {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 9px;
  border-radius: var(--bb-radius-pill);
  border: 1px solid var(--bb-border-strong);
  background: var(--bb-bg-elevated);
  color: var(--bb-text-secondary);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}
.bb-fresh::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
.bb-fresh--live      { border-color: var(--bb-positive-border); background: var(--bb-positive-bg); color: var(--bb-positive); }
.bb-fresh--recent    { border-color: var(--bb-info-border);     background: var(--bb-info-bg);     color: var(--bb-info); }
.bb-fresh--stale     { border-color: var(--bb-caution-border);  background: var(--bb-caution-bg);  color: var(--bb-caution); }
/* NOT LIVE is a HOLLOW dot: a distinct shape, not merely a distinct hue. */
.bb-fresh--notlive   { border-color: var(--bb-neutral-border);  background: var(--bb-neutral-bg);  color: var(--bb-neutral); }
.bb-fresh--notlive::before {
  background: transparent;
  border: 1.5px solid currentColor;
}
.bb-fresh--unavailable { border-color: var(--bb-negative-border); background: var(--bb-negative-bg); color: var(--bb-negative); }
.bb-fresh--unavailable::before {
  background: transparent;
  border: 1.5px dashed currentColor;
}
.bb-fresh__age {
  font-family: var(--bb-font-mono);
  font-weight: var(--bb-fw-regular);
  letter-spacing: 0;
  text-transform: none;
  opacity: 0.85;
}


/* =====================================================================
   8. STANDARDIZED EMPTY / DEGRADED / LOADING STATES (Part 20)
   =====================================================================
   ONE visual language for every honest absence. The variant sets the
   accent; the markup always carries a KIND word, a plain-English title
   and, where one exists, a real technical reason in a disclosure --
   never a raw traceback, and never a limitation quietly translated away. */

.bb-state {
  display: flex;
  gap: var(--bb-space-3);
  padding: var(--bb-space-4);
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
  color: var(--bb-text-secondary);
}
.bb-state__mark {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--bb-radius-md);
  border: 1px solid var(--bb-border-strong);
  background: var(--bb-bg-elevated);
  color: var(--bb-text-tertiary);
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-bold);
}
.bb-state__body {
  min-width: 0;
  flex: 1 1 auto;
}
.bb-state__kind {
  display: block;
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
  margin-bottom: 2px;
}
.bb-state__title {
  margin: 0 0 var(--bb-space-1);
  font-size: var(--bb-fs-card-title);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
}
.bb-state__text {
  margin: 0;
  max-width: 72ch;
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
}
.bb-state__actions {
  margin-top: var(--bb-space-3);
}

.bb-state--info    { border-color: var(--bb-info-border); }
.bb-state--info .bb-state__mark    { border-color: var(--bb-info-border); background: var(--bb-info-bg); color: var(--bb-info); }
.bb-state--caution { border-color: var(--bb-caution-border); }
.bb-state--caution .bb-state__mark { border-color: var(--bb-caution-border); background: var(--bb-caution-bg); color: var(--bb-caution); }
.bb-state--gated   { border-color: var(--bb-border-strong); background: var(--bb-surface-raised); }
.bb-state--gated .bb-state__mark   { border-color: var(--bb-accent); background: var(--bb-accent-bg); color: var(--bb-accent); }
.bb-state--error   { border-color: var(--bb-negative-border); }
.bb-state--error .bb-state__mark   { border-color: var(--bb-negative-border); background: var(--bb-negative-bg); color: var(--bb-negative); }
.bb-state--neutral { border-style: dashed; background: transparent; }

/* `.bb-empty-state` is the 020.0-era shape and is still used by a
   number of secondary surfaces (Front Office's five per-section
   absences, Scenario Lab's list states, the research pages). Rather
   than rewrite twenty templates in a presentation campaign, it is
   REALIGNED here so it reads as the same component family as
   `.bb-state`: same border treatment, same radius, same title
   typography. One visual language, two markup shapes -- and the second
   one is now a documented cleanup target, not a silent inconsistency. */
.bb-empty-state {
  border-style: solid;
  border-color: var(--bb-border-strong);
  border-radius: var(--bb-radius-lg);
  padding: var(--bb-space-4);
  background: var(--bb-surface-card);
}
.bb-empty-state__title {
  font-size: var(--bb-fs-card-title);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
  margin-bottom: var(--bb-space-1);
}

/* Loading. `.bb-skeleton` already exists for row shimmer; this is the
   inline "working" affordance for an htmx swap. */
.bb-loading {
  display: inline-flex;
  align-items: center;
  gap: var(--bb-space-2);
  font-size: var(--bb-fs-small);
  color: var(--bb-text-tertiary);
}
.bb-loading::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--bb-border-strong);
  border-top-color: var(--bb-accent);
  animation: bb-spin 700ms linear infinite;
}
@keyframes bb-spin {
  to { transform: rotate(360deg); }
}


/* =====================================================================
   9. SIGNATURE VISUAL -- BBV / MARKET / EDGE STACK (Part 3C)
   =====================================================================
   THREE DISTINCT LABELLED VALUES. They are never summed, never averaged,
   never blended into a single score, and the layout makes that structural:
   three separate bordered cells with three separate captions. */

.bb-valstack {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--bb-border);
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  overflow: hidden;
}
.bb-valstack__cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--bb-space-2) var(--bb-space-3);
  background: var(--bb-surface-card);
  min-width: 0;
}
.bb-valstack__label {
  font-size: var(--bb-fs-micro);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
  white-space: nowrap;
}
.bb-valstack__value {
  font-family: var(--bb-font-numeric);
  font-size: var(--bb-fs-md);
  font-weight: var(--bb-fw-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--bb-text-primary);
  line-height: var(--bb-leading-tight);
}
.bb-valstack__value--absent {
  color: var(--bb-text-tertiary);
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-regular);
}
.bb-valstack__sub {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* =====================================================================
   10. SIGNATURE VISUAL -- TRADE BALANCE METER (Part 3A)
   =====================================================================
   Drawn ONLY from `trade_evaluation_view`'s existing balance-meter block
   (`lean`, `confidence`, `swing_factors`, `pick_uncertainty_present`).
   The engine publishes a categorical LEAN, not a ratio -- so this meter
   draws a three-position categorical scale, never a fabricated
   percentage bar. If the backend has no meter, nothing is drawn. */

.bb-balance {
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-raised);
  padding: var(--bb-space-3);
}
.bb-balance__scale {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--bb-space-1);
  margin: var(--bb-space-2) 0;
}
.bb-balance__seg {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: var(--bb-space-2) var(--bb-space-1);
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-sm);
  background: var(--bb-bg-elevated);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
  text-align: center;
}
.bb-balance__seg::before {
  content: attr(data-glyph);
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-md);
  line-height: 1;
}
/* The active segment is filled, outlined AND carries a "◀ THIS ONE"
   marker in the markup -- three signals, never hue alone. */
.bb-balance__seg.is-active {
  border-color: var(--bb-border-strong);
  background: var(--bb-surface);
  color: var(--bb-text-primary);
  box-shadow: inset 0 0 0 1px var(--bb-border-strong);
}
.bb-balance__seg.is-active[data-lean="FAVORABLE"] {
  border-color: var(--bb-positive-border);
  background: var(--bb-positive-bg);
  color: var(--bb-positive);
}
.bb-balance__seg.is-active[data-lean="UNFAVORABLE"] {
  border-color: var(--bb-negative-border);
  background: var(--bb-negative-bg);
  color: var(--bb-negative);
}
/* NEUTRAL is the engine's real "even" vocabulary (UX correction bug
   fix); "EVEN" kept one release for safety, though nothing emits it. */
.bb-balance__seg.is-active[data-lean="NEUTRAL"],
.bb-balance__seg.is-active[data-lean="EVEN"] {
  border-color: var(--bb-info-border);
  background: var(--bb-info-bg);
  color: var(--bb-info);
}
.bb-balance__ends {
  display: flex;
  justify-content: space-between;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bb-balance__note {
  margin: var(--bb-space-2) 0 0;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  line-height: var(--bb-leading-body);
}

/* =====================================================================
   TRADE BALANCE BAR + VERDICT (Post-V1 Signature Visual Identity Pack,
   Parts 31-32)
   =====================================================================
   VISUAL PLACEMENT ONLY. The marker sits at Base Package Value's own
   give/receive split (`trade_evaluation_view`'s existing, already-
   certified `outgoing_base_package_value`/`incoming_base_package_value`
   -- never a new number) purely to draw a proportion; it is never fed
   back into the recommendation, which stays exactly the certified
   `recommendation`/`balance_meter.lean` this page already renders above.
   The raw, unbounded numbers are always printed beside it so nothing is
   hidden behind the normalization. */
.bb-tradebar {
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-raised);
  padding: var(--bb-space-4);
}
.bb-tradebar__sides {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--bb-space-3);
  margin-bottom: var(--bb-space-3);
}
.bb-tradebar__side {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.bb-tradebar__side--receive {
  text-align: right;
}
.bb-tradebar__side-label {
  font-size: var(--bb-fs-micro);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-tradebar__side-value {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-xl);
  font-weight: var(--bb-fw-bold);
  color: var(--bb-text-primary);
  white-space: nowrap;
}
.bb-tradebar__track {
  position: relative;
  height: 10px;
  border-radius: var(--bb-radius-pill);
  background: var(--bb-bg-elevated);
  border: 1px solid var(--bb-border);
}
.bb-tradebar__fill {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  border-radius: var(--bb-radius-pill);
  background: var(--bb-accent-blackbird);
  opacity: 0.35;
}
.bb-tradebar__center {
  position: absolute;
  top: -4px;
  bottom: -4px;
  left: 50%;
  width: 1px;
  background: var(--bb-border-strong);
}
.bb-tradebar__marker {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 1.1rem;
  line-height: 1;
  color: var(--bb-text-primary);
}
.bb-tradebar__marker[data-lean="FAVORABLE"] { color: var(--bb-positive); }
.bb-tradebar__marker[data-lean="UNFAVORABLE"] { color: var(--bb-negative); }
.bb-tradebar__marker[data-lean="NEUTRAL"],
.bb-tradebar__marker[data-lean="EVEN"],
.bb-tradebar__marker[data-lean="UNCERTAIN"] { color: var(--bb-info); }
.bb-tradebar__note {
  margin: var(--bb-space-3) 0 0;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  line-height: var(--bb-leading-body);
}

/* UX correction: each side's package NAMED at the bar -- identity
   labels only, straight from the composed asset views. */
.bb-tradebar-packages {
  display: flex;
  justify-content: space-between;
  gap: var(--bb-space-4);
  margin-top: var(--bb-space-2);
}
.bb-tradebar-packages__side {
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-secondary);
  min-width: 0;
}
.bb-tradebar-packages__side--receive {
  text-align: right;
}

/* --- Trade Desk composer recomposition (UX correction campaign) --- */
.bb-counterparty-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--bb-space-2) var(--bb-space-3);
}
/* display:none keeps the composer's hidden asset inputs in the form
   submission -- the collapse is purely visual. */
.bb-composer-collapsed {
  display: none;
}
.bb-composer-edit {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--bb-space-3);
  justify-content: center;
}
.bb-composer-edit[hidden] {
  display: none;
}

.bb-verdict {
  text-align: center;
  padding: var(--bb-space-4) 0 var(--bb-space-2);
}
.bb-verdict__label {
  font-size: var(--bb-fs-display);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-tight);
  color: var(--bb-text-primary);
}
.bb-verdict__label[data-tone="positive"] { color: var(--bb-positive); }
.bb-verdict__label[data-tone="negative"] { color: var(--bb-negative); }
.bb-verdict__label[data-tone="neutral"] { color: var(--bb-info); }
.bb-verdict__label[data-tone="caution"] { color: var(--bb-caution); }
.bb-verdict__lean {
  margin: var(--bb-space-2) auto 0;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-sm);
  letter-spacing: 0.04em;
  color: var(--bb-text-secondary);
}
.bb-verdict__sentence {
  margin: var(--bb-space-2) auto 0;
  max-width: 640px;
  color: var(--bb-text-secondary);
  font-size: var(--bb-fs-body);
}

/* =====================================================================
   POSITION STRENGTH RADAR (Post-V1 Visual Fidelity Completion Pack,
   Part 3) -- four REAL per-position ranks as a diamond, normalized
   purely for this shape's geometry. Rank text always printed beside it.
   ===================================================================== */
.bb-radar__ring {
  fill: none;
  stroke: var(--bb-border-subtle);
  stroke-width: 1;
}
.bb-radar__axis {
  stroke: var(--bb-border);
  stroke-width: 1;
}
.bb-radar__shape {
  fill: var(--bb-accent-bg);
  stroke: var(--bb-accent);
  stroke-width: 1.5;
  stroke-linejoin: round;
}
.bb-radar__dot {
  fill: var(--bb-accent);
}
.bb-radar__label {
  fill: var(--bb-text-tertiary);
  font-size: 10px;
  font-family: var(--bb-font-ui);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bb-radar__rank {
  fill: var(--bb-text-primary);
  font-size: 12px;
  font-family: var(--bb-font-mono);
  font-weight: var(--bb-fw-semibold);
}

/* =====================================================================
   FRANCHISE DIRECTION BAND (Post-V1 Visual Fidelity Completion Pack,
   Part 11) -- a rail across the 8 real direction states, current one
   marked. No prediction, no timeline -- a position, not a forecast.
   ===================================================================== */
.bb-dirband {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 2px;
  position: relative;
  padding-top: 14px;
}
.bb-dirband::before {
  content: "";
  position: absolute;
  top: 18px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--bb-border-strong);
}
.bb-dirband__stop {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
}
.bb-dirband__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--bb-border-strong);
  border: 2px solid var(--bb-surface-raised);
  z-index: 1;
}
.bb-dirband__label {
  font-size: var(--bb-fs-micro);
  letter-spacing: 0.03em;
  color: var(--bb-text-tertiary);
  line-height: 1.25;
}
.bb-dirband__stop.is-current .bb-dirband__dot {
  background: var(--bb-accent);
  box-shadow: 0 0 0 4px var(--bb-accent-bg);
  width: 12px;
  height: 12px;
}
.bb-dirband__stop.is-current .bb-dirband__label {
  color: var(--bb-text-primary);
  font-weight: var(--bb-fw-semibold);
}
/* UX correction: eight labelled columns were still forced onto tablet
   widths (621-900px measured as the overflow band); the 4-across wrap
   the phone tier already used starts at the tablet tier instead. */
@media (max-width: 900px) {
  .bb-dirband {
    grid-template-columns: repeat(4, 1fr);
    row-gap: var(--bb-space-3);
  }
  .bb-dirband::before {
    display: none;
  }
}

/* =====================================================================
   DOSSIER LIST (Post-V1 Visual Fidelity Completion Pack, Part 13) --
   Archives' date-rail row layout, reusable anywhere a chronological log
   beats a stack of identical cards.
   ===================================================================== */
.bb-dossier {
  display: flex;
  flex-direction: column;
}
.bb-dossier__row {
  display: grid;
  grid-template-columns: 132px 1fr;
  gap: var(--bb-space-4);
  padding: var(--bb-space-3) 0;
  border-bottom: 1px solid var(--bb-border-subtle);
}
.bb-dossier__row:first-child {
  padding-top: 0;
}
.bb-dossier__date {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 2px;
}
.bb-dossier__date-main {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-secondary);
}
.bb-dossier__date-age {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.bb-dossier__summary {
  margin: var(--bb-space-2) 0 var(--bb-space-2);
  color: var(--bb-text-primary);
}
@media (max-width: 700px) {
  .bb-dossier__row {
    grid-template-columns: 1fr;
    gap: var(--bb-space-1);
  }
  .bb-dossier__date {
    flex-direction: row;
    gap: var(--bb-space-2);
  }
}

/* CANONICAL vs ROSTER-FIT separation (Part 13). This is the single most
   important structural rule on the Trade Desk: what a package is worth
   and what it does to YOUR roster are different questions with different
   answers, and the layout must never let them blur. Canonical readings
   sit in a solid-bordered band; roster-fit readings sit in a visually
   DEMOTED, dashed, indented band that says what it is. */
.bb-canon {
  border: 1px solid var(--bb-border-strong);
  border-left: 3px solid var(--bb-accent);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-raised);
  padding: var(--bb-space-4);
}
.bb-fit {
  border: 1px dashed var(--bb-border-strong);
  border-radius: var(--bb-radius-md);
  background: transparent;
  padding: var(--bb-space-4);
}
.bb-boundary {
  display: flex;
  align-items: center;
  gap: var(--bb-space-3);
  margin: var(--bb-space-4) 0 var(--bb-space-3);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-boundary::before,
.bb-boundary::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--bb-border);
}


/* =====================================================================
   11. SIGNATURE VISUAL -- POSITION STRENGTH MATRIX (Part 3D)
   =====================================================================
   QB/RB/WR/TE, each showing the LEAGUE-RELATIVE band, the need/surplus
   classification and the starter-vs-depth split -- every one of them a
   field `team_intelligence` already publishes per position. The bar is a
   rendering of `league_rank of league_team_count`; it invents nothing. */

.bb-matrix {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--bb-space-3);
}
.bb-matrix__cell {
  display: flex;
  flex-direction: column;
  gap: var(--bb-space-2);
  padding: var(--bb-space-3);
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
}
.bb-matrix__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bb-space-2);
}
.bb-matrix__rank {
  font-family: var(--bb-font-numeric);
  font-size: var(--bb-fs-md);
  font-weight: var(--bb-fw-bold);
  font-variant-numeric: tabular-nums;
  color: var(--bb-text-primary);
}
.bb-matrix__rank small {
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-regular);
  color: var(--bb-text-tertiary);
}
/* League-relative band. The FILL is proportional to the published rank;
   the number beside it is the same rank in words, so the bar is never
   the only way to read it. */
.bb-band {
  height: 6px;
  border-radius: var(--bb-radius-pill);
  background: var(--bb-bg-elevated);
  border: 1px solid var(--bb-border);
  overflow: hidden;
}
.bb-band__fill {
  height: 100%;
  background: var(--bb-neutral);
  opacity: 0.85;
}
.bb-band__fill--strong { background: var(--bb-positive); }
.bb-band__fill--middle { background: var(--bb-info); }
.bb-band__fill--weak   { background: var(--bb-caution); }
.bb-band__fill--none   { background: var(--bb-border-strong); }

.bb-matrix__split {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--bb-space-2);
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-matrix__split b {
  font-family: var(--bb-font-numeric);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-secondary);
}


/* =====================================================================
   12. SIGNATURE VISUAL -- LEAGUE LANDSCAPE (Part 3E)
   =====================================================================
   Every team's published strength rank, direction and positional needs,
   side by side. DELIBERATELY NOT a composite "league power rating":
   Blackbird does not compute one, and this campaign does not invent one.
   The bar is the same rank the table publishes, drawn. */

.bb-landscape {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
/* PRE-MERGE CORRECTION PACK, P2 -- five cells, five columns. The
   direction badge (Fringe Contender ...) and the strength rank (Strength
   #12) each get an auto-sized column of their own, so neither can ever
   be laid over the other: the old four-column template had no cell for
   the badge at all and let it overflow into the strength text. */
.bb-landscape__row {
  display: grid;
  grid-template-columns: minmax(120px, 1.4fr) auto auto minmax(90px, 1fr) minmax(120px, 1.2fr);
  align-items: center;
  gap: var(--bb-space-3);
  padding: var(--bb-space-2) var(--bb-space-3);
  border-radius: var(--bb-radius-sm);
  border: 1px solid transparent;
  font-size: var(--bb-fs-small);
}
.bb-landscape__row:hover {
  background: var(--bb-surface-hover);
}
/* The user's own team is marked with an accent rule AND a "YOU" badge in
   the markup. It is never moved: the order stays the canonical order. */
.bb-landscape__row.is-you {
  background: var(--bb-accent-bg);
  border-color: var(--bb-accent);
}
.bb-landscape__team {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--bb-space-2);
}
.bb-landscape__team a {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bb-landscape__direction {
  display: flex;
  align-items: center;
  min-width: 0;
}
.bb-landscape__direction .bb-badge {
  white-space: nowrap;
}
.bb-landscape__strength {
  font-size: var(--bb-fs-micro);
  white-space: nowrap;
}
.bb-landscape__needs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  justify-content: flex-end;
}
@media (max-width: 760px) {
  /* Phone: team name on its own line, then direction | strength on one
     line, then the band and the needs full-width -- nothing shares a
     cell, nothing can collide. */
  .bb-landscape__row {
    grid-template-columns: auto 1fr;
    row-gap: var(--bb-space-1);
  }
  .bb-landscape__team,
  .bb-landscape__row > .bb-band,
  .bb-landscape__needs {
    grid-column: 1 / -1;
  }
  .bb-landscape__strength {
    justify-self: end;
  }
  .bb-landscape__needs {
    justify-content: flex-start;
  }
}

/* PRE-MERGE CORRECTION PACK, P2 -- TEAM ROSTER IN LINEUP ORDER. One
   card, several groups (Starters / Bench / Injured Reserve / Taxi Squad
   / Draft Picks), each with its own small heading; the group tables are
   the same scan table the flat roster used. */
.bb-roster-group {
  margin-top: var(--bb-space-2);
}
.bb-roster-group:first-of-type {
  margin-top: 0;
}
.bb-roster-group__head {
  margin-bottom: var(--bb-space-2);
}
.bb-roster-group__head .bb-sectionhead__title {
  font-size: var(--bb-fs-md);
}
/* The Schedule & Byes deep link: a status chip that is a REAL link, and
   the explicit action beneath the rows -- both point at League
   Intelligence's own schedule block. */
.bb-ti-schedule-link {
  text-decoration: none;
  cursor: pointer;
}
a.bb-badge.bb-ti-schedule-link:hover,
a.bb-badge.bb-ti-schedule-link:focus-visible {
  text-decoration: underline;
}

/* PRE-MERGE CORRECTION PACK, P2 -- a big metric value that IS the link.
   Team Intelligence's Record tile and Power Rank hero deep-link into
   League Intelligence's standings / landscape. The value keeps its own
   colour and weight; the underline appears on hover/focus so the number
   still reads as a number first. */
.bb-tile__link,
.bb-herostat__link {
  color: inherit;
  text-decoration: none;
  text-decoration-color: var(--bb-accent);
  text-underline-offset: 0.18em;
  border-radius: var(--bb-radius-sm);
}
.bb-tile__link:hover,
.bb-tile__link:focus-visible,
.bb-herostat__link:hover,
.bb-herostat__link:focus-visible {
  text-decoration: underline;
  color: var(--bb-accent);
}
.bb-tile__link::after,
.bb-herostat__link::after {
  content: " \2197";
  font-size: 0.55em;
  vertical-align: super;
  color: var(--bb-text-tertiary);
}


/* =====================================================================
   13. PLAYER CARD SYSTEM -- ONE CARD, THREE DENSITIES (Part 17)
   =====================================================================
   COMPACT  : identity + rank + value + edge
   STANDARD : + position rank, tier, role, bye, status
   FEATURED : the player page / trade result hero
   These are DENSITIES OF ONE CARD, not three cards. The macro is
   `partials/player_card.html`; these classes only change how much of it
   is on screen at each size. */

.bb-pcard {
  display: flex;
  flex-direction: column;
  gap: var(--bb-space-3);
  padding: var(--bb-space-3);
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
}
.bb-pcard--compact {
  gap: var(--bb-space-2);
  padding: var(--bb-space-2) var(--bb-space-3);
}
.bb-pcard--featured {
  padding: var(--bb-space-4);
  border-color: var(--bb-border-strong);
  background: var(--bb-surface-raised);
  box-shadow: var(--bb-shadow-sm);
}
.bb-pcard__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--bb-space-3);
  flex-wrap: wrap;
}
.bb-pcard__identity {
  min-width: 0;
}
.bb-pcard__name {
  display: block;
  font-size: var(--bb-fs-card-title);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
  line-height: var(--bb-leading-tight);
}
.bb-pcard--featured .bb-pcard__name {
  font-size: var(--bb-fs-lg);
}
a.bb-pcard__name:hover {
  color: var(--bb-accent);
}
.bb-pcard__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--bb-space-2);
  margin-top: 3px;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-pcard__marks {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 5px;
}


/* =====================================================================
   14. DATA TABLE SHELL (Parts 9/15/16/18)
   =====================================================================
   `.bb-table` stays exactly as it is -- it is load-bearing for every
   certified board. These are refinements layered on top of it. */

/* Numeric columns share one alignment and one tabular figure set, so a
   column of ranks forms a straight edge instead of a ragged one. */
.bb-table .bb-num,
.bb-table .bb-pos-rank {
  font-variant-numeric: tabular-nums;
}

/* Player identity is the scan anchor of every board: it gets weight,
   full text colour and a hover affordance. Everything else in the row is
   reference. */
.bb-table .bb-cell-player {
  font-weight: var(--bb-fw-medium);
  color: var(--bb-text-primary);
}
.bb-table .bb-cell-player a {
  color: var(--bb-text-primary);
  font-weight: var(--bb-fw-semibold);
}
.bb-table .bb-cell-player a:hover {
  color: var(--bb-accent);
  text-decoration: none;
}
.bb-table .bb-cell-ref {
  color: var(--bb-text-secondary);
}

/* Zebra-free, rule-light density with a readable hover band. A dense
   board is easier to scan with one strong hover than with permanent
   stripes competing with the tier bands. */
.bb-table--scan tbody tr:hover > td {
  background: var(--bb-surface-hover);
}
.bb-table--dense tbody td {
  padding-top: var(--bb-row-pad-y-compact);
  padding-bottom: var(--bb-row-pad-y-compact);
}

/* Sticky header contrast: the header must stay readable over scrolled
   rows, which the transparent-ish elevated surface did not guarantee. */
.bb-table thead th {
  box-shadow: inset 0 -1px 0 var(--bb-border-strong);
  z-index: 2;
}

/* A drafted row on the cheat sheet: struck through AND labelled DRAFTED
   in the markup. */
.bb-table tbody tr.bb-row--drafted > td {
  opacity: 0.45;
}
.bb-table tbody tr.bb-row--drafted .bb-cell-player {
  text-decoration: line-through;
}

/* Table caption / footnote shared shape. */
.bb-tablenote {
  margin: var(--bb-space-2) 0 0;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  line-height: var(--bb-leading-body);
}


/* =====================================================================
   15. DRAFT ROOM LAYOUT (Part 10)
   =====================================================================
   Board on the primary-left, the certified recommendation on the
   primary-right, the user's own queue secondary below. The legacy
   SHADOW diagnostic stays exactly as demoted -- collapsed, labelled,
   and OUTSIDE this grid so it can never read as a peer panel. */

.bb-room {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(320px, 0.9fr);
  gap: var(--bb-space-4);
  align-items: start;
}
.bb-room__board,
.bb-room__rec {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--bb-space-4);
}
/* SOURCE ORDER IS RECOMMENDATION-FIRST ON PURPOSE. On a phone the call
   must be the first thing under the header -- a drafter with 30 seconds
   on the clock needs the answer before the board. On desktop `order`
   swaps them so the board takes the primary-left column and the
   recommendation the primary-right, per Part 10, without the markup
   having to choose the worse mobile order. */
@media (min-width: 1081px) {
  .bb-room__board { order: 1; }
  .bb-room__rec { order: 2; }
}
@media (max-width: 1080px) {
  .bb-room {
    grid-template-columns: 1fr;
  }
}

/* The recommendation call itself -- the largest single element on the
   page when one exists. */
.bb-call {
  display: flex;
  align-items: center;
  gap: var(--bb-space-3);
  padding: var(--bb-space-3) var(--bb-space-4);
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-md);
  background: var(--bb-bg-elevated);
}
.bb-call--go   { border-color: var(--bb-positive-border); background: var(--bb-positive-bg); }
.bb-call--wait { border-color: var(--bb-caution-border);  background: var(--bb-caution-bg); }
.bb-call__word {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-xl);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.04em;
  line-height: 1;
  color: var(--bb-text-primary);
}
.bb-call--go .bb-call__word   { color: var(--bb-positive); }
.bb-call--wait .bb-call__word { color: var(--bb-caution); }
.bb-call__subject {
  min-width: 0;
}

/* The legacy diagnostic wrapper. Deliberately the quietest container in
   this stylesheet. */
.bb-legacy {
  border: 1px dashed var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: transparent;
  padding: var(--bb-space-2) var(--bb-space-3);
  margin-top: var(--bb-space-5);
  opacity: 0.85;
}
.bb-legacy > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--bb-space-2);
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-legacy > summary::-webkit-details-marker { display: none; }


/* =====================================================================
   16. MY BLACKBIRD -- LEAGUE CARDS (Part 7)
   ================================================================== */

.bb-leaguegrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: var(--bb-space-4);
}
@media (max-width: 900px) {
  .bb-leaguegrid {
    grid-template-columns: 1fr;
  }
}
/* POST-DEPLOY CORRECTION PACK, Defect 3: the selected league is
   `mb.cards[0]` (`my_blackbird.service.build_my_blackbird` sorts it
   first -- never a template-side reorder), so it renders in the SAME
   uniform grid, the SAME card footprint, as every other league --
   `--featured` is a subtle indicator only (accent border, no size or
   grid-span change). It previously spanned the full grid width
   (`grid-column: 1 / -1`) and used larger fonts; both are removed here
   -- a giant strip between grid rows was the reported defect, not the
   accent border itself. */
.bb-leaguecard--featured {
  border-left: 3px solid var(--bb-accent);
  background: var(--bb-surface-raised);
}
.bb-leaguecard__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--bb-space-3);
  flex-wrap: wrap;
  margin-bottom: var(--bb-space-3);
}
.bb-leaguecard__name {
  margin: 0;
  font-size: var(--bb-fs-card-title);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
  line-height: var(--bb-leading-tight);
}
.bb-leaguecard__sub {
  margin-top: 2px;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-leaguecard__need {
  margin-top: var(--bb-space-3);
  padding: var(--bb-space-2) var(--bb-space-3);
  border-left: 2px solid var(--bb-caution-border);
  background: var(--bb-bg-elevated);
  border-radius: 0 var(--bb-radius-sm) var(--bb-radius-sm) 0;
  font-size: var(--bb-fs-small);
}

.bb-welcome {
  margin-bottom: var(--bb-space-5);
}
.bb-welcome__title {
  margin: 0 0 var(--bb-space-1);
  font-size: var(--bb-fs-display);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: var(--bb-tracking-tight);
  line-height: var(--bb-leading-tight);
  color: var(--bb-text-primary);
}
.bb-welcome__sub {
  margin: 0;
  color: var(--bb-text-secondary);
  max-width: 80ch;
}


/* =====================================================================
   16b. UTILITIES THAT REPLACE REPEATED INLINE STYLE (Part 24)
   =====================================================================
   These exist because the SAME literal `style="..."` string appeared
   dozens of times across the template tree -- `margin:0` 121 times,
   the micro font size 80 times, `gap:0` 22 times, the "quiet footnote
   under a card" rule 20 times. Those are genuinely repeated patterns,
   not one-offs, and every one of them was a place a future edit could
   drift.

   Deliberately NOT a utility framework. One-off positioning, one-off
   widths and one-off grid overrides stay inline where they are honest
   about being one-offs. */
.bb-m0 { margin: 0; }
.bb-mb-2 { margin-bottom: var(--bb-space-2); }
.bb-mb-3 { margin-bottom: var(--bb-space-3); }
.bb-mt-2 { margin-top: var(--bb-space-2); }
.bb-mt-3 { margin-top: var(--bb-space-3); }
.bb-t-micro { font-size: var(--bb-fs-micro); }
.bb-t-sm { font-size: var(--bb-fs-small); }
.bb-gap-0 { gap: 0; }
.bb-strong { font-weight: var(--bb-fw-semibold); color: var(--bb-text-primary); }
.bb-list { margin: 0; padding-left: 1.2em; }
.bb-list li { margin-bottom: 4px; }
/* The "quiet explanatory sentence under a card" pattern. */
.bb-note {
  margin: var(--bb-space-2) 0 0;
  font-size: var(--bb-fs-small);
  color: var(--bb-text-secondary);
  line-height: var(--bb-leading-body);
}


/* =====================================================================
   17. RESPONSIVE (Part 18)
   =====================================================================
   Not "shrink the desktop". Each breakpoint decides which fields still
   earn their place; the rest move into a disclosure that is present in
   the DOM at every size. A CRITICAL DECISION IS NEVER HIDDEN. */

/* =====================================================================
   PACK 2 ADDITIONS
   =====================================================================
   Everything above this line is Pack 1 and is unchanged except where a
   breakpoint was explicitly retuned (Part 10/16, each annotated in
   place). Everything below is new, and every rule here exists to serve
   a specific Pack 2 finding -- there is no speculative styling. */

/* The two-track card, as a CLASS rather than the inline `style="grid-
   column: span 2"` Command Center used to carry -- declared BEFORE the
   breakpoints below so the single-column collapse rule can override it
   (same specificity, later wins). */
.bb-card--wide {
  grid-column: span 2;
}

/* FRESHNESS WITH A SUBJECT (Part 14) -- "Board · Recent", "Rosters ·
   Stale". The subject is a quiet caption; the pill keeps its own
   colour, glyphless five-word vocabulary and tooltip. */
.bb-freshgroup {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.bb-freshgroup__subject {
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}

/* ONE SIDE OF AN EXCHANGE (Part 5 / Part 20).
   `bb-trade-side` was referenced by SIX templates -- the Trade Builder,
   the Scenario Lab composer and its three sibling composers, and the
   scenario detail page -- and DEFINED BY NONE of them: it resolved to
   nothing in every stylesheet. Rather than strip a class six authors
   independently reached for, it now carries the behaviour they clearly
   meant: a grid child that will not blow its track out, with its own
   content column. */
.bb-trade-side {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--bb-space-2);
}

/* THE HYPOTHETICAL STAMP (Part 5).
   Scenario Lab's whole safety story is "this changes nothing real".
   Pack 1 solved the same class of confusion on the Trade Desk with
   `.bb-canon` (a canonical reading) versus `.bb-fit` (context applied
   to it); a scenario reuses that exact pair, and this stamp is the word
   that rides on the hypothetical half so the distinction is never
   carried by the border alone. */
.bb-hypo-stamp {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 10px;
  border: 1px dashed var(--bb-border-strong);
  border-radius: var(--bb-radius-pill);
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
  background: transparent;
}

/* A scannable list row that is a LINK -- the shape Command Center,
   Front Office and Research Terminal had each re-implemented as an
   inline `style="text-decoration:none;color:inherit;..."` on an `<a>`,
   in four slightly different paddings. */
.bb-listrow {
  display: flex;
  align-items: baseline;
  gap: var(--bb-space-2);
  flex-wrap: wrap;
  padding: var(--bb-space-2) 0;
  border-bottom: 1px solid var(--bb-border-subtle);
  color: inherit;
  text-decoration: none;
}
.bb-listrow:last-child {
  border-bottom: none;
}
a.bb-listrow:hover {
  text-decoration: none;
  background: var(--bb-surface-hover);
}
.bb-listrow__main {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--bb-text-primary);
}
.bb-listrow__sub {
  flex-basis: 100%;
  margin: 2px 0 0;
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-secondary);
}
.bb-listrow__end {
  flex: 0 0 auto;
  margin-left: auto;
  white-space: nowrap;
}

/* Tablet: metric grids and matrices reflow before tables do. */
@media (max-width: 1024px) {
  .bb-metrics {
    grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  }
}

@media (max-width: 900px) {
  /* THE HORIZONTAL-OVERFLOW FIX, and the single most important rule in
     this section.

     `layout.css` collapses the shell to `grid-template-columns: 1fr` on
     mobile. `1fr` is `minmax(auto, 1fr)`, and that `auto` minimum is the
     MIN-CONTENT width of the widest item in the track -- so the top
     bar's own controls were sizing the whole shell, the main column
     inherited that width, and every page then ran off the right edge of
     a 390px viewport (confirmed in real Chromium at 390x844: the page
     header's subject line, the Team Intelligence metric tiles and the
     Rankings action strip were all clipped by `body { overflow-x:
     hidden }`).

     `minmax(0, 1fr)` caps the track at the viewport. Tables keep their
     own `overflow-x: auto` scroller, so wide data still scrolls INSIDE
     its container -- which is the behaviour Part 18 asks for -- while
     the page body itself never scrolls sideways. */
  .bb-shell,
  .bb-shell--drawer-collapsed,
  .bb-shell--nav-collapsed {
    grid-template-columns: minmax(0, 1fr);
  }
  .bb-topbar,
  .bb-topbar__left,
  .bb-topbar__right,
  .bb-main {
    min-width: 0;
  }

  .bb-pagehead {
    margin-bottom: var(--bb-space-4);
  }
  .bb-pagehead__title {
    font-size: var(--bb-fs-lg);
  }
  .bb-welcome__title {
    font-size: var(--bb-fs-xl);
  }
  /* THE TAP-TARGET RULES THAT USED TO LIVE HERE MOVED ONE BLOCK DOWN.
     UX correction sized buttons and class-carrying inline links for a
     finger at this breakpoint; PACK 2 PART 16 added the links the bare-
     `a` rule in `layout.css` could not reach. Both were correct and both
     are intact -- DW-3.2 Phase 1F only WIDENED the condition they fire
     under (a coarse pointer at any width, not only a narrow viewport),
     which meant they had to leave a width-only query. See section 17C
     immediately below; they are re-stated there verbatim, in the same
     cascade neighbourhood, so nothing downstream of this block changed
     which rule it wins against. */

  /* A card that spans two grid tracks on desktop must not create an
     IMPLICIT second track once the grid has collapsed to one column --
     which is exactly what `grid-column: span 2` does, and exactly the
     390px horizontal overflow measured on Command Center's Market
     Movement card before this rule existed. */
  .bb-card--wide {
    grid-column: auto;
  }
}


/* =====================================================================
   17C. TOUCH TARGET FLOOR -- SHELL, BOARD AND UTILITY CONTROLS
   =====================================================================
   DW-3.2 Phase 1F. The companion to `components.css`'s primitives
   section, which carries the full rationale; the short version is that
   an authenticated production audit measured twelve interactive
   surfaces under the ~40px a finger needs, and that the fix is a HIT
   AREA change only -- no glyph, label, colour, border or font-size
   moves.

   THE CONDITION, AND WHY IT IS A UNION. `(max-width: 900px)` is this
   codebase's phone tier and stays authoritative for layout. But the
   tablet tier `layout.css` opened at 1200px turns the evidence drawer
   into an off-canvas SHEET while leaving its toggle and close button
   sized at 29px -- a finger-driven control that a width-only query
   never reached. `(pointer: coarse)` closes that gap at any width and
   matches no mouse-driven desktop, which is what protects the density
   of every board below 1201px on a real desktop.

   WHY THESE RULES SIT HERE AND NOT AT THE END OF THE FILE. Placing them
   immediately after the 900px block keeps their cascade position: a
   later home would have let `.bb-btn { min-height: 40px }` overrun
   `.bb-btn--lg { min-height: 44px }` (line ~2697) and SHRINK the learn
   layer's call to action on a phone. Order is load-bearing; do not
   move this section without re-checking the two `min-height` rules
   that follow it. */
@media (pointer: coarse), (max-width: 900px) {
  /* Every button that is a real action gets a real tap target. The
     token's own 40px minimum -- `--bb-tap-min` existed since 020.0 and
     buttons never read it.

     The three descendant selectors are not decoration: `.bb-actions
     .bb-btn` pinned the page's own verbs at 34px with specificity
     (0,2,0), which BEAT the bare `.bb-btn` floor, so the action strip
     -- the one place a surface puts its primary verb -- was the least
     tappable strip on the page. Filter/board bars carry the same shape
     and the same trap. */
  .bb-btn,
  .bb-actions .bb-btn,
  .bb-filterbar .bb-btn,
  .bb-boardbar .bb-btn {
    min-height: var(--bb-tap-min);
  }
  /* Square controls: the nav toggle, the drawer toggle and the evidence
     drawer's own close button are all `.bb-btn--icon`, and a one-glyph
     button is as narrow as its glyph without this. */
  .bb-btn--icon {
    min-width: var(--bb-tap-min);
  }
  .bb-btn--sm {
    padding: 6px 10px;
  }

  /* Header/context-bar controls and disclosure summaries: each was
     sized by its text plus a couple of pixels (32 / 32 / 32 / 28). */
  .bb-ctxbtn,
  .bb-ctxsync,
  .bb-search__trigger,
  .bb-listrow,
  .bb-disclosure > summary,
  .bb-legacy > summary {
    min-height: var(--bb-tap-min);
  }

  /* PACK 2, PART 16 -- THE TAP TARGETS THE BARE-`a` RULE COULD NOT
     REACH. `layout.css` gives every plain inline link `padding-block:
     4px` on mobile, but that is a TAG selector: any link that also
     carries a class (`.bb-chip`, `.bb-subtle.bb-t-micro`) outranks it
     and kept its tight text line-box. Measured in real Chromium at
     390px, that left the cross-surface links -- "Front Office", "Full
     picture", "Trade Builder", "Available RBs" -- and the league/context
     mismatch chip at 23px tall.

     Phase 1F changes the CONDITION, not the list. The audit re-measured
     these same links at 15-24px because it ran on a touch device WIDER
     than 900px, where none of this fired. The list is deliberately left
     as it shipped: `display: inline-flex` makes a link an atomic inline
     that cannot wrap mid-phrase, which is safe on a label or a badge and
     is exactly how a long link in PROSE (a card footnote, a table
     caption) would push a 320px phone into horizontal overflow. Prose
     links keep `layout.css`'s bare-`a` padding instead.

     Padding and min-height only: no border, no background, no font-size
     change, so nothing here alters how any of these read. */
  a.bb-chip,
  a.bb-subtle,
  a.bb-t-micro,
  a.bb-nav__link,
  .bb-evidence a,
  .bb-card__header a {
    min-height: var(--bb-tap-min);
    display: inline-flex;
    align-items: center;
  }
  a.bb-chip {
    padding-block: 6px;
  }

  /* THE PLAYER LINK -- the most-tapped target in the product and, at
     19-27px tall, one of the worst. It is deliberately NOT given a
     `min-height` and a flex box: `display: inline-flex` makes an anchor
     an ATOMIC inline, and text-decoration does not propagate into one --
     which would silently delete the line-through that marks a DRAFTED
     row on the Cheat Sheet, a non-colour signal Part 19 requires.

     Vertical padding on an INLINE box grows the hit area without
     touching the line box, which is the same instrument `layout.css`
     already uses on bare links. For the padding to become real height
     rather than an overlay that steals the neighbouring row's taps, the
     row has to make room for it -- so the cell and the link relax by
     the SAME amount, `--bb-row-pad-y-relaxed`, a density token that has
     existed unused since 020.0 for exactly this. Link hit area and row
     height then land on the same 43-46px box with no overlap between
     adjacent rows.

     Dense boards are included on purpose: the Draft Room board and the
     Cheat Sheet are the surfaces most likely to be read one-handed, and
     a 29px row on a phone is where a mis-tap costs a pick. Desktop --
     including every dense board at every desktop width -- keeps its 5px
     compact rhythm untouched. */
  .bb-table tbody td,
  .bb-table--dense tbody td {
    padding-block: var(--bb-row-pad-y-relaxed);
  }
  .bb-table .bb-cell-player a {
    padding-block: var(--bb-row-pad-y-relaxed);
  }
}


/* Phone: the priority-column collapse `layout.css` already performs for
   rankings is extended to the other canonical boards, which had none. */
@media (max-width: 620px) {
  /* THE TOP BAR AT PHONE WIDTH. Measured in real Chromium at 390px, the
     bar's controls needed ~465px and were being clipped. Nothing was
     removed to fix it -- every control (nav, search, drawer, products,
     account) is still present and still reachable. The WORDMARK shrinks
     to the existing BB// identity mark (Part 29), the account button
     truncates, and the bar's own padding and gaps tighten. */
  .bb-topbar {
    /* Keeps the safe-area compensation layout.css establishes -- only
       the horizontal breathing room tightens at phone width. */
    padding: var(--bb-safe-top) calc(var(--bb-space-2) + var(--bb-safe-right)) 0 calc(var(--bb-space-2) + var(--bb-safe-left));
    gap: var(--bb-space-2);
  }
  /* UX correction: at phone width the bar's content measured 404px in a
     390px viewport (the new, wider brand lockup pushed it over). The
     emblem shrinks, and the Products switcher moves to its nav-sheet
     home above rather than truncating every other control. */
  .bb-mark--lockup {
    width: 22px;
    height: 19px;
  }
  .bb-topbar #bb-product-menu {
    display: none;
  }
  .bb-topbar__left,
  .bb-topbar__right {
    gap: var(--bb-space-2);
  }
  .bb-wordmark {
    font-size: 0;
    line-height: 1;
  }
  .bb-wordmark::before {
    content: "BB//";
    font-size: var(--bb-fs-md);
    letter-spacing: 0.04em;
  }
  .bb-wordmark small {
    display: none;
  }
  .bb-topbar__right > [data-bb-menu] > .bb-btn {
    max-width: 92px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: block;
  }

  /* The context bar keeps the three facts a phone user is actually here
     for -- which league, which format context, how fresh -- and folds
     season/team-count and the league's own format summary into the
     league switcher, where both are already listed per league. */
  .bb-contextbar .bb-fact--secondary {
    display: none;
  }
  .bb-actions__spacer {
    display: none;
  }

  .bb-table td.bb-col-secondary,
  .bb-table th.bb-col-secondary {
    display: none;
  }
  .bb-table {
    min-width: 0;
  }
  .bb-valstack {
    grid-template-columns: 1fr;
  }
  .bb-balance__scale {
    grid-template-columns: 1fr;
  }
  .bb-tradebar__sides {
    flex-direction: column;
    gap: 4px;
  }
  .bb-tradebar__side--receive {
    text-align: left;
  }
  /* DW-3.2 WR-1K -- A HALF-APPLIED RESPONSIVE RULE, COMPLETED.
     `.bb-tradebar__sides` (the Give/Receive VALUES) has stacked into a
     column here since the Trade Desk recomposition, but
     `.bb-tradebar-packages` -- the give/receive ASSET NAMES that
     `trade_result.html` renders directly beneath the same balance bar,
     with `--receive` right-aligned to pair with the value above it --
     was left as a two-across `space-between` row.

     The two only read as one comparison because they line up. Once the
     values stacked and the packages did not, the right-aligned receive
     package no longer sat under anything naming it: on a 390px phone
     the reader got "Give / Receive" down the left, then a row whose
     right-hand half was an unlabelled list of player names. Nothing was
     clipped or unreachable -- `__side` already carries `min-width: 0`,
     so the names wrap rather than overflow -- but the ATTRIBUTION was
     gone, which on a trade verdict is the whole reading.

     Stated exactly as its sibling above, at the same breakpoint, so the
     pair cannot drift apart again. */
  .bb-tradebar-packages {
    flex-direction: column;
    gap: 4px;
  }
  .bb-tradebar-packages__side--receive {
    text-align: left;
  }
  .bb-verdict__label {
    font-size: var(--bb-fs-xl);
  }
  .bb-dirband {
    grid-template-columns: repeat(4, 1fr);
    row-gap: var(--bb-space-4);
  }
  .bb-dirband::before {
    display: none;
  }
  .bb-room__rec,
  .bb-room__board {
    gap: var(--bb-space-3);
  }
}

/* The 320px floor (smallest supported iPhone width): the account button
   tightens further, and the learn-layer grids drop their 280px track
   minimum -- measured at 4px of horizontal overflow without these. */
@media (max-width: 360px) {
  .bb-topbar__right > [data-bb-menu] > .bb-btn {
    max-width: 72px;
  }
  .bb-learn__grid--2,
  .bb-learn__chooser {
    grid-template-columns: 1fr;
  }
}


/* =====================================================================
   17B. LEARN LAYER -- GETTING STARTED / HELP / CONTEXTUAL HELP
   =====================================================================
   FINAL V1.0 PRESENTATION CERTIFICATION PACK 3.

   THIS SECTION ADDS NO NEW COLOUR, NO NEW FONT AND NO NEW SPACING VALUE.
   Every declaration below points at a token already in `tokens.css`, so
   the two educational pages read as the same product as every other
   page -- an onboarding surface that looks like a different app is the
   fastest way to make a new user distrust the one they landed in.

   It is also entirely additive: no existing selector was retuned, so
   nothing that shipped in Pack 1 or Pack 2 moved by a pixel. */

/* --- back path (Part 5) -------------------------------------------- */
/* A REAL control, visually quieter than a button and louder than the
   inert eyebrow it sits beside. */
.bb-backpath {
  display: inline-flex;
  align-items: center;
  gap: var(--bb-space-1);
  min-height: var(--bb-tap-min);
  padding-right: var(--bb-space-2);
  font-size: var(--bb-fs-small);
  color: var(--bb-text-secondary);
  text-decoration: none;
}
.bb-backpath:hover,
.bb-backpath:focus-visible {
  color: var(--bb-text-primary);
  text-decoration: underline;
}
.bb-backpath__arrow {
  color: var(--bb-text-tertiary);
}

/* --- contextual help disclosure (Parts 3-4) ------------------------ */
/* The same `bb-disclosure` shape, marked so a page's "what am I looking
   at" control is visually distinguishable from its technical-evidence
   disclosures without being a second component. */
.bb-about {
  margin-bottom: var(--bb-space-4);
  border-color: var(--bb-border);
}
.bb-about > summary {
  color: var(--bb-accent);
}
.bb-about__body p {
  margin: 0 0 var(--bb-space-2);
  max-width: 84ch;
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-about__body p:last-child {
  margin-bottom: 0;
}
.bb-about__body strong {
  color: var(--bb-text-primary);
}

/* --- draft position gap cell (Part 8B) ------------------------------ */
/* Two readings, or one difference, in a cell narrow enough to sit in a
   live draft board. Never tinted by direction: the sign is the signal
   and a hue would imply good/bad, which this reading does not claim. */
.bb-gapcell {
  white-space: nowrap;
  font-family: var(--bb-font-numeric);
  font-variant-numeric: tabular-nums;
  font-size: var(--bb-fs-micro);
}
.bb-gapcell__value {
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
}
.bb-gapcell__pair {
  display: inline-flex;
  align-items: baseline;
  gap: var(--bb-space-1);
  color: var(--bb-text-secondary);
}
.bb-gapcell__vs {
  color: var(--bb-text-tertiary);
}

/* --- the learn pages ----------------------------------------------- */
.bb-learn__section {
  margin-bottom: var(--bb-space-7);
}
.bb-learn__body {
  max-width: 76ch;
  margin: 0 0 var(--bb-space-3);
  font-size: var(--bb-fs-body);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-learn__body strong {
  color: var(--bb-text-primary);
  font-weight: var(--bb-fw-semibold);
}
.bb-learn__note {
  max-width: 84ch;
  margin: var(--bb-space-3) 0 0;
  padding-left: var(--bb-space-3);
  border-left: 2px solid var(--bb-border-strong);
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-tertiary);
}
.bb-learn__note strong {
  color: var(--bb-text-secondary);
}
.bb-learn__term {
  margin: 0 0 var(--bb-space-1);
  font-size: var(--bb-fs-card-title);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: var(--bb-tracking-tight);
  color: var(--bb-text-primary);
}
.bb-learn__gloss {
  margin: 0 0 var(--bb-space-3);
  font-size: var(--bb-fs-small);
  color: var(--bb-accent);
}
.bb-learn__list {
  max-width: 84ch;
  margin: 0;
  padding-left: 1.15em;
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-learn__list li {
  margin-bottom: var(--bb-space-2);
}
.bb-learn__list strong {
  color: var(--bb-text-primary);
}

/* Concept cards. `auto-fit` + `minmax` means the same markup is four
   columns on a desk, two on a tablet and one on a phone with no
   breakpoint of its own to keep in sync. */
.bb-learn__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--bb-space-4);
}
.bb-learn__grid--2 {
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

/* Freshness vocabulary list. */
.bb-learn__deflist {
  display: grid;
  gap: var(--bb-space-2);
  margin: var(--bb-space-3) 0;
}
.bb-learn__def {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--bb-space-3);
  font-size: var(--bb-fs-small);
  color: var(--bb-text-secondary);
}

/* The loop. Numbered, ordered, and readable as a list of destinations
   rather than as decoration. */
.bb-learn__flow {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--bb-space-2);
}
.bb-learn__step {
  display: grid;
  grid-template-columns: 92px minmax(150px, auto) 1fr;
  align-items: baseline;
  gap: var(--bb-space-3);
  padding: var(--bb-space-3);
  border: 1px solid var(--bb-border-subtle);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
}
.bb-learn__stepword {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  color: var(--bb-text-tertiary);
}
.bb-learn__steplink {
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-accent);
  text-decoration: none;
}
.bb-learn__steplink:hover,
.bb-learn__steplink:focus-visible {
  text-decoration: underline;
}
.bb-learn__steptext {
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}

/* "Where should I start?" -- the strongest section on the page. */
.bb-learn__chooser {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--bb-space-3);
}
.bb-learn__choice {
  display: flex;
  flex-direction: column;
  gap: var(--bb-space-1);
  padding: var(--bb-space-4);
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
  text-decoration: none;
  transition: border-color var(--bb-transition-fast), background var(--bb-transition-fast);
}
.bb-learn__choice:hover,
.bb-learn__choice:focus-visible {
  border-color: var(--bb-accent);
  background: var(--bb-surface-hover);
}
.bb-learn__choice--lead {
  border-color: var(--bb-accent);
  background: var(--bb-accent-bg);
}
.bb-learn__when {
  font-size: var(--bb-fs-micro);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-learn__where {
  font-size: var(--bb-fs-md);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
}
.bb-learn__why {
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}

/* The primary call to action. */
.bb-learn__cta {
  margin-top: var(--bb-space-6);
  padding: var(--bb-space-6);
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-elevated);
}
.bb-learn__ctatitle {
  margin: 0 0 var(--bb-space-2);
  font-size: var(--bb-fs-section-title);
  letter-spacing: var(--bb-tracking-tight);
  color: var(--bb-text-primary);
}
.bb-learn__ctatext {
  max-width: 76ch;
  margin: 0 0 var(--bb-space-4);
  font-size: var(--bb-fs-body);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}

/* One larger button size, used only by the call to action above. */
.bb-btn--lg {
  min-height: 44px;
  padding: 0 var(--bb-space-5);
  font-size: var(--bb-fs-body);
  font-weight: var(--bb-fw-semibold);
}

@media (max-width: 720px) {
  /* The three-column step collapses to a stack rather than squeezing a
     92px label column onto a 390px phone. */
  .bb-learn__step {
    grid-template-columns: 1fr;
    gap: var(--bb-space-1);
  }
  .bb-learn__section {
    margin-bottom: var(--bb-space-6);
  }
  .bb-learn__cta {
    padding: var(--bb-space-4);
  }
}


/* =====================================================================
   BOARD SURFACES -- RANKINGS / AVAILABLE PLAYERS / CHEAT SHEET
   (Visual-only pass, post-V1)
   =====================================================================
   Presentation-only pass over the three dense board surfaces. Every
   selector below decorates markup that already exists (a wrapper class,
   an existing `td`/`th`) or reuses an existing macro's own output --
   nothing here changes a row's order, a column's data, or a certified
   htmx contract. See `rankings_results.html`, `available_players.html`
   and `cheat_sheet_table.html` for the markup these rules attach to. */

/* One cohesive control strip: format toggle, position tabs, freshness
   and search used to read as three unrelated floating rows. A single
   card-like band behind them reads as one board header instead. */
.bb-boardbar {
  display: flex;
  flex-direction: column;
  gap: var(--bb-space-3);
  padding: var(--bb-space-3) var(--bb-space-3) var(--bb-space-1);
  margin-bottom: var(--bb-space-4);
  background: var(--bb-surface-card);
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
}
.bb-boardbar .bb-filterbar,
.bb-boardbar .bb-tabs {
  margin-bottom: 0;
}
.bb-boardbar > .bb-tabs {
  padding-bottom: var(--bb-space-2);
  border-bottom: 1px solid var(--bb-border-subtle);
}

/* A visible, keyboard-reachable row treatment. `:focus-within` fires
   when the row's own player link (or any focusable control inside it)
   receives keyboard focus, so the same left accent bar a mouse user
   sees on hover is what a keyboard user sees too -- no JS, no new
   tabindex, no change to what `data-bb-row-href` or any certified
   selector finds. */
.bb-table--scan tbody tr:hover > td:first-child,
.bb-table--scan tbody tr:focus-within > td:first-child {
  box-shadow: inset 3px 0 0 var(--bb-accent);
}
.bb-table--scan tbody tr:focus-within > td {
  background: var(--bb-surface-hover);
}
/* Stronger BB Rank / player-name lead.
   Available Players and the Cheat Sheet wrap their rank cell in
   `.bb-rank`/`.bb-rank--lead` directly (see `available_players.html` /
   `partials/cheat_sheet_table.html`) -- the same lead-number treatment
   `ui.rank_badge()` renders everywhere else. Rankings' own rank cell
   CANNOT take that wrapper: `tests/web/test_v1_cross_surface_
   consistency.py::TestOneReadingSixSurfaces::test_the_rendered_
   rankings_row_draws_the_canonical_rank_and_value` asserts its markup
   byte-for-byte as `<td class="bb-num">{rank}</td>`, so the emphasis
   here is CSS-only, keyed off row structure rather than a new class --
   `tr[data-bb-row-href]` only matches Rankings' own data rows (Available
   Players' rows carry no such attribute), so this never reaches a table
   this campaign did not mean to touch. */
.bb-table--rankings tbody tr[data-bb-row-href] > td:first-child {
  font-family: var(--bb-font-numeric);
  font-weight: var(--bb-fw-bold);
  font-size: var(--bb-fs-md);
  color: var(--bb-text-primary);
}
.bb-table--rankings .bb-cell-player a,
.bb-cheat-sheet__table .bb-cell-player a {
  font-size: var(--bb-fs-body);
}

/* SIGNATURE READING BRACKET -- the value / market / edge column group.
   Mirrors the IDEA behind `ui.value_stack()` (three separate readings,
   never blended into one score) without reusing its card-shaped markup,
   which does not fit inside a table row. A shared, slightly raised
   backdrop plus a hairline on the group's outer edges visually brackets
   Blackbird's own reading, the market's reading and the Edge comparison
   as one related-but-separate cluster, distinct from identity columns
   (Rank/Player/Pos/Bye/Status) on one side and supporting evidence
   (Opportunity/Confidence/Trajectory) on the other. No column moved, no
   header renamed, no value touched. */
.bb-table th.bb-col-reading,
.bb-table td.bb-col-reading {
  background: var(--bb-bg-elevated);
}
.bb-table th.bb-col-reading:first-of-type,
.bb-table td.bb-col-reading:first-of-type {
  border-left: 1px solid var(--bb-border);
}
.bb-table th.bb-col-reading:last-of-type,
.bb-table td.bb-col-reading:last-of-type {
  border-right: 1px solid var(--bb-border);
}
.bb-table--scan tbody tr:hover td.bb-col-reading,
.bb-table--scan tbody tr:focus-within td.bb-col-reading {
  background: var(--bb-surface-hover);
}

/* Phone-tier column collapse (Rankings/Available Players/Cheat Sheet).
   `bb-col-secondary` (market data, hidden at 620px) and `bb-col-tertiary`
   (supporting evidence, hidden at 1024px) already existed; neither one
   fit fields like Bye/Status/Role, which are identity/reference context
   rather than a decision field, so they survived all the way to a 390px
   phone and pushed Rank Edge past the horizontal scroll edge -- measured
   in real Chromium, `layout.css`'s own comment on `.bb-table--rankings`
   already documents Pos/BBV/EDGE as the intended surviving priority
   columns. `bb-col-mobile` closes that gap: hidden ONLY at the phone
   tier (a tablet keeps every column), so BB Rank / Player / Pos /
   BBV-or-Surplus / Rank Edge are what is guaranteed to fit without a
   sideways scroll. Nothing hidden here is lost -- it is still in the
   row's own "All readings" disclosure. */
@media (max-width: 620px) {
  .bb-table td.bb-col-mobile,
  .bb-table th.bb-col-mobile {
    display: none;
  }
  /* Tightened cell padding, scoped to the three dense board tables only
     (not every `.bb-table` in the app): reclaims just enough width for
     the Cheat Sheet's longer "Board Value" header to sit beside Rank
     Edge without a sideways scroll, measured in real Chromium at 390px.
     Selectors match `components.css`'s own `.bb-table thead th` /
     `.bb-table tbody td` structure so this specificity actually wins. */
  .bb-table.bb-table--rankings thead th,
  .bb-table.bb-table--rankings tbody td,
  .bb-table.bb-cheat-sheet__table thead th,
  .bb-table.bb-cheat-sheet__table tbody td {
    padding-left: var(--bb-space-2);
    padding-right: var(--bb-space-2);
  }
}


/* =====================================================================
   17B. REMAINING VISUAL FIDELITY COMPLETION -- SEVEN SECONDARY SURFACES
   =====================================================================
   Draft Room, Scenario Lab, Research Terminal, Player Intelligence,
   Account, Getting Started, Help. Presentation-only, mirroring the
   board-surfaces pass above: every selector decorates markup that
   already exists or reuses an already-published reading, restated for
   emphasis. No methodology, order, or field changed. */

/* --- DRAFT ROOM: the recommendation call, made the loudest thing in
   the room. `.bb-call__eyebrow` is a plain label above the existing
   `.bb-call` block; the player's name inside it is bumped from a
   template-inline font-size to a dedicated class so it reads as the
   page's single largest identity, ahead of every tile around it. */
.bb-call__eyebrow {
  display: block;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
  margin-bottom: 2px;
}
.bb-call__name {
  display: block;
  font-size: var(--bb-fs-xl);
  font-weight: var(--bb-fw-bold);
  line-height: var(--bb-leading-tight);
  color: var(--bb-text-primary);
}

/* Roster-fit rail: the SAME `rc.unfilled_dedicated_starters` / `rc.
   open_flex_slots` fields the plain-text "Your lineup" sentence already
   read, restated as a compact row of open-slot chips instead of a run-on
   clause -- no new field, no computed ratio. */
.bb-fitrail {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bb-space-1);
  align-items: center;
}
.bb-fitrail__slot {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-semibold);
  padding: 2px 7px;
  border-radius: var(--bb-radius-sm);
  background: var(--bb-caution-bg);
  border: 1px solid var(--bb-caution-border);
  color: var(--bb-caution);
  white-space: nowrap;
}
.bb-fitrail__slot--filled {
  background: var(--bb-positive-bg);
  border-color: var(--bb-positive-border);
  color: var(--bb-positive);
}

/* --- SCENARIO LAB: position counts restated as a real before/after
   pair (current -> hypothetical) instead of a value plus a caption --
   same two numbers `ev.trade.hypothetical_position_counts` and `ev.
   trade.current_position_counts` already published side by side. */
.bb-beforeafter {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-family: var(--bb-font-numeric);
}
.bb-beforeafter__before {
  color: var(--bb-text-tertiary);
  font-size: var(--bb-fs-sm);
}
.bb-beforeafter__arrow {
  color: var(--bb-text-tertiary);
  font-size: var(--bb-fs-sm);
}
.bb-beforeafter__after {
  font-size: var(--bb-fs-md);
  font-weight: var(--bb-fw-bold);
  color: var(--bb-text-primary);
}
.bb-beforeafter--up .bb-beforeafter__after { color: var(--bb-positive); }
.bb-beforeafter--down .bb-beforeafter__after { color: var(--bb-negative); }

/* --- RESEARCH TERMINAL: the one page where the proprietary-insight
   violet is deliberately allowed a second appearance beside the
   canonical reading, since a research profile's whole purpose is
   surfacing Blackbird's own disagreement with the market as evidence. */
.bb-canon--research {
  border-left: 2px solid var(--bb-proprietary-border);
  padding-left: var(--bb-space-4);
}

/* --- PLAYER INTELLIGENCE: header + value stack merged into one hero,
   so identity and the three signature readings read as a single
   composed dossier rather than two stacked blocks. */
.bb-dossier-hero {
  padding: var(--bb-space-4);
}
.bb-dossier-hero .bb-player-header {
  margin-bottom: var(--bb-space-4);
}

/* --- ACCOUNT: connection-status hero strip (identity + Sleeper +
   league sync at a glance), so the page reads as a control panel
   instead of a stack of equal-weight settings cards. */
.bb-connectstrip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bb-space-5);
  align-items: center;
}
.bb-connectstrip__item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 140px;
}
.bb-connectstrip__label {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-connectstrip__divider {
  width: 1px;
  align-self: stretch;
  background: var(--bb-border);
  min-height: 36px;
}
@media (max-width: 620px) {
  .bb-connectstrip__divider { display: none; }
}

/* --- GETTING STARTED: numbered workflow rail. Pure CSS counters over
   the SAME `.bb-learn__step` markup -- no step was reworded, reordered,
   or renumbered in the template; this only draws the ordinal Blackbird
   already implies by list order. */
.bb-learn__flow {
  counter-reset: bb-step;
}
.bb-learn__step {
  position: relative;
}
.bb-learn__step::before {
  counter-increment: bb-step;
  content: "0" counter(bb-step);
  position: absolute;
  top: var(--bb-space-2);
  right: var(--bb-space-3);
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-bold);
  color: var(--bb-border-strong);
}
.bb-welcome {
  position: relative;
  overflow: hidden;
}
.bb-welcome::after {
  content: "";
  position: absolute;
  top: -4%;
  right: -6%;
  width: 460px;
  height: 158px;
  z-index: 0;
  pointer-events: none;
  opacity: 0.05;
  /* PACK 2 (2026-09): the locked mark, via the one brand-mark token. */
  background-image: var(--bb-brand-mark);
  background-size: contain;
  background-repeat: no-repeat;
}
.bb-welcome > * {
  position: relative;
  z-index: 1;
}

/* --- HELP: quick-jump section navigation. Anchors into the SAME
   sections already on the page -- no content moved, no new page. */
.bb-jumpnav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bb-space-2);
  padding: var(--bb-space-3);
  margin-bottom: var(--bb-space-4);
  background: var(--bb-surface-card);
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
}
.bb-jumpnav__link {
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-medium);
  color: var(--bb-text-secondary);
  text-decoration: none;
  padding: 4px 10px;
  border-radius: var(--bb-radius-pill);
  border: 1px solid var(--bb-border-subtle);
  white-space: nowrap;
}
.bb-jumpnav__link:hover,
.bb-jumpnav__link:focus-visible {
  color: var(--bb-text-primary);
  border-color: var(--bb-accent);
}
html {
  scroll-padding-top: calc(var(--bb-topbar-height) + var(--bb-contextbar-height) + var(--bb-space-3));
}


/* =====================================================================
   19. INTELLIGENCE HQ ATMOSPHERE LAYER (Visual Overhaul, approved mock)
   =====================================================================
   The mock's composition already exists page-by-page (hero bands,
   priorities, radar, balance bar, landscape). What it has that this
   stylesheet did not is LIGHT: per-panel glow, one signature gradient,
   a faint blueprint grid, dramatic focal numerals. This section adds
   that layer on top of the existing system -- every rule is additive
   decoration over markup and readings that already exist. Nothing here
   carries meaning by colour alone (Part 19 contract holds), and nothing
   animates continuously.
   ================================================================== */

/* --- 19.1 THE PRIMARY HERO PANEL, LIT ------------------------------
   Every `.bb-icard--primary` (Command Brief, Team overview, Draft Room
   header, Player dossier, Account identity...) gains: a top signal
   hairline, a faint blueprint grid, and an accent wash. The watermark
   from section 4 still renders -- these stack under the same ::before
   via background layering on the card itself. */
.bb-icard--primary {
  border-color: rgba(140, 102, 242, 0.28);
  background-color: var(--bb-surface-raised);
  background-image: var(--bb-grad-hero), var(--bb-texture-grid);
  background-size: auto, var(--bb-texture-grid-size);
  box-shadow: var(--bb-shadow-sm), var(--bb-glow-accent);
}
.bb-icard--primary::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--bb-grad-signal);
  opacity: 0.85;
  z-index: 1;
  pointer-events: none;
}

/* --- 19.2 HERO STAT BAND -------------------------------------------
   The mock's row of large glowing stat panels. `ui.power_rank_hero`
   renders into this shape: label / focal numeral / sub, one panel per
   already-published reading. `data-tone` tints a panel's hairline and
   glow; the words inside are still the signal. */
.bb-herostat {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  gap: var(--bb-space-3);
  align-items: stretch;
}
.bb-herostat__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  padding: var(--bb-space-3) var(--bb-space-4);
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-md);
  background: var(--bb-bg-elevated);
  overflow: hidden;
}
.bb-herostat__panel::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: var(--bb-accent);
  opacity: 0.55;
}
.bb-herostat__panel[data-tone="positive"]::before { background: var(--bb-positive); }
.bb-herostat__panel[data-tone="negative"]::before { background: var(--bb-negative); }
.bb-herostat__panel[data-tone="caution"]::before  { background: var(--bb-caution); }
.bb-herostat__panel[data-tone="violet"]::before   { background: var(--bb-proprietary); }
.bb-herostat__panel[data-tone="positive"] { box-shadow: var(--bb-glow-positive); }
.bb-herostat__panel[data-tone="negative"] { box-shadow: var(--bb-glow-negative); }
.bb-herostat__label {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-herostat__value {
  font-family: var(--bb-font-numeric);
  font-size: var(--bb-fs-2xl);
  font-weight: var(--bb-fw-bold);
  line-height: 1.05;
  letter-spacing: var(--bb-tracking-tight);
  color: var(--bb-text-primary);
  white-space: nowrap;
}
.bb-herostat__value small {
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-medium);
  color: var(--bb-text-tertiary);
  letter-spacing: 0;
}
.bb-herostat__value--word {
  font-family: var(--bb-font-ui);
  font-size: var(--bb-fs-lg);
  white-space: normal;
  line-height: var(--bb-leading-tight);
}
.bb-herostat__panel[data-tone="positive"] .bb-herostat__value--word { color: var(--bb-positive); }
.bb-herostat__panel[data-tone="negative"] .bb-herostat__value--word { color: var(--bb-negative); }
.bb-herostat__sub {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  line-height: var(--bb-leading-tight);
}
.bb-herostat__panel--ring {
  flex-direction: row;
  align-items: center;
  gap: var(--bb-space-3);
}

/* --- 19.3 RANK RING -------------------------------------------------
   The mock's ring gauge, drawn from an ALREADY-PUBLISHED `rank of
   count`: fill = (count - rank + 1) / count, the SAME normalization
   `league_band` documents. Never a 0-100 score -- the rank number sits
   in the centre and is the reading. */
.bb-ring {
  flex: none;
}
.bb-ring__track {
  stroke: var(--bb-border);
  fill: none;
}
/* The fill arc's gradient stroke is referenced per-instance inside the
   macro's own SVG (each ring embeds its own <linearGradient> with a
   caller-supplied unique id); this rule carries the geometry and an
   accent fallback for any context that strips defs. */
.bb-ring__fill {
  stroke: var(--bb-accent);
  fill: none;
  stroke-linecap: round;
  transform: rotate(-90deg);
  transform-origin: 50% 50%;
}
.bb-ring__rank {
  font-family: var(--bb-font-numeric);
  font-size: 19px;
  font-weight: var(--bb-fw-bold);
  fill: var(--bb-text-primary);
}
.bb-ring__of {
  font-family: var(--bb-font-ui);
  font-size: 8.5px;
  fill: var(--bb-text-tertiary);
}

/* --- 19.4 PRIORITY CARDS -------------------------------------------
   Command Center's Top Priorities as the mock's category-tagged card
   row: each card carries its category badge, headline, why-it-matters
   line and its own existing nav_target as a visible CTA. Same data,
   same links -- a card instead of a list row. */
.bb-priogrid {
  display: grid;
  /* UX correction: `auto-fill` reserved phantom empty tracks when there
     were fewer priorities than columns -- literal dead space on the
     flagship page. `auto-fit` collapses the empties so the real cards
     use the row. */
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--bb-space-3);
}
.bb-priocard {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--bb-space-2);
  padding: var(--bb-space-4);
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-md);
  background: var(--bb-bg-elevated);
  color: inherit;
  text-decoration: none;
  overflow: hidden;
  transition: border-color var(--bb-transition-fast), box-shadow var(--bb-transition-fast),
              transform var(--bb-transition-fast);
}
.bb-priocard::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 2px;
  background: var(--bb-accent);
  opacity: 0.6;
}
.bb-priocard:hover,
.bb-priocard:focus-visible {
  border-color: rgba(140, 102, 242, 0.45);
  box-shadow: var(--bb-glow-accent);
  text-decoration: none;
  transform: translateY(-1px);
}
@media (prefers-reduced-motion: reduce) {
  .bb-priocard,
  .bb-priocard:hover { transform: none; }
}
.bb-priocard__headline {
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
  line-height: var(--bb-leading-tight);
}
.bb-priocard__why {
  margin: 0;
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-secondary);
  line-height: var(--bb-leading-body);
  flex: 1;
}
.bb-priocard__cta {
  align-self: flex-start;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.08em;
  color: var(--bb-accent);
}

/* --- 19.5 LANDSCAPE TIER BANDS -------------------------------------
   The mock's ELITE / CONTENDERS / ... tier table, as band headers
   inserted where the already-published Power Rank label CHANGES between
   consecutive rows -- the tier-divider pattern the Rankings board
   already uses. Row order is untouched: the service's own order is
   preserved and a band is only a caption over it. */
.bb-tierband {
  display: flex;
  align-items: center;
  gap: var(--bb-space-2);
  margin: var(--bb-space-3) 0 var(--bb-space-1);
  padding: 0 var(--bb-space-2);
}
.bb-tierband:first-child {
  margin-top: 0;
}
.bb-tierband__label {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-accent);
  white-space: nowrap;
}
.bb-tierband[data-tier="TITLE_FAVORITE"] .bb-tierband__label,
.bb-tierband[data-tier="STRONG_CONTENDER"] .bb-tierband__label { color: var(--bb-positive); }
.bb-tierband[data-tier="EARLY_REBUILD"] .bb-tierband__label,
.bb-tierband[data-tier="DEEP_REBUILD"] .bb-tierband__label { color: var(--bb-negative); }
.bb-tierband__rule {
  height: 1px;
  flex: 1;
  background: linear-gradient(to right, var(--bb-border-strong), transparent);
}

/* --- 19.6 NAVIGATION, LIT ------------------------------------------
   Icon slot, glowing active box, and a closing wordmark stamp. Icons
   are aria-hidden decoration; label + hint + aria-current still carry
   the meaning. */
.bb-navitem__icon {
  flex: none;
  width: 17px;
  height: 17px;
  color: var(--bb-text-tertiary);
  transition: color var(--bb-transition-fast);
}
.bb-navitem:hover .bb-navitem__icon { color: var(--bb-text-secondary); }
.bb-navitem.is-active .bb-navitem__icon { color: var(--bb-accent); }
.bb-navitem.is-active {
  box-shadow: inset 0 0 18px rgba(140, 102, 242, 0.10);
}
.bb-navgroup__label::before {
  content: "";
  display: inline-block;
  width: 10px;
  height: 2px;
  margin-right: 6px;
  vertical-align: middle;
  background: var(--bb-grad-signal);
  opacity: 0.7;
}
.bb-nav__foot {
  margin-top: var(--bb-space-5);
  padding: var(--bb-space-3);
  border-top: 1px solid var(--bb-border-subtle);
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  letter-spacing: 0.1em;
  color: var(--bb-text-tertiary);
  display: flex;
  align-items: center;
  gap: var(--bb-space-2);
}
.bb-nav__foot .bb-mark { width: 14px; height: 14px; color: var(--bb-accent); opacity: 0.7; }

/* --- 19.7 TOPBAR & SHELL DEPTH -------------------------------------- */
.bb-topbar {
  background: var(--bb-grad-topbar);
  border-bottom-color: rgba(140, 102, 242, 0.16);
}
.bb-topbar__emblem {
  display: inline-flex;
  color: var(--bb-accent);
  filter: drop-shadow(0 0 10px rgba(140, 102, 242, 0.55));
  opacity: 0.9;
}
.bb-contextbar {
  background-image: linear-gradient(180deg, rgba(140, 102, 242, 0.03), transparent);
}

/* --- 19.8 TRADE BALANCE METER, LIT ---------------------------------
   The mock's fair->great gradient track. The words beside it (side
   values, certified lean, verdict) are unchanged and still the
   reading; the gradient replaces a flat 35%-opacity fill. */
.bb-tradebar {
  background-image: var(--bb-grad-panel-accent);
}
.bb-tradebar__track {
  height: 14px;
  background: var(--bb-grad-balance);
  border-color: var(--bb-border-strong);
}
.bb-tradebar__fill {
  background: transparent;
  opacity: 1;
  border-right: 1px solid rgba(231, 233, 238, 0.28);
}
.bb-tradebar__marker {
  font-size: 1.35rem;
  filter: drop-shadow(0 0 6px currentColor);
}
.bb-tradebar__side-value {
  font-size: var(--bb-fs-2xl);
}

/* --- 19.9 VERDICTS & CALLS, LOUDER ---------------------------------- */
.bb-verdict__label {
  font-family: var(--bb-font-mono);
  letter-spacing: 0.05em;
  text-shadow: 0 0 24px currentColor;
}
.bb-call--go { box-shadow: var(--bb-glow-positive); }
.bb-call--wait { box-shadow: var(--bb-glow-caution); }
.bb-call__word {
  text-shadow: 0 0 18px currentColor;
}

/* --- 19.10 WELCOME / PAGE HEADS ------------------------------------- */
.bb-welcome {
  padding: var(--bb-space-5);
  border: 1px solid rgba(140, 102, 242, 0.22);
  border-radius: var(--bb-radius-lg);
  background-color: var(--bb-surface-card);
  background-image: var(--bb-grad-hero), var(--bb-texture-grid);
  background-size: auto, var(--bb-texture-grid-size);
  box-shadow: var(--bb-glow-accent);
  margin-bottom: var(--bb-space-5);
}
.bb-pagehead__eyebrow {
  background: var(--bb-grad-signal);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* --- 19.11 COMMAND CENTER FLAGSHIP ----------------------------------
   The reference implementation: display-scale title, a ring beside it,
   scaled-up stat numerals, and an asymmetric main/rail band below. */
.bb-cchero__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--bb-space-5);
  flex-wrap: wrap;
}
.bb-cchero__titleblock {
  min-width: 0;
}
.bb-cchero__title {
  margin: 4px 0 6px;
  font-size: clamp(2rem, 4vw, 2.9rem);
  font-weight: 800;
  letter-spacing: 0.015em;
  text-transform: uppercase;
  line-height: 1.02;
  color: var(--bb-text-primary);
}
.bb-cchero__ring {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.bb-cchero .bb-herostat__value {
  font-size: clamp(1.9rem, 3vw, 2.6rem);
}
.bb-ccgrid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: var(--bb-space-5);
  align-items: start;
}
@media (max-width: 1200px) {
  .bb-ccgrid {
    grid-template-columns: 1fr;
  }
}

/* --- 19.12 SITE-WIDE PROPAGATION ------------------------------------
   Shared primitives that every surface already uses, lit the same way,
   so no page reads as a legacy island. */

/* Board control strips (Rankings / Available / Cheat Sheet / Research)
   join the hero language: signal hairline + accent wash. */
.bb-boardbar {
  position: relative;
  overflow: hidden;
  border-color: rgba(140, 102, 242, 0.20);
  background-image: var(--bb-grad-panel-accent);
}
.bb-boardbar::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: var(--bb-grad-signal);
  opacity: 0.8;
}

/* Section rhythm: every section title carries the same small signal
   tick the nav group labels carry -- one recurring brand gesture. */
.bb-sectionhead__title::before {
  content: "";
  display: inline-block;
  width: 12px;
  height: 3px;
  margin-right: 8px;
  vertical-align: middle;
  border-radius: 2px;
  background: var(--bb-grad-signal);
  opacity: 0.75;
}

/* Deeper card layering: standard cards keep their flat face; icards --
   the section-level containers -- gain a touch of shadow so surface
   hierarchy (page < card < icard < icard--primary) is visible depth,
   not just border weight. */
.bb-icard {
  box-shadow: var(--bb-shadow-sm);
}

/* Trade Desk / Scenario Lab composer sides: the two package panels are
   the working surface of both pages -- they join the elevated-panel
   language (raised face + accent hairline) so neither page opens on a
   flat form. */
.bb-trade-side {
  position: relative;
  overflow: hidden;
  background: var(--bb-bg-elevated);
  border-color: var(--bb-border-strong);
}
.bb-trade-side::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: var(--bb-accent);
  opacity: 0.45;
}

/* --- 19.13 SMALL SCREENS -------------------------------------------- */
@media (max-width: 620px) {
  .bb-herostat {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .bb-herostat__value {
    font-size: var(--bb-fs-xl);
  }
  .bb-priogrid {
    grid-template-columns: 1fr;
  }
  .bb-cchero__title {
    font-size: 1.6rem;
  }
}


/* =====================================================================
   18. PRINT (Part 16)
   =====================================================================
   The Cheat Sheet's print document has its own light palette; these
   rules make sure the SHELL never reaches paper if a user prints any
   other page, and that nothing dark-on-dark wastes ink. */

@media print {
  .bb-topbar,
  .bb-nav,
  .bb-drawer,
  .bb-scrim,
  .bb-contextbar,
  .bb-skip-link,
  .bb-search,
  .bb-print-hide {
    display: none !important;
  }
  .bb-shell {
    display: block;
  }
  .bb-main {
    padding: 0;
  }
  html, body {
    background: #fff;
    color: #111;
  }
  .bb-card,
  .bb-icard,
  .bb-state {
    border-color: #bbb;
    background: #fff;
    box-shadow: none;
  }
  a {
    color: #111;
    text-decoration: underline;
  }
}


/* =====================================================================
   DRAFT POSITION FILTERS -- the available-player board's chip row
   =====================================================================
   Markup: `partials/draft_position_filters.html`, rendered by BOTH the
   Live Draft Room board and Mock Draft. One component, one stylesheet
   section, so the two rooms cannot look like two products.

   MOBILE-FIRST, AND DELIBERATELY NOT A DROPDOWN. This control is tapped
   between picks with a clock running: six one-tap targets beat a select
   that costs a tap to open, a scroll, and a tap to choose -- and a
   dropdown cannot show a MULTI-selection at all, which is the whole
   point of the control.

   WHY IT SCROLLS INSTEAD OF WRAPPING. `.bb-filterbar` and `.bb-actions`
   wrap, because their contents are a variable-length strip of verbs and
   a second line costs nothing. This row is fixed at six short chips and
   sits directly above the board a drafter is trying to read, so a wrap
   would spend a whole line of a 390px screen to gain nothing. Instead it
   is a single non-wrapping row inside its OWN `overflow-x: auto`
   container: at 390px the six chips fit, and at 320px the last one
   scrolls into reach rather than widening the page. `max-width: 100%`
   plus the scroller is what keeps it inside `.bb-main` (which clips with
   `overflow-x: hidden`), the layering
   `tests/web/test_ui_contract_sweep.py` pins as load-bearing.

   THE TAP FLOOR IS UNCONDITIONAL, ON PURPOSE. Every chip is at least
   `--bb-tap-min` (40px) tall at EVERY width, not only at the phone tier.
   The desktop-density rule this codebase holds -- see
   `tests/web/test_touch_targets.py::TestDesktopDensityIsNotCollateral
   Damage` -- protects REPEATED BOARD ROWS, where a height floor costs
   rows of visible data per screen. This is one control strip drawn once
   per board; sizing it for a finger costs a single row of pixels and
   removes any chance of a mis-tap selecting the wrong position mid-pick.
   `.bb-posfilter__chip` is therefore listed in that test's
   `UNCONDITIONAL_HEIGHT_ALLOWED` set with the same reasoning.

   SELECTED IS A STATE, NOT A VERB. An active chip uses the SAME
   translucent-purple selected treatment `identity.css` already defines
   for a selected filter pill, never the solid CTA fill -- the board's
   real actions (Queue, Draft) must stay the loudest thing on the
   surface. Multi-selection is legible because several chips carry that
   state at once, and every chip also reports `aria-pressed`, so a screen
   reader announces the same fact the colour does. */
.bb-posfilter {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--bb-space-2);
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  margin-bottom: var(--bb-space-2);
  padding-bottom: 2px;
}
/* The scrollbar itself is suppressed rather than the content: the row
   still scrolls, it just does not spend 8px of a phone screen drawing a
   track under six chips. */
.bb-posfilter::-webkit-scrollbar {
  display: none;
}
.bb-posfilter__chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--bb-tap-min);
  min-width: var(--bb-tap-min);
  padding: 0 var(--bb-space-3);
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-pill);
  background: var(--bb-surface-card);
  color: var(--bb-text-secondary);
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: 0.02em;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--bb-transition-fast), background var(--bb-transition-fast),
              border-color var(--bb-transition-fast);
}
/* Rendered as an `<a>` on link-mode surfaces (Mock Draft), so the
   underline every other anchor carries has to be turned off here or one
   surface draws underlined chips and the other does not. */
a.bb-posfilter__chip,
a.bb-posfilter__chip:hover {
  text-decoration: none;
}
.bb-posfilter__chip:hover {
  border-color: var(--bb-border-strong);
  color: var(--bb-text-primary);
  background: var(--bb-surface-hover);
}
.bb-posfilter__chip:focus-visible {
  border-color: var(--bb-purple-bright);
  color: var(--bb-text-primary);
}
.bb-posfilter__chip.is-active {
  background-image: linear-gradient(180deg, rgb(var(--bb-purple-rgb) / 0.30), rgb(var(--bb-purple-rgb) / 0.10));
  background-color: transparent;
  border-color: var(--bb-purple-border-strong);
  color: var(--bb-purple-bright);
  box-shadow: var(--bb-glow-purple-sm);
  font-weight: var(--bb-fw-bold);
}
.bb-posfilter__chip.is-active:hover {
  background-image: linear-gradient(180deg, rgb(var(--bb-purple-rgb) / 0.42), rgb(var(--bb-purple-rgb) / 0.16));
  border-color: var(--bb-purple-bright);
  color: var(--bb-purple-bright);
}

/* -------------------------------------------------------------------
   DRAFT-WEEKEND CORRECTION PACK, Priority 6 -- THE MENU SHOWS WHAT THE
   BOTTOM BAR DOES NOT.
   -------------------------------------------------------------------
   Command / My HQ / Draft / Rankings / Trades are permanently one tap
   away in `.bb-bottomnav`. Drawing them AGAIN at the top of the Menu
   sheet pushed the SECONDARY destinations -- Messages, Members,
   Research, League Intelligence, Front Office, Account, Help -- below
   the fold on a 390px screen, which is exactly the "the drawer feels
   like a second page" complaint. The rows still exist in the DOM and
   the desktop rail still renders every one of them; the phone simply
   does not draw the five it already shows at the bottom of the screen.

   THIS RULE IS AT THE END OF hq.css, AND THAT PLACEMENT IS
   LOAD-BEARING. `.bb-navitem { display: flex }` is declared EARLIER in
   this same file at equal specificity, and a media query adds no
   specificity of its own -- so at equal weight SOURCE ORDER decides,
   and the override has to come last. It was written twice before this
   (in `layout.css`, which loads first; then earlier in this file) and
   had no effect either time. Both stylesheets and the markup "looked"
   correct every time; only a real headless-browser pass
   (`tests/web/test_draft_weekend_mobile_browser.py`) caught that the
   rows were still on screen.
   ------------------------------------------------------------------- */
@media (max-width: 900px) {
  .bb-navitem--in-bottomnav {
    display: none;
  }

  /* THE SAME MEASUREMENT, ONE ITEM FURTHER DOWN. With the five
     duplicated rows gone, the browser pass showed ACCOUNT -- the last
     group in the sheet -- still sitting past 844px. The remaining cost
     was `.bb-navnote`: a four-line PROSE paragraph explaining the
     Discord companion, sitting between the navigation and the account
     group. It is a caption, not a destination, and on a phone it was
     buying nothing while pushing a real destination off screen.

     REPLACEMENT AFFORDANCE: the Field Terminal group's own LABEL stays
     visible immediately above it, and the same explanation is on the
     Help page. Nothing navigable is hidden -- that group has no web
     route to link to in the first place (see `NAV_GROUPS`). */
  .bb-navnote {
    display: none;
  }
}


/* =====================================================================
   20. WHOLE-SITE CAMPAIGN, PACK 1 (2026-09) -- HQ SHELL REFINEMENT
   =====================================================================
   The first pack of the whole-site Blackbird Intelligence HQ campaign.
   Everything here is SHARED-SYSTEM layout: the context bar's one-row
   discipline, the page-header contract's rail and context line, the
   section-head step, the nav's compact Field Terminal note, the intel
   drawer head, and the typography foundation the new self-hosted faces
   need. Paint retunes for the same pack live in `identity.css`
   (annotated "PACK 1 (2026-09)" in place). No page template changed
   its own markup; no reading, order or route changed.
   ================================================================== */

/* --- 20.1 TYPOGRAPHY FOUNDATION ------------------------------------
   Inter for UI, JetBrains Mono for every data value. Numbers in a
   column must line up, so tabular figures are the default on every
   numeric role, not something each board opts into. Headings balance
   their line breaks (a two-line title splits evenly instead of leaving
   one orphaned word). */
body {
  text-rendering: optimizeLegibility;
}
h1, h2, h3 {
  text-wrap: balance;
}
.bb-mono,
.bb-num,
.bb-rank,
.bb-tile__value,
.bb-fact__value,
.bb-evidence__value,
.bb-herostat__value {
  font-variant-numeric: tabular-nums;
}
.bb-table tbody td {
  font-variant-numeric: tabular-nums;
}
/* Rankings-family boards (Rankings / Available Players / Cheat Sheet):
   a player's name never wraps on a desktop board -- a wrapped name
   doubles the row height and halves how many rows a scan covers. Wide
   data still scrolls inside `.bb-table-wrap`; the draft room's own
   boards are deliberately NOT included (their certified layout is the
   benchmark this campaign measures against, not a target). */
@media (min-width: 901px) {
  .bb-table--rankings .bb-cell-player {
    white-space: nowrap;
  }
}

/* --- 20.2 CONTEXT BAR: ONE ROW -------------------------------------
   The bar is its own size container so its controls answer to the
   bar's OWN width (which depends on whether the intel rail is docked),
   not to the viewport. Under ~1040px of bar the two sync verbs keep
   their icon and `aria-label` and drop their visible text; under
   ~960px the Season fact yields (league name and format stay). Both
   thresholds are ABOVE the 900px phone tier on purpose: they are a
   desktop/tablet fit rule, and the phone tier has its own two-row
   contract below. */
.bb-contextbar {
  container-type: inline-size;
  container-name: bb-contextbar;
  gap: var(--bb-space-2) var(--bb-space-3);
}
.bb-contextbar__break {
  display: none;
}
.bb-ctxsync {
  justify-content: center;
}
.bb-ctxsync__label {
  white-space: nowrap;
}
@container bb-contextbar (max-width: 1040px) {
  .bb-ctxsync__label {
    display: none;
  }
  .bb-ctxsync {
    min-width: 36px;
    padding-inline: var(--bb-space-2);
  }
}
@container bb-contextbar (max-width: 960px) {
  .bb-fact--season {
    display: none;
  }
}
/* The league name is the one fact allowed to be long; it truncates
   before it wraps the bar. */
.bb-ctxbtn .bb-fact__value {
  max-width: 22ch;
}

/* --- 20.3 PAGE HEADER CONTRACT -------------------------------------
   eyebrow / title / subject / context / rail. The rail is the page's
   primary actions, right of the title on desktop. The context line is
   a mono fact ("Redraft - 1QB - Board recent") for pages whose reading
   is scoped to a league/format -- one line, never a second badge row. */
.bb-pagehead__rail {
  align-self: center;
  margin-left: auto;
  flex: 0 1 auto;
}
.bb-pagehead__context {
  margin: var(--bb-space-2) 0 0;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  letter-spacing: 0.04em;
  color: var(--bb-text-tertiary);
}
.bb-pagehead__subject {
  max-width: 70ch;
}

/* --- 20.4 SECTION HEAD: ITS OWN STEP -------------------------------
   A section head is now visibly a DIFFERENT thing from a card caption:
   a size between the page title and a card title, and a hairline rule
   that spans the section, so a page reads as title > section > panel
   > label rather than as three near-equal weights. */
.bb-sectionhead {
  align-items: flex-end;
  padding-bottom: var(--bb-space-2);
  border-bottom: 1px solid var(--bb-border-subtle);
  margin-bottom: var(--bb-space-4);
}
.bb-sectionhead__title {
  font-size: var(--bb-fs-section-head);
  line-height: var(--bb-leading-tight);
}

/* --- 20.5 NAV: THE FIELD TERMINAL NOTE, COLLAPSED -------------------
   The Discord companion's explanation used to sit in the rail as a
   five-line paragraph between two navigation groups. It is now a
   closed details element: the label stays visible and reachable, the
   prose costs no rail height until asked for. Same words, same place. */
.bb-navnote {
  padding: 0 var(--bb-space-3);
  margin: 0;
}
.bb-navnote > summary {
  display: flex;
  align-items: center;
  gap: var(--bb-space-2);
  min-height: 28px;
  list-style: none;
  cursor: pointer;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.05em;
  color: var(--bb-text-secondary);
}
.bb-navnote > summary::-webkit-details-marker {
  display: none;
}
.bb-navnote > summary::after {
  content: "\25B8";
  margin-left: auto;
  color: var(--bb-text-tertiary);
}
.bb-navnote[open] > summary::after {
  content: "\25BE";
}
.bb-navnote__body {
  margin: var(--bb-space-1) 0 var(--bb-space-2);
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  line-height: var(--bb-leading-body);
}

/* --- 20.6 INTEL DRAWER HEAD ----------------------------------------
   The evidence rail opens with the mark and a stamp, ruled off from
   the readings beneath it -- the same head language as the nav foot. */
.bb-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bb-space-2);
  margin-bottom: var(--bb-space-4);
  padding-bottom: var(--bb-space-2);
  border-bottom: 1px solid var(--bb-border-subtle);
}
.bb-drawer__title {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-drawer__title .bb-mark {
  width: 14px;
  height: 14px;
  color: var(--bb-accent);
}

/* --- 20.7 TOPBAR ICON CONTROLS -------------------------------------
   The hamburger, drawer toggle and close are stroke icons now, not
   text glyphs (a text glyph renders in whatever the platform's fallback
   font happens to be). Sized to the icon button's own box. */
.bb-btn--icon svg {
  display: block;
  width: 18px;
  height: 18px;
}
.bb-topbar__right .bb-btn--ghost {
  color: var(--bb-text-secondary);
}

/* --- 20.8 PHONE TIER -----------------------------------------------
   Two rows of context, never three: [League + freshness] over
   [draft state + format + sync + import]. The break element is what
   makes the second row start where it should regardless of how long
   the league name is. */
@media (max-width: 900px) {
  .bb-contextbar {
    gap: var(--bb-space-2);
  }
  .bb-contextbar__break {
    display: block;
    flex-basis: 100%;
    height: 0;
  }
  .bb-contextbar__group {
    flex: 1 1 auto;
  }
  .bb-contextbar__group .bb-ctxbtn {
    max-width: 100%;
  }
  .bb-ctxbtn .bb-fact__value {
    max-width: 20ch;
  }
  /* The freshness pill sits BESIDE the League fact on a phone, so its
     own "League" subject word is a duplicate of the label 8px to its
     left; the pill (RECENT / STALE + age + tooltip) stays whole.
     Documented in `tests/web/test_ui_contract_sweep.py`. */
  .bb-contextbar .bb-freshgroup__subject {
    display: none;
  }
  /* Row two: draft state + format stamp on the left, the two sync verbs
     pushed to the right edge whether or not a stamp is present. */
  .bb-contextbar > .bb-ctxsync,
  .bb-contextbar > form {
    margin-left: auto;
  }
  .bb-contextbar > .bb-ctxsync + form {
    margin-left: 0;
  }
  .bb-pagehead__rail {
    flex-basis: 100%;
    margin-left: 0;
    align-self: auto;
  }
  .bb-sectionhead {
    margin-bottom: var(--bb-space-3);
  }
}


/* =====================================================================
   21. WHOLE-SITE CAMPAIGN, PACK 2 (2026-09) -- COMMAND CENTER /
       MY BLACKBIRD / MY TEAM, TO THE APPROVED MOCK
   =====================================================================
   The first page-specific application of the Pack 1 system, measured
   against ONE selected Command Center mock. Its grammar, in order:

     hero      title block left, Power Rank ring right, ~150px tall
     strip     ONE bordered instrument cluster of label/value/sub cells
               separated by hairlines -- never six floating cards
     rail      the Direction stops on one thin line
     priority  category-tinted cards: category, headline, why, one CTA
     modules   3-across panels, each a mono caps title + a "View →"
     drawer    a narrow, useful intel rail: facts, trending, actions

   Spacing rhythm is 12px between bands and modules, 16px inside a
   panel, 18px inside a strip cell. Type: display title 44px/800 caps,
   strip values 24px/700 mono, module titles 11px mono caps, body 13px.
   Graphite dominates; purple marks Blackbird's own layer, the current
   direction stop and the primary action; blue is instrumentation.
   Every value here is one the route already published.
   ================================================================== */

/* --- 21.1 THE BACKGROUND-MARK SEAM ----------------------------------
   The mock's faint insignia behind the hero and the rail. Reads the
   one `--bb-brand-mark` token (tokens.css) so the chosen logo swaps in
   once. Opacity stays under 0.05: atmosphere behind data. */
.bb-watermark {
  position: relative;
  overflow: hidden;
}
.bb-watermark::before {
  content: "";
  position: absolute;
  right: 2%;
  top: -22%;
  width: min(360px, 44%);
  aspect-ratio: 128 / 112;
  background-image: var(--bb-brand-mark);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: right top;
  opacity: 0.045;
  pointer-events: none;
  z-index: 0;
}
.bb-watermark > * {
  position: relative;
  z-index: 1;
}
.bb-icard--primary::before {
  background-image: var(--bb-brand-mark);
}

/* --- 21.2 PAGE FRAME ----------------------------------------------- */
.bb-cc {
  display: flex;
  flex-direction: column;
  gap: var(--bb-space-3);
}

/* --- 21.3 HERO ------------------------------------------------------
   GRAND REIMAGINATION, PHASE 1 (2026-09): the Command-Center-only hero
   (`.bb-cc__hero`, `__herotext`, `__eyebrow`, `__title`, `__sub`,
   `__ring`, `__ringlabel`) was retired in favour of the SHARED page
   identity band `.bb-hero` -- section 23 below -- which every flagship
   page (Command Center, Draft Ops, Mock Draft, and the seven Phase 2
   pages) now composes from. Nothing else in this section changed. */

/* --- 21.4 THE INSTRUMENT STRIP -------------------------------------
   One cluster, hairline-divided cells. `data-tone` colours only the
   small marker dot; the numeral stays primary text. */
.bb-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
  overflow: hidden;
}
.bb-strip__cell {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  min-width: 0;
  padding: var(--bb-space-3) 18px;
  border-right: 1px solid var(--bb-border-subtle);
  color: inherit;
  text-decoration: none;
}
.bb-strip__cell:last-child {
  border-right: 0;
}
a.bb-strip__cell:hover {
  background: var(--bb-purple-wash);
  text-decoration: none;
}
.bb-strip__label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
  white-space: nowrap;
}
.bb-strip__label::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--bb-accent-data);
}
.bb-strip__cell[data-tone="positive"] .bb-strip__label::before { background: var(--bb-positive); }
.bb-strip__cell[data-tone="negative"] .bb-strip__label::before { background: var(--bb-negative); }
.bb-strip__cell[data-tone="caution"]  .bb-strip__label::before { background: var(--bb-caution); }
.bb-strip__cell[data-tone="violet"]   .bb-strip__label::before { background: var(--bb-purple-bright); }
.bb-strip__value {
  font-family: var(--bb-font-numeric);
  font-size: 1.5rem;
  font-weight: var(--bb-fw-bold);
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--bb-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bb-strip__value small {
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-medium);
  color: var(--bb-text-tertiary);
}
.bb-strip__value--word {
  font-family: var(--bb-font-ui);
  font-size: 1.125rem;
  white-space: normal;
  line-height: 1.2;
}
.bb-strip__cell[data-tone="positive"] .bb-strip__value--word { color: var(--bb-positive); }
.bb-strip__cell[data-tone="negative"] .bb-strip__value--word { color: var(--bb-negative); }
.bb-strip__sub {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  line-height: var(--bb-leading-tight);
}
/* Metric tiles rendered by `ui.metric` (My Blackbird cards, My Team)
   adopt the strip grammar when their grid carries this class: same
   words, same tooltips, one cluster instead of five outlined boxes. */
.bb-strip--tiles.bb-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  gap: 0;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
  overflow: hidden;
}
.bb-strip--tiles .bb-tile,
.bb-strip--tiles .bb-tile--lead {
  border: 0;
  border-right: 1px solid var(--bb-border-subtle);
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  padding: var(--bb-space-3) 16px;
  gap: 3px;
  justify-content: flex-start;
}
.bb-strip--tiles .bb-tile:last-child {
  border-right: 0;
}
.bb-strip--tiles .bb-tile__label {
  font-family: var(--bb-font-mono);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
}
.bb-strip--tiles .bb-tile__value,
.bb-strip--tiles .bb-tile--lead .bb-tile__value {
  font-size: 1.4rem;
  line-height: 1.12;
  text-shadow: none;
  overflow-wrap: break-word;
}
.bb-strip--tiles .bb-tile--unavailable .bb-tile__value {
  font-size: 1.125rem;
}
.bb-strip--tiles .bb-tile__sub {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}

/* --- 21.5 THE DIRECTION RAIL --------------------------------------- */
.bb-dirrail {
  display: flex;
  align-items: center;
  gap: var(--bb-space-5);
  padding: 8px 18px 10px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
}
.bb-dirrail__label {
  flex: none;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-dirrail .bb-dirband {
  flex: 1 1 auto;
  min-width: 0;
  padding-top: 10px;
}
.bb-dirrail .bb-dirband::before {
  top: 14px;
}
.bb-dirrail .bb-dirband__dot {
  border-color: var(--bb-surface-card);
}
.bb-dirrail .bb-dirband__stop.is-current .bb-dirband__dot {
  background: var(--bb-purple-bright);
  box-shadow: 0 0 0 4px rgb(var(--bb-purple-rgb) / 0.22), 0 0 12px rgb(var(--bb-purple-rgb) / 0.7);
}
.bb-dirrail .bb-dirband__stop.is-current .bb-dirband__label {
  color: var(--bb-purple-bright);
}

/* --- 21.6 SECTION LABELS AND MODULE PANELS -------------------------
   The mock has no large in-page headings: a band is named by a mono
   caps label with an optional "View all →" at the far right. */
.bb-cc__sectionhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bb-space-2);
  margin: 4px 0 8px;
}
.bb-cc__sectiontitle {
  /* typography (was mono/uppercase): UI Uniformity Pack 06, hq.css
     §37.2 -- now the shared section-title role. */
  margin: 0;
}
.bb-cc__sectionnote {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-cc__sectionlink {
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-purple-bright);
  text-decoration: none;
  white-space: nowrap;
}
.bb-cc__sectionlink:hover {
  text-decoration: underline;
}
.bb-modgrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--bb-space-3);
  align-items: start;
}
.bb-modgrid--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.bb-modstack {
  display: flex;
  flex-direction: column;
  gap: var(--bb-space-3);
  min-width: 0;
}
.bb-mod {
  /* box (padding/border/radius/background): UI Uniformity Pack 06,
     hq.css §37.7. */
  min-width: 0;
}
.bb-mod__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bb-space-2);
  margin-bottom: 10px;
}
.bb-mod__title {
  /* typography (font/tracking/case/colour): UI Uniformity Pack 06,
     hq.css §37.1 -- this is the module-eyebrow role, not a section
     title. */
  margin: 0;
  flex: none;
  white-space: nowrap;
}
.bb-mod__link {
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-purple-bright);
  text-decoration: none;
  white-space: nowrap;
}
.bb-mod__link:hover {
  text-decoration: underline;
}
.bb-mod__meta {
  min-width: 0;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  text-align: right;
  line-height: 1.2;
}
.bb-mod__sub {
  /* typography: UI Uniformity Pack 06, hq.css §37.1. */
  margin: 12px 0 6px;
}
.bb-mod__sub:first-child {
  margin-top: 0;
}
.bb-mod .bb-evidence__row {
  padding: 5px 0;
  font-size: var(--bb-fs-sm);
}
.bb-mod .bb-listrow {
  padding: 6px 0;
}
.bb-mod .bb-listrow__sub {
  font-size: var(--bb-fs-micro);
}
.bb-mod .bb-state {
  padding: var(--bb-space-3);
}
.bb-mod .bb-actions {
  margin-top: 10px;
}
.bb-mod .bb-actions .bb-btn {
  min-height: 30px;
  padding: 4px 10px;
  font-size: var(--bb-fs-micro);
}
.bb-mod__posture {
  margin: 0;
  font-size: var(--bb-fs-md);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
}
.bb-mod__counts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 6px;
}
.bb-mod__count {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 8px;
  border: 1px solid var(--bb-border-subtle);
  border-radius: var(--bb-radius-md);
  background: var(--bb-bg-elevated);
}
.bb-mod__count b {
  font-family: var(--bb-font-numeric);
  font-size: var(--bb-fs-lg);
  font-weight: var(--bb-fw-bold);
  line-height: 1;
  color: var(--bb-text-primary);
}
.bb-mod__count span {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-mod__posrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bb-space-2);
  padding: 4px 0;
  font-size: var(--bb-fs-sm);
}
.bb-mod__quiet {
  margin: 0;
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-secondary);
  line-height: var(--bb-leading-body);
}
.bb-mod__foot {
  margin: 10px 0 0;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  line-height: var(--bb-leading-body);
}

/* --- 21.7 PRIORITY CARDS ------------------------------------------- */
.bb-priogrid {
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}
.bb-prio {
  --prio: var(--bb-purple-bright);
  --prio-rgb: var(--bb-purple-rgb);
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  border: 1px solid rgb(var(--prio-rgb) / 0.35);
  border-radius: 10px;
  background-color: var(--bb-surface-card);
  background-image: linear-gradient(180deg, rgb(var(--prio-rgb) / 0.10), transparent 62%);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--bb-transition-fast), background-color var(--bb-transition-fast);
}
.bb-prio:hover,
.bb-prio:focus-visible {
  border-color: rgb(var(--prio-rgb) / 0.7);
  text-decoration: none;
}
/* One modifier per `category_css` word the route can emit: negative /
   positive / caution / info, and `muted` -- which on a priority card is
   Blackbird's own layer (TRADE / LEAGUE), so it takes the purple. */
.bb-prio--muted    { --prio: var(--bb-purple-bright); --prio-rgb: var(--bb-purple-rgb); }
.bb-prio--negative { --prio: var(--bb-negative); --prio-rgb: var(--bb-negative-rgb); }
.bb-prio--positive { --prio: var(--bb-positive); --prio-rgb: var(--bb-positive-rgb); }
.bb-prio--caution  { --prio: var(--bb-caution);  --prio-rgb: var(--bb-caution-rgb); }
.bb-prio--info     { --prio: var(--bb-accent-data); --prio-rgb: var(--bb-data-rgb); }
.bb-prio__cat {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--prio);
}
.bb-prio__cat::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: var(--prio);
}
.bb-prio__headline {
  font-size: var(--bb-fs-base);
  font-weight: var(--bb-fw-semibold);
  line-height: 1.3;
  color: var(--bb-text-primary);
}
.bb-prio__why {
  margin: 0;
  flex: 1;
  font-size: var(--bb-fs-sm);
  line-height: 1.45;
  color: var(--bb-text-secondary);
}
.bb-prio__cta {
  margin-top: 4px;
  padding: 7px 10px;
  border: 1px solid rgb(var(--prio-rgb) / 0.45);
  border-radius: 6px;
  background: rgb(var(--prio-rgb) / 0.08);
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-semibold);
  text-align: center;
  color: var(--prio);
}
.bb-prio:hover .bb-prio__cta {
  background: rgb(var(--prio-rgb) / 0.16);
}

/* --- 21.8 THE INTEL RAIL ------------------------------------------- */
.bb-railact {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bb-space-2);
  margin-bottom: 6px;
  padding: 8px 10px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-bg-elevated);
  color: var(--bb-text-primary);
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-medium);
  text-decoration: none;
}
.bb-railact::after {
  content: "\203A";
  color: var(--bb-text-tertiary);
  font-size: var(--bb-fs-md);
  line-height: 1;
}
.bb-railact:hover {
  border-color: var(--bb-purple-border);
  text-decoration: none;
}
.bb-railrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bb-space-2);
  padding: 5px 0;
  border-bottom: 1px solid var(--bb-border-subtle);
  font-size: var(--bb-fs-sm);
}
.bb-railrow:last-child {
  border-bottom: 0;
}
.bb-railrow a {
  color: var(--bb-text-primary);
  font-weight: var(--bb-fw-medium);
}
.bb-railrow__sub {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-drawer .bb-evidence__value {
  font-size: var(--bb-fs-sm);
}

/* --- 21.9 MY BLACKBIRD: FRANCHISE DOSSIERS ------------------------- */
.bb-leaguegrid {
  gap: var(--bb-space-3);
}
.bb-leaguecard {
  padding: 14px 16px 14px;
}
.bb-leaguecard__head {
  margin-bottom: 10px;
}
.bb-leaguecard__name {
  font-size: var(--bb-fs-lg);
  font-weight: var(--bb-fw-bold);
  letter-spacing: -0.01em;
}
.bb-leaguecard__kicker {
  /* typography + purple colour exception: UI Uniformity Pack 06,
     hq.css §37.1. */
  display: block;
  margin-bottom: 2px;
}
.bb-leaguecard__sub {
  font-family: var(--bb-font-mono);
  letter-spacing: 0.02em;
}
.bb-leaguecard__need {
  margin-top: 10px;
  padding: 8px 12px;
  border-left-width: 3px;
}
.bb-leaguecard__need p {
  margin: 2px 0 0;
  font-size: var(--bb-fs-sm);
}
/* PRE-RESET FABLE PASS: a lineup-fill need is the one "biggest need" a
   manager must act on before kickoff, so it earns a chip and a handoff.
   Negative tone carried by the WORD ("Lineup issue") plus the hue, never
   the hue alone. Everything else on the block is unchanged. */
/* .bb-leaguecard__need--lineup's accent (was border-left-color + a
   gradient background, which needed a border-left-STYLE this rule never
   declared to actually render): UI Uniformity Pack 06, hq.css §37.9 now
   gives it the same inset left-rail `.bb-rows__item[data-tone]` uses. */
.bb-leaguecard__attention {
  /* box (padding/radius/font/border/background): UI Uniformity Pack 06,
     hq.css §37.5 (shared `.bb-badge` box). Tone kept explicit here
     (this chip is always negative, never a data-driven tone). */
  gap: 6px;
  margin: 4px 0 2px;
  border-color: var(--bb-negative-border);
  background: var(--bb-negative-bg);
  text-transform: uppercase;
  color: var(--bb-negative);
}
.bb-leaguecard__attention-word::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--bb-negative);
  vertical-align: 1px;
}
.bb-leaguecard__attention-sep { color: var(--bb-text-tertiary); }
.bb-leaguecard__attention .bb-pos { text-transform: none; letter-spacing: 0; }
.bb-leaguecard__attention-link {
  display: inline-block;
  margin-top: 4px;
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-purple-bright);
  text-decoration: none;
}
.bb-leaguecard__attention-link:hover,
.bb-leaguecard__attention-link:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
/* LINEUP ATTENTION -- the per-slot alert list (empty starter, unavailable/
   review/unverified starter, and up to MAX_QUALITY_UPGRADES_PER_ROSTER
   healthy-vs-healthy quality upgrades). Compact by design: a small label,
   a badge-led list, no new card shell. The list is a plain flex column
   with no fixed height, so it grows to fit 1-3 upgrade items without
   clipping or overlap. Reuses the existing `.bb-badge--*` tone system
   verbatim. */
.bb-lineup-attention {
  margin-top: 10px;
  margin-bottom: 4px;
}
.bb-lineup-attention__list {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.bb-lineup-attention__item {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: var(--bb-fs-sm);
}
.bb-lineup-attention__text {
  min-width: 0;
}
.bb-lineup-attention__sub {
  display: block;
  color: var(--bb-text-tertiary);
  font-size: var(--bb-fs-micro);
}
.bb-lineup-attention__sub a {
  color: var(--bb-purple-bright);
  text-decoration: none;
}
.bb-lineup-attention__sub a:hover,
.bb-lineup-attention__sub a:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
.bb-leaguecard__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 4px;
  margin-top: 12px;
}
.bb-leaguecard__actions .bb-btn--primary {
  margin-right: 8px;
}
.bb-leaguecard__actions .bb-actions {
  display: contents;
}
.bb-leaguecard__actions .bb-actions .bb-btn:not(.bb-btn--primary) {
  min-height: 28px;
  padding: 3px 9px;
  border-color: transparent;
  background: transparent;
  box-shadow: none;
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-medium);
  color: var(--bb-text-secondary);
}
.bb-leaguecard__actions .bb-actions .bb-btn:not(.bb-btn--primary):hover {
  color: var(--bb-purple-bright);
  background: var(--bb-purple-wash);
}
/* LIVE FANTASY MATCHUP A2 -- state-aware prominence hooks only (Step 5).
   No new color system: PREGAME/UNAVAILABLE never render this block at
   all (see the template), LIVE reuses the SAME positive/pulse treatment
   `.bb-gd-card.is-live` already uses, FINAL reuses the SAME quieted
   secondary-text treatment `.bb-gd-card.is-final` already uses. */
.bb-livematchup {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  margin: 8px 0;
  padding: 6px 10px;
  border-radius: var(--bb-radius-sm);
  border: 1px solid var(--bb-border-subtle, rgba(255, 255, 255, 0.08));
}
.bb-livematchup__badge {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.bb-livematchup__badge::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 6px;
  border-radius: 50%;
  vertical-align: 1px;
}
.bb-livematchup__score {
  font-family: var(--bb-font-mono);
  font-weight: var(--bb-fw-bold);
  font-size: var(--bb-fs-md);
}
.bb-livematchup__result,
.bb-livematchup__counts,
.bb-livematchup__pending {
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-secondary);
}
.bb-livematchup__fresh {
  flex-basis: 100%;
}
/* LIVE -- prominent, the SAME positive pulse `.bb-gd-card.is-live::before`
   already establishes for a genuinely in-progress game. */
.bb-livematchup--live {
  border-color: var(--bb-positive);
  background: linear-gradient(90deg, rgb(var(--bb-positive-rgb) / 0.08), transparent 80%);
}
.bb-livematchup--live .bb-livematchup__badge {
  color: var(--bb-positive);
}
.bb-livematchup--live .bb-livematchup__badge::before {
  background: var(--bb-positive);
  box-shadow: 0 0 8px rgb(var(--bb-positive-rgb) / 0.45);
}
/* FINAL -- persistent result, no longer urgent. The SAME quieted
   secondary-text treatment `.bb-gd-card.is-final` already establishes. */
.bb-livematchup--final {
  color: var(--bb-text-secondary);
}
.bb-livematchup--final .bb-livematchup__badge {
  color: var(--bb-text-tertiary);
}
/* PREGAME -- quiet/informational, no badge dot at all. Class-based (not
   parent-state-based) so BOTH the compact card and the Team Intelligence
   panel share the identical "quiet" treatment. */
.bb-livematchup--pregame .bb-livematchup__badge,
.bb-livematchup__badge--quiet {
  color: var(--bb-text-tertiary);
}
.bb-livematchup--pregame .bb-livematchup__badge::before,
.bb-livematchup__badge--quiet::before {
  display: none;
}
.bb-mb-cards__refresh {
  display: block;
  margin-bottom: 6px;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
/* Team Intelligence's own Live Matchup panel -- a plain `.bb-icard`, so
   ONLY a `data-state`-keyed left-border accent is added (never the
   compact card's flex layout above); the badge/color rules are shared. */
.bb-ti-livematchup[data-state="LIVE"] {
  border-left: 3px solid var(--bb-positive);
}
.bb-ti-livematchup[data-state="LIVE"] .bb-livematchup__badge {
  color: var(--bb-positive);
}
.bb-ti-livematchup[data-state="LIVE"] .bb-livematchup__badge::before {
  background: var(--bb-positive);
  box-shadow: 0 0 8px rgb(var(--bb-positive-rgb) / 0.45);
}
.bb-ti-livematchup[data-state="FINAL"] .bb-livematchup__badge {
  color: var(--bb-text-tertiary);
}
.bb-leaguecard .bb-strip--tiles.bb-metrics {
  margin-top: 4px;
}

/* --- 21.10 MY TEAM: TEAM HERO + DEPTH CHART ------------------------ */
.bb-ti-hero {
  padding: 16px 20px;
}
.bb-ti-hero .bb-sectionhead {
  border-bottom: 0;
  padding-bottom: 0;
  margin-bottom: 10px;
}
.bb-ti-hero .bb-sectionhead__title {
  font-size: 1.75rem;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.bb-ti-hero .bb-sectionhead__title::before {
  display: none;
}
.bb-ti-hero .bb-herostat {
  gap: 0;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
  overflow: hidden;
  margin-top: 12px;
}
.bb-ti-hero .bb-herostat__panel {
  border: 0;
  border-right: 1px solid var(--bb-border-subtle);
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  padding: 10px 16px;
}
.bb-ti-hero .bb-herostat__panel:last-child {
  border-right: 0;
}
.bb-ti-hero .bb-herostat__panel::before {
  display: none;
}
.bb-ti-hero .bb-herostat__value {
  font-size: 1.5rem;
}
.bb-ti-hero .bb-herostat__value--word {
  font-size: 1.125rem;
}
.bb-ti-hero .bb-dirrail {
  margin-top: 12px;
}
.bb-ti-hero .bb-icard__foot {
  margin-top: 12px;
}
.bb-roster-group__head {
  margin-bottom: 6px;
  padding-bottom: 4px;
  border-bottom: 0;
}
.bb-roster-group__head .bb-sectionhead__title {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bb-text-secondary);
}
.bb-roster-group__head .bb-sectionhead__title::before {
  width: 10px;
  height: 2px;
}
.bb-table--roster tbody td {
  padding-top: 6px;
  padding-bottom: 6px;
}
.bb-table--roster .bb-cell-player a {
  font-weight: var(--bb-fw-semibold);
}
.bb-table--roster td:first-child {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --- 21.11 PHONE (390 x 844) --------------------------------------- */
@media (max-width: 900px) {
  .bb-cc__hero {
    flex-direction: column;
    align-items: stretch;
    gap: var(--bb-space-3);
    min-height: 0;
    padding: var(--bb-space-4);
  }
  .bb-cc__title {
    font-size: 1.9rem;
  }
  .bb-cc__sub {
    font-size: var(--bb-fs-sm);
  }
  .bb-cc__ring {
    flex-direction: row;
    justify-content: center;
    gap: 14px;
    padding: 6px 0 0;
    border-top: 1px solid var(--bb-border-subtle);
    border-radius: 0;
  }
  .bb-strip {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .bb-strip__cell {
    padding: 10px 12px;
  }
  .bb-strip__cell:nth-child(3n) {
    border-right: 0;
  }
  .bb-strip__cell:nth-child(n + 4) {
    border-top: 1px solid var(--bb-border-subtle);
  }
  /* Exactly four cells read as 2x2, never three plus a stranded one. */
  .bb-strip:has(> :nth-child(4)):not(:has(> :nth-child(5))) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .bb-strip:has(> :nth-child(4)):not(:has(> :nth-child(5))) .bb-strip__cell:nth-child(3n) {
    border-right: 1px solid var(--bb-border-subtle);
  }
  .bb-strip:has(> :nth-child(4)):not(:has(> :nth-child(5))) .bb-strip__cell:nth-child(2n) {
    border-right: 0;
  }
  .bb-strip:has(> :nth-child(4)):not(:has(> :nth-child(5))) .bb-strip__cell:nth-child(n + 3) {
    border-top: 1px solid var(--bb-border-subtle);
  }
  .bb-strip__label {
    white-space: normal;
    line-height: 1.15;
    font-size: 0.625rem;
  }
  .bb-strip__value {
    font-size: 1.25rem;
  }
  .bb-strip__value--word {
    font-size: var(--bb-fs-base);
  }
  .bb-strip--tiles.bb-metrics {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .bb-strip--tiles .bb-tile {
    padding: 10px 12px;
  }
  .bb-strip--tiles .bb-tile:nth-child(3n) {
    border-right: 0;
  }
  .bb-strip--tiles .bb-tile:nth-child(n + 4) {
    border-top: 1px solid var(--bb-border-subtle);
  }
  .bb-strip--tiles .bb-tile__value,
  .bb-strip--tiles .bb-tile--lead .bb-tile__value {
    font-size: 1.05rem;
    overflow-wrap: break-word;
  }
  .bb-dirrail {
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    padding: 10px 14px;
  }
  .bb-modgrid,
  .bb-modgrid--2 {
    grid-template-columns: 1fr;
  }
  .bb-mod__counts {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  .bb-ti-hero {
    padding: 14px;
  }
  .bb-ti-hero .bb-sectionhead__title {
    font-size: 1.4rem;
  }
  .bb-ti-hero .bb-herostat {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .bb-ti-hero .bb-herostat__panel:nth-child(3n) {
    border-right: 0;
  }
  .bb-ti-hero .bb-herostat__panel:nth-child(n + 4) {
    border-top: 1px solid var(--bb-border-subtle);
  }
  .bb-ti-hero .bb-herostat__value {
    font-size: 1.25rem;
  }
}
@media (min-width: 901px) and (max-width: 1200px) {
  .bb-modgrid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* =====================================================================
   22. WHOLE-SITE CAMPAIGN, PACK 3 (2026-09) -- TEAM / LEAGUE / PLAYER
       INTELLIGENCE, TO THE APPROVED MOCK
   =====================================================================
   Pack 2 gave Command Center, My Blackbird and My Team the mock's
   grammar. This pack extends the SAME grammar (strip cells, hairline
   panels, mono caps labels, restrained purple) to the three pages that
   round out the canonical hierarchy COMMAND CENTER -> LEAGUE -> TEAM ->
   PLAYER -- Team Intelligence's depth chart, League Intelligence's own
   hero/landscape, and Player Intelligence's decision snapshot and
   valuation stack. Every rule below is presentation over a reading that
   already existed; nothing here adds a service call or a computed value.
   ================================================================== */

/* --- 22.1 TEAM: THE DEPTH CHART, NOT A DATABASE TABLE ---------------
   Starters get a purple rule down the row's edge (the same accent
   `is-you` marks a team with, elsewhere) so the eye separates who is on
   the field from who is behind them without a wall of colour. IR/Taxi
   sit slightly recessed and their group heading takes the caution tone
   -- the same "this needs attention" register the rest of the product
   already uses for injury/roster-status language, never a second one. */
.bb-roster-group[data-bb-roster-group="starter"] .bb-table--roster tbody tr td:first-child,
.bb-roster-group[data-bb-roster-group="starter"] .bb-rostercard {
  box-shadow: inset 3px 0 0 var(--bb-accent);
}
.bb-roster-group[data-bb-roster-group="ir"] .bb-table--roster,
.bb-roster-group[data-bb-roster-group="taxi"] .bb-table--roster,
.bb-roster-group[data-bb-roster-group="ir"] .bb-rostercards,
.bb-roster-group[data-bb-roster-group="taxi"] .bb-rostercards {
  opacity: 0.88;
}
.bb-roster-group[data-bb-roster-group="ir"] .bb-roster-group__head .bb-sectionhead__title,
.bb-roster-group[data-bb-roster-group="taxi"] .bb-roster-group__head .bb-sectionhead__title {
  color: var(--bb-caution);
}
.bb-roster-group[data-bb-roster-group="ir"] .bb-roster-group__head .bb-sectionhead__title::before,
.bb-roster-group[data-bb-roster-group="taxi"] .bb-roster-group__head .bb-sectionhead__title::before {
  background: var(--bb-caution);
}
.bb-roster-group[data-bb-roster-group="picks"] .bb-roster-group__head .bb-sectionhead__title {
  color: var(--bb-purple-bright);
}

/* --- 22.2 TEAM: MOBILE DEPTH CHART -----------------------------------
   `.bb-rostercards` renders the SAME rows `.bb-rostertable` already
   drew, as slot-first cards -- never the desktop table squeezed into a
   390px viewport. Exactly one of the two is visible at a time. */
.bb-rostercards {
  display: none;
}
.bb-rostercard {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  margin-bottom: 6px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
  color: inherit;
  text-decoration: none;
}
.bb-rostercard:last-child {
  margin-bottom: 0;
}
.bb-rostercard:hover,
.bb-rostercard:focus-visible {
  border-color: var(--bb-purple-border);
  text-decoration: none;
}
.bb-rostercard__slot {
  flex: none;
  font-size: var(--bb-fs-micro);
}
.bb-rostercard__main {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.bb-rostercard__name {
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bb-rostercard__meta {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bb-rostercard__value {
  flex: none;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-secondary);
}
.bb-rostercard__status {
  grid-column: 1 / -1;
  justify-self: start;
  margin-top: 2px;
}
@media (max-width: 900px) {
  .bb-rostertable {
    display: none;
  }
  .bb-rostercards {
    display: block;
  }
}

/* --- 22.3 LEAGUE: THE LANDSCAPE'S OWN TEAM highlight -----------------
   `is-you` already tints the row and its border with the SAME purple
   `--bb-accent` token this page's team-badges use; the edge rule makes
   it legible at a glance in a dense 12-row table, not just on hover. */
.bb-landscape__row.is-you {
  box-shadow: inset 3px 0 0 var(--bb-accent);
}
.bb-landscape__row.is-you .bb-landscape__team a {
  font-weight: var(--bb-fw-semibold);
}

/* --- 22.4 PLAYER: THE DECISION SNAPSHOT WINS THE PAGE ----------------
   The one panel below the hero that gets the hero's own signal
   treatment -- a faint purple top hairline and a slightly raised
   surface -- so "what does Blackbird think right now" is visually the
   loudest thing on the page after identity, exactly once. */
.bb-icard--decision {
  position: relative;
  border-color: var(--bb-purple-border);
  background-color: var(--bb-surface-raised);
}
.bb-icard--decision::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--bb-grad-signal);
  opacity: 0.75;
  border-radius: var(--bb-radius-lg) var(--bb-radius-lg) 0 0;
}

/* --- 22.5 PLAYER: WHOSE READING IS WHOSE -----------------------------
   Three cells, three owners: Blackbird's own value (purple, the
   product's own layer), the external market's (blue, instrumentation --
   `--bb-accent-data` is the same blue Rank Edge's tooltip vocabulary
   already assigns to "instrumentation"), and Blackbird's disagreement
   with the market (the SAME ultraviolet `--bb-proprietary` the BB//
   badge beneath this stack already uses). MAV never gets the purple. */
.bb-valstack__cell[data-role="value"] {
  border-top: 2px solid var(--bb-purple-bright);
}
.bb-valstack__cell[data-role="value"] .bb-valstack__label {
  color: var(--bb-purple-bright);
}
.bb-valstack__cell[data-role="market"] {
  border-top: 2px solid var(--bb-accent-data);
}
.bb-valstack__cell[data-role="edge"] {
  border-top: 2px solid var(--bb-proprietary);
}
.bb-valstack__cell[data-role="edge"] .bb-valstack__label {
  color: var(--bb-proprietary);
}

/* --- 22.6 PHONE (390 x 844) ------------------------------------------ */
@media (max-width: 900px) {
  .bb-rostercard {
    grid-template-columns: auto 1fr;
  }
  .bb-rostercard__value {
    grid-column: 1 / -1;
    justify-content: flex-start;
    margin-top: 2px;
  }
}

/* =====================================================================
   23. GRAND REIMAGINATION, PHASE 1 (2026-09) -- THE LAYOUT PRIMITIVES
   =====================================================================
   WHY THIS SECTION EXISTS. The owner used the Pack 1-3 production build
   in a real live draft and judged it "still basic": too much unused
   desktop canvas, not close enough to the approved mocks. The cause was
   COMPOSITION, not colour -- flagship pages were a thin header, then a
   single column of equal-weight cards, so a 1920px monitor showed a
   1560px stack of small rectangles with air around them.

   These primitives are the shared grammar every flagship page composes
   from, so the remaining seven mock pages inherit a system rather than
   a pile of per-page overrides:

     .bb-hero      page identity band: eyebrow / display title / tagline /
                   description on the left, ONE focal instrument on the
                   right, technical texture + the brand mark behind it.
     .bb-field     the intelligence field: a 12-track grid the page's
                   modules span (.bb-span-N). Asymmetry is allowed and
                   encouraged -- a dominant surface beside a rail.
     .bb-mod--*    surface ROLES for the module panel Pack 2 introduced:
                   --lead (the dominant surface, raised), --flat (an
                   information field with a rule, not a card), --inset
                   (a recessed reference area). Elevation means
                   something again, because most modules no longer
                   have it.
     .bb-brief     a full-width, two-column dense list band.
     .bb-posture   a distinctive Blackbird reading given real weight
                   (Team Direction is the first consumer).
     .bb-closing   the once-per-page brand insignia that closes a
                   flagship page or its rail.
     .bb-rail-callout  the rail's bottom-pinned "#1 priority" restatement.

   Every value drawn by a consumer is one its route already published.
   Nothing here computes, ranks or guesses.
   ================================================================== */

/* --- 23.1 THE HERO BAND ------------------------------------------- */
.bb-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--bb-space-4) var(--bb-space-6);
  padding: 30px 32px 28px;
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-lg);
  background-color: var(--bb-surface-raised);
  background-image:
      linear-gradient(90deg, rgb(var(--bb-purple-rgb) / 0.14), rgb(var(--bb-purple-rgb) / 0.04) 46%, transparent 72%),
      var(--bb-texture-hatch),
      var(--bb-texture-grid),
      var(--bb-face-raised);
  background-size: auto, auto, var(--bb-texture-grid-size), auto;
  box-shadow: var(--bb-elev-2);
}
/* The signature wing across the top, the mark behind the right edge. */
.bb-hero::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  background: var(--bb-wing);
  z-index: 1;
}
.bb-hero.bb-watermark::before {
  right: 26%;
  top: -30%;
  width: min(420px, 38%);
  opacity: 0.055;
}
.bb-hero--compact {
  padding: 18px 24px 16px;
}
.bb-hero__main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.bb-hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bb-purple-bright);
}
.bb-hero__eyebrow::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--bb-purple-bright);
  box-shadow: 0 0 8px rgb(var(--bb-purple-rgb) / 0.6);
}
.bb-hero__title {
  margin: 0;
  font-size: clamp(2.25rem, 4vw, 3.5rem);
  /* weight/letter-spacing: UI Uniformity Pack 06, hq.css §37.3 -- the
     one surviving declaration for both. */
  text-transform: uppercase;
  line-height: 0.98;
  color: var(--bb-text-primary);
}
.bb-hero--compact .bb-hero__title {
  font-size: clamp(1.75rem, 2.8vw, 2.5rem);
}
.bb-hero__tagline {
  margin: 2px 0 0;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bb-text-secondary);
}
.bb-hero__desc {
  margin: 0;
  font-size: var(--bb-fs-base);
  line-height: 1.45;
  color: var(--bb-text-secondary);
  max-width: 66ch;
}
.bb-hero__status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  margin-top: 6px;
}
.bb-hero__status .bb-chip,
.bb-hero__status .bb-badge,
.bb-hero__status .bb-fresh {
  font-size: var(--bb-fs-micro);
}
.bb-hero__aside {
  display: flex;
  align-items: center;
  gap: var(--bb-space-5);
  min-width: 0;
}
/* A big labelled readout beside the focal instrument. */
.bb-hero__stat {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  padding-right: var(--bb-space-5);
  border-right: 1px solid var(--bb-border);
}
.bb-hero__stat:last-child {
  border-right: 0;
  padding-right: 0;
}
.bb-hero__stat-label {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
  white-space: nowrap;
}
.bb-hero__stat-value {
  font-family: var(--bb-font-numeric);
  font-size: 1.75rem;
  font-weight: var(--bb-fw-bold);
  line-height: 1.05;
  color: var(--bb-text-primary);
  white-space: nowrap;
}
.bb-hero__stat-value--word {
  font-family: var(--bb-font-ui);
  font-size: 1.35rem;
  letter-spacing: -0.01em;
  white-space: normal;
}
.bb-hero__stat-value small {
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-medium);
  color: var(--bb-text-tertiary);
}
.bb-hero__stat-sub {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  max-width: 24ch;
  line-height: 1.3;
}
.bb-hero__stat[data-tone="positive"] .bb-hero__stat-value--word { color: var(--bb-positive); }
.bb-hero__stat[data-tone="negative"] .bb-hero__stat-value--word { color: var(--bb-negative); }
.bb-hero__stat[data-tone="violet"] .bb-hero__stat-value--word { color: var(--bb-purple-bright); }
/* The focal ring: the mock's single hero instrument. */
.bb-hero__ring {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 8px 18px 6px;
  text-decoration: none;
  color: inherit;
  border-radius: var(--bb-radius-lg);
}
.bb-hero__ring:hover {
  text-decoration: none;
  background: var(--bb-purple-wash);
}
.bb-hero__ringlabel {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-purple-bright);
}
.bb-hero__ringsub {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  text-align: center;
  max-width: 18ch;
  line-height: 1.3;
}
.bb-hero__ring .bb-ring__track {
  stroke: var(--bb-border-strong);
  stroke-width: 7;
}
.bb-hero__ring .bb-ring__fill {
  stroke-width: 7;
  filter: drop-shadow(0 0 8px rgb(var(--bb-purple-rgb) / 0.6));
}
.bb-hero__ring .bb-ring__rank {
  font-size: 34px;
}
.bb-hero__ring .bb-ring__of {
  font-size: 11px;
}
.bb-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bb-space-2);
}

/* --- 23.2 THE INTELLIGENCE FIELD ------------------------------------
   Twelve tracks. A module says how much of the field it owns; the
   page decides the shape. */
.bb-field {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--bb-space-3);
  align-items: stretch;
}
.bb-field--tight {
  gap: var(--bb-space-2);
}
/* Records and dossiers: rows top-align, so a short lead surface beside a
   tall reference column never stretches into a hollow card. */
.bb-field--top {
  align-items: start;
}
.bb-span-3  { grid-column: span 3; }
.bb-span-4  { grid-column: span 4; }
.bb-span-5  { grid-column: span 5; }
.bb-span-6  { grid-column: span 6; }
.bb-span-7  { grid-column: span 7; }
.bb-span-8  { grid-column: span 8; }
.bb-span-9  { grid-column: span 9; }
.bb-span-12 { grid-column: span 12; }
.bb-field > * {
  min-width: 0;
}
.bb-field > .bb-mod {
  margin: 0;
}
/* A stacked column fills its row: the last module in the stack takes
   the remaining height, so a short stack beside a tall lead surface
   never leaves a void under it. */
.bb-field > .bb-modstack {
  height: 100%;
}
.bb-field > .bb-modstack > .bb-mod:last-child {
  flex: 1 1 auto;
}

/* --- 23.3 SURFACE ROLES FOR MODULES ---------------------------------
   The Pack 2 module (`.bb-mod`) stays the default panel. These three
   roles are what stop a page from reading as card soup: one dominant
   raised surface, flat information fields with a rule, and recessed
   reference areas -- so the eye is told what matters. */
.bb-mod--lead {
  border-color: var(--bb-purple-border);
  background-color: var(--bb-surface-raised);
  background-image: var(--bb-face-intel), var(--bb-face-raised);
  box-shadow: var(--bb-elev-2);
  position: relative;
}
.bb-mod--lead::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  background: var(--bb-wing);
  border-radius: var(--bb-radius-lg) var(--bb-radius-lg) 0 0;
}
.bb-mod--flat {
  border: 0;
  border-top: 1px solid var(--bb-border);
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  padding-left: 0;
  padding-right: 0;
}
.bb-mod--inset {
  background-color: var(--bb-bg-elevated);
  background-image: none;
  border-color: var(--bb-border-subtle);
  box-shadow: none;
}
.bb-mod__body {
  min-width: 0;
}
/* Two dense columns of rows inside one module, for reading sets the
   mock draws as compact tables (movers, watch items). */
.bb-mod__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--bb-space-4);
}
.bb-mod__cols > * {
  min-width: 0;
}

/* --- 23.4 THE POSTURE READING ---------------------------------------
   Team Direction is a distinctive Blackbird reading and is drawn like
   one: a big word with the direction's own explanation lines under it,
   not a sentence in a card. */
.bb-posture {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px 12px;
  border-radius: var(--bb-radius-md);
  border: 1px solid var(--bb-purple-border);
  background: linear-gradient(90deg, var(--bb-purple-soft), transparent 70%), var(--bb-bg-elevated);
}
.bb-posture__eyebrow {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-purple-bright);
}
.bb-posture__word {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.05;
  color: var(--bb-text-primary);
}
.bb-posture__lines {
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.bb-posture__lines li {
  position: relative;
  padding-left: 14px;
  font-size: var(--bb-fs-sm);
  line-height: 1.4;
  color: var(--bb-text-secondary);
}
.bb-posture__lines li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 8px;
  height: 2px;
  background: var(--bb-purple);
}

/* --- 23.5 THE BRIEF BAND --------------------------------------------
   Everything Blackbird is tracking, as two dense columns of rows in
   one flat band: a reading field, not a disclosure. */
.bb-brief__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--bb-space-6);
}
.bb-brief__grid > * {
  min-width: 0;
}
.bb-brief__grid .bb-listrow {
  border-bottom: 1px solid var(--bb-border-subtle);
}

/* --- 23.6 THE CLOSING INSIGNIA --------------------------------------
   Once per flagship page (or its rail): the mark, the product's own
   standing claim, nothing theatrical. */
.bb-closing {
  display: flex;
  align-items: center;
  gap: var(--bb-space-3);
  padding: 12px 16px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background:
      linear-gradient(90deg, rgb(var(--bb-purple-rgb) / 0.10), transparent 55%),
      var(--bb-texture-hatch),
      var(--bb-bg-elevated);
  color: var(--bb-text-tertiary);
}
.bb-closing .bb-mark {
  width: 22px;
  height: 20px;
  color: var(--bb-text-secondary);
  flex: none;
}
.bb-closing__word {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bb-text-secondary);
}
.bb-closing__note {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  margin-left: auto;
  text-align: right;
}

/* --- 23.7 THE RAIL CALLOUT ------------------------------------------
   The rail's bottom-pinned restatement of the #1 priority, with its own
   action. Category-tinted through the same `--prio` custom properties
   the priority cards use (set by the `.bb-prio--X` word). */
.bb-rail-callout {
  --prio: var(--bb-purple-bright);
  --prio-rgb: var(--bb-purple-rgb);
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px;
  border: 1px solid rgb(var(--prio-rgb) / 0.4);
  border-radius: var(--bb-radius-md);
  background: linear-gradient(180deg, rgb(var(--prio-rgb) / 0.12), transparent 70%), var(--bb-surface-card);
}
.bb-rail-callout__cat {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--prio);
}
.bb-rail-callout__headline {
  margin: 0;
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-semibold);
  line-height: 1.35;
  color: var(--bb-text-primary);
}
.bb-rail-callout__cta {
  margin-top: 2px;
  padding: 6px 10px;
  border: 1px solid rgb(var(--prio-rgb) / 0.45);
  border-radius: 6px;
  background: rgb(var(--prio-rgb) / 0.10);
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-semibold);
  text-align: center;
  color: var(--prio);
  text-decoration: none;
}
.bb-rail-callout__cta:hover {
  text-decoration: none;
  background: rgb(var(--prio-rgb) / 0.18);
}
.bb-rail-callout.bb-prio--negative { --prio: var(--bb-negative); --prio-rgb: var(--bb-negative-rgb); }
.bb-rail-callout.bb-prio--positive { --prio: var(--bb-positive); --prio-rgb: var(--bb-positive-rgb); }
.bb-rail-callout.bb-prio--caution  { --prio: var(--bb-caution);  --prio-rgb: var(--bb-caution-rgb); }
.bb-rail-callout.bb-prio--info     { --prio: var(--bb-accent-data); --prio-rgb: var(--bb-data-rgb); }

/* --- 23.8 COMMAND CENTER COMPOSITION TUNING -------------------------
   The instrument strip and priority row tile edge to edge; a strip
   cell is a real instrument now (taller, its numeral louder). */
.bb-strip--wide .bb-strip__cell {
  padding: 16px 20px 15px;
}
.bb-strip--wide .bb-strip__value {
  font-size: 1.7rem;
}
.bb-priogrid--wide {
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
.bb-cc__headline {
  margin: 0 0 8px;
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-secondary);
}

/* --- 23.9 RESPONSIVE -------------------------------------------------
   Tablet (<=1200): the field halves; the hero stacks its instrument.
   Phone (<=900): everything is one column, in source order. */
@media (max-width: 1200px) {
  .bb-span-3, .bb-span-4, .bb-span-5 { grid-column: span 6; }
  .bb-span-7, .bb-span-8, .bb-span-9 { grid-column: span 12; }
}
@media (max-width: 900px) {
  .bb-hero {
    grid-template-columns: 1fr;
    padding: 18px 16px 16px;
    gap: var(--bb-space-3);
  }
  .bb-hero__aside {
    justify-content: space-between;
    gap: var(--bb-space-3);
  }
  .bb-hero__stat {
    padding-right: var(--bb-space-3);
  }
  .bb-hero__title {
    font-size: 1.9rem;
  }
  .bb-hero.bb-watermark::before {
    right: -6%;
    top: -10%;
    width: 46%;
  }
  .bb-span-3, .bb-span-4, .bb-span-5, .bb-span-6,
  .bb-span-7, .bb-span-8, .bb-span-9 { grid-column: span 12; }
  .bb-brief__grid,
  .bb-mod__cols {
    grid-template-columns: 1fr;
  }
  .bb-closing__note {
    margin-left: 0;
    text-align: left;
  }
  .bb-closing {
    flex-wrap: wrap;
  }
}

/* --- 23.10 THE NAVIGATION HIERARCHY ----------------------------------
   GRAND REIMAGINATION, PHASE 1: the nav is designed, not accumulated.
   Eight destinations carry `flagship` (1-8) in `pages.NAV_GROUPS` and
   render LOUDER -- brighter label, a lit icon, a fuller row -- while
   every support surface reads quieter. Same rows, same hrefs, same
   `aria-current`; only the weight changed. */
.bb-navgroup__label {
  color: var(--bb-text-tertiary);
  letter-spacing: 0.16em;
  padding-top: 2px;
}
.bb-navitem {
  color: var(--bb-text-tertiary);
  font-weight: var(--bb-fw-medium);
}
.bb-navitem .bb-navitem__icon {
  opacity: 0.65;
}
.bb-navitem--flagship {
  color: var(--bb-text-primary);
  font-weight: var(--bb-fw-semibold);
}
.bb-navitem--flagship .bb-navitem__icon {
  opacity: 1;
  color: var(--bb-purple-bright);
}
.bb-navitem--flagship .bb-navitem__label {
  font-size: var(--bb-fs-base);
  letter-spacing: -0.005em;
}
.bb-navitem--flagship .bb-navitem__hint {
  color: var(--bb-text-secondary);
}
.bb-navitem:not(.bb-navitem--flagship) {
  min-height: 34px;
  padding-top: 5px;
  padding-bottom: 5px;
}
.bb-navitem:not(.bb-navitem--flagship) .bb-navitem__hint {
  display: none;
}
.bb-navitem:not(.bb-navitem--flagship):hover .bb-navitem__hint,
.bb-navitem:not(.bb-navitem--flagship):focus-visible .bb-navitem__hint,
.bb-navitem:not(.bb-navitem--flagship).is-active .bb-navitem__hint {
  display: block;
}
.bb-navitem:not(.bb-navitem--flagship):hover,
.bb-navitem:not(.bb-navitem--flagship).is-active {
  color: var(--bb-text-primary);
}
.bb-navitem.is-active {
  color: var(--bb-purple-bright);
}
/* The nav group that holds the loudest destinations gets a hairline
   rule under it so COMMAND reads as the top of the tree. */
.bb-navgroup:first-of-type {
  padding-bottom: var(--bb-space-2);
  border-bottom: 1px solid var(--bb-border-subtle);
}


/* =====================================================================
   24. GRAND REIMAGINATION, PHASE 1B (2026-09) -- THE ENVIRONMENT, BUILT
   =====================================================================
   WHY THIS SECTION EXISTS. Phase 1 recomposed the flagship pages and the
   owner's reaction to the live build was "this still looks like the same
   Blackbird". Measured before this pack, at 2560x1440: a 1720px page
   floating in a 1960px column (120px of black either side), purple on
   under 1.2% of the viewport, a 224px nav that reads as a list of links,
   a 44px context strip of small text controls, and one bordered-card
   grammar for every module. Section 23's PRIMITIVES were right; their
   PRESENTATION was not.

   This section is the STRUCTURAL half of Phase 1B: proportions,
   typography scale, surface roles, and the wide-desktop compositions.
   `identity.css` section 17 is the PAINT half (purple as environment,
   depth, seams, glow) and `draft_room.css` section 13 is the War Room's
   own mode change. Nothing here computes a number, moves a route or
   changes a contract; it is the same readings on a bigger, darker,
   more purple instrument.

   THE FOUR DESKTOP TIERS
     1366  compact workstation   -- everything present, tight rhythm
     1440  standard desktop      -- the reference composition
     1920  expanded command      -- rails widen, brief goes 3-up, hero
                                    grows, modules breathe
     2560  full HQ               -- the nav is a command rail, the intel
                                    drawer a working column, the field
                                    recomposes into three full-width
                                    asymmetric bands, brief 4-up. No
                                    centred cap: the canvas is the page.
   ================================================================== */

/* --- 24.1 THE CANVAS IS THE PAGE ------------------------------------
   The centred cap is retired. The content well fills the column between
   the two rails at every width; what the extra tracks are FOR is decided
   per band below, never left as gutter. */
.bb-page {
  max-width: none;
  margin-inline: 0;
}
.bb-cc {
  gap: var(--bb-space-4);
}
:root {
  --bb-topbar-height: calc(62px + var(--bb-safe-top));
  --bb-contextbar-height: 54px;
}

/* --- 24.2 THE TOP BAR: A COMMAND STRIP, NOT A TITLE BAR -------------- */
.bb-topbar {
  gap: var(--bb-space-5);
  padding-left: calc(var(--bb-space-5) + var(--bb-safe-left));
  padding-right: calc(var(--bb-space-5) + var(--bb-safe-right));
}
.bb-brand {
  gap: 12px;
}
.bb-mark--lockup {
  width: 40px;
  height: 35px;
}
.bb-wordmark {
  font-size: 1.2rem;
  letter-spacing: 0.14em;
  line-height: 1;
}
.bb-wordmark small {
  margin-top: 4px;
  letter-spacing: 0.24em;
}
.bb-search__trigger {
  min-width: 300px;
}

/* --- 24.3 THE NAV: A COMMAND RAIL ------------------------------------
   Groups are ruled sections with a full-width seam; flagship rows are
   taller, carry a lit icon tile and a mono index; support rows stay
   compact. The active row is a filled purple band with a rail. */
.bb-nav {
  padding: 22px 14px 28px;
}
.bb-navgroup {
  margin-bottom: 20px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--bb-border-subtle);
}
.bb-navgroup:first-of-type {
  padding-bottom: 14px;
}
.bb-navgroup:last-of-type {
  border-bottom: 0;
}
.bb-navgroup__label {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 10px 10px;
  letter-spacing: 0.22em;
}
.bb-navgroup__label::before {
  width: 14px;
  margin-right: 0;
}
.bb-navgroup__label::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--bb-border-subtle);
}
.bb-navgroup__items {
  gap: 3px;
}
.bb-navitem {
  gap: 12px;
  padding: 7px 12px 7px 12px;
  border-left-width: 3px;
  border-radius: 9px;
}
.bb-navitem--flagship {
  padding: 9px 12px 9px 12px;
}
.bb-navitem--flagship .bb-navitem__icon {
  width: 30px;
  height: 30px;
  padding: 6px;
  border-radius: 8px;
  border: 1px solid transparent;
}
.bb-navitem--flagship .bb-navitem__label {
  font-size: 0.9375rem;
  letter-spacing: -0.01em;
}
.bb-navitem--flagship .bb-navitem__hint {
  margin-top: 1px;
}
/* The mono index on a flagship row -- read from the row's own
   `data-bb-flagship` (1-8). Decoration; the label carries the meaning. */
.bb-navitem--flagship::after {
  content: "0" attr(data-bb-flagship);
  margin-left: auto;
  flex: none;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.1em;
}
.bb-navitem:not(.bb-navitem--flagship) {
  padding-left: 14px;
}
.bb-navitem:not(.bb-navitem--flagship) .bb-navitem__icon {
  width: 16px;
  height: 16px;
}
.bb-nav__foot {
  margin-top: var(--bb-space-4);
  padding: 12px 14px;
  border: 1px solid transparent;
  border-radius: 9px;
  letter-spacing: 0.14em;
}
.bb-nav__foot .bb-mark {
  width: 18px;
  height: 16px;
}

/* --- 24.4 THE CONTEXT BAR: AN INSTRUMENT BAND ------------------------
   The league switcher becomes a lit instrument; the facts beside it are
   mono readouts behind a vertical seam; the format stamp is a filled
   control; the sync verbs are a grouped action cluster at the right. */
.bb-contextbar {
  padding: 8px 20px;
  gap: var(--bb-space-2) 12px;
}
.bb-contextbar__group .bb-ctxbtn {
  min-height: 38px;
  padding: 4px 14px 4px 14px;
  gap: 12px;
  border-radius: 9px;
}
.bb-fact__label {
  font-family: var(--bb-font-mono);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.2em;
  font-size: 0.625rem;
}
.bb-ctxbtn .bb-fact__value {
  font-size: var(--bb-fs-base);
  letter-spacing: -0.01em;
  max-width: 22ch;
}
.bb-fact--secondary {
  padding-left: 14px;
  border-left: 2px solid transparent;
}
.bb-fact--secondary .bb-fact__value {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-sm);
  letter-spacing: 0.01em;
}
.bb-contextbar__divider {
  width: 2px;
  margin: 0;
  border-radius: 2px;
}
.bb-ctxbtn--accent {
  min-height: 38px;
  padding: 0 12px;
  border-radius: 9px;
  font-size: var(--bb-fs-sm);
  letter-spacing: 0.08em;
  font-weight: var(--bb-fw-bold);
}
.bb-ctxsync {
  min-height: 38px;
  padding-inline: 12px;
  border-radius: 9px;
}
.bb-contextbar .bb-freshgroup {
  align-self: center;
}
/* In a narrow bar (both rails docked at 1440) the readouts truncate
   sooner so the bar stays ONE row -- the same container the §20.2
   label/season rules already answer to. */
@container bb-contextbar (max-width: 1040px) {
  .bb-ctxbtn .bb-fact__value {
    max-width: 14ch;
  }
  .bb-fact--secondary .bb-fact__value {
    max-width: 13ch;
  }
  .bb-fact--secondary {
    padding-left: 10px;
  }
  .bb-contextbar {
    gap: var(--bb-space-2) 8px;
    padding-inline: 12px;
  }
  .bb-contextbar__group .bb-ctxbtn {
    padding-inline: 10px;
    gap: 8px;
  }
  .bb-ctxbtn--accent {
    padding: 0 10px;
  }
}

/* --- 24.5 THE HERO: CINEMATIC, NOT A HEADER ---------------------------
   Height comes from padding and content, never a floor: the base is the
   1366 compact tier, and every wider tier adds padding. */
.bb-hero {
  /* A WRAPPING band, not a two-column grid: the title block keeps a
     real minimum width and the focal instrument drops beneath it when
     the hero is narrow (a 1440 desktop with both rails docked), instead
     of squeezing the title into a 300px column. */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  padding: 32px 36px 30px;
  gap: var(--bb-space-5) var(--bb-space-6);
  border-radius: 16px;
}
.bb-hero__main {
  flex: 1 1 440px;
}
.bb-hero__aside {
  flex: 0 1 auto;
  margin-left: auto;
}
/* The compact hero's aside is two small readouts; it stays beside the
   title on a 1366 workstation. */
.bb-hero--compact .bb-hero__main {
  flex-basis: 340px;
}
.bb-hero::after {
  height: 3px;
}
.bb-hero.bb-watermark::before {
  right: 22%;
  top: -36%;
  width: min(600px, 44%);
}
.bb-hero__main {
  gap: 8px;
}
.bb-hero__eyebrow {
  align-items: flex-start;
  letter-spacing: 0.24em;
  line-height: 1.4;
}
.bb-hero__eyebrow::before {
  flex: none;
  margin-top: 4px;
}
.bb-hero__title {
  font-size: var(--bb-fs-display-xl);
  /* weight/letter-spacing: UI Uniformity Pack 06, hq.css §37.3. */
  line-height: 0.94;
}
.bb-hero__tagline {
  margin-top: 6px;
  font-size: 0.875rem;
  letter-spacing: 0.16em;
}
.bb-hero__desc {
  font-size: var(--bb-fs-md);
  max-width: 62ch;
}
.bb-hero__status {
  margin-top: 10px;
  gap: 8px 10px;
}
.bb-hero__status .bb-chip {
  padding: 4px 11px;
  border-radius: 6px;
}
.bb-hero__aside {
  gap: var(--bb-space-5);
}
.bb-hero__stat {
  gap: 5px;
  padding: 6px 24px 6px 0;
}
.bb-hero__stat-label {
  letter-spacing: 0.22em;
}
.bb-hero__stat-value {
  font-size: 2.25rem;
}
.bb-hero__stat-value--word {
  font-size: 1.75rem;
  font-weight: 800;
}
.bb-hero__stat-sub {
  font-size: var(--bb-fs-sm);
  max-width: 26ch;
}
.bb-hero__ring {
  padding: 10px 16px 8px;
  gap: 6px;
  border-radius: 16px;
}
/* The ring scales with the tier (the SVG carries a viewBox, so its
   text scales with it): 148 compact, 172 standard, 190 at full HQ. */
.bb-hero__ring .bb-ring {
  width: 148px;
  height: 148px;
}
.bb-hero__ringlabel {
  letter-spacing: 0.24em;
}
.bb-hero__ring .bb-ring__track {
  stroke-width: 8;
}
.bb-hero__ring .bb-ring__fill {
  stroke-width: 8;
}
.bb-hero__ring .bb-ring__rank {
  font-size: 42px;
}
.bb-hero__ring .bb-ring__of {
  font-size: 12px;
}
/* The flagship hero (Command Center): the tallest band in the product. */
.bb-hero--cc {
  padding-top: 40px;
  padding-bottom: 36px;
}
/* The compact hero (Draft Ops, Mock Draft) keeps its height discipline
   but takes the same type scale. */
.bb-hero--compact {
  padding: 26px 32px 24px;
}
.bb-hero--compact .bb-hero__title {
  font-size: clamp(2rem, 3.2vw, 2.9rem);
}

/* --- 24.6 THE INSTRUMENT: STRIP + DIRECTION RAIL AS ONE BODY ---------- */
.bb-instrument {
  display: flex;
  flex-direction: column;
}
.bb-instrument .bb-strip {
  border-radius: 14px 14px 0 0;
  border-bottom: 0;
}
.bb-instrument .bb-dirrail {
  border-radius: 0 0 14px 14px;
}
.bb-strip {
  border-radius: 14px;
}
.bb-strip--wide .bb-strip__cell {
  padding: 22px 28px 20px;
  gap: 6px;
}
.bb-strip__label {
  letter-spacing: 0.2em;
}
.bb-strip__label::before {
  width: 7px;
  height: 7px;
}
.bb-strip--wide .bb-strip__value {
  font-size: var(--bb-fs-instrument);
  letter-spacing: -0.02em;
}
.bb-strip--wide .bb-strip__value--word {
  font-size: 1.4rem;
}
.bb-strip__sub {
  font-size: var(--bb-fs-sm);
}
.bb-dirrail {
  padding: 14px 28px 18px;
  gap: var(--bb-space-6);
}
.bb-dirrail__label {
  letter-spacing: 0.22em;
}
.bb-dirrail .bb-dirband {
  padding-top: 12px;
}
.bb-dirrail .bb-dirband::before {
  top: 16px;
  height: 2px;
}
.bb-dirrail .bb-dirband__dot {
  width: 11px;
  height: 11px;
}
.bb-dirrail .bb-dirband__stop.is-current .bb-dirband__dot {
  width: 15px;
  height: 15px;
}
.bb-dirrail .bb-dirband__label {
  font-size: var(--bb-fs-sm);
  letter-spacing: 0;
}
.bb-dirrail .bb-dirband__stop.is-current .bb-dirband__label {
  font-weight: var(--bb-fw-bold);
}

/* --- 24.7 THE TACTICAL ZONE: TOP PRIORITIES ---------------------------
   The page's tactical centre is a FRAMED band, not a heading over loose
   cards. Its first item, when there are three or more, becomes a
   full-width lead strip (category / headline / why / action in one
   row); the rest tile beneath it, each with its own category rail. */
.bb-tactical {
  position: relative;
  overflow: hidden;
  padding: 20px 24px 22px;
  border: 1px solid transparent;
  border-radius: 16px;
}
.bb-tactical .bb-cc__sectionhead {
  margin: 0 0 14px;
}
.bb-cc__sectionhead {
  margin: 6px 0 12px;
}
.bb-cc__sectiontitle {
  /* typography (mono/wing dash retired): UI Uniformity Pack 06, hq.css
     §37.2. */
  display: inline-flex;
  align-items: center;
}
.bb-cc__sectionlink {
  font-size: var(--bb-fs-sm);
}
.bb-cc__headline {
  margin: 0 0 14px;
  font-size: var(--bb-fs-base);
}
.bb-priogrid,
.bb-priogrid--wide {
  gap: 12px;
}
.bb-priogrid--wide {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.bb-prio {
  gap: 10px;
  padding: 18px 20px 18px 22px;
  border-radius: 12px;
}
.bb-prio__cat {
  align-self: flex-start;
  padding: 3px 9px 3px 8px;
  border-radius: 5px;
}
.bb-prio__headline {
  font-size: var(--bb-fs-md);
  line-height: 1.25;
}
.bb-prio__cta {
  padding: 9px 12px;
  border-radius: 8px;
}
/* The lead strip: only when there are 3+ items, so a lone or paired
   priority never becomes a giant. */
.bb-priogrid--wide > .bb-prio:first-child:nth-last-child(n+3) {
  grid-column: 1 / -1;
  flex-direction: row;
  align-items: center;
  gap: 28px;
  padding: 22px 28px 22px 30px;
}
.bb-priogrid--wide > .bb-prio:first-child:nth-last-child(n+3) .bb-prio__cat {
  flex: none;
}
.bb-priogrid--wide > .bb-prio:first-child:nth-last-child(n+3) .bb-prio__headline {
  flex: 0 1 38%;
  font-size: var(--bb-fs-lg);
  line-height: 1.2;
}
.bb-priogrid--wide > .bb-prio:first-child:nth-last-child(n+3) .bb-prio__why {
  flex: 1 1 auto;
}
.bb-priogrid--wide > .bb-prio:first-child:nth-last-child(n+3) .bb-prio__cta {
  flex: none;
  margin-top: 0;
  padding: 11px 18px;
}

/* --- 24.8 THE FIELD AND ITS SURFACE ROLES ------------------------------
   Four roles, visibly different in structure as well as paint:
     .bb-mod           a flat intelligence ZONE (thin frame, seam on top)
     .bb-mod--lead     the raised dominant surface
     .bb-mod--inset    a recessed reference area
     .bb-mod--flat     a full-width information band with a rule
   Module titles carry a wing tick; evidence rows read as an embedded
   table; count tiles read as small instruments. */
.bb-field {
  gap: var(--bb-space-4);
}
.bb-mod {
  padding: 18px 20px 20px;
  border-radius: 12px;
}
.bb-mod--lead {
  padding: 22px 24px 24px;
  border-radius: 14px;
}
.bb-mod--flat {
  padding-top: 18px;
  border-top-width: 2px;
}
.bb-mod__head {
  margin-bottom: 12px;
}
.bb-mod__title {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: var(--bb-fs-label);
  letter-spacing: 0.2em;
}
.bb-mod__title::before {
  content: "";
  width: 14px;
  height: 3px;
  border-radius: 2px;
  background: var(--bb-wing-short);
}
.bb-mod__sub {
  margin: 16px 0 8px;
  letter-spacing: 0.18em;
}
.bb-mod .bb-evidence__row {
  padding: 7px 10px;
  margin: 0 -10px;
  border-radius: 6px;
}
.bb-mod .bb-listrow {
  padding: 8px 10px;
  margin: 0 -10px;
  border-radius: 6px;
}
.bb-mod__count {
  padding: 10px 10px 8px;
  gap: 4px;
  border-radius: 8px;
}
.bb-mod__count b {
  font-size: var(--bb-fs-xl);
}
.bb-posture {
  margin: 2px 0 8px;
  padding: 16px 18px 18px 20px;
  gap: 6px;
  border-radius: 10px;
}
.bb-posture__word {
  font-size: 1.85rem;
  line-height: 1.02;
}
.bb-posture__lines {
  margin-top: 8px;
  gap: 5px;
}
.bb-brief__grid {
  gap: 0 var(--bb-space-7);
}
.bb-brief__grid .bb-listrow {
  padding: 10px 10px;
}
.bb-closing {
  padding: 18px 24px;
  border-radius: 12px;
}
.bb-closing .bb-mark {
  width: 28px;
  height: 25px;
}
.bb-closing__word {
  font-size: var(--bb-fs-sm);
  letter-spacing: 0.2em;
}

/* --- 24.9 THE INTEL DRAWER: A WORKING INTELLIGENCE COLUMN -------------
   A flex column so its closing insignia pins to the foot of the rail
   when the page's sections are short (the mock's bottom-pinned card);
   with long content it simply follows them. Off-canvas tiers keep their
   own `position`/`inset` from `layout.css` -- only the inner flow is a
   column. */
.bb-drawer {
  display: flex;
  flex-direction: column;
  padding: 22px 22px 32px;
}
.bb-drawer > * {
  flex: none;
}
/* THE RAILS STAY WITH YOU. At the docked tiers both rails are sticky,
   viewport-height columns that scroll on their own -- the mock's
   persistent sidebar and intel rail -- so the closing insignia pins to
   the foot of the SCREEN and a long page never scrolls the navigation
   away. The off-canvas tiers (<=1200 drawer, <=900 nav) keep their own
   `position: fixed` sheets from `layout.css`; this is `min-width` only. */
@media (min-width: 1201px) {
  .bb-nav,
  .bb-drawer {
    position: sticky;
    top: var(--bb-topbar-height);
    align-self: start;
    height: calc(100vh - var(--bb-topbar-height));
    height: calc(100dvh - var(--bb-topbar-height));
    overflow-y: auto;
    scrollbar-width: thin;
  }
}
.bb-closing--rail {
  margin-top: auto;
  flex-wrap: wrap;
  gap: 8px 12px;
  padding: 14px 16px;
}
.bb-closing--rail .bb-closing__note {
  flex-basis: 100%;
  margin-left: 0;
  text-align: left;
}
.bb-drawer__head {
  margin-bottom: 22px;
  padding-bottom: 14px;
}
.bb-drawer__title {
  gap: 9px;
  letter-spacing: 0.22em;
}
.bb-drawer__title .bb-mark {
  width: 18px;
  height: 16px;
}
.bb-drawer__section {
  margin-bottom: 26px;
}
.bb-drawer__section-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
  letter-spacing: 0.22em;
}
.bb-drawer__section-title::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--bb-border-subtle);
}
/* Quick actions as ONE segmented band, not five floating buttons. */
.bb-drawer .bb-railact {
  margin: 0;
  padding: 11px 14px;
  border-radius: 0;
}
.bb-drawer .bb-railact + .bb-railact {
  border-top: 0;
}
.bb-drawer .bb-railact:first-of-type {
  border-radius: 9px 9px 0 0;
}
.bb-drawer .bb-railact:last-of-type {
  border-radius: 0 0 9px 9px;
}
.bb-rail-callout {
  padding: 16px 18px 18px;
  gap: 8px;
  border-radius: 10px;
}
.bb-rail-callout__headline {
  font-size: var(--bb-fs-base);
}
.bb-rail-callout__cta {
  padding: 9px 12px;
  border-radius: 8px;
}
.bb-drawer .bb-evidence__row {
  padding: 7px 0;
}

/* --- 24.10 DRAFT OPS PICKER: A COMPOSED FIELD, NOT ONE CARD ------------
   The eligible-draft list leads (raised, wide); the rehearsal path and
   the board surfaces that work without a draft take the support
   column. Same links, same rows. */
.bb-dr-pickfield .bb-dr-picker {
  gap: 10px;
}
.bb-dr-pickfield .bb-dr-draftrow {
  padding: 16px 18px 16px 20px;
  border-radius: 10px;
}
.bb-dr-pickfield .bb-dr-draftrow__title {
  font-size: var(--bb-fs-md);
}
.bb-dr-support__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bb-space-3);
  padding: 12px 14px;
  border: 1px solid var(--bb-border);
  border-radius: 9px;
  color: var(--bb-text-primary);
  text-decoration: none;
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-semibold);
}
.bb-dr-support__row + .bb-dr-support__row {
  margin-top: 8px;
}
.bb-dr-support__row:hover {
  text-decoration: none;
}
.bb-dr-support__row::after {
  content: "\2192";
  flex: none;
  color: var(--bb-text-tertiary);
}
.bb-dr-support__note {
  margin: 12px 0 0;
  font-size: var(--bb-fs-sm);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
/* The picker page's lower register: the certification instrument and
   the closing insignia, so the canvas ends on purpose. */
.bb-dr-pickfoot {
  display: flex;
  flex-direction: column;
  gap: var(--bb-space-4);
  margin-top: var(--bb-space-4);
}

/* --- 24.10a THE SHARED PAGE HEAD: THE SAME FAMILY AS THE HERO ----------
   Every page that is NOT a recomposed flagship (Rankings, Trade Desk,
   Team / League / Player Intelligence, Research, Front Office, Messages,
   Members, Archives, Account, Help ...) opens with `.bb-pagehead`. It
   keeps its own job -- a kicker, a title, a subject line, the page's
   actions -- but takes the environment's scale and band treatment so
   the site reads as ONE product: a purple-graphite band, a display-size
   title, the wing along its foot. Paint lives in identity.css §17.14. */
.bb-pagehead {
  padding: 22px 26px 20px;
  margin-bottom: var(--bb-space-5);
  border: 1px solid transparent;
  border-radius: 14px;
  overflow: hidden;
  gap: var(--bb-space-3) var(--bb-space-5);
}
.bb-pagehead::after {
  height: 3px;
}
.bb-pagehead__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  letter-spacing: 0.22em;
}
.bb-pagehead__eyebrow::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: var(--bb-purple-bright);
  box-shadow: 0 0 8px rgb(var(--bb-purple-rgb) / 0.6);
}
.bb-pagehead__title {
  font-size: clamp(1.9rem, 2.4vw, 2.75rem);
  font-weight: 800;
  letter-spacing: -0.015em;
  line-height: 1.02;
}
.bb-pagehead__subject {
  margin-top: 8px;
  font-size: var(--bb-fs-base);
  max-width: 70ch;
}
.bb-pagehead__context {
  margin-top: 10px;
}
/* radius: UI Uniformity Pack 06, hq.css §37.7 -- this literal 12px had
   drifted off the documented Fable radius step; removed. */
@media (min-width: 1900px) {
  .bb-pagehead {
    padding: 28px 32px 26px;
  }
}
@media (max-width: 900px) {
  .bb-pagehead {
    padding: 16px 16px 14px;
    border-radius: 12px;
  }
  .bb-pagehead__title {
    font-size: 1.6rem;
  }
  .bb-pagehead__subject {
    font-size: var(--bb-fs-sm);
  }
}

/* --- 24.10b THE CLOSING FOOTER BAR --------------------------------------
   Slim, full width, once per flagship page, at the very end: brand +
   tagline left, diamond-bulleted micro-labels right. Hidden with the
   rest of the page chrome in War Room mode (`draft_room.css` §13). */
.bb-foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 28px;
  margin-top: var(--bb-space-2);
  padding: 12px 22px;
  border: 1px solid transparent;
  border-radius: 10px;
}
.bb-foot__brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.bb-foot__brand .bb-mark {
  width: 18px;
  height: 16px;
}
.bb-foot__tagline {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.bb-foot__marks {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 18px;
  margin: 0 0 0 auto;
  padding: 0;
  list-style: none;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.bb-foot__marks li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.bb-foot__marks li::before {
  content: "\25C6";
  font-size: 7px;
}

/* --- 24.11 THE FOUR TIERS ----------------------------------------------
   The base rules above ARE the 1366 compact workstation. Each wider
   tier adds to them (min-width steps only -- the codebase's max-width
   tiers are the phone/tablet set and are not extended here). */
.bb-strip--wide .bb-strip__cell {
  padding: 18px 22px 16px;
}
.bb-search__trigger {
  min-width: 220px;
}
/* 1440: the standard intelligence desktop. */
@media (min-width: 1440px) {
  .bb-hero {
    padding: 40px 44px 36px;
    gap: var(--bb-space-5) var(--bb-space-7);
  }
  .bb-hero--cc {
    padding-top: 44px;
    padding-bottom: 40px;
  }
  .bb-hero--compact {
    padding: 28px 36px 26px;
  }
  .bb-hero__ring .bb-ring {
    width: 172px;
    height: 172px;
  }
  .bb-hero__ring {
    padding: 12px 24px 10px;
  }
  .bb-hero__stat {
    padding-right: 32px;
  }
  .bb-hero__aside {
    gap: var(--bb-space-6);
  }
  .bb-strip--wide .bb-strip__cell {
    padding: 22px 28px 20px;
  }
  .bb-search__trigger {
    min-width: 300px;
  }
}
/* 1920: the expanded command center. */
@media (min-width: 1900px) {
  .bb-cc {
    gap: 18px;
  }
  .bb-hero {
    padding: 48px 56px 44px;
  }
  .bb-hero--cc {
    padding-top: 56px;
    padding-bottom: 50px;
  }
  .bb-hero--compact {
    padding: 32px 44px 30px;
  }
  .bb-hero__aside {
    gap: 44px;
  }
  .bb-field {
    gap: 18px;
  }
  .bb-mod {
    padding: 20px 24px 22px;
  }
  .bb-mod--lead {
    padding: 24px 28px 26px;
  }
  .bb-brief__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .bb-strip--wide .bb-strip__cell {
    padding: 26px 32px 24px;
  }
  .bb-strip--wide .bb-strip__value {
    font-size: 2.4rem;
  }
  .bb-tactical {
    padding: 24px 28px 26px;
  }
  .bb-priogrid--wide {
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  }
  .bb-drawer {
    padding: 26px 26px 36px;
  }
  .bb-nav {
    padding: 26px 16px 32px;
  }
  .bb-navitem--flagship {
    padding: 10px 14px;
  }
  .bb-navitem--flagship .bb-navitem__label {
    font-size: 1rem;
  }
  .bb-navitem--flagship .bb-navitem__icon {
    width: 34px;
    height: 34px;
    padding: 7px;
  }
  .bb-search__trigger {
    min-width: 360px;
  }
}
/* 2560: the full HQ. The field is RECOMPOSED -- three full-width
   asymmetric bands instead of the 1920 stack, the brief goes 4-up, the
   hero becomes a true band, and the priorities tile wider. Nothing is
   merely scaled. */
@media (min-width: 2300px) {
  .bb-cc {
    gap: 20px;
  }
  .bb-hero {
    padding: 56px 64px 52px;
    gap: var(--bb-space-6) 72px;
  }
  .bb-hero--cc {
    padding-top: 68px;
    padding-bottom: 62px;
  }
  .bb-hero--compact {
    padding: 36px 48px 34px;
  }
  .bb-hero__desc {
    font-size: var(--bb-fs-lg);
    max-width: 64ch;
  }
  .bb-hero__stat-value {
    font-size: 2.6rem;
  }
  .bb-hero__stat-value--word {
    font-size: 2rem;
  }
  .bb-hero__ring .bb-ring {
    width: 190px;
    height: 190px;
  }
  .bb-field {
    gap: 20px;
  }
  .bb-field--cc > :nth-child(1) { grid-column: span 4; }
  .bb-field--cc > :nth-child(2) { grid-column: span 5; }
  .bb-field--cc > :nth-child(3) { grid-column: span 3; }
  .bb-field--cc > :nth-child(4) { grid-column: span 3; }
  .bb-field--cc > :nth-child(5) { grid-column: span 3; }
  .bb-field--cc > :nth-child(6) { grid-column: span 6; }
  .bb-field--cc > :nth-child(7) { grid-column: span 4; }
  .bb-field--cc > :nth-child(8) { grid-column: span 3; }
  .bb-field--cc > :nth-child(9) { grid-column: span 5; }
  .bb-brief__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  .bb-mod {
    padding: 22px 26px 24px;
  }
  .bb-strip--wide .bb-strip__cell {
    padding: 30px 36px 28px;
  }
  .bb-strip--wide .bb-strip__value {
    font-size: 2.75rem;
  }
  .bb-dirrail {
    padding: 18px 36px 22px;
  }
  .bb-tactical {
    padding: 28px 32px 30px;
  }
  .bb-priogrid--wide {
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  }
  .bb-priogrid--wide > .bb-prio:first-child:nth-last-child(n+3) {
    padding: 26px 34px 26px 36px;
  }
  .bb-drawer {
    padding: 30px 30px 40px;
  }
  .bb-nav {
    padding: 30px 18px 36px;
  }
  .bb-navitem--flagship .bb-navitem__label {
    font-size: 1.0625rem;
  }
  .bb-search__trigger {
    min-width: 420px;
  }
  .bb-dr-pickfield .bb-dr-draftrow {
    padding: 20px 24px;
  }
}

/* --- 24.12 PHONE (390 x 844) -------------------------------------------
   The environment must never cost the phone a row: the hero's cinematic
   padding, the lead-strip priority row and the instrument scale all
   step back down. Nothing new is hidden. */
@media (max-width: 900px) {
  :root {
    --bb-topbar-height: calc(58px + var(--bb-safe-top));
  }
  .bb-page {
    max-width: none;
  }
  .bb-hero,
  .bb-hero--cc,
  .bb-hero--compact {
    padding: 22px 18px 20px;
    border-radius: 12px;
  }
  .bb-hero__title {
    font-size: 2.1rem;
  }
  .bb-hero__desc {
    font-size: var(--bb-fs-base);
  }
  .bb-hero__stat-value {
    font-size: 1.75rem;
  }
  .bb-hero__stat-value--word {
    font-size: 1.35rem;
  }
  /* The aside stacks: the readout as a full-width row over the ring,
     never a squeezed column beside it. */
  .bb-hero__aside {
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--bb-space-3);
  }
  .bb-hero__stat {
    flex: 1 1 100%;
    padding: 4px 0 10px;
    border-right: 0;
    border-bottom: 1px solid var(--bb-border);
  }
  .bb-hero__stat-sub {
    max-width: none;
  }
  .bb-hero__ring {
    margin-inline: auto;
  }
  .bb-wordmark {
    font-size: 0;
  }
  .bb-strip--wide .bb-strip__cell {
    padding: 14px 16px 13px;
  }
  .bb-strip--wide .bb-strip__value {
    font-size: 1.6rem;
  }
  .bb-dirrail {
    padding: 12px 16px 14px;
  }
  .bb-tactical {
    padding: 14px 14px 16px;
    border-radius: 12px;
  }
  .bb-priogrid--wide > .bb-prio:first-child:nth-last-child(n+3) {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    padding: 18px 18px;
  }
  .bb-priogrid--wide > .bb-prio:first-child:nth-last-child(n+3) .bb-prio__headline {
    flex: none;
    font-size: var(--bb-fs-md);
  }
  .bb-mod,
  .bb-mod--lead {
    padding: 16px 16px 18px;
  }
  .bb-posture__word {
    font-size: 1.5rem;
  }
  .bb-contextbar {
    padding: var(--bb-space-2) var(--bb-space-3);
  }
  .bb-contextbar__group .bb-ctxbtn {
    padding: 4px 12px;
  }
  .bb-ctxbtn .bb-fact__value {
    font-size: var(--bb-fs-sm);
  }
  .bb-topbar {
    gap: var(--bb-space-3);
    padding-left: calc(var(--bb-space-3) + var(--bb-safe-left));
    padding-right: calc(var(--bb-space-3) + var(--bb-safe-right));
  }
  .bb-mark--lockup {
    width: 32px;
    height: 28px;
  }
  .bb-search__trigger {
    min-width: 0;
  }
  /* The nav SHEET keeps the desktop rail's language at the phone's
     rhythm: the drawer-owned destinations (Messages, Members, Research,
     League Intelligence, Front Office) must all sit inside a 390x844
     viewport with nothing scrolled -- the DW-1 measurement. */
  .bb-nav {
    padding: 12px 10px 20px;
  }
  .bb-navgroup {
    margin-bottom: 10px;
    padding-bottom: 6px;
  }
  .bb-navgroup:first-of-type {
    padding-bottom: 6px;
  }
  .bb-navgroup__label {
    padding: 0 8px 6px;
  }
  .bb-navgroup__items {
    gap: 1px;
  }
  .bb-navitem,
  .bb-navitem--flagship {
    padding-top: 5px;
    padding-bottom: 5px;
  }
  .bb-navitem--flagship .bb-navitem__icon {
    width: 24px;
    height: 24px;
    padding: 4px;
  }
  .bb-navitem--flagship .bb-navitem__label {
    font-size: var(--bb-fs-sm);
  }
  .bb-nav__foot {
    margin-top: 8px;
    padding: 8px 12px;
  }
  .bb-drawer {
    padding: 18px 16px 28px;
  }
  .bb-closing {
    padding: 14px 16px;
  }
  .bb-foot {
    padding: 12px 14px;
    gap: 8px 16px;
  }
  .bb-foot__marks {
    margin-left: 0;
  }
}


/* =====================================================================
   25. GRAND REIMAGINATION, PHASE 2A (2026-09) -- LEAGUE INTELLIGENCE
   =====================================================================
   The first page-specific recomposition after the Phase 1B environment.
   STRUCTURE ONLY (paint is identity.css section 18). League-specific
   classes (`bb-li-*`) extend the shared grammar so no shared surface
   changes:

     .bb-hero--li       the hero with the league crest + your ring
     .bb-li-shape       the League Shape rail: eight published direction
                        states, a count of teams in each, you marked
     .bb-field--li      the field: the board leads, the rail beside it
     .bb-li-board       the League Landscape board -- one grid, three
                        densities decided by the board's OWN width
                        (container queries), never by hiding a value:
                          wide    10 columns, one line per team
                          mid     7 columns, points and streak stacked
                          narrow  a card per team (the phone)
     .bb-li-power       the Power Board: the same strength rank, in
                        strength order, standings rank beside it
     .bb-li-pos         positional scarcity meters
     .bb-li-matchup     compact matchup rows
   ================================================================== */

/* --- 25.0 THE MODULE HOOKS ----------------------------------------------
   Every League module carries its own name so a later pack can tune one
   without touching the shared `.bb-mod`. They are grid children of the
   field and must never force it wider than its track. */
.bb-li-instrument {
  display: flex;
  flex-direction: column;
}
.bb-li-power,
.bb-li-posture,
.bb-li-pos,
.bb-li-sched,
.bb-li-partners,
.bb-li-bracket,
.bb-li-move,
.bb-li-picks {
  min-width: 0;
}
.bb-li-pos__pos {
  display: flex;
  align-items: center;
}
.bb-li-board__c-dir {
  min-width: 0;
}
.bb-li-board__row--plain {
  cursor: pointer;
}

/* --- 25.1 THE HERO: crest + your standing + your ring ---------------- */
.bb-li {
  gap: var(--bb-space-4);
}
.bb-hero--li {
  padding: 30px 34px 28px;
}
/* Below the expanded tier the title block gives up width so the aside
   fits beside it: your standing and your ring on the first row, the
   crest underneath. At 1920+ the three sit in one row. */
.bb-hero--li .bb-hero__main {
  flex-basis: 360px;
}
.bb-li-hero__aside {
  display: grid;
  grid-template-columns: auto auto;
  grid-template-areas:
    "stat ring"
    "crest crest";
  align-items: center;
  gap: 10px 12px;
}
.bb-li-hero__aside .bb-hero__stat {
  grid-area: stat;
  padding-right: 14px;
}
.bb-li-hero__aside .bb-hero__ring {
  grid-area: ring;
  padding-inline: 10px;
}
.bb-li-hero__aside .bb-hero__ring .bb-ring {
  width: 148px;
  height: 148px;
}
.bb-li-crest {
  grid-area: crest;
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
  padding: 12px 0 0;
  border-top: 1px solid var(--bb-border);
}
.bb-li-crest__mark {
  flex: none;
  width: 56px;
  height: 49px;
}
.bb-li-crest__text {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.bb-li-crest__name {
  font-size: 1.4rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.05;
  color: var(--bb-text-primary);
  max-width: 18ch;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bb-li-crest__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.bb-li-crest__chip {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 5px;
  border: 1px solid var(--bb-border-strong);
  white-space: nowrap;
}
.bb-li-crest__season {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}

/* --- 25.1b THE INSTRUMENT STRIP: six cells on one line at 1440 -------- */
.bb-li-instrument .bb-strip {
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
}
.bb-li-instrument .bb-strip--wide .bb-strip__cell {
  padding: 16px 16px 14px;
}
.bb-li-instrument .bb-strip__label {
  white-space: normal;
  line-height: 1.25;
}
.bb-li-instrument .bb-strip--wide .bb-strip__value {
  font-size: 1.7rem;
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}
.bb-li-instrument .bb-strip--wide .bb-strip__value--word {
  font-size: 1.15rem;
}

/* --- 25.2 THE LEAGUE SHAPE RAIL --------------------------------------- */
.bb-li-shape {
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  padding: 12px 20px 14px;
}
.bb-li-shape__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 14px;
}
.bb-li-shape__meta {
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-secondary);
}
.bb-li-shape__rail {
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  gap: 6px;
  align-items: end;
}
.bb-li-shape__stop {
  position: relative;
  display: grid;
  grid-template-rows: auto 44px auto;
  justify-items: center;
  gap: 6px;
  min-width: 0;
  padding: 10px 6px 8px;
  border: 1px solid transparent;
  border-radius: 8px;
  text-align: center;
}
.bb-li-shape__count {
  font-family: var(--bb-font-numeric);
  font-size: 1.25rem;
  font-weight: var(--bb-fw-bold);
  line-height: 1;
  color: var(--bb-text-tertiary);
}
.bb-li-shape__stop.has-teams .bb-li-shape__count {
  color: var(--bb-text-primary);
}
.bb-li-shape__bar {
  display: flex;
  align-items: flex-end;
  width: 100%;
  max-width: 64px;
  height: 44px;
  border-bottom: 1px solid var(--bb-border-strong);
}
.bb-li-shape__fill {
  width: 100%;
  height: calc(100% * var(--bb-li-n, 0) / var(--bb-li-max, 1));
  border-radius: 3px 3px 0 0;
}
.bb-li-shape__stop.has-teams .bb-li-shape__fill {
  min-height: 4px;
}
.bb-li-shape__name {
  font-size: var(--bb-fs-micro);
  line-height: 1.2;
  color: var(--bb-text-tertiary);
}
.bb-li-shape__stop.has-teams .bb-li-shape__name {
  color: var(--bb-text-secondary);
  font-weight: var(--bb-fw-semibold);
}
/* Team names under each stop: only where the rail is wide enough
   (full HQ); the same names are in every stop's tooltip. */
.bb-li-shape__teams {
  display: none;
  flex-direction: column;
  gap: 1px;
  width: 100%;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-li-shape__teams span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bb-li-shape__you {
  position: absolute;
  top: -9px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 1px 7px;
  border-radius: 4px;
}

/* --- 25.3 THE EARLY-SEASON NOTE ------------------------------------- */
.bb-li-note {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 10px 16px;
  border: 1px solid var(--bb-border);
  border-radius: 10px;
  font-size: var(--bb-fs-sm);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-li-note__mark {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 2px;
}

/* --- 25.4 THE FIELD ----------------------------------------------------
   Below the expanded tier the board takes the whole width (its wide
   density needs it) and the rail sits under it two-up; at 1920+ the
   board leads (8) with the rail beside it (4). */
.bb-field--li > .bb-li-lead {
  grid-column: span 12;
  container-type: inline-size;
  container-name: bb-li-lead;
}
.bb-field--li > .bb-li-rail {
  grid-column: span 12;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--bb-space-4);
  align-items: start;
}
/* Module heads on this page wrap instead of clipping a long title or
   breaking a meta phrase word by word; the meta reads under the title
   when it has to. */
.bb-li .bb-mod__head {
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 12px;
}
.bb-li .bb-mod__title {
  white-space: normal;
  line-height: 1.35;
}
.bb-li .bb-mod__meta {
  flex: 1 1 auto;
  text-align: left;
}
.bb-li .bb-mod__head .bb-mod__link {
  margin-left: auto;
}
.bb-li-lead__head {
  margin-bottom: 14px;
}
.bb-field--li > .bb-li-fulltable {
  order: 99;
}
/* Supporting modules pair up until the expanded tier (three-up at 1920+,
   one column on a phone -- the shared 900 tier, restated at this
   specificity). */
.bb-field--li > .bb-span-4 {
  grid-column: span 6;
}
.bb-li-lead .bb-state {
  margin-bottom: 12px;
}

/* --- 25.5 THE LEAGUE LANDSCAPE BOARD --------------------------------- */
.bb-li-board {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--bb-border-subtle);
  border-radius: 10px;
  overflow: hidden;
}
.bb-li-board__head,
.bb-li-board .bb-li-board__row {
  display: grid;
  grid-template-columns: 28px minmax(120px, 1.6fr) 56px 62px 62px 60px 44px minmax(96px, 1fr) minmax(132px, auto) minmax(116px, 0.9fr);
  grid-template-areas: "rank team record pf pa diff streak power dir needs";
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
}
.bb-li-board__head {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
/* The row overrides the legacy `.bb-landscape__row` five-column grid
   (still used by the shared macro elsewhere) at higher specificity. */
.bb-li-board .bb-landscape__row,
.bb-li-board .bb-li-board__row {
  border: 0;
  border-top: 1px solid var(--bb-border-subtle);
  border-radius: 0;
  font-size: var(--bb-fs-sm);
  color: inherit;
  text-decoration: none;
  min-height: 38px;
}
.bb-li-board__c-rank   { grid-area: rank; }
.bb-li-board__c-team   { grid-area: team; }
.bb-li-board__c-record { grid-area: record; }
.bb-li-board__c-pf     { grid-area: pf; }
.bb-li-board__c-pa     { grid-area: pa; }
.bb-li-board__c-diff   { grid-area: diff; }
.bb-li-board__c-streak { grid-area: streak; }
.bb-li-board__c-power  { grid-area: power; }
.bb-li-board .bb-landscape__direction { grid-area: dir; }
.bb-li-board__c-needs  { grid-area: needs; }
.bb-li-board__c-rank {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-sm);
  color: var(--bb-text-tertiary);
}
.bb-li-board .bb-li-board__c-team {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.bb-li-board__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
  text-decoration: none;
}
.bb-li-board__name:hover {
  text-decoration: underline;
}
.bb-li-board__you {
  flex: none;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 1px 6px;
  border-radius: 4px;
}
.bb-li-board__detail {
  flex: none;
  margin-left: auto;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  text-decoration: none;
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--bb-transition-fast), color var(--bb-transition-fast);
}
.bb-li-board__row:hover .bb-li-board__detail,
.bb-li-board__row:focus-within .bb-li-board__detail {
  opacity: 1;
}
.bb-li-board__c-record,
.bb-li-board__c-num,
.bb-li-board__c-streak {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bb-li-board__c-num {
  color: var(--bb-text-secondary);
}
.bb-li-board__c-record {
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
}
.bb-li-board__c-diff .is-up,
.bb-li-board__c-streak .is-up { color: var(--bb-positive); }
.bb-li-board__c-diff .is-down,
.bb-li-board__c-streak .is-down { color: var(--bb-negative); }
.bb-li-board__c-power {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.bb-li-board__c-power .bb-band {
  flex: 1 1 auto;
  min-width: 40px;
}
.bb-li-board .bb-landscape__strength {
  flex: none;
  width: 3ch;
  text-align: right;
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-bold);
  color: var(--bb-text-primary);
}
.bb-li-board .bb-landscape__direction {
  min-width: 0;
}
.bb-li-dir {
  white-space: nowrap;
}
.bb-li-board .bb-landscape__needs {
  justify-content: flex-start;
}
/* Phone-only cell captions: printed by the narrow density below. */
.bb-li-board__row [data-label]::before {
  content: none;
}

/* The MID density: the board is narrower than ten columns need (a
   1440 desktop with both rails docked). Points stack in one column,
   streak under the record -- every value still printed. */
@container bb-li-lead (max-width: 899px) {
  .bb-li-board__head,
  .bb-li-board .bb-li-board__row {
    grid-template-columns: 28px minmax(170px, 2fr) 50px 62px 54px minmax(90px, 1fr) minmax(132px, auto) minmax(96px, 0.8fr);
    grid-template-areas:
      "rank team record pf diff power dir needs"
      "rank team streak pa diff power dir needs";
    row-gap: 2px;
  }
  .bb-li-board__c-pa,
  .bb-li-board__c-streak {
    font-size: var(--bb-fs-micro);
    line-height: 1.3;
    align-self: start;
  }
  .bb-li-board__c-record,
  .bb-li-board__c-pf {
    align-self: end;
    line-height: 1.3;
  }
}

/* The NARROW density: a card per team. Rank down the left edge; the
   team and its direction on the first line; the record readings each
   with its own caption; the power bar; then the needs. */
@container bb-li-lead (max-width: 559px) {
  .bb-li-board__head {
    display: none;
  }
  .bb-li-board .bb-li-board__row {
    grid-template-columns: 26px auto auto auto auto minmax(0, 1fr);
    grid-template-areas:
      "rank team team team team team"
      "rank record streak pf pa diff"
      "rank power power power dir dir"
      "rank needs needs needs needs needs";
    gap: 8px 10px;
    padding: 10px 12px 12px;
  }
  .bb-li-board__c-rank {
    align-self: start;
    font-size: var(--bb-fs-base);
    font-weight: var(--bb-fw-bold);
    color: var(--bb-text-secondary);
  }
  .bb-li-board .bb-landscape__direction {
    justify-content: flex-end;
  }
  .bb-li-board__detail {
    opacity: 1;
  }
  .bb-li-board__c-record,
  .bb-li-board__c-num,
  .bb-li-board__c-streak {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    gap: 1px;
  }
  /* The mid density's stacked pairs (streak under record, PA under PF)
     also match here; on the card every reading is its own captioned
     cell, so they take the same size and sit on the same line. */
  .bb-li-board__c-record,
  .bb-li-board__c-pf,
  .bb-li-board__c-pa,
  .bb-li-board__c-streak {
    align-self: auto;
    font-size: inherit;
    line-height: inherit;
  }
  .bb-li-board__row [data-label]::before {
    content: attr(data-label);
    font-family: var(--bb-font-mono);
    font-size: 0.625rem;
    font-weight: var(--bb-fw-bold);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--bb-text-tertiary);
  }
  .bb-li-board__c-power [data-label]::before,
  .bb-li-board .bb-landscape__direction::before,
  .bb-li-board .bb-landscape__needs::before {
    content: none;
  }
  .bb-li-board__c-diff {
    justify-self: end;
    align-items: flex-end;
  }
}
/* The plain board (V1 strength unavailable): five columns, two lines
   on a phone. */
.bb-li-board--plain .bb-li-board__head,
.bb-li-board--plain .bb-li-board__row {
  grid-template-columns: 28px minmax(120px, 1.6fr) 60px 72px 72px;
  grid-template-areas: "rank team record pf pa";
}
@container bb-li-lead (max-width: 559px) {
  .bb-li-board--plain .bb-li-board__row {
    grid-template-columns: 26px auto auto minmax(0, 1fr);
    grid-template-areas:
      "rank team team team"
      "rank record pf pa";
  }
}

/* --- 25.6 THE POWER BOARD ---------------------------------------------- */
.bb-li-power__list {
  display: flex;
  flex-direction: column;
}
.bb-li-power__row {
  display: grid;
  grid-template-columns: 24px 10px minmax(0, 1fr) 38px 84px;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  margin: 0 -8px;
  border-top: 1px solid var(--bb-border-subtle);
  border-radius: 6px;
  font-size: var(--bb-fs-sm);
  color: inherit;
  text-decoration: none;
}
.bb-li-power__row:first-child {
  border-top: 0;
}
.bb-li-power__row:hover {
  text-decoration: none;
}
.bb-li-power__rank {
  font-family: var(--bb-font-mono);
  font-weight: var(--bb-fw-bold);
  color: var(--bb-text-primary);
  text-align: right;
}
.bb-li-power__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--bb-border-strong);
}
.bb-li-power__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--bb-text-primary);
}
.bb-li-power__standing {
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  text-align: right;
}
.bb-li-power__row.is-unranked .bb-li-power__name {
  color: var(--bb-text-tertiary);
}

/* --- 25.7 THE POSTURE MODULE ----------------------------------------- */
.bb-li-posture .bb-posture {
  margin-top: 0;
}
.bb-li-posture__stage {
  margin: 4px 0 0;
  font-size: var(--bb-fs-sm);
  line-height: 1.4;
  color: var(--bb-text-secondary);
}
.bb-li-posture__stage strong {
  color: var(--bb-text-primary);
}
.bb-li-posture__list {
  margin: 0;
  padding-left: 16px;
  font-size: var(--bb-fs-sm);
  line-height: 1.45;
}
.bb-li-posture__list li {
  margin-bottom: 3px;
}
.bb-li-posture .bb-mod__link {
  display: inline-block;
  margin-top: 10px;
}

/* --- 25.8 THE SUPPORTING INSTRUMENTS -------------------------------- */
.bb-li-pos__row {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-top: 1px solid var(--bb-border-subtle);
}
.bb-li-pos__row:first-of-type {
  border-top: 0;
  padding-top: 0;
}
.bb-li-pos__body {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}
.bb-li-pos__meter {
  display: flex;
  height: 8px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--bb-border-subtle);
}
.bb-li-pos__seg {
  height: 100%;
}
.bb-li-pos__label {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
  line-height: 1.3;
}
.bb-li-pos__label strong {
  color: var(--bb-text-primary);
}
.bb-li-pos__slots {
  display: block;
  margin-top: 1px;
}
.bb-li-pos__you {
  min-width: 0;
}
.bb-li-matchups {
  display: flex;
  flex-direction: column;
}
.bb-li-matchup {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  margin: 0 -8px;
  border-top: 1px solid var(--bb-border-subtle);
  border-radius: 6px;
  font-size: var(--bb-fs-sm);
}
.bb-li-matchup:first-child {
  border-top: 0;
}
.bb-li-matchup__team,
.bb-li-matchup__opp {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--bb-text-secondary);
}
.bb-li-matchup__opp {
  text-align: right;
}
.bb-li-matchup__team.is-winner,
.bb-li-matchup__opp.is-winner {
  color: var(--bb-text-primary);
  font-weight: var(--bb-fw-semibold);
}
.bb-li-matchup__score {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-primary);
  white-space: nowrap;
}
.bb-li-matchup__mark {
  flex: none;
}
.bb-li-partners__list {
  display: flex;
  flex-direction: column;
}
.bb-li-partner {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 10px;
  padding: 8px 0;
  border-top: 1px solid var(--bb-border-subtle);
  font-size: var(--bb-fs-sm);
}
.bb-li-partner:first-child {
  border-top: 0;
  padding-top: 0;
}
.bb-li-partner__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
  text-decoration: none;
}
.bb-li-partner__end {
  display: flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}
.bb-li-partner__needs {
  grid-column: 1 / -1;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-li-partner__needs strong {
  color: var(--bb-text-secondary);
}
.bb-li-fulltable {
  padding-top: 8px;
  padding-bottom: 0;
}
.bb-li-fulltable .bb-disclosure {
  margin: 0;
}

/* --- 25.9 THE TIERS ----------------------------------------------------- */
@media (min-width: 1900px) {
  /* The aside keeps its two-row grid (standing beside the ring, the
     crest beneath) at 1920: with both rails docked the hero's interior
     is ~1070px, and a single crest / standing / ring row (~820px) beside
     a 440px title block would wrap under the title and leave the hero
     tall and empty. The single row is the 2560 tier's. */
  .bb-hero--li .bb-hero__main {
    flex-basis: 440px;
  }
  .bb-li-hero__aside .bb-hero__ring .bb-ring {
    width: 172px;
    height: 172px;
  }
  .bb-li-hero__aside .bb-hero__stat {
    padding-right: 28px;
  }
  .bb-li-instrument .bb-strip--wide .bb-strip__cell {
    padding: 24px 28px 22px;
  }
  .bb-li-instrument .bb-strip--wide .bb-strip__value {
    font-size: var(--bb-fs-instrument);
  }
  .bb-field--li > .bb-li-lead {
    grid-column: span 8;
  }
  .bb-field--li > .bb-li-rail {
    grid-column: span 4;
    display: flex;
    flex-direction: column;
  }
  .bb-field--li > .bb-span-4 {
    grid-column: span 4;
  }
  .bb-hero--li {
    padding-top: 44px;
    padding-bottom: 40px;
  }
  .bb-li-crest__mark {
    width: 64px;
    height: 56px;
  }
  .bb-li-crest__name {
    font-size: 1.6rem;
  }
  .bb-li-shape__teams {
    display: flex;
  }
  .bb-li-shape__stop {
    grid-template-rows: auto 48px auto auto;
    padding: 12px 8px 10px;
  }
  .bb-li-shape__bar {
    height: 48px;
    max-width: 80px;
  }
}
@media (min-width: 2300px) {
  /* The hero aside as one row: crest, standing, ring. */
  .bb-li-hero__aside {
    display: flex;
    gap: var(--bb-space-6);
  }
  .bb-li-crest {
    order: -1;
    padding: 8px 28px 8px 0;
    border-top: 0;
    border-right: 1px solid var(--bb-border);
  }
  .bb-li-board__head,
  .bb-li-board .bb-li-board__row {
    padding: 10px 16px;
    gap: 12px;
  }
  .bb-li-board .bb-li-board__row {
    font-size: var(--bb-fs-base);
    padding-top: 12px;
    padding-bottom: 12px;
  }
  .bb-li-board .bb-landscape__strength {
    font-size: var(--bb-fs-base);
  }
  .bb-li-shape__count {
    font-size: 1.5rem;
  }
  .bb-li-shape__stop {
    grid-template-rows: auto 56px auto auto;
  }
  .bb-li-shape__bar {
    height: 56px;
    max-width: 96px;
  }
  .bb-li-power__row {
    padding: 8px 10px;
    font-size: var(--bb-fs-base);
  }
  .bb-li-matchup,
  .bb-li-partner {
    font-size: var(--bb-fs-base);
  }
}
/* Tablet: the rail's two modules keep their pair; phone: one column. */
@media (max-width: 900px) {
  .bb-field--li > .bb-li-rail {
    grid-template-columns: 1fr;
  }
  .bb-field--li > .bb-span-4 {
    grid-column: span 12;
  }
  .bb-li-hero__aside {
    grid-template-columns: 1fr;
    grid-template-areas:
      "crest"
      "stat"
      "ring";
    justify-items: stretch;
  }
  .bb-li-hero__aside .bb-hero__stat {
    padding-right: 0;
  }
  .bb-li-crest {
    padding: 0 0 12px;
    border-top: 0;
    border-bottom: 1px solid var(--bb-border);
  }
  .bb-li-instrument .bb-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .bb-li-crest__name {
    max-width: none;
    white-space: normal;
  }
  .bb-li-shape {
    padding: 12px 14px 14px;
  }
  .bb-li-shape__rail {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 4px;
  }
  .bb-li-shape__stop {
    padding: 10px 2px 6px;
  }
  .bb-li-note {
    align-items: flex-start;
  }
  .bb-li-note__mark {
    margin-top: 6px;
  }
  .bb-li-pos__row {
    grid-template-columns: 40px minmax(0, 1fr);
  }
  .bb-li-pos__you {
    grid-column: 2;
  }
  .bb-li-matchup {
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas:
      "team score mark"
      "opp opp mark";
    row-gap: 2px;
  }
  .bb-li-matchup__team { grid-area: team; }
  .bb-li-matchup__score { grid-area: score; }
  .bb-li-matchup__opp { grid-area: opp; text-align: left; }
  .bb-li-matchup__mark { grid-area: mark; }
}


/* =====================================================================
   26. GRAND REIMAGINATION, PHASE 2A (2026-09) -- THE PHONE SHELL, TUNED
   =====================================================================
   The mobile nav sheet read as the desktop command rail compressed into
   a drawer. STRUCTURE ONLY (paint is identity.css section 19): the
   flagship index (01/02/03...) is a desktop reading and yields on the
   phone; rows, icons, group rhythm and the scrollbar take the phone's
   own density. Grouping, labels, hrefs and the bottom bar are unchanged.
   ================================================================== */
@media (max-width: 900px) {
  /* The mono index is decoration that reads at desktop scale only; the
     label carries the meaning on every tier. */
  .bb-navitem--flagship::after {
    display: none;
  }
  .bb-nav {
    overflow-y: auto;
    padding: 8px 10px 20px;
    scrollbar-width: thin;
  }
  .bb-nav::-webkit-scrollbar {
    width: 5px;
  }
  .bb-nav::-webkit-scrollbar-track {
    background: transparent;
  }
  .bb-nav::-webkit-scrollbar-thumb {
    border-radius: 3px;
  }
  .bb-navctx {
    padding: 8px 10px;
    gap: 2px;
    min-height: 40px;
  }
  .bb-navpicker__summary {
    min-height: 38px;
    padding: 5px 10px;
  }
  .bb-navgroup {
    margin-bottom: 4px;
    padding-bottom: 6px;
  }
  .bb-navgroup:first-of-type {
    padding-bottom: 6px;
  }
  .bb-navgroup__label {
    padding: 6px 8px 4px;
    letter-spacing: 0.2em;
    gap: 8px;
  }
  .bb-navgroup__items {
    gap: 1px;
  }
  .bb-navitem,
  .bb-navitem--flagship {
    min-height: 42px;
    gap: 11px;
    padding: 5px 10px;
    border-left-width: 3px;
    border-radius: 8px;
  }
  .bb-navitem--flagship .bb-navitem__icon {
    width: 28px;
    height: 28px;
    padding: 5px;
    border-radius: 7px;
  }
  .bb-navitem--flagship .bb-navitem__label {
    font-size: 0.9375rem;
  }
  .bb-navitem--flagship .bb-navitem__hint {
    margin-top: 0;
    line-height: 1.25;
  }
  .bb-navitem:not(.bb-navitem--flagship) {
    min-height: 36px;
    padding: 4px 10px 4px 15px;
  }
  .bb-navitem:not(.bb-navitem--flagship) .bb-navitem__icon {
    width: 18px;
    height: 18px;
    margin-inline: 5px;
  }
  .bb-navitem:not(.bb-navitem--flagship) .bb-navitem__label {
    font-size: var(--bb-fs-small);
  }
  .bb-nav__foot {
    margin-top: 10px;
    padding: 9px 12px;
    letter-spacing: 0.12em;
  }
  /* The top shell: the four controls space evenly, the toggle sits on
     the same 40px footprint as the utility icons, the wordmark stays
     a compact "BB//". */
  .bb-topbar {
    gap: 10px;
  }
  .bb-topbar__left {
    gap: 8px;
  }
  .bb-topbar__right {
    gap: 6px;
  }
  .bb-nav-toggle,
  .bb-topbar__right .bb-btn--icon {
    width: 40px;
    height: 40px;
    min-height: 40px;
    padding: 0;
  }
  .bb-search__trigger {
    min-height: 40px;
    padding-inline: 10px;
  }
  .bb-mark--lockup {
    width: 30px;
    height: 26px;
  }
}

/* Matchup Command V1: existing schedule rows are keyboard/touch links.
   The 44px floor is a touch-context concern only, same reasoning as the
   `pointer: coarse` rationale earlier in this file (~line 2462):
   `.bb-li-matchup` is a repeated row in the League Radar board, so an
   unconditional floor here costs rows of matchups visible per screen on
   a mouse-driven desktop. Gated the same way every other touch floor in
   this pack is -- coarse pointer, or this codebase's phone tier. */
@media (pointer: coarse), (max-width: 900px) {
  a.bb-li-matchup { min-height: var(--bb-tap-min); }
}
a.bb-li-matchup .bb-li-matchup__team,
a.bb-li-matchup .bb-li-matchup__opp { text-decoration: underline; text-underline-offset: 3px; }


/* =====================================================================
   33. GLOBAL LIVE WIRE RAIL (Game Experience campaign, 2026-09)
   =====================================================================
   The topbar's centre cluster: one link, one line, three states
   (`partials/live_wire_rail.html`). Read-only, rendered with the page,
   never polled, never scrolled. Quiet while idle; the dot lights when a
   game is live; the tail turns vivid only while Blackbird has just
   observed a real score/status change. No `@keyframes`: the live state
   is a lit dot with a still ring, legible without motion.

   Purple stays interaction authority (hover/focus). Team colour appears
   only on the two team codes, through `ui.team_code()`. Green is the
   live-state colour, exactly as on Game Day. */
.bb-lw {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  min-width: 0;
  min-height: 32px;
  padding: 0 12px;
  border: 1px solid var(--bb-border-subtle);
  border-radius: var(--bb-radius-pill);
  background: rgb(var(--bb-ink-rgb) / 0.18);
  color: var(--bb-text-secondary);
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: border-color var(--bb-transition-fast), color var(--bb-transition-fast), background var(--bb-transition-fast);
}
.bb-lw:hover,
.bb-lw:focus-visible {
  color: var(--bb-text-primary);
  border-color: var(--bb-purple-border-strong);
  background: var(--bb-purple-wash);
  text-decoration: none;
}
.bb-lw:focus-visible { outline: none; box-shadow: var(--bb-focus-ring); }
.bb-lw__dot {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--bb-border-strong);
}
.bb-lw__brand { color: var(--bb-text-tertiary); letter-spacing: 0.12em; }
.bb-lw__sep { color: var(--bb-text-tertiary); opacity: 0.7; }
.bb-lw__core {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--bb-text-primary);
}
.bb-lw__team .bb-team-code { font-size: var(--bb-fs-micro); letter-spacing: 0.06em; }
.bb-lw__score { font-variant-numeric: tabular-nums; font-weight: var(--bb-fw-bold); }
.bb-lw__tail { color: var(--bb-text-secondary); }
.bb-lw__count {
  padding: 1px 6px;
  border-radius: var(--bb-radius-pill);
  border: 1px solid var(--bb-border);
  color: var(--bb-text-tertiary);
  font-size: 0.625rem;
}

/* LIVE: the dot lights. The rail's own frame stays graphite. */
.bb-lw[data-state="live"],
.bb-lw[data-state="change"] { border-color: var(--bb-positive-border); }
.bb-lw[data-state="live"] .bb-lw__dot,
.bb-lw[data-state="change"] .bb-lw__dot {
  background: var(--bb-positive);
  box-shadow: 0 0 0 2px rgb(var(--bb-positive-rgb) / 0.22), 0 0 10px rgb(var(--bb-positive-rgb) / 0.55);
}
.bb-lw[data-state="live"] .bb-lw__brand,
.bb-lw[data-state="change"] .bb-lw__brand { color: var(--bb-positive); }
.bb-lw[data-state="live"]:hover,
.bb-lw[data-state="change"]:hover { border-color: var(--bb-purple-border-strong); }

/* CHANGE: the only vivid moment -- the tail takes the purple light,
   because the change is Blackbird's own observation, not a team's. */
.bb-lw[data-state="change"] {
  background: linear-gradient(90deg, var(--bb-purple-soft), rgb(var(--bb-positive-rgb) / 0.06));
}
.bb-lw__tail--change { color: var(--bb-purple-bright); font-weight: var(--bb-fw-bold); }

/* Phone / narrow -- PRE-RESET FABLE PASS (2026-09): THE STRIP.
   Measured at 390px before this pass: the centre cluster had ~40px of
   room between the brand and the four right-hand controls, so the rail
   compressed to a lone dot with the score clipped away -- unreadable
   precisely when it mattered. The rail no longer competes for that row.
   The topbar WRAPS on the phone tier (section 35 below): the same
   `.bb-topbar__center` element -- same include, same `live_wire_header`
   seam, no second poller, no second state -- becomes a thin full-width
   second row directly under the controls and above the context bar.
   With a whole row to itself the caption and the tail come back; only
   the decorative middle-dot stays yielded (documented in
   `test_ui_contract_sweep.py`'s HIDDEN_ON_PHONE). */
@media (max-width: 900px) {
  .bb-lw {
    width: 100%;
    justify-content: flex-start;
    gap: 10px;
    min-height: var(--bb-lwstrip-height);
    padding: 0 calc(var(--bb-space-3) + var(--bb-safe-left)) 0 calc(var(--bb-space-3) + var(--bb-safe-left));
    border: 0;
    border-radius: 0;
    background: rgb(var(--bb-ink-rgb) / 0.28);
    letter-spacing: 0.06em;
    font-size: 0.6875rem;
  }
  .bb-lw:hover,
  .bb-lw:focus-visible {
    background: var(--bb-purple-wash);
  }
  .bb-lw:focus-visible {
    box-shadow: inset 0 0 0 2px rgb(var(--bb-purple-bright-rgb));
  }
  .bb-lw__sep { display: none; }
  .bb-lw__core { font-size: 0.6875rem; gap: 7px; }
  .bb-lw__tail { margin-left: 2px; }
  .bb-lw__count { margin-left: auto; }
  .bb-lw[data-state="live"],
  .bb-lw[data-state="change"] {
    box-shadow: inset 0 1px 0 var(--bb-positive-border);
  }
  .bb-lw[data-state="change"] {
    background: linear-gradient(90deg, var(--bb-purple-soft), rgb(var(--bb-positive-rgb) / 0.06));
  }
}


/* =====================================================================
   34. WHAT BLACKBIRD CAN DO + VALUE METHODOLOGY (pre-reset Fable pass)
   =====================================================================
   Two static education pages (`platform.html`, `methodology.html`) built
   on the learn-page grammar (section 17's `.bb-learn__*`) plus the
   Grand Reimagination hero. STRUCTURE AND PAINT TOGETHER, in the shell's
   own tokens: purple is Blackbird's identity / proprietary layer, the
   semantic hues (positive / caution / info / data blue) mark meaning,
   and every meaning is also carried by a word -- no colour-only signal.

   RESPONSIVE DISCIPLINE. No grid track wider than 280px, so nothing
   here needs its own phone collapse; every multi-column module folds
   through `auto-fit` or collapses at the existing 720px / 900px tiers.
   No unconditional 40px height floor outside a touch context. */

/* --- 34.1 shared: the compact hero's aside becomes a jump rail -------- */
.bb-pf-hero,
.bb-vm-hero {
  position: relative;
  margin-bottom: var(--bb-space-5);
}
.bb-pf-hero__aside {
  align-self: stretch;
}
.bb-pf-jump {
  display: grid;
  grid-template-columns: repeat(3, max-content);
  gap: 4px 18px;
  align-content: center;
  justify-content: end;
}
.bb-pf-jump__link {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 3px 0;
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--bb-text-secondary);
  text-decoration: none;
  white-space: nowrap;
}
.bb-pf-jump__link:hover,
.bb-pf-jump__link:focus-visible {
  color: var(--bb-text-primary);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.bb-pf-jump__index {
  font-family: var(--bb-font-mono);
  color: var(--bb-purple-bright);
}

/* --- 34.2 the badge vocabulary ---------------------------------------- */
.bb-pf-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 5px;
  margin: 2px 0 8px;
}
.bb-pf-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 7px;
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-sm);
  background: rgb(var(--bb-ink-rgb) / 0.18);
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.08em;
  color: var(--bb-text-secondary);
  white-space: nowrap;
}
.bb-pf-badge--personalized { border-color: var(--bb-purple-border-strong); background: var(--bb-purple-soft); color: var(--bb-purple-bright); }
.bb-pf-badge--league { border-color: var(--bb-info-border); background: var(--bb-info-bg); color: var(--bb-info); }
.bb-pf-badge--roster { border-color: var(--bb-accent-data-border); background: var(--bb-accent-data-bg); color: var(--bb-accent-data); }
.bb-pf-badge--format { border-color: var(--bb-border-strong); background: rgb(var(--bb-ink-rgb) / 0.3); color: var(--bb-text-primary); }
.bb-pf-badge--live { border-color: var(--bb-positive-border); background: var(--bb-positive-bg); color: var(--bb-positive); }
.bb-pf-badge--dynasty { border-color: var(--bb-caution-border); background: var(--bb-caution-bg); color: var(--bb-caution); }
.bb-pf-badge--redraft { border-color: var(--bb-border-strong); background: transparent; color: var(--bb-text-secondary); }
.bb-pf-badge--partial {
  border-style: dashed;
  background: transparent;
  opacity: 0.85;
}

/* --- 34.3 the legend --------------------------------------------------- */
.bb-pf-legend {
  margin-bottom: var(--bb-space-6);
  padding: 14px 18px 12px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
}
.bb-pf-legend__title {
  margin: 0 0 4px;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bb-text-secondary);
}
.bb-pf-legend__lead {
  max-width: 80ch;
  margin: 0 0 10px;
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-pf-legend__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 6px 18px;
  margin: 0;
}
.bb-pf-legend__row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: var(--bb-fs-small);
  color: var(--bb-text-secondary);
}
.bb-pf-legend__row dt { flex: none; display: flex; gap: 4px; margin: 0; }
.bb-pf-legend__row dd { margin: 0; padding-top: 1px; }

/* --- 34.4 a question group and its cards ------------------------------- */
.bb-pf-group {
  margin-bottom: var(--bb-space-6);
  scroll-margin-top: calc(var(--bb-topbar-height) + var(--bb-contextbar-height) + var(--bb-space-3));
}
.bb-pf-group__head {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--bb-border);
}
.bb-pf-group__index {
  flex: none;
  font-family: var(--bb-font-mono);
  font-size: 1.6rem;
  font-weight: var(--bb-fw-bold);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--bb-purple-bright);
  text-shadow: 0 0 18px rgb(var(--bb-purple-rgb) / 0.45);
}
.bb-pf-group__text { min-width: 0; flex: 1 1 auto; }
.bb-pf-group__label {
  margin: 0;
  font-size: var(--bb-fs-section-title);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-tight);
  color: var(--bb-text-primary);
}
.bb-pf-group__question {
  margin: 2px 0 0;
  font-size: var(--bb-fs-small);
  color: var(--bb-text-tertiary);
}
.bb-pf-group__count {
  flex: none;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-pf-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
  gap: var(--bb-space-3);
}
.bb-pf-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 14px 16px 12px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
  box-shadow: var(--bb-edge-light);
  scroll-margin-top: calc(var(--bb-topbar-height) + var(--bb-contextbar-height) + var(--bb-space-3));
  transition: border-color var(--bb-transition-fast), background var(--bb-transition-fast);
}
.bb-pf-card:hover {
  border-color: var(--bb-purple-border);
}
.bb-pf-card:target {
  border-color: var(--bb-purple-border-strong);
  background: var(--bb-purple-wash);
}
.bb-pf-card--hidden {
  border-left: 3px solid var(--bb-purple);
}
.bb-pf-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}
.bb-pf-card__name {
  margin: 0;
  font-size: var(--bb-fs-card-title);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: var(--bb-tracking-tight);
  color: var(--bb-text-primary);
}
.bb-pf-flag {
  flex: none;
  padding: 2px 7px;
  border-radius: var(--bb-radius-pill);
  border: 1px solid var(--bb-purple-border);
  background: var(--bb-purple-soft);
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--bb-purple-bright);
  white-space: nowrap;
}
.bb-pf-card__summary {
  margin: 0 0 8px;
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-pf-card__when {
  margin: 0 0 6px;
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-primary);
}
.bb-pf-card__whenlabel {
  display: inline-block;
  margin-right: 4px;
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bb-purple-bright);
}
.bb-pf-card__note {
  margin: 0 0 8px;
  padding-left: 10px;
  border-left: 2px solid var(--bb-border-strong);
  font-size: var(--bb-fs-micro);
  line-height: 1.45;
  color: var(--bb-text-tertiary);
}
.bb-pf-card__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  margin-top: auto;
  padding-top: 8px;
  border-top: 1px solid var(--bb-border-subtle);
}
.bb-pf-card__link {
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-purple-bright);
  text-decoration: none;
}
.bb-pf-card__link:hover,
.bb-pf-card__link:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
.bb-pf-card__link--via { color: var(--bb-text-secondary); }
.bb-pf-season {
  margin-left: auto;
  padding: 1px 7px;
  border-radius: var(--bb-radius-pill);
  border: 1px solid var(--bb-border);
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
  white-space: nowrap;
}
.bb-pf-season--in-season { border-color: var(--bb-positive-border); color: var(--bb-positive); }
.bb-pf-season--draft { border-color: var(--bb-caution-border); color: var(--bb-caution); }
.bb-pf-season--year-round { border-color: var(--bb-border-strong); color: var(--bb-text-secondary); }
.bb-pf-status {
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
  white-space: nowrap;
}
.bb-pf-card__related {
  margin: 8px 0 0;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-pf-card__related a { color: var(--bb-text-secondary); text-decoration: none; }
.bb-pf-card__related a:hover,
.bb-pf-card__related a:focus-visible { color: var(--bb-text-primary); text-decoration: underline; }
.bb-pf-card__relatedlabel {
  margin-right: 4px;
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* --- 34.5 the sections below the map ------------------------------------ */
.bb-pf-section {
  margin-bottom: var(--bb-space-7);
  scroll-margin-top: calc(var(--bb-topbar-height) + var(--bb-contextbar-height) + var(--bb-space-3));
}
.bb-pf-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: var(--bb-space-3);
  align-items: stretch;
}
.bb-pf-split__col {
  min-width: 0;
  padding: 14px 16px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
}
.bb-pf-split__col--league {
  border-color: var(--bb-purple-border);
  background-image: linear-gradient(180deg, var(--bb-purple-wash), transparent 60%);
}
.bb-pf-split__title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 2px;
  font-size: var(--bb-fs-card-title);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
}
.bb-pf-split__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
}
.bb-pf-split__dot--global { background: var(--bb-text-tertiary); }
.bb-pf-split__dot--league { background: var(--bb-purple-bright); box-shadow: 0 0 10px rgb(var(--bb-purple-rgb) / 0.6); }
.bb-pf-split__sub {
  margin: 0 0 10px;
  font-size: var(--bb-fs-small);
  color: var(--bb-text-tertiary);
}
.bb-pf-split__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 3px 12px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--bb-fs-small);
}
.bb-pf-split__list a { color: var(--bb-text-secondary); text-decoration: none; }
.bb-pf-split__list a:hover,
.bb-pf-split__list a:focus-visible { color: var(--bb-text-primary); text-decoration: underline; }
.bb-pf-split__partial {
  display: block;
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-pf-split__arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bb-purple-bright);
}
.bb-pf-split__arrow span {
  writing-mode: vertical-rl;
  padding: 10px 0;
  border-left: 1px dashed var(--bb-purple-border-strong);
  border-right: 1px dashed var(--bb-purple-border-strong);
}

/* the journey */
.bb-pf-journey {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--bb-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}
.bb-pf-stage {
  position: relative;
  min-width: 0;
  padding: 14px 14px 12px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
}
.bb-pf-stage--act {
  border-color: var(--bb-caution-border);
  background-image: linear-gradient(180deg, var(--bb-caution-bg), transparent 70%);
}
.bb-pf-stage__index {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  margin-bottom: 8px;
  border-radius: 50%;
  border: 1px solid var(--bb-purple-border-strong);
  background: var(--bb-purple-soft);
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  color: var(--bb-purple-bright);
}
.bb-pf-stage--act .bb-pf-stage__index { border-color: var(--bb-caution-border); background: var(--bb-caution-bg); color: var(--bb-caution); }
.bb-pf-stage__word {
  margin: 0 0 4px;
  font-size: var(--bb-fs-card-title);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--bb-text-primary);
}
.bb-pf-stage__text {
  margin: 0 0 8px;
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-pf-stage__text strong { color: var(--bb-text-primary); }
.bb-pf-stage__links {
  margin: 0;
  font-size: var(--bb-fs-micro);
  color: var(--bb-text-tertiary);
}
.bb-pf-stage__links a { color: var(--bb-purple-bright); text-decoration: none; font-weight: var(--bb-fw-semibold); }
.bb-pf-stage__links a:hover,
.bb-pf-stage__links a:focus-visible { text-decoration: underline; }

/* the season / format maps */
.bb-pf-maps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--bb-space-3);
  margin-bottom: var(--bb-space-5);
}
.bb-pf-maps--2 {
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  margin-bottom: 0;
}
.bb-pf-map {
  min-width: 0;
  padding: 12px 14px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
}
.bb-pf-map__title { margin: 0 0 4px; font-size: var(--bb-fs-small); }
.bb-pf-map__title .bb-pf-season { margin-left: 0; font-size: var(--bb-fs-micro); }
.bb-pf-map__sub { margin: 0 0 8px; font-size: var(--bb-fs-micro); color: var(--bb-text-tertiary); }
.bb-pf-map__list {
  display: grid;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--bb-fs-small);
}
.bb-pf-map__list a { color: var(--bb-text-secondary); text-decoration: none; }
.bb-pf-map__list a:hover,
.bb-pf-map__list a:focus-visible { color: var(--bb-text-primary); text-decoration: underline; }

/* live intelligence */
.bb-pf-live {
  padding: 16px 18px 14px;
  border: 1px solid var(--bb-positive-border);
  border-radius: var(--bb-radius-lg);
  background: linear-gradient(180deg, rgb(var(--bb-positive-rgb) / 0.06), transparent 55%), var(--bb-surface-card);
}
.bb-pf-live__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-bottom: 12px;
}
.bb-pf-live__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--bb-positive);
  box-shadow: 0 0 0 2px rgb(var(--bb-positive-rgb) / 0.22), 0 0 10px rgb(var(--bb-positive-rgb) / 0.55);
}
.bb-pf-live__title {
  margin: 0;
  font-size: var(--bb-fs-section-title);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-tight);
  color: var(--bb-text-primary);
}
.bb-pf-live__note {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bb-positive);
}
.bb-pf-live__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--bb-space-3);
}
.bb-pf-live__cell { min-width: 0; }
.bb-pf-live__cell--boundary {
  padding: 10px 12px;
  border: 1px dashed var(--bb-border-strong);
  border-radius: var(--bb-radius-md);
}
.bb-pf-live__cellname {
  margin: 0 0 4px;
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bb-text-primary);
}
.bb-pf-live__text { margin: 0 0 6px; font-size: var(--bb-fs-small); line-height: var(--bb-leading-body); color: var(--bb-text-secondary); }
.bb-pf-live__links { margin: 0; font-size: var(--bb-fs-small); }
.bb-pf-live__links a { color: var(--bb-purple-bright); font-weight: var(--bb-fw-semibold); text-decoration: none; }
.bb-pf-live__links a:hover,
.bb-pf-live__links a:focus-visible { text-decoration: underline; }

/* quick start + the trust card */
.bb-pf-finish {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  gap: var(--bb-space-3);
}
.bb-pf-finish__title {
  margin: 0 0 10px;
  font-size: var(--bb-fs-section-title);
  font-weight: var(--bb-fw-bold);
  letter-spacing: var(--bb-tracking-tight);
  color: var(--bb-text-primary);
}
.bb-pf-quickstart {
  padding: 16px 18px;
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-elevated);
}
.bb-pf-quickstart__list {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.bb-pf-quickstart__list li {
  display: grid;
  grid-template-columns: 26px minmax(0, auto) minmax(0, 1fr);
  align-items: baseline;
  gap: 8px;
  font-size: var(--bb-fs-body);
}
.bb-pf-quickstart__list a { font-weight: var(--bb-fw-semibold); color: var(--bb-purple-bright); text-decoration: none; }
.bb-pf-quickstart__list a:hover,
.bb-pf-quickstart__list a:focus-visible { text-decoration: underline; }
.bb-pf-quickstart__n {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-bold);
  color: var(--bb-text-tertiary);
}
.bb-pf-quickstart__why { font-size: var(--bb-fs-small); color: var(--bb-text-tertiary); }
.bb-pf-trust {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 16px 18px;
  border: 1px solid var(--bb-purple-border-strong);
  border-radius: var(--bb-radius-lg);
  background-image: linear-gradient(135deg, var(--bb-purple-soft), transparent 70%);
  background-color: var(--bb-surface-card);
  text-decoration: none;
  transition: border-color var(--bb-transition-fast), background-color var(--bb-transition-fast);
}
.bb-pf-trust:hover,
.bb-pf-trust:focus-visible { background-color: var(--bb-purple-wash); border-color: var(--bb-purple-bright); text-decoration: none; }
.bb-pf-trust__eyebrow {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-micro);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bb-purple-bright);
}
.bb-pf-trust__title { font-size: var(--bb-fs-section-title); font-weight: var(--bb-fw-bold); color: var(--bb-text-primary); }
.bb-pf-trust__text { font-size: var(--bb-fs-small); line-height: var(--bb-leading-body); color: var(--bb-text-secondary); }

/* --- 34.6 methodology: the rail ---------------------------------------- */
.bb-vm-rail {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 6px;
  margin-bottom: var(--bb-space-6);
}
.bb-vm-rail__item {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  padding: 8px 10px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
  text-decoration: none;
  transition: border-color var(--bb-transition-fast), background var(--bb-transition-fast);
}
.bb-vm-rail__item:hover,
.bb-vm-rail__item:focus-visible { border-color: var(--bb-purple-border-strong); background: var(--bb-purple-wash); text-decoration: none; }
.bb-vm-rail__term {
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.06em;
  color: var(--bb-purple-bright);
}
.bb-vm-rail__gloss { font-size: var(--bb-fs-micro); line-height: 1.35; color: var(--bb-text-secondary); }

.bb-vm-section {
  margin-bottom: var(--bb-space-7);
  scroll-margin-top: calc(var(--bb-topbar-height) + var(--bb-contextbar-height) + var(--bb-space-3));
}
.bb-vm-answer {
  max-width: 84ch;
  margin: 0 0 var(--bb-space-4);
  padding: 12px 16px;
  border-left: 3px solid var(--bb-purple);
  border-radius: 0 var(--bb-radius-md) var(--bb-radius-md) 0;
  background: var(--bb-purple-wash);
  font-size: var(--bb-fs-md);
  line-height: 1.45;
  color: var(--bb-text-primary);
}
.bb-vm-answer__label {
  display: block;
  margin-bottom: 2px;
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bb-purple-bright);
}

/* --- 34.7 methodology: the value stack diagram --------------------------- */
.bb-vm-stack {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
  margin: var(--bb-space-3) 0;
  padding: 16px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
  background-image: var(--bb-texture-grid);
  background-size: var(--bb-texture-grid-size);
}
.bb-vm-track {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: var(--bb-radius-md);
  border: 1px solid var(--bb-border-subtle);
}
.bb-vm-track--bbv { border-color: var(--bb-purple-border); background: var(--bb-purple-wash); }
.bb-vm-track--mav { border-color: var(--bb-info-border); background: var(--bb-info-bg); }
.bb-vm-track__label {
  flex: 0 0 100%;
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-vm-inputs { display: flex; flex-wrap: wrap; gap: 6px; }
.bb-vm-node {
  display: inline-flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 10px;
  border-radius: var(--bb-radius-md);
  border: 1px solid var(--bb-border-strong);
  background: var(--bb-surface-raised);
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
  text-decoration: none;
  white-space: nowrap;
}
.bb-vm-node small { font-size: 0.625rem; font-weight: var(--bb-fw-regular); letter-spacing: 0.04em; color: var(--bb-text-tertiary); white-space: normal; }
.bb-vm-node--input { border-style: dashed; background: transparent; font-weight: var(--bb-fw-regular); color: var(--bb-text-secondary); }
.bb-vm-node--value { border-color: var(--bb-purple-border-strong); background: var(--bb-purple-soft); color: var(--bb-purple-bright); }
.bb-vm-node--market { border-color: var(--bb-info-border); background: var(--bb-info-bg); color: var(--bb-info); }
.bb-vm-node--edge { border-color: var(--bb-positive-border); background: var(--bb-positive-bg); color: var(--bb-positive); }
.bb-vm-node--layer { border-color: var(--bb-border-strong); background: rgb(var(--bb-ink-rgb) / 0.25); }
a.bb-vm-node:hover,
a.bb-vm-node:focus-visible { border-color: var(--bb-purple-bright); text-decoration: none; }
.bb-vm-arrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--bb-text-tertiary);
  font-size: var(--bb-fs-micro);
}
.bb-vm-arrow::before { content: "\2192"; font-size: var(--bb-fs-md); }
.bb-vm-arrow em { font-style: normal; font-family: var(--bb-font-mono); font-size: 0.625rem; letter-spacing: 0.06em; text-transform: uppercase; }
.bb-vm-meet {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 12px;
}
.bb-vm-meet__line { flex: 1 1 auto; height: 1px; background: linear-gradient(90deg, var(--bb-purple-border-strong), var(--bb-positive-border), var(--bb-info-border)); }
.bb-vm-consumers { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 12px 4px; }

/* --- 34.8 methodology: ingredients, comparisons, facts ------------------- */
.bb-vm-ingredients {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 8px;
}
.bb-vm-ingredient {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
  font-size: var(--bb-fs-small);
  color: var(--bb-text-secondary);
}
.bb-vm-ingredient strong { color: var(--bb-text-primary); }
.bb-vm-ingredient__mark { font-family: var(--bb-font-mono); font-size: 0.625rem; letter-spacing: 0.1em; color: var(--bb-purple-bright); }
.bb-vm-ingredient a { color: var(--bb-purple-bright); }
.bb-vm-compare {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--bb-space-3);
  margin-bottom: var(--bb-space-4);
}
.bb-vm-compare__col {
  min-width: 0;
  padding: 12px 14px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
}
.bb-vm-compare__col--d { border-color: var(--bb-purple-border); background-image: linear-gradient(180deg, var(--bb-purple-wash), transparent 60%); }
.bb-vm-compare__title {
  margin: 0 0 8px;
  font-family: var(--bb-font-mono);
  font-size: var(--bb-fs-small);
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.1em;
  color: var(--bb-purple-bright);
}
.bb-vm-compare__facts { display: grid; gap: 6px; margin: 0; }
.bb-vm-compare__facts > div { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 8px; font-size: var(--bb-fs-small); }
.bb-vm-compare__facts dt { margin: 0; font-family: var(--bb-font-mono); font-size: 0.625rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--bb-text-tertiary); padding-top: 2px; }
.bb-vm-compare__facts dd { margin: 0; color: var(--bb-text-secondary); }
.bb-vm-compare__facts dd strong { color: var(--bb-text-primary); }
.bb-vm-not {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 8px 14px;
  align-items: start;
  padding: 10px 14px;
  border: 1px solid var(--bb-negative-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-negative-bg);
}
.bb-vm-not__label {
  padding-top: 2px;
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bb-negative);
  white-space: nowrap;
}
.bb-vm-not__list { margin: 0; padding-left: 1.1em; font-size: var(--bb-fs-small); line-height: var(--bb-leading-body); color: var(--bb-text-secondary); }
.bb-vm-not__list a { color: var(--bb-text-primary); }
.bb-vm-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 8px;
  margin-top: var(--bb-space-3);
}
.bb-vm-fact {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-vm-fact strong { color: var(--bb-text-primary); }
.bb-vm-fact--warn { border-color: var(--bb-caution-border); background-image: linear-gradient(180deg, var(--bb-caution-bg), transparent 70%); }

/* --- 34.9 methodology: sources ------------------------------------------- */
.bb-vm-sources {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 8px;
}
.bb-vm-source {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-vm-source--live { border-color: var(--bb-positive-border); }
.bb-vm-source--research { border-style: dashed; }
.bb-vm-source--rejected { opacity: 0.8; }
.bb-vm-source__role {
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-vm-source--live .bb-vm-source__role { color: var(--bb-positive); }
.bb-vm-source__name { font-size: var(--bb-fs-card-title); color: var(--bb-text-primary); }
.bb-vm-source--rejected .bb-vm-source__name { text-decoration: line-through; text-decoration-color: var(--bb-negative); text-decoration-thickness: 1px; }
.bb-vm-source__text { margin: 0; }

/* --- 34.10 methodology: the Edge meter ------------------------------------ */
.bb-vm-meter { margin: var(--bb-space-3) 0; }
.bb-vm-meter__bar {
  position: relative;
  height: 10px;
  margin: 0 0 10px;
  border-radius: var(--bb-radius-pill);
  background: linear-gradient(90deg, rgb(var(--bb-purple-rgb) / 0.55), rgb(var(--bb-positive-rgb) / 0.35) 50%, rgb(var(--bb-info-rgb) / 0.55));
  box-shadow: inset 0 0 0 1px var(--bb-border);
}
.bb-vm-meter__tick {
  position: absolute;
  top: -4px;
  width: 2px;
  height: 18px;
  border-radius: 1px;
  background: var(--bb-text-primary);
  opacity: 0.55;
}
.bb-vm-meter__tick--l { left: 16.5%; }
.bb-vm-meter__tick--c { left: 50%; opacity: 0.9; }
.bb-vm-meter__tick--r { left: 83.5%; }
.bb-vm-meter__zones {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 8px;
}
.bb-vm-zone {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-vm-zone--higher { border-color: var(--bb-purple-border-strong); }
.bb-vm-zone--aligned { border-color: var(--bb-positive-border); }
.bb-vm-zone--lower { border-color: var(--bb-info-border); }
.bb-vm-zone__arrow { font-family: var(--bb-font-mono); font-size: var(--bb-fs-md); font-weight: var(--bb-fw-bold); }
.bb-vm-zone--higher .bb-vm-zone__arrow { color: var(--bb-purple-bright); }
.bb-vm-zone--aligned .bb-vm-zone__arrow { color: var(--bb-positive); }
.bb-vm-zone--lower .bb-vm-zone__arrow { color: var(--bb-info); }
.bb-vm-zone__name { color: var(--bb-text-primary); }
.bb-vm-zone__read { color: var(--bb-text-secondary); }

/* --- 34.11 methodology: same player, two boards -------------------------- */
.bb-vm-boards {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: var(--bb-space-3);
  align-items: center;
  margin: var(--bb-space-3) 0;
}
.bb-vm-board {
  min-width: 0;
  padding: 12px 14px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
}
.bb-vm-board__title {
  display: block;
  margin-bottom: 8px;
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-vm-board__rows { display: grid; gap: 4px; margin-bottom: 10px; }
.bb-vm-board__rows span { display: block; height: 8px; border-radius: 2px; background: var(--bb-border-strong); }
.bb-vm-board__rows span:nth-child(3) { width: 82%; }
.bb-vm-board__rows span:nth-child(4) { width: 64%; }
.bb-vm-board__rows span:nth-child(5) { width: 48%; }
.bb-vm-board__rows--short span:nth-child(3) { width: 58%; }
.bb-vm-board__rows span.is-you { background: var(--bb-purple-bright); box-shadow: 0 0 10px rgb(var(--bb-purple-rgb) / 0.55); }
.bb-vm-board__reads { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: var(--bb-fs-small); color: var(--bb-text-secondary); }
.bb-vm-board__read strong { color: var(--bb-text-primary); font-family: var(--bb-font-mono); }
.bb-vm-boards__eq {
  text-align: center;
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  line-height: 1.4;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bb-purple-bright);
}

/* --- 34.12 methodology: not a sum ---------------------------------------- */
.bb-vm-notsum {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  margin: 0 0 var(--bb-space-4);
  padding: 18px 16px 14px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
}
.bb-vm-notsum__eq {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--bb-font-mono);
  font-size: 1.6rem;
  font-weight: var(--bb-fw-bold);
  color: var(--bb-text-primary);
}
.bb-vm-notsum__op { font-size: 1rem; font-weight: var(--bb-fw-regular); color: var(--bb-text-tertiary); }
.bb-vm-notsum__strike {
  position: absolute;
  top: 34px;
  left: calc(50% - 90px);
  width: 180px;
  height: 3px;
  border-radius: 2px;
  background: var(--bb-negative);
  transform: rotate(-8deg);
  box-shadow: 0 0 10px rgb(var(--bb-negative-rgb) / 0.6);
}
.bb-vm-notsum__caption { font-size: var(--bb-fs-small); color: var(--bb-text-secondary); text-align: center; }
.bb-vm-checklist {
  display: grid;
  gap: 6px;
  margin: 0 0 var(--bb-space-4);
  padding-left: 1.2em;
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-vm-checklist strong { color: var(--bb-text-primary); }

/* --- 34.13 methodology: the validation timeline -------------------------- */
.bb-vm-timeline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}
.bb-vm-step {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  padding: 14px 12px 10px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-vm-step::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  background: var(--bb-purple-rail);
  border-radius: var(--bb-radius-md) var(--bb-radius-md) 0 0;
}
.bb-vm-step strong { color: var(--bb-text-primary); }
.bb-vm-step__dot {
  width: 8px;
  height: 8px;
  margin-bottom: 4px;
  border-radius: 50%;
  background: var(--bb-purple-bright);
  box-shadow: 0 0 8px rgb(var(--bb-purple-rgb) / 0.6);
}

/* --- 34.14 methodology: examples, sources table, limits, links ---------- */
.bb-vm-examples {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--bb-space-3);
}
.bb-vm-example {
  min-width: 0;
  padding: 12px 14px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
}
.bb-vm-example__kicker {
  display: inline-block;
  margin-bottom: 6px;
  padding: 2px 8px;
  border-radius: var(--bb-radius-pill);
  border: 1px solid var(--bb-purple-border);
  background: var(--bb-purple-soft);
  font-family: var(--bb-font-mono);
  font-size: 0.625rem;
  font-weight: var(--bb-fw-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bb-purple-bright);
}
.bb-vm-example__title { margin: 0 0 4px; font-size: var(--bb-fs-card-title); font-weight: var(--bb-fw-semibold); color: var(--bb-text-primary); }
.bb-vm-example__text { margin: 0; font-size: var(--bb-fs-small); line-height: var(--bb-leading-body); color: var(--bb-text-secondary); }
.bb-vm-srctable { display: grid; gap: 4px; }
.bb-vm-srcrow {
  display: grid;
  grid-template-columns: minmax(120px, 180px) minmax(0, 1fr);
  gap: 12px;
  padding: 8px 12px;
  border: 1px solid var(--bb-border-subtle);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-vm-srcrow strong { color: var(--bb-text-primary); }
.bb-vm-nots {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 6px 14px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
}
.bb-vm-nots li {
  position: relative;
  padding: 8px 10px 8px 30px;
  border: 1px solid var(--bb-border-subtle);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
}
.bb-vm-nots li::before {
  content: "\2715";
  position: absolute;
  left: 10px;
  top: 8px;
  font-family: var(--bb-font-mono);
  font-weight: var(--bb-fw-bold);
  color: var(--bb-negative);
}
.bb-vm-links { margin-bottom: var(--bb-space-5); }
.bb-vm-linkgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 8px;
}
.bb-vm-linkcard {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  padding: 12px 14px;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface-card);
  font-size: var(--bb-fs-small);
  line-height: var(--bb-leading-body);
  color: var(--bb-text-secondary);
  text-decoration: none;
  transition: border-color var(--bb-transition-fast), background var(--bb-transition-fast);
}
.bb-vm-linkcard strong { color: var(--bb-purple-bright); }
.bb-vm-linkcard:hover,
.bb-vm-linkcard:focus-visible { border-color: var(--bb-purple-border-strong); background: var(--bb-purple-wash); text-decoration: none; }

/* --- 34.15 the phone tier ------------------------------------------------ */
@media (max-width: 900px) {
  .bb-pf-hero,
  .bb-vm-hero {
    grid-template-columns: minmax(0, 1fr);
  }
  .bb-pf-hero__aside { justify-content: flex-start; }
  .bb-pf-jump { grid-template-columns: repeat(2, minmax(0, 1fr)); justify-content: start; }
  .bb-pf-split,
  .bb-pf-finish,
  .bb-vm-boards {
    grid-template-columns: 1fr;
  }
  .bb-pf-split__arrow { padding: 2px 0; }
  .bb-pf-split__arrow span {
    writing-mode: horizontal-tb;
    padding: 0 12px;
    border: 0;
    border-top: 1px dashed var(--bb-purple-border-strong);
    border-bottom: 1px dashed var(--bb-purple-border-strong);
  }
  .bb-vm-boards__eq { padding: 2px 0; }
  .bb-vm-track { padding: 10px; }
  .bb-vm-node { white-space: normal; }
  .bb-vm-compare__facts > div { grid-template-columns: 84px minmax(0, 1fr); }
  .bb-vm-srcrow { grid-template-columns: 1fr; gap: 2px; }
  .bb-vm-not { grid-template-columns: 1fr; gap: 4px; }
  .bb-pf-group__index { font-size: 1.3rem; }
  .bb-pf-legend { padding: 12px 14px 10px; }
}
@media (max-width: 720px) {
  .bb-pf-jump__link { white-space: normal; }
  .bb-vm-notsum__eq { font-size: 1.3rem; }
  .bb-vm-notsum__strike { top: 30px; }
}


/* =====================================================================
   35. THE PHONE TOPBAR, WRAPPED (pre-reset Fable pass, 2026-09)
   =====================================================================
   Two bounded corrections to the phone shell, measured at 390x844 in
   real Chromium before this pass:

   (a) THE LIVE WIRE STRIP. The topbar becomes a two-row flex wrap: the
       brand and the four controls on row one, the SAME `.bb-topbar__
       center` cluster on row two as a full-bleed strip
       (`--bb-lwstrip-height`). Every consumer of `--bb-topbar-height`
       -- the nav and drawer sheets' inset, the sticky context bar, the
       shell's grid row -- follows the taller token automatically, which
       is what keeps this a layout change and not a re-plumbing. Desktop
       (>900px) is untouched: the rail stays in the centre of one row.

   (b) OPTICAL ALIGNMENT. The account button sat 8px shorter than the
       40px icon buttons beside it; the search trigger collapsed to a
       narrow pill with an undersized glyph; the left cluster's gaps were
       uneven. Every control on row one is now the same 40px box, the
       search glyph is the same weight as its neighbours, and the
       clusters share one gap. No control was removed or renamed. */
@media (max-width: 900px) {
  :root {
    --bb-lwstrip-height: 32px;
    --bb-topbar-height: calc(58px + var(--bb-lwstrip-height) + var(--bb-safe-top));
  }
  .bb-topbar {
    flex-wrap: wrap;
    align-content: flex-start;
    row-gap: 0;
    column-gap: var(--bb-space-2);
    padding-bottom: 0;
  }
  .bb-topbar__left,
  .bb-topbar__right {
    min-height: 58px;
    gap: var(--bb-space-2);
  }
  .bb-topbar__left { flex: 1 1 auto; }
  .bb-topbar__right { flex: 0 0 auto; }
  .bb-topbar__center {
    order: 3;
    flex: 1 1 100%;
    min-width: 0;
    height: var(--bb-lwstrip-height);
    margin: 0 calc(-1 * (var(--bb-space-2) + var(--bb-safe-right))) 0 calc(-1 * (var(--bb-space-2) + var(--bb-safe-left)));
    justify-content: stretch;
    overflow: hidden;
    border-top: 1px solid rgb(var(--bb-purple-rgb) / 0.16);
  }
  /* The off-canvas sheets open UNDER ROW ONE and OVER THE STRIP: the
     strip is page context, not chrome the sheet must respect, and a
     sheet that started 32px lower would push the drawer-owned
     destinations (`test_draft_weekend_mobile_browser.py`'s own
     measurement) that much further toward the fold. `z-index: 61` lifts
     both sheets above the topbar's 60 for exactly the strip's band --
     they still begin below the controls, so the hamburger that opened
     them stays visible and tappable. The scrim (45) is untouched. */
  .bb-nav,
  .bb-drawer {
    top: calc(58px + var(--bb-safe-top));
    z-index: 61;
  }
  /* (b) one 40px box for every control on the row */
  .bb-nav-toggle,
  .bb-topbar__right .bb-btn--icon,
  .bb-search__trigger,
  .bb-topbar__right > [data-bb-menu] > .bb-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--bb-tap-min);
    height: var(--bb-tap-min);
    padding-top: 0;
    padding-bottom: 0;
    line-height: 1;
  }
  .bb-search__trigger {
    width: var(--bb-tap-min);
    min-width: var(--bb-tap-min);
    padding-inline: 0;
    gap: 0;
  }
  .bb-search__glyph {
    font-size: 1.125rem;
    line-height: 1;
    color: var(--bb-text-secondary);
  }
  .bb-topbar__right > [data-bb-menu] > .bb-btn {
    max-width: 96px;
    padding-inline: 10px;
    font-size: var(--bb-fs-sm);
  }
  .bb-brand { gap: 8px; }
}



/* =====================================================================
   36. FABLE PACK 01 (2026-09) -- THE SHELL AND THE SURFACE FAMILIES
   =====================================================================
   The first true design pass. This section is the STRUCTURAL half of
   the shared visual system (`identity.css` section 19 is the paint;
   `tokens.css`'s FABLE block is the vocabulary). It loads after every
   section above, so at equal specificity it wins -- which is how a
   compact shell replaces the Phase 1B "command rail + instrument band
   + hero" composition without rewriting those sections.

   THE SHELL, IN ONE LINE EACH
     desktop  left rail (232px) + compact top (52px bar + 40px context
              strip) + primary canvas + optional intel drawer
     tablet   same rail, drawer becomes a sheet (unchanged 1200 tier)
     phone    52px header + 26px Live Wire strip + compact two-row
              context + content + 5-slot bottom navigation

   Nothing here changes a route, a resolver, a query param or an htmx
   target. Same markup, same tests, a different instrument.
   ================================================================== */

/* --- 36.1 GEOMETRY ---------------------------------------------------
   `--bb-topbar-height` is read by every sticky offset and sheet inset
   in the product, so the shell shrinks in one place. */
:root {
  --bb-topbar-height: calc(var(--bb-shell-topbar) + var(--bb-safe-top));
  --bb-contextbar-height: var(--bb-shell-contextbar);
  --bb-nav-width: var(--bb-rail-width);
}
@media (min-width: 1440px) {
  :root { --bb-nav-width: 240px; }
}
@media (min-width: 1680px) {
  :root { --bb-nav-width: var(--bb-rail-width-wide); --bb-drawer-width: var(--bb-drawer-width-wide); }
}
@media (min-width: 2300px) {
  :root { --bb-nav-width: var(--bb-rail-width-hq); --bb-drawer-width: var(--bb-drawer-width-hq); }
}

/* --- 36.2 THE TOP BAR: a utility strip, not a title bar ------------- */
.bb-topbar {
  gap: var(--bb-space-4);
  padding-left: calc(var(--bb-space-4) + var(--bb-safe-left));
  padding-right: calc(var(--bb-space-4) + var(--bb-safe-right));
}
.bb-brand {
  gap: 10px;
}
.bb-mark--lockup {
  width: 28px;
  height: 25px;
}
.bb-wordmark {
  font: var(--bb-type-brand);
  letter-spacing: var(--bb-tracking-brand);
}
.bb-wordmark small {
  margin-top: 3px;
  font-size: 0.5625rem;
  letter-spacing: 0.2em;
}
.bb-search__trigger {
  min-width: 260px;
  min-height: var(--bb-control-md);
  border-radius: var(--bb-radius-md);
}
/* The account control: an initial in a 28px tile, the name beside it
   on desktop, the name yielding on a phone (documented in
   `test_ui_contract_sweep.py`). One button, one tab stop, as before. */
.bb-usermenu {
  gap: 8px;
  min-height: var(--bb-control-md);
  padding-inline: 6px 10px;
}
.bb-usermenu__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: var(--bb-radius-sm);
  font: var(--bb-type-chip);
  letter-spacing: 0;
  text-transform: uppercase;
}
.bb-usermenu__name {
  max-width: 14ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bb-usermenu__caret {
  font-size: 0.625rem;
}
.bb-topbar__right .bb-btn--icon {
  width: var(--bb-control-md);
  min-height: var(--bb-control-md);
  border-radius: var(--bb-radius-md);
}

/* --- 36.3 THE RAIL: destinations, grouped, quiet -------------------
   Group labels are tiny mono captions with no rules, no seams and no
   index numbers. Flagship rows keep their hint line and a slightly
   taller box; support rows are one line. The active row is a 3px
   purple bar plus a soft fill (paint in identity.css section 19). */
.bb-nav {
  padding: 14px 10px 20px;
}
.bb-navgroup {
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--bb-border-subtle);
}
.bb-navgroup:first-of-type {
  padding-bottom: 10px;
}
.bb-navgroup__label {
  gap: 8px;
  padding: 0 10px 6px;
  font: var(--bb-type-label);
  letter-spacing: 0.16em;
}
.bb-navgroup__label::before {
  width: 8px;
  height: 2px;
  margin-right: 0;
}
.bb-navgroup__label::after {
  content: none;
}
.bb-navgroup__items {
  gap: 1px;
}
.bb-navitem {
  gap: 10px;
  min-height: var(--bb-rail-row);
  padding: 5px 10px 5px 9px;
  border-left-width: 3px;
  border-radius: var(--bb-radius-md);
}
.bb-navitem--flagship {
  min-height: var(--bb-rail-row-flagship);
  padding: 6px 10px 6px 9px;
}
.bb-navitem--flagship .bb-navitem__icon {
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  border-radius: 0;
}
.bb-navitem--flagship .bb-navitem__label {
  font-size: var(--bb-fs-sm);
  letter-spacing: 0;
}
.bb-navitem--flagship .bb-navitem__hint {
  margin-top: 0;
  font-size: 0.6875rem;
}
.bb-navitem--flagship::after {
  content: none;
}
.bb-navitem:not(.bb-navitem--flagship) {
  padding-left: 9px;
}
.bb-navitem:not(.bb-navitem--flagship) .bb-navitem__icon {
  width: 16px;
  height: 16px;
}
.bb-navitem:not(.bb-navitem--flagship) .bb-navitem__label {
  font-size: var(--bb-fs-sm);
}
.bb-nav__foot {
  margin-top: var(--bb-space-3);
  padding: 10px 10px 0;
  border: 0;
  border-top: 1px solid var(--bb-border-subtle);
  border-radius: 0;
  font: var(--bb-type-label);
  letter-spacing: 0.12em;
}
.bb-nav__foot .bb-mark {
  width: 14px;
  height: 12px;
}

/* --- 36.4 THE CONTEXT STRIP: one thin row of facts and controls ------ */
.bb-contextbar {
  min-height: var(--bb-contextbar-height);
  padding: 4px 16px;
  gap: 6px 10px;
}
.bb-contextbar__group .bb-ctxbtn {
  min-height: 30px;
  padding: 2px 10px 2px 10px;
  gap: 8px;
  border-radius: var(--bb-radius-md);
}
.bb-fact__label {
  font: var(--bb-type-label);
  font-size: 0.5625rem;
  letter-spacing: 0.16em;
}
.bb-ctxbtn .bb-fact__value {
  font-size: var(--bb-fs-sm);
  font-weight: var(--bb-fw-semibold);
}
.bb-fact--secondary {
  padding-left: 10px;
  border-left: 1px solid var(--bb-border);
}
.bb-fact--secondary .bb-fact__value {
  font-size: var(--bb-fs-micro);
}
.bb-contextbar__divider {
  width: 1px;
}
.bb-ctxbtn--accent {
  min-height: 30px;
  padding: 0 10px;
  border-radius: var(--bb-radius-md);
  font: var(--bb-type-chip);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.bb-ctxsync {
  min-height: 30px;
  padding-inline: 10px;
  border-radius: var(--bb-radius-md);
}
.bb-contextbar .bb-fresh {
  padding: 1px 8px;
}

/* --- 36.5 THE PAGE HEADER: a compact locator, not a hero --------------
   eyebrow / title / subject / context / rail, at app scale. The only
   ornament is the wing under it (identity.css keeps `::after`). */
.bb-pagehead {
  padding: 2px 0 14px;
  margin-bottom: var(--bb-space-4);
  border: 0;
  border-radius: 0;
  overflow: visible;
  gap: var(--bb-space-2) var(--bb-space-4);
}
.bb-pagehead::after {
  height: 2px;
}
.bb-pagehead__eyebrow {
  gap: 7px;
  margin-bottom: 4px;
  font: var(--bb-type-label);
  letter-spacing: 0.16em;
}
.bb-pagehead__eyebrow::before {
  width: 6px;
  height: 6px;
  border-radius: 1px;
  box-shadow: none;
}
.bb-pagehead__title {
  font: var(--bb-type-page-title);
  letter-spacing: var(--bb-tracking-tight);
}
.bb-pagehead__subject {
  margin-top: 5px;
  font: var(--bb-type-helper);
  max-width: 76ch;
}
.bb-pagehead__context {
  margin-top: 6px;
  font: var(--bb-type-evidence);
}
.bb-pagehead__rail {
  gap: var(--bb-space-2);
}
@media (min-width: 1900px) {
  .bb-pagehead {
    padding: 2px 0 14px;
  }
}
.bb-sectionhead {
  margin-bottom: var(--bb-space-3);
}
.bb-sectionhead__title {
  font: var(--bb-type-section);
}
.bb-sectionhead__note {
  font: var(--bb-type-meta);
}

/* The flagship hero (`.bb-hero`, Command Center / Draft Ops / Mock
   Draft / League Intelligence) is NOT redesigned here -- those pages
   have their own later packs -- but it takes the same scale discipline
   so no page opens with a marketing band. */
.bb-hero {
  padding: 18px 22px 16px;
  border-radius: var(--bb-radius-lg);
}
.bb-hero__eyebrow {
  font: var(--bb-type-label);
  letter-spacing: 0.16em;
}
.bb-hero__eyebrow::before {
  width: 6px;
  height: 6px;
  box-shadow: none;
}
.bb-hero__title {
  font-size: clamp(1.5rem, 1.8vw, 1.875rem);
  line-height: 1.1;
}

/* --- 36.6 SURFACE FAMILIES --------------------------------------------
   Eight reusable faces. A page composes from these rather than from
   one rounded card repeated twelve times. Paint is in identity.css.

     A  PRIMARY INTELLIGENCE   .bb-icard--primary      (existing)
     B  SUPPORTING EVIDENCE    .bb-icard / .bb-icard--quiet / .bb-evidence (existing)
     C  DECISION / RECOMMEND.  .bb-reco                (new, this section)
     D  LIVE / TACTICAL        .bb-live-surface        (new)
     E  SUMMARY / STATUS STRIP .bb-strip               (existing)
     F  DATA TABLE / DENSE LIST .bb-table / .bb-rows   (existing / new)
     G  DISCLOSURE             .bb-disclosure          (existing)
     H  UTILITY / ACCOUNT      .bb-utility             (new)
   plus three COMPOSITION helpers -- `.bb-canvas` (split canvas),
   `.bb-zone` (a full-width band, no card frame) and `.bb-attention`
   (an attention-first block that breaks a grid). */
.bb-icard {
  padding: 14px 16px;
  margin-bottom: var(--bb-space-3);
}
.bb-icard--primary {
  padding: 16px 18px 16px 20px;
}
.bb-icard--primary::before {
  width: 320px;
  height: 110px;
  opacity: 0.035;
}
.bb-icard__foot {
  font: var(--bb-type-meta);
}

/* C. DECISION / RECOMMENDATION -- the trust pattern.
   verdict row -> headline -> WHY (expandable) -> risks / alternatives
   -> evidence -> validity strip. Concise by default: the verdict, the
   headline and the validity are always visible; everything else is a
   disclosure. Tone is carried by `data-tone` on the verdict word AND by
   the word itself -- never colour alone. */
.bb-reco {
  position: relative;
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-raised);
  padding: 0;
  margin-bottom: var(--bb-space-3);
  overflow: hidden;
}
.bb-reco__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 14px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--bb-border-subtle);
}
.bb-reco__kicker {
  font: var(--bb-type-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-reco__verdict {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: var(--bb-type-decision);
  letter-spacing: 0.01em;
  color: var(--bb-text-primary);
}
.bb-reco__verdict::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 2px;
  background: var(--bb-neutral);
  flex: none;
}
.bb-reco__verdict[data-tone="positive"] { color: var(--bb-positive); }
.bb-reco__verdict[data-tone="positive"]::before { background: var(--bb-positive); }
.bb-reco__verdict[data-tone="negative"] { color: var(--bb-negative); }
.bb-reco__verdict[data-tone="negative"]::before { background: var(--bb-negative); }
.bb-reco__verdict[data-tone="caution"] { color: var(--bb-caution); }
.bb-reco__verdict[data-tone="caution"]::before { background: var(--bb-caution); }
.bb-reco__verdict[data-tone="info"] { color: var(--bb-info); }
.bb-reco__verdict[data-tone="info"]::before { background: var(--bb-info); }
.bb-reco__confidence {
  margin-left: auto;
}
.bb-reco__body {
  padding: 12px 16px 14px;
}
.bb-reco__headline {
  margin: 0;
  font: var(--bb-type-card);
  color: var(--bb-text-primary);
  max-width: 72ch;
}
.bb-reco__why {
  margin: 8px 0 0;
  font: var(--bb-type-body);
  color: var(--bb-text-secondary);
  max-width: 72ch;
}
.bb-reco__sections {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0;
  border-top: 1px solid var(--bb-border-subtle);
}
.bb-reco__section {
  padding: 10px 16px 12px;
  border-right: 1px solid var(--bb-border-subtle);
  min-width: 0;
}
.bb-reco__section:last-child {
  border-right: 0;
}
.bb-reco__label {
  display: block;
  margin-bottom: 6px;
  font: var(--bb-type-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-reco__section--risks .bb-reco__label { color: var(--bb-caution); }
.bb-reco__list {
  margin: 0;
  padding: 0;
  list-style: none;
  font: var(--bb-type-helper);
  color: var(--bb-text-secondary);
}
.bb-reco__list li {
  position: relative;
  padding-left: 12px;
  margin-bottom: 4px;
}
.bb-reco__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 5px;
  height: 1px;
  background: var(--bb-border-strong);
}
.bb-reco__section--risks .bb-reco__list li::before { background: var(--bb-caution); }
.bb-reco__evidence {
  margin: 0;
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 3px 12px;
  font: var(--bb-type-evidence);
}
.bb-reco__evidence dt { color: var(--bb-text-tertiary); margin: 0; }
.bb-reco__evidence dd { color: var(--bb-text-secondary); margin: 0; font-variant-numeric: tabular-nums; }
.bb-reco__foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 14px;
  padding: 8px 16px;
  border-top: 1px solid var(--bb-border-subtle);
  background: var(--bb-bg-elevated);
  font: var(--bb-type-meta);
  color: var(--bb-text-tertiary);
}
.bb-reco .bb-disclosure {
  margin-top: 10px;
}
@media (max-width: 620px) {
  .bb-reco__sections {
    grid-template-columns: 1fr;
  }
  .bb-reco__section {
    border-right: 0;
    border-bottom: 1px solid var(--bb-border-subtle);
  }
  .bb-reco__section:last-child {
    border-bottom: 0;
  }
}

/* RECOMMENDATION VALIDITY -- the third freshness semantic. A mono
   stamp with a clock glyph; the STATE WORD is always printed. */
.bb-validity {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: var(--bb-type-chip);
  letter-spacing: 0.04em;
  color: var(--bb-validity-unknown);
  white-space: nowrap;
}
.bb-validity::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  box-sizing: border-box;
  flex: none;
}
.bb-validity[data-state="valid"]    { color: var(--bb-validity-valid); }
.bb-validity[data-state="expiring"] { color: var(--bb-validity-expiring); }
.bb-validity[data-state="expired"]  { color: var(--bb-validity-expired); }
.bb-validity[data-state="expired"]::before { border-style: dashed; }
.bb-validity[data-state="unknown"]  { color: var(--bb-validity-unknown); }
.bb-validity__word { text-transform: uppercase; font-weight: var(--bb-fw-bold); }
.bb-validity__note { font-family: var(--bb-font-ui); font-weight: var(--bb-fw-regular); letter-spacing: 0; text-transform: none; color: var(--bb-text-tertiary); }

/* NEW INTELLIGENCE -- the second freshness semantic. Purple, because a
   new observation is Blackbird's own voice. A dot form for dense rows,
   a word form for headlines. Never used for "data was refreshed". */
.bb-newmark {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 1px 7px;
  border-radius: var(--bb-radius-sm);
  border: 1px solid var(--bb-new-border);
  background: var(--bb-new-bg);
  color: var(--bb-new);
  font: var(--bb-type-chip);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: middle;
}
.bb-newmark__age {
  font-weight: var(--bb-fw-regular);
  letter-spacing: 0;
  text-transform: none;
  opacity: 0.85;
}
.bb-newmark--dot {
  padding: 0;
  border: 0;
  background: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--bb-new);
  box-shadow: 0 0 0 2px rgb(var(--bb-purple-rgb) / 0.22);
}

/* D. LIVE / TACTICAL SURFACE. Graphite with a cyan seam on the left,
   mono readouts, and a state chip. `data-state` on the surface lets a
   whole panel go quiet (final/stale) or lit (live) with one attribute;
   the `.bb-live-state` chip family below prints the word. When a game
   is live the surface is allowed to dominate: `.bb-live-surface--lead`
   spans the canvas and is the first thing under the page header. */
.bb-live-surface {
  position: relative;
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-raised);
  padding: 12px 16px 12px 18px;
  margin-bottom: var(--bb-space-3);
  box-shadow: inset 3px 0 0 var(--bb-border-strong);
}
.bb-live-surface[data-state="live"],
.bb-live-surface[data-state="halftime"] {
  box-shadow: inset 3px 0 0 var(--bb-live);
  border-color: var(--bb-live-border);
}
.bb-live-surface[data-state="attention"] {
  box-shadow: inset 3px 0 0 var(--bb-attention);
  border-color: var(--bb-attention-border);
}
.bb-live-surface[data-state="final"],
.bb-live-surface[data-state="stale"],
.bb-live-surface[data-state="unknown"] {
  background: var(--bb-surface);
}
.bb-live-surface--lead {
  padding: 16px 20px 16px 22px;
}
.bb-live-surface__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 12px;
  margin-bottom: 8px;
}
.bb-live-surface__title {
  margin: 0;
  font: var(--bb-type-card);
  color: var(--bb-text-primary);
}
.bb-live-surface__meta {
  margin-left: auto;
  font: var(--bb-type-evidence);
  color: var(--bb-text-tertiary);
}
.bb-live-surface__readout {
  font: var(--bb-type-live);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: var(--bb-text-primary);
}
.bb-live-surface__readout small {
  font: var(--bb-type-metric);
  color: var(--bb-text-tertiary);
}

/* LIVE STATE CHIP FAMILY. Seven states, each a WORD plus a hue plus a
   dot SHAPE (filled = happening, hollow = not yet, dashed = uncertain,
   square = done). The same chip serves Game Day, the Live Wire strip,
   Lineup Radar time blocks and any future tactical panel. */
.bb-live-state {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px;
  border-radius: var(--bb-radius-sm);
  border: 1px solid var(--bb-border-strong);
  background: var(--bb-bg-elevated);
  color: var(--bb-text-secondary);
  font: var(--bb-type-chip);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.bb-live-state::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
  box-sizing: border-box;
}
.bb-live-state[data-state="live"]      { color: var(--bb-live); border-color: var(--bb-live-border); background: var(--bb-live-bg); }
.bb-live-state[data-state="live"]::before { box-shadow: var(--bb-glow-live); }
.bb-live-state[data-state="halftime"]  { color: var(--bb-live); border-color: var(--bb-live-border); }
.bb-live-state[data-state="halftime"]::before { background: transparent; border: 1.5px solid currentColor; border-bottom-color: transparent; }
.bb-live-state[data-state="upcoming"]  { color: var(--bb-text-secondary); }
.bb-live-state[data-state="upcoming"]::before { background: transparent; border: 1.5px solid currentColor; }
.bb-live-state[data-state="final"]     { color: var(--bb-text-tertiary); border-color: var(--bb-border); }
.bb-live-state[data-state="final"]::before { border-radius: 1px; }
.bb-live-state[data-state="stale"]     { color: var(--bb-caution); border-color: var(--bb-caution-border); background: var(--bb-caution-bg); }
.bb-live-state[data-state="stale"]::before { background: transparent; border: 1.5px dashed currentColor; }
.bb-live-state[data-state="unknown"]   { color: var(--bb-text-tertiary); border-style: dashed; }
.bb-live-state[data-state="unknown"]::before { background: transparent; border: 1.5px dotted currentColor; }
.bb-live-state[data-state="attention"] { color: var(--bb-attention); border-color: var(--bb-attention-border); background: var(--bb-attention-bg); }
.bb-live-state[data-state="attention"]::before { border-radius: 1px; transform: rotate(45deg); width: 6px; height: 6px; }
.bb-live-state__detail {
  font-weight: var(--bb-fw-regular);
  letter-spacing: 0;
  text-transform: none;
  opacity: 0.9;
}

/* F. DENSE ROW LIST -- rows without a table: a hairline between each,
   a leading cell, a main cell, a trailing mono value. */
.bb-rows {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-card);
  overflow: hidden;
}
.bb-rows__item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 7px 12px;
  border-bottom: 1px solid var(--bb-border-subtle);
  min-height: 36px;
}
.bb-rows__item:last-child {
  border-bottom: 0;
}
.bb-rows__lead {
  font: var(--bb-type-evidence);
  color: var(--bb-text-tertiary);
  min-width: 3ch;
  text-align: right;
}
.bb-rows__main {
  min-width: 0;
  font: var(--bb-type-body);
  color: var(--bb-text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bb-rows__sub {
  display: block;
  font: var(--bb-type-meta);
  color: var(--bb-text-tertiary);
}
.bb-rows__end {
  font: var(--bb-type-metric);
  font-variant-numeric: tabular-nums;
  color: var(--bb-text-primary);
  text-align: right;
}
.bb-rows__item[data-tone="attention"] { box-shadow: inset 3px 0 0 var(--bb-attention); }
.bb-rows__item[data-tone="live"]      { box-shadow: inset 3px 0 0 var(--bb-live); }
.bb-rows__item[data-tone="negative"]  { box-shadow: inset 3px 0 0 var(--bb-negative); }
.bb-rows__item[data-tone="positive"]  { box-shadow: inset 3px 0 0 var(--bb-positive); }
.bb-rows__item.is-selected { background: var(--bb-purple-soft); box-shadow: inset 3px 0 0 var(--bb-purple-bright); }

/* Tables: header row quieter, rows tighter, numerics aligned. */
.bb-table thead th {
  font: var(--bb-type-label);
  letter-spacing: 0.1em;
  padding: 7px var(--bb-space-3);
}
.bb-table {
  font-size: var(--bb-fs-sm);
}

/* H. UTILITY / ACCOUNT PANEL -- lower priority by construction: a
   lighter border, smaller type, a tertiary heading. Used for account,
   help, settings and Updates-class content. */
.bb-utility {
  border: 1px solid var(--bb-border-subtle);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface);
  padding: 12px 14px;
  margin-bottom: var(--bb-space-3);
  font: var(--bb-type-helper);
  color: var(--bb-text-secondary);
}
.bb-utility__title {
  margin: 0 0 6px;
  font: var(--bb-type-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-utility p {
  margin: 0 0 6px;
}
.bb-utility p:last-child {
  margin-bottom: 0;
}

/* COMPOSITION: a split canvas -- primary workspace left, support
   column right; collapses to one column below the phone tier. */
.bb-canvas {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 340px);
  gap: var(--bb-space-4);
  align-items: start;
}
.bb-canvas--wide-aside {
  grid-template-columns: minmax(0, 1fr) minmax(300px, 420px);
}
.bb-canvas__main,
.bb-canvas__aside {
  min-width: 0;
}
@media (max-width: 1200px) {
  .bb-canvas,
  .bb-canvas--wide-aside {
    grid-template-columns: 1fr;
  }
}

/* COMPOSITION: a zone -- a full-width band with a hairline and a
   caption, no card frame. The antidote to card soup. */
.bb-zone {
  padding: 12px 0 4px;
  margin-bottom: var(--bb-space-3);
  border-top: 1px solid var(--bb-border);
}
.bb-zone__head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 10px;
}
.bb-zone__title {
  margin: 0;
  font: var(--bb-type-section);
  color: var(--bb-text-primary);
}
.bb-zone__note {
  font: var(--bb-type-meta);
  color: var(--bb-text-tertiary);
}
.bb-zone__note--end {
  margin-left: auto;
}

/* COMPOSITION: attention-first block. My Blackbird's "what matters
   right now" is allowed to break a symmetric grid: this block spans
   the full canvas, carries an amber seam and a count, and sits ABOVE
   whatever grid follows. */
.bb-attention {
  grid-column: 1 / -1;
  border: 1px solid var(--bb-attention-border);
  border-radius: var(--bb-radius-lg);
  background: var(--bb-surface-raised);
  box-shadow: inset 3px 0 0 var(--bb-attention);
  padding: 10px 14px 12px 16px;
  margin-bottom: var(--bb-space-3);
}
.bb-attention--urgent {
  border-color: var(--bb-negative-border);
  box-shadow: inset 3px 0 0 var(--bb-negative);
}
.bb-attention__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}
.bb-attention__title {
  margin: 0;
  font: var(--bb-type-card);
  color: var(--bb-text-primary);
}
.bb-attention__count {
  font: var(--bb-type-chip);
  padding: 1px 7px;
  border-radius: var(--bb-radius-sm);
  border: 1px solid var(--bb-attention-border);
  color: var(--bb-attention);
}
.bb-attention--urgent .bb-attention__count {
  border-color: var(--bb-negative-border);
  color: var(--bb-negative);
}

/* TIME BLOCK -- the kickoff-window grammar Lineup Radar will inherit:
   a mono time caption with a rule, then rows. Not a card. */
.bb-timeblock {
  margin-bottom: var(--bb-space-3);
}
.bb-timeblock__head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
  font: var(--bb-type-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bb-text-secondary);
}
.bb-timeblock__head::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--bb-border-subtle);
}
.bb-timeblock--next .bb-timeblock__head {
  color: var(--bb-attention);
}
.bb-timeblock--next .bb-timeblock__head::after {
  background: var(--bb-attention-border);
}
.bb-timeblock--live .bb-timeblock__head {
  color: var(--bb-live);
}
.bb-timeblock--live .bb-timeblock__head::after {
  background: var(--bb-live-border);
}

/* --- 36.7 TYPOGRAPHY ROLE UTILITIES ------------------------------------
   For the places a role is needed without a component around it. */
.bb-type-page-title { font: var(--bb-type-page-title); letter-spacing: var(--bb-tracking-tight); color: var(--bb-text-primary); }
.bb-type-live       { font: var(--bb-type-live); font-variant-numeric: tabular-nums; color: var(--bb-text-primary); }
.bb-type-decision   { font: var(--bb-type-decision); color: var(--bb-text-primary); }
.bb-type-section    { font: var(--bb-type-section); color: var(--bb-text-primary); }
.bb-type-card       { font: var(--bb-type-card); color: var(--bb-text-primary); }
.bb-type-value      { font: var(--bb-type-value); font-variant-numeric: tabular-nums; color: var(--bb-text-primary); }
.bb-type-metric     { font: var(--bb-type-metric); font-variant-numeric: tabular-nums; color: var(--bb-text-secondary); }
.bb-type-body       { font: var(--bb-type-body); color: var(--bb-text-primary); }
.bb-type-helper     { font: var(--bb-type-helper); color: var(--bb-text-secondary); }
.bb-type-meta       { font: var(--bb-type-meta); color: var(--bb-text-tertiary); }
.bb-type-evidence   { font: var(--bb-type-evidence); color: var(--bb-text-tertiary); }
.bb-type-label      { font: var(--bb-type-label); letter-spacing: 0.12em; text-transform: uppercase; color: var(--bb-text-tertiary); }
.bb-type-chip       { font: var(--bb-type-chip); letter-spacing: var(--bb-tracking-chip); }

/* --- 36.8 LOADING / EMPTY / ERROR --------------------------------------
   The `.bb-state` shape stays (kind / title / text / detail). What
   changes: it is a quiet graphite panel with a small tone mark, never a
   loud card. A LOADING skeleton is a static striped block (no shimmer
   under reduced motion -- `hq.css` section 0 zeroes the animation). */
.bb-state {
  padding: 12px 14px;
  border-color: var(--bb-border);
  gap: 10px;
}
.bb-state__mark {
  width: 26px;
  height: 26px;
  border-radius: var(--bb-radius-sm);
  font-size: var(--bb-fs-micro);
}
.bb-state__kind {
  font: var(--bb-type-label);
  letter-spacing: 0.14em;
}
.bb-state__title {
  font: var(--bb-type-card);
}
.bb-state__text {
  font: var(--bb-type-helper);
}
.bb-skeleton-group {
  display: block;
}
.bb-skeleton--block {
  height: 72px;
  margin: 6px 0;
}
.bb-skeleton--value {
  width: 6ch;
  height: 22px;
  display: inline-block;
}

/* --- 36.9 SELECTED / ACTIVE / HOVER / FOCUS ---------------------------
   One grammar everywhere: hover = raised surface, selected = purple
   soft fill + 3px purple bar (or a 2px underline on tabs / bottom nav),
   focus = the bright-purple ring (section 0). A selected state is
   never colour alone: the bar/underline is the second signal. */
.bb-tab {
  padding: 7px 12px;
  font-size: var(--bb-fs-sm);
  border-bottom-width: 2px;
}
.bb-actions .bb-btn.is-active,
.bb-chip.is-active,
.bb-btn.is-active {
  box-shadow: inset 0 -2px 0 var(--bb-purple-bright);
}

/* --- 36.10 THE PHONE SHELL --------------------------------------------
   52px header: menu, mark, then search / messages / drawer / account
   as four equal 44px targets. The Live Wire strip is a 26px second row.
   The context strip is two tight rows at portrait widths and ONE row
   between 621 and 900 (the forced break yields there -- documented in
   `test_ui_contract_sweep.py`). */
@media (max-width: 900px) {
  :root {
    --bb-lwstrip-height: var(--bb-shell-lwstrip);
    --bb-topbar-height: calc(var(--bb-shell-topbar) + var(--bb-lwstrip-height) + var(--bb-safe-top));
  }
  .bb-topbar {
    row-gap: 0;
    column-gap: 6px;
    padding-left: calc(var(--bb-space-2) + var(--bb-safe-left));
    padding-right: calc(var(--bb-space-2) + var(--bb-safe-right));
  }
  .bb-topbar__left,
  .bb-topbar__right {
    min-height: var(--bb-shell-topbar);
    gap: 4px;
  }
  /* Row one must never wrap: the four 44px controls on the right and
     the menu + brand on the left have to fit 374px at 390. The brand
     therefore compacts to the mark plus the "BB//" identity stamp on a
     phone (the same reduction section 17 established), restated here
     because the unconditional brand role above would otherwise win. */
  .bb-topbar__left {
    flex: 1 1 auto;
    min-width: 0;
  }
  .bb-topbar__right {
    flex: 0 0 auto;
  }
  .bb-brand {
    min-width: 0;
  }
  .bb-topbar__center {
    height: var(--bb-lwstrip-height);
    border-top: 1px solid var(--bb-border-subtle);
  }
  .bb-nav,
  .bb-drawer {
    top: calc(var(--bb-shell-topbar) + var(--bb-safe-top));
  }
  .bb-mark--lockup {
    width: 26px;
    height: 23px;
  }
  .bb-wordmark {
    font-size: var(--bb-fs-sm);
  }
  .bb-nav-toggle,
  .bb-topbar__right .bb-btn--icon,
  .bb-search__trigger,
  .bb-topbar__right > [data-bb-menu] > .bb-btn {
    width: var(--bb-tap-min);
    min-width: var(--bb-tap-min);
    height: var(--bb-tap-min);
    min-height: var(--bb-tap-min);
    padding-inline: 0;
    border-radius: var(--bb-radius-md);
  }
  .bb-usermenu {
    gap: 0;
    max-width: var(--bb-tap-min);
    justify-content: center;
  }
  .bb-usermenu__name,
  .bb-usermenu__caret {
    display: none;
  }
  .bb-usermenu__avatar {
    width: 26px;
    height: 26px;
  }
  .bb-lw {
    min-height: var(--bb-lwstrip-height);
    font-size: 0.625rem;
  }
  .bb-lw__core {
    font-size: 0.625rem;
  }

  /* context strip */
  .bb-contextbar {
    margin: calc(-1 * var(--bb-space-3)) calc(-1 * var(--bb-space-3)) var(--bb-space-3);
    padding: 6px var(--bb-space-3);
    gap: 6px 8px;
    min-height: 0;
  }
  .bb-contextbar__group .bb-ctxbtn,
  .bb-ctxbtn--accent,
  .bb-ctxsync {
    min-height: 32px;
  }
  .bb-contextbar__group {
    flex: 1 1 auto;
    min-width: 0;
  }
  .bb-ctxbtn .bb-fact__value {
    max-width: 18ch;
  }
  .bb-contextbar > .bb-ctxsync,
  .bb-contextbar > form {
    margin-left: 0;
  }
  .bb-contextbar > .bb-btn--sm:not(.bb-ctxsync),
  .bb-contextbar > [data-bb-menu]#bb-context-menu {
    margin-left: auto;
  }
  .bb-contextbar > [data-bb-menu]#bb-context-menu ~ .bb-ctxsync,
  .bb-contextbar > [data-bb-menu]#bb-context-menu ~ form {
    margin-left: 0;
  }

  .bb-pagehead {
    padding: 0 0 12px;
    border-radius: 0;
    margin-bottom: var(--bb-space-3);
  }
  .bb-pagehead__title {
    font-size: 1.25rem;
  }
  .bb-pagehead__subject {
    font-size: var(--bb-fs-sm);
  }
  .bb-hero {
    padding: 14px 16px 12px;
  }
  .bb-hero__title {
    font-size: 1.375rem;
  }

  /* the nav sheet, at the phone rhythm */
  .bb-nav {
    padding: 10px 8px 20px;
  }
  .bb-navitem,
  .bb-navitem--flagship {
    min-height: var(--bb-tap-min);
  }

  /* bottom navigation: the selected slot carries a 2px top bar in
     addition to its colour, so selection is never hue alone. */
  .bb-bottomnav__item {
    position: relative;
    gap: 3px;
  }
  .bb-bottomnav__item.is-active::before {
    content: "";
    position: absolute;
    top: 0;
    left: 22%;
    right: 22%;
    height: 2px;
    border-radius: 0 0 2px 2px;
    background: var(--bb-purple-bright);
  }
  .bb-bottomnav__item span {
    font-size: 0.625rem;
    letter-spacing: 0.04em;
  }
}
@media (max-width: 620px) {
  .bb-wordmark {
    font-size: 0;
    line-height: 1;
    letter-spacing: 0;
  }
  .bb-wordmark::before {
    content: "BB//";
    font: var(--bb-type-brand);
    letter-spacing: 0.06em;
  }
}
/* The context strip WRAPS NATURALLY on a phone instead of being forced
   to two rows: with no league selected (League + format stamp + import)
   it is one row; with a league, its freshness and the controls it
   wraps to two, and the spacer keeps the controls right-aligned on
   the second row. The forced break stays in the markup for the shell
   contract but yields at every phone width. */
@media (max-width: 900px) {
  .bb-contextbar__break {
    display: none;
  }
  .bb-contextbar__spacer {
    flex: 1 1 8px;
  }
  .bb-contextbar > [data-bb-menu]#bb-context-menu,
  .bb-contextbar > .bb-btn--sm:not(.bb-ctxsync) {
    margin-left: auto;
  }
}

/* =====================================================================
   37. FABLE PACK 02 (2026-09) -- LINEUP RADAR / NEXT TO LOCK
   =====================================================================
   The signature Blackbird experience: NEXT TO LOCK dominates by
   hierarchy (raised surface, larger mono time, amber eyebrow), never by
   a purple banner and never by animation. Every other block is a quiet
   `.bb-timeblock`-style rule. Attention rows expand with an amber/red
   rail; healthy starters are one line; bench-only players collapse
   into one closed disclosure per block; the unknown-schedule block is
   dashed and subordinate; resolved players sit in a closed disclosure
   at the foot, cyan reserved for a genuinely in-progress row. Purple
   appears only on the "Selected league" stamp and the one primary CTA.

   Tokens only; every class here is a NEW class this pack's templates
   use (`lineup_radar.html`, `partials/lineup_radar_macros.html`,
   `partials/my_blackbird_attention.html`, `my_blackbird.html`) -- no
   interpolated stem, `data-*` carries every state.
   ================================================================== */

/* --- 37.1 TIME BLOCK ---------------------------------------------------
   `.bb-lr-block` inherits the Pack 01 `.bb-timeblock` grammar (a mono
   caption + rule, not a card) for every block except the next one,
   which is promoted to a raised surface. */
.bb-lr-block {
  margin-bottom: var(--bb-space-4);
}
.bb-lr-block__head {
  display: grid;
  grid-template-columns: auto auto auto 1fr auto;
  align-items: center;
  gap: var(--bb-space-2) var(--bb-space-3);
  min-height: 36px;
  padding: 6px 0;
  list-style: none;
  cursor: pointer;
  border-bottom: 1px solid var(--bb-border-subtle);
  color: var(--bb-text-secondary);
}
.bb-lr-block__head::-webkit-details-marker {
  display: none;
}
.bb-lr-block__eyebrow {
  font: var(--bb-type-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bb-text-secondary);
  white-space: nowrap;
}
.bb-lr-block__time {
  font: var(--bb-type-metric);
  color: var(--bb-text-primary);
  white-space: nowrap;
}
.bb-lr-block__countdown {
  font: var(--bb-type-chip);
  letter-spacing: 0.04em;
  color: var(--bb-text-tertiary);
  white-space: nowrap;
}
.bb-lr-block__countdown[data-phase="passed"] {
  color: var(--bb-text-tertiary);
  border-bottom: 1px dashed var(--bb-border-strong);
}
.bb-lr-block__counts {
  min-width: 0;
  font: var(--bb-type-meta);
  color: var(--bb-text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bb-lr-block__attn {
  color: var(--bb-attention);
  font-weight: var(--bb-fw-bold);
}
.bb-lr-block__chev {
  width: 8px;
  height: 8px;
  flex: none;
  border-right: 1.5px solid var(--bb-text-tertiary);
  border-bottom: 1.5px solid var(--bb-text-tertiary);
  transform: rotate(45deg);
  transition: transform var(--bb-transition-fast);
}
.bb-lr-block[open] > .bb-lr-block__head .bb-lr-block__chev {
  transform: rotate(-135deg);
}
.bb-lr-block__body {
  padding: var(--bb-space-2) 0 0;
}
.bb-lr-block__note {
  margin: 4px 0 var(--bb-space-2);
  font: var(--bb-type-helper);
  color: var(--bb-text-tertiary);
}

/* NEXT TO LOCK -- the one block promoted by hierarchy: raised surface,
   strong border, a shadow, a larger mono time, the amber eyebrow with a
   hollow-diamond glyph. A next block that has already kicked off with
   no live signal yet (`data-phase="passed"`) keeps this exact surface
   -- only the countdown slot (above) admits it cannot promise a count. */
.bb-lr-block[data-next="true"] {
  background: var(--bb-surface-raised);
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-lg);
  box-shadow: var(--bb-elev-2);
  padding: 10px 16px 12px;
}
.bb-lr-block[data-next="true"] .bb-lr-block__head {
  border-bottom: 0;
  padding-bottom: 2px;
}
.bb-lr-block[data-next="true"] .bb-lr-block__eyebrow {
  color: var(--bb-attention);
  position: relative;
  padding-left: 14px;
}
.bb-lr-block[data-next="true"] .bb-lr-block__eyebrow::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -4px;
  border: 1.5px solid var(--bb-attention);
  transform: rotate(45deg);
  box-sizing: border-box;
}
.bb-lr-block[data-next="true"] .bb-lr-block__time {
  font: var(--bb-type-value);
  font-size: 18px;
}
.bb-lr-block[data-next="true"] .bb-lr-block__countdown {
  color: var(--bb-attention);
  font-weight: var(--bb-fw-bold);
}
.bb-lr-block[data-next="true"] .bb-lr-block__countdown[data-phase="passed"] {
  color: var(--bb-text-tertiary);
}

/* SCHEDULE UNKNOWN -- dashed, subordinate, no time, no countdown. */
.bb-lr-block--unknown {
  margin-bottom: var(--bb-space-4);
  padding-top: var(--bb-space-2);
  border-top: 1px dashed var(--bb-border);
}
.bb-lr-block--unknown .bb-lr-block__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--bb-space-3);
  cursor: default;
  border-bottom: 0;
}
.bb-lr-block--unknown .bb-lr-block__eyebrow {
  position: relative;
  padding-left: 14px;
  color: var(--bb-text-tertiary);
}
.bb-lr-block--unknown .bb-lr-block__eyebrow::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -4px;
  border: 1.5px dotted var(--bb-text-tertiary);
  border-radius: 50%;
  box-sizing: border-box;
}

/* --- 37.2 GROUPS (attention / starters / unknown / bench) ------------- */
.bb-lr-group {
  margin-bottom: var(--bb-space-2);
}
.bb-lr-group__label {
  display: block;
  margin-bottom: 4px;
  font: var(--bb-type-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-lr-group--bench {
  margin-bottom: 0;
}
.bb-lr-group--bench > .bb-lr-group__summary {
  min-height: 28px;
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
}
.bb-lr-group--bench > .bb-lr-group__summary::-webkit-details-marker {
  display: none;
}

/* --- 37.3 PLAYER ROW ---------------------------------------------------
   Starter/bench/unknown/mixed are WORDS + a glyph shape, never colour
   alone (`::before` on `.bb-lr-status`). Attention rows carry an inset
   rail; a bench-only row is one closed line per block. */
.bb-lr-row {
  border-bottom: 1px solid var(--bb-border-subtle);
}
.bb-lr-row:last-child {
  border-bottom: 0;
}
.bb-lr-row[data-tone="attention"] {
  box-shadow: inset 3px 0 0 var(--bb-attention);
}
.bb-lr-row[data-tone="negative"] {
  box-shadow: inset 3px 0 0 var(--bb-negative);
}
.bb-lr-row__main {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--bb-space-2) var(--bb-space-3);
  min-height: 36px;
  padding: 4px var(--bb-space-2);
  list-style: none;
  cursor: default;
}
details.bb-lr-row > .bb-lr-row__main {
  cursor: pointer;
}
details.bb-lr-row > .bb-lr-row__main::-webkit-details-marker {
  display: none;
}
details.bb-lr-row[open] > .bb-lr-row__main {
  background: var(--bb-surface-hover);
}
.bb-lr-row__identity {
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  font: var(--bb-type-body);
  color: var(--bb-text-primary);
}
.bb-lr-row__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bb-lr-row__team {
  font: var(--bb-type-evidence);
  color: var(--bb-text-tertiary);
  white-space: nowrap;
}
.bb-lr-row__opp {
  color: var(--bb-text-tertiary);
}
.bb-lr-row__lock {
  font: var(--bb-type-evidence);
  color: var(--bb-text-tertiary);
  white-space: nowrap;
}
.bb-lr-row__attn {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.bb-lr-row__note {
  font: var(--bb-type-meta);
  color: var(--bb-text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bb-lr-row__leagues {
  font: var(--bb-type-meta);
  color: var(--bb-text-tertiary);
  white-space: nowrap;
}
.bb-lr-row__chev {
  width: 7px;
  height: 7px;
  flex: none;
  border-right: 1.5px solid var(--bb-text-tertiary);
  border-bottom: 1.5px solid var(--bb-text-tertiary);
  transform: rotate(45deg);
  transition: transform var(--bb-transition-fast);
}
details.bb-lr-row[open] > .bb-lr-row__main .bb-lr-row__chev {
  transform: rotate(-135deg);
}
.bb-lr-row__go {
  font: var(--bb-type-chip);
  color: var(--bb-accent-data);
  white-space: nowrap;
}
.bb-lr-row__body {
  padding: 0 0 var(--bb-space-2) var(--bb-space-2);
}

/* STATUS CHIP -- Starter/Bench/Unknown/mixed, word + glyph. */
.bb-lr-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: var(--bb-type-chip);
  letter-spacing: 0.04em;
  color: var(--bb-text-secondary);
  white-space: nowrap;
}
.bb-lr-status::before {
  content: "";
  width: 7px;
  height: 7px;
  flex: none;
  box-sizing: border-box;
  background: currentColor;
}
.bb-lr-status[data-state="starter"] {
  color: var(--bb-text-primary);
}
.bb-lr-status[data-state="bench"] {
  color: var(--bb-text-tertiary);
}
.bb-lr-status[data-state="bench"]::before {
  background: transparent;
  border: 1.5px solid currentColor;
}
.bb-lr-status[data-state="unknown"] {
  color: var(--bb-text-tertiary);
}
.bb-lr-status[data-state="unknown"]::before {
  background: transparent;
  border: 1.5px dotted currentColor;
  border-radius: 50%;
}
.bb-lr-status[data-state="mixed"] {
  color: var(--bb-text-secondary);
}
.bb-lr-status[data-state="mixed"]::before {
  width: 5px;
  height: 5px;
  box-shadow: 4px 0 0 currentColor;
  margin-right: 2px;
}

/* ATTENTION WORD -- amber/red/info text, never colour alone (the word
   is the badge's own already-published severity term). */
.bb-lr-attn {
  font: var(--bb-type-chip);
  letter-spacing: 0.04em;
}
.bb-lr-attn[data-tone="negative"] { color: var(--bb-negative); }
.bb-lr-attn[data-tone="attention"],
.bb-lr-attn[data-tone="caution"] { color: var(--bb-attention); }
.bb-lr-attn[data-tone="info"] { color: var(--bb-info); }
.bb-lr-attn[data-tone="none"] { color: var(--bb-text-tertiary); }

/* SELECTED LEAGUE STAMP -- purple, identity/selection only. */
.bb-lr-selected {
  display: inline-flex;
  align-items: center;
  margin-left: 6px;
  padding: 0 6px;
  border: 1px solid var(--bb-purple-border-strong);
  border-radius: var(--bb-radius-sm);
  font: var(--bb-type-chip);
  letter-spacing: 0.04em;
  color: var(--bb-purple-bright);
  background: var(--bb-purple-wash);
  white-space: nowrap;
}

/* --- 37.4 LEAGUE INSTANCE LIST (the per-league drilldown) -------------- */
.bb-lr-instlist {
  margin: 0;
  padding: 0;
  list-style: none;
}
.bb-lr-inst {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) auto auto minmax(0, 2fr) auto;
  align-items: center;
  gap: var(--bb-space-2) var(--bb-space-3);
  min-height: 34px;
  padding: 4px var(--bb-space-2);
  border-bottom: 1px solid var(--bb-border-subtle);
  font: var(--bb-type-helper);
}
.bb-lr-inst:last-child {
  border-bottom: 0;
}
.bb-lr-inst[data-tone="attention"],
.bb-lr-inst[data-tone="caution"] {
  box-shadow: inset 3px 0 0 var(--bb-attention);
}
.bb-lr-inst[data-tone="negative"] {
  box-shadow: inset 3px 0 0 var(--bb-negative);
}
.bb-lr-inst[data-tone="info"] {
  box-shadow: inset 3px 0 0 var(--bb-info);
}
.bb-lr-inst__league {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--bb-text-primary);
}
.bb-lr-inst__team {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--bb-text-secondary);
}
.bb-lr-inst__slot {
  font: var(--bb-type-evidence);
  color: var(--bb-text-tertiary);
}
.bb-lr-inst__notes {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.bb-lr-inst__note {
  display: block;
  color: var(--bb-text-secondary);
}
.bb-lr-inst__note .bb-badge {
  margin-right: 4px;
}
.bb-lr-inst__go {
  font: var(--bb-type-chip);
  color: var(--bb-accent-data);
  white-space: nowrap;
}

/* --- 37.5 RESOLVED HANDOFF / LEAGUE ISSUES ----------------------------- */
.bb-lr-resolved {
  margin-top: var(--bb-space-3);
}
.bb-lr-issues {
  margin: 0;
  padding: 0;
  list-style: none;
}
.bb-lr-issues__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--bb-space-2);
  padding: 4px 0;
}
.bb-lr-issues__league {
  color: var(--bb-text-primary);
}
.bb-lr-issues__reason {
  font: var(--bb-type-meta);
  color: var(--bb-text-tertiary);
}

/* --- 37.6 RADAR STRIP / ATTENTION SUMMARY (Lineup Radar page) --------- */
.bb-lr-strip {
  margin-bottom: var(--bb-space-3);
}
.bb-lr-attention {
  margin-bottom: var(--bb-space-3);
}
.bb-lr-scope {
  display: flex;
  gap: var(--bb-space-2);
}
.bb-lr-scope__disabled {
  display: inline-flex;
  align-items: center;
  opacity: 0.45;
  cursor: default;
}
.bb-lr-allclear {
  padding: var(--bb-space-3) 0;
  font: var(--bb-type-body);
  color: var(--bb-text-secondary);
}

/* DENSE ATTENTION LIST -- shared by the radar page's own summary and My
   Blackbird's "Needs attention now" band. */
.bb-attn-list {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--bb-border);
  border-radius: var(--bb-radius-md);
  background: var(--bb-surface);
  overflow: hidden;
}
.bb-attn-list__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--bb-border-subtle);
  font: var(--bb-type-helper);
}
.bb-attn-list__item:last-child {
  border-bottom: 0;
}
.bb-attn-list__item[data-tone="negative"] {
  box-shadow: inset 3px 0 0 var(--bb-negative);
}
.bb-attn-list__item[data-tone="caution"] {
  box-shadow: inset 3px 0 0 var(--bb-attention);
}
.bb-attn-list__item[data-tone="info"] {
  box-shadow: inset 3px 0 0 var(--bb-info);
}
.bb-attn-list__league,
.bb-attn-list__player {
  color: var(--bb-text-primary);
}
.bb-attn-list__text {
  flex: 1 1 220px;
  min-width: 0;
  color: var(--bb-text-secondary);
}
.bb-attn-list__go {
  font: var(--bb-type-chip);
  color: var(--bb-accent-data);
  white-space: nowrap;
}
.bb-attn-list__time {
  font: var(--bb-type-evidence);
  color: var(--bb-text-tertiary);
  white-space: nowrap;
}

/* --- 37.7 MY BLACKBIRD -- ATTENTION-BAND GROUPS + ALL-CLEAR ------------ */
.bb-mbattn-group {
  margin-bottom: var(--bb-space-2);
}
.bb-mbattn-group:last-child {
  margin-bottom: 0;
}
.bb-mbattn-group__label {
  display: block;
  margin-bottom: 4px;
  font: var(--bb-type-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-mb-allclear {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 0;
  margin-bottom: var(--bb-space-3);
  font: var(--bb-type-body);
  color: var(--bb-text-secondary);
}
.bb-mb-allclear__dot {
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 50%;
  background: var(--bb-positive);
}

/* --- 37.8 MY BLACKBIRD -- THE "RIGHT NOW" ZONE + SNAPSHOT -------------- */
.bb-mbnow {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: var(--bb-space-4);
  align-items: start;
  margin-bottom: var(--bb-space-3);
}
.bb-mbnow__radar {
  min-width: 0;
}
.bb-mbnow__strip {
  align-self: stretch;
}
/* The attention band's body (`partials/my_blackbird_attention.html`)
   groups its three sub-lists (Lineup / Draft rooms / Sync) with a
   little breathing room -- `.bb-attention__head`/`__title`/`__count`
   above are Pack 01's own, this is the one new part this pack adds. */
.bb-attention__body {
  display: flex;
  flex-direction: column;
  gap: var(--bb-space-2);
}
.bb-lr-snap {
  background: var(--bb-surface-raised);
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-lg);
  padding: 14px 16px;
}
.bb-lr-snap[data-state="unknown"],
.bb-lr-snap[data-state="none"] {
  background: var(--bb-surface);
  border-color: var(--bb-border);
}
.bb-lr-snap__eyebrow {
  display: block;
  margin-bottom: 6px;
  font: var(--bb-type-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bb-attention);
}
.bb-lr-snap[data-state="unknown"] .bb-lr-snap__eyebrow,
.bb-lr-snap[data-state="none"] .bb-lr-snap__eyebrow {
  color: var(--bb-text-tertiary);
}
.bb-lr-snap__time-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 4px;
}
.bb-lr-snap__time {
  font-size: 20px;
}
.bb-lr-snap__day {
  font: var(--bb-type-meta);
  color: var(--bb-text-tertiary);
}
.bb-lr-snap__countdown {
  font: var(--bb-type-chip);
  color: var(--bb-attention);
}
.bb-lr-snap__countdown[data-phase="passed"] {
  color: var(--bb-text-tertiary);
}
.bb-lr-snap__counts {
  margin: 0 0 4px;
  font: var(--bb-type-meta);
  color: var(--bb-text-secondary);
}
.bb-lr-snap__names {
  margin: 0 0 8px;
  font: var(--bb-type-evidence);
  color: var(--bb-text-tertiary);
}
.bb-lr-snap__quiet {
  margin: 0 0 8px;
  font: var(--bb-type-helper);
  color: var(--bb-text-tertiary);
}

/* --- 37.9 RESPONSIVE (existing 1200 / 900 / 620 tiers only) ------------ */
@media (max-width: 1200px) {
  .bb-mbnow {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 900px) {
  .bb-lr-block__head {
    grid-template-columns: 1fr auto;
    grid-template-areas: "eyebrow chev" "time countdown" "counts counts";
  }
  .bb-lr-block__eyebrow { grid-area: eyebrow; }
  .bb-lr-block__chev { grid-area: chev; }
  .bb-lr-block__time { grid-area: time; }
  .bb-lr-block__countdown { grid-area: countdown; justify-self: end; }
  .bb-lr-block__counts { grid-area: counts; white-space: normal; }
}
@media (max-width: 620px) {
  .bb-lr-row__main {
    grid-template-columns: 1fr auto;
    grid-template-areas: "identity end" "status status";
    row-gap: 2px;
  }
  .bb-lr-row__identity { grid-area: identity; }
  .bb-lr-row__go,
  .bb-lr-row__chev { grid-area: end; justify-self: end; }
  .bb-lr-row__attn,
  .bb-lr-row__leagues {
    grid-area: status;
  }
  .bb-lr-row__attn {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px;
  }
  .bb-lr-inst {
    grid-template-columns: 1fr;
    row-gap: 2px;
  }
  .bb-lr-inst__go {
    justify-self: stretch;
    text-align: right;
  }
}

/* --- 37.10 MY BLACKBIRD -- HEALTHY CARDS COMPRESS (CSS-only, optional) -
   A card with nothing to flag (no `.bb-lineup-attention` block --
   `partials/my_blackbird_card_grid.html`'s own markup, untouched by
   this pack) tightens its vertical rhythm slightly, so a healthy
   portfolio reads denser than one genuinely carrying a real per-card
   alert. Pure `:has()` density read of the SAME DOM the card grid
   already renders -- no markup change, no new class on the card. */
.bb-leaguecard:not(:has(.bb-lineup-attention)) {
  padding-bottom: 10px;
}
.bb-leaguecard:not(:has(.bb-lineup-attention)) .bb-leaguecard__head {
  margin-bottom: 8px;
}

/* --- 37.11 TOUCH TARGETS ------------------------------------------------
   Every interactive control this pack adds keeps its dense desktop size
   and rises to the platform floor only at the coarse-pointer / phone
   tier -- the same union `.bb-disclosure > summary` already uses. */
@media (pointer: coarse), (max-width: 900px) {
  .bb-lr-block__head,
  .bb-lr-row__main,
  details.bb-lr-row > .bb-lr-row__main {
    min-height: var(--bb-tap-min);
  }
  .bb-lr-group--bench > .bb-lr-group__summary {
    min-height: var(--bb-tap-min);
  }
  .bb-lr-inst {
    min-height: var(--bb-tap-min);
  }
}

/* --- 37.12 CORRECTIONS FROM REAL-BROWSER EVIDENCE ------------------------
   (a) The block head's counts wrap rather than truncate: a count that is
       cut to "2 need..." is worse than a second line.
   (b) Phone head: time, countdown and counts each take a full row so the
       countdown never spills past the viewport edge.
   (c) Shared-shell adjustment, needed by this pack's realistic fixtures
       (a 13-character display name beside a Live Wire rail that names
       the next kickoff): on the 901-1200 tier the search trigger gives
       up 70px and the account name caps at 9ch, so the top bar fits a
       1024px viewport without a horizontal scroll. Desktop >= 1201 is
       unchanged. */
.bb-lr-block__counts {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}
@media (max-width: 620px) {
  .bb-lr-block__head {
    grid-template-areas: "eyebrow chev" "time time" "countdown countdown" "counts counts";
  }
  .bb-lr-block__countdown {
    justify-self: start;
    white-space: normal;
  }
}
@media (min-width: 901px) and (max-width: 1200px) {
  .bb-search__trigger {
    min-width: 190px;
  }
  .bb-usermenu__name {
    max-width: 9ch;
  }
}

/* (d) Phone row: the earlier <=620 rule put the status chip, the
   attention word and the league count into ONE grid area, so they
   painted on top of each other. The row is a wrapping flex line
   instead: identity + the end control on line one, then status /
   attention / league count flowing on the next line(s). */
@media (max-width: 620px) {
  .bb-lr-row__main {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 10px;
  }
  .bb-lr-row__identity {
    flex: 1 1 calc(100% - 52px);
    order: 0;
  }
  .bb-lr-row__chev {
    order: 1;
    flex: 0 0 auto;
    margin-left: auto;
  }
  /* A single-league row has no chevron; its "My Team" link closes the
     status line instead ("Starter · 1 league · My Team ->"). */
  .bb-lr-row__go {
    order: 3;
    flex: 0 0 auto;
    margin-left: auto;
  }
  .bb-lr-status,
  .bb-lr-row__attn,
  .bb-lr-row__leagues {
    order: 2;
    flex: 0 1 auto;
    min-width: 0;
  }
  .bb-lr-row__attn {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px;
  }
  .bb-lr-row__note {
    flex: 1 1 100%;
  }
}

/* =====================================================================
   37. UI UNIFORMITY PACK 06 (2026-09) -- SHARED PRIMITIVES
   =====================================================================
   Phase 1 of this pack classified the product's competing implementations
   of one-idea components across Command Center, Trade Desk, My Blackbird
   and Waiver Intelligence (see `docs/FABLE_UI_UNIFORMITY.md`). This
   section is ADDITIVE ALIASING, not a rename: every rule below lists the
   OLD class names it now also governs, so no template changed its class
   attributes for these primitives and no test that pins a class name on
   these components can break. It loads after every section above, so at
   equal specificity it wins -- the mechanism the whole Fable layer
   already relies on (see section 36's own header comment).

   WHAT THIS SECTION DOES NOT DO: it does not touch `.bb-hero`'s
   composition (Command Center's flagship hero stays deferred to its own
   pack, per `docs/FABLE_VISUAL_SYSTEM.md` §19), does not touch
   `.bb-td-verdict__glyph`'s shape grammar, does not touch
   `ui.balance_meter()`, and does not touch `.bb-band__fill--strong/
   --middle/--weak/--none` (Rankings/Landscape/Position Matrix's own
   tone modifiers, used well beyond the three target pages).
   ================================================================== */

/* --- 37.1 EYEBROW / MODULE LABEL ---------------------------------------
   One micro-caption role for "this is a label, not a value": mono,
   `--bb-type-label`, uppercase, tertiary. Hero/pagehead eyebrows are the
   one variant that stays purple-bright with a dot (the page-identity
   gesture) -- everything else reads as a quiet caption. Only the
   TYPOGRAPHIC properties are aliased; each class keeps its own layout
   (display, gap, margin) declared earlier in this file. */
.bb-eyebrow,
.bb-hero__eyebrow,
.bb-pagehead__eyebrow,
.bb-mod__sub,
.bb-mod__title,
.bb-td-side__label,
.bb-td-package__k,
.bb-td-advantage__k,
.bb-leaguecard__kicker,
.bb-lr-snap__eyebrow,
.bb-wi-row1__head,
.bb-reco__kicker,
.bb-reco__label {
  font: var(--bb-type-label);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-eyebrow--dot,
.bb-hero__eyebrow,
.bb-pagehead__eyebrow,
.bb-leaguecard__kicker {
  color: var(--bb-purple-bright);
}
.bb-eyebrow--dot::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 1px;
  margin-right: 6px;
  background: var(--bb-purple-bright);
  vertical-align: 1px;
}

/* --- 37.2 SECTION TITLE + SECTION HEAD ROW -----------------------------
   ONE section-title role (Inter, `--bb-type-section`, primary text, no
   uppercase) -- `.bb-mod__title` is NOT here: it stays a module eyebrow
   (37.1), the label above a module's own content, not a page section
   head. `.bb-cc__sectiontitle`'s mono/uppercase/wing treatment is
   retired in favour of this shared role. */
.bb-sectiontitle,
.bb-cc__sectiontitle,
.bb-zone__title,
.bb-sectionhead__title,
.bb-attention__title {
  font: var(--bb-type-section);
  text-transform: none;
  letter-spacing: normal;
  color: var(--bb-text-primary);
}
/* ONE section-head ROW layout: title left, note/link right. */
.bb-sectionhead,
.bb-cc__sectionhead,
.bb-zone__head,
.bb-attention__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bb-space-2);
  margin: 0 0 var(--bb-space-3);
}

/* --- 37.3 PAGE TITLE: ONE WEIGHT, ONE TRACKING -------------------------
   `.bb-hero__title` carried three separate weight/tracking declarations
   (§21.3's dead grid-hero rule, §24.5's cinematic rule, both 800/hand-
   tracked) before the Fable layer (§36.5) only ever corrected its SIZE.
   This is the one surviving weight/tracking rule; the two upstream ones
   have had their conflicting declarations removed (see the deletions
   noted in `docs/FABLE_UI_UNIFORMITY.md`). Size and uppercase are
   UNCHANGED -- uppercase is the hero's one identity gesture and Waiver
   shares it deliberately. */
.bb-hero__title {
  font-weight: 650;
  letter-spacing: var(--bb-tracking-tight);
}
/* The hero tagline reads as an eyebrow-weight caption in secondary ink,
   not its own bespoke mono/bold/tertiary declaration. */
.bb-hero__tagline {
  font: var(--bb-type-label);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-secondary);
}

/* --- 37.4 METRIC TILE ---------------------------------------------------
   Label / value / sub, one role each, aliasing five competing
   implementations. `--lg` (and `.bb-strip__value`/`.bb-herostat__value`,
   which are always the lead instrument reading) stay at the larger
   size; every other metric value converges on `--bb-type-value`
   (mono 600 18px) -- Waiver's minis and My Blackbird's card metrics
   both step down to it. */
.bb-metric__label,
.bb-strip__label,
.bb-tile__label,
.bb-wi-mini__label,
.bb-herostat__label,
.bb-mod__count span {
  font: var(--bb-type-label);
  letter-spacing: var(--bb-tracking-label);
  text-transform: uppercase;
  color: var(--bb-text-tertiary);
}
.bb-metric__value,
.bb-strip__value,
.bb-tile__value,
.bb-wi-mini__value,
.bb-herostat__value,
.bb-mod__count b {
  font: var(--bb-type-value);
  font-variant-numeric: tabular-nums;
  color: var(--bb-text-primary);
}
.bb-metric__value--lg,
.bb-strip__value,
.bb-herostat__value {
  font-size: 1.5rem;
}
.bb-metric__sub,
.bb-strip__sub,
.bb-tile__sub,
.bb-wi-mini__sub,
.bb-herostat__sub {
  font: var(--bb-type-meta);
  color: var(--bb-text-tertiary);
}

/* --- 37.5 PILL / STATUS BADGE -------------------------------------------
   `.bb-badge`'s box (padding, radius, `--bb-type-chip`, 1px border)
   becomes the one pill recipe. `.bb-td-advantage` keeps its own dot
   (`::before`) and key/value spans, declared in `trade_desk.css`; only
   its outer box is shared here. `.bb-wi-pill`'s own tone rules
   (`--positive`/`--caution`) are untouched -- only its box duplicated
   `.bb-badge`'s. */
.bb-badge,
.bb-wi-pill,
.bb-leaguecard__attention,
.bb-td-advantage {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: var(--bb-radius-sm);
  font: var(--bb-type-chip);
  border: 1px solid var(--bb-neutral-border);
  background: var(--bb-neutral-bg);
  color: var(--bb-neutral);
  white-space: nowrap;
}

/* --- 37.6 BAR TRACK / FILL ----------------------------------------------
   One 6px pill-radius track, aliasing four page-local recipes. Colour
   stays each caller's own (data-driven tone classes are untouched).
   `.bb-tradebar__track` gets the same GEOMETRY only -- its semantic
   fair<->great gradient background (`--bb-grad-balance`) is deliberately
   NOT overridden here, so the Trade Value placement bar keeps its own
   reading. */
.bb-bar,
.bb-band,
.bb-wi-heat-bar,
.bb-wi-roster__bar,
.bb-wi-scarcity-bar,
.bb-tradebar__track {
  height: 6px;
  border-radius: var(--bb-radius-pill);
  overflow: hidden;
}
.bb-bar,
.bb-band,
.bb-wi-heat-bar,
.bb-wi-roster__bar,
.bb-wi-scarcity-bar {
  background: var(--bb-surface-hover);
}
.bb-bar__fill,
.bb-band__fill,
.bb-wi-heat-bar__fill,
.bb-wi-roster__barfill,
.bb-wi-scarcity-bar__fill,
.bb-tradebar__fill {
  display: block;
  height: 100%;
  border-radius: var(--bb-radius-pill);
}
.bb-bar__fill { background: var(--bb-purple); }
.bb-bar__fill[data-tone="positive"] { background: var(--bb-positive); }
.bb-bar__fill[data-tone="caution"]  { background: var(--bb-caution); }
.bb-bar__fill[data-tone="negative"] { background: var(--bb-negative); }
.bb-bar__fill[data-tone="info"]     { background: var(--bb-info); }
.bb-bar__fill[data-tone="live"]     { background: var(--bb-live); }

/* --- 37.7 CARD SURFACE ---------------------------------------------------
   `.bb-icard`'s recipe (hairline `--bb-border`, `--bb-radius-md`,
   `--bb-elev-1`, 14x16 padding) becomes the one card box. `.bb-icard`
   itself is included because an earlier, un-tokenised `border-radius:
   12px` override (section 21.3) had drifted it off the documented
   8->6px Fable radius step; this reasserts the token. `background-color`
   (never the `background` SHORTHAND) is used throughout so `.bb-prio`'s
   own category-tint gradient (`background-image`, untouched) keeps
   painting over it. `.bb-leaguecard`, `.bb-prio` and `.bb-lr-snap` only
   take the radius fix -- their markup already carries `.bb-icard`
   (leaguecard) or they keep their own intentional face (prio's tint,
   lr-snap's raised/strong-border prominence as a callout); their inner
   layout and elevation are unchanged either way. */
.bb-icard,
.bb-mod,
.bb-card,
.bb-td-side,
.bb-leaguecard,
.bb-prio,
.bb-lr-snap {
  border-radius: var(--bb-radius-md);
}
.bb-icard,
.bb-mod,
.bb-card,
.bb-td-side {
  background-color: var(--bb-surface-card);
  border-color: var(--bb-border);
  box-shadow: var(--bb-elev-1);
  padding: 14px 16px;
}
/* `.bb-card__header` reads as a section-head row, same as 37.2. */
.bb-card__header {
  align-items: center;
}

/* --- 37.8 PRIMARY / DECISION SURFACES ------------------------------------
   `.bb-reco`/`.bb-td-verdict` are already raised with a purple rail
   (identity.css). Command Center's Top Priorities (`.bb-tactical`) joins
   that family: raised surface + the same 3px purple rail, so it reads as
   Blackbird's own opinion surface, without changing its inner markup.
   My Blackbird's "Needs attention now" (`.bb-attention`) already carries
   a semantic (amber/red) rail and a raised surface by construction --
   that colour is load-bearing (Part 19: purple is never a semantic
   carrier), so only its padding is brought in line here, not its rail
   colour. */
.bb-reco__body,
.bb-td-verdict__body,
.bb-tactical,
.bb-attention {
  padding: 16px 18px;
}
.bb-tactical {
  background: var(--bb-surface-raised);
  box-shadow: inset 3px 0 0 var(--bb-purple-bright);
}

/* --- 37.9 ROW LEFT-RAIL CONVENTION ---------------------------------------
   My Blackbird's "Biggest need" lineup-issue accent shares the same
   inset-left-rail grammar `.bb-rows__item[data-tone]` already uses,
   instead of its own bespoke gradient. */
.bb-leaguecard__need--lineup {
  box-shadow: inset 3px 0 0 var(--bb-negative);
}

/* --- 37.10 GLYPH TILE -----------------------------------------------------
   One "this row's kind, as an icon" tile aliasing Waiver's insight glyph
   and the shared empty-state mark. `.bb-td-verdict__glyph`'s shape
   grammar (a DIFFERENT idea -- the verdict's own glyph vocabulary) is
   untouched. */
.bb-glyph,
.bb-wi-insight-glyph,
.bb-state__mark {
  width: 28px;
  height: 28px;
  border-radius: var(--bb-radius-sm);
  background: var(--bb-surface-raised);
  border: 1px solid var(--bb-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--bb-text-secondary);
}

/* --- 37.11 TABLE RANK ALIAS -----------------------------------------------
   Waiver's board rank tile now renders with the same numerals as the
   shared `ui.rank_badge()` macro (`.bb-rank`/`.bb-rank__hash`) without
   touching the Waiver template. */
.bb-wi-board-rank {
  font: var(--bb-type-metric);
  font-variant-numeric: tabular-nums;
}
.bb-wi-board-rank .bb-rank__hash {
  color: var(--bb-text-tertiary);
  font-weight: var(--bb-fw-regular);
  font-size: 0.85em;
}

/* --- 37.12 TABS: THE SCROLL-ON-OVERFLOW BEHAVIOUR IS NOW GENERIC ---------
   Waiver's phone-width horizontal scroll and touch floor move onto the
   shared `.bb-tabs` base, so any page reaching for `.bb-tabs` gets the
   identical behaviour Waiver's `.bb-wi-tabs` used to carry alone. */
.bb-tabs {
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.bb-tabs .bb-tab {
  white-space: nowrap;
  flex: none;
}
@media (pointer: coarse), (max-width: 900px) {
  .bb-tabs .bb-tab {
    min-height: var(--bb-tap-min);
    display: inline-flex;
    align-items: center;
  }
}

/* --- 37.13 SPACING -------------------------------------------------------
   Section gap and in-card gap read from the documented scale; nothing
   else in this file changes as a result since every consumer already
   read `--bb-space-3`/`--bb-space-5` for these roles. Declared here as
   the one place that states the rule out loud. */
:root {
  --bb-uniformity-card-padding: 14px 16px;
  --bb-uniformity-surface-padding: 16px 18px;
  --bb-uniformity-section-gap: var(--bb-space-5);
  --bb-uniformity-card-gap: var(--bb-space-3);
}

/* --- 37.14 COMMAND CENTER: RAW VALUE CLEANUP -----------------------------
   Small utility classes so two inline `style=` attributes in
   `command_center.html` (a hard-coded margin, a hard-coded semantic
   colour) become classes instead of ad-hoc attributes. */
.bb-cc-foot-note {
  margin: 0 0 6px;
}
.bb-cc-risers-title {
  color: var(--bb-positive);
}
.bb-cc-fallers-title {
  color: var(--bb-negative);
}

/* --- 37.15 TRADE DESK: COMPOSER SELECT WIDTH -----------------------------
   The counterparty `<select>`'s inline `style="max-width:420px;"`
   becomes a class. */
.bb-td-counterparty-select {
  max-width: 420px;
}

/* --- 37.16 MOBILE CORRECTION: LINEUP RADAR FIRST-VIEWPORT BUDGET --------
   37.4's shared metric-tile sizing and 37.8's shared decision-surface
   padding are both unconditional -- correct for the desktop/tablet
   unification they were written for, but on the phone width they
   silently clobbered pre-existing sizing that was smaller at this width
   (`.bb-strip__value`'s `@media (max-width: 900px)` downsize to 1.25rem,
   `.bb-strip__sub`'s pre-Pack06 `--bb-fs-sm` cascade result, and
   `.bb-attention`/`.bb-attention__head`'s original tighter box), pushing
   Lineup Radar's "Next to Lock" block ~25px below the 390x844
   first-viewport budget. Corrected here, scoped to Lineup Radar's own
   instances only (`.bb-lr-strip`, `.bb-lr-attention`) so no other
   consumer of `.bb-strip__value` or `.bb-attention` (Command Center, My
   Blackbird, Waiver) changes. */
@media (max-width: 900px) {
  .bb-lr-strip .bb-strip__value {
    font-size: 1.25rem;
  }
  .bb-lr-strip .bb-strip__sub {
    font-size: var(--bb-fs-sm);
    line-height: var(--bb-leading-tight);
  }
  .bb-lr-attention {
    padding: 10px 14px 12px 16px;
  }
  .bb-lr-attention .bb-attention__head {
    margin-bottom: 8px;
  }
}

/* =====================================================================
   38. READABILITY / URGENCY NORMALIZATION (2026-09)
   =====================================================================
   A design audit (real Chromium screenshots) found decision-critical
   text and action affordances reading at the same visual weight as
   ambient metadata, opportunity/upgrade badges rendering neutral gray,
   and sync/data-quality problems sharing the same amber as football
   urgency. This section is a SURGICAL, presentation-only correction,
   additive over sections 36/37 exactly the way section 37 was additive
   over 36: nothing above is renamed or deleted, this just loads later
   and wins at equal specificity. No functional/backend/routing/data
   change. The graphite "Intelligence HQ" visual system -- near-black
   shell, Blackbird Purple as selective accent only, the existing
   chips/bars/cards/type scale -- is preserved, not redesigned.

   THE FIVE LEVELS THIS PASS NORMALIZES, and the existing primitive that
   already carries each one (no new class family beyond what is used
   below):
     CRITICAL / ACTION NOW    -> `.bb-badge--negative` (now bold),
                                  `.bb-attention--urgent`, red 3px rail
     NEEDS ATTENTION / REVIEW -> `.bb-badge--caution`, amber 3px rail
     OPPORTUNITY / UPGRADE    -> `.bb-badge--positive` (green) or
                                  `.bb-badge--caution` (amber, "upgrade
                                  available" per the existing
                                  view-model's own tone) -- the tone is
                                  never invented here, only restored to
                                  visibility (root cause #1 below)
     NORMAL / STABLE          -> primary text, no rail
     SUPPORTING / CONTEXT     -> secondary text; tertiary is reserved
                                  for timestamps / metadata only
     SYNC / DATA QUALITY      -> `--bb-info` hollow ring / dashed rail,
                                  never amber or red -- a sync problem
                                  must never read as "your lineup is
                                  bad", and a lineup problem must never
                                  read as "data may be stale"
   ================================================================== */

/* --- ROOT CAUSE #1: badge tone modifiers, restated after section 37.5 -
   Section 37.5 (~line 11960) re-declared `.bb-badge`'s box at equal
   specificity and LATER in the cascade than components.css 573-576's
   tone modifiers, so every `.bb-badge--positive/--negative/--caution/
   --info` silently rendered neutral gray -- verified in screenshots on
   "Upgrade available" (My Blackbird / Lineup Radar), "Starter need" /
   "Depth need" (Waiver) and Command Center's brief category badges;
   148 usages across 46 templates are affected. Restated here,
   additively, after section 37 -- components.css and 37.5 are both
   untouched, per this codebase's additive-aliasing convention. Critical
   reads one step heavier than the other three tones. */
.bb-badge--positive { border-color: var(--bb-positive-border); background: var(--bb-positive-bg); color: var(--bb-positive); }
.bb-badge--negative { border-color: var(--bb-negative-border); background: var(--bb-negative-bg); color: var(--bb-negative); font-weight: 700; }
.bb-badge--caution  { border-color: var(--bb-caution-border);  background: var(--bb-caution-bg);  color: var(--bb-caution); }
.bb-badge--info     { border-color: var(--bb-info-border);     background: var(--bb-info-bg);     color: var(--bb-info); }

/* --- ROOT CAUSE #2: the "NEXT TO LOCK" eyebrow, restated after 37.1 ----
   Section 37.1's shared eyebrow alias (~line 11835) lists
   `.bb-lr-snap__eyebrow` in its selector list and sets it to tertiary
   gray, overriding this component's own rule (~line 11592) which reads
   the amber `--bb-attention` token for its lit state. Restored here;
   the "unknown/none" state stays tertiary, matching the component's
   original intent. */
.bb-lr-snap__eyebrow {
  color: var(--bb-attention);
}
.bb-lr-snap[data-state="unknown"] .bb-lr-snap__eyebrow,
.bb-lr-snap[data-state="none"] .bb-lr-snap__eyebrow {
  color: var(--bb-text-tertiary);
}

/* --- A1: My Blackbird attention-band item text must not be muted ------
   "QB · Name -- A clearly stronger legal option is available on your
   bench. · Bench options: ..." is the decision text, not metadata; the
   sibling `.bb-attn-list__time` stays tertiary on purpose. */
.bb-attn-list__text {
  color: var(--bb-text-primary);
  font: var(--bb-type-body);
}

/* --- A2: Lineup Radar instance notes -- only the FIRST note (the
   attention message: badge + message + "Bench options") reads primary;
   subsequent notes (the Role/Opportunity supporting-evidence line) stay
   secondary -- supporting evidence must stay visibly secondary but
   readable, never tertiary. */
.bb-lr-inst__notes > .bb-lr-inst__note:first-child {
  color: var(--bb-text-primary);
}

/* --- A4: Next-to-Lock snapshot -- who locks next is not decorative,
   it's a reading. Up from tertiary to secondary. */
.bb-lr-snap__names,
.bb-lr-snap__quiet {
  color: var(--bb-text-secondary);
}

/* --- B1: action links read as a real affordance, not chip-size mono
   data-blue text ("Open My Team ->", "Find a replacement ->") --
   the same secondary-button look `.bb-btn` uses, reusing its tokens,
   without changing markup. Never purple: `.bb-btn--primary` is
   reserved for the single primary CTA per surface (see the CTA rule,
   docs/FABLE_UI_UNIFORMITY.md). */
.bb-attn-list__go,
.bb-lr-inst__go {
  display: inline-flex;
  align-items: center;
  min-height: var(--bb-control-sm);
  padding: 0 10px;
  border: 1px solid var(--bb-border-strong);
  border-radius: var(--bb-radius-sm);
  background: var(--bb-surface);
  color: var(--bb-text-primary);
  font: var(--bb-type-chip);
  text-decoration: none;
}
.bb-attn-list__go:hover,
.bb-lr-inst__go:hover {
  background: var(--bb-surface-hover);
  border-color: var(--bb-purple-border-strong);
}
@media (pointer: coarse), (max-width: 900px) {
  .bb-attn-list__go,
  .bb-lr-inst__go {
    min-height: var(--bb-tap-min);
  }
}

/* --- B2: the "Selected league" stamp must not outrank the severity
   badge beside it. Demoted weight, still outlined purple -- context is
   still not colour-alone, just no longer the loudest thing in the row. */
.bb-lr-selected {
  border-color: var(--bb-purple-border);
  color: var(--bb-text-secondary);
  font-weight: 500;
}

/* --- C1: My Blackbird "Sync Issues" strip cell -- a HOLLOW ring in the
   informational blue, distinct in both shape (hollow vs the filled
   amber/red football dots on this same strip) and hue, so a sync
   problem never reads as "your lineup is bad". Value colour is stated
   for clarity; it matches the strip's own default. */
.bb-strip__cell[data-tone="sync"] .bb-strip__label::before {
  background: transparent;
  box-shadow: inset 0 0 0 2px var(--bb-info);
}
.bb-strip__cell[data-tone="sync"] .bb-strip__value {
  color: var(--bb-text-primary);
}

/* --- C2: My Blackbird attention-band "Sync" group -- reads as data
   quality, not football urgency: an info-blue group label and a dashed
   info-blue rail in place of the amber/red inset rail the Lineup
   group's items use. The sync items carry no `data-tone` today (no
   inset box-shadow is actually painted), so the explicit `transparent`
   below only documents intent; `padding-left` is reduced by the dashed
   border's own width (3px) so its content sits in the same visual
   column the inset-rail items use -- no layout shift. */
.bb-mbattn-group[data-kind="sync"] .bb-mbattn-group__label {
  color: var(--bb-info);
}
.bb-mbattn-group[data-kind="sync"] .bb-attn-list__item {
  box-shadow: inset 3px 0 0 transparent;
  border-left: 3px dashed var(--bb-info-border);
  padding-left: 7px;
}

/* --- CORRECTION: UPGRADE_AVAILABLE reads positive, not data-blue -------
   Restoring the badge tone modifiers (root cause #1 above) exposed that
   the lineup view-model publishes UPGRADE_AVAILABLE as tone `info` --
   that tone is DATA/INFORMATIONAL everywhere else in the product, but on
   these lineup-attention surfaces (My Blackbird's attention band, the
   per-card lineup-issue list, and Lineup Radar's holes/instance notes)
   `info` means "a clearly stronger option exists," an OPPORTUNITY per
   the five-level statement at the top of this section. Left as `info`
   it shared the same blue this pass reserves for SYNC / DATA QUALITY
   (C1/C2 above), collapsing two different meanings into one hue. The
   templates now emit `.bb-badge--positive` for this case (presentation
   only -- the view-model's `tone`/`data-tone` value is untouched); these
   rules make the item rail and the inline attention word agree. Never
   touches `.bb-reco__verdict[data-tone="info"]` or
   `.bb-bar__fill[data-tone="info"]`, which are a different idea. */
.bb-attn-list__item[data-tone="info"] {
  box-shadow: inset 3px 0 0 var(--bb-positive);
}
.bb-lr-attn[data-tone="info"] {
  color: var(--bb-positive);
}
.bb-lr-inst[data-tone="info"] {
  box-shadow: inset 3px 0 0 var(--bb-positive);
}

/* --- MOBILE BUDGET CORRECTION: Lineup Radar first-viewport (390x844) --
   A1's larger `--bb-type-body` attention text and B1's 44px touch-floor
   action button each add a few px of row height; §37.16 already trims
   this same page's mobile budget for exactly this reason (the shared
   `.bb-strip__value`/`.bb-attention` sizing is correct everywhere else
   but too tall for this page's own first-viewport budget). Scoped to
   `.bb-lr-attention`/`.bb-lr-strip` only -- My Blackbird's attention
   band, which has no such budget, is untouched. */
@media (max-width: 900px) {
  .bb-lr-attention .bb-attn-list__item,
  .bb-lr-strip .bb-attn-list__item {
    padding-top: 4px;
    padding-bottom: 4px;
  }
  .bb-lr-attention {
    padding-bottom: 8px;
  }
}

/* =====================================================================
   39. SEMANTIC HIERARCHY V2 (2026-09)
   =====================================================================
   A design audit (real Chromium screenshots) found several surfaces
   presenting a decision, its supporting evidence, and page-scoped
   metadata at the SAME visual weight -- a reader could not tell "this
   is the call" from "this is why" from "this is bookkeeping" without
   reading every word. This section is a SURGICAL, presentation-only
   correction, additive over sections 36/37/38 exactly the way each
   earlier section was additive over the one before it: nothing above
   is renamed or deleted, this just loads later and wins at equal
   specificity. No functional/backend/routing/data change.

   NOTE ON NUMBERING: the spec that commissioned this pass called this
   section "38"; section 38 (READABILITY / URGENCY NORMALIZATION) was
   already occupying that slot by the time this pass started, so this
   is 39 instead -- still appended at the very end of the file, after
   every earlier section, which is the property that actually matters
   for the cascade. See docs/FABLE_SEMANTIC_HIERARCHY_V2.md.
   ================================================================== */

/* --- S1: THE DECISION LINE -- one reusable "a sentence Blackbird
   says" primitive. THE LEAD is the ONLY piece that may carry a
   semantic tone (positive/caution/negative); `__why`/`__ev`/`__meta`
   are never coloured -- they read secondary/secondary/tertiary no
   matter what the lead says. */
.bb-say {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
  min-width: 0;
}
.bb-say__lead {
  font: var(--bb-type-card);
  font-weight: var(--bb-fw-bold);
  color: var(--bb-text-primary);
}
.bb-say__lead[data-tone="positive"] { color: var(--bb-positive); }
.bb-say__lead[data-tone="caution"]  { color: var(--bb-caution); }
.bb-say__lead[data-tone="negative"] { color: var(--bb-negative); }
.bb-say__why {
  flex-basis: 100%;
  font: var(--bb-type-body);
  color: var(--bb-text-secondary);
}
.bb-say__ev {
  font: var(--bb-type-helper);
  color: var(--bb-text-secondary);
}
.bb-say__sig {
  font-weight: var(--bb-fw-semibold);
  color: var(--bb-text-primary);
}
.bb-say__meta {
  flex-basis: 100%;
  font: var(--bb-type-evidence);
  color: var(--bb-text-tertiary);
}
.bb-say__go {
  font: var(--bb-type-chip);
}

/* --- S2: KILL WHOLE-CARD SEMANTIC WASHES -------------------------------
   Command Center's priority cards (`.bb-prio`) and the Intel Drawer's
   restated top priority (`.bb-rail-callout`) used a category-tinted
   gradient wash across the ENTIRE card face (hq.css ~4699-4771,
   ~5897-5944) -- the hierarchy brief this pass builds from forbids
   whole-surface semantic colour: colour marks a LEAD PHRASE, never a
   card. UI Uniformity Pack 06 (`docs/FABLE_UI_UNIFORMITY.md` §3)
   explicitly carved out an exception for `.bb-prio`'s tint ("the
   directive explicitly named only its radius as off-token, not its
   background"); this pass deliberately REVERSES that exception for
   the reason above. The category colour survives exactly two places:
   the 3px inset left rail (already `--prio`-driven) and `.bb-prio__cat`
   ' s own text/dot -- both are untouched here. */
.bb-prio,
.bb-rail-callout,
.bb-prio--muted,
.bb-prio--negative,
.bb-prio--positive,
.bb-prio--caution,
.bb-prio--info,
.bb-priogrid--wide > .bb-prio:first-child:nth-last-child(n+3) {
  background-image: none;
  background-color: var(--bb-surface-card);
  border-color: var(--bb-border);
  box-shadow: inset 3px 0 0 var(--prio);
}
/* CORRECTION PASS: the category colour is never allowed to recolour the
   OUTER BORDER (or hover to a stronger version of it) -- only the 3px
   inset rail, `.bb-prio__cat`'s text/dot, and the CTA text link may
   carry it. Restated for the `:hover`/`:focus-visible` states
   specifically because `.bb-prio:hover`/`identity.css`'s own hover
   rules recolour the border AND add a category-tinted glow to the
   box-shadow -- a whole-card wash exactly like the one this section
   already removes at rest. */
.bb-prio:hover,
.bb-prio:focus-visible {
  border-color: var(--bb-border-strong);
  box-shadow: inset 3px 0 0 var(--prio);
}
.bb-prio__cta,
.bb-rail-callout__cta {
  background: transparent;
  border: 0;
  padding: 0;
  text-align: left;
  font: var(--bb-type-chip);
  letter-spacing: var(--bb-tracking-chip);
  color: var(--bb-purple-bright);
}
.bb-prio:hover .bb-prio__cta {
  text-decoration: underline;
}
.bb-prio__headline {
  font: var(--bb-type-card);
  font-weight: var(--bb-fw-bold);
  color: var(--bb-text-primary);
}
.bb-prio__why {
  font: var(--bb-type-body);
  color: var(--bb-text-secondary);
}

/* --- S3: HERO TAGLINE/DESC READ AS METADATA, NOT A SECOND HEADLINE -----
   Command Center's and Waiver's hero taglines are demoted a step
   further than UI Uniformity Pack 06 left them (37.3 made the tagline
   an eyebrow-weight caption; this pass reads it as tertiary metadata
   instead of a secondary-ink caption) so the one real headline on each
   hero is unambiguous. */
.bb-hero__tagline {
  color: var(--bb-text-tertiary);
  font-weight: var(--bb-fw-medium);
}
.bb-hero__desc {
  font-size: var(--bb-fs-sm);
}

/* --- P1: MY BLACKBIRD -- attention band + per-card lineup attention ----
   `.bb-say`'s children need to lay out inside the existing flex row
   `.bb-lineup-attention__text` already is (its parent
   `.bb-lineup-attention__item` is the flex row; `__text` itself was a
   plain inline-ish flex child with no internal layout of its own). */
.bb-lineup-attention__text {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 8px;
}

/* --- P2: LINEUP RADAR -- league-instance notes ------------------------
   The first attention note (badge + message + "Bench options") reads
   as evidence (`.bb-say__ev`, secondary), not the primary-ink decision
   text section 38's A1/A2 correction made it -- the badge already
   carries the decision weight here, so the message beside it is
   supporting evidence, matching the `.bb-say` grammar this pass
   applies everywhere else. Restated at the SAME specificity as 38's
   rule (`.bb-lr-inst__notes > .bb-lr-inst__note:first-child`), later in
   the cascade, so it wins without renaming or deleting that rule. */
.bb-lr-inst__notes > .bb-lr-inst__note:first-child {
  color: var(--bb-text-secondary);
}
