:root {
  color-scheme: light;

  /* surfaces */
  --page: #f7f6f1;
  --surface: #ffffff;
  --surface-2: #fbfaf5;
  --surface-3: #f1efe6;

  /* ink */
  --ink: #0c0c0e;
  --ink-2: #2a2a2e;
  --muted: #6b6b73;
  --faint: #a4a4ab;

  /* lines */
  --line: #e7e4d9;
  --line-soft: #efece2;
  --line-strong: #d4d0c2;

  /* accent — used sparingly */
  --accent: #b08533;
  --accent-deep: #8a6422;
  --accent-soft: #f4ecd2;

  /* signals */
  --positive: #2c6a4a;
  --positive-soft: #e6f0ea;
  --negative: #8b3527;
  --negative-soft: #f3e6e2;
  --warn: #8a6422;
  --warn-soft: #f8eecb;
  --neutral-soft: #f1efe6;

  /* radii */
  --r-xs: 4px;
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;

  /* type */
  --font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-serif: ui-serif, "Iowan Old Style", "Charter", "Cambria", Georgia, serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, "JetBrains Mono", Consolas, monospace;
}

* { box-sizing: border-box; }

[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  /* Belt-and-suspenders against horizontal page scroll on mobile.
     Some internal blocks (post-sim transparency tables, ranges
     grids) carry a `min-width: 720px` so they stay readable on
     desktop but can poke past the viewport edge on a 390px phone
     before their own `.data-table { overflow-x: auto }` wrapper
     engages. When that happens, the body widens to fit the row,
     `.app { margin: 0 auto }` re-centers against the wider body,
     and the user sees the page hugging the left edge with blank
     space on the right. Clipping at the root keeps the viewport
     authoritative; the data tables retain their own internal
     horizontal scroll for the long rows. */
  overflow-x: clip;
}

body {
  margin: 0;
  min-width: 320px;
  overflow-x: clip;
  background: var(--page);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  font-feature-settings: "ss01" 1, "cv11" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Fallback for browsers that don't support `overflow-x: clip` (older
   Safari, etc.) — `hidden` does the same thing for our case since we
   never need horizontal page scroll. */
@supports not (overflow-x: clip) {
  html, body { overflow-x: hidden; }
}

button, select, input, textarea { font: inherit; color: inherit; }

button {
  cursor: pointer;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font-weight: 600;
  letter-spacing: -0.005em;
  transition: border-color 150ms ease, background 150ms ease, color 150ms ease;
}

button:hover { border-color: var(--line-strong); }

a { color: inherit; text-decoration: none; }

a:hover { color: var(--accent-deep); }

button:focus-visible,
a:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

h1, h2, h3, p { margin: 0; }

.num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "ss01" 1;
  letter-spacing: -0.01em;
}

/* ── shell ─────────────────────────────────────── */

/* Header height varies with viewport because .brand-logo scales
   between 56px and 96px. The variable lets sticky children (rail,
   tier notice) calc their ``top`` offsets cleanly so they always
   clear the now-sticky .top header without overlapping. */
:root {
  --header-h: 96px;
}
@media (min-width: 480px) { :root { --header-h: 104px; } }
@media (min-width: 720px) { :root { --header-h: 120px; } }
@media (min-width: 1020px) { :root { --header-h: 136px; } }

.app {
  width: min(100% - 24px, 1500px);
  margin: 0 auto;
  padding: 16px 0 64px;
  display: grid;
  gap: 22px;
}

/* Reserve clearance at the bottom of the page for the floating
   "Stay in the loop" subscribe launcher (52px button + 20px gutter
   = ~72px). Without this, the last item in the games list sits
   permanently underneath the widget on mobile and can't be scrolled
   into clean view. */
@media (max-width: 720px) {
  .app { padding-bottom: 110px; }
}

.top {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 12px;
  padding: 6px 4px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 14px;
  /* position: sticky pins the header to the viewport top during
     scroll AND establishes a positioning context for the absolutely
     anchored .settings-cluster (below). Background matches the page
     so content scrolling underneath doesn't bleed through and the
     header reads as part of the same canvas, not a separate panel.
     z-index sits above the rail (default stack) but below the
     simulation modal (z: 100) and settings dropdown (z: 100). */
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--page);
}

.brand { display: inline-flex; align-items: center; gap: 12px; min-width: 0; }

/* Header lockup image. The PNG is 866×288 (3:1 aspect), and the
   tagline "SPORTS SIMULATOR" inside it needs real vertical pixels
   to stay legible — so sizing is driven by the tagline floor, not
   the icon. The max-width on the smallest viewport keeps the
   lockup from crowding the Login button on ~320px phones. */
.brand-logo {
  display: block;
  height: 56px;
  width: auto;
  max-width: 180px;
}

@media (min-width: 480px) {
  .brand-logo { height: 64px; max-width: 240px; }
}

@media (min-width: 720px) {
  .brand-logo { height: 80px; max-width: 280px; }
}

@media (min-width: 1020px) {
  .brand-logo { height: 96px; max-width: 320px; }
}

.brand-mark {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  background: var(--ink);
  color: #fff;
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.02em;
}

.brand-text strong {
  display: block;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.1;
}

.brand-text small {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.top-nav {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  /* Reserve room on the right edge of the nav for the absolutely-
     positioned settings cluster (~32px gear + 4px right offset).
     Without this, other nav items (status pills, login button) can
     extend under the gear when the nav wraps to multiple lines and
     visually overlap it. Harmless when the cluster is hidden
     (logged-out users) — just adds a small right-side gutter. */
  padding-right: 44px;
}

.pill {
  display: inline-flex;
  align-items: center;
  height: 26px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-2);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.01em;
}

.pill.subtle { color: var(--muted); }

.link {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-2);
}

.link.subtle { color: var(--muted); }

.link:hover { color: var(--accent-deep); }

.kicker {
  display: inline-block;
  color: var(--muted);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.kicker.subtle { color: var(--faint); }

/* Cold-pull indicator. A fresh odds fetch (cache miss) round-trips to the
   sportsbook and can take several seconds; a cache hit returns near-instantly.
   When a load runs long enough to clearly be a real pull, the market kicker
   switches to this prominent pulsing state so the user understands we're
   fetching live odds and waits it out instead of bouncing. */
.kicker.pulling-fresh {
  color: var(--accent);
  text-transform: none;
  letter-spacing: 0.01em;
  font-size: 11px;
  animation: pulling-fresh-pulse 1.1s ease-in-out infinite;
}
@keyframes pulling-fresh-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* Source tags — distinguish "live sportsbook lines" from "simulator output". */
.source-tag {
  padding: 4px 9px;
  border-radius: 999px;
  font-size: 10px;
  letter-spacing: 0.16em;
  border: 1px solid transparent;
}

.source-tag-book {
  background: var(--accent-soft);
  border-color: var(--accent-deep);
  color: var(--accent-deep);
}

.source-tag-sim {
  background: var(--positive-soft);
  border-color: var(--positive);
  color: var(--positive);
}

.block.source-book {
  border-color: var(--accent-deep);
  border-left-width: 4px;
}

.block.source-sim {
  border-color: var(--positive);
  border-left-width: 4px;
}

/* ── layout ────────────────────────────────────── */

.layout {
  display: grid;
  /* minmax(0, 1fr) (not just 1fr) so the grid item can shrink
     below its content's natural width — without this, any block
     wider than the viewport (data tables, box scores) forces the
     whole canvas off the right edge on mobile. */
  grid-template-columns: minmax(0, 1fr);
  gap: 22px;
}

@media (min-width: 1080px) {
  .layout {
    grid-template-columns: 300px minmax(0, 1fr);
    gap: 36px;
    align-items: start;
  }
}

/* ── rail (left sidebar) ──────────────────────── */

.rail {
  display: grid;
  gap: 14px;
  align-content: start;
  position: sticky;
  /* Clear the sticky header (.top). --header-h tracks the logo
     scaling across breakpoints; +12px breathing room keeps the rail
     from touching the header's bottom border. */
  top: calc(var(--header-h) + 12px);
}

@media (max-width: 1079px) {
  .rail { position: static; }
}

.sport-tabs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
}

.sport-tab {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  padding: 8px 6px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}

.sport-tab:hover:not([disabled]):not(.active) {
  background: var(--surface-2);
  color: var(--ink);
}

.sport-tab.active {
  background: var(--ink);
  color: #ffffff;
}

.sport-tab-icon {
  font-size: 16px;
  line-height: 1;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
}

.sport-tab[disabled] {
  color: var(--faint);
  cursor: not-allowed;
  opacity: 0.55;
}

.rail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.ghost-btn {
  height: 28px;
  padding: 0 10px;
  font-size: 12px;
  font-weight: 500;
  background: transparent;
  border-color: var(--line);
  color: var(--muted);
}

.ghost-btn:hover {
  border-color: var(--line-strong);
  color: var(--ink);
}

.ghost-btn[disabled],
.ghost-btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.5;
  border-color: var(--line-soft);
  background: var(--surface-2);
  color: var(--faint);
}

.ghost-btn[disabled]:hover,
.ghost-btn[aria-disabled="true"]:hover {
  border-color: var(--line-soft);
  background: var(--surface-2);
  color: var(--faint);
}

.rail-list {
  display: grid;
  gap: 6px;
  max-height: 70vh;
  overflow-y: auto;
  padding-right: 4px;
  scrollbar-color: var(--line-strong) transparent;
}

/* Mobile / narrow tablet: release the rail-list's internal scroll.
   The rail is ``position: static`` at this width (single-column
   layout), so the games sit at the top of the page rather than in
   a fixed sidebar. Keeping the 70vh max-height + overflow-y:auto on
   the list creates a nested scroll trap — touch-scrolling the list
   feels like scrolling the page, but the page itself doesn't move
   and the user can't reach the sim results below. With these
   overrides the games render inline and the page is the single
   scroll surface. */
@media (max-width: 1079px) {
  .rail-list {
    max-height: none;
    overflow-y: visible;
    padding-right: 0;
  }
}

.game-card {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 12px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-soft);
  background: var(--surface);
  text-align: left;
  transition: border-color 150ms ease, background 150ms ease, transform 150ms ease;
}

/* ── Today (multi-sport) home view ───────────────── */

.today-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 26px 0 14px;
  padding: 0 4px 10px;
  border-bottom: 2px solid var(--line-strong, var(--line-soft));
}
.today-section-head:first-child { margin-top: 8px; }

.today-section-title {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.today-section-icon {
  font-size: 22px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.today-section-label {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--ink);
  line-height: 1.1;
}

.today-section-count {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--surface-2, var(--surface));
  border: 1px solid var(--line-soft);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.04em;
  white-space: nowrap;
}

/* ── Today search bar ───────────────────────────── */

.today-search {
  position: relative;
  display: flex;
  align-items: center;
  margin: 4px 0 14px;
}

.today-search-icon {
  position: absolute;
  left: 12px;
  font-size: 14px;
  color: var(--muted);
  pointer-events: none;
  line-height: 1;
}

.today-search-input {
  width: 100%;
  padding: 11px 38px 11px 38px;
  border-radius: 10px;
  border: 1px solid var(--line-soft);
  background: var(--surface);
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  outline: none;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}

.today-search-input::placeholder { color: var(--muted); }

.today-search-input:focus {
  border-color: var(--ink);
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.05);
}

.today-search-input::-webkit-search-cancel-button { display: none; }

.today-search-clear {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: none;
  background: var(--surface-2, var(--surface));
  color: var(--muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.today-search-clear:hover { background: var(--line-soft); color: var(--ink); }

.today-no-match {
  margin: 16px 4px;
  font-size: 13px;
  color: var(--muted);
}

.today-section-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
}

@media (max-width: 640px) {
  .today-section-cards {
    grid-template-columns: 1fr;
  }
}

.today-section-empty {
  margin: 4px 4px 8px;
  font-size: 12px;
  color: var(--muted);
  line-height: 1.45;
}

.today-tile {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 14px 16px;
  border-radius: 12px;
  border: 1px solid var(--line-soft);
  background: var(--surface);
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease, transform 150ms ease, box-shadow 150ms ease;
}

.today-tile:hover {
  border-color: var(--line-strong);
  background: var(--surface-2);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.05);
}

.today-tile.live {
  border-color: var(--accent, #d33);
}

.today-tile-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.today-tile-league {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

.today-tile-status {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.today-tile-status.live {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--accent, #d33);
  font-weight: 700;
  letter-spacing: 0.08em;
}

.today-tile-live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent, #d33);
  animation: today-tile-pulse 1.4s ease-in-out infinite;
}

@keyframes today-tile-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

.today-tile-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.today-tile-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.team-logo--tile {
  width: 32px;
  height: 32px;
  font-size: 10px;
  flex-shrink: 0;
}
.team-logo--tile img { inset: 2px; width: calc(100% - 4px); height: calc(100% - 4px); }

.today-tile-team {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.game-card:hover {
  border-color: var(--line-strong);
  background: var(--surface-2);
}

.game-card.active {
  border-color: var(--ink);
  background: var(--surface);
  box-shadow: inset 3px 0 0 var(--accent);
}

.game-card.loading { cursor: progress; opacity: 0.7; }

.game-card.live,
.game-card.live:hover {
  /* Live games are still clickable — they load the last saved sim
     instead of fetching fresh odds. Keep the pointer cursor; the 🔒
     icon and red border carry the "limited" visual cue. */
  cursor: pointer;
  background: var(--surface-2);
  border-color: var(--line-soft);
  border-left: 3px solid var(--negative);
  padding-left: 9px;
  opacity: 0.85;
  transform: none;
}

.game-card[disabled] { pointer-events: none; cursor: not-allowed; }

.game-card.live .game-team { color: var(--muted); }
.game-card.live .game-team strong { font-weight: 500; }

.game-live-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  padding: 2px 8px;
  height: 18px;
  border-radius: 999px;
  background: var(--negative);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.game-live-dot {
  width: 5px;
  height: 5px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.35);
  animation: game-live-pulse 1.6s ease-in-out infinite;
}

@keyframes game-live-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

.game-lock {
  font-size: 12px;
  color: var(--muted);
  filter: grayscale(1);
}

.game-time {
  display: block;
  margin-bottom: 6px;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.game-teams { display: grid; gap: 3px; min-width: 0; }

.game-team {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  gap: 8px;
  align-items: center;
  font-size: 13px;
  color: var(--ink);
  letter-spacing: -0.005em;
}

.game-team strong {
  font-weight: 550;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.game-arrow {
  color: var(--faint);
  font-size: 16px;
  transition: color 150ms ease, transform 150ms ease;
}

.game-card:hover .game-arrow { color: var(--ink); transform: translateX(2px); }
.game-card.active .game-arrow { color: var(--accent-deep); }

.team-logo {
  position: relative;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--surface-3);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 8px;
  font-weight: 700;
}

.team-logo img {
  position: absolute;
  inset: 1px;
  width: calc(100% - 2px);
  height: calc(100% - 2px);
  object-fit: contain;
  background: #fff;
}

.team-logo.sm { width: 28px; height: 28px; font-size: 9px; }
.team-logo.sm img { inset: 2px; width: calc(100% - 4px); height: calc(100% - 4px); }

.team-logo.md { width: 26px; height: 26px; font-size: 9px; }
.team-logo.md img { inset: 2px; width: calc(100% - 4px); height: calc(100% - 4px); }

.team-logo.lg { width: 36px; height: 36px; font-size: 11px; }
.team-logo.lg img { inset: 2px; width: calc(100% - 4px); height: calc(100% - 4px); }

.team-logo.xl { width: 56px; height: 56px; font-size: 13px; }
.team-logo.xl img { inset: 4px; width: calc(100% - 8px); height: calc(100% - 8px); }

@media (max-width: 720px) {
  .team-logo.xl { width: 44px; height: 44px; }
}

.rail-foot {
  display: grid;
  gap: 12px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}

.rail-note {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.55;
}

.rail-link {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent-deep);
  letter-spacing: 0.01em;
}

.rail-link:hover { color: var(--ink); }

.rail-legend {
  display: grid;
  gap: 8px;
  margin-top: 4px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface, #fff);
}

.rail-legend-title {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.rail-legend ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.rail-legend li {
  display: grid;
  grid-template-columns: 14px 1fr;
  gap: 8px;
  align-items: start;
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-2);
}

.rail-legend-swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  margin-top: 3px;
  border: 1px solid rgba(0, 0, 0, 0.06);
}

.rail-legend-swatch.swatch-strong {
  background: var(--positive-soft);
  border-color: var(--positive);
}

.rail-legend-swatch.swatch-aligned {
  background: var(--warn-soft, #fdf3da);
  border-color: var(--warn, #8a6d3b);
}

.rail-legend-swatch.swatch-weak {
  background: var(--negative-soft);
  border-color: var(--negative);
}

.rail-legend-text strong { color: var(--ink); font-weight: 600; }
.rail-legend-text em { font-style: italic; color: var(--ink); }

.rail-legend-note {
  margin: 0;
  font-size: 11px;
  line-height: 1.45;
  color: var(--muted);
}

/* Mobile-only legend, lives just above the box score table.
   On desktop the rail legend handles this and the in-section copy is
   hidden. On mobile the rail isn't a useful place for a legend (it
   stacks above the canvas and the user has to scroll past games and
   simulation controls to find it), so we surface a copy right where
   it's needed. */
.box-legend-mobile {
  display: none;
  margin: 12px 0 14px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
}

.box-legend-title {
  display: block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 8px;
}

.box-legend-mobile ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.box-legend-mobile li {
  display: grid;
  grid-template-columns: 14px 1fr;
  gap: 8px;
  align-items: start;
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-2);
}

.box-legend-mobile li strong { color: var(--ink); font-weight: 600; }

.box-legend-swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  margin-top: 3px;
  border: 1px solid rgba(0, 0, 0, 0.06);
}

.box-legend-swatch.swatch-strong  { background: var(--positive-soft); border-color: var(--positive); }
.box-legend-swatch.swatch-aligned { background: var(--warn-soft, #fdf3da); border-color: var(--warn, #8a6d3b); }
.box-legend-swatch.swatch-weak    { background: var(--negative-soft); border-color: var(--negative); }

@media (max-width: 680px) {
  .rail-legend { display: none; }
  .box-legend-mobile { display: block; }
}

/* ── canvas ───────────────────────────────────── */

.canvas {
  display: grid;
  gap: 28px;
  min-width: 0;
}

/* ── hero ─────────────────────────────────────── */

.hero {
  display: grid;
  gap: 14px;
  /* Reserve breathing room above when something inside the hero
     (matchup title, run button) is the target of scrollIntoView.
     Without this the sticky .top header overlaps the top of the
     hero after the scroll, so the user lands on a partially-hidden
     section and thinks the page didn't move. */
  scroll-margin-top: calc(var(--header-h) + 16px);
}

.hero-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 20px;
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(30px, 4.6vw, 50px);
  line-height: 1.04;
  letter-spacing: -0.02em;
  color: var(--ink);
  max-width: none;
}

.hero-team {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.hero-team-name { white-space: nowrap; }

.hero-vs {
  font-style: italic;
  font-weight: 400;
  font-size: 0.55em;
  color: var(--muted);
  letter-spacing: 0;
}

@media (max-width: 720px) {
  .hero-title { gap: 10px 14px; }
  .hero-team { gap: 10px; }
  .hero-team-name {
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

.hero-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 13px;
}

.hero-meta .dot { color: var(--faint); }

.hero-meta span:not(.dot) { font-weight: 500; }

.hero-controls {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  align-items: stretch;
  margin-top: 6px;
}

.tier {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: hidden;
  box-shadow: 0 1px 0 rgba(12, 12, 14, 0.04), 0 8px 20px -16px rgba(12, 12, 14, 0.25);
}

.tier-btn {
  display: grid;
  gap: 4px;
  align-items: start;
  text-align: left;
  padding: 14px 18px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--ink-2);
  transition: background 150ms ease, color 150ms ease, transform 150ms ease;
}

.tier-btn + .tier-btn { border-left: 1.5px solid var(--line-strong); }

.tier-btn:hover { background: var(--surface-2); color: var(--ink); }

.tier-btn.active {
  background: var(--ink);
  color: #fff;
  box-shadow: inset 0 0 0 1px var(--ink);
}

.tier-btn.active .tier-meta { color: rgba(255,255,255,0.72); }

.tier-name {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.tier-meta {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  font-family: var(--font-mono);
  letter-spacing: 0;
}

/* Pro tier — locked / premium hint */
.tier-btn-pro .tier-name { color: var(--accent-deep); }
.tier-btn-pro .tier-meta { color: var(--accent-deep); opacity: 0.85; }

.tier-btn-pro:hover {
  background: var(--accent-soft);
  color: var(--accent-deep);
}
.tier-btn-pro:hover .tier-name,
.tier-btn-pro:hover .tier-meta { color: var(--accent-deep); }

.tier-btn-pro.active {
  background: var(--accent-deep);
  color: #fff;
  box-shadow: inset 0 0 0 1px var(--accent-deep);
}
.tier-btn-pro.active .tier-name,
.tier-btn-pro.active .tier-meta { color: #fff; }
.tier-btn-pro.active .tier-meta { opacity: 0.78; }

.tier-lock {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* Pro account state: drop the "locked" caption styling and render
   the meta line as a positive "Pro unlocked" pill instead. */
.tier-btn-unlocked .tier-meta {
  align-self: start;
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 8px;
  border-radius: 999px;
  background: var(--positive-soft);
  color: var(--positive);
  border: 1px solid rgba(44, 106, 74, 0.32);
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 1;
}

.tier-btn-pro.tier-btn-unlocked .tier-meta { color: var(--positive); }
.tier-btn-pro.tier-btn-unlocked:hover .tier-meta { color: var(--positive); }
.tier-btn-pro.tier-btn-unlocked.active .tier-meta {
  /* On the active state the button has a dark fill — invert the pill
     so it stays legible (light pill on dark button). */
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.22);
  opacity: 1;
}

.run-btn {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  height: 48px;
  padding: 0 20px;
  border-radius: var(--r-sm);
  border: 1px solid var(--ink);
  background: var(--ink);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
}

.run-btn:hover {
  background: var(--ink-2);
  border-color: var(--ink-2);
}

.run-arrow {
  font-family: var(--font-mono);
  font-size: 16px;
  transition: transform 150ms ease;
}

.run-btn:hover .run-arrow { transform: translateX(3px); }

.run-btn:disabled,
.run-btn.is-locked {
  opacity: 0.55;
  cursor: not-allowed;
  filter: grayscale(0.4);
}

.run-btn:disabled:hover,
.run-btn.is-locked:hover { transform: none; }
.run-btn:disabled:hover .run-arrow,
.run-btn.is-locked:hover .run-arrow { transform: none; }

/* Run-meta: seed + sim timestamp + odds age, placed under the Run
   button. Stacks on narrow widths so each fact gets its own line. */
.run-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: 12px;
  padding: 8px 12px;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0;
}

.run-meta-row {
  white-space: nowrap;
}

.run-meta-row + .run-meta-row::before {
  content: "·";
  margin-right: 14px;
  color: var(--faint);
}

@media (max-width: 600px) {
  .run-meta { flex-direction: column; gap: 4px; }
  .run-meta-row + .run-meta-row::before { display: none; }
}

/* Run button — full-width, prominent variant */
.run-btn-xl {
  display: flex;
  width: 100%;
  height: 60px;
  padding: 0 28px;
  border-radius: var(--r-md);
  font-size: 16px;
  letter-spacing: -0.01em;
  box-shadow: 0 1px 0 rgba(12, 12, 14, 0.05), 0 12px 28px -14px rgba(12, 12, 14, 0.55);
  transition: background 150ms ease, border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease;
}

.run-btn-xl .run-btn-label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.run-btn-xl .run-arrow { font-size: 20px; }

.run-btn-xl:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 0 rgba(12, 12, 14, 0.06), 0 18px 36px -16px rgba(12, 12, 14, 0.6);
}

.run-btn-xl:active {
  transform: translateY(0);
  box-shadow: 0 1px 0 rgba(12, 12, 14, 0.05), 0 6px 16px -10px rgba(12, 12, 14, 0.45);
}

@media (max-width: 640px) {
  .run-btn-xl { height: 56px; font-size: 15px; padding: 0 22px; }
}

/* ── warning modal (no matchup) ───────────────── */

.warn-modal {
  position: fixed;
  inset: 0;
  z-index: 110;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(12, 12, 14, 0.45);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: sim-fade-in 180ms ease;
}

/* Card mirrors the editorial vocabulary used by .pro-locked and the
   block headers: kicker + serif title + body copy + arrow-tipped
   primary CTA on var(--ink). Subtle surface border instead of a red
   alarm stripe — this is a "do this first" nudge, not an error. */
.warn-card {
  position: relative;
  width: min(420px, 100%);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 32px 28px 24px;
  text-align: left;
  box-shadow:
    0 32px 80px rgba(12, 12, 14, 0.22),
    0 2px 8px rgba(12, 12, 14, 0.08);
  animation: warn-pop 220ms cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

@keyframes warn-pop {
  from { opacity: 0; transform: scale(0.96); }
  to { opacity: 1; transform: scale(1); }
}

.warn-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  border-radius: 999px;
  color: var(--ink-2);
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease;
}

.warn-close:hover {
  background: var(--surface-2);
  color: var(--ink);
}

.warn-kicker {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--negative, #8b3527);
  margin-bottom: 6px;
}

.warn-title {
  margin: 0 0 8px;
  font-family: var(--font-serif);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.warn-copy {
  margin: 0 0 22px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
}

.warn-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  height: 44px;
  padding: 0 22px;
  border-radius: var(--r-sm);
  border: 1px solid var(--ink);
  background: var(--ink);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
}

.warn-btn:hover {
  background: #000;
  border-color: #000;
  box-shadow: 0 6px 18px -8px rgba(0, 0, 0, 0.45);
}

.warn-btn-arrow {
  font-family: var(--font-mono);
  transition: transform 150ms ease;
}

.warn-btn:hover .warn-btn-arrow { transform: translateX(3px); }

/* ── notice ───────────────────────────────────── */

.notice {
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  background: var(--surface);
  border-radius: var(--r-sm);
  padding: 14px 16px;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.55;
}

.notice strong { color: var(--ink); font-weight: 600; }

.notice-warn {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 16px;
  border: 1px solid var(--negative);
  border-left-width: 4px;
  background:
    linear-gradient(0deg, rgba(139, 53, 39, 0.04), rgba(139, 53, 39, 0.04)),
    var(--warn-soft);
  border-radius: var(--r-md);
  padding: 16px 18px;
  color: var(--ink);
  box-shadow: 0 1px 0 rgba(139, 53, 39, 0.06), 0 6px 18px -10px rgba(139, 53, 39, 0.25);
}

/* Free-tier preview warning stays pinned to the top as the user
   scrolls — aligns visually with the rail by sharing the same
   calc(var(--header-h) + 12px) offset so both sit just below the
   sticky header. z-index keeps it above scrolling content (stat
   cells use 0; tooltips bump higher) but below the header (60) and
   modal/dropdown (100). The warn-soft background is solid, so
   nothing bleeds through behind it. */
#tierNotice {
  position: sticky;
  top: calc(var(--header-h) + 12px);
  z-index: 30;
}

@media (max-width: 1079px) {
  /* Match the rail's static behavior on narrow viewports where the
     layout collapses to one column and sticky would feel cramped. */
  #tierNotice { position: static; }
}

.notice-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: var(--negative);
  color: #fff;
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 16px;
  line-height: 1;
  flex-shrink: 0;
}

.notice-body { min-width: 0; }

.notice-title {
  margin: 0 0 4px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--negative);
  text-transform: none;
}

.notice-copy {
  margin: 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-2);
}

.notice-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--negative);
  background: var(--negative);
  color: #fff;
  font-weight: 600;
  font-size: 13px;
  padding: 9px 14px;
  border-radius: var(--r-sm);
  white-space: nowrap;
  transition: background 150ms ease, transform 150ms ease, box-shadow 150ms ease;
}

.notice-cta:hover {
  background: #6f2a1f;
  border-color: #6f2a1f;
  box-shadow: 0 6px 16px -8px rgba(139, 53, 39, 0.55);
}

.notice-cta-arrow {
  font-family: var(--font-mono);
  transition: transform 150ms ease;
}

.notice-cta:hover .notice-cta-arrow { transform: translateX(3px); }

@media (max-width: 640px) {
  .notice-warn {
    grid-template-columns: auto 1fr;
    grid-template-areas:
      "icon body"
      "cta cta";
    row-gap: 12px;
  }
  .notice-icon { grid-area: icon; }
  .notice-body { grid-area: body; }
  .notice-cta { grid-area: cta; justify-content: center; }
}

/* ── strip ────────────────────────────────────── */

.strip {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: hidden;
}

@media (min-width: 720px) {
  .strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .strip-cell + .strip-cell { border-left: 1px solid var(--line); border-top: 0; }
}

.strip-cell {
  display: grid;
  gap: 8px;
  padding: 22px 24px;
  align-content: start;
}

.strip-cell + .strip-cell { border-top: 1px solid var(--line); }

.cell-label {
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.cell-value {
  font-size: clamp(28px, 3.4vw, 36px);
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.cell-note {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0;
}

@media (min-width: 960px) {
  .strip-cell-wide { grid-column: span 1; }
}

/* projected score — two team rows like the consensus panel */
.cell-score {
  display: grid;
  gap: 0;
  width: 100%;
  font-family: var(--font-sans);
  font-size: 14px;
  letter-spacing: -0.005em;
}

.score-placeholder {
  font-family: var(--font-mono);
  font-size: 28px;
  color: var(--faint);
}

.score-team {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  padding: 10px 0;
}

.score-team + .score-team { border-top: 1px solid var(--line-soft); }

.score-team-name {
  font-size: 14px;
  font-weight: 550;
  color: var(--ink);
  /* Wrap long team names onto multiple lines instead of truncating
     with ellipsis — "Montréal Canadiens" / "Tampa Bay Lightning" /
     "Toronto Maple Leafs" otherwise get cut off in the Win-probability
     cell. Natural wrap on spaces; tightened line-height keeps the
     two-line block visually balanced with the percentage on the right.
  */
  white-space: normal;
  line-height: 1.15;
  overflow-wrap: anywhere;
}

.score-team-num {
  font-family: var(--font-mono);
  font-size: clamp(26px, 2.6vw, 32px);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
}

.score-team.score-team-winner .score-team-num { color: var(--ink); }

.score-team.score-team-winner .score-team-name { color: var(--ink); font-weight: 600; }

/* margin cell — full team name, big signed number */
.cell-margin {
  display: grid;
  gap: 6px;
  align-content: start;
  width: 100%;
}

.margin-team {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 550;
  color: var(--ink-2);
  letter-spacing: -0.005em;
  line-height: 1.25;
  word-break: break-word;
}

.margin-value {
  font-family: var(--font-mono);
  font-size: clamp(28px, 3.4vw, 36px);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
  line-height: 1;
}

/* ── block (generic section) ──────────────────── */

.block {
  display: grid;
  gap: 16px;
  /* Allow the block to shrink to its grid track's width — without
     this, a wide child (e.g. a data-table with 720px-min rows)
     blows the block out and the whole canvas overflows the
     viewport on mobile. The data-table already has its own
     overflow-x: auto, but that only kicks in if its containing
     block is willing to be narrower than its content. */
  min-width: 0;
}

.block-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}

.block-head h2 {
  margin-top: 4px;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.2;
  color: var(--ink);
}

.block-note {
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
}

/* ── consensus matchup ────────────────────────── */

.consensus-matchup {
  display: grid;
  gap: 12px;
}

.consensus-teams {
  display: grid;
  gap: 12px;
}

@media (min-width: 760px) {
  .consensus-teams {
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: stretch;
    gap: 16px;
  }
}

.consensus-team {
  display: grid;
  gap: 14px;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
}

.team-role {
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.team-identity {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  gap: 12px;
  align-items: center;
}

.team-identity strong {
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.1;
  overflow: hidden;
  text-overflow: ellipsis;
}

.team-stat-strip {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  border-top: 1px solid var(--line-soft);
  padding-top: 12px;
}

.team-stat-strip > span { display: grid; gap: 4px; }

.team-stat-strip > span + span {
  border-left: 1px solid var(--line-soft);
  padding-left: 14px;
}

.team-stat-strip small {
  color: var(--muted);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.team-stat-strip strong {
  font-family: var(--font-mono);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.consensus-odds {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0;
}

.consensus-center {
  display: grid;
  gap: 4px;
  place-items: center;
  align-content: center;
  min-width: 120px;
  padding: 18px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
  text-align: center;
}

.consensus-center .label-sm {
  color: var(--muted);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.consensus-center .total-num {
  font-family: var(--font-mono);
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.consensus-center .label-foot {
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0.04em;
}

/* ── market agreement panel ──────────────────── */

.market-agreement {
  display: grid;
  gap: 18px;
}

.market-agreement-summary {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
}

.agreement-score {
  display: flex;
  align-items: baseline;
  gap: 4px;
  padding: 8px 14px;
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-weight: 700;
  border: 2px solid currentColor;
}

.agreement-score-num { font-size: 28px; line-height: 1; }
.agreement-score-label { font-size: 11px; opacity: 0.7; }

.agreement-score.score-high { color: var(--positive); background: var(--positive-soft); }
.agreement-score.score-mid  { color: var(--warn, #8a6d3b); background: var(--warn-soft, #fdf3da); }
.agreement-score.score-low  { color: var(--negative); background: var(--negative-soft); }

.agreement-summary-text {
  display: grid;
  gap: 4px;
  font-size: 13px;
  line-height: 1.4;
}

.agreement-summary-text strong { color: var(--ink); font-weight: 700; font-size: 14px; }

.agreement-summary-detail {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
}

.agreement-subhead {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin: 0 0 10px;
}

.agreement-stat-grid {
  display: grid;
  gap: 8px;
}

.agreement-stat-row {
  display: grid;
  grid-template-columns: 90px 1fr 36px 110px;
  align-items: center;
  gap: 10px;
  font-size: 12px;
}

.agreement-stat-label {
  font-weight: 600;
  color: var(--ink-2);
}

.agreement-stat-bar {
  height: 8px;
  background: var(--neutral-soft, #efeee9);
  border-radius: 4px;
  overflow: hidden;
}

.agreement-stat-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--negative) 0%, var(--warn, #8a6d3b) 50%, var(--positive) 90%);
  border-radius: 4px;
  transition: width 0.2s ease;
}

.agreement-stat-num {
  font-family: var(--font-mono);
  font-weight: 700;
  text-align: right;
  color: var(--ink);
}

.agreement-stat-meta {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--muted);
  text-align: right;
}

.agreement-div-grid {
  display: grid;
  grid-template-columns: minmax(110px, 1.6fr) 50px 60px 80px 80px 70px;
  gap: 6px 14px;
  align-items: baseline;
  font-size: 12px;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.agreement-div-head {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-family: var(--ui-font, inherit);
}

/* Right-align numeric headers + cells (cols 3-6: Line, Sim, Market, Gap)
   so each column's values share a clean trailing edge. Player + Stat
   stay left-aligned. */
.agreement-div-grid > :nth-child(6n + 3),
.agreement-div-grid > :nth-child(6n + 4),
.agreement-div-grid > :nth-child(6n + 5),
.agreement-div-grid > :nth-child(6n + 6) {
  text-align: right;
}

.agreement-div-player {
  font-family: var(--ui-font, inherit);
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.agreement-gap-pos { color: var(--positive); font-weight: 700; }
.agreement-gap-neg { color: var(--negative); font-weight: 700; }

@media (max-width: 680px) {
  .market-agreement-summary { flex-direction: column; align-items: flex-start; }
  .agreement-stat-row { grid-template-columns: 70px 1fr 32px 84px; }
  .agreement-div-grid {
    grid-template-columns: minmax(90px, 1.4fr) 42px 50px 64px 64px 56px;
    gap: 4px 8px;
    font-size: 11px;
  }
}

/* ── gap cards ────────────────────────────────── */

.gap-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

@media (min-width: 720px) {
  .gap-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1180px) {
  .gap-grid { grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr)); }
}

.gap-card {
  position: relative;
  display: grid;
  gap: 10px;
  align-content: start;
  padding: 18px 18px 20px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  min-height: 132px;
}

.gap-card.primary {
  background: var(--surface);
  border-color: var(--ink);
}

.gap-card.primary::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--accent);
  border-radius: var(--r-md) 0 0 var(--r-md);
}

.gap-card .card-label {
  color: var(--muted);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.gap-card strong {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.15;
  color: var(--ink);
}

.gap-card.primary strong {
  font-family: var(--font-serif);
  font-size: 28px;
  font-weight: 500;
}

.gap-card p {
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.5;
}

.signal-pill {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 9px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--neutral-soft);
  color: var(--ink-2);
  border: 1px solid var(--line);
}

.signal-pill.signal-strong {
  background: var(--positive-soft);
  color: var(--positive);
  border-color: rgba(44, 106, 74, 0.3);
}

.signal-pill.signal-conflict {
  background: var(--negative-soft);
  color: var(--negative);
  border-color: rgba(139, 53, 39, 0.2);
}

/* ── takeaways ────────────────────────────────── */

.takeaway-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

@media (min-width: 720px) {
  .takeaway-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1180px) {
  .takeaway-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.takeaway {
  display: grid;
  gap: 8px;
  align-content: start;
  padding: 16px;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
  background: var(--surface);
}

.takeaway strong {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  color: var(--ink);
}

.takeaway p {
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.5;
}

/* ── distributions / bars ─────────────────────── */

.dist-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
}

@media (min-width: 760px) {
  .dist-grid { grid-template-columns: 1fr 1fr; gap: 40px; }
}

.bars { display: grid; gap: 10px; margin-top: 14px; }

/* Two-tone vertical histogram with sportsbook-line overlay. SVG fills
   its container width; viewBox scales the chart down on narrow widths
   without overflow. Bars on either side of the book line render in
   the over/under tones so the visual immediately communicates which
   side the simulator is favouring. */
.dist-hist {
  display: block;
  width: 100%;
  height: auto;
  max-height: 240px;
  margin-top: 14px;
}

.dist-baseline {
  stroke: var(--line);
  stroke-width: 1;
}

.dist-bar {
  fill: var(--ink-2);
  transition: fill 200ms ease;
}

.dist-bar.under {
  fill: var(--negative);
}

.dist-bar.over {
  fill: var(--positive);
}

.dist-bookline {
  stroke: var(--ink);
  stroke-width: 1.4;
  stroke-dasharray: 4 3;
}

.dist-bookline-label {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  fill: var(--ink);
  text-anchor: middle;
}

.dist-bookline-tick {
  font-weight: 700;
  fill: var(--ink);
}

.dist-side-label {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0;
}

.dist-side-label-under {
  fill: var(--negative);
}

.dist-side-label-over {
  fill: var(--positive);
}

.dist-axis-label {
  font-family: var(--font-mono);
  font-size: 10px;
  fill: var(--muted);
  text-anchor: middle;
}

/* Per-bar percentage label sitting above each bar. The peak bar gets
   slightly heavier weight so the most likely outcome stands out at a
   glance. */
.dist-bar-label {
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 500;
  fill: var(--ink-2);
  text-anchor: middle;
}

.dist-bar-label.is-peak {
  font-weight: 700;
  fill: var(--ink);
}

.bar-row {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr) 56px;
  gap: 12px;
  align-items: center;
  font-size: 12px;
}

.bar-row strong {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 12px;
  color: var(--ink-2);
  letter-spacing: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bar-track {
  height: 6px;
  border-radius: 999px;
  background: var(--surface-3);
  overflow: hidden;
}

.bar-fill {
  height: 100%;
  border-radius: inherit;
  background: var(--ink);
  transition: width 240ms ease;
}

/* ── lean cards (NBA: biggest model leans per stat) ─────── */

.gap-card.lean-card strong {
  font-size: 16px;
  letter-spacing: -0.01em;
  display: grid;
  gap: 4px;
}

.lean-card-headline {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.lean-card-median {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.lean-card-vs {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
}

.lean-card-detail {
  margin: 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ink-2);
}

.lean-card-odds {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
}

/* ── box-score gap cards (one per stat category) ─────────── */

.gap-card.box-gap-card strong {
  font-size: 18px;
  letter-spacing: -0.01em;
}

.gap-card.box-gap-card .box-gap-line {
  display: block;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  margin-top: 2px;
}

.gap-card.box-gap-card.gap-positive {
  border-left: 3px solid var(--positive);
}

.gap-card.box-gap-card.gap-negative {
  border-left: 3px solid var(--negative);
}

.bar-row span:last-child {
  text-align: right;
  font-family: var(--font-mono);
  color: var(--muted);
  font-size: 12px;
}

/* ── data tables ──────────────────────────────── */

.data-table, .mini-table {
  overflow-x: auto;
  /* min-width: 0 lets the table shrink inside its grid parent so
     overflow-x actually engages instead of the table pushing its
     parent wider. */
  min-width: 0;
  scrollbar-color: var(--line-strong) transparent;
  /* iOS / Android: visible scrollbar hint that the table scrolls.
     Without it the user just sees "cut off" content with no
     indication they can swipe to see the rest. */
  -webkit-overflow-scrolling: touch;
}

.table-header,
.table-row {
  display: grid;
  gap: 10px;
  align-items: center;
  min-height: 42px;
  min-width: 720px;
  padding: 0 4px;
  border-bottom: 1px solid var(--line-soft);
  font-size: 13px;
}

.table-header {
  min-height: 32px;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.table-row:hover { background: var(--surface-2); }

.table-row strong {
  font-weight: 550;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.table-header span:nth-child(n+2),
.table-row span:nth-child(n+2),
.table-row strong:nth-child(n+2) {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.table-row strong:nth-child(1) { font-family: var(--font-sans); text-align: left; }

.period-grid { grid-template-columns: 72px 70px 70px 1fr; min-width: 0; }
.period-grid--nhl { grid-template-columns: 84px 56px 64px 72px 72px 78px 1fr; }

/* Narrow viewports: the seven-column layout (Market · Line · Sim avg ·
   Sim over · Mkt over · Δ · 80% range) sums to ~426px of fixed tracks
   and overflows the ~360-400px CSS viewport on phones — the right-
   hand columns disappear off the edge. Drop the 80% range column
   (least critical, already implied by the Sim avg / Line columns) and
   let the rest flex with the viewport. */
@media (max-width: 720px) {
  .period-grid--nhl {
    grid-template-columns:
      minmax(48px, 0.95fr)
      minmax(34px, 0.6fr)
      minmax(44px, 0.75fr)
      minmax(44px, 0.85fr)
      minmax(44px, 0.85fr)
      minmax(48px, 0.9fr);
    gap: 6px;
    font-size: 12px;
  }
  /* Hide the trailing "80% range" cell — it's the 7th cell of every
     row. Using nth-child(7n) targets it across header and body rows. */
  .period-grid--nhl > *:nth-child(7n) {
    display: none;
  }
  /* Tighten the delta pill so its padding doesn't push the column
     past the now-narrower track. */
  .period-grid--nhl .period-delta {
    padding: 1px 4px;
    font-size: 0.88em;
  }
}

.period-delta {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  display: inline-block;
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 0.92em;
}
.period-delta--neutral { color: var(--muted, #6b7280); background: transparent; }
.period-delta--mild    { color: #8a6d3b; background: rgba(214, 158, 46, 0.14); }
.period-delta--strong  { color: #9b2c2c; background: rgba(229, 62, 62, 0.14); }

.period-split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 18px;
}

@media (min-width: 720px) {
  .period-split { grid-template-columns: 1fr 1fr; gap: 24px; }
}

/* MLB only emits a single column (Inning markets); keep it full-width
   instead of letting it sit half-empty on the left at desktop widths. */
.period-split.single { grid-template-columns: 1fr; }

/* Period moneylines table: 7 columns (period · away sim/mkt/gap · home
   sim/mkt/gap) for NBA/MLB, 8 columns when ties are surfaced (NHL). */
.mls-grid {
  min-width: 0;
  gap: 6px;
  padding: 0 6px;
}

.mls-grid-2 {
  grid-template-columns: minmax(80px, 1fr) repeat(6, minmax(58px, 1fr));
}

.mls-grid-3 {
  grid-template-columns: minmax(80px, 1fr) repeat(3, minmax(54px, 1fr)) minmax(54px, 0.7fr) repeat(3, minmax(54px, 1fr));
}

.mls-grid span,
.mls-grid strong {
  font-family: var(--font-mono);
  font-size: 12px;
  text-align: right;
}

.mls-grid strong:first-child,
.mls-grid > span:first-child {
  text-align: left;
  font-family: var(--font-sans);
  font-size: 13px;
}

/* Two-row header: row 1 carries team names spanning the three
   sub-columns (sim/mkt/gap), row 2 carries the column labels. Without
   the span, the full team name ("Philadelphia Phillies") repeats in
   each narrow ~58px column and the text overlaps on mobile. */
.mls-team-row {
  border-bottom: 0;
  min-height: 24px;
  padding-bottom: 0;
  align-items: end;
}
.mls-team-row .mls-team-name {
  text-align: center;
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  /* Hyphenate/break long team names cleanly inside the spanned cell
     instead of forcing the grid track wider than the viewport. */
  overflow-wrap: anywhere;
  line-height: 1.15;
}
.mls-team-row .mls-team-away,
.mls-team-row .mls-team-home {
  grid-column: span 3;
}
.mls-team-row .mls-team-tie {
  /* Tie column is a single cell — no span, but still centered to
     align with the team-name visual grouping. */
  text-align: center;
}
.mls-sub-row {
  /* Match the existing .table-header look but tighten vertical
     spacing so the two-row header isn't double-stacked tall. */
  min-height: 28px;
}

.mls-gap-pos { color: var(--positive); }
.mls-gap-neg { color: var(--negative); }

/* Each column is a self-contained card so quarters and halves don't
   visually bleed into each other. */
.period-column {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 14px 16px 6px;
  background: var(--surface);
}

.period-column-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line-soft);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-2);
  width: 100%;
}

.period-column-title::before {
  content: "";
  display: inline-block;
  width: 4px;
  height: 12px;
  background: var(--accent);
  border-radius: 2px;
}

.period-column .table-row:last-child {
  border-bottom: 0;
}

.period-split .period-grid,
.period-split .table-row,
.period-split .table-header {
  min-width: 0;
  gap: 8px;
}

.first-team-split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}

@media (min-width: 720px) {
  .first-team-split { grid-template-columns: 1fr 1fr; }
}

.first-team-column-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
}

.first-team-leftover { margin-top: 18px; }

.ranges-grid {
  grid-template-columns: minmax(180px, 1.4fr) 80px repeat(4, minmax(72px, 1fr)) minmax(220px, 1.6fr);
}

.runs-grid {
  grid-template-columns: 56px minmax(160px, 1fr) minmax(160px, 1fr) 70px 110px;
}

.pbp-grid {
  grid-template-columns: 80px 100px minmax(220px, 1fr) 90px 70px;
}

.ranges-grid span:first-child,
.ranges-grid strong:first-child,
.ranges-grid span:nth-child(2),
.ranges-grid span:last-child,
.pbp-grid span:nth-child(-n+3),
.pbp-grid strong:nth-child(-n+3) {
  text-align: left;
  font-family: var(--font-sans);
}

.range-takeaway {
  color: var(--muted);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  white-space: normal;
}

/* ── mini table (first basket) ────────────────── */

.mini-table { display: grid; gap: 0; }

.mini-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  min-height: 44px;
  padding: 0 4px;
  border-bottom: 1px solid var(--line-soft);
  font-size: 13px;
}

.mini-row strong {
  font-weight: 550;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mini-row span {
  font-family: var(--font-mono);
  color: var(--muted);
  font-size: 12px;
  text-align: right;
}

/* ── soccer / World Cup macro ─────────────────── */

.soccer-macro { display: grid; gap: 20px; }

.soccer-macro-group { display: grid; gap: 8px; }

.soccer-resultbar {
  display: flex;
  height: 16px;
  border-radius: 999px;
  overflow: hidden;
  border: 1px solid var(--line);
}
.soccer-seg { height: 100%; }
.soccer-seg-home { background: var(--accent); }
.soccer-seg-draw { background: var(--line); }
.soccer-seg-away { background: var(--positive); }

.soccer-resultlegend {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  font-size: 12px;
  color: var(--muted);
}
.soccer-resultlegend span { display: inline-flex; align-items: center; gap: 6px; }
.soccer-resultlegend strong { color: var(--ink); font-family: var(--font-mono); }
.soccer-legend-dot { width: 10px; height: 10px; border-radius: 3px; }
.soccer-legend-dot.home { background: var(--accent); }
.soccer-legend-dot.draw { background: var(--line); }
.soccer-legend-dot.away { background: var(--positive); }

.soccer-score-grid { display: flex; flex-wrap: wrap; gap: 10px; }
.soccer-score-chip {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 64px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
}
.soccer-score-chip strong { font-family: var(--font-serif); font-size: 18px; color: var(--ink); }
.soccer-score-chip span { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }

.soccer-fit-row .soccer-fit-cmp { display: inline-flex; gap: 10px; align-items: center; }
.soccer-fit-gap { font-weight: 600; }
.soccer-fit-gap.gap-strong { color: var(--warn); }
.soccer-fit-gap.gap-conflict { color: var(--negative); }

/* Country flags in team chips — flags are rectangular, not round. */
.team-flag { overflow: hidden; background: var(--surface); }
.team-flag img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }

.soccer-box-note { margin-left: 10px; font-size: 11px; font-weight: 500; color: var(--muted); font-family: var(--font-mono); }

/* Percentage shown next to a gap-card headline value (soccer match markets). */
.gap-card-sub { margin-left: 6px; font-weight: 500; color: var(--muted); font-size: 0.8em; }

/* Scoreline card: top line big (in the gap-card <strong>), alternates listed
   one per line below it. */
.sl-alts { display: grid; gap: 4px; margin-top: 2px; }
.sl-alt {
  display: flex; justify-content: space-between; gap: 12px;
  font-size: 12px; color: var(--muted);
}
.sl-alt .num { color: var(--ink); font-family: var(--font-mono); }

/* Double-chance card: all three outcomes (1X / 12 / X2), one per line, the
   pick over its sim/book/gap so it fits a normal-width card in the row. */
.dc-list { display: grid; gap: 7px; }
.dc-line {
  display: grid; gap: 1px;
  padding: 4px 0; border-bottom: 1px solid var(--line-soft); font-size: 13px;
}
.dc-line:last-child { border-bottom: 0; }
.dc-pick { font-weight: 550; color: var(--ink); }
.dc-vals { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.dc-vals .soccer-fit-gap { margin-left: 6px; font-weight: 600; }

/* Match-markets reuses the gap-card look but holds a variable number of
   cards (scoreline + BTTS + 1X/12/X2), so auto-fit keeps every row balanced
   instead of the gaps section's fixed 4-column template. */
#soccerMatchMarkets { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
@media (min-width: 720px) { #soccerMatchMarkets { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); } }
/* When the module is Pro-locked, the placeholder spans the full row. */
.gap-grid > .pro-locked { grid-column: 1 / -1; }

/* Team-goal distribution + corners mini bar charts */
.soccer-goalsplit { display: grid; gap: 28px; grid-template-columns: 1fr; align-items: start; }
@media (min-width: 760px) { .soccer-goalsplit { grid-template-columns: 1fr 1fr; } }
.soccer-goalcol { display: grid; gap: 12px; }
.soccer-goalcol-head {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--font-serif); font-size: 16px; color: var(--ink);
}
.soccer-goalcol-line { margin-left: auto; font-family: var(--font-mono); font-size: 11px; color: var(--muted); font-style: normal; }
.soccer-goalchart { display: grid; gap: 6px; }
/* Chart rows and the over-ladder rows below them share the SAME column
   geometry so labels (left) and percentages (right) line up down the whole
   module: [label] [flexible middle] [right-aligned value]. */
.goalchart-row,
.soccer-goalcol .soccer-fit-row {
  display: grid;
  grid-template-columns: 64px 1fr 56px;
  gap: 10px;
  align-items: center;
  min-height: 0;
  padding: 4px 0;
  border-bottom: 1px solid var(--line-soft);
}
.goalchart-k { font-family: var(--font-mono); font-size: 12px; color: var(--muted); }
.goalchart-bar { height: 12px; border-radius: 3px; background: var(--line-soft); overflow: hidden; }
.goalchart-fill { display: block; height: 100%; background: var(--accent); border-radius: 3px; }
.goalchart-p { font-family: var(--font-mono); font-size: 12px; color: var(--ink); text-align: right; }
/* In the team-goals module the over-ladder reuses the chart geometry:
   "Over X" label, the sim·book comparison in the middle, the gap at right. */
.soccer-goalcol .soccer-fit-row strong { font-weight: 550; font-size: 12px; }
.soccer-goalcol .soccer-fit-row .soccer-fit-cmp {
  display: flex; justify-content: space-between; align-items: center;
  grid-column: 2 / 4; gap: 10px; font-size: 11px;
}

/* Soccer box: 5-column outfield override of the fixed 6-column NHL grid.
   Compound selector (two classes) so it out-specifies the later
   .box-row--nhl-skaters repeat(6) rule — otherwise the box renders a 6th
   empty column and doesn't fill the panel width. */
@media (min-width: 1180px) {
  .box-header--nhl-skaters.box-header--soccer,
  .box-row--nhl-skaters.box-row--soccer {
    grid-template-columns: minmax(150px, 1.2fr) repeat(var(--soccer-cols, 5), minmax(0, 1fr));
  }
}

/* ── soccer: phone layout ─────────────────────────
   The module sim-vs-book rows and charts have fixed/auto columns that get
   cramped on a narrow screen — stack and tighten so nothing overflows. */
@media (max-width: 600px) {
  /* Handicap / corners / half-result rows: stack the selection above its
     Sim·Book·gap line instead of forcing both onto one row (which truncated
     long picks like "Algeria or Draw"). */
  .mini-row.soccer-fit-row {
    grid-template-columns: 1fr;
    align-items: start;
    gap: 2px;
    min-height: 0;
    padding: 9px 2px;
  }
  .mini-row.soccer-fit-row strong { white-space: normal; }
  .mini-row.soccer-fit-row .soccer-fit-cmp {
    justify-content: flex-start;
    flex-wrap: wrap;
    text-align: left;
  }
  /* Team-goal chart + over ladder: tighter fixed columns. */
  .goalchart-row,
  .soccer-goalcol .soccer-fit-row { grid-template-columns: 48px 1fr 46px; gap: 6px; }
  .soccer-goalcol .soccer-fit-row .soccer-fit-cmp { gap: 6px; font-size: 10.5px; }
  /* Result-bar legend: stack the three teams rather than squeeze 3 columns. */
  .soccer-resultlegend { grid-template-columns: 1fr; gap: 4px; }
  /* "team split unavailable" note drops below the heading. */
  .soccer-box-note { display: block; margin-left: 0; margin-top: 3px; }
  /* Double-chance values can wrap under the pick on very narrow screens. */
  .dc-vals { white-space: normal; }
}

/* ── sim-modal: soccer pitch with a ball shot into the net ── */
.pitch {
  position: relative;
  width: 100%;
  height: 150px;
  margin: 8px 0 22px;
  overflow: hidden;
  display: none;
}
.sim-card.sport-soccer_wc .court,
.sim-card.sport-soccer_wc .rink,
.sim-card.sport-soccer_wc .diamond { display: none; }
.sim-card.sport-soccer_wc .pitch { display: block; }

.pitch-field-svg { position: absolute; inset: 10px 0 12px 0; width: 100%; height: calc(100% - 22px); }

.soccer-ball-wrap {
  position: absolute;
  top: 50%;
  left: 6%;
  width: 22px;
  height: 22px;
  margin-top: -11px;
  animation: soccer-shot 2.4s cubic-bezier(0.4, 0.05, 0.5, 0.95) infinite;
  will-change: left, top, opacity;
}
.soccer-ball-svg {
  width: 100%; height: 100%; display: block;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.18));
  animation: soccer-ball-spin 0.5s linear infinite;
}
@keyframes soccer-ball-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
@keyframes soccer-shot {
  /* dribble in from the left, weaving across the pitch */
  0%   { left: 6%;  top: 50%; opacity: 1; }
  20%  { left: 22%; top: 56%; }
  40%  { left: 38%; top: 45%; }
  58%  { left: 56%; top: 53%; }
  /* strike toward the goal/net on the right goal line (~95% / 50%) */
  72%  { left: 72%; top: 44%; opacity: 1; }
  84%  { left: 86%; top: 49%; }
  90%  { left: 92%; top: 50%; opacity: 1; }   /* into the net */
  93%  { left: 93%; top: 50%; opacity: 0; }   /* settle + fade */
  94%  { left: 6%;  top: 50%; opacity: 0; }   /* invisible reset */
  100% { left: 6%;  top: 50%; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .soccer-ball-wrap { animation: none; left: 50%; }
  .soccer-ball-svg { animation: none; }
}

/* ── box score ────────────────────────────────── */

.box-table { display: grid; gap: 24px; }

.team-box { display: grid; gap: 8px; }

.team-box h3 {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  align-self: start;
  padding: 6px 14px 6px 6px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  font-family: var(--font-serif);
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.team-box-name { line-height: 1; }

.box-header { display: none; }

.box-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  align-items: stretch;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
  padding: 14px;
  background: var(--surface);
  font-size: 13px;
}

.box-row > .player-name {
  grid-column: 1 / -1;
  display: grid;
  gap: 2px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.stat-cell {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 8px;
  align-content: start;
  min-height: 64px;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
  padding: 9px 11px;
  background: var(--surface-2);
}

.stat-label {
  color: var(--muted);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.stat-cell > strong {
  justify-self: end;
  font-family: var(--font-mono);
  font-size: 19px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.015em;
  line-height: 1;
}

.stat-market {
  grid-column: 1 / -1;
  display: grid;
  gap: 2px;
  font-family: var(--font-mono);
  line-height: 1.3;
  overflow-wrap: anywhere;
  text-align: left;
}

.stat-range {
  grid-column: 1 / -1;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1.25;
}

.market-line {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  font-variant-numeric: tabular-nums;
}

.market-line-tag {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.market-line-num {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.005em;
  color: var(--ink-2);
}

.market-odds {
  display: block;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--faint);
}

.market-hit {
  display: block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink-2);
}

.market-skew {
  display: inline-block;
  margin-top: 2px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--warn, #8a6d3b);
  background: var(--warn-soft, #fdf3da);
  border: 1px solid rgba(138, 109, 59, 0.25);
  cursor: help;
}

/* Magnitude-band cells for non-NBA stat tables */
.stat-cell.over-hit strong,
.stat-cell.under-hit strong,
.stat-cell.near-hit strong {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 6px;
  font-weight: 700;
}

.stat-cell.over-hit strong {
  background: var(--positive-soft);
  color: var(--positive);
}

.stat-cell.under-hit strong {
  background: var(--negative-soft);
  color: var(--negative);
}

.stat-cell.near-hit strong {
  background: var(--warn-soft);
  color: var(--warn);
}

/* ── NBA box score cell — tight box-score look ──────────────── */

.stat-cell--bet,
.stat-cell--info {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 1px;
  min-height: 48px;
  padding: 6px 10px;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  text-align: right;
  font-variant-numeric: tabular-nums;
  cursor: default;
}

.stat-cell-label {
  align-self: flex-start;
  font-size: 9px;
  letter-spacing: 0.14em;
}

.stat-cell-value {
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.01em;
  line-height: 1.05;
}

.stat-cell-line,
.stat-cell-sub {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  color: var(--muted);
  letter-spacing: 0;
  line-height: 1.1;
}

/* Signal-tinted backgrounds replace the pill text — color IS the
   signal, so 49 redundant "ALIGNED" pills don't crowd every row.
   Hover reveals the signal name as a tooltip via the title attr. */
.stat-cell--bet.signal-strong  { background: var(--positive-soft); border-color: rgba(44, 106, 74, 0.35); }
.stat-cell--bet.signal-neutral { background: var(--warn-soft, #fdf3da); border-color: rgba(138, 109, 59, 0.25); }
.stat-cell--bet.signal-weak    { background: var(--negative-soft); border-color: rgba(139, 53, 39, 0.30); }

.stat-cell--bet.signal-strong  .stat-cell-line { color: var(--positive); }
.stat-cell--bet.signal-weak    .stat-cell-line { color: var(--negative); }
.stat-cell--bet.signal-neutral .stat-cell-line { color: var(--warn, #8a6d3b); }

.stat-cell-empty {
  color: var(--faint);
  font-weight: 500;
}

.stat-cell-details {
  width: 100%;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--ink);
  text-align: left;
  margin-top: 4px;
}

.stat-cell-details > summary {
  cursor: pointer;
  list-style: none;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding: 1px 0;
  user-select: none;
  text-align: right;
}

.stat-cell-details > summary::-webkit-details-marker { display: none; }

.stat-cell-details > summary::before {
  content: "▸ ";
  display: inline-block;
  font-size: 9px;
}

.stat-cell-details[open] > summary::before { content: "▾ "; }

.stat-cell-details > summary:hover { color: var(--ink); }

.stat-cell-details > .bet-rates {
  margin-top: 4px;
  font-size: 11px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
}

.stat-cell-details > .bet-supporting {
  margin-top: 2px;
  font-size: 10px;
  font-weight: 500;
  color: var(--ink-2);
}

.stat-cell-details > .market-skew { margin-top: 4px; }

@media (min-width: 680px) {
  .box-row { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .box-row > .player-name { grid-column: 1 / -1; }
}

@media (min-width: 1180px) {
  .box-header,
  .box-row {
    display: grid;
    grid-template-columns: minmax(180px, 1.3fr) repeat(6, minmax(64px, 1fr));
    gap: 8px;
    align-items: center;
    min-width: 0;
  }
  /* Box-header carries the column labels at desktop width, so the
     in-cell stat-label is redundant. Hide to reduce noise. */
  .box-row .stat-cell-label { display: none; }

  .box-header--mlb-batters,
  .box-row--mlb-batters {
    grid-template-columns: minmax(160px, 1.3fr) repeat(7, minmax(58px, 1fr));
    gap: 6px;
  }

  .box-header--mlb-pitchers,
  .box-row--mlb-pitchers {
    grid-template-columns: minmax(160px, 1.3fr) repeat(5, minmax(64px, 1fr));
  }

  /* WNBA: PTS / REB / AST / 3PM only (no BLK / STL — DK doesn't
     price those markets for WNBA). */
  .box-header--wnba,
  .box-row--wnba {
    grid-template-columns: minmax(180px, 1.3fr) repeat(4, minmax(64px, 1fr));
  }

  .box-header {
    display: grid;
    min-height: 32px;
    padding: 0 4px;
    border-bottom: 1px solid var(--line);
    color: var(--muted);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }

  /* Match the right-padding of stat-cell so the header text and the
     cell numbers below it share the same right edge (the .stat-cell
     has padding: 6px 10px). */
  .box-header span:not(:first-child) { text-align: right; padding-right: 10px; }

  .box-row {
    min-height: 56px;
    padding: 6px 8px;
    border: 0;
    border-bottom: 1px solid var(--line-soft);
    border-radius: 0;
    background: transparent;
    transition: background 150ms ease;
  }

  .box-row:hover { background: var(--surface-2); }

  .box-row > .player-name {
    grid-column: auto;
    font-size: 14px;
    font-weight: 600;
  }

  .stat-cell {
    grid-template-columns: 1fr;
    min-height: 44px;
    border: 0;
    padding: 0;
    background: transparent;
    justify-items: end;
  }

  .stat-label { display: none; }

  .stat-cell > strong {
    justify-self: end;
    font-size: 17px;
    font-weight: 700;
  }

  .stat-market {
    grid-column: auto;
    justify-self: end;
    justify-items: end;
    max-width: 100%;
    text-align: right;
  }
}

/* ── audit ────────────────────────────────────── */

.audit-block details {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
}

.audit-block summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px 20px;
  cursor: pointer;
  list-style: none;
  border-bottom: 1px solid transparent;
  user-select: none;
}

.audit-block summary::-webkit-details-marker { display: none; }

.audit-block summary::after {
  content: "→";
  margin-left: auto;
  color: var(--faint);
  font-family: var(--font-mono);
  transition: transform 150ms ease;
}

.audit-block details[open] summary { border-bottom-color: var(--line); }

.audit-block details[open] summary::after { transform: rotate(90deg); }

.summary-title {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.audit-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
  padding: 20px;
}

@media (min-width: 1080px) {
  .audit-grid { grid-template-columns: 0.85fr 1.15fr; gap: 32px; }
}

.audit-grid > div { display: grid; gap: 10px; }

.scroll-table { max-height: 460px; overflow-y: auto; }

/* ── empty + status ───────────────────────────── */

.empty {
  color: var(--muted);
  font-size: 13px;
  padding: 14px 0;
}

.status-line {
  margin: 4px 4px 0;
  min-height: 18px;
  color: var(--muted);
  font-size: 12px;
  font-family: var(--font-mono);
  letter-spacing: 0;
}

/* ── simulation modal ─────────────────────────── */

.sim-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(12, 12, 14, 0.42);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: sim-fade-in 220ms ease;
}

@keyframes sim-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.sim-card {
  width: min(460px, 100%);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 28px 28px 22px;
  box-shadow: 0 32px 80px rgba(12, 12, 14, 0.18), 0 2px 8px rgba(12, 12, 14, 0.06);
  animation: sim-card-in 320ms cubic-bezier(0.2, 0.8, 0.3, 1);
}

@keyframes sim-card-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.sim-card-head {
  display: grid;
  gap: 6px;
  text-align: center;
  margin-bottom: 18px;
}

.sim-card-head .kicker { letter-spacing: 0.16em; }

.sim-card-title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 24px;
  letter-spacing: -0.015em;
  line-height: 1.15;
  color: var(--ink);
}

.sim-card-title em {
  font-style: italic;
  font-weight: 400;
  color: var(--muted);
}

.sim-card-sub {
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.45;
  max-width: 340px;
  margin: 2px auto 0;
}

/* court + animation */

.court {
  position: relative;
  width: 100%;
  height: 150px;
  margin: 8px 0 22px;
  overflow: hidden;
}

.court-floor {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--line);
}

.court-floor::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 18px;
  background: linear-gradient(to top, rgba(232, 127, 43, 0.05), transparent);
}

.hoop-svg {
  position: absolute;
  top: 4px;
  right: 6px;
  width: 96px;
  height: 76px;
}

.ball-wrap {
  position: absolute;
  bottom: 1px;
  left: 0;
  width: 26px;
  height: 26px;
  animation: ball-trajectory 2.6s cubic-bezier(0.45, 0.05, 0.55, 0.95) infinite;
  will-change: left, bottom, opacity;
}

.ball-svg {
  width: 100%;
  height: 100%;
  display: block;
  filter: drop-shadow(0 2px 2px rgba(122, 62, 21, 0.18));
  animation: ball-spin 0.55s linear infinite;
  will-change: transform;
}

@keyframes ball-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes ball-trajectory {
  /* setup */
  0%   { left: 0%;   bottom: 1px;  opacity: 1; }
  /* bounce 1 */
  8%   { left: 8%;   bottom: 42px; }
  16%  { left: 18%;  bottom: 1px; }
  /* bounce 2 */
  24%  { left: 28%;  bottom: 36px; }
  32%  { left: 38%;  bottom: 1px; }
  /* bounce 3 */
  40%  { left: 46%;  bottom: 28px; }
  48%  { left: 54%;  bottom: 1px; }
  /* gather */
  56%  { left: 60%;  bottom: 22px; }
  62%  { left: 62%;  bottom: 1px; }
  /* arc shot to hoop */
  72%  { left: 70%;  bottom: 92px; opacity: 1; }
  78%  { left: 76%;  bottom: 96px; }
  82%  { left: 80%;  bottom: 88px; }
  86%  { left: 81%;  bottom: 70px; opacity: 0.85; }
  90%  { left: 81%;  bottom: 50px; opacity: 0; }
  /* invisible reset */
  91%  { left: 0%;   bottom: 1px;  opacity: 0; }
  100% { left: 0%;   bottom: 1px;  opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .ball-wrap { animation: none; left: 8%; }
  .ball-svg { animation: none; }
}

/* phase tracker */

.phases {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.phases li {
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: 12px;
  align-items: center;
  font-size: 13px;
  color: var(--faint);
  font-weight: 500;
  letter-spacing: -0.005em;
  transition: color 220ms ease;
}

.phase-dot {
  position: relative;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1.5px solid var(--line-strong);
  background: var(--surface);
  transition: border-color 220ms ease, background 220ms ease;
}

.phases li.running { color: var(--ink); font-weight: 600; }

.phases li.running .phase-dot {
  border-color: var(--accent);
  animation: phase-pulse 1.3s ease-in-out infinite;
}

.phases li.done { color: var(--ink-2); font-weight: 500; }

.phases li.done .phase-dot {
  background: var(--accent);
  border-color: var(--accent);
  animation: none;
}

.phases li.done .phase-dot::after {
  content: "";
  position: absolute;
  top: 2.5px;
  left: 4.5px;
  width: 4px;
  height: 7.5px;
  border-right: 1.5px solid #fff;
  border-bottom: 1.5px solid #fff;
  transform: rotate(45deg);
}

@keyframes phase-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(176, 133, 51, 0.32); }
  50%      { box-shadow: 0 0 0 6px rgba(176, 133, 51, 0); }
}

.sim-foot {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--line-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  color: var(--muted);
}

.sim-foot-label { font-weight: 500; }

.sim-foot-elapsed {
  font-family: var(--font-mono);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/* ── transparency block ─────────────────────────── */

.transparency-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
}

.transparency-grid > div {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 14px;
}

.anchors-grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, 1fr);
  gap: 8px;
  font-variant-numeric: tabular-nums;
  align-items: center;
}

.rates-grid {
  display: grid;
  grid-template-columns: 1.6fr repeat(7, minmax(50px, 1fr)) 1.6fr;
  gap: 6px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  align-items: center;
}

.remainder-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 8px;
  font-variant-numeric: tabular-nums;
  align-items: center;
}

.prop-fit-grid {
  display: grid;
  grid-template-columns: 1.3fr 0.9fr 0.9fr repeat(3, minmax(54px, 0.75fr));
  gap: 8px;
  font-variant-numeric: tabular-nums;
  align-items: center;
}

.anchor-good { color: var(--positive); font-weight: 600; }
.anchor-bad { color: var(--negative); font-weight: 600; }

@media (max-width: 900px) {
  .transparency-grid {
    grid-template-columns: 1fr;
  }
}

/* ── responsive top ───────────────────────────── */

@media (max-width: 640px) {
  .top {
    grid-template-columns: 1fr;
  }

  .top-nav { justify-self: start; }

  .hero-controls .tier-btn { padding: 12px; }

  .hero-meta { font-size: 12px; }
}

/* ── NHL: sim modal rink + puck ───────────────── */

.rink {
  position: relative;
  width: 100%;
  height: 150px;
  margin: 8px 0 22px;
  overflow: hidden;
  display: none;
}

.sim-card.sport-nhl .court,
.sim-card.sport-nhl .diamond { display: none; }
.sim-card.sport-nhl .rink { display: block; }

.sim-card.sport-mlb .court,
.sim-card.sport-mlb .rink { display: none; }
.sim-card.sport-mlb .diamond { display: block; }

.rink-svg {
  position: absolute;
  inset: 12px 0 14px 0;
  width: 100%;
  height: calc(100% - 26px);
  display: block;
}

.puck-wrap {
  position: absolute;
  /* Centered vertically on the rink — top-down view, puck glides
     horizontally without any 3D vertical hop. */
  top: 50%;
  margin-top: -7px;
  left: 8%;
  width: 14px;
  height: 14px;
  animation: puck-glide 3.2s cubic-bezier(0.55, 0, 0.45, 1) infinite;
  will-change: left;
}

.puck-svg {
  width: 100%;
  height: 100%;
  display: block;
}

@keyframes puck-glide {
  0%   { left: 8%;  opacity: 1; }
  80%  { left: 86%; opacity: 1; }
  90%  { left: 88%; opacity: 0; }
  91%  { left: 8%;  opacity: 0; }
  100% { left: 8%;  opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .puck-wrap { animation: none; left: 12%; }
}

/* ── MLB: sim modal diamond + pitch/swing ──────── */

.diamond {
  position: relative;
  width: 100%;
  height: 170px;
  margin: 8px 0 22px;
  display: none;
  overflow: hidden;
}

.diamond-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  filter: drop-shadow(0 6px 12px rgba(12, 12, 14, 0.18));
}

/* Ball travels from the pitcher's mound (~50% width, ~60% height in
   the viewBox) to home plate (~50% width, ~84% height). The keyframes
   express that as a small downward arc + brief pause + reset. */
.pitch-wrap {
  position: absolute;
  left: calc(50% - 7px);
  top: 60%;
  width: 14px;
  height: 14px;
  animation: pitch-throw 1.6s cubic-bezier(0.65, 0, 0.35, 1) infinite;
  will-change: top, transform, opacity;
}

.pitch-svg {
  width: 100%;
  height: 100%;
  display: block;
}

@keyframes pitch-throw {
  0%   { top: 56%; transform: translateY(0)    scale(0.55); opacity: 0;   }
  10%  { top: 56%; transform: translateY(0)    scale(0.6);  opacity: 0.6; }
  35%  { top: 68%; transform: translateY(-4px) scale(0.95); opacity: 1;   }
  60%  { top: 80%; transform: translateY(-2px) scale(1.15); opacity: 1;   }
  75%  { top: 86%; transform: translateY(0)    scale(1.25); opacity: 0;   }
  100% { top: 56%; transform: translateY(0)    scale(0.55); opacity: 0;   }
}

/* Bat swings on contact (the moment the ball reaches home plate),
   then resets. Pivot is at the right end (the handle) so the barrel
   sweeps left-to-right like a right-handed swing.  */
.bat-wrap {
  position: absolute;
  left: calc(50% - 30px);
  bottom: 14%;
  width: 42px;
  height: 8px;
  transform-origin: 90% 50%;
  /* Smoother swing — gentler ease keeps the load and follow-through
     from feeling abrupt. */
  animation: bat-swing 1.9s cubic-bezier(0.4, 0, 0.4, 1) infinite;
  will-change: transform;
}

.bat-svg {
  width: 100%;
  height: 100%;
  display: block;
  filter: drop-shadow(0 2px 2px rgba(12, 12, 14, 0.3));
}

@keyframes bat-swing {
  /* More keyframes, more graceful arc — no long stationary hold at
     the load position, and the return-to-ready unwinds through the
     full arc instead of snapping back from follow-through. */
  0%   { transform: rotate(45deg);  }    /* ready stance */
  18%  { transform: rotate(50deg);  }    /* small load wind-up */
  36%  { transform: rotate(20deg);  }    /* trigger forward */
  50%  { transform: rotate(-30deg); }    /* through the zone */
  60%  { transform: rotate(-60deg); }    /* contact */
  72%  { transform: rotate(-45deg); }    /* follow-through */
  88%  { transform: rotate(10deg);  }    /* relax back through the zone */
  100% { transform: rotate(45deg);  }    /* fully reset */
}

/* Dust puff at home plate on contact — a quick scale-and-fade halo. */
.diamond::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 8%;
  width: 26px;
  height: 12px;
  margin-left: -13px;
  border-radius: 50%;
  background: radial-gradient(ellipse, rgba(232, 200, 150, 0.85) 0%, rgba(232, 200, 150, 0) 70%);
  opacity: 0;
  animation: contact-puff 1.6s ease-out infinite;
  will-change: opacity, transform;
  pointer-events: none;
}

@keyframes contact-puff {
  0%, 65%   { opacity: 0; transform: scale(0.4); }
  72%       { opacity: 0.95; transform: scale(1); }
  90%       { opacity: 0; transform: scale(1.6); }
  100%      { opacity: 0; transform: scale(0.4); }
}

@media (prefers-reduced-motion: reduce) {
  .pitch-wrap,
  .bat-wrap,
  .diamond::after { animation: none; }
  .pitch-wrap { top: 75%; }
  .bat-wrap { transform: rotate(45deg); }
}

/* ── NHL: skater box grid ─────────────────────── */

.box-header--nhl-skaters,
.box-row--nhl-skaters {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.box-header--nhl-skaters { display: none; }

@media (min-width: 1180px) {
  .box-header--nhl-skaters,
  .box-row--nhl-skaters {
    grid-template-columns: minmax(170px, 1.4fr) repeat(6, minmax(56px, 1fr));
    gap: 8px;
    align-items: center;
  }

  .box-header--nhl-skaters { display: grid; }
}

/* ── NHL: goalie cards ────────────────────────── */

.goalie-report {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}

@media (min-width: 760px) {
  .goalie-report { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.goalie-card {
  display: grid;
  gap: 14px;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
}

.goalie-card-head {
  display: grid;
  gap: 6px;
}

.goalie-team {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.goalie-name {
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.goalie-meta {
  color: var(--muted);
  font-size: 12px;
  font-family: var(--font-mono);
  letter-spacing: 0;
}

.goalie-stats {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 1180px) {
  .goalie-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.goalie-stat {
  display: grid;
  gap: 4px;
  align-content: start;
  padding: 12px;
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
}

.goalie-stat strong {
  font-family: var(--font-mono);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.goalie-stat .stat-label {
  font-size: 10px;
  letter-spacing: 0.12em;
}

.goalie-stat .stat-range {
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 10px;
}

.goalie-line {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-2);
  line-height: 1.3;
}

.goalie-line-empty {
  color: var(--faint);
  font-style: italic;
}

/* ── NHL: market fit table ────────────────────── */

.fit-grid {
  grid-template-columns: minmax(160px, 1.2fr) minmax(160px, 1.4fr) repeat(3, minmax(72px, 1fr));
}

.fit-grid strong:first-child,
.fit-grid span:nth-child(2) {
  text-align: left;
  font-family: var(--font-sans);
}

/* ============================================================
   ── Mobile pass: tighten everything below 720px / 480px
   ============================================================
   The page already has scattered responsive overrides above;
   this block consolidates the rules that matter most on phones
   so nothing overflows or feels cramped on a 360px screen.
   ============================================================ */

@media (max-width: 720px) {
  .app {
    width: 100%;
    padding: 12px 14px 56px;
    gap: 16px;
  }

  .canvas { gap: 22px; }

  /* Force box-sizing so borders + padding don't push any block past
     the .app horizontal padding (was a source of "modules misaligned"
     on mobile when border-widths varied between sections). */
  .canvas > section,
  .canvas > .block,
  .block > * { box-sizing: border-box; max-width: 100%; }

  /* Tighten box-row so 6 stat cells fit comfortably across mobile
     widths. The original 14px + 10px gap was sized for desktop. */
  .box-row { padding: 10px; gap: 6px; }
  .stat-cell--bet,
  .stat-cell--info { padding: 5px 8px; min-height: 42px; }
  .stat-cell-headline { font-size: 14px; gap: 6px; }
  .stat-cell-line { font-size: 11px; }
  .team-box { gap: 6px; }

  .block { gap: 12px; }

  .block-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
  .block-head h2 { font-size: 18px; line-height: 1.2; }
  .block-note { font-size: 12px; line-height: 1.45; }

  .hero { gap: 10px; }
  .hero-meta { font-size: 11px; gap: 6px; }

  /* Score strip cells stack. Make each cell breathe a little less. */
  .strip-cell { padding: 14px 12px; }
  .cell-score { font-size: clamp(26px, 8vw, 34px); }
  .cell-margin { gap: 4px; }
  .margin-team { font-size: 12px; }
  .margin-value { font-size: clamp(24px, 7vw, 32px); }
  .cell-value { font-size: clamp(24px, 7vw, 30px); }

  /* Tier buttons stack on narrow widths so labels fit. */
  .tier { grid-template-columns: 1fr 1fr; }

  /* Gap cards: use full-width single column rather than the 1.4fr/3-col grid. */
  .gap-grid { grid-template-columns: 1fr; gap: 10px; }
  .gap-card { padding: 14px 14px 16px; min-height: 0; }
  .gap-card.primary strong { font-size: 22px; }
  .gap-card strong { font-size: 18px; }
  .gap-card p { font-size: 12px; }

  /* Takeaway cards in a single column. */
  .takeaway-list { grid-template-columns: 1fr; }
  .takeaway { padding: 14px; }
  .takeaway strong { font-size: 16px; }

  /* Period split stacks vertically (already does at <720px) — give the
     two columns a touch more breathing room when stacked. */
  .period-split { gap: 14px; }
  .period-column { padding: 12px 14px 6px; }

  /* First team basket already collapses; reduce the title weight. */
  .first-team-column-title { font-size: 11px; }

  /* Source tags shrink to fit. */
  .source-tag { font-size: 9px; padding: 3px 7px; letter-spacing: 0.12em; }

  /* Run-meta already stacks; ensure the dot separator hides on stack. */
  .run-meta { font-size: 10px; }
}

@media (max-width: 480px) {
  .app { padding: 10px 12px 48px; }

  /* Hero title scales further; meta stays compact. */
  .hero-title { font-size: clamp(22px, 7.5vw, 32px); gap: 8px 12px; }
  .hero-meta { gap: 4px 8px; }
  .hero-meta .dot { display: none; }

  /* Block padding tightens; section gaps tighten. */
  .canvas { gap: 18px; }
  .block-head h2 { font-size: 17px; }

  /* Run button keeps full width (already does); reduce height slightly. */
  .run-btn-xl { height: 52px; padding: 0 18px; font-size: 14px; }
  .run-btn-xl .run-arrow { font-size: 18px; }

  /* Score strip cells: 8px padding on smallest screens. */
  .strip-cell { padding: 12px 10px; }

  /* Gap card pill — keep readable but shrink. */
  .signal-pill { height: 20px; padding: 0 8px; font-size: 9px; }

  /* Sport tab buttons get tighter. */
  .sport-tab { padding: 7px 4px; font-size: 11px; letter-spacing: 0.08em; }

  /* Box-score per-team header logo gets smaller. */
  .team-box h3 { font-size: 14px; }
}

/* Tables (.table-row / .table-header) keep their min-width: 720px so
   the column grid never collapses; .data-table wraps them with
   horizontal scroll, which is a deliberate trade-off — the alternative
   is squishing seven numerical columns into 360px, which is unreadable.
   The period-split tables override this min-width with .period-split
   .table-row so quarters and halves still fit on a phone screen. */

/* ── Pro gate placeholder ─────────────────────────────────────── */

/* Replaces a Free-tier-gated section's body (e.g. #takeawayList for
   MLB Main Takeaways). The actual section content is NEVER rendered
   to the DOM when Free — this card is the only thing inside the
   slot. The frosted/translucent aesthetic comes from layered greys
   on top of the surface; there's nothing visually 'behind' it. */
.pro-locked {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 8px;
  padding: 32px 24px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background:
    linear-gradient(135deg,
      rgba(120, 120, 130, 0.10) 0%,
      rgba(120, 120, 130, 0.04) 50%,
      rgba(120, 120, 130, 0.10) 100%),
    var(--surface);
  color: var(--ink-2);
  overflow: hidden;
  isolation: isolate;
  /* Many sections use CSS grid layouts (e.g. .takeaway-list is a
     2-3 column grid). Without grid-column: 1 / -1 the locked card
     would sit in a single cell at 1/2 or 1/3 width — we want it to
     fill the full section. Harmless on non-grid parents. */
  grid-column: 1 / -1;
  width: 100%;
}

/* Faint diagonal hatch pattern overlay — gives the card a "frosted"
   feel without actually placing anything blurred behind it. Pointer-
   events disabled so the CTA stays clickable. */
.pro-locked::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    -45deg,
    rgba(120, 120, 130, 0.05) 0,
    rgba(120, 120, 130, 0.05) 6px,
    transparent 6px,
    transparent 14px
  );
  pointer-events: none;
  z-index: -1;
}

.pro-locked-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--ink);
  color: #fff;
  margin-bottom: 4px;
  box-shadow: 0 4px 14px -6px rgba(0, 0, 0, 0.35);
}

.pro-locked-kicker {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--negative, #8b3527);
}

.pro-locked-title {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.pro-locked-copy {
  margin: 0;
  max-width: 460px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-2);
}

.pro-locked-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 10px 18px;
  border: 1px solid var(--negative, #8b3527);
  border-radius: var(--r-sm);
  background: var(--negative, #8b3527);
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: -0.005em;
  transition: background 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
}

.pro-locked-cta:hover {
  background: #6f2a1f;
  border-color: #6f2a1f;
  color: #fff;
  box-shadow: 0 6px 18px -8px rgba(139, 53, 39, 0.55);
}

.pro-locked-cta-arrow {
  font-family: var(--font-mono);
  transition: transform 150ms ease;
}
.pro-locked-cta:hover .pro-locked-cta-arrow { transform: translateX(3px); }

/* ── account UI (top nav: Login / Upgrade / Settings) ─────────── */

/* Login button mirrors home.css's .btn-login so the look is
   consistent across pages. Kept here as a copy (rather than loading
   home.css from /dashboard) for the same reason as the footer styles
   below — one rule's worth of duplication beats pulling in 800
   lines of unrelated page styling. */
.btn-login {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.005em;
  transition: border-color 150ms ease, background 150ms ease, color 150ms ease;
}
.btn-login:hover {
  border-color: var(--ink);
  background: var(--surface-2);
  color: var(--ink);
}

.btn-upgrade-pro {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 14px;
  border: 1px solid var(--negative, #8b3527);
  border-radius: var(--r-sm);
  background: var(--negative, #8b3527);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.005em;
  transition: background 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
}
.btn-upgrade-pro:hover {
  background: #6f2a1f;
  border-color: #6f2a1f;
  box-shadow: 0 6px 16px -8px rgba(139, 53, 39, 0.5);
}

/* Settings gear is the entry to the dropdown. The cluster is pinned
   absolutely to the right edge of the .top header (which is the
   positioning context — see ``.top { position: sticky }``) so the
   cog wheel always sits in the top-right corner regardless of how
   the nav's other items wrap on narrow viewports. The dropdown is
   absolutely positioned below this cluster on desktop and switches
   to a viewport-fixed panel on mobile (the @media query lower in
   this file). */
.settings-cluster {
  /* Stretch top-to-bottom so we can vertical-center the gear with
     align-items, without introducing a `transform`. A `transform` on
     an ancestor creates a new containing block for `position: fixed`
     descendants, which would re-anchor the mobile dropdown to this
     32px-wide cluster instead of the viewport — pushing it off-screen. */
  position: absolute;
  top: 0;
  bottom: 0;
  right: 4px;
  display: inline-flex;
  align-items: center;
}

.settings-gear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-2);
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease, background 150ms ease, transform 200ms ease;
}
.settings-gear:hover {
  color: var(--ink);
  border-color: var(--ink);
  background: var(--surface-2);
}
.settings-gear[aria-expanded="true"] {
  border-color: var(--ink);
  color: var(--ink);
  background: var(--surface-2);
}

/* Settings dropdown — responsive by default.
   - Wide screens: anchored to the cog wheel in the top-right.
   - Narrow screens: pinned to the viewport with symmetric gutters
     so it can never overflow off-screen or collapse to a thin strip.
   `dvh` (dynamic viewport height) accounts for mobile browser chrome
   like Safari's URL bar so the max-height adapts as the bar shows/hides. */
.settings-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: min(320px, calc(100vw - 24px));
  min-width: 260px;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  box-shadow: 0 12px 28px -10px rgba(0, 0, 0, 0.18), 0 2px 6px -2px rgba(0, 0, 0, 0.08);
  z-index: 1000;
  max-height: calc(100dvh - 80px);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* Mobile bottom sheet ────────────────────────────────
   On phones we abandon the cog-anchored dropdown and turn the panel
   into a native-feeling bottom sheet: full viewport width, rounded
   top corners, drag-handle + close X in a header, dimmed backdrop
   behind it. Driven entirely by CSS — `body.settings-open` is toggled
   from openSettings/closeSettings so the backdrop and scroll-lock
   stay in sync with the panel. */
@media (max-width: 720px) {
  .settings-dropdown {
    position: fixed;
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    min-width: 0;
    max-width: none;
    max-height: 88dvh;
    border-radius: 18px 18px 0 0;
    /* Respect the iOS home-indicator safe area so the bottom of the
       sheet (sign-in CTA, sign-out button) isn't covered by it. */
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: 0 -10px 32px rgba(12, 12, 14, 0.22),
                0 -1px 0 rgba(12, 12, 14, 0.05);
    animation: settings-sheet-up 280ms cubic-bezier(0.2, 0.8, 0.3, 1);
  }
}

@keyframes settings-sheet-up {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

/* iOS Safari < 15.4 doesn't understand `dvh`. Fall back gracefully to vh. */
@supports not (height: 100dvh) {
  .settings-dropdown {
    max-height: calc(100vh - 80px);
  }
  @media (max-width: 720px) {
    .settings-dropdown {
      max-height: 88vh;
    }
  }
}

/* Sheet head: drag-handle pill + close X. Hidden on desktop; the
   desktop dropdown doesn't need either affordance. */
.settings-sheet-head { display: none; }
@media (max-width: 720px) {
  .settings-sheet-head {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px 12px 8px;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    border-radius: 18px 18px 0 0;
  }
  .settings-sheet-grip {
    display: block;
    width: 40px;
    height: 4px;
    border-radius: 999px;
    background: var(--line-strong);
  }
  .settings-sheet-close {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    width: 36px;
    height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    color: var(--ink-2);
    border-radius: 999px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .settings-sheet-close:hover,
  .settings-sheet-close:focus-visible {
    color: var(--ink);
    background: var(--surface-2);
  }
}

/* Backdrop behind the sheet. Injected by JS so the markup stays
   shared across pages — only styled here. z-index sits just below
   .top (60) so the sticky header (with the gear) remains tappable
   while the sheet is open, but high enough to cover all page
   content (which has no positioning / z-index). */
.settings-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(12, 12, 14, 0.45);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  z-index: 50;
  animation: settings-backdrop-in 240ms ease;
}
@media (max-width: 720px) {
  .settings-backdrop:not([hidden]) { display: block; }
  /* Lock body scroll while the sheet is open so the page underneath
     doesn't slide around when the user scrolls a long settings list. */
  body.settings-open { overflow: hidden; }
  /* Hide the floating "Stay in the loop" subscribe launcher — its
     z-index (9000) would otherwise poke above the backdrop. */
  body.settings-open .sub-widget { visibility: hidden; }
}
@keyframes settings-backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.settings-section {
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}
.settings-section:last-child { border-bottom: 0; }

.settings-section-title {
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.settings-section-note {
  margin: 0 0 10px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-2);
}

.settings-tz-group {
  display: grid;
  gap: 4px;
}

.settings-tz-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-radius: var(--r-sm);
  cursor: pointer;
  font-size: 13px;
  color: var(--ink);
}
.settings-tz-option:hover { background: var(--surface-2); }
.settings-tz-option input { accent-color: var(--ink); margin: 0; }
.settings-tz-option input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 2px; border-radius: 2px; }

.settings-membership {
  display: grid;
  gap: 10px;
}
.settings-membership-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 13px;
}
.settings-membership-label { color: var(--muted); font-weight: 500; }
.settings-membership-value {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-2);
  font-weight: 600;
  font-size: 12px;
  color: var(--ink);
}
.settings-membership-value[data-tier="paid"] {
  background: var(--negative, #8b3527);
  color: #fff;
}

.settings-membership-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--negative, #8b3527);
  border-radius: var(--r-sm);
  background: var(--negative, #8b3527);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease;
}
.settings-membership-cta:hover {
  background: #6f2a1f;
  border-color: #6f2a1f;
  color: #fff;
}
.settings-membership-cta--ghost {
  background: transparent;
  color: var(--ink-2);
  border-color: var(--line-strong);
}
.settings-membership-cta--ghost:hover {
  background: var(--surface-2);
  border-color: var(--ink);
  color: var(--ink);
}

.settings-signout {
  width: 100%;
  height: 32px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease, background 150ms ease;
}
.settings-signout:hover {
  color: var(--ink);
  border-color: var(--ink);
  background: var(--surface-2);
}

/* ── account info (read-only, Clerk-styled "greyed out") ─────── */
.settings-account-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 10px;
}
.settings-account-field:last-child { margin-bottom: 0; }
.settings-account-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.settings-account-input {
  width: 100%;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--ink-2);
  font-size: 13px;
  font-family: inherit;
  cursor: not-allowed;
  user-select: text;
}
.settings-account-input:focus {
  outline: none;
  border-color: var(--line-strong);
}

/* ── sign-in CTA (shown when signed out) ─────────────────────── */
.settings-signin-cta {
  width: 100%;
  height: 36px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--ink);
  color: var(--surface);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  margin-bottom: 8px;
  transition: background 150ms ease, border-color 150ms ease;
}
.settings-signin-cta:hover {
  background: var(--ink-2);
}

/* ── footer (shared with home page) ───────────────────────────── */

/* Mirrors home.css's .home-foot block. Copied here instead of
   loading home.css from /dashboard because the command center only
   needs the footer rules and importing all of home.css would pull
   in 800+ lines of unused page-specific styling. Keep these
   selectors in sync with home.css if either changes. */
.home-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 20px;
  padding: 24px 4px 8px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--muted);
}

@media (min-width: 720px) {
  .home-foot { padding: 28px 4px 8px; }
}

.home-foot-brand { font-weight: 600; color: var(--ink-2); }

.home-foot-links {
  display: inline-flex;
  gap: 14px;
  margin-left: auto;
}

.home-foot-links a {
  color: var(--ink-2);
  font-weight: 500;
}

.home-foot-links a:hover { color: var(--accent-deep); }

.home-foot-disclaimer {
  flex-basis: 100%;
  margin: 0;
  font-size: 11.5px;
  color: var(--faint);
  line-height: 1.5;
}
