/* ════════════════════════════════════════════════════════════════════════
   redesign.css — Hybrid "Data-Dense + Warm" design-system layer (Stage 1)
   Loaded LAST (after styles.css + polish.css). Additive + reversible: remove
   the <link> to fully revert to the prior look. Driven by the ui-ux-pro-max
   skill (Data-Dense Dashboard style + reasoning rules) per the user's choice:
   keep the warm --brand accent, adopt data-dense density, structure, tabular
   numerics, consistent elevation/radius, AA focus, and smooth state motion.
   NO markup/JS changes — restyles the shared component classes only.
   ════════════════════════════════════════════════════════════════════════ */

:root {
  /* Data-dense system variables (skill: --table-row-height 36, padding 12) */
  --rd-radius:      10px;   /* modern card rounding (was flat 0) */
  --rd-radius-sm:   7px;    /* controls / inputs */
  --rd-radius-pill: 999px;  /* status chips */
  --rd-row-h:       38px;   /* dense table row */
  --rd-pad:         13px;   /* card padding */
  /* taste-skill: tint shadows to the warm background hue; NO saturated glows */
  --rd-elev-1:      0 1px 2px rgba(74,46,28,.06);
  --rd-elev-2:      0 1px 2px rgba(74,46,28,.06), 0 8px 20px -12px rgba(74,46,28,.18);
  --rd-elev-hover:  0 2px 4px rgba(74,46,28,.08), 0 12px 26px -14px rgba(74,46,28,.26);
  --rd-rule:        var(--rule-soft, rgba(15,14,12,.10));
  --rd-rule-strong: rgba(15,14,12,.16);
  --rd-row-hover:   rgba(178,52,21,.045);   /* warm row highlight */
  --rd-head-bg:     rgba(15,14,12,.03);
  --rd-t:           160ms var(--ease-expo, cubic-bezier(.16,1,.3,1));
}
html[data-theme="dark"] {
  --rd-rule:        rgba(255,255,255,.10);
  --rd-rule-strong: rgba(255,255,255,.16);
  --rd-row-hover:   rgba(248,166,140,.06);
  --rd-head-bg:     rgba(255,255,255,.04);
  --rd-elev-1:      0 1px 2px rgba(0,0,0,.30);
  --rd-elev-2:      0 2px 4px rgba(0,0,0,.30), 0 8px 20px -8px rgba(0,0,0,.45);
  --rd-elev-hover:  0 6px 16px -6px rgba(0,0,0,.55);
}

/* ── 1. Accessibility: one consistent, visible focus ring everywhere (skill §1) */
a:focus-visible, button:focus-visible, [role="button"]:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible,
[tabindex]:focus-visible, summary:focus-visible {
  outline: 2px solid var(--brand, #b23415);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ── 2. Smooth, meaningful state motion (skill §7: 150–300ms; reduced-motion safe) */
a, button, [role="button"], .posChip, .sub-pill,
.ws-card, .hub-card, .mtd-card, .ws-section, .sub-section, .profile-section,
.lse-field, .study-affected__chip, .next-rail__card, .intel-col {
  transition: background-color var(--rd-t), border-color var(--rd-t),
              box-shadow var(--rd-t), transform var(--rd-t), color var(--rd-t);
}
@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* ── 3. Tabular numerics for all data (skill: number-tabular — no layout shift) */
.num, .row-adp, .row-mom, .ws-metric__value, .mtd-delta, .mtd-tag,
table td, table th, .sub-stat__value, .glog-tbl td, .lse-step__inp,
.mta2-stat b, .mta2-card__val {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ── 4. Cards / sections: modern radius + consistent elevation (skill §4 elevation) */
.ws-section, .sub-section, .hub-card, .mtd-card, .profile-section,
.lse-field, .study-affected, .intel-col, .next-rail__card, .ws-card,
.lab-card, .mtd, .pa-strip {
  border-radius: var(--rd-radius);
  border: 1px solid var(--rd-rule);
  background-clip: padding-box;
}
.ws-section, .sub-section, .mtd-card, .profile-section, .study-affected,
.intel-col, .lab-card { box-shadow: var(--rd-elev-1); }

/* Interactive cards lift on hover (skill: state-clarity, scale-feedback) */
.hub-card:hover, .mtd-card:hover, .next-rail__card:hover,
.study-affected__chip:hover, .lab-card:hover {
  box-shadow: var(--rd-elev-hover);
  border-color: var(--brand-tint, rgba(178,52,21,.20));   /* soft, not a hard saturated outline */
  transform: translateY(-1px);                            /* taste-skill: restrained motion */
}

/* ── 5. Data-dense tables — SUB-PAGE tables only (skill: sticky header,
   row-hover, gridlines). The main Rankings table (#tableBody in .table-wrap)
   keeps its bespoke dark sticky header at top:64px — intentionally NOT touched
   here, to avoid a specificity battle on the most important surface. */
.sub-section table thead th, .glog-tbl thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--rd-head-bg);
  backdrop-filter: saturate(1.4) blur(2px);
  -webkit-backdrop-filter: saturate(1.4) blur(2px);
  font: 700 10.5px/1.3 var(--font, system-ui);
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-3, #6a655b);
  padding: 9px 12px;
  border-bottom: 1px solid var(--rd-rule-strong);
}
.sub-section table tbody td, .glog-tbl tbody td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--rd-rule);
  vertical-align: middle;
}
.sub-section table tbody tr, .glog-tbl tbody tr { transition: background-color var(--rd-t); }
.sub-section table tbody tr:hover, .glog-tbl tbody tr:hover { background: var(--rd-row-hover); }
/* horizontal scroll guard on small screens (skill §5: no horizontal page scroll) */
.table-wrap, .glog-tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ── 6. Chips / pills: unified pill geometry (skill: icon/style consistency) */
.posChip, .sub-pill, .row-adp, .row-mini-pill, .pa-chip, .mtd-tag,
.mtd-need-chip, .lab-tier, .study-tier-badge {
  border-radius: var(--rd-radius-pill);
}
.row-mom { border-radius: var(--rd-radius-sm); }

/* ── 7. Buttons: consistent radius + press feedback (skill §2, §4 primary-action) */
.lse-btn, .hero__cta, .ops-btn, .mta2-btn, .sub-cta, .lse-seg, .lse-step,
.lse-seg__btn { border-radius: var(--rd-radius-sm); }
.lse-btn:active, .hero__cta:active, .ops-btn:active, .mta2-btn:active {
  transform: translateY(1px);
}

/* ── 8. KPI / metric blocks: data-dense card treatment (skill: KPI cards) */
.ws-metric, .mtd-card, .sub-stat {
  padding: var(--rd-pad);
}
.ws-metric { border-radius: var(--rd-radius); border: 1px solid var(--rd-rule); background: var(--surface, #fff); }

/* ── 9. Inputs: modern field affordance + AA (skill §8 forms) */
input[type="text"], input[type="number"], input[type="search"], select, textarea,
.ops-form__input, .ops-form__area, .lse-step__inp {
  border-radius: var(--rd-radius-sm);
}

/* ════════════════════════════════════════════════════════════════════════
   Stage 1.5 — aesthetic steer (taste-skill: precise numerics, refined
   hierarchy, single warm accent, no AI-tells). Display VALUES only — never
   table cells — so column widths stay stable.
   ════════════════════════════════════════════════════════════════════════ */
.big-num, .hero-stat__value, .study-stat__value, .attr-card__value,
.attr-li__value, .signal-core__value, .multivar-row__value, .mm-card__big,
.expl-trajectory-stat__value, .expl-headline-figure__num-block,
.ws-metric__value, .sub-stat__value, .mta2-stat b, .mta2-grade,
.mtd-delta, .row-mom, .hero-clean__delta {
  font-family: var(--mono, 'JetBrains Mono', ui-monospace, monospace);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.015em;
}

/* Hierarchy via weight + tracking, not just scale (taste-skill: no oversized H1) */
.sub-hero__title, .ws-section__title, .mtd-title, .hub-hero__title,
.study-article > header h2, .expl-hero__name {
  letter-spacing: -.022em;
}

/* Section eyebrows: quiet, technical, mono micro-labels for a data product */
.ws-section__eyebrow, .sub-hero__eyebrow, .mtd-eyebrow, .lse-field__sub {
  font-feature-settings: "tnum" 1;
}

/* ════════════════════════════════════════════════════════════════════════
   Stage 2 — per-surface information hierarchy (no new effects: spacing,
   grouping, emphasis, scanning, fewer/quieter boxes).
   ════════════════════════════════════════════════════════════════════════ */

/* ── DASHBOARD — primary question: "What changed today for my team?" ──────
   The My Team briefing is the answer; compress the decorative hero so it leads,
   and make the change-count scannable. De-emphasize, don't remove. */
.hub-workspace[data-workspace="dashboard"] .hub-hero__inner { min-height: 0; }
.hub-workspace[data-workspace="dashboard"] .hub-hero__art {
  max-height: 112px; overflow: hidden; align-self: center;
}
.hub-workspace[data-workspace="dashboard"] .hub-hero__photo {
  max-height: 112px; width: auto; object-fit: contain;
}
/* "N changes on your roster" = the answer → make it read instantly (hierarchy) */
.mtd-summary { font-size: 13.5px; }
.mtd-summary strong { font-size: 18px; line-height: 1; }
.mtd-head { align-items: center; }
/* a11y: the one too-bright section-pill red (Trade Center) → AA red, keep identity */
a.hub-section-pill[href*="trade-center"] { color: var(--red, #a8201a) !important; }

/* ── PLAYER PAGE — primary question: "Buy / hold / trade / fade?" ──────────
   Make the verdict + actionable signal dominate; keep reference content
   (comps, attribution, splits, game log, cascade) available but secondary.
   CSS-only: emphasis + reorder via stable .profile-section--<modifier> classes.
   No new effects. */
/* 1. Alerts strip = the verdict → the scannable focal point under the hero */
#explainerMain .pa-strip { margin: 6px 0 16px; gap: 8px; }
#explainerMain .pa-chip { padding: 7px 13px; }
#explainerMain .pa-chip__lab { font-size: 12.5px; }
/* 2. Surface the actionable signal: pull Market Movement (trade signal) + the
   Fantasy Thesis (human takeaway) to the top of the detail flow (were ~9th /
   ~1st-but-below-everything). Reference sections keep DOM order below. */
.explainer-flow { display: flex; flex-direction: column; }
.explainer-flow > .profile-section--market { order: -2; }
.explainer-flow > .profile-section--thesis { order: -1; }
/* 3. Reference sections stay available but quieter (smaller eyebrow) */
.explainer-flow > .profile-section--comps .profile-section__eyebrow,
.explainer-flow > .profile-section--multivar .profile-section__eyebrow,
.explainer-flow > .profile-section--splits .profile-section__eyebrow,
.explainer-flow > .profile-section--gamelog .profile-section__eyebrow {
  font-size: 12px;
}

/* ════════════════════════════════════════════════════════════════════════
   Stage 2 — Targeted IA fix (no nav overhaul): surface daily actions on the
   Dashboard + sharpen Dashboard ("what changed") vs My Team ("what to do").
   Layout + hierarchy only — reuses existing pill styling; no new effects.
   ════════════════════════════════════════════════════════════════════════ */
/* Dashboard quick-actions toolbar: daily tools one click from the hub
   (lineup / waivers / start-sit / trade / injuries) instead of buried in the
   Operations workspace. Deliberately NOT sticky (unlike .hub-section-strip) so
   it never collides with the section-nav strip; the pills reuse
   .hub-section-pill and inherit the dashboard workspace tone. */
.hub-quick-actions {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 8px; margin: 2px 0 18px;
}
.hub-quick-actions__lab {
  font: 700 10.5px/1 var(--font, system-ui);
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-3, #6a655b); margin-right: 4px;
}
/* Briefing → My Team hand-off CTA (de-dup: the Dashboard reports what changed,
   My Team is where you act). Accent link using the existing --brand token. */
.mtd-head__act {
  font-weight: 600; white-space: nowrap;
  color: var(--brand, #b23415); text-decoration: none;
}
.mtd-head__act:hover { text-decoration: underline; }

/* ── TRADE ANALYZER — answer-first: collapse the "Roster construction" advanced
   row by default. The markup ships it [hidden] and the Advanced ▾ toggle flips
   that attribute, but a base `.mta2-adv{display:flex}` rule overrode it — so the
   row was always shown (~50px of config above the verdict) and the toggle was a
   no-op. Respecting [hidden] declutters the top AND repairs the toggle. */
.mta2-adv[hidden] { display: none; }
/* a11y (WCAG 1.4.1, surfaced on this route): the empty-state "Import opponents
   in Sync" hint has an inline link distinguished by color only — underline it so
   it's distinguishable without relying on color. */
.mta2-qa-row a { text-decoration: underline; }

/* ── RESEARCH HUB (studies index, #/research/studies) — mobile answer-first.
   The category sidebar is a sticky, height-capped column on desktop, but the
   existing ≤900px rule makes it position:static / max-height:none, so its full
   category list (~5600px, all 166 study links) stacks ABOVE the index — burying
   the tier filter chips, the freshness stamp, and every study card ~6800px down
   (0 cards on the first mobile screen). The index is self-navigable on mobile
   (tier filter chips + search + category-grouped cards + the Data-Backed vs
   Framework/Experimental split), so collapse the redundant sidebar there to
   surface the answer. No content is hidden — every study, including experimental,
   still renders in the index with its honest tier label. */
@media (max-width: 900px) {
  .studies-sidebar { display: none; }
}

/* ── TRADE ANALYZER a11y — muted-text AA on the cream page bg. Companion to the
   PE4 fix (polish.css) that darkened --text-4 scoped to .mta2. The remaining
   muted labels (.mta2-chip, .mta2-ex__s, .mta2-empty__lead p) use --text-3
   (#6a655b ≈ 5.05:1 — borderline) and axe flags them transiently during the
   entry fade; darken --text-3 scoped to the analyzer (light theme only) for a
   comfortable AA margin (~6:1). The hardcoded inline #6b7280 in rosterQuickAdd
   (≈4.21:1 — a genuine fail) is fixed at source in trade-analyzer.js. No hue
   change, no layout/logic change; the green/red grade tones are untouched. */
html:not([data-theme="dark"]) .mta2 { --text-3: #5d584d; }

/* ── Owner request (2026-06-08): hide the Methodology tab from the site — it was
   an internal/dev surface ("just for me"). One rule covers every render path: the
   top-nav tab, the mobile drawer (same .layer1-rail__item, revealed by the burger),
   and its hover flyout (a display:none trigger can't be hovered, so the flyout
   never populates for methodology). The footer's two methodology doc links are
   hidden too. Routes (#/methodology*) are intentionally LEFT INTACT, so the owner
   keeps direct-URL access; the "45 stale" data-health chip is unaffected. Fully
   reversible — delete these two rules to restore. */
.layer1-rail__item[data-workspace="methodology"] { display: none; }
.home-footer__col a[href*="methodology"] { display: none; }

/* ── Owner request (2026-06-08): remove the "N stale" data-pipeline chip from the
   top-right nav. app.js reveals it (inline display) when sources are stale; this
   overrides that so it never shows. */
#siteNavDataHealth { display: none !important; }

/* ── Owner branding (2026-06-08): recolor the hero wordmark accent letter ("r")
   from the orange --accent gimmick to Ohio State scarlet. */
.hero__title .gradient,
.hero__title--scoreboard .gradient,
.hero__title--clean .gradient {
  color: #BB0000 !important;
  -webkit-text-fill-color: #BB0000 !important;
}
/* Owner fix (2026-06-08): the wordmark "r" overlapped the "g" — a base rule set
   .gradient margin-left:-0.08em (pulling it onto the "g"). Neutralize so the "r"
   sits after the "g" at the title's normal tracking (no overlap). */
.hero__title .gradient { margin-left: 0 !important; }

/* Owner branding (2026-06-08): the Risers & fallers card's trend lines (the
   rising line + the falling line, stroke=currentColor) → Ohio State scarlet. */
.home-surface__viz .viz-up,
.home-surface__viz .viz-down { color: #BB0000 !important; }

/* ── Owner request (2026-06-08): format section subtitles correctly site-wide.
   The shared .profile-section__sub (e.g. Market Movement's "Cross-referenced
   signals · …") was 18px/600/near-black — it read as a heading competing with
   its own eyebrow label. Render it as a proper muted subtitle (smaller, normal
   weight, secondary color) so the eyebrow is the label and this is the descriptor.
   Applies to every profile section. */
.profile-section__sub {
  font-size: 13.5px !important;
  font-weight: 500 !important;
  line-height: 1.45 !important;
  letter-spacing: 0 !important;
  color: var(--text-2, #5a5650) !important;
}

/* ── Owner fix (2026-06-08): rankings table header was overlapping row #1. The
   .table-wrap is overflow-x:auto (mobile scroll-guard), which makes the sticky
   thead pin to the WRAP rather than the page — so top:64px (meant to clear the
   fixed nav when page-pinned) pushed the header 64px DOWN into the first rows.
   Pin it to the wrap top instead so the header sits correctly above the rows. */
#tableWrap thead th, .table-wrap thead th { top: 0 !important; } /* generalized 2026-06-16: ALL .table-wrap (prospects/daily/etc.) pin sticky thead to the wrap, not the page — top:64px pushed labels into row 1 */

/* ════════════════════════════════════════════════════════════════════════
   Owner request (2026-06-08): RANKINGS-FAMILY LEFT RAIL — a real shared
   sidebar modeled on the dashboard Shell-B rail. The rankingsRail() IIFE
   (app.js) builds an independent <aside class="shell-b__rail rank-rail">
   across the 8 family routes and sets body[data-rank-rail]. The rail reuses
   the .shell-b__rail visual styling (defined in polish.css) so it looks
   identical to the dashboard; only the content reflow + horizontal-bar
   suppression live here.

   Desktop (≥769px) only: replace the horizontal sub-nav with the rail and
   reflow the family .page content right to clear the fixed rail (mirrors the
   Shell-B offset: padding-left = rail width + gutter). Mobile (≤768px) keeps
   the existing horizontal sub-nav — the rail auto-hides via the existing
   .shell-b__rail max-width:768px rule, and these reflow rules don't apply.
   Display/navigation only — no engine/projection/value changes.
   ════════════════════════════════════════════════════════════════════════ */
@media (min-width: 769px) {
  /* Desktop: the rail replaces the horizontal sub-nav. */
  body[data-rank-rail] .workspace-subnav--top[data-parent="rankings"] { display: none !important; }
  /* Reflow family content to clear the fixed 250px rail. */
  body[data-rank-rail] .page {
    max-width: none !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
    padding-left: calc(var(--shell-left-rail-w, 250px) + 24px) !important;
    padding-right: 24px !important;
  }
}
@media (min-width: 769px) and (max-width: 1100px) {
  body[data-rank-rail] .page {
    padding-left: calc(var(--shell-left-rail-w, 250px) + 16px) !important;
    padding-right: 16px !important;
  }
}

/* ── Owner fix (2026-06-09): remove two stray UI bits ────────────────────
   1) The "Skip to main content" link (.skip-to-content) slides in as a black
      block at the top-left whenever it takes keyboard focus — visible across
      the whole site. Owner asked to remove it. (It was the WCAG bypass-blocks
      skip link; the site remains keyboard-navigable without it.)
   2) The dynamic workspace sub-nav (#wsSubtab) renders as an empty tan pill on
      routes where it has no items (e.g. the home page). Hide it while empty so
      the stray block doesn't show; it still appears when it has real items. */
.skip-to-content { display: none !important; }
#wsSubtab:empty { display: none !important; }

/* ── Owner request (2026-06-09): clean integrations-style import cards on
   #/operations/sync. Three equal platform cards (ESPN / Yahoo / Sleeper)
   under one header; statuses render only when they have content. */
.ops-connect {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin-top: 14px;
}
@media (max-width: 1100px) { .ops-connect { grid-template-columns: 1fr 1fr; } }
@media (max-width: 760px)  { .ops-connect { grid-template-columns: 1fr; } }

.ops-connect__card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--sv-surface, #fbfaf6);
  border: 1px solid var(--sv-hairline, rgba(15, 14, 12, .10));
  border-radius: 12px;
  padding: 16px 16px 14px;
}
.ops-connect__top { display: flex; align-items: center; gap: 10px; }
.ops-connect__badge {
  width: 34px; height: 34px; flex: 0 0 34px;
  border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  font: 800 15px/1 var(--sv-font, system-ui);
  letter-spacing: .02em;
  background: var(--sv-ink, #14130f);
  color: #fff;
}
.ops-connect__title { font: 700 15px/1.2 var(--sv-font, system-ui); color: var(--sv-ink, #14130f); }
.ops-connect__tag {
  margin-top: 2px;
  font: 600 10.5px/1.3 var(--sv-font, system-ui);
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--sv-ink-3, #6a655b);
}
.ops-connect__body { margin: 0; font-size: 13px; line-height: 1.55; color: var(--text-2, #5a5650); flex: 1 1 auto; }
.ops-connect__body a { color: inherit; text-decoration: underline; }
.ops-connect__act { display: flex; gap: 8px; align-items: center; }
.ops-connect__act--col { flex-direction: column; align-items: stretch; }
.ops-connect__act .ops-form__input { width: 100%; box-sizing: border-box; }
.ops-connect__card .ops-form__status { font-size: 12px; line-height: 1.45; }

/* Empty status spans (no message yet) take no space — kills the stray "-"
   era placeholders without touching how messages appear. */
.ops-form__status:empty { display: none; }

/* ── Portfolio HQ (owner request 2026-06-09): All Portfolios upgraded into a
   cross-league HQ — summary strip, per-league cards (★ my team, projected
   finish, entry/payout/ROI), and the cross-team composition table. */
.hq-strip {
  display: flex; flex-wrap: wrap; gap: 12px;
  margin: 0 0 18px;
}
.hq-stat {
  background: var(--sv-surface, #fbfaf6);
  border: 1px solid var(--sv-hairline, rgba(15, 14, 12, .10));
  border-radius: 12px;
  padding: 12px 16px;
  min-width: 120px;
}
.hq-stat__n { font: 700 17px/1.25 var(--sv-font, system-ui); color: var(--sv-ink, #14130f); }
.hq-stat__l { margin-top: 2px; font: 600 10.5px/1.3 var(--sv-font, system-ui); letter-spacing: .07em; text-transform: uppercase; color: var(--sv-ink-3, #6a655b); }
.hq-stat--cta { display: flex; align-items: center; }

.hq-leagues { display: grid; grid-template-columns: 1fr; gap: 12px; margin-top: 12px; }
.hq-league {
  background: var(--sv-surface, #fbfaf6);
  border: 1px solid var(--sv-hairline, rgba(15, 14, 12, .10));
  border-radius: 12px;
  padding: 14px 16px;
}
.hq-league__head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 14px; }
.hq-mine { margin-top: 10px; font-size: 13.5px; line-height: 1.5; }
.hq-pickrow { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 13px; }
.hq-moneyrow { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.hq-mlab { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 5px; font: 700 10px/1 var(--sv-font, system-ui); letter-spacing: .07em; text-transform: uppercase; color: var(--sv-ink-3, #6a655b); }
.hq-mlab .hq-money { width: 92px; padding: 7px 9px; font-size: 13px; border: 1px solid var(--sv-hairline, rgba(15,14,12,.14)); border-radius: 8px; background: #fff; font-variant-numeric: tabular-nums; }
.hq-roi { margin-top: 10px; font-size: 13.5px; }
.hq-pos { color: #2e7d32; }
.hq-neg { color: #c0392b; }
.hq-dim { color: var(--sv-ink-3, #6a655b); }
.hq-lgs .ops-plat { margin-right: 4px; }

/* ★ my-team toggle + platform chip (HQ cards + Sync stored list) */
.ops-mine {
  border: 0; background: none; cursor: pointer;
  font-size: 15px; line-height: 1; padding: 2px 4px;
  color: var(--sv-ink-3, #8a857a);
  border-radius: 6px;
}
.ops-mine:hover { color: #BB0000; background: rgba(187, 0, 0, .06); }
.ops-mine.is-mine { color: #BB0000; }
.hq-pickrow .ops-mine {
  border: 1px solid var(--sv-hairline, rgba(15,14,12,.14));
  padding: 5px 10px; font-size: 12.5px; border-radius: 999px;
  background: #fff;
}
.ops-plat {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font: 700 10px/1.4 var(--sv-font, system-ui);
  letter-spacing: .06em; text-transform: uppercase;
  background: rgba(15, 14, 12, .06); color: var(--sv-ink-3, #5d584d);
}

/* Season money ledger (inside each HQ league card) */
.hq-ledger { margin-top: 12px; border-top: 1px dashed var(--sv-hairline, rgba(15,14,12,.12)); padding-top: 10px; }
.hq-ledger summary { cursor: pointer; font-size: 13px; color: var(--sv-ink-2, #3f3b33); }
.hq-ledger summary:hover { color: var(--sv-ink, #14130f); }
.hq-led-table { width: 100%; border-collapse: collapse; margin: 10px 0 4px; font-size: 12.5px; }
.hq-led-table th { text-align: left; font: 700 10px/1.4 var(--sv-font, system-ui); letter-spacing: .07em; text-transform: uppercase; color: var(--sv-ink-3, #6a655b); padding: 4px 8px 4px 0; }
.hq-led-table th.num, .hq-led-table td.num { text-align: right; }
.hq-led-table td { padding: 4px 8px 4px 0; border-top: 1px solid var(--sv-hairline, rgba(15,14,12,.07)); }
.hq-led-note { color: var(--sv-ink-3, #6a655b); }
.hq-led-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 8px; }
.hq-led-form .hq-led-in {
  padding: 6px 8px; font-size: 12.5px;
  border: 1px solid var(--sv-hairline, rgba(15,14,12,.14));
  border-radius: 8px; background: #fff;
}
.hq-led-form .hq-led-in[data-f="a"] { width: 96px; }
.hq-led-form .hq-led-in[data-f="n"] { flex: 1 1 140px; min-width: 120px; }

/* Draft-order rule selector (HQ league cards) */
.hq-draftmode {
  padding: 3px 6px; font: 600 11.5px/1.3 var(--sv-font, system-ui);
  border: 1px solid var(--sv-hairline, rgba(15,14,12,.14));
  border-radius: 7px; background: #fff; color: var(--sv-ink-2, #3f3b33);
  margin: 0 4px;
}

/* Pick-probability mini bar + lottery ball editor */
.hq-draftbar { margin-top: 8px; }
.hq-pickbar { display: flex; align-items: flex-end; gap: 3px; max-width: 420px; }
.hq-pickbar__col { flex: 1 1 0; min-width: 14px; text-align: center; }
.hq-pickbar__b {
  background: var(--sv-ink-3, #8a857a); opacity: .55;
  border-radius: 3px 3px 0 0; margin: 0 auto; width: 100%;
}
.hq-pickbar__b.is-modal { background: #BB0000; opacity: .9; }
.hq-pickbar__lbl { margin-top: 3px; font: 600 9.5px/1 var(--sv-font, system-ui); color: var(--sv-ink-3, #6a655b); font-variant-numeric: tabular-nums; }
.hq-ballsrow { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 10px; font-size: 12px; }
.hq-ballsrow .hq-balls {
  width: 52px; padding: 4px 6px; font-size: 12.5px;
  border: 1px solid var(--sv-hairline, rgba(15,14,12,.14));
  border-radius: 7px; background: #fff;
}

/* ════════════════════════════════════════════════════════════════════════
   Typography pass (owner request 2026-06-10): one shared label/value unit
   for every stat line, small-caps section subheads inside cards, footnotes
   as quiet block notes, structured list rows — replaces the run-on
   "a · b · c" strings that had accumulated across the HQ surfaces.
   ════════════════════════════════════════════════════════════════════════ */
.hq-kvrow { display: flex; flex-wrap: wrap; gap: 8px 22px; margin-top: 10px; align-items: baseline; }
.hq-kv { display: inline-flex; flex-direction: column; gap: 2px; min-width: 64px; }
.hq-kv__l {
  font: 700 9.5px/1.2 var(--sv-font, system-ui);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--sv-ink-3, #6a655b); white-space: nowrap;
}
.hq-kv__v {
  font: 650 14.5px/1.25 var(--sv-font, system-ui);
  color: var(--sv-ink, #14130f);
  font-variant-numeric: tabular-nums;
}
.hq-kv--pos .hq-kv__v { color: #2e7d32; }
.hq-kv--neg .hq-kv__v { color: #c0392b; }
.hq-kv--warn .hq-kv__v { color: #8a6a14; }

.hq-subh {
  margin-top: 16px;
  display: flex; align-items: center; gap: 8px;
  font: 700 10.5px/1.3 var(--sv-font, system-ui);
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--sv-ink-3, #6a655b);
  border-top: 1px dashed var(--sv-hairline, rgba(15,14,12,.10));
  padding-top: 12px;
}
.hq-subh .hq-draftmode { text-transform: none; letter-spacing: 0; width: auto !important; flex: 0 0 auto; }

.hq-note {
  margin-top: 6px;
  font: 500 11.5px/1.5 var(--sv-font, system-ui);
  color: var(--sv-ink-3, #8a857a);
  max-width: 70ch;
}

/* My-team name line */
.hq-mine { margin-top: 2px; }
.hq-mine a strong { font-size: 15px; letter-spacing: -.005em; }

/* Stored portfolios: structured rows instead of run-on text */
.ops-list .ops-list__row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0;
  border-top: 1px solid var(--sv-hairline, rgba(15,14,12,.07));
}
.ops-list .ops-list__row:first-child { border-top: 0; }
.ops-list__name { font-size: 13.5px; }
.ops-list__meta {
  margin-left: auto;
  font: 500 12px/1.4 var(--sv-font, system-ui);
  color: var(--sv-ink-3, #6a655b);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Readability: keep section sub-copy at a readable measure, consistent
   numeric alignment in stat displays site-wide. */
.ops-section__sub { max-width: 78ch; line-height: 1.55 !important; }
.hq-stat__n, .ops-teams-table td.num, .hq-led-table td.num { font-variant-numeric: tabular-nums; }
.hq-roi { font-variant-numeric: tabular-nums; }

/* Odds-history sparkline (HQ league cards) */
.hq-trend { display: flex; align-items: center; gap: 10px; margin-top: 8px; font-size: 11.5px; }
.hq-trend .hq-spark { flex: 0 0 auto; opacity: .9; }

/* Roster alerts (HQ) */
.hq-alert {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 7px 0; font-size: 13px; line-height: 1.45;
  border-top: 1px solid var(--sv-hairline, rgba(15,14,12,.06));
}
.hq-alert:first-of-type { border-top: 0; }
.hq-alert__tag {
  flex: 0 0 auto;
  font: 700 9.5px/1.6 var(--sv-font, system-ui);
  letter-spacing: .07em; padding: 1px 7px; border-radius: 999px;
  background: rgba(15,14,12,.06); color: var(--sv-ink-3, #5d584d);
}
.hq-alert--warn .hq-alert__tag { background: rgba(176,108,0,.12); color: #8a6a14; }
.hq-alert--neg .hq-alert__tag { background: rgba(192,57,43,.12); color: #c0392b; }
.hq-alert--ok .hq-alert__tag { background: rgba(46,125,50,.12); color: #2e7d32; }

/* My player news (HQ) */
.hq-news { list-style: none; margin: 0; padding: 0; }
.hq-news__item { padding: 10px 0; border-top: 1px solid var(--sv-hairline, rgba(15,14,12,.07)); }
.hq-news__item:first-child { border-top: 0; }
.hq-news__meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; font-size: 11.5px; color: var(--sv-ink-3, #6a655b); }
.hq-news__date { font-variant-numeric: tabular-nums; }
.hq-news__exp { font: 600 10.5px/1.4 var(--sv-font, system-ui); letter-spacing: .04em; }
.hq-news__exp--hot { color: #BB0000; font-weight: 700; }
.hq-news__head { margin-top: 4px; font-size: 13.5px; line-height: 1.45; }
.hq-news__head a { color: inherit; text-decoration: underline; }


/* ── Site loadbar (owner request 2026-06-11): thin scarlet progress bar
   across the very top — visible from first paint until the projection
   engine is warm, and briefly on every route change. Created by the inline
   bootstrap in index.html, driven by the siteLoadbar IIFE in app.js. */
#siteLoadbar {
  position: fixed; top: 0; left: 0;
  height: 3px; width: 4%;
  background: #BB0000;
  z-index: 100000;
  transition: width .25s ease, opacity .4s ease;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  #siteLoadbar { transition: none; }
}


/* ════════════════════════════════════════════════════════════════════════
   Alignment contract (owner request 2026-06-11). A measured audit found
   header/cell text-align mismatches across the shared table families
   (th left vs td right, numeric headers left, numeric cells drifting) from
   overlapping legacy rules. This block is the END of that fight: text
   columns LEFT, numeric columns RIGHT, headers always match their cells.
   !important is deliberate — this is the last file in the cascade and the
   contract must be deterministic.
   ════════════════════════════════════════════════════════════════════════ */
.sub-table th, .sub-table td,
.glog-tbl th, .glog-tbl td,
.savant-career-table th, .savant-career-table td,
.mm-skill-table th, .mm-skill-table td,
.pintel-tbl th, .pintel-tbl td,
.pevo-sh__tbl th, .pevo-sh__tbl td,
.ops-power-table th, .ops-power-table td,
.ops-teams-table th, .ops-teams-table td,
.ops-matchup-top th, .ops-matchup-top td,
.ops-standings-table th, .ops-standings-table td {
  text-align: left !important;
}
/* Numeric columns: header AND cell right, tabular figures. Covers every
   numeric class convention in the codebase. Selector specificity is kept
   ABOVE the left-contract blanket (.sub-table th = 0,1,1) so the numeric
   override always wins the !important tie. */
.sub-table th.sub-table__cell--num, .sub-table td.sub-table__cell--num,
table th.sub-table__cell--num, table td.sub-table__cell--num,
table th.num, table td.num,
table td[data-num], table th[data-num],
.ops-power-table th.num, .ops-power-table td.num,
.ops-teams-table th.num, .ops-teams-table td.num,
.ops-standings-table th.num, .ops-standings-table td.num,
.ops-matchup-top th.num, .ops-matchup-top td.num,
.hq-led-table th.num, .hq-led-table td.num {
  text-align: right !important;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}
/* Rank + name columns in the shared report tables never wrap mid-name —
   the wrap that made names ragged; .table-wrap provides horizontal scroll. */
.sub-table th:nth-child(1), .sub-table td:nth-child(1),
.sub-table th:nth-child(2), .sub-table td:nth-child(2) {
  white-space: nowrap;
}
/* Headers across these families: consistent vertical alignment with cells. */
.sub-table th, .glog-tbl th, .savant-career-table th, .mm-skill-table th,
.pintel-tbl th, .pevo-sh__tbl th { vertical-align: bottom; }
.sub-table td, .glog-tbl td, .savant-career-table td, .mm-skill-table td,
.pintel-tbl td, .pevo-sh__tbl td { vertical-align: middle; }

/* ===== HOMEPAGE V2 (Savant-inspired) ===== */
/* Data-dense, Baseball-Savant-inspired home. Uses canonical theme tokens so it
   stays consistent with the boards (light --bg, white --surface, navy --ink,
   blue --brand). One intentional dark element: the slate strip up top. */
.hv2 { max-width: 1180px; margin: 0 auto; padding: 0 20px 72px; }
.hv2 a { text-decoration: none; color: inherit; }
.hv2 .num, .hv2 [data-num] { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
.hv2-eyebrow { font-size: 10.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--text-3); }

/* ── Slate strip (the "Savant scoreboard") ───────────────────────────── */
.hv2-slate { background: linear-gradient(180deg,#1c3a5b 0%,#12273f 100%); border-radius: 14px; margin: 18px 0 22px; padding: 13px 16px 15px; box-shadow: 0 2px 12px rgba(12,31,56,.14); }
.hv2-slate__inner { }
.hv2-slate__head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 10px; }
.hv2-slate__title { color: #fff; font-weight: 800; font-size: 14px; letter-spacing: .01em; display: flex; align-items: center; gap: 9px; }
.hv2-slate__live { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: #6fd3ff; }
.hv2-slate__dot { width: 6px; height: 6px; border-radius: 50%; background: #34d399; box-shadow: 0 0 0 0 rgba(52,211,153,.6); animation: hv2pulse 2s infinite; }
@keyframes hv2pulse { 0%{box-shadow:0 0 0 0 rgba(52,211,153,.5)} 70%{box-shadow:0 0 0 7px rgba(52,211,153,0)} 100%{box-shadow:0 0 0 0 rgba(52,211,153,0)} }
.hv2-slate__all { color: #9db8d6; font-size: 12px; font-weight: 700; }
.hv2-slate__all:hover { color: #fff; }
.hv2-slate__track { display: flex; gap: 10px; overflow-x: auto; scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.25) transparent; padding-bottom: 4px; }
.hv2-slate__track::-webkit-scrollbar { height: 6px; }
.hv2-slate__track::-webkit-scrollbar-thumb { background: rgba(255,255,255,.18); border-radius: 6px; }
.hv2-game { flex: 0 0 auto; min-width: 184px; background: rgba(255,255,255,.045); border: 1px solid rgba(255,255,255,.09); border-radius: 11px; padding: 10px 12px; color: #e9eef6; transition: background .14s, border-color .14s, transform .14s; }
.hv2-game:hover { background: rgba(255,255,255,.085); border-color: rgba(255,255,255,.2); transform: translateY(-1px); }
.hv2-game__time { font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #8fb0d6; margin-bottom: 7px; }
.hv2-game__row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 2px 0; }
.hv2-game__team { display: flex; align-items: center; gap: 8px; min-width: 0; }
.hv2-game__bar { width: 3px; height: 16px; border-radius: 2px; flex: 0 0 auto; background: #5b7da6; }
.hv2-game__abbr { font-weight: 800; font-size: 13px; letter-spacing: .02em; }
.hv2-game__sp { font-size: 11px; color: #9fb6d2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 92px; }
.hv2-game__sp b { color: #cdd9e8; font-weight: 700; }

/* ── Hero band (compact, light) ──────────────────────────────────────── */
.hv2-hero { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; margin-bottom: 18px; }
.hv2-hero__l { min-width: 280px; flex: 1 1 420px; }
.hv2-hero__kicker { display: inline-flex; align-items: center; gap: 7px; font-size: 11px; font-weight: 700; color: var(--brand); background: var(--brand-soft); border: 1px solid var(--brand-tint); border-radius: 999px; padding: 3px 11px; margin-bottom: 11px; }
.hv2-hero__brand { display: inline-flex; align-items: center; gap: 11px; margin-bottom: 14px; }
.hv2-hero__mark { width: 42px; height: 42px; display: block; flex: none; border-radius: 11px; box-shadow: 0 4px 14px -2px rgba(13,35,64,.22); }
.hv2-hero__wordmark { font-size: 30px; line-height: 1; font-weight: 850; letter-spacing: -.025em; color: var(--text-1); }
.hv2-hero__wordmark b { color: var(--brand); font-weight: 850; }
.hv2-hero__title { font-size: 30px; line-height: 1.08; font-weight: 850; letter-spacing: -.02em; color: var(--text-1); margin: 0 0 7px; }
.hv2-hero__title b { color: var(--brand); }
.hv2-hero__lede { font-size: 14.5px; line-height: 1.5; color: var(--text-2); margin: 0 0 14px; max-width: 540px; }
.hv2-hero__ctas { display: flex; gap: 10px; flex-wrap: wrap; }
.hv2-btn { display: inline-flex; align-items: center; gap: 7px; font-size: 13.5px; font-weight: 700; padding: 9px 16px; border-radius: 9px; border: 1px solid var(--hairline-strong); color: var(--text-1); background: var(--surface); transition: transform .12s, box-shadow .12s, background .12s; }
.hv2-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(13,35,64,.1); }
.hv2-btn--primary { background: var(--brand-grad); border-color: transparent; color: #fff; }
.hv2-btn--primary:hover { box-shadow: 0 6px 18px rgba(29,95,167,.32); }
.hv2-hero__search { flex: 0 0 auto; }

/* ── KPI row ──────────────────────────────────────────────────────────── */
.hv2-kpis { display: grid; grid-template-columns: repeat(4,1fr); gap: 12px; margin-bottom: 22px; }
.hv2-kpi { background: var(--surface); border: 1px solid var(--hairline); border-radius: 13px; padding: 13px 15px; display: block; transition: transform .12s, box-shadow .12s, border-color .12s; }
.hv2-kpi:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(13,35,64,.09); border-color: var(--hairline-strong); }
.hv2-kpi__n { font-size: 25px; font-weight: 850; letter-spacing: -.02em; color: var(--text-1); line-height: 1.05; }
.hv2-kpi__n.is-pos { color: var(--cat-good,#0f766e); }
.hv2-kpi__l { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-3); margin-top: 5px; }
.hv2-kpi--wide .hv2-kpi__n { font-size: 18px; }

/* ── Main grid + cards ───────────────────────────────────────────────── */
.hv2-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
.hv2-card { background: var(--surface); border: 1px solid var(--hairline); border-radius: 14px; overflow: hidden; display: flex; flex-direction: column; }
.hv2-card__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 13px 16px 11px; border-bottom: 1px solid var(--hairline); }
.hv2-card__title { font-size: 14.5px; font-weight: 800; letter-spacing: -.01em; color: var(--text-1); display: flex; align-items: center; gap: 8px; }
.hv2-card__title .hv2-accent { width: 4px; height: 15px; border-radius: 2px; background: var(--brand); display: inline-block; }
.hv2-card__all { font-size: 11.5px; font-weight: 700; color: var(--brand); white-space: nowrap; }
.hv2-card__all:hover { text-decoration: underline; }
.hv2-card__body { padding: 6px 8px 8px; }

/* leaderboard rows */
.hv2-lb { display: flex; flex-direction: column; }
.hv2-lb__row { display: grid; grid-template-columns: 26px 1fr auto auto; align-items: center; gap: 10px; padding: 7px 8px; border-radius: 8px; transition: background .12s; }
.hv2-lb__row:hover { background: var(--surface-soft); }
.hv2-lb__rank { font-size: 12px; font-weight: 800; color: var(--text-3); text-align: center; font-variant-numeric: tabular-nums; }
.hv2-lb__row--top .hv2-lb__rank { color: var(--brand); }
.hv2-lb__main { min-width: 0; display: flex; align-items: center; gap: 8px; }
.hv2-lb__name { font-size: 13.5px; font-weight: 700; color: var(--text-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hv2-lb__meta { font-size: 11px; color: var(--text-3); font-weight: 600; white-space: nowrap; }
.hv2-lb__val { font-size: 14px; font-weight: 800; color: var(--text-1); font-variant-numeric: tabular-nums; text-align: right; }
.hv2-lb__val small { font-size: 10px; font-weight: 700; color: var(--text-3); margin-left: 2px; }
.hv2-lb__spark { display: inline-flex; align-items: center; justify-content: flex-end; width: 58px; opacity: .92; transition: opacity .14s; }
.hv2-lb__row:hover .hv2-lb__spark { opacity: 1; }
.hv2-spark { width: 58px; height: 22px; display: block; }
.hv2 .posChip { font-size: 9.5px; padding: 1px 5px; }

/* ── Managr vs Market edge ───────────────────────────────────────────── */
.hv2-edge { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px; }
.hv2-edge__col { padding: 6px 6px 2px; }
.hv2-edge__h { font-size: 10.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; margin-bottom: 4px; display: flex; align-items: center; gap: 6px; }
.hv2-edge__h--love { color: var(--cat-good,#0f766e); }
.hv2-edge__h--fade { color: var(--cat-bad,#b91c1c); }
.hv2-edge__row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 8px; padding: 6px 6px; border-radius: 7px; }
.hv2-edge__row:hover { background: var(--surface-soft); }
.hv2-edge__nm { font-size: 12.5px; font-weight: 700; color: var(--text-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hv2-edge__nm small { color: var(--text-3); font-weight: 600; font-size: 10.5px; margin-left: 4px; }
.hv2-edge__delta { font-size: 11px; font-weight: 800; padding: 1px 7px; border-radius: 999px; font-variant-numeric: tabular-nums; }
.hv2-edge__delta--love { color: var(--cat-good,#0f766e); background: rgba(15,118,110,.1); }
.hv2-edge__delta--fade { color: var(--cat-bad,#b91c1c); background: rgba(185,28,28,.09); }
.hv2-edge__note { font-size: 11px; color: var(--text-3); padding: 8px 12px 2px; line-height: 1.4; }

/* ── Player news feed ────────────────────────────────────────────────── */
.hv2-news { display: flex; flex-direction: column; }
.hv2-news__row { display: grid; grid-template-columns: auto 1fr; gap: 11px; padding: 9px 10px; border-radius: 9px; align-items: start; transition: background .12s; }
.hv2-news__row:hover { background: var(--surface-soft); }
.hv2-news__src { font-size: 10px; font-weight: 800; letter-spacing: .03em; text-transform: uppercase; color: #fff; background: var(--text-3); border-radius: 5px; padding: 3px 6px; white-space: nowrap; margin-top: 1px; }
.hv2-news__src--il { background: var(--cat-bad,#b91c1c); }
.hv2-news__b { min-width: 0; }
.hv2-news__hl { font-size: 13px; font-weight: 700; line-height: 1.32; color: var(--text-1); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.hv2-news__meta { font-size: 11px; color: var(--text-3); margin-top: 3px; font-weight: 600; }
.hv2-news__meta b { color: var(--text-2); }

/* ── Stat leaders grid ───────────────────────────────────────────────── */
.hv2-statwrap { margin-bottom: 16px; }
.hv2-stats { display: grid; grid-template-columns: repeat(3,1fr); gap: 12px; padding: 12px; }
.hv2-stat { border: 1px solid var(--hairline); border-radius: 11px; padding: 9px 11px 6px; background: var(--surface-soft); }
.hv2-stat__h { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 5px; }
.hv2-stat__lbl { font-size: 11px; font-weight: 800; letter-spacing: .03em; color: var(--text-1); }
.hv2-stat__sub { font-size: 10.5px; font-weight: 700; color: var(--text-3); text-transform: uppercase; letter-spacing: .04em; }
.hv2-stat__row { display: grid; grid-template-columns: 14px 1fr auto; gap: 7px; align-items: center; padding: 3.5px 0; }
.hv2-stat__rk { font-size: 10px; font-weight: 800; color: var(--text-3); text-align: center; }
.hv2-stat__nm { font-size: 12px; font-weight: 600; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hv2-stat__v { font-size: 12.5px; font-weight: 800; color: var(--text-1); font-variant-numeric: tabular-nums; }
.hv2-stat__row:first-of-type .hv2-stat__nm { color: var(--text-1); font-weight: 700; }

/* ── Workspace shortcuts ─────────────────────────────────────────────── */
.hv2-ways { display: grid; grid-template-columns: repeat(3,1fr); gap: 12px; }
.hv2-way { background: var(--surface); border: 1px solid var(--hairline); border-radius: 13px; padding: 14px 16px; display: flex; gap: 12px; align-items: flex-start; transition: transform .12s, box-shadow .12s, border-color .12s; }
.hv2-way:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(13,35,64,.09); border-color: var(--brand-tint); }
.hv2-way__ic { width: 34px; height: 34px; flex: 0 0 auto; border-radius: 9px; background: var(--brand-soft); color: var(--brand); display: grid; place-items: center; font-size: 17px; }
.hv2-way__nm { font-size: 14px; font-weight: 800; color: var(--text-1); }
.hv2-way__d { font-size: 11.5px; color: var(--text-3); margin-top: 2px; line-height: 1.35; }

.hv2-sectlabel { display: flex; align-items: baseline; gap: 10px; margin: 26px 2px 12px; }
.hv2-sectlabel h2 { font-size: 16px; font-weight: 850; letter-spacing: -.01em; color: var(--text-1); margin: 0; }
.hv2-sectlabel span { font-size: 12px; color: var(--text-3); }

/* ── Responsive ──────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .hv2-grid { grid-template-columns: 1fr; }
  .hv2-kpis { grid-template-columns: 1fr 1fr; }
  .hv2-stats { grid-template-columns: 1fr 1fr; }
  .hv2-ways { grid-template-columns: 1fr; }
  .hv2-hero__title { font-size: 25px; }
}
@media (max-width: 560px) {
  .hv2-kpis, .hv2-stats { grid-template-columns: 1fr; }
  .hv2-edge { grid-template-columns: 1fr; }
}

/* ===== HOMEPAGE V2 — polish overrides ===== */
.hv2-kpi__n, .hv2-kpi__l, .hv2-way__nm, .hv2-way__d { display: block; }
.hv2-way > span:last-of-type { display: flex; flex-direction: column; min-width: 0; }
.hv2-way__nm { margin-bottom: 1px; }

/* ===== HOMEPAGE V2 — build-out (movers, data-bars, polish) ===== */
/* GPU-safe bar grow (transform only); honors reduced-motion */
@keyframes hv2grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* Stat-leader data bars (subtle background fill behind each row) */
.hv2-stat__row { position: relative; overflow: hidden; }
.hv2-stat__rk, .hv2-stat__nm, .hv2-stat__v { position: relative; z-index: 1; }
.hv2-stat__fill { position: absolute; left: 0; top: 2px; bottom: 2px; z-index: 0; border-radius: 4px;
  background: linear-gradient(90deg, rgba(29,95,167,.16), rgba(29,95,167,.04));
  transform-origin: left; animation: hv2grow .7s cubic-bezier(.32,.72,0,1) both; }

/* Biggest Movers — diverging bar columns */
.hv2-mv { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px; }
.hv2-mv__col { padding: 6px 8px 2px; }
.hv2-mv__col:first-child { border-right: 1px solid var(--hairline); }
.hv2-mv__row { display: grid; grid-template-columns: 1fr 64px 38px; align-items: center; gap: 9px; padding: 6px 4px; border-radius: 7px; transition: background .2s cubic-bezier(.32,.72,0,1); }
.hv2-mv__row:hover { background: var(--surface-soft); }
.hv2-mv__nm { font-size: 12.5px; font-weight: 700; color: var(--text-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hv2-mv__nm small { color: var(--text-3); font-weight: 600; font-size: 10.5px; margin-left: 4px; }
.hv2-mv__barwrap { height: 7px; background: var(--surface-soft); border-radius: 4px; overflow: hidden; }
.hv2-mv__bar { display: block; height: 100%; border-radius: 4px; transform-origin: left; animation: hv2grow .7s cubic-bezier(.32,.72,0,1) both; }
.hv2-mv__bar--up { background: linear-gradient(90deg, var(--cat-good,#0f766e), #2bb39a); }
.hv2-mv__bar--down { background: linear-gradient(90deg, #d96b6b, var(--cat-bad,#b91c1c)); }
.hv2-mv__delta { font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums; text-align: right; }
.hv2-mv__delta--up { color: var(--cat-good,#0f766e); }
.hv2-mv__delta--down { color: var(--cat-bad,#b91c1c); }
@media (max-width: 560px) { .hv2-mv { grid-template-columns: 1fr; } .hv2-mv__col:first-child { border-right: 0; border-bottom: 1px solid var(--hairline); } }

/* Premium polish: softer diffused shadows + custom easing (Apple/Linear-tier) */
.hv2-card, .hv2-kpi, .hv2-way, .hv2-game {
  box-shadow: 0 1px 2px rgba(13,35,64,.04), 0 10px 28px -14px rgba(13,35,64,.16);
  transition: transform .5s cubic-bezier(.32,.72,0,1), box-shadow .5s cubic-bezier(.32,.72,0,1), border-color .3s ease;
}
.hv2-kpi:hover, .hv2-way:hover { transform: translateY(-3px); box-shadow: 0 2px 4px rgba(13,35,64,.05), 0 20px 44px -16px rgba(13,35,64,.24); }
.hv2-btn, .hv2-card__all, .hv2-lb__row, .hv2-edge__row, .hv2-news__row { transition: all .2s cubic-bezier(.32,.72,0,1); }
.hv2-spark path { transition: stroke .3s ease; }

@media (prefers-reduced-motion: reduce) {
  .hv2-stat__fill, .hv2-mv__bar { animation: none; transform: scaleX(1); }
  .hv2-kpi, .hv2-way, .hv2-card, .hv2-game, .hv2-btn { transition: none; }
}

/* ===== HOMEPAGE V2 — value landscape ===== */
.hv2-land { padding: 8px 14px 12px; }
.hv2-land__chart { width: 100%; height: 148px; display: block; }
.hv2-land__meta { display: flex; justify-content: space-between; gap: 10px; font-size: 11px; font-weight: 600; color: var(--text-3); margin-top: 6px; }
.hv2-land__meta span:nth-child(2) { font-weight: 500; text-align: center; flex: 1 1 auto; min-width: 0; }
.hv2-land__meta span:nth-child(2) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 560px){ .hv2-land__meta span:nth-child(2){ display:none; } }

/* ===== HOMEPAGE V2 — interactivity + dashboard graphs ===== */
.hv2-posfilter { display: flex; flex-wrap: wrap; gap: 5px; padding: 2px 8px 9px; }
.hv2-poschip { font-size: 11px; font-weight: 700; letter-spacing: .02em; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--hairline); background: var(--surface); color: var(--text-2); cursor: pointer; font-variant-numeric: tabular-nums; transition: background .18s cubic-bezier(.32,.72,0,1), color .18s, border-color .18s, transform .12s; }
.hv2-poschip:hover { border-color: var(--brand-tint); color: var(--text-1); transform: translateY(-1px); }
.hv2-poschip.is-on { background: var(--brand); border-color: transparent; color: #fff; }
.dhub-hv2 { max-width: none; padding: 0; margin-top: 4px; }
.dhub-hv2 .hv2-card { margin-bottom: 16px; }

/* ===== HOMEPAGE V2 — mobile polish ===== */
@media (max-width: 560px) {
  .hv2-slate__head { flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
  .hv2-slate__title { font-size: 13px; line-height: 1.3; }
  .hv2-slate__all { margin-left: auto; }
  .hv2-hero__title { font-size: 23px; }
}
@media (max-width: 480px) {
  .hv2 { padding: 0 14px 56px; }
  .hv2-lb__row { grid-template-columns: 22px 1fr auto auto; gap: 7px; }
  .hv2-lb__spark, .hv2-spark { width: 44px; }
  .hv2-lb__name { font-size: 13px; }
  .hv2-lb__val { font-size: 13px; }
  .hv2 .posChip { font-size: 10px; padding: 1px 4px; }
  .hv2-card__title { font-size: 13.5px; }
}

.hv2-way__ic svg { width: 19px; height: 19px; }
.hv2-way__ic { font-size: 0; }

/* ===== HOMEPAGE V2 — premium elevation ===== */
/* 1 · Display face (Outfit) on every heading, label, and numeral — the single biggest lift */
.hv2-hero__title, .hv2-hero__kicker, .hv2-kpi__n, .hv2-kpi__l, .hv2-card__title, .hv2-card__all,
.hv2-lb__val, .hv2-lb__rank, .hv2-stat__v, .hv2-stat__lbl, .hv2-stat__sub, .hv2-mv__delta,
.hv2-edge__delta, .hv2-edge__h, .hv2-sectlabel h2, .hv2-slate__title, .hv2-slate__live,
.hv2-game__abbr, .hv2-game__time, .hv2-way__nm, .hv2-eyebrow, .hv2-poschip, .hv2-land__meta,
.hv2-hero__wordmark {
  font-family: var(--font-display, 'Outfit'), system-ui, sans-serif; }

/* 2 · Container rhythm */
.hv2 { max-width: 1160px; padding-bottom: 84px; }
.hv2-grid { gap: 18px; margin-bottom: 18px; }
.hv2-statwrap { margin-bottom: 18px; }

/* 3 · Slate — a proper premium dark band */
.hv2-slate { border-radius: 18px; padding: 16px 20px 18px; margin: 20px 0 24px; border: 1px solid rgba(255,255,255,.05);
  background: radial-gradient(135% 160% at 0% 0%, #173a5e 0%, #0c1f38 52%, #091829 100%);
  box-shadow: 0 1px 2px rgba(8,20,40,.35), 0 26px 54px -28px rgba(8,20,40,.6); }
.hv2-slate__title { font-size: 15px; font-weight: 700; letter-spacing: -.01em; }
.hv2-game { min-width: 200px; padding: 12px 15px; border-radius: 14px; }
.hv2-game__abbr { font-size: 14px; }
.hv2-game__time { font-size: 10.5px; margin-bottom: 9px; }

/* 4 · Hero — give it presence + a nested-icon CTA */
.hv2-hero { margin: 24px 0 28px; align-items: center; }
.hv2-hero__kicker { font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase; font-weight: 700; padding: 5px 13px; }
.hv2-hero__title { font-size: 44px; line-height: 1.0; font-weight: 700; letter-spacing: -.035em; margin-bottom: 13px; text-wrap: balance; }
.hv2-hero__lede { font-size: 16px; line-height: 1.55; max-width: 540px; margin-bottom: 18px; }
.hv2-hero__ctas { gap: 12px; }
.hv2-btn { font-size: 14px; font-weight: 700; border-radius: 12px; padding: 11px 20px; transition: transform .4s cubic-bezier(.32,.72,0,1), box-shadow .4s cubic-bezier(.32,.72,0,1); }
.hv2-btn:active { transform: scale(.98); }
.hv2-btn--primary { padding: 8px 8px 8px 20px; gap: 12px; box-shadow: 0 8px 20px -8px rgba(29,95,167,.55); }
.hv2-btn--primary span { display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: rgba(7,17,38,.32); transition: transform .4s cubic-bezier(.32,.72,0,1); }
.hv2-btn--primary:hover span { transform: translateX(3px) scale(1.04); }

/* 5 · KPIs — bigger, confident numerals */
.hv2-kpis { gap: 14px; margin-bottom: 26px; }
.hv2-kpi { padding: 17px 19px; border-radius: 16px; box-shadow: var(--shadow-2); border-color: rgba(13,35,64,.06); }
.hv2-kpi__n { font-size: 31px; font-weight: 700; letter-spacing: -.03em; }
.hv2-kpi--wide .hv2-kpi__n { font-size: 21px; }
.hv2-kpi--wide .hv2-kpi__n span { font-size: 21px !important; }
.hv2-kpi__l { font-size: 11px; letter-spacing: .07em; margin-top: 8px; }

/* 6 · Cards — soft float, squircle, refined header */
.hv2-card { border-radius: 17px; border-color: rgba(13,35,64,.06); box-shadow: var(--shadow-2); }
.hv2-card__head { padding: 15px 18px 13px; }
.hv2-card__title { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
.hv2-card__title .hv2-accent { width: 4px; height: 17px; border-radius: 3px; }
.hv2-card__all { font-size: 12px; font-weight: 700; }

/* 7 · Leaderboard refinement */
.hv2-lb__row { padding: 8px 9px; }
.hv2-lb__val { font-size: 15px; font-weight: 700; }
.hv2-lb__rank { font-size: 12.5px; font-weight: 700; }

/* 8 · Section labels + shortcuts */
.hv2-sectlabel { margin: 34px 2px 14px; }
.hv2-sectlabel h2 { font-size: 19px; font-weight: 700; letter-spacing: -.02em; }
.hv2-way { border-radius: 16px; padding: 16px 18px; box-shadow: var(--shadow-2); }
.hv2-way__ic { width: 38px; height: 38px; border-radius: 11px; }
.hv2-way__nm { font-size: 15px; font-weight: 700; }

@media (max-width: 480px) { .hv2-hero__title { font-size: 30px; } .hv2-kpi__n { font-size: 27px; } }

/* ===== HOMEPAGE V2 — masthead split ===== */
.hv2-masthead { display: grid; grid-template-columns: 1.15fr .85fr; gap: 38px; align-items: center; margin: 24px 0 30px; }
.hv2-masthead .hv2-hero { display: block; margin: 0; }
.hv2-masthead .hv2-hero__title { font-size: 38px; }
.hv2-masthead .hv2-hero__l { flex: none; min-width: 0; }
.hv2-masthead .hv2-kpis { grid-template-columns: 1fr 1fr; margin: 0; gap: 14px; }
.hv2-masthead .hv2-kpi { padding: 18px 20px; }
@media (max-width: 900px) { .hv2-masthead { grid-template-columns: 1fr; gap: 20px; } .hv2-masthead .hv2-hero__title { font-size: 34px; } }
@media (max-width: 560px) { .hv2-masthead .hv2-kpis { grid-template-columns: 1fr; } }

/* ===== HOMEPAGE V2 — light/dark contrast ===== */
/* Theme-aware semantic TEXT colors: dark-on-light in light mode, light-on-dark in dark mode. */
/* All home deltas / edge headers / boom-bust %s use var(--cat-good/--cat-bad) so this fixes them everywhere. */
:root { --cat-good: #0f766e; --cat-bad: #b91c1c; }
html[data-theme="dark"] { --cat-good: #2dd4bf; --cat-bad: #f3837b; }
/* Badges keep WHITE text, so pin their backgrounds to fixed dark colors readable in BOTH themes */
/* (the source badge previously used --text-3, which flips light in dark mode → white-on-light failed). */
.hv2-news__src { background: #475a6f; color: #fff; }
.hv2-news__src--il { background: #b91c1c; color: #fff; }
/* Tinted delta pills: lift the tint a touch in dark so the brighter text reads cleanly */
html[data-theme="dark"] .hv2-edge__delta--love { background: rgba(45,212,191,.13); }
html[data-theme="dark"] .hv2-edge__delta--fade { background: rgba(243,131,123,.13); }
/* Do not transition COLOR on theme switch (avoids a low-contrast flash mid-fade; settled colors are AA). */
.hv2 a, .hv2-lb__name, .hv2-card__all, .hv2-lb__row, .hv2-edge__row, .hv2-news__row, .hv2-mv__row { transition-property: background-color, border-color, transform, box-shadow, opacity; }


/* ===== DARK-MODE contrast remediation (shared board components) ===== */
/* The --sv-* "Savant" palette (polish.css :root) was light-only — no dark flip — so card
   titles, search inputs, Configure League, and pos/neg numerals went dark-on-dark on every
   board. Flip the whole palette for dark; this cascades to all routes that use var(--sv-*). */
html[data-theme="dark"] {
  --sv-bg: #0b1521; --sv-bg-soft: #0f1c2b; --sv-surface: #101e2f; --sv-surface-alt: #15273c;
  --sv-hairline: rgba(168,196,226,.10); --sv-hairline-2: rgba(168,196,226,.18);
  --sv-ink: #eef4fb; --sv-ink-2: #c2d2e4; --sv-ink-3: #94aac2; --sv-ink-4: #8499b0;
  --sv-blue: #5b9bd8; --sv-blue-hover: #79b0e4; --sv-blue-soft: rgba(91,155,216,.14);
  --sv-pos: #3ddc97; --sv-neg: #f3837b;
}
/* Components with hardcoded (non-token) colors that lacked dark variants */
html[data-theme="dark"] .dhub-row__val--buy { color: #3ddc97; }
html[data-theme="dark"] .row-mini-pill--blue { color: #7aa5e0 !important; }
html[data-theme="dark"] .row-mini-pill--gold { color: #d8b46a !important; }
/* Active position tab uses --sv-ink as BACKGROUND (dark pill + white text); give it an explicit dark-readable bg */
html[data-theme="dark"] body[data-route="rankings"] .pos-tab.is-active,
html[data-theme="dark"] body[data-route="rankings"] .pos-tab[aria-selected="true"],
html[data-theme="dark"] body[data-route="rankings"] .pos-tabs button.is-active,
html[data-theme="dark"] body[data-route="rankings"] .pos-tabs button[aria-selected="true"],
html[data-theme="dark"] .pos-tab.active { background: #2d74c4 !important; color: #fff !important; border-color: #2d74c4 !important; }


/* ════════════════════════════════════════════════════════════════════
   WAVE 2 — AUDIT POLISH (2026-06-16)
   Mobile scroll affordance · reduced-motion backdrop-filter · safe-area.
   ════════════════════════════════════════════════════════════════════ */

/* Edge-fade scroll cue REMOVED (owner 2026-06-22): the ::after used
   position:absolute; right:0 inside the overflow-x scroll container, so it
   anchored to the scrolled CONTENT edge (not the viewport edge) and rendered as
   a stray vertical white band cutting through the middle of the board. The
   native scrollbar already signals horizontal scrollability. */
.table-wrap, #tableWrap { position: relative; }

/* Reduced-motion users: drop the GPU backdrop blur (jank on low-end devices).
   The rgba overlays already dim the background, so only the blur is removed. */
@media (prefers-reduced-motion: reduce) {
  .auth-modal__backdrop, .cmd-palette__backdrop,
  .hub-section-strip.is-stuck, .sharecard-ov {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
}

/* Safe-area insets for notch / Dynamic-Island devices (paired with
   viewport-fit=cover). Keeps the scrollable drawer body + any fixed bottom
   chrome clear of the home indicator. */
@supports (padding: max(0px)) {
  .drawer__body { padding-bottom: max(16px, env(safe-area-inset-bottom)); }
  .drawer-backdrop { padding-bottom: env(safe-area-inset-bottom); }
}

/* ── Trade Analyzer — saved proposals (build-out 2026-06-16) ──────────────── */
.mta2-saved { margin-top: 16px; }
.mta2-saved__title { font: 700 12px/1.4 var(--font, system-ui); letter-spacing: .04em; text-transform: uppercase; color: var(--text-3); margin: 0 0 8px; }
.mta2-saved__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.mta2-saved__row { border: 1px solid var(--hairline, rgba(15,14,12,.12)); border-radius: 10px; padding: 9px 12px; background: var(--surface, #fff); }
.mta2-saved__hd { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text); }
.mta2-saved__hd b { color: var(--accent, #0b6cb8); }
.mta2-saved__when { color: var(--text-3); font-size: 11px; }
.mta2-saved__x { margin-left: auto; appearance: none; border: 0; background: transparent; color: var(--text-3); cursor: pointer; font-size: 13px; line-height: 1; padding: 4px 6px; border-radius: 6px; }
.mta2-saved__x:hover { background: var(--surface-soft, rgba(0,0,0,.05)); color: var(--red, #c8202b); }
.mta2-saved__bd { margin-top: 4px; font-size: 12px; color: var(--text-2); }
.mta2-saved__k { font-weight: 700; color: var(--text-3); font-size: 10.5px; text-transform: uppercase; letter-spacing: .03em; margin-right: 3px; }
.mta2-saved__k--give { margin-left: 8px; }

/* ── Slate-strip readability fix (2026-06-17) ─────────────────────────────────
   The "Today's slate" card uses a dark navy radial-gradient background. Its team
   abbreviation (.hv2-game__abbr) had no explicit color, so it inherited the page's
   dark --text (#1f3a57) and rendered dark-on-dark (≈1.3:1, unreadable). Force the
   slate's text light; give the abbr a bright tint so the team reads clearly. These
   are appended last so they win regardless of the earlier (non-winning) rules. */
.hv2-slate, .hv2-slate__inner, .hv2-game { color: #e9eef6; }
.hv2-game__abbr { color: #f4f8fe; }
/* The home wrapper sets `.hv2 a { color: inherit }` (specificity 0,1,1) which beats
   `.hv2-btn--primary { color:#fff }` (0,1,0) — so the primary CTA (an <a>) inherited
   the dark --text on its blue gradient (dark-on-dark). Restore white above that. */
.hv2 a.hv2-btn--primary, .hv2 a.hv2-btn--primary span { color: #fff; }
