/* Consensus Edge — Slate redesign theme tokens
 * Source: docs/superpowers/specs/2026-05-09-slate-redesign-design.md §4
 */
:root {
  /* FIX 2026-07-12 (UI cleanup Batch 2): --slate-* tokens are now aliases of
     the canonical main.css palette — this block previously defined a parallel
     near-duplicate palette (e.g. --slate-green duplicated --accent's #10b981).
     Also: --slate-accent and --slate-text-1 were referenced throughout this
     file but NEVER defined — every var(--slate-accent, #1ddc7a) usage was
     silently rendering its fallback, a third shade of green. Both are now
     defined, so the fallbacks below are inert. */
  --slate-bg: var(--bg-base);
  --slate-bg-card: var(--bg-card);
  --slate-bg-hover: rgba(16,185,129,0.04);
  --slate-border: rgba(255,255,255,0.08);
  --slate-border-soft: rgba(255,255,255,0.04);
  --slate-text: var(--text-primary);
  --slate-text-1: var(--text-primary);
  --slate-text-2: var(--text-muted);
  --slate-text-3: var(--text-dim);
  /* #52525b was 2.44:1 — WCAG 1.4.3 AA fail (FIX 2026-07-18 → #83838d, 5.0:1).
     FIX 2026-07-23: still read as dim gray; brightened to 6.9:1 with the rest
     of the muted ramp. Stays the lowest rung, below --text-dim. */
  --slate-text-4: #9c9ca6;
  --slate-green: var(--accent);
  --slate-green-bright: var(--accent-blue-light);
  --slate-blue: #60a5fa;
  --slate-amber: var(--accent-amber);
  --slate-red: var(--accent-red);
  --slate-accent: var(--accent);
  --slate-mono: var(--font-mono);
}

/* ===== Slate redesign — Tier 1 Hero Strip ===== */
.slate-hero-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 28px;
}
.hc-mini {
  background: var(--slate-bg-card);
  border: 1px solid var(--slate-border);
  border-radius: 10px;
  overflow: hidden;
  position: relative;
  cursor: pointer;
  transition: transform 0.15s, border 0.15s;
}
.hc-mini:hover {
  transform: translateY(-2px);
  border-color: rgba(16,185,129,0.4);
}
.hc-mini::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--slate-green), var(--slate-green-bright));
}
.hc-mini.lock::before { background: linear-gradient(90deg, #3b82f6, var(--slate-blue)); }
.hc-mini.lean::before { background: linear-gradient(90deg, var(--slate-amber), #fbbf24); }

.hc-mini-h { padding: 11px 14px 9px; position: relative; }
.hc-mini-rank {
  font-family: var(--slate-mono); font-size: 12px; color: var(--slate-text-3);
  letter-spacing: 0.16em; font-weight: 700; text-transform: uppercase;
}
.hc-mini-pick { font-size: 15px; font-weight: 800; color: var(--slate-text); margin-top: 4px; line-height: 1.2; }
.hc-mini-ctx { font-size: 12px; color: var(--slate-text-3); font-family: var(--slate-mono); margin-top: 3px; }
.hc-mini-grade {
  position: absolute; top: 11px; right: 14px;
  padding: 2px 8px; border-radius: 999px;
  font-family: var(--slate-mono); font-weight: 800; font-size: 12px;
  letter-spacing: 0.06em;
  background: rgba(16,185,129,0.12); color: var(--slate-green);
  border: 1px solid rgba(16,185,129,0.4);
}
.hc-mini-grade.lock { background: rgba(59,130,246,0.12); color: var(--slate-blue); border-color: rgba(59,130,246,0.4); }
.hc-mini-grade.lean { background: rgba(245,158,11,0.12); color: var(--slate-amber); border-color: rgba(245,158,11,0.4); }

.hc-mini-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
  background: var(--slate-border-soft);
}
.hc-mini-cell { background: var(--slate-bg); padding: 10px 4px 9px; text-align: center; }
.hc-mini-cell-l {
  font-size: 12px; color: var(--slate-text-3); text-transform: uppercase;
  letter-spacing: 0.12em; font-weight: 700;
}
.hc-mini-cell-v {
  font-family: var(--slate-mono); font-size: 15px; font-weight: 800;
  color: var(--slate-text); margin-top: 4px; line-height: 1;
}
.hc-mini-cell-v.accent { color: var(--slate-green); }
.hc-mini-cell-v.lock { color: var(--slate-blue); }
/* FIX 2026-08-01: multi-word books wrapped to two lines once the hero started
   naming the CHOSEN market's book ("Hard Rock Bet", not the moneyline's
   "BetOnline"), which made that cell taller than its three siblings and
   desynced the 4-cell grid's baselines. One line, ellipsis past the cell. */
.hc-mini-cell-v.book {
  font-family: 'IBM Plex Sans', sans-serif; font-size: 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.hc-mini-foot {
  padding: 8px 14px; border-top: 1px solid var(--slate-border-soft);
  display: flex; align-items: center; justify-content: space-between;
}
.hc-mini-meta { font-size: 12px; color: var(--slate-text-2); font-family: var(--slate-mono); }
.hc-mini-cta {
  background: var(--slate-green); color: var(--slate-bg);
  border: none; padding: 4px 10px; border-radius: 4px;
  font-weight: 800; font-size: 12px; cursor: pointer;
}

/* ===== Slate redesign — Tier 2 Filterable Board ===== */
.slate-section-h {
  display: flex; align-items: baseline; justify-content: space-between;
  margin: 0 0 12px;
}
.slate-section-title {
  font-size: 13px; color: var(--slate-text); text-transform: uppercase;
  letter-spacing: 0.18em; font-weight: 700;
}
.slate-section-meta { font-size: 12px; color: var(--slate-text-4); font-family: var(--slate-mono); }

.slate-filter-bar {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 4px; padding: 6px 0;
  border-bottom: 1px solid var(--slate-border-soft);
}
.slate-filter-tabs { display: flex; gap: 4px; }
.slate-filter-tab {
  padding: 5px 11px; border-radius: 5px;
  font-family: var(--slate-mono); font-size: 12px;
  color: var(--slate-text-3); cursor: pointer; font-weight: 600;
  background: transparent; border: none;
}
.slate-filter-tab.active { background: rgba(16,185,129,0.1); color: var(--slate-green); }

.slate-board-head {
  display: grid;
  grid-template-columns: 56px 1fr 130px 96px 88px 80px 56px;
  gap: 12px; padding: 10px 12px;
  font-family: var(--slate-mono); font-size: 12px;
  color: var(--slate-text-3); text-transform: uppercase;
  letter-spacing: 0.14em; font-weight: 700;
  border-bottom: 1px solid var(--slate-border-soft);
}
.slate-row {
  display: grid;
  grid-template-columns: 56px 1fr 130px 96px 88px 80px 56px;
  gap: 12px; padding: 12px; align-items: center;
  border-bottom: 1px solid var(--slate-border-soft);
  cursor: pointer; transition: background 0.12s;
}
.slate-row:hover { background: var(--slate-bg-hover); }
.slate-row-sport {
  font-family: var(--slate-mono); font-size: 12px;
  color: var(--slate-text-3); font-weight: 700;
  padding: 4px 6px; background: rgba(255,255,255,0.04);
  border-radius: 4px; text-align: center; letter-spacing: 0.06em;
}
.slate-row-game { font-size: 14px; color: var(--slate-text); font-weight: 700; line-height: 1.3; }
.slate-row-time { font-family: var(--slate-mono); font-size: 12px; color: var(--slate-text-3); margin-top: 2px; }
.slate-row-pick { font-size: 13px; color: var(--slate-text); font-weight: 600; }
.slate-row-pick-label {
  font-family: var(--slate-mono); font-size: 12px;
  color: var(--slate-text-3); letter-spacing: 0.1em;
  text-transform: uppercase; margin-bottom: 2px;
}
.slate-row-price { font-family: var(--slate-mono); font-size: 14px; color: var(--slate-text); font-weight: 800; }
.slate-row-book { font-family: var(--slate-mono); font-size: 12px; color: var(--slate-text-3); margin-top: 2px; }
.slate-row-conf {
  font-family: var(--slate-mono); font-size: 13px;
  color: var(--slate-text-2); font-weight: 700; text-align: center;
}
.slate-row-conf-bar {
  width: 50px; height: 3px; background: var(--slate-border);
  border-radius: 2px; margin: 4px auto 0; overflow: hidden;
}
.slate-row-conf-bar-fill { height: 100%; background: var(--slate-blue); }

.slate-edge-chip {
  padding: 4px 8px; border-radius: 4px;
  font-family: var(--slate-mono); font-size: 12px;
  font-weight: 800; text-align: center;
}
.slate-edge-chip.pos {
  background: rgba(16,185,129,0.12);
  color: var(--slate-green);
  border: 1px solid rgba(16,185,129,0.3);
}
.slate-edge-chip.zero {
  color: var(--slate-text-4); font-weight: 600;
  border: 1px dashed var(--slate-border);
}
/* FIX 2026-07-20: a real edge on a pick the pipeline did NOT recommend is
   muted, not green. Green is reserved for BET/LEAN/LOCK — it means "we
   recommend this", not "this number is positive". */
.slate-edge-chip.muted {
  background: transparent;
  color: var(--slate-text-3);
  border: 1px solid var(--slate-border);
  font-weight: 700;
}
/* The pipeline's sizing grade, rendered INSIDE the EV chip (stacked above the
   number) so the verdict and the number are never separated — and so the row's
   child count is unchanged, which the positional phone selectors depend on. */
.slate-grade-chip {
  display: block;
  font-size: 12px; font-weight: 800;
  letter-spacing: 0.04em; line-height: 1.25;
  white-space: nowrap;
}
.slate-grade-chip.actionable { color: var(--slate-green); }
.slate-grade-chip.muted { color: var(--slate-text-3); }
.slate-row-add {
  background: transparent; color: var(--slate-text-3);
  border: 1px solid var(--slate-border);
  padding: 5px 0; border-radius: 4px;
  cursor: pointer; font-size: 15px; font-weight: 700;
  font-family: var(--slate-mono);
}
.slate-row-add:hover { border-color: var(--slate-green); color: var(--slate-green); }

/* Phase B Sprint 4 #1: share-chip → /pick/{id} permalink.
   Slate row grid only allocates space when the chip renders; absence
   leaves the row visually unchanged. */
.slate-row-share {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  border: 1px solid var(--slate-border); border-radius: 4px;
  text-decoration: none; color: var(--slate-text-3);
  font-size: 15px; font-weight: 700;
  background: transparent;
}
.slate-row-share:hover {
  border-color: var(--slate-blue, #1f6feb);
  color: var(--slate-blue, #1f6feb);
}

/* Phase B Sprint 4 #5: watchlist star toggle. Same dimensions as the
   share chip so the row grid stays tidy. Two states: off (☆ gray) and
   on (★ amber). */
.slate-row-star {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  background: transparent;
  border: 1px solid var(--slate-border);
  border-radius: 4px;
  color: var(--slate-text-3);
  font-size: 16px; font-weight: 700; line-height: 1;
  cursor: pointer;
  padding: 0;
}
.slate-row-star:hover {
  border-color: var(--accent-amber);
  color: var(--accent-amber);
}
/* FIX 2026-07-12 (Batch 2): active star was a light #fff8e1 box on the dark UI. */
.slate-row-star.on {
  background: var(--accent-amber-bg);
  border-color: var(--accent-amber);
  color: var(--accent-amber);
}

/* Multi-book summary surfaced on mobile row at <640px only.
   Hidden on desktop (drilldown carries the full line-shopping table). */
.slate-row-multibook {
  display: none;
  font-family: var(--slate-mono); font-size: 12px;
  color: var(--slate-text-3); letter-spacing: 0.04em;
}

/* ===== Slate redesign — Tier 3 Live Strip ===== */
.slate-live-strip { margin-top: 28px; }
.slate-live-row {
  display: grid;
  grid-template-columns: 56px 1fr 110px 90px 76px;
  gap: 12px; padding: 10px 12px; align-items: center;
  border-bottom: 1px solid var(--slate-border-soft);
  background: rgba(239,68,68,0.02);
}
.slate-live-status {
  font-family: var(--slate-mono); font-size: 12px;
  color: var(--slate-red); font-weight: 800;
  letter-spacing: 0.06em; margin-top: 2px;
}
.slate-live-score { font-family: var(--slate-mono); font-size: 12px; color: var(--slate-text-2); }
.slate-live-dot {
  display: inline-block; width: 6px; height: 6px;
  background: var(--slate-red); border-radius: 50%;
  animation: slate-pulse 2s infinite; margin-right: 6px;
  vertical-align: middle;
}
@keyframes slate-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* ===== Slate redesign — Drilldown takeover ===== */
.slate-drilldown[hidden] { display: none; }

.slate-takeover-h {
  padding: 16px 24px;
  border-bottom: 1px solid var(--slate-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  background: var(--slate-bg-card);
  border-radius: 12px 12px 0 0;
}
.slate-takeover-back {
  background: transparent;
  color: var(--slate-text-3);
  border: 1px solid var(--slate-border);
  padding: 6px 11px;
  border-radius: 5px;
  font-size: 12px;
  cursor: pointer;
  font-family: var(--slate-mono);
}
.slate-takeover-back:hover { border-color: var(--slate-green); color: var(--slate-green); }

.slate-takeover-title-block { flex: 1; text-align: center; }
.slate-takeover-title { font-size: 18px; font-weight: 800; color: var(--slate-text); line-height: 1.2; }
.slate-takeover-title-ctx {
  font-size: 12px; color: var(--slate-text-3);
  font-family: var(--slate-mono); margin-top: 4px;
}

.slate-takeover-actions { display: flex; gap: 8px; }
.slate-takeover-action {
  background: transparent; border: 1px solid var(--slate-border);
  color: var(--slate-text-2); padding: 7px 13px; border-radius: 5px;
  font-size: 12px; cursor: pointer; font-weight: 700;
  font-family: var(--slate-mono);
}
.slate-takeover-action:hover { border-color: var(--slate-text-2); color: var(--slate-text); }
.slate-takeover-add {
  background: var(--slate-green); color: var(--slate-bg);
  border-color: var(--slate-green);
}
.slate-takeover-add:hover { background: #059669; border-color: #059669; }

/* Summary mosaic (4-cell, scaled larger than hero card) */
.slate-takeover-summary {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--slate-border-soft);
  border-bottom: 1px solid var(--slate-border);
}
.slate-ts-cell {
  background: var(--slate-bg);
  padding: 18px 12px;
  text-align: center;
  cursor: default;
}
.slate-ts-cell-l {
  font-size: 12px; color: var(--slate-text-3);
  text-transform: uppercase; letter-spacing: 0.14em; font-weight: 700;
}
.slate-ts-cell-v {
  font-family: var(--slate-mono);
  font-size: 28px; font-weight: 800;
  color: var(--slate-text);
  margin-top: 8px; line-height: 1;
}
.slate-ts-cell-v.accent { color: var(--slate-green); }
.slate-ts-cell-v.lock { color: var(--slate-blue); }
.slate-ts-cell-v.book {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 16px;
}
.slate-ts-cell-sub {
  font-size: 12px; color: var(--slate-text-4);
  margin-top: 6px; font-family: var(--slate-mono);
}

/* Narrative blocks */
.slate-takeover-body {
  padding: 24px;
  display: grid;
  /* FIX 2026-07-24: bare 1fr sizes the track to the widest child's
     min-content (grid items default min-width:auto) — one wide child
     (props rows, line-shopping table) stretched EVERY drilldown panel to
     ~469px at a 390px viewport, pushing the Signal Stack weight column
     off-screen. minmax(0, 1fr) pins the track to the container width so
     each panel's own overflow-x:auto container handles its excess. */
  grid-template-columns: minmax(0, 1fr);
  gap: 18px;
}
.slate-narr-block {
  background: var(--slate-bg-card);
  border: 1px solid var(--slate-border);
  border-radius: 10px;
  padding: 18px 20px;
}
.slate-narr-h {
  font-size: 12px; color: var(--slate-text-3);
  text-transform: uppercase; letter-spacing: 0.16em;
  font-weight: 700; margin-bottom: 12px;
}
.slate-narr-body {
  color: var(--slate-text-2);
  font-size: 14px; line-height: 1.7;
}
.slate-narr-body p { margin: 0; }
.slate-narr-body p + p { margin-top: 10px; }
.slate-narr-body strong { color: var(--slate-text); }
.slate-narr-body code {
  background: rgba(255,255,255,0.06);
  padding: 1px 5px; border-radius: 3px;
  color: var(--slate-green);
  font-family: var(--slate-mono); font-size: 12px;
}
.slate-narr-math {
  font-family: var(--slate-mono);
  background: rgba(255,255,255,0.04);
  padding: 12px 14px; border-radius: 6px;
  font-size: 13px; line-height: 1.7;
  margin: 10px 0;
}
.slate-narr-math .accent { color: var(--slate-green); }

/* Line shopping table */
.slate-ls-table { width: 100%; border-collapse: collapse; }
.slate-ls-table th {
  font-family: var(--slate-mono);
  font-size: 12px; color: var(--slate-text-3);
  text-transform: uppercase; letter-spacing: 0.12em;
  font-weight: 700; padding: 8px 10px; text-align: left;
  border-bottom: 1px solid var(--slate-border);
}
.slate-ls-table td {
  padding: 10px; border-bottom: 1px solid var(--slate-border-soft);
  font-size: 13px; color: var(--slate-text);
}
.slate-ls-table tr.best { background: rgba(16,185,129,0.04); }
.slate-ls-table tr.best td { color: var(--slate-green); font-weight: 700; }
.slate-ls-price { font-family: var(--slate-mono); font-weight: 700; }

/* Reduced-juice EV display (NFL sprint W1 / spec M3 — 2026-05-10).
   "Juice" column shows implied-prob delta vs the sharpest book on the
   slate. Sharp users key on this number to choose where to bet. */
.slate-ls-juice {
  font-family: var(--slate-mono); font-size: 0.92em; font-weight: 600;
}
.slate-ls-juice--sharp {
  color: var(--slate-green); font-style: italic;
}
.slate-ls-juice--bad {
  /* Paying extra juice — warn-ish color but not alarming */
  color: var(--slate-warn, #c97a00);
}
.slate-ls-juice--good {
  /* Rare: book is sharper than the "sharpest" (outlier) */
  color: var(--slate-green);
}

/* Game props row (placeholder shape — Phase 2.5 fills the data) */
.slate-prop-row {
  display: grid;
  grid-template-columns: 1fr 90px 90px 80px 56px;
  gap: 10px; padding: 10px 12px; align-items: center;
  border-bottom: 1px solid var(--slate-border-soft);
}
.slate-prop-row:last-child { border-bottom: none; }
.slate-prop-name { font-size: 13px; color: var(--slate-text); font-weight: 600; }
.slate-prop-line {
  font-family: var(--slate-mono); font-size: 13px;
  color: var(--slate-text-2);
}

/* Phase 2.5 placeholder (shown for line-shopping and props blocks
   until enriched data is wired) */
.slate-coming-soon {
  padding: 32px 16px;
  text-align: center;
  color: var(--slate-text-3);
  font-size: 14px;
  font-family: var(--slate-mono);
  background: rgba(255,255,255,0.02);
  border: 1px dashed var(--slate-border);
  border-radius: 8px;
}
.slate-coming-soon strong { color: var(--slate-text-2); }

/* ===== Slate redesign — Parlay Cart (Phase 3) ===== */

/* The rail is a slide-in drawer at all viewport widths, hidden by default
   and toggled open via the top-nav "Parlay Builder" button.
   FIX 2026-05-09: was permanently visible at >=1024px and stole 352px of
   horizontal real estate from the slate; now only appears on demand. */
.parlay-rail {
  position: fixed;
  top: 72px;            /* below the top nav bar (~56px header + 16px gap) */
  right: 16px;
  width: 320px;
  max-height: calc(100vh - 88px);
  overflow-y: auto;
  background: var(--slate-bg-card);
  border: 1px solid var(--slate-border);
  border-radius: 12px;
  padding: 18px;
  font-family: 'IBM Plex Sans', sans-serif;
  z-index: 50;
  /* Closed state: slid off-screen to the right */
  transform: translateX(calc(100% + 24px));
  transition: transform 0.25s ease-out;
}
.parlay-rail.parlay-rail--open {
  transform: translateX(0);
}

.parlay-rail-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.parlay-rail-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-weight: 800;
  color: var(--slate-text);
}
.parlay-rail-count {
  font-family: var(--slate-mono);
  font-size: 12px;
  color: var(--slate-text-3);
  padding: 2px 7px;
  background: rgba(255,255,255,0.04);
  border-radius: 999px;
}

/* Empty state */
.parlay-empty {
  padding: 24px 12px;
  text-align: center;
  background: rgba(255,255,255,0.02);
  border: 1px dashed var(--slate-border);
  border-radius: 8px;
  font-size: 12px;
  color: var(--slate-text-3);
  line-height: 1.6;
}

/* Leg cards */
.parlay-leg {
  /* Declared, not inherited from whatever else claims this class name.
     main.css:857 used to style .parlay-leg unscoped for the floating parlay
     SLIP; `display` was the one property it declared and slate.css did not,
     so the slip's flex row laid out this card and pushed .parlay-leg-meta
     under the corner button. main.css is scoped to .parlay-slip now, and
     this line makes the cart's layout its own statement rather than a
     default that a future collision can take over again.
     Stacked: pick on its own line, .parlay-leg-meta below it. */
  display: block;
  background: var(--slate-bg);
  border: 1px solid var(--slate-border);
  border-radius: 7px;
  padding: 10px 11px;
  /* Gutter for the absolutely-positioned .parlay-leg-x below: 6px offset +
     28px button + 2px clearance. Without it the button sits on top of
     .parlay-leg-meta — measured at 1024px AND 1440px, an overlap of 13.8px
     on every leg with the button winning the hit test over the price, so a
     click beside the odds removed the leg. The phone block at the end of
     this file widens both to 44/46px. */
  padding-right: 36px;
  margin-bottom: 6px;
  position: relative;
}
.parlay-leg-x {
  position: absolute;
  top: 6px;
  right: 6px;
  /* A declared box, not a glyph-sized one: it was 18.8x15, which is both
     under the 24px AA target floor and impossible for the card to reserve a
     matching gutter against. 28px matches .slate-row-star, the desktop
     convention elsewhere on the board. */
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--slate-text-4);
  cursor: pointer;
  font-size: 15px;
  padding: 0;
  border-radius: 3px;
  line-height: 1;
  background: transparent;
  border: none;
}
.parlay-leg-x:hover { color: var(--slate-red); background: rgba(239,68,68,0.06); }
.parlay-leg-pick {
  font-size: 13px;
  font-weight: 700;
  color: var(--slate-text);
  padding-right: 18px;
  line-height: 1.3;
}
.parlay-leg-meta {
  font-family: var(--slate-mono);
  font-size: 12px;
  color: var(--slate-text-3);
  margin-top: 5px;
  display: flex;
  justify-content: space-between;
}
.parlay-leg-meta strong { color: var(--slate-text-2); }

/* Summary block */
.parlay-summary {
  background: rgba(16,185,129,0.06);
  border: 1px solid rgba(16,185,129,0.25);
  border-radius: 8px;
  padding: 11px 12px;
  margin: 12px 0 10px;
}
.parlay-summary-row {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--slate-text-2);
  margin-bottom: 5px;
}
.parlay-summary-row.big {
  font-size: 15px;
  font-weight: 800;
  color: var(--slate-text);
  margin-bottom: 0;
  padding-top: 7px;
  border-top: 1px solid rgba(16,185,129,0.18);
}
.parlay-summary-row strong { color: var(--slate-green); font-family: var(--slate-mono); }
.parlay-summary-row.neg strong { color: var(--slate-red); }
/* Grade-gated: a positive combined EV on a parlay with a non-recommended leg
   must NOT read green — dim it so it doesn't look like a model pick. */
.parlay-summary-row.muted strong { color: var(--slate-text-2); }
.parlay-summary-note {
  font-size: 12px;
  line-height: 1.35;
  color: var(--accent-amber, #e8a40f);
  margin-top: 6px;
}

/* Stake input */
.parlay-stake-input {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--slate-border);
  color: var(--slate-text);
  font-family: var(--slate-mono);
  font-size: 13px;
  font-weight: 700;
  padding: 3px 6px;
  border-radius: 4px;
  width: 70px;
  text-align: right;
}
.parlay-stake-input:focus {
  outline: none;
  border-color: var(--slate-green);
}

/* Build & Take CTA */
.parlay-cta {
  width: 100%;
  background: var(--slate-green);
  color: var(--slate-bg);
  border: none;
  padding: 11px;
  border-radius: 7px;
  font-weight: 800;
  font-size: 14px;
  cursor: pointer;
}
.parlay-cta:hover { background: #059669; }
.parlay-cta:disabled {
  background: rgba(255,255,255,0.06);
  color: var(--slate-text-3);
  cursor: not-allowed;
}

/* Helper text */
.parlay-helper {
  font-size: 12px;
  color: var(--slate-text-4);
  margin-top: 14px;
  line-height: 1.55;
  font-family: var(--slate-mono);
  text-align: center;
}

/* FIX 2026-05-09: removed the desktop right-padding reservation. The rail
   is now a slide-in drawer (closed by default) at all viewport widths,
   so .main-content reclaims the full screen width. */

/* Phase 4 — bottom-anchored drawer at <1024px, integrated with the
   existing bottom-nav Parlay tab. Hidden by default (translateY off-screen);
   .parlay-rail--open class slides it up. */
@media (max-width: 1023px) {
  .parlay-rail {
    /* Override Phase 3's fixed-position desktop rail */
    position: fixed;
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    width: auto;
    max-width: 100vw;
    max-height: 75vh;
    border-radius: 16px 16px 0 0;
    border-bottom: none;
    transform: translateY(100%);
    transition: transform 0.25s ease-out;
    box-shadow: 0 -8px 24px rgba(0,0,0,0.4);
    /* Account for the bottom-nav height (~56px) so the drawer doesn't
       hide under it. The bottom-nav-padding env safe-area-inset is
       inherited from the V1 mobile foundations. */
    padding-bottom: calc(72px + env(safe-area-inset-bottom));
    z-index: 110;  /* above bottom-nav (main.css:73 sets nav z-index: 100) */
  }
  .parlay-rail.parlay-rail--open {
    transform: translateY(0);
  }
  /* Phase 4 does NOT add right-padding on .main-content for mobile —
     the drawer slides over content instead of pushing it. */
}

/* Backdrop when drawer is open — tap-to-close affordance */
.parlay-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.4);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease-out;
  z-index: 105;
}
/* Backdrop only goes opaque/active on mobile (modal drawer pattern).
   At desktop the drawer is non-modal — slate behind stays interactive. */
@media (max-width: 1023px) {
  .parlay-backdrop.parlay-backdrop--open {
    opacity: 1;
    pointer-events: auto;
  }
}

/* Cart count badge on the bottom-nav Parlay tab */
.bn-badge {
  position: absolute;
  top: 4px;
  right: calc(50% - 18px);
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  background: var(--slate-green);
  color: var(--slate-bg);
  border-radius: 999px;
  font-family: var(--slate-mono);
  font-size: 12px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
.bn-badge[hidden] { display: none; }

/* Ensure the bottom-nav button is the badge's positioning anchor.
   (V1 mobile work added .bottom-nav-item but may not have set
    position: relative; safe to set unconditionally — won't change
    layout, only enables abs-positioned children.) */
.bottom-nav-item { position: relative; }

/* ===== Slate redesign — Phase 4 Mobile Reflow ===== */

/* Tier 1 hero strip: 3-col grid → vertical stack on <640px */
@media (max-width: 639px) {
  .slate-hero-strip {
    grid-template-columns: 1fr;
    gap: 10px;
    margin-bottom: 20px;
  }
  .hc-mini-pick { font-size: 14px; }
  .hc-mini-cell { padding: 9px 4px 8px; }
  .hc-mini-cell-v { font-size: 14px; }
  .hc-mini-cell-v.book { font-size: 12px; }
}

/* Tier 2 slate row — the SINGLE phone layout (<640px).
   FIX 2026-07-12 (Batch 2 follow-up): two overlapping phone blocks used to
   fight here — this one ("Phase 4": 3-col grid-template-areas card) and a
   later "Wave 3 #15" 4-col compact block (~L1131, now deleted). Both applied
   at phone widths: the later block overrode grid-template-columns (4 tracks)
   but NOT grid-template-areas (3 named columns), so the matchup cell rendered
   in a 70px track while the 131px 1fr track held only the pick, the 36px 4th
   track was orphaned, and the share/star chips auto-placed arbitrarily.
   Reproduced live on prod v415 (matchup w=70px) before this consolidation.
   Single layout now:
     matchup(1fr)  edge(84px)   star(44px)
     pick          price        add
   Hidden on phone (all carried by the tap-to-drilldown): column header,
   sport chip, confidence, multibook summary, share chip. */
@media (max-width: 639px) {
  .slate-board-head { display: none; }  /* Column headers don't fit; row content is self-labeled */

  .slate-row {
    grid-template-columns: 1fr 84px 44px;
    grid-template-areas:
      "matchup edge  star"
      "pick    price add";
    gap: 6px 8px;
    padding: 10px 8px;
  }
  .slate-row > .slate-row-sport { display: none; }  /* sport → drilldown */
  .slate-row > div:nth-child(2) { grid-area: matchup; }
  .slate-row > div:nth-child(3) { grid-area: pick; }
  .slate-row > div:nth-child(4) { grid-area: price; justify-self: end; text-align: right; }
  .slate-row > .slate-row-conf,
  .slate-row > div:has(.slate-row-conf) { display: none; }  /* conf → drilldown */
  .slate-row > .slate-edge-chip { grid-area: edge; justify-self: end; align-self: start; }
  .slate-row > .slate-row-share { display: none; }  /* drilldown has a Share action */
  /* WCAG 2.5.5 touch targets: the row's 3rd grid column is already 44px, so
     size the ☆/+ controls to fill it. FIX 2026-07-18: were 28px (star) / 36px
     (add) — Fitts's-law misfires one-handed, and unreliable for motor-impaired
     users (see accessibility-audit skill). */
  .slate-row > .slate-row-star  {
    grid-area: star; justify-self: end; align-self: start;
    min-width: 44px; min-height: 44px;
  }
  .slate-row > .slate-row-add   {
    grid-area: add; justify-self: end; align-self: end;
    min-width: 44px; min-height: 44px; font-size: 16px; padding: 0;
  }
  .slate-row > .slate-row-multibook { display: none; }  /* drilldown line-shopping */

  .slate-row-game { font-size: 14px; }
  .slate-row-time { font-size: 12px; }
  .slate-row-pick { font-size: 13px; }
  .slate-row-price { font-size: 14px; }
  .slate-row-pick-label { font-size: 12px; }
  .slate-row-book { font-size: 12px; }

  /* Drilldown prop rows: 5-col → 2-row card, same collapse as .slate-row
     above. FIX 2026-07-25: the desktop grid (1fr 90px 90px 80px 56px, gap
     10, padding 12) needs 380px of fixed width before the 1fr, and sits in
     a ~270px container inside the drilldown — so .slate-row-add rendered at
     x=467 against a 375px client width and pushed 107px of HORIZONTAL PAGE
     SCROLL. Pre-dates the shell-scroll fix (02ede1e); .main-content's old
     overflow:hidden had been MASKING it, which meant the price, EV chip and
     "+" add-to-parlay button were silently cut off and unreachable on
     phones — the same failure main.css:1718 documents for game cards.
     Guarded by tests/test_slate_prop_row_mobile.py. */
  .slate-prop-row {
    grid-template-columns: 1fr 84px 44px;
    grid-template-areas:
      "name edge  add"
      "line price add";
    gap: 4px 8px;
    padding: 10px 8px;
  }
  .slate-prop-row > .slate-prop-name { grid-area: name; }
  .slate-prop-row > .slate-prop-line { grid-area: line; }
  .slate-prop-row > .slate-ls-price  { grid-area: price; justify-self: end; }
  .slate-prop-row > .slate-edge-chip { grid-area: edge; justify-self: end; }
  /* WCAG 2.5.5 — the desktop column was 56px; keep a real target here. */
  .slate-prop-row > .slate-row-add {
    grid-area: add; justify-self: end; align-self: center;
    min-width: 44px; min-height: 44px; font-size: 16px; padding: 0;
  }
}

/* Tier 3 live row: 5-col → 2-row card on <640px */
@media (max-width: 639px) {
  .slate-live-row {
    grid-template-columns: 56px 1fr 76px;
    grid-template-areas:
      "sport matchup edge"
      "pick  score   .";
    row-gap: 8px;
    padding: 10px 10px;
  }
  .slate-live-row > .slate-row-sport  { grid-area: sport; }
  .slate-live-row > div:nth-child(2)  { grid-area: matchup; }
  .slate-live-row > .slate-row-pick   { grid-area: pick; font-size: 13px; }
  .slate-live-row > .slate-live-score { grid-area: score; font-size: 12px; }
  .slate-live-row > .slate-edge-chip  { grid-area: edge; justify-self: end; align-self: start; }
}

/* Drilldown takeover mobile reflow at <640px */
@media (max-width: 639px) {
  /* Header: stack title above actions; back button stays full-width on its row */
  .slate-takeover-h {
    flex-wrap: wrap;
    padding: 12px 14px;
    gap: 10px;
  }
  /* FIX 2026-08-11 (Slate mobile review): both of these were SHRUNK here — to
     ~26px (12px font + 5px padding + 1px border) — and nothing bumped them
     back. .slate-takeover-back is the way OUT of the drilldown, the primary
     back-navigation on a phone. .slate-takeover-action only regained 44px in
     the max-width:539px block below, so 540-639px shipped the compact size.
     Keep the compact type (the header has to fit); buy the height with
     padding instead. Guarded by tests/test_slate_touch_targets.py. */
  .slate-takeover-back {
    flex: 0 0 auto; font-size: 12px; padding: 5px 9px;
    min-height: 44px; display: inline-flex; align-items: center;
  }
  .slate-takeover-title-block { flex: 1 1 100%; order: 3; text-align: left; }
  .slate-takeover-title { font-size: 16px; }
  .slate-takeover-title-ctx { font-size: 12px; }
  .slate-takeover-actions { flex: 0 0 auto; gap: 6px; }
  .slate-takeover-action {
    font-size: 12px; padding: 5px 9px;
    min-height: 44px; display: inline-flex; align-items: center;
    justify-content: center;
  }

  /* Summary mosaic: 4-cell → 2x2 grid */
  .slate-takeover-summary {
    grid-template-columns: repeat(2, 1fr);
    padding: 0 14px;
  }
  .slate-ts-cell { padding: 14px 8px; }
  .slate-ts-cell-v { font-size: 22px; margin-top: 6px; }
  .slate-ts-cell-v.book { font-size: 15px; }
  .slate-ts-cell-sub { font-size: 12px; }

  /* Body padding tighter */
  .slate-takeover-body {
    padding: 16px 14px;
    gap: 14px;
  }
  .slate-narr-block { padding: 14px 14px; }
  .slate-narr-h { font-size: 12px; }
  .slate-narr-body { font-size: 13px; line-height: 1.6; }
  .slate-narr-math { font-size: 12px; padding: 10px 12px; }

  /* Line-shopping table: horizontal scroll wrapper so all 4 columns
     stay readable without column collapse logic.
     FIX 2026-05-14 per reviewer audit: the prior CSS set thead/tbody/tr
     to display:table width:100%, which UNDID the overflow-x scroll
     because the inner table reset back to 100% width. Removed that
     override — table now inherits the parent's natural sizing and
     horizontally scrolls when columns exceed viewport. */
  .slate-narr-block .slate-ls-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
    min-width: 100%;
  }
}

/* FIX 2026-07-12: the primary sort tabs (By edge / sport / time) were ~22px
   tall (padding 5px 11px, 11px font) — half the 44px minimum touch target and
   the most-used Slate interaction. Enforce a 44px hit area on phones. */
@media (max-width: 639px) {
  .slate-filter-tab {
    min-height: 44px;
    padding: 10px 14px;
    display: inline-flex;
    align-items: center;
  }
}

/* NFL post-Q1 in-play update block (Phase 6)
   FIX 2026-07-12 (Batch 2): was fully light-themed (#f7fbff gradient + dark
   ink) and rendered as a white box on the dark-only UI. Remapped to tokens. */
.slate-post-q1 {
  background: var(--bg-elevated);
  border-left: 4px solid var(--slate-blue);
  border-radius: 0 6px 6px 0;
  padding: 0.9rem 1.1rem;
  margin: 0.8rem 0;
}
.slate-post-q1-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
  font-size: 1rem;
}
.slate-post-q1-ts {
  color: var(--slate-text-3);
  font-size: 0.86rem;
  font-weight: normal;
}
.slate-post-q1-probs {
  display: flex;
  gap: 0.7rem;
  align-items: center;
  flex-wrap: wrap;
  font-size: 1.02rem;
  margin: 0.4rem 0;
}
.slate-post-q1-arrow {
  color: var(--slate-text-3);
  font-weight: bold;
}
.slate-post-q1-delta {
  font-weight: 700;
  padding: 0.15rem 0.55rem;
  border-radius: 10px;
  background: var(--bg-raised);
  font-size: 0.94rem;
}
.slate-post-q1-delta.good {
  background: var(--accent-green-bg);
  color: var(--accent-green);
}
.slate-post-q1-delta.bad {
  background: var(--accent-red-bg);
  color: var(--accent-red);
}
.slate-post-q1-state {
  font-family: -apple-system, monospace;
  font-size: 0.9rem;
  color: var(--slate-text-3);
  margin: 0.3rem 0;
}
.slate-post-q1-summary {
  font-size: 0.96rem;
  color: var(--slate-text-2);
  font-style: italic;
  margin-top: 0.3rem;
}

/* NFL lookahead-spot trap-game pill (Phase 5+ UI surfacing)
   FIX 2026-07-12 (Batch 2): light #fff8e1 card remapped to dark amber tokens. */
.slate-lookahead {
  background: var(--accent-amber-bg);
  border-left: 4px solid var(--accent-amber);
  border-radius: 0 6px 6px 0;
  padding: 0.7rem 1rem;
  margin: 0.8rem 0;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex-wrap: wrap;
}
.slate-lookahead-pill {
  background: var(--accent-amber);
  color: var(--bg-base);
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  padding: 0.25rem 0.65rem;
  border-radius: 12px;
  white-space: nowrap;
}
.slate-lookahead-body {
  font-size: 0.96rem;
  color: var(--slate-text-2);
  line-height: 1.4;
  flex: 1 1 180px;
  min-width: 0;
}

/* Drilldown action buttons at <540px: stack to 2-row grid so
   Share / Log bet / + Add to parlay don't crush against each other
   on narrow phones. Per 2026-05-14 reviewer audit S3. */
@media (max-width: 539px) {
  .slate-takeover-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    width: 100%;
    flex: 1 1 100%;
  }
  .slate-takeover-action {
    width: 100%;
    text-align: center;
    min-height: 44px;
    padding: 8px 6px;
    box-sizing: border-box;
  }
  /* Share is the first child — full-width row above the two primary actions */
  .slate-takeover-actions > :first-child {
    grid-column: 1 / -1;
  }
}

/* Signals fired audit trail — per-pick expandable in slate drilldown.
   Per 2026-05-14 reviewer audit: "Every other product shows EV +5.2%
   with no audit trail. CE has the data — surface it." */
/* FIX 2026-07-12 (Batch 2): whole block was light-themed (#f7f9fc card, dark
   ink, light borders) — white box on the dark UI. Remapped to tokens. */
.slate-signals-fired {
  background: var(--bg-elevated);
  border: 1px solid var(--slate-border);
  border-radius: 6px;
  padding: 0.75rem 1rem;
  margin: 0.8rem 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
.slate-signals-fired summary {
  cursor: pointer; font-size: 1rem; color: var(--slate-text);
  display: flex; justify-content: space-between; align-items: center;
  gap: 0.6rem;
}
.slate-signals-fired summary::-webkit-details-marker { display: none; }
.slate-signals-fired summary::before {
  content: '▸'; transition: transform 0.15s; color: var(--slate-text-3);
  font-size: 0.85em; margin-right: 0.3rem;
}
.slate-signals-fired[open] summary::before { transform: rotate(90deg); }
.sf-count { font-size: 0.88rem; color: var(--slate-text-3); font-weight: normal; }
.sf-body { margin-top: 0.6rem; }
.sf-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.4rem 0.8rem;
  padding: 0.55rem 0; border-bottom: 1px dashed var(--slate-border);
  font-size: 0.94rem;
}
.sf-row:last-child { border-bottom: none; }
.sf-row-name {
  color: var(--slate-blue); text-decoration: none; font-weight: 600;
}
.sf-row-name:hover { text-decoration: underline; }
.sf-row-mag {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-weight: 700; font-size: 0.92rem;
  align-self: start; white-space: nowrap;
}
.sf-row-mag.good { color: var(--accent-green); }
.sf-row-mag.bad { color: var(--accent-red); }
.sf-row-explain {
  grid-column: 1 / -1;
  color: var(--slate-text-3); font-size: 0.88rem;
  font-style: italic;
}
.sf-row-unavail { opacity: 0.5; }
.sf-unavail-details {
  margin-top: 0.5rem; padding-top: 0.5rem;
  border-top: 1px solid var(--slate-border);
}
.sf-unavail-details summary {
  font-size: 0.88rem; color: var(--slate-text-3); cursor: pointer;
}
.sf-footnote {
  font-size: 0.85rem; color: var(--slate-text-3);
  margin-top: 0.6rem; padding-top: 0.5rem;
  border-top: 1px solid var(--slate-border);
}
.sf-footnote a { color: var(--slate-blue); }

/* Phase B Sprint 4 #4+++: sign-in CTA strip on slate for unauthed
   visitors. Hidden by default; slate.js toggles visible when authed=false.
   Mirrors the /pick/{id} CTA banner styling. */
.slate-signin-cta {
  background: linear-gradient(135deg, #1f6feb 0%, #1556c5 100%);
  color: #fff; padding: 0.85rem 1.1rem; border-radius: 8px;
  margin: 0 0 1rem; display: flex; gap: 0.8rem;
  align-items: center; justify-content: space-between;
  flex-wrap: wrap; font-size: 0.96rem;
}
.slate-signin-cta strong { font-weight: 700; }
.slate-signin-cta-btn {
  background: #fff; color: #1f6feb; padding: 0.55rem 1.1rem;
  border-radius: 4px; text-decoration: none; font-weight: 700;
  min-height: 44px; display: inline-flex; align-items: center;
  flex-shrink: 0;
}
.slate-signin-cta-btn:hover { background: #f0f7ff; }

/* Phase B Sprint 5 #1: slate-level "lines as of HH:MM ET" header.
   Always visible (not toggled), small grayscale strip. Turns amber
   at 5min stale, red at 15min stale via .stale-warn / .stale-red. */
.slate-freshness {
  font-family: var(--slate-mono, ui-monospace, monospace);
  font-size: 0.85rem;
  color: var(--slate-text-3, #a3a3ad);
  padding: 0.35rem 0.05rem;
  margin: 0 0 0.45rem;
  display: flex; align-items: center; gap: 0.4rem;
  line-height: 1.3;
}
/* FIX 2026-07-12 (Batch 2): stale colors were dark-on-light ink (#a86c00,
   #9b1c1c) — near-invisible on the dark UI. Remapped to accent tokens. */
.slate-freshness::before {
  content: "●";
  font-size: 0.75rem;
  color: var(--accent-green);
  line-height: 1;
}
.slate-freshness.stale-warn { color: var(--accent-amber); }
.slate-freshness.stale-warn::before { color: var(--accent-amber); }
.slate-freshness.stale-red { color: var(--accent-red); font-weight: 600; }
.slate-freshness.stale-red::before { color: var(--accent-red); }

/* American / Decimal odds-format toggle — sits at the end of the freshness row.
   Colour stays neutral (it is a format control, not a recommendation signal). */
.odds-format-toggle {
  margin-left: auto;
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--slate-border, #30363d);
  border-radius: 6px;
  flex: none;
}
.odds-format-btn {
  font: inherit;
  font-size: 0.8rem;
  line-height: 1.4;
  min-height: 26px;
  padding: 3px 9px;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--slate-text-3, #a3a3ad);
  cursor: pointer;
}
.odds-format-btn.active {
  background: var(--slate-bg-2, rgba(255, 255, 255, 0.08));
  color: var(--slate-text, #e6edf3);
  font-weight: 600;
}
.odds-format-btn:hover:not(.active) { color: var(--slate-text-2, #c9d1d9); }
/* Touch targets: the compact 26px reads fine with a mouse but is a fat-finger
   miss on a phone — and a mis-tap here silently reformats EVERY price on the
   board. Bump to the 44px standard the 2026-07-18 a11y sweep adopted (WCAG
   2.5.5). Also let the freshness row wrap instead of crowding the timestamp:
   at 375px the text and toggle sat 6px apart, and a full "Lines as of 3:47 PM
   EDT · refreshed 12 min ago" string needs the room.
   Pinned by tests/test_slate_touch_targets.py. */
@media (max-width: 639px) {
  .slate-freshness { flex-wrap: wrap; row-gap: 0.35rem; }
  .odds-format-toggle { margin-left: 0; }
  .odds-format-btn {
    min-height: 44px;
    padding: 3px 14px;
  }
}

/* 2026-05-17 audit proposal — honest scorecard tile on /ui landing.
   Surfaces CLV credibility above the Best Bets hero so sharps see
   the metric that actually matters before they see any picks. */
.scorecard-tile {
  background: var(--slate-bg-card, #161b22);
  border: 1px solid var(--slate-border, #30363d);
  border-left: 3px solid var(--slate-accent, #1ddc7a);
  border-radius: 8px;
  padding: 0.9rem 1.1rem;
  margin: 0 0 0.8rem;
}
.scorecard-tile-h {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 0.6rem;
}
.scorecard-tile-label {
  font-family: var(--slate-mono, ui-monospace, monospace);
  font-size: 0.8rem; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--slate-accent, #1ddc7a);
}
.scorecard-tile-link {
  font-size: 0.88rem; font-weight: 600;
  color: var(--slate-text-2, #c9d1d9);
  text-decoration: none;
}
.scorecard-tile-link:hover { color: var(--slate-accent, #1ddc7a); }
.scorecard-tile-stats {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 0.8rem;
}
.scorecard-tile-stat {
  display: flex; flex-direction: column; gap: 0.15rem;
}
.scorecard-tile-stat-l {
  font-size: 0.8rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--slate-text-3, #8b949e);
}
.scorecard-tile-stat-v {
  font-family: var(--slate-mono, ui-monospace, monospace);
  font-size: 1.35rem; font-weight: 700;
  color: var(--slate-text-1, #e6edf3);
  line-height: 1.1;
}
.scorecard-tile-stat-v.pos { color: var(--ev-pos); }
.scorecard-tile-stat-v.neg { color: var(--ev-neg); }
.scorecard-tile-stat-x {
  font-size: 0.8rem;
  color: var(--slate-text-3, #8b949e);
}

/* 2026-08-06 per-market CLV rows. Four columns: market, CLV, beat%, graded N.
   Market column is flexible; the three numeric columns are fixed-ish so the
   figures line up down the table and the row does not reflow as values change
   width. */
.scorecard-markets {
  display: flex; flex-direction: column; gap: 0.35rem;
  margin: 0.25rem 0 0.5rem;
}
.scorecard-markets-head,
.scorecard-market-row {
  display: grid;
  grid-template-columns: minmax(5.5rem, 1fr) 5rem 4.5rem 3.5rem;
  gap: 0.6rem; align-items: baseline;
}
.scorecard-markets-head {
  /* 0.75rem = 12px, the type-scale floor (tests/test_type_scale_floor.py).
     Do not shave this to buy column width — use the short header labels. */
  font-size: 0.75rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--slate-text-3, #8b949e);
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--slate-border, #30363d);
}
.scorecard-markets-head span:not(:first-child),
.scorecard-market-row > .scorecard-market-v { text-align: right; }
/* Full header wording on wide viewports; the narrow forms swap in at 640px. */
.scorecard-markets-head .h-narrow { display: none; }
.scorecard-market-m {
  font-size: 0.9rem; font-weight: 600;
  color: var(--slate-text-2, #c9d1d9);
}
.scorecard-market-v {
  font-family: var(--slate-mono, ui-monospace, monospace);
  font-size: 1.05rem; font-weight: 700;
  color: var(--slate-text-1, #e6edf3);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.scorecard-market-v.pos { color: var(--ev-pos); }
.scorecard-market-v.neg { color: var(--ev-neg); }
.scorecard-markets-note {
  font-size: 0.75rem; line-height: 1.4;
  color: var(--slate-text-3, #8b949e);
  margin-bottom: 0.6rem;
}
.scorecard-markets-note[hidden] { display: none; }
/* 639, not 640: main.css:97 opens the tablet tier at min-width:640px, and the
   rest of the Slate's phone rules stop at 639. At exactly 640px this block used
   to reorder the page for mobile while the board stayed on its desktop
   7-column grid. Pinned by tests/test_slate_touch_targets.py. */
@media (max-width: 639px) {
  /* FIX 2026-08-06: the per-market table was invisible on a phone. Measured on
     prod at 375x812 the hero started at y=801, behind 670px of nav (56), main
     header (181), sign-in CTA (155) and the freshness block (278 — 34% of the
     fold, mostly out-of-season league timestamps).

     Reorder so the hero leads. Flex rather than a DOM move because the order
     must differ from desktop, and a DOM move would need JS on resize. Scoped
     entirely inside this media query — desktop order is untouched.

     NOTE: flex stops margin collapsing between these children. That was
     checked visually at 375 and at desktop; if spacing ever looks off here,
     that is the mechanism. */
  #view-premium { display: flex; flex-direction: column; }
  #view-premium > #proof-top-sentinel { order: 1; }
  #view-premium > #proof-hero        { order: 2; }
  #view-premium > .slate-tier-1      { order: 3; }
  #view-premium > #slate-signin-cta  { order: 4; }
  #view-premium > #slate-freshness   { order: 5; }
  #view-premium > *                  { order: 6; }

  /* NOTE: the active-day un-hide is NOT here. It has the same specificity as
     the rule it overrides (`.proof-hero.is-active #proof-full`, ~280 lines
     below), and a media query adds none — so it must come LATER in source
     order to win. It lives directly after that rule. */

  /* Freshness disclosure (see _renderFreshness). The summary carries the
     count inline so the qualification survives collapse; only the per-sport
     enumeration is behind the tap. Inherits the host's stale-warn colour. */
  #slate-freshness { flex-wrap: wrap; }
  #slate-freshness .fresh-detail { width: 100%; margin-top: 2px; }
  #slate-freshness .fresh-detail > summary {
    cursor: pointer; font-size: 0.75rem; color: inherit;
    /* FIX 2026-08-11 (Slate mobile review): was 24px. This disclosure is built
       ONLY on phones (_renderFreshness gates it behind matchMedia), so there is
       no desktop size to fall back to — 24px was the only size it ever had. */
    padding: 2px 0; min-height: 44px; display: list-item;
  }
  #slate-freshness .fresh-detail > div {
    font-size: 0.75rem; line-height: 1.4; padding-top: 2px;
    color: var(--slate-text-3, #8b949e);
  }

  .scorecard-tile-stats { grid-template-columns: 1fr 1fr 1fr; gap: 0.5rem; }
  .scorecard-tile-stat-v { font-size: 1.1rem; }
  .scorecard-tile-stat-l, .scorecard-tile-stat-x { font-size: 0.75rem; }

  /* Four numeric columns are tight at 375px. Narrow the fixed columns and the
     gap rather than wrapping: a wrapped row would break the visual alignment
     that makes the three markets comparable at a glance. Market labels
     abbreviate to ML / Spread / O/U in the renderer at this width. */
  .scorecard-markets-head,
  .scorecard-market-row {
    grid-template-columns: minmax(3.2rem, 1fr) 4.2rem 3.4rem 2.6rem;
    gap: 0.35rem;
  }
  .scorecard-market-v { font-size: 0.95rem; }
  .scorecard-market-m { font-size: 0.8rem; }
  /* Stays at the 12px floor on mobile too — the short labels above, not a
     smaller font, are what makes four columns fit at 375px. */
  .scorecard-markets-head { letter-spacing: 0.02em; }
  .scorecard-markets-head .h-wide { display: none; }
  .scorecard-markets-head .h-narrow { display: inline; }

  /* (Wave 3 #15's 4-col compact slate block was removed 2026-07-12 — it
     half-overrode the Phase 4 card layout above and crushed the matchup
     cell into a 70px track. The consolidated phone layout now lives in the
     single <640px block near L728.) */
}

/* Phase B Sprint 5 #6: per-row staleness chip — appears next to the
   book name on slate rows when the underlying line is ≥5min old. */
.slate-row-stale {
  display: inline-block;
  font-family: ui-monospace, monospace;
  font-size: 0.78rem; font-weight: 700;
  padding: 0.05rem 0.35rem;
  border-radius: 3px;
  letter-spacing: 0.04em;
  vertical-align: middle;
  margin-left: 0.3rem;
}
.slate-row-stale.stale-warn { background: var(--accent-amber-bg); color: var(--accent-amber); }
.slate-row-stale.stale-red  { background: var(--accent-red-bg); color: var(--accent-red); }

/* Wave 3 #11 Session 2.5: live in-play pill next to the slate-row pick.
   Renders only when /api/slate/picks supplies live_home_prob (NHL in v1). */
.slate-row-live-pill {
  display: inline-block;
  font-family: ui-monospace, monospace;
  font-size: 0.75rem; font-weight: 800;
  padding: 0.05rem 0.4rem;
  border-radius: 3px;
  letter-spacing: 0.06em;
  margin-left: 0.4rem;
  vertical-align: middle;
  background: rgba(139,148,158,0.18);
  color: var(--slate-text-2, #c9d1d9);
}
.slate-row-live-pill.pos {
  background: rgba(29,220,122,0.18);
  color: var(--slate-green, #1ddc7a);
}
.slate-row-live-pill.neg {
  background: rgba(248,81,73,0.18);
  color: var(--slate-red, #f85149);
}

/* Phase B Sprint 5 #7: inline opening→current sparkline next to price. */
.slate-row-sparkline {
  display: inline-block;
  vertical-align: middle;
  margin-left: 0.3rem;
  opacity: 0.85;
}

/* 2026-05-17 audit follow-up: white bg + giant blue button on a dark app
   was jarring and looked like a tout-style modal. Restyled as a quiet
   inline panel using the slate's own card vars so it sits flush with
   the surrounding dark theme. CTA demoted from button-brick to small
   accent-colored text link. */
.slate-empty-state {
  background: var(--slate-bg-card, #161b22);
  border: 1px dashed var(--slate-border, #30363d);
  border-radius: 8px;
  padding: 1.2rem 1.1rem;
  text-align: center;
  margin: 0.5rem 0;
}
.slate-empty-title {
  font-size: 1rem; font-weight: 600;
  color: var(--slate-text-1, #e6edf3);
  margin-bottom: 0.3rem;
}
.slate-empty-sub {
  font-size: 0.94rem; color: var(--slate-text-3, #8b949e);
  margin-bottom: 0.5rem; line-height: 1.45;
}
.slate-empty-clear {
  background: transparent; color: var(--slate-accent, #1ddc7a);
  border: none; padding: 0.3rem 0.4rem;
  font-size: 0.94rem; font-weight: 600;
  cursor: pointer; text-decoration: underline;
  text-underline-offset: 3px; min-height: 32px;
}
.slate-empty-clear:hover { color: var(--slate-green-bright); }

/* Phase B Sprint 5 #9: keyboard navigation focus ring + help overlay. */
.slate-row.kbd-focus {
  outline: 2px solid var(--slate-blue);
  outline-offset: -2px;
  background: rgba(96,165,250,0.10);
}
.slate-kbd-help {
  position: fixed; inset: 0;
  background: rgba(11, 18, 32, 0.45);
  display: none;
  align-items: center; justify-content: center;
  z-index: 200;
}
.slate-kbd-help-card {
  background: var(--bg-elevated); border: 1px solid var(--slate-border); border-radius: 8px;
  padding: 1.4rem 1.6rem;
  max-width: 420px; width: calc(100% - 2rem);
  box-shadow: 0 8px 28px rgba(0,0,0,0.18);
}
.slate-kbd-help-title {
  font-size: 1.1rem; font-weight: 700;
  margin-bottom: 0.8rem;
}
.slate-kbd-help-list {
  display: grid; grid-template-columns: 6rem 1fr;
  gap: 0.4rem 0.8rem;
  margin: 0 0 1rem; font-size: 1rem;
}
.slate-kbd-help-list dt {
  font-family: ui-monospace, monospace;
  font-weight: 700; color: var(--slate-text);
}
.slate-kbd-help-list dd {
  margin: 0; color: var(--slate-text-2);
}
.slate-kbd-help-close {
  background: #1f6feb; color: #fff;
  border: 1px solid #1f6feb;
  padding: 0.55rem 1.1rem; border-radius: 4px;
  font-size: 0.96rem; font-weight: 600;
  cursor: pointer; min-height: 44px;
}

/* Phase B Sprint 5 #12: dense-mode toggle for desktop power users.
   Shrinks vertical padding + line-heights so ~2x rows fit per scroll.
   Activated via the .dense-mode class on the slate board container. */
.slate-dense-toggle {
  display: inline-flex; align-items: center; gap: 0.35rem;
  background: transparent;
  border: 1px solid var(--slate-border);
  color: var(--slate-text-3);
  padding: 0.35rem 0.7rem; border-radius: 4px;
  cursor: pointer; font-size: 0.9rem; font-weight: 600;
  font-family: var(--slate-mono);
  min-height: 32px;
}
.slate-dense-toggle:hover {
  border-color: var(--slate-text-2);
  color: var(--slate-text);
}
.slate-dense-toggle.active {
  background: rgba(31, 111, 235, 0.12);
  border-color: var(--slate-blue);
  color: var(--slate-blue);
}
.slate-board.dense-mode .slate-row {
  padding: 5px 12px;
  gap: 8px;
}
.slate-board.dense-mode .slate-row-game { font-size: 13px; }
.slate-board.dense-mode .slate-row-time {
  display: inline-block; margin-top: 0; margin-left: 0.4rem;
}
.slate-board.dense-mode .slate-row-pick-label { display: none; }
.slate-board.dense-mode .slate-row-conf-bar { display: none; }
.slate-board.dense-mode .slate-row-multibook { display: none; }
.slate-board.dense-mode .slate-row-book {
  display: inline; margin-top: 0; margin-left: 0.3rem;
}

/* Phase B Sprint 5 #13: clickable column headers. */
.slate-board-th {
  cursor: pointer;
  user-select: none;
  padding: 0 0.15rem;
  border-radius: 3px;
  transition: color 0.12s;
}
.slate-board-th:hover { color: var(--slate-text); }
.slate-board-th.active { color: var(--slate-blue); font-weight: 700; }

/* Phase 1 soccer-three-way: Draw chance chip on soccer slate rows.
   Muted inline pill; cursor:help surfaces the tooltip explaining the data source.
   Returns '' for non-soccer rows via _renderDrawChip() no-op guard. */
.slate-draw-chip {
  display: inline-block;
  padding: 2px 8px;
  margin: 4px 0 0;
  font-size: 0.78em;
  color: var(--slate-text-3);
  background: var(--slate-border-soft);
  border-radius: 10px;
  font-weight: 500;
  cursor: help;
}

/* F5 row-expander cells — MLB First-5-Innings (Task 7 — 2026-05-23).
   Rendered by _renderF5Block(game) inside slate-takeover-body when
   game.sport==='mlb' and game.f5 is present. */
.slate-row-f5-section {
  border-top: 1px solid var(--border, #e0e0e0);
  margin-top: 8px;
  padding-top: 8px;
}
.slate-row-f5-label {
  font-size: 0.85em;
  font-weight: 600;
  color: var(--slate-text-3);
  margin-bottom: 4px;
}
.slate-row-f5-cells {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.slate-cell.f5-cell {
  /* FIX 2026-07-12 (Batch 2): --f5-bg was never defined, so the light #f9f9fb
     fallback always rendered — white cells on the dark drilldown. */
  background: var(--bg-elevated);
  border: 1px dashed var(--border);
  border-radius: 4px;
  padding: 6px;
  min-width: 140px;
}

/* ===== Mobile touch targets — WCAG 2.5.5 Target Size (min 44x44) =====
   FIX 2026-07-18: on a 375px viewport the primary "Take →" CTA rendered 22px
   tall (an outright WCAG 2.2 fail), the density toggle 32px, and the ▸ Compare
   / Line-Movement disclosures 34px. Expand the tap area on mobile only — the
   dense desktop layout is unchanged. Elevated priority for motor-impaired users
   (accessibility-audit skill). Placed at end-of-file so these override the
   base .slate-dense-toggle (min-height:32px) etc. by source order. The per-row
   ☆/+ are handled in the max-width:639px row block above. */
@media (max-width: 639px) {
  .hc-mini-cta {
    min-height: 44px;
    padding: 6px 16px;
    font-size: 13px;
  }
  .slate-dense-toggle { min-height: 44px; }
  .ls-expand-toggle {
    min-height: 44px;
    display: flex;
    align-items: center;
  }

  /* FIX 2026-08-11 (Slate mobile review): four more controls the 07-18 sweep
     never enumerated. Same end-of-file placement and the same reason — these
     must beat their base rules on source order. */

  /* Removes a leg from the parlay cart. 15px font + line-height:1 + no
     vertical padding rendered ~15x20px, and on a phone the rail IS the bottom
     drawer (max-width:1023px block above), so this is the only way to drop a
     leg.

     The gutter goes on the CARD, not on .parlay-leg-pick. main.css:857
     declares a SECOND .parlay-leg — the old parlay-builder component, same
     class name — with display:flex + justify-content:space-between, and
     slate.css never sets display, so that wins and the cart leg is a flex
     row. The pick is the LEFT item and never reaches the button; the item
     that sits under it is .parlay-leg-meta, which carries the odds price.
     Measured in a browser at 375px: padding on the pick left a 33x29px
     overlap, so a tap beside the price removed the leg. Reserving the
     button's own width on the card clears it under either layout. */
  .parlay-leg {
    padding-right: 46px;
  }
  .parlay-leg-x {
    top: 0; right: 0;
    min-width: 44px; min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0;
  }

  /* The ONLY control on an empty slate — same dead-end argument the sentinel
     already records for .cc-empty-action. */
  .slate-empty-clear {
    min-height: 44px;
    display: inline-flex; align-items: center;
  }

  /* Drilldown disclosures that sit beside the already-guarded
     .slate-ctx-details summary (main.css:2190) and were left at ~19px/~17px. */
  .slate-signals-fired summary {
    min-height: 44px;
    align-items: center;  /* already display:flex; keep its ::before marker */
  }
  /* Left as the default list-item so the disclosure triangle survives — only
     the height changes. */
  .sf-unavail-details summary {
    min-height: 44px;
    padding: 0.7rem 0;
  }
}

/* ===== Beta track-record reframe (2026-07-20) ===== */
/* Full hero shown on quiet days; condenses to #proof-sticky on scroll. */
.proof-hero { margin: 0 0 12px; }
.proof-hero .tagline {
  font-family: ui-monospace, monospace; font-size: 12px; font-weight: 700;
  letter-spacing: .28em; color: var(--accent, #3a7bd5); text-transform: uppercase;
}
#proof-full { text-align: center; padding: 14px 12px 4px; }
.proof-headline { font-size: 20px; font-weight: 800; margin: 8px 0 4px; }
.proof-sub { color: var(--text-muted, #9a9aa3); font-size: 14px; margin-bottom: 12px; }
.proof-cta {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; min-width: 44px; padding: 0 16px; border-radius: 8px;
  font-weight: 800; font-size: 14px; text-decoration: none;
  background: #15803d; color: #ffffff; /* AA: #ffffff on #15803d ≈ 4.6:1 (13px bold = normal text, needs 4.5) */
}
.proof-cta--ghost {
  background: transparent; color: var(--text, #cfcfe0);
  border: 1px solid rgba(255,255,255,.2); margin-left: 6px;
}
.proof-disclaimer { color: var(--text-faint, #6e6e78); font-size: 12px; margin-top: 8px; }
.proof-disclaimer a { color: var(--accent, #3a7bd5); }

/* Honest "0 qualifying bets" status card (quiet only). */
#proof-status {
  margin: 12px 0 0; padding: 12px 13px; border-radius: 10px;
  background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.09);
}
#proof-status .proof-status-h { font-weight: 800; font-size: 14px; }
#proof-status ul { margin: 6px 0 0; padding-left: 18px; }
#proof-status li { color: var(--text-muted, #9a9aa3); font-size: 13px; margin: 2px 0; }

/* Sticky compact strip: pinned CLV bar. Hidden until condensed/active. */
#proof-sticky {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; font-size: 12px;
  background: var(--bg, #0e0e13); border-bottom: 1px solid rgba(34,197,94,.28);
  transition: opacity .18s ease;
}
#proof-sticky.hidden { display: none; }
#proof-sticky .pv { color: #22c55e; font-weight: 800; }
#proof-sticky .pl { color: var(--text-muted, #8a8a93); }
#proof-sticky .proof-cta { margin-left: auto; min-height: 32px; padding: 0 10px; font-size: 12px; }

/* Active day: full hero hidden, strip leads. */
.proof-hero.is-active #proof-full,
.proof-hero.is-active #proof-status { display: none; }

/* FIX 2026-08-06: on a phone the rule above made the per-market CLV table
   unreachable, not merely lower — #proof-full was not rendered at all. Show it
   so the table can lead the fold; slate.js then wires the same
   IntersectionObserver `quiet` uses, so the strip still takes over once the
   hero scrolls away.

   This MUST sit after the rule it overrides. Same selector, same specificity
   (0,2,1), and a media query contributes none — so source order is the only
   thing deciding it. Placed inside the mobile block up at the reorder, it
   lost silently: the rules parsed, the URL looked right, and #proof-full
   stayed display:none. #proof-status stays hidden — the "0 qualifying bets"
   panel is for the quiet state and would contradict a populated Best Bets. */
@media (max-width: 639px) {
  .proof-hero.is-active #proof-full { display: block; }
}

/* Proof-unavailable: hide the whole hero, no track-record claim. */
.proof-hero.is-proof-unavailable { display: none; }

/* Bill a11y: no motion when the user asks for none. */
@media (prefers-reduced-motion: reduce) {
  #proof-sticky { transition: none; }
}

/* A cart leg whose game started after it was added: priced pregame, so it
   cannot be placed. Marked here so the reason is visible BEFORE Build & Take
   refuses. Amber (a warning to act on), not red (not an error state). */
.parlay-leg--started { opacity: 0.75; }
.parlay-leg-started {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  vertical-align: middle;
  color: var(--accent-amber, #e8a40f);
  background: rgba(232, 164, 15, 0.12);
  border: 1px solid rgba(232, 164, 15, 0.35);
}

/* Jurisdiction note under the hero card's "Best" book.
   Added 2026-08-09: the board quoted Betfair as best book on the single
   headline pick of a US-only beta. Muted — it is a caveat on the price, not
   an alarm.
   A first pass used 0.62rem and failed tests/test_type_scale_floor.py at
   9.92px against the 12px floor. Correctly: this is a jurisdiction warning
   on a price, so the one thing it must not be is too small to read. Uses the
   ramp's own --text-xs. */
.hc-mini-cell-note {
  font-size: var(--text-xs);
  line-height: 1.2;
  margin-top: 2px;
  color: var(--text-muted, #8a8f98);
  font-style: italic;
}

/* Log-bet chips — row and hero card.
   Added 2026-08-10. The pre-filled /me/log-bet URL existed but was surfaced
   only in the takeover, two clicks deep, while the runbook measures activation
   on logged bets. Same 28px box as the share chip so the row grid is unchanged.
   font-size in px, above the 12px floor tests/test_type_scale_floor.py enforces. */
.slate-row-log {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  border: 1px solid var(--slate-border); border-radius: 4px;
  text-decoration: none; color: var(--slate-text-3);
  font-size: 14px; font-weight: 700;
  background: transparent;
}
.slate-row-log:hover {
  border-color: var(--slate-blue, #1f6feb);
  color: var(--slate-blue, #1f6feb);
}

.hc-mini-log {
  display: inline-flex; align-items: center; gap: 3px;
  margin-right: 8px;
  text-decoration: none;
  color: var(--slate-text-3, #8a8f98);
  font-size: 12px; font-weight: 600;
  white-space: nowrap;
}
.hc-mini-log:hover { color: var(--slate-blue, #1f6feb); }
