/* DIAMOND:CONTEXT — design system v2 (sportsbook-modern).
 *
 * Deep navy background, vibrant accent colors with distinct semantic
 * roles (red = LIVE, green = win, blue = action), Inter typography
 * with tabular numerics, soft 8px rounded card surfaces. Field uses
 * real ballpark colors (grass green, dirt tan) against the dark UI.
 */

:root {
    /* Surface palette — deep navy, NOT pure black */
    --bg:          #0B1220;
    --surface:     #141C2E;
    --surface-2:   #1E2942;
    --border:      #26304A;

    /* Text — primary is bright for readability; dim is for secondary
       labels/metadata only. Dim is set bright enough (Slate-300) that
       it passes AA contrast on the dark bg — anything secondary that
       readers need to actually parse still passes muster. */
    --text:        #F5F7FA;
    --text-dim:    #CBD5E1;
    --text-faint:  #94A3B8;  /* For decorative-only labels (timestamps, etc.) */

    /* Accents — each does ONE job */
    --accent-live: #EF4444;   /* LIVE badges, urgent, losses */
    --accent-win:  #22C55E;   /* wins, positive, occupied bases */
    --accent-action: #3B82F6; /* CTAs, links, nav active */

    /* Field illustration palette — real ballpark colors */
    --grass:       #3F6B2A;
    --grass-light: #4A7A35;
    --grass-dark:  #355A23;
    --dirt:        #B58A5A;
    --dirt-dark:   #8B6F47;
    --chalk:       #E8E8E8;

    /* 15-game max slate fits a desktop viewport in 5×3 without scroll.
       Width: 1920px - 36px page padding - 48px gaps / 5 cols = 367px
              → rounded to 360 to leave a touch of breathing room.
       Height: typical viewport ~1080px - header 50 - nav 50 - datebar
              60 - page padding 40 = ~880px for the grid. 3 rows + 2
              gaps (12px) = (880-24)/3 = ~285px per tile. Setting
              min-height a touch lower so tile content (which is
              fairly compact) drives natural sizing on slates with
              fewer games, while the 285-ish target is still hit on
              a full slate. */
    /* Board tile sizing — target: 5 cols × 3 rows = 15 games visible
       at once on a 1280-1920px desktop without scrolling.
         1920 viewport → (1920 - 36px page padding - 4×12px gap) / 5
                         ≈ 367px per tile.
         1280 viewport → (1280 - 36 - 48) / 5 ≈ 239px per tile.
       --tile-w sits at the lower bound so auto-fill packs 5 at the
       narrow end; max-width on main.board caps the row to exactly 5
       at the wide end so it doesn't sprawl to 6-7 cols on ultrawide. */
    /* Wider tile (220 → 260) — MLB.com / At Bat keep their game
       cards around 280-340px so the inning header + team rows +
       player blocks read at one glance, not packed. We split the
       difference: 260px is wide enough for a clear hierarchy
       while still fitting 5 per row at 1500-1620px viewport. */
    --tile-w: 260px;
    --tile-min-h: 175px;
    --radius: 8px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* The `hidden` HTML attribute should suppress display, but `main.board`,
   `.game-view`, etc. set `display: grid` / `display: flex` directly, which
   wins on specificity. Force the attribute to take priority so only one
   <main> view ever renders at a time. */
[hidden] { display: none !important; }

html, body { height: 100%; }
body {
    background: var(--bg);
    color: var(--text);
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
                 Roboto, sans-serif;
    font-feature-settings: 'tnum' 1, 'cv11' 1;
    font-size: 14px;
    line-height: 1.4;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ── HEADER ────────────────────────────────────────────────────── */

header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 22px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}

/* Header brand: logo mark + wordmark wrapped in an <a> that links
   home. Reads as one unit ("the brand"), clickable from any view. */
header .brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    color: inherit;
}
header .brand-mark {
    width: 26px;
    height: 26px;
    transition: transform 240ms ease;
    flex-shrink: 0;
}
header .brand:hover .brand-mark {
    /* Subtle tilt on hover — same visual language as a rotating
       knob, reads as 'clickable.' */
    transform: rotate(8deg);
}

header h1 {
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--text);
    margin: 0;
}
header h1 .colon { color: var(--accent-win); }

.live-indicator {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    background: var(--accent-live);
    border-radius: 20px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.12em;
    color: white;
}
.live-indicator .dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: white;
    animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.4; }
}

/* ── THE BOARD ─────────────────────────────────────────────────── */

/* Tile grid with natural sizing. Scrolls if the slate doesn't fit the
   viewport — that's accepted; the Game view's ticker keeps the rest of
   the slate visible while you're inside a single game. */
main.board {
    flex: 1;
    overflow: auto;
    /* Bottom gutter 100px so the fixed widgets clear the last
       tile row — see .leaders-view. */
    padding: 8px 18px 100px;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(var(--tile-w), 1fr));
    gap: 10px;
    align-content: start;
    justify-content: center;
    /* Cap at 5 columns × tile-width + gaps so the slate doesn't
       spread to 6-8 columns on ultrawide. 5×260 + 4×10 + 36px page
       padding ≈ 1376px — comfortable max so 15 tiles read as a
       neat 5×3 grid. */
    max-width: 1620px;
    margin: 0 auto;
    width: 100%;
}

.empty {
    grid-column: 1 / -1;
    text-align: center;
    color: var(--text-dim);
    padding: 96px 16px;
    line-height: 1.7;
}

/* Date navigation bar above the Board's tile grid. Spans the full
   grid width (same trick as .empty: grid-column: 1 / -1). Prev /
   center label / next + a native date picker for arbitrary jumps. */
.board-datebar {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 4px;
    padding: 2px 4px;
    flex-wrap: wrap;
    position: relative;
}
.board-datebar .bd-arrow {
    color: var(--accent-action);
    text-decoration: none;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    padding: 4px 6px;
    border-radius: 4px;
    transition: background 120ms ease, color 120ms ease;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.board-datebar .bd-arrow:hover {
    background: var(--surface-2);
    color: var(--text);
}
.board-datebar .bd-arrow.disabled {
    color: var(--text-dim);
    opacity: 0.4;
    cursor: default;
    pointer-events: none;
}
.board-datebar .bd-arrow-date {
    font-variant-numeric: tabular-nums;
    color: var(--text-dim);
    font-weight: 500;
    font-size: 11px;
    letter-spacing: 0.02em;
}
.board-datebar .bd-arrow:hover .bd-arrow-date { color: var(--text); }
.board-datebar .bd-center {
    display: inline-flex;
    align-items: baseline;
    gap: 10px;
    flex: 1;
    justify-content: center;
    min-width: 0;
}
.board-datebar .bd-today-pill {
    display: inline-flex;
    align-items: center;
    padding: 3px 8px;
    background: var(--accent-action);
    color: white;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.16em;
    line-height: 1;
}
.board-datebar .bd-today-link {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.12em;
    color: var(--accent-action);
    text-decoration: none;
    text-transform: uppercase;
    border-bottom: 1px dotted rgba(59, 130, 246, 0.4);
}
.board-datebar .bd-today-link:hover {
    color: var(--text);
    border-bottom-color: var(--text);
}
.board-datebar .bd-date {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.005em;
}
.board-datebar .bd-jump {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-dim);
    font-family: inherit;
    font-size: 11px;
    padding: 4px 6px;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    transition: border-color 120ms ease, color 120ms ease;
    color-scheme: dark;
}
.board-datebar .bd-jump:hover,
.board-datebar .bd-jump:focus {
    border-color: var(--accent-action);
    color: var(--text);
    outline: none;
}
.empty .sub {
    font-size: 11px;
    font-weight: 550;
    letter-spacing: 0.15em;
    color: var(--accent-win);
    margin-top: 12px;
    text-transform: uppercase;
}

/* ── GAME TILE ─────────────────────────────────────────────────── */

.tile {
    width: auto;
    min-height: var(--tile-min-h);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 8px 12px 10px;
    display: flex;
    /* Distribute the limited content (matchup + state + body +
       WE bar) so the bar always hugs the bottom and the body
       fills the middle. Without this, short Final tiles left a
       gap of dead space below the W/L/S row. */
    flex-direction: column;
    gap: 5px;
    text-decoration: none;
    color: inherit;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
    transition: transform 150ms ease, border-color 150ms ease,
                background 150ms ease;
    position: relative;
}
.tile:hover {
    transform: translateY(-2px);
    border-color: var(--accent-action);
    background: var(--surface-2);
}

/* The top live game on the slate gets a faint red ring so the eye picks it
   up first without a separate hero card. Driven by sort order, not by class
   name — the first child .tile that's also Live qualifies. */
.tile[data-status="Live"]:first-child {
    border-color: rgba(239, 68, 68, 0.45);
    box-shadow:
        0 1px 3px rgba(0, 0, 0, 0.4),
        0 0 0 1px rgba(239, 68, 68, 0.2);
}

/* Every other live tile gets a subtle border-left accent so the
   slate visually separates Live games from Preview / Final at a
   glance, without competing with the top-card red ring. */
.tile[data-status="Live"] {
    border-left: 2px solid rgba(239, 68, 68, 0.55);
    padding-left: 11px;   /* 12 - 1 of the extra border, keeps text on-grid */
}

/* Final tiles read 'done' — slightly faded surface, slightly
   muted border. The eye reaches Live tiles first; Final tiles
   sit quietly until you tap. */
.tile[data-status="Final"] {
    background: rgba(15, 23, 42, 0.45);
    border-color: rgba(148, 163, 184, 0.15);
}
.tile[data-status="Final"] .team .name,
.tile[data-status="Final"] .team .score {
    color: var(--text-dim);
}
.tile[data-status="Final"] .team .name { font-weight: 600; }   /* was 800 */
.tile[data-status="Final"] .team .rec  { opacity: 0.7; }

/* MLB.com / At Bat style header — inning + situation read as a
   thin uppercase label across the top of the tile with a divider
   beneath, instead of being buried between the matchup and the
   batter/pitcher rows. Anchors the eye on game state first. */
.tile .tile-top {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    padding: 1px 0 5px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 4px;
}
.tile .tile-top .state {
    margin-top: 0;
    text-align: left;
    font-size: 10px;
    letter-spacing: 0.14em;
    font-weight: 700;
    color: var(--text);
}
.tile[data-status="Live"] .tile-top .state {
    color: var(--accent-live);
}
.tile[data-status="Final"] .tile-top .state {
    color: var(--text-dim);
}

.tile .matchup {
    display: flex;
    flex-direction: column;
}

.tile .team {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 5px 0;
    border-bottom: 1px solid var(--border);
}
.tile .team:last-child { border-bottom: none; padding-bottom: 3px; }
.tile .team:first-child { padding-top: 3px; }

.tile .team .team-id {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
}
.tile .team .name {
    font-size: 14px;
    /* MLB.com / At Bat render team names in MEDIUM weight (600,
       not 700-800) so they read as a 'team' not a 'header'. The
       score column on the right carries the eye instead. */
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.01em;
}
.tile .team .rec {
    font-size: 11px;
    /* Lighter still — the record is informational, not a focal
       point. MLB uses near-regular weight (450) in light gray. */
    font-weight: 450;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
}
.tile .team .score {
    font-size: 18px;
    /* Score gets the bold weight (700), not the team name. This
       inverts the previous emphasis and matches every modern
       sportsbook + MLB scoreboard convention: team is name-weight,
       score is the focal glyph. */
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}
.tile[data-status="Preview"] .team .score {
    color: var(--text-dim);
    font-weight: 550;
}

.tile .state {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    text-align: center;
    color: var(--text-dim);
    margin-top: 2px;
}
.tile[data-status="Live"] .state {
    color: var(--accent-live);
}
.tile[data-status="Final"] .state {
    /* 'FINAL' reads as a quiet badge — letter-spaced, dim, but
       distinct enough from 'PREVIEW' / 'LIVE' to anchor the eye. */
    color: var(--text-dim);
    font-size: 9px;
    letter-spacing: 0.16em;
    padding: 2px 0;
}

/* Live batter / pitcher block. Filled in by hydrateLiveTile after the
   Board's /api/games/today fetch lands. Shell renders em-dashes so the tile
   doesn't reflow when the hydrate result arrives. */
.tile .tile-players {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.tile .tile-players .player-row {
    display: grid;
    /* Was 46|26 — at 12px label font the 'PITCHING' glyph chain
       overran 46px and clipped the trailing G. 64px gives it
       breathing room without eating into the name column. */
    grid-template-columns: 54px 22px minmax(0, 1fr);
    align-items: center;
    gap: 6px;
    font-size: 12px;
    /* The generic .player-row (used inside the live game pane) has
       10px×14px padding, a surface background, and a border — that
       turns each AT BAT / PITCHING row into an inset card ~50px
       tall. On the slate tiles we want a one-line row instead, so
       null those styles. */
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    min-height: 20px;
    max-width: none;
}
.tile .tile-players .player-row .label {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.10em;
    text-transform: uppercase;
}
.tile .tile-players .player-row strong {
    /* The wrapper just stretches across the name + hand spans —
       all visual properties live on .pname / .phand below. */
    color: var(--text);
    font-weight: 400;
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    flex: 1;
}
.tile .tile-players .player-row .pname {
    /* Player name reads as the primary glyph: full content weight
       (650) with slightly tightened tracking. Sportsbook + MLB
       At Bat broadcast graphics use this look — a name reads,
       not announces. */
    color: var(--text);
    font-weight: 550;
    letter-spacing: -0.005em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.tile .tile-players .player-row .phand {
    /* User wanted the hand to 'fit in better with the rest of the
       font' — the badge pill stuck out as its own visual block.
       Now matches the AT BAT / PITCHING label style: small,
       uppercase, dim, letter-spaced. Reads as metadata adjacent
       to the name, not a separate UI element. */
    color: var(--text-dim);
    font-weight: 600;
    font-size: 0.72em;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    flex-shrink: 0;
    margin-left: 1px;
}
.tile .tile-players .player-row .phand::before { content: "("; }
.tile .tile-players .player-row .phand::after  { content: ")"; }
.tile .tile-players .player-row.dim .pname,
.tile .tile-players .player-row.dim .phand {
    color: var(--text-dim);
    opacity: 0.55;
}

/* Sportsbook-style WE bar across the tile bottom. Hidden for pregame since
   there's no game state to anchor a probability to. */
.tile .tile-we {
    display: flex;
    flex-direction: column;
    gap: 2px;
    /* Auto top margin pushes the WE bar to the bottom of the tile
       in the flex column, so the matchup + state + body always
       fill the upper portion and the bar is visually anchored. */
    margin-top: auto;
}
.tile .tile-we .we-bar {
    height: 4px;
    background: var(--accent-live);
    border-radius: 3px;
    overflow: hidden;
}
.tile .tile-we .we-bar > span {
    display: block;
    height: 100%;
    background: var(--accent-win);
    transition: width 400ms ease;
}
.tile .tile-we .we-labels {
    display: flex;
    justify-content: space-between;
    font-size: 10px;
    font-weight: 550;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
}

/* Probable pitchers (pregame) and decisions (final) sit just under the state
   line — same visual block as before; the tile-body picks one of the two. */
.tile .tile-extra {
    font-size: 11px;
    font-weight: 500;
    color: var(--text);
    text-align: center;
    letter-spacing: 0.01em;
    line-height: 1.35;
    /* Pad the body block slightly so a Final tile's W/L/S row
       sits centered between the team header above and the WE bar
       below instead of crowding either edge. */
    padding: 6px 0 4px;
}
.tile .tile-extra .dim {
    color: var(--text-dim);
    font-weight: 550;
    letter-spacing: 0.05em;
}
.tile .tile-pitcher,
.tile .tile-decision {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    vertical-align: middle;
}
/* Decision row (W / L / S) breathes — separator '·' between
   pitcher decisions gets a touch of spacing so the row reads as
   a sequence, not a run-on. */
.tile .tile-decision + .tile-decision {
    margin-left: 4px;
}
.tile .tile-photo {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--bg);
    object-fit: cover;
    object-position: center top;
}
.tile .tile-photo-empty {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: rgba(148, 163, 184, 0.12);
    border: 1px dashed rgba(148, 163, 184, 0.25);
    box-sizing: border-box;
    display: inline-block;
    flex-shrink: 0;
}
.tile .tile-pitcher-tba {
    color: var(--text-dim);
    font-weight: 550;
}

/* Preview-state tile body: pitchers stacked LEFT, start time RIGHT.
   Both share the same horizontal row so the time visually pairs
   with the matchup it labels instead of floating mid-tile. */
.tile .tile-preview-row {
    display: flex;
    align-items: center;
    gap: 8px;
    justify-content: space-between;
    margin-top: 4px;
    flex: 1;
}
.tile .tile-time-side {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--text-dim);
    white-space: nowrap;
    text-transform: uppercase;
}

/* Probables: stacked two-row pitcher layout — one row per side,
   each row [avatar | THROWS + name]. Both rows share an avatar
   slot (real photo OR dashed-circle placeholder for TBA) so the
   rows align vertically across every tile, even when one side
   hasn't named their starter. Left-aligned now so the pitcher
   block reads as a unit on the left and the time on the right. */
.tile .tile-extra.probables {
    display: flex;
    flex-direction: column;
    gap: 4px;
    align-items: flex-start;
    flex: 1 1 auto;
    min-width: 0;
}
.tile .tile-pitcher-row {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 10px;
    line-height: 1.2;
    text-align: left;
    min-height: 22px;        /* match avatar height for alignment */
    max-width: 100%;
}
.tile .tile-pitcher-row.is-tba .tile-pitcher-text {
    color: var(--text-dim);
    font-weight: 550;
}
.tile .tile-pitcher-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
/* Hide the "vs" — no longer needed once pitchers are stacked
   vertically as a clear two-row list. */
.tile .tile-pitcher-row .dim {
    display: none;
}
.tile .tile-live-photo {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--bg);
    object-fit: cover;
    object-position: center top;
    display: block;
}
.tile .tile-live-photo-empty {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--bg);
    display: block;
}

/* HOT pill for close, late-inning live games. Moved to TOP-LEFT
   so it doesn't sit on top of the away-team score in the top-right
   corner. Same visual grammar as the header LIVE pill. */
.tile .hot-pill {
    position: absolute;
    top: -4px;
    left: 10px;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 2px 6px 2px 5px;
    border-radius: 3px;
    background: var(--accent-live);
    color: #fff;
    font-size: 8px;
    font-weight: 700;
    letter-spacing: 0.14em;
    line-height: 1;
    box-shadow: 0 0 6px rgba(239, 68, 68, 0.5);
    z-index: 2;
}
.tile .hot-pill .dot {
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: #fff;
    animation: pulse 1.5s ease-in-out infinite;
}

/* ── STANDINGS VIEW ────────────────────────────────────────────── */

.standings-view {
    flex: 1;
    overflow: auto;
    /* Bottom gutter for the fixed widgets — see .leaders-view. */
    padding: 14px 24px 100px;
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 1620px;
    margin: 0 auto;
    width: 100%;
}
.standings-view .empty { padding: 48px 16px; }

.standings-head {
    display: flex;
    align-items: baseline;
    gap: 14px;
}
.standings-head h2 {
    font-size: 17px;
    font-weight: 700;
    letter-spacing: 0.18em;
    color: var(--text);
}
.standings-head .standings-meta {
    font-size: 11px;
    font-weight: 550;
    letter-spacing: 0.12em;
    color: var(--text-dim);
    text-transform: uppercase;
}

.standings-league {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.league-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.18em;
    color: var(--text-dim);
    text-transform: uppercase;
}

.standings-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
    gap: 16px;
}

.division-block {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}
.division-head {
    padding: 10px 14px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}
.division-name {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.15em;
    color: var(--text);
    text-transform: uppercase;
}

.standings-table {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}
.standings-table th {
    text-align: right;
    /* Was 9 — too small next to 12 cells. 10 sits a clean step
       below the cell text without losing the "label" feel. */
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.12em;
    color: var(--text-dim);
    text-transform: uppercase;
    padding: 8px 8px 6px;
    border-bottom: 1px solid var(--border);
}
.standings-table th.col-team {
    text-align: left;
    padding-left: 14px;
}
.standings-table td {
    text-align: right;
    padding: 7px 8px;
    font-size: 12px;
    color: var(--text);
    border-bottom: 1px solid var(--border);
    font-weight: 500;
}
.standings-table tr:last-child td { border-bottom: none; }
.standings-table td.col-team {
    text-align: left;
    padding-left: 14px;
    font-weight: 550;
    letter-spacing: 0.01em;
}
.standings-table tr.leader td.col-team strong {
    color: var(--accent-win);
}

.standings-table .streak-win { color: var(--accent-win); font-weight: 600; }
.standings-table .streak-loss { color: var(--accent-live); font-weight: 600; }
.standings-table .rd-pos { color: var(--accent-win); font-weight: 550; }
.standings-table .rd-neg { color: var(--accent-live); font-weight: 550; }

/* ── LEADERS VIEW ──────────────────────────────────────────────── */

.leaders-view {
    flex: 1;
    overflow: auto;
    /* Bottom-pad 100px so the centered RECENT/Active Bets pill and
       the launcher (both fixed at the viewport bottom) clear the
       last row of leader cards without overlapping. Same gutter
       added to .hot-view / .mvp-view / .markets-view / main.board
       for the same reason. */
    padding: 8px 16px 100px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.leaders-view .empty { padding: 48px 16px; }

.leaders-head {
    display: flex;
    align-items: center;
    gap: 14px;
}
.leaders-mode-toggle {
    margin-left: auto;
    display: inline-flex;
    background: rgba(15, 23, 42, 0.7);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 2px;
}
.leaders-mode-btn {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text-dim);
    font: inherit;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    padding: 5px 12px;
    border-radius: 999px;
    cursor: pointer;
    transition: background 120ms, color 120ms;
}
.leaders-mode-btn:hover { color: var(--text); }
.leaders-mode-btn.active {
    background: var(--accent-action);
    color: #0B1220;
}
.leaders-head h2 {
    font-size: 17px;
    font-weight: 700;
    letter-spacing: 0.18em;
    color: var(--text);
}
.leaders-head .leaders-meta {
    font-size: 11px;
    font-weight: 550;
    letter-spacing: 0.12em;
    color: var(--text-dim);
    text-transform: uppercase;
}

.leaders-section {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.leaders-section-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.18em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 0;
    line-height: 1.4;
}

.leaders-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
    gap: 6px;
}

.leader-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
    display: flex;
    flex-direction: column;
}
.leader-head {
    padding: 4px 10px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
.leader-stat {
    /* Stat-name header (HR, AVG, OPS…) — 11px reads cleanly and
       sits even with the 11px row text. */
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text);
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
}

.leader-list {
    list-style: none;
    padding: 1px 0;
    margin: 0;
}
.leader-row {
    display: grid;
    grid-template-columns: 14px 22px minmax(0, 1fr) auto auto;
    gap: 6px;
    align-items: center;
    padding: 3px 10px;
    /* 10.5px was a half-pixel that doesn't render crisply on most
       displays; round to 11px which sits on the 11/12 content tier
       used everywhere else. */
    font-size: 11px;
    line-height: 1.25;
}
.leader-photo {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--bg);
    object-fit: cover;
    object-position: center top;
}
.leader-photo-empty {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--bg);
}
.leader-rank {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.leader-row[data-rank="1"] .leader-rank {
    color: var(--accent-win);
}
.leader-name {
    color: var(--text);
    font-weight: 550;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.leader-team {
    color: var(--text-dim);
    /* Was 9px — too small next to the 11px name. 10px reads as a
       quiet secondary at the right edge without looking faded. */
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
}
.leader-value {
    color: var(--text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
    min-width: 38px;
    text-align: right;
    /* Bumped 11 → 12 so the value reads as the primary glyph in
       the row, matching the visual hierarchy of stat tables
       elsewhere on the site. */
    font-size: 12px;
}
.leader-empty {
    padding: 14px;
    text-align: center;
    color: var(--text-dim);
    font-size: 11px;
    font-style: italic;
}

/* ── MVP / CY YOUNG VIEW ───────────────────────────────────────── */

.mvp-view {
    flex: 1;
    overflow: auto;
    /* Bottom gutter for the fixed widgets — see .leaders-view. */
    padding: 8px 18px 100px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-width: 1620px;
    margin: 0 auto;
    width: 100%;
}
.mvp-view .empty { padding: 48px 16px; }

.mvp-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
}
.mvp-head h2 {
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text);
}
.mvp-head .mvp-meta {
    font-size: 10px;
    font-weight: 550;
    letter-spacing: 0.10em;
    color: var(--text-dim);
    text-transform: uppercase;
}

.mvp-foot {
    font-size: 11px;
    color: var(--text-dim);
    line-height: 1.5;
    padding: 4px 0 0;
    max-width: 640px;
}

/* Sub-header above the OPS/ERA grid — lets us label the band so
   the WPA section above feels distinct, not just "more leaders." */
.mvp-section-head {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.16em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-top: 8px;
}

/* ── WPA BAND ───────────────────────────────────────────────────────
   The leverage-weighted contribution leaderboard. Sits ABOVE the
   traditional OPS/ERA grid because it's the editorial position of
   this app — "stats are stats; this is who's actually moved win
   probability." Subtle green tint to match the live game's
   forecast / "edge" coloring. */
.wpa-band {
    background: rgba(34, 197, 94, 0.05);
    border: 1px solid rgba(34, 197, 94, 0.18);
    border-radius: var(--radius);
    padding: 8px 12px 10px;
}
.wpa-band .wpa-band-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 6px;
}
.wpa-band .wpa-band-title {
    font-size: 12px;
    font-weight: 700;
    color: var(--accent-win);
    letter-spacing: -0.005em;
}
.wpa-band .wpa-band-meta {
    font-size: 10px;
    font-weight: 550;
    letter-spacing: 0.08em;
    color: var(--text-dim);
    text-transform: uppercase;
}
.wpa-band .wpa-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
}
@media (min-width: 720px) {
    .wpa-band .wpa-grid { grid-template-columns: 1fr 1fr; }
}
.wpa-band .wpa-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: calc(var(--radius) - 2px);
    padding: 6px 10px 8px;
}
.wpa-band .wpa-empty .wpa-empty-msg {
    color: var(--text-dim);
    font-size: 12px;
    font-style: italic;
    padding: 12px 0;
}
.wpa-band .wpa-head {
    display: flex;
    flex-direction: column;
    gap: 1px;
    margin-bottom: 4px;
    padding-bottom: 3px;
    border-bottom: 1px solid var(--border);
}
.wpa-band .wpa-title {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.10em;
    color: var(--text);
    text-transform: uppercase;
}
.wpa-band .wpa-blurb {
    font-size: 10px;
    color: var(--text-dim);
    font-weight: 500;
}
.wpa-band .wpa-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}
.wpa-band .wpa-row {
    display: grid;
    grid-template-columns: 16px 22px minmax(0, 1fr) 40px 36px;
    gap: 6px;
    align-items: center;
    padding: 3px 0;
    /* Round 10.5 → 11 (no half-px, doesn't render crisply) and
       match the same 11px content tier the leader rows use. */
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}
.wpa-band .wpa-photo {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--bg);
    object-fit: cover;
    object-position: center top;
    display: block;
}
.wpa-band .wpa-photo-empty {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--bg);
    display: block;
}
.wpa-band .wpa-row + .wpa-row {
    border-top: 1px solid rgba(255, 255, 255, 0.04);
}
.wpa-band .wpa-rank {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 600;
    text-align: right;
}
.wpa-band .wpa-name {
    color: var(--text);
    font-weight: 550;
    text-decoration: none;
    border-bottom: 1px dotted var(--text-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.wpa-band .wpa-name:hover {
    color: var(--accent-action);
    border-bottom-color: currentColor;
}
.wpa-band .wpa-pa {
    color: var(--text-dim);
    font-size: 10px;
    text-align: right;
    font-weight: 500;
}
.wpa-band .wpa-val {
    text-align: right;
    font-weight: 700;
    font-size: 11px;
}
.wpa-band .wpa-pos { color: var(--accent-win);  }
.wpa-band .wpa-neg { color: var(--accent-live); }

.mvp-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
    gap: 8px;
}

.race-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
    display: flex;
    flex-direction: column;
}
.race-card[data-group="pitching"] .race-head {
    border-bottom-color: rgba(59, 130, 246, 0.35);
}
.race-head {
    padding: 6px 12px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
.race-title {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    color: var(--text);
    text-transform: uppercase;
}

.race-list {
    list-style: none;
    padding: 2px 0;
    margin: 0;
}
.race-empty {
    padding: 18px;
    text-align: center;
    color: var(--text-dim);
    font-size: 11px;
    font-style: italic;
}

.cand-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px;
    align-items: center;
    padding: 3px 12px;
    border-bottom: 1px solid var(--border);
}
.cand-row:last-child { border-bottom: none; }
.cand-row[data-rank="1"] {
    background: linear-gradient(
        90deg,
        rgba(34, 197, 94, 0.06),
        transparent 60%
    );
}

.cand-id {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}
.cand-photo {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--bg);
    object-fit: cover;
    object-position: center top;
    flex-shrink: 0;
}
.cand-photo-empty {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--bg);
    flex-shrink: 0;
}
.cand-rank {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    min-width: 14px;
}
.cand-row[data-rank="1"] .cand-rank { color: var(--accent-win); }
.cand-name {
    font-size: 11px;
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cand-team {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
}

.cand-stats {
    display: flex;
    gap: 10px;
    align-items: baseline;
}
.cand-stat {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    line-height: 1;
}
.cand-stat-value {
    font-size: 11px;
    font-weight: 600;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.cand-stat-label {
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 0.10em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-top: 2px;
}
.cand-stat.primary .cand-stat-value {
    font-size: 13px;
    font-weight: 700;
    color: var(--accent-win);
}
.race-card[data-group="pitching"] .cand-stat.primary .cand-stat-value {
    color: var(--accent-action);
}

/* ── BOTTOM NAV ────────────────────────────────────────────────── */

nav {
    display: flex;
    background: var(--surface);
    border-top: 1px solid var(--border);
    flex-shrink: 0;
}
nav .nav-item {
    flex: 1;
    text-align: center;
    padding: 10px 0;
    color: var(--text-dim);
    text-decoration: none;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.12em;
    transition: color 120ms ease, background 120ms ease;
}
nav .nav-item .num {
    color: var(--accent-action);
    margin-right: 8px;
}
nav .nav-item.active {
    color: var(--text);
    background: var(--surface-2);
}
nav .nav-item:hover:not(.disabled) {
    color: var(--text);
    background: var(--surface-2);
}
nav .nav-item.disabled { cursor: default; opacity: 0.45; }
nav .nav-item.disabled .num { color: var(--text-dim); }

/* ── PLAYER PROFILE VIEW ──────────────────────────────────────── */
/* Reached via clickable player names anywhere in the app. Bookmarkable
   URL: #player/{mlbam}. Shows career splits + this-season activity. */

.player-view {
    flex: 1;
    overflow: auto;
    /* Bottom gutter for the fixed widgets — see .leaders-view. */
    padding: 18px 0 100px;
    display: flex;
    flex-direction: column;
}
.player-view .back-link {
    padding: 0 32px 12px;
}

.player-doc {
    width: 100%;
    max-width: 920px;
    margin: 0 auto;
    padding: 0 24px;
    color: var(--text);
}

/* ── HERO HEADER ─────────────────────────────────────────────────
   Name big, jersey# trailing, meta strip below. Convention every
   baseball site uses. Now with the player's headshot to the left —
   same MLB CDN every other baseball site uses. */
.player-hero {
    margin-bottom: 24px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 18px;
}
.ph-headshot {
    flex: 0 0 128px;
    width: 128px;
    height: 128px;
    border-radius: 50%;
    background: var(--surface);
    border: 1px solid var(--border);
    overflow: hidden;
    position: relative;
}
.ph-headshot img {
    width: 100%;
    height: 100%;
    /* User direction (2026-06-06): 'Make sure the whole face and hat
       are in the frame. Shrink the picture if you need to.' Was
       object-fit: cover with center-top — cropped the top of the hat
       AND the chin. 'contain' fits the full portrait inside the
       circle; the empty corners on the sides blend with the dark
       surface background. */
    object-fit: contain;
    object-position: center;
    display: block;
}
.ph-headshot-initials {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-dim);
    font-size: 34px;
    font-weight: 700;
    letter-spacing: -0.02em;
    text-transform: uppercase;
    pointer-events: none;
    opacity: 0;
    transition: opacity 80ms ease;
}
.ph-headshot.ph-headshot-fallback .ph-headshot-initials {
    opacity: 1;
}
.ph-body {
    flex: 1;
    min-width: 0;
}
.ph-name-row {
    display: flex;
    align-items: baseline;
    gap: 16px;
    margin-bottom: 8px;
    flex-wrap: wrap;
}
.ph-name {
    font-size: 36px;
    line-height: 1;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--text);
    margin: 0;
}
.ph-jersey {
    font-size: 17px;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--text-dim);
}
.ph-meta {
    display: flex;
    align-items: baseline;
    gap: 6px;
    flex-wrap: wrap;
    font-size: 12px;
    font-weight: 550;
    letter-spacing: 0.04em;
    color: var(--text-dim);
}
.ph-meta .ph-dot {
    color: var(--text-dim);
    opacity: 0.5;
    padding: 0 2px;
}
.player-warning {
    color: var(--accent-live);
}

/* ── PLAYER MODULE WRAPPER ──────────────────────────────────────── */
.player-module {
    display: flex;
    flex-direction: column;
    gap: 18px;
    margin-bottom: 26px;
}
.player-module + .player-module {
    padding-top: 24px;
    border-top: 1px solid var(--border);
}
.pm-pitcher-note {
    font-size: 11px;
    color: var(--text-dim);
    font-style: italic;
}

/* ── PLAYER TONIGHT ────────────────────────────────────────────────
   Projection card at the top of the player profile when the player
   has a game today. Combines matchup info + expected line + recent
   form + head-to-head + streaks. Green-tinted to signal "forward-
   looking / live" — same accent as the live game forecast block. */
.player-tonight {
    background: rgba(34, 197, 94, 0.05);
    border: 1px solid rgba(34, 197, 94, 0.2);
    border-radius: var(--radius);
    padding: 16px 18px;
    margin-bottom: 24px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.player-tonight .pt-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding-bottom: 12px;
    border-bottom: 1px solid rgba(34, 197, 94, 0.18);
}
.player-tonight .pt-when {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent-win);
}
.player-tonight .pt-tags {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}
.player-tonight .pt-tag {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text);
    background: rgba(148, 163, 184, 0.1);
    padding: 3px 8px;
    border-radius: 99px;
}
.player-tonight .pt-tag-pitcher {
    background: rgba(59, 130, 246, 0.1);
    color: var(--text);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px 3px 3px;
}
.player-tonight .pt-tag-photo {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--bg);
    object-fit: cover;
    object-position: center top;
    flex-shrink: 0;
}
.player-tonight .pt-tag-photo-empty {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--bg);
    flex-shrink: 0;
}
.player-tonight .pt-tag-text { display: inline-flex; align-items: baseline; gap: 4px; }
.player-tonight .pt-tag-pitcher a {
    color: var(--text);
    text-decoration: none;
    border-bottom: 1px dotted var(--text-dim);
}

/* Expected line — 5-tile grid mirrors the slash strip's visual
   language so the projected stats read as parallel to season stats. */
.player-tonight .pt-expected-head {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 8px;
}
.player-tonight .pt-expected-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 6px;
    margin-bottom: 8px;
}
.player-tonight .pt-stat {
    text-align: center;
    padding: 10px 6px;
    background: var(--bg);
    border-radius: calc(var(--radius) - 2px);
}
.player-tonight .pt-stat-val {
    font-size: 20px;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}
.player-tonight .pt-stat-key {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.1em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-top: 4px;
}
.player-tonight .pt-expected-meta {
    font-size: 11px;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}
.player-tonight .pt-expected-meta strong {
    color: var(--text);
    font-weight: 600;
}
.player-tonight .pt-expected-empty {
    font-size: 12px;
    color: var(--text-dim);
    font-style: italic;
    padding: 8px 0;
}

/* Player-prop strip — chips showing every public market line on this
   player for tonight's game. Sits between the projected line and the
   recent-form sections so users see "model says X / market says Y"
   without leaving the player profile. */
.player-tonight .pt-prop-strip:not(:empty) {
    margin-top: 14px;
    padding: 12px;
    border-radius: var(--radius);
    background: rgba(148, 163, 184, 0.05);
    border: 1px dashed rgba(148, 163, 184, 0.2);
}
.player-tonight .pt-prop-strip-head {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.1em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 8px;
}
.player-tonight .pt-prop-strip-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.player-tonight .pt-prop-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 9px;
    border-radius: 99px;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text);
    text-decoration: none;
    font-size: 11px;
    font-weight: 550;
    transition: border-color 80ms ease;
}
.player-tonight .pt-prop-chip:hover {
    border-color: var(--accent-action);
}
.player-tonight .pt-prop-chip-side {
    color: var(--text);
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.player-tonight .pt-prop-chip-pct {
    font-variant-numeric: tabular-nums;
    color: var(--accent-action);
    font-weight: 600;
}
.player-tonight .pt-prop-chip-src {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-faint);
}
.player-tonight .pt-prop-strip-note {
    margin-top: 6px;
    font-size: 10px;
    color: var(--text-faint);
    letter-spacing: 0.04em;
}
.player-tonight .pt-prop-strip-empty-msg {
    font-size: 11px;
    color: var(--text-faint);
    line-height: 1.5;
}

/* Recent form — compact rows with the slash line. */
.player-tonight .pt-recent-head,
.player-tonight .pt-h2h-head {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 6px;
}
.player-tonight .pt-recent {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 12px;
}
.player-tonight .pt-recent-row {
    display: grid;
    grid-template-columns: 90px 1fr;
    gap: 10px;
    align-items: baseline;
    padding: 3px 0;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}
.player-tonight .pt-recent-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--text-dim);
    text-transform: uppercase;
}
.player-tonight .pt-recent-line {
    color: var(--text);
}
.player-tonight .pt-recent-line strong {
    color: var(--text);
    font-weight: 600;
}
.player-tonight .pt-recent-dim .pt-recent-line {
    color: var(--text-dim);
    font-size: 11px;
}

/* Head-to-head — single line + sample note. */
.player-tonight .pt-h2h {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 12px;
}
.player-tonight .pt-h2h-line {
    font-size: 13px;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    margin-bottom: 4px;
}
.player-tonight .pt-h2h-note {
    font-size: 10px;
    color: var(--text-dim);
    font-style: italic;
}

/* Streak pills — sit at the bottom, only shown when notable. */
.player-tonight .pt-streaks {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.player-tonight .pt-streak-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--text);
    background: rgba(148, 163, 184, 0.1);
    padding: 4px 10px;
    border-radius: 99px;
}
.player-tonight .pt-streak-pill.pt-streak-hit {
    color: var(--accent-live);
    background: rgba(239, 68, 68, 0.12);
}

/* ── SLASH STRIP ─────────────────────────────────────────────────
   The headline 5-tile stat strip (AVG/OBP/SLG/OPS/HR) every site
   leads with. Big numbers, small caps label below. */
.slash-strip {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px 18px;
}
.slash-strip .ss-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 14px;
    gap: 12px;
}
.slash-strip .ss-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    color: var(--accent-action);
    text-transform: uppercase;
}
.slash-strip .ss-extra {
    font-size: 11px;
    color: var(--text-dim);
    font-weight: 500;
}
.slash-strip .ss-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 6px;
    margin-bottom: 12px;
}
.slash-strip .ss-tile {
    text-align: center;
    padding: 10px 6px;
    background: var(--bg);
    border-radius: calc(var(--radius) - 2px);
}
.slash-strip .ss-tile-counter { background: rgba(34, 197, 94, 0.08); }
.slash-strip .ss-val {
    font-size: 22px;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
    line-height: 1.1;
}
.slash-strip .ss-key {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.1em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-top: 4px;
}
.slash-strip .ss-counts {
    display: flex;
    align-items: baseline;
    gap: 6px;
    flex-wrap: wrap;
    font-size: 12px;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}
.slash-strip .ss-counts strong {
    color: var(--text);
    font-weight: 600;
}
.slash-strip .ss-dot {
    color: var(--text-dim);
    opacity: 0.4;
}

/* ── MATCHUP BAND ────────────────────────────────────────────────
   The visual centerpiece — vs LHP / vs RHP, current + career. Subtle
   blue tint distinguishes it from the rest as "the matchup engine
   angle." Other sites bury platoon under a tab; we promote it here. */
.matchup-band {
    background: rgba(59, 130, 246, 0.06);
    border: 1px solid rgba(59, 130, 246, 0.18);
    border-radius: var(--radius);
    padding: 14px 16px 18px;
}
.matchup-band .mb-band-title {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--accent-action);
    text-transform: uppercase;
    margin-bottom: 14px;
}
.matchup-band .mb-section + .mb-section { margin-top: 14px; }
.matchup-band .mb-section-head {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.1em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 8px;
}
.matchup-band .mb-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
}
@media (min-width: 640px) {
    .matchup-band .mb-grid { grid-template-columns: 1fr 1fr; }
}
.matchup-band .mb-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: calc(var(--radius) - 2px);
    padding: 12px 14px;
}
.matchup-band .mb-empty .mb-head { color: var(--text-dim); }
.matchup-band .mb-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 8px;
}
.matchup-band .mb-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text);
}
.matchup-band .mb-pa {
    font-size: 10px;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}
.matchup-band .mb-slash {
    display: flex;
    align-items: baseline;
    gap: 4px;
    margin-bottom: 8px;
    font-variant-numeric: tabular-nums;
}
.matchup-band .mb-slash-val {
    font-size: 17px;
    font-weight: 700;
    color: var(--text);
}
.matchup-band .mb-slash-sep {
    color: var(--text-dim);
    opacity: 0.5;
    font-size: 15px;
}
.matchup-band .mb-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 2px 0;
    font-size: 12px;
    color: var(--text-dim);
}
.matchup-band .mb-row strong {
    color: var(--text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* ── RATE PROFILE ────────────────────────────────────────────────
   The FanGraphs-style "advanced rates" mini-table. Current vs Career
   side-by-side. */
.rate-profile {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
}
.rate-profile .rp-head {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 10px;
}
.rate-profile .rp-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}
.rate-profile .rp-table thead th {
    text-align: right;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--text-dim);
    text-transform: uppercase;
    padding: 4px 8px 6px;
    border-bottom: 1px solid var(--border);
}
.rate-profile .rp-table tbody th {
    text-align: left;
    color: var(--text);
    padding: 7px 8px;
    font-weight: 500;
    font-size: 12px;
}
.rate-profile .rp-table tbody td {
    text-align: right;
    padding: 7px 8px;
    font-weight: 600;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.rate-profile .rp-table tbody tr + tr th,
.rate-profile .rp-table tbody tr + tr td {
    border-top: 1px solid rgba(255, 255, 255, 0.04);
}

/* ── OUTCOME BREAKDOWN ──────────────────────────────────────────
   The existing bar-chart view, kept smaller and below the new
   hierarchy. */
.outcome-breakdown {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
}
.outcome-breakdown .ob-head {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 10px;
}
.outcome-breakdown .ob-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
}
@media (min-width: 720px) {
    .outcome-breakdown .ob-grid { grid-template-columns: 1fr 1fr; }
}
.career-split-empty {
    opacity: 0.55;
}

.career-split {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
}
.career-split .cs-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}
.career-split .cs-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text);
    text-transform: uppercase;
}
.career-split .cs-pa {
    font-size: 10px;
    font-weight: 550;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
}
.cs-row {
    display: grid;
    grid-template-columns: 100px minmax(0, 1fr) 36px 50px;
    gap: 8px;
    align-items: center;
    font-size: 11px;
    padding: 3px 0;
    font-variant-numeric: tabular-nums;
}
.cs-outcome { color: var(--text); }
.cs-bar {
    height: 6px;
    background: var(--surface-2);
    border-radius: 3px;
    overflow: hidden;
}
.cs-bar > span {
    display: block;
    height: 100%;
    background: var(--accent-action);
}
.cs-row:first-of-type .cs-bar > span { background: var(--accent-win); }
.cs-row:first-of-type .cs-outcome,
.cs-row:first-of-type .cs-pct { color: var(--accent-win); font-weight: 600; }
.cs-pct {
    color: var(--text);
    text-align: right;
    font-weight: 550;
}
.cs-n {
    color: var(--text-dim);
    text-align: right;
    font-size: 10px;
}

.player-empty {
    padding: 40px 0;
    text-align: center;
    color: var(--text-dim);
    font-size: 13px;
    line-height: 1.6;
}
.player-empty p + p { margin-top: 8px; }

/* The clickable name everywhere it appears. Subtle hover so it doesn't
   shout "I'm a link" when you're reading the surrounding text. */
.player-link {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px dotted rgba(59, 130, 246, 0.3);
    transition: color 120ms ease, border-color 120ms ease;
}
.player-link:hover {
    color: var(--accent-action);
    border-bottom-color: var(--accent-action);
}

/* ── HOT MOMENTS VIEW ─────────────────────────────────────────── */
/* "Where should I be watching right now?" — the leverage-sorted feed
   of live moments. Bigger cards than the Board because each one is
   pitched as a destination, not part of a grid scan. */

.hot-view {
    flex: 1;
    overflow: auto;
    /* Bottom gutter for the fixed widgets — see .leaders-view. */
    padding: 10px 18px 100px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: 1620px;
    margin: 0 auto;
    width: 100%;
}
.hot-view .empty { padding: 60px 16px; }

.hot-head {
    display: flex;
    align-items: baseline;
    gap: 14px;
    flex-wrap: wrap;
}
.hot-head h2 {
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.hot-head .hot-flame {
    font-size: 17px;
    filter: drop-shadow(0 0 6px rgba(239, 68, 68, 0.4));
}
.hot-head .hot-meta {
    font-size: 11px;
    font-weight: 500;
    color: var(--text-dim);
    letter-spacing: 0.04em;
}

.hot-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
    gap: 8px;
}

.hot-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 8px 12px 10px;
    text-decoration: none;
    color: inherit;
    display: flex;
    flex-direction: column;
    gap: 5px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
    transition: transform 150ms ease, border-color 150ms ease,
                background 150ms ease, box-shadow 150ms ease;
    position: relative;
}
.hot-card:hover {
    transform: translateY(-2px);
    border-color: var(--accent-action);
    background: var(--surface-2);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
}

/* The top hot card gets a red glow — the implicit "this is THE one
   right now" without needing a separate hero card. */
.hot-card:first-child {
    border-color: rgba(239, 68, 68, 0.5);
    box-shadow:
        0 1px 3px rgba(0, 0, 0, 0.4),
        0 0 0 1px rgba(239, 68, 68, 0.25),
        0 0 28px rgba(239, 68, 68, 0.1);
}

.hot-card-head {
    display: flex;
    align-items: baseline;
    gap: 6px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--border);
}
.hot-rank {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--accent-action);
    font-variant-numeric: tabular-nums;
}
.hot-card:first-child .hot-rank { color: var(--accent-live); }

.hot-reason {
    flex: 1;
    font-size: 10px;
    font-weight: 550;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.hot-lev {
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 0.08em;
    color: var(--text-dim);
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
}

.hot-matchup {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.hot-team {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 2px 0;
}
.hot-team + .hot-team {
    border-top: 1px solid var(--border);
}
.hot-team-name {
    font-size: 12px;
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.005em;
}
.hot-team-score {
    font-size: 15px;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.hot-state {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    text-align: center;
    color: var(--accent-live);
    padding: 2px 6px;
    background: rgba(239, 68, 68, 0.08);
    border-radius: 4px;
}

.hot-we {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.hot-we-bar {
    height: 5px;
    background: var(--accent-live);
    border-radius: 3px;
    overflow: hidden;
}
.hot-we-bar > span {
    display: block;
    height: 100%;
    background: var(--accent-win);
    transition: width 400ms ease;
}
.hot-we-labels {
    display: flex;
    justify-content: space-between;
    font-size: 10px;
    font-weight: 550;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
}

/* Tiny leverage meter — taller card-level signal of "how hot is hot". */
.hot-meter {
    height: 3px;
    background: var(--bg);
    border-radius: 2px;
    overflow: hidden;
}
.hot-meter > span {
    display: block;
    height: 100%;
    background: linear-gradient(
        to right,
        var(--accent-action),
        var(--accent-live)
    );
}

.hot-cta {
    /* Whole card is the clickable link — hide the standalone CTA
       row to save vertical space. The accent border + cursor
       already cue "this is tappable." */
    display: none;
}
/* Watch button on each hot card — lets you watch a game straight from this
   view (no need to open the game first). */
.hot-actions { margin-top: 8px; }
.hot-watch {
    width: 100%;
    padding: 8px 10px;
    border: 0;
    border-radius: 8px;
    background: var(--accent-live, #e8554e);
    color: #fff;
    font: 700 0.82rem system-ui, sans-serif;
    cursor: pointer;
}
.hot-watch:hover { filter: brightness(1.06); }
.hot-we-labels {
    font-size: 10px;
}

/* ── BETS-ON-THIS-GAME STRIP ──────────────────────────────────── */
/* Shown above the mode toggle on every game view when the user
   has placed bets on the game. Pulls from the bot/practice fire
   log in localStorage; hidden when the game has none. */

.game-bets-strip {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 14px;
    margin: 12px 0 8px;
    background: rgba(15, 23, 42, 0.65);
    border: 1px solid var(--border);
    border-radius: 10px;
}
.game-bets-strip[data-practice="true"] {
    background: rgba(34, 197, 94, 0.05);
    border-color: rgba(34, 197, 94, 0.28);
}
.game-bets-compact {
    padding: 6px 10px;
    gap: 5px;
    margin: 8px 0 4px;
}
.game-bets-compact .game-bets-head {
    gap: 8px;
}
.game-bets-compact .game-bets-summary {
    font-size: 10px;
}
.game-bets-compact .game-bets-title {
    font-size: 11px;
}
.game-bets-compact .game-bets-list {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 2px 12px;
    font-size: 11px;
}
.game-bets-compact .game-bets-list li {
    gap: 6px;
}
.game-bets-compact .game-bets-tag {
    font-size: 9px;
    padding: 2px 6px;
}
.game-bets-toggle {
    appearance: none;
    background: rgba(56, 189, 248, 0.12);
    border: 1px solid rgba(56, 189, 248, 0.3);
    color: var(--accent-action, #38BDF8);
    font-family: inherit;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 3px 9px;
    border-radius: 999px;
    cursor: pointer;
    margin-left: auto;
}
.game-bets-toggle:hover {
    background: rgba(56, 189, 248, 0.22);
}
.game-bets-empty {
    font-size: 11px;
    color: var(--text-dim);
    margin: 4px 0;
    font-style: italic;
}
.game-bets-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.game-bets-tag {
    background: rgba(56, 189, 248, 0.2);
    color: #38BDF8;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-size: 10px;
    padding: 3px 9px;
    border-radius: 4px;
}
.game-bets-strip[data-practice="true"] .game-bets-tag {
    background: rgba(34, 197, 94, 0.22);
    color: #22C55E;
}
.game-bets-title {
    font-weight: 700;
    letter-spacing: 0.04em;
    font-size: 12px;
    color: var(--text);
}
.game-bets-summary {
    color: var(--text-dim);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    margin-left: auto;
}
.game-bets-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 4px 16px;
    font-size: 12px;
}
.game-bets-list li {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 0;
    min-width: 0;
}
.game-bets-badge {
    flex-shrink: 0;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.06em;
    padding: 2px 6px;
    border-radius: 4px;
}
.game-bets-badge-open { background: rgba(148, 163, 184, 0.18); color: var(--text-dim); }
.game-bets-badge-won  { background: rgba(34, 197, 94, 0.22); color: #22C55E; }
.game-bets-badge-lost { background: rgba(248, 113, 113, 0.22); color: #f87171; }
.game-bets-label {
    flex: 1;
    color: var(--text);
    /* No ellipsing — show the full label. If it's too long it
       wraps to the next line within the row. */
    white-space: normal;
    overflow-wrap: anywhere;
}
.game-bets-meta {
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}
.game-bets-pos { color: #22C55E; font-weight: 600; font-variant-numeric: tabular-nums; }
.game-bets-neg { color: #f87171; font-weight: 600; font-variant-numeric: tabular-nums; }
.game-bets-overflow {
    color: var(--text-dim);
    font-style: italic;
}

/* ── GAMECAST ──────────────────────────────────────────────────── */
/* Toggle bar above the game pane, segmented-control style. */

.game-mode-toggle {
    display: inline-flex;
    align-self: flex-start;
    margin: 0 32px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 2px;
}
.game-mode-toggle button {
    background: transparent;
    border: none;
    color: var(--text-dim);
    font-family: inherit;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    padding: 7px 14px;
    border-radius: 4px;
    cursor: pointer;
    transition: background 120ms ease, color 120ms ease;
}
.game-mode-toggle button:hover { color: var(--text); }
.game-mode-toggle button.active {
    background: var(--accent-action);
    color: white;
}
/* 'Watch' button sits next to the mode tabs but reads as a distinct
   primary action — red wash so it doesn't look like another tab.
   Clicking pops MLB.tv in a sized window the user positions next to
   the app (or PiPs from the player's own controls). */
.game-mode-toggle .game-watch-btn {
    background: rgba(239, 68, 68, 0.18);
    color: #FCA5A5;
    margin-left: 6px;
}
.game-mode-toggle .game-watch-btn:hover {
    background: rgba(239, 68, 68, 0.28);
    color: #FECACA;
}

.gamecast-pane {
    padding: 0 32px;
    flex: 1;
    min-height: 0;
}
.gamecast-loading,
.gamecast-pane .empty {
    text-align: center;
    color: var(--text-dim);
    padding: 60px 16px;
    font-size: 13px;
    letter-spacing: 0.04em;
}

/* ── BOX SCORE ──────────────────────────────────────────────────── */

/* Box-score pane mirrors the gamecast pane's outer chrome — same
   horizontal padding, same scrollable region. Inside, we stack a
   line-score grid and four team blocks (away batting, home batting,
   away pitching, home pitching) for textbook readability. */
.boxscore-pane {
    padding: 0 32px;
    flex: 1;
    min-height: 0;
}
.boxscore-loading,
.boxscore-pane .empty {
    text-align: center;
    color: var(--text-dim);
    padding: 60px 16px;
    font-size: 13px;
    letter-spacing: 0.04em;
}
.boxscore {
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding-bottom: 32px;
}

/* Team toggle inside the box-score pane — sits below the line score
   and above the batting/pitching tables. Segmented control, same
   visual language as the outer game-mode toggle but smaller. */
.bs-team-toggle {
    display: inline-flex;
    align-self: flex-start;
    gap: 0;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 3px;
}
.bs-team-toggle button {
    background: transparent;
    border: none;
    color: var(--text-dim);
    padding: 6px 16px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border-radius: calc(var(--radius) - 4px);
    cursor: pointer;
    transition: color 80ms ease, background 80ms ease;
}
.bs-team-toggle button:hover { color: var(--text); }
.bs-team-toggle button.active {
    background: var(--accent-action);
    color: white;
}

/* Line score: tight grid, big numbers, R/H/E pulled out with a
   stronger border so the eye lands on totals first. */
.bs-linescore {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.bs-linescore th,
.bs-linescore td {
    padding: 8px 10px;
    text-align: right;
    font-size: 13px;
    color: var(--text);
}
.bs-linescore thead th {
    background: var(--bg);
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--border);
}
.bs-linescore th.ls-tot-h {
    color: var(--text);
    font-weight: 700;
    background: var(--bg);
}
.bs-linescore .ls-team {
    text-align: left;
    font-weight: 700;
    letter-spacing: 0.06em;
}
.bs-linescore td.ls-tot {
    font-weight: 600;
    background: rgba(255, 255, 255, 0.02);
    border-left: 1px solid var(--border);
}
.bs-linescore td.ls-tot-r {
    color: var(--accent-win);
    font-weight: 700;
    font-size: 14px;
    border-left: 1px solid var(--border);
}
.bs-linescore tbody tr + tr td,
.bs-linescore tbody tr + tr th {
    border-top: 1px solid var(--border);
}

/* Per-team batting and pitching blocks. */
.bs-team-block {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.bs-team-head {
    padding: 10px 14px;
    margin: 0;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-dim);
    background: var(--bg);
    border-bottom: 1px solid var(--border);
}
.bs-table {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
    font-size: 13px;
}
.bs-table th,
.bs-table td {
    padding: 7px 8px;
    text-align: right;
    color: var(--text);
}
.bs-table thead th {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    color: var(--text-dim);
    text-transform: uppercase;
    border-bottom: 1px solid var(--border);
}
.bs-table tbody tr + tr td { border-top: 1px solid rgba(255,255,255,0.04); }
.bs-table tfoot td {
    border-top: 1px solid var(--border);
    color: var(--text);
    font-weight: 600;
    background: var(--bg);
}
.bs-table .bs-order {
    color: var(--text-dim);
    font-size: 11px;
    width: 24px;
    text-align: right;
    padding-right: 4px;
}
.bs-table .bs-name {
    text-align: left;
    color: var(--text);
    font-weight: 550;
    white-space: nowrap;
}
.bs-table .bs-name-wrap {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}
.bs-table .bs-photo {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--bg);
    object-fit: cover;
    object-position: center top;
    flex-shrink: 0;
}
.bs-table .bs-photo-empty {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--bg);
    flex-shrink: 0;
}
.bs-table .bs-name-text { display: inline-flex; align-items: baseline; gap: 0; }
.bs-table .bs-name .player-link {
    color: var(--text);
    border-bottom: 1px dotted var(--text-dim);
    text-decoration: none;
}
.bs-table .bs-name .player-link:hover {
    color: var(--accent-action);
    border-bottom-color: currentColor;
}
.bs-table .bs-pos {
    margin-left: 6px;
    font-size: 10px;
    font-weight: 550;
    color: var(--text-dim);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.bs-table .bs-decision {
    margin-left: 6px;
    font-size: 10px;
    font-weight: 600;
    color: var(--accent-action);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.bs-table .bs-season {
    color: var(--text-dim);
    font-weight: 500;
    border-left: 1px solid var(--border);
    padding-left: 10px;
}
.bs-table .bs-pitches {
    color: var(--text-dim);
    font-weight: 500;
    font-size: 11px;
}

.gamecast-list {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* One plate appearance — header (inning + matchup + outcome) plus the
   two-column body (prediction on the left, pitch sequence on the right). */
.pa-block {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

/* Thin between-PA baserunning event row — stolen bases, wild
   pitches, balks, pickoffs. Lighter than a PA block; reads as
   a one-line event in the gamecast stream. */
.br-row {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 7px 14px;
    background: rgba(15, 23, 42, 0.45);
    border: 1px solid var(--border);
    border-left: 3px solid rgba(245, 158, 11, 0.55);
    border-radius: 6px;
    font-size: 12px;
    color: var(--text-dim);
}
.br-row[data-event-type^="caught_stealing"],
.br-row[data-event-type^="pickoff"] {
    border-left-color: rgba(239, 68, 68, 0.55);
}
.br-row[data-event-type="balk"] {
    border-left-color: rgba(168, 85, 247, 0.6);
}
.br-inning {
    color: var(--text-dim);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-size: 10px;
}
.br-event {
    color: var(--text);
    font-weight: 600;
}
.br-runner {
    color: var(--text);
    text-decoration: none;
}
.br-runner:hover { text-decoration: underline; }
.br-desc {
    flex: 1;
    min-width: 0;
    color: var(--text-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.br-score {
    font-variant-numeric: tabular-nums;
    background: rgba(15, 23, 42, 0.8);
    padding: 2px 8px;
    border-radius: 3px;
    color: var(--text);
}
.br-we-delta {
    font-variant-numeric: tabular-nums;
    background: rgba(34, 197, 94, 0.18);
    color: #22C55E;
    padding: 2px 8px;
    border-radius: 3px;
    font-weight: 600;
}
.pa-block[data-outcome="HR"] {
    border-color: rgba(34, 197, 94, 0.5);
}
.pa-block[data-outcome="K"] {
    border-color: rgba(239, 68, 68, 0.4);
}

.pa-head {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 14px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
}
.pa-inning {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.16em;
    color: var(--accent-action);
    text-transform: uppercase;
}
.pa-matchup {
    font-size: 13px;
    color: var(--text);
    flex: 1;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
}
.pa-matchup .dim {
    color: var(--text-dim);
    font-weight: 500;
}
.pa-avatar-link { display: inline-flex; }
.pa-matchup .pa-avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--bg);
    object-fit: cover;
    object-position: center top;
    display: block;
}
.pa-matchup .pa-avatar-empty {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--bg);
    display: block;
}
.pa-score {
    font-size: 11px;
    font-weight: 600;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    padding: 2px 6px;
    background: var(--bg);
    border-radius: 3px;
    letter-spacing: 0.04em;
}
.pa-outcome-badge {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text);
    padding: 3px 8px;
    background: var(--bg);
    border-radius: 3px;
}
.pa-outcome-badge[data-outcome="HR"] {
    background: rgba(34, 197, 94, 0.18);
    color: var(--accent-win);
}
.pa-outcome-badge[data-outcome="K"] {
    background: rgba(239, 68, 68, 0.18);
    color: var(--accent-live);
}

/* WE swing per PA on the Gamecast — "+3.4pp WE" or "-1.8pp WE",
   color-coded so a single eye-scan tells you the home team gained or
   lost ground on that PA. Home-perspective; sign is straight from
   WE_TABLE_V2 lookups for the state before and after the PA. */
.pa-we-delta {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 3px 7px;
    border-radius: 3px;
    font-variant-numeric: tabular-nums;
}
.pa-we-delta.pa-we-pos {
    background: rgba(34, 197, 94, 0.16);
    color: var(--accent-win);
}
.pa-we-delta.pa-we-neg {
    background: rgba(239, 68, 68, 0.16);
    color: var(--accent-live);
}

.pa-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
    padding: 14px;
}
@media (min-width: 720px) {
    .pa-body {
        grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    }
}

.pa-section-head {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.14em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 8px;
}

.pa-no-data {
    font-size: 11px;
    color: var(--text-dim);
    font-style: italic;
    padding: 6px 0;
}

/* Predicted distribution — same visual grammar as the matchup card's
   outcome table, just compacted for the gamecast block. */
.pa-pred-row {
    display: grid;
    grid-template-columns: 90px minmax(0, 1fr) 36px 14px;
    gap: 8px;
    align-items: center;
    font-size: 11px;
    padding: 2px 0;
    font-variant-numeric: tabular-nums;
}
.pa-pred-label {
    color: var(--text-dim);
}
.pa-pred-bar {
    height: 6px;
    background: var(--surface-2);
    border-radius: 3px;
    overflow: hidden;
}
.pa-pred-bar > span {
    display: block;
    height: 100%;
    background: var(--accent-action);
}
.pa-pred-pct {
    color: var(--text);
    text-align: right;
    font-weight: 550;
}
.pa-pred-check {
    color: var(--accent-win);
    font-weight: 700;
    text-align: center;
}
.pa-pred-row.actual .pa-pred-label,
.pa-pred-row.actual .pa-pred-pct { color: var(--accent-win); font-weight: 600; }
.pa-pred-row.actual .pa-pred-bar > span { background: var(--accent-win); }

/* Pitch-by-pitch — number, type, velocity, result, count-after. */
.pa-pitch-row {
    display: grid;
    grid-template-columns: 16px 80px 60px minmax(0, 1fr) 28px;
    gap: 8px;
    align-items: baseline;
    font-size: 11px;
    padding: 4px 6px;
    border-radius: 3px;
    font-variant-numeric: tabular-nums;
}
.pa-pitch-row + .pa-pitch-row { margin-top: 2px; }
.pa-pitch-row.ball     { background: rgba(148, 163, 184, 0.06); }
.pa-pitch-row.strike   { background: rgba(239, 68, 68, 0.10); }
.pa-pitch-row.foul     { background: rgba(245, 158, 11, 0.08); }
.pa-pitch-row.in-play  { background: rgba(34, 197, 94, 0.12); }
.pa-pitch-num {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 600;
    text-align: right;
}
.pa-pitch-type {
    color: var(--text);
    font-weight: 550;
}
.pa-pitch-velo {
    color: var(--accent-action);
    font-weight: 600;
    text-align: right;
}
.pa-pitch-velo .dim {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 550;
    margin-left: 2px;
}
.pa-pitch-result {
    color: var(--text);
    font-weight: 500;
}
.pa-pitch-count {
    color: var(--text-dim);
    text-align: right;
    font-weight: 550;
    font-size: 10px;
}
/* Statcast hit data line — sits directly under the .pa-pitch-row
   for any pitch put in play. Indented under the type column so
   the relationship to the pitch above is obvious. Compact and dim
   so it doesn't compete with the pitch line. */
.pa-pitch-hit {
    margin: 2px 0 4px 32px;
    padding: 2px 6px;
    font-size: 10.5px;
    color: var(--accent-action, #38BDF8);
    background: rgba(56, 189, 248, 0.06);
    border-left: 2px solid rgba(56, 189, 248, 0.35);
    border-radius: 0 3px 3px 0;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
    display: inline-block;
}
.pa-pitch-hit strong {
    color: var(--text);
    font-weight: 700;
}

/* ── ABOUT / METHODS VIEW ─────────────────────────────────────── */

.about-view {
    flex: 1;
    overflow: auto;
    padding: 28px 24px 48px;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.about-doc {
    width: 100%;
    max-width: 720px;
    color: var(--text);
    line-height: 1.6;
    font-size: 14px;
}
.about-doc section {
    margin-top: 28px;
    padding-top: 24px;
    border-top: 1px solid var(--border);
}
.about-doc section:first-of-type { border-top: none; padding-top: 0; }

.about-head h1 {
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.005em;
    margin-bottom: 8px;
}
.about-head h1 .colon { color: var(--accent-win); }
.about-tagline {
    color: var(--text-dim);
    font-size: 14px;
    font-weight: 500;
}

.about-doc h2 {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.16em;
    color: var(--accent-action);
    text-transform: uppercase;
    margin-bottom: 14px;
}

.about-doc p {
    margin-bottom: 12px;
    color: var(--text);
}
.about-doc p:last-child { margin-bottom: 0; }

.about-doc ul,
.about-doc ol {
    margin: 8px 0 12px 22px;
    color: var(--text);
}
.about-doc li { margin-bottom: 5px; }

.about-doc a {
    color: var(--accent-action);
    text-decoration: none;
    border-bottom: 1px dotted rgba(59, 130, 246, 0.4);
    transition: border-color 120ms ease;
}
.about-doc a:hover { border-bottom-color: var(--accent-action); }

.about-doc code {
    font-family: 'SF Mono', Menlo, Consolas, monospace;
    font-size: 12px;
    padding: 1px 5px;
    border-radius: 3px;
    background: var(--surface-2);
    color: var(--accent-win);
}

.about-formula {
    font-family: 'SF Mono', Menlo, Consolas, monospace;
    font-size: 13px;
    padding: 10px 14px;
    margin: 8px 0 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent-win);
    border-radius: 4px;
    color: var(--text);
    overflow-x: auto;
}

.about-source {
    font-size: 12px;
    color: var(--text-dim);
    padding: 8px 10px;
    background: var(--surface);
    border-radius: 4px;
    margin-top: 10px;
    font-weight: 500;
}
.about-source strong { color: var(--text); }

.about-glossary {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 6px 18px;
    margin-top: 8px;
}
.about-glossary dt {
    color: var(--accent-action);
    font-weight: 600;
    font-size: 12px;
    letter-spacing: 0.04em;
}
.about-glossary dd {
    color: var(--text);
    font-size: 13px;
}

.dot-inline {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--accent-win);
    margin-right: 2px;
    vertical-align: middle;
}

.about-foot {
    margin-top: 32px;
    padding-top: 20px;
    border-top: 1px solid var(--border);
    font-size: 12px;
    color: var(--text-dim);
}
.about-foot p { margin-bottom: 6px; }
.about-foot .about-attribution {
    font-style: italic;
    line-height: 1.5;
    margin-top: 12px;
}

/* The "How it works" link in the matchup card's evidence line + the
   WE card's evidence line — same look as other dim cross-links. */
.evidence-link {
    color: var(--accent-action);
    text-decoration: none;
    border-bottom: 1px dotted rgba(59, 130, 246, 0.4);
    margin-left: 4px;
}
.evidence-link:hover { border-bottom-color: var(--accent-action); }

/* ── PAGE FOOTER ───────────────────────────────────────────────── */
/* Required Retrosheet attribution + MLB Stats API credit. Tiny strip at
   the very bottom of the page so it's never the foreground but is always
   reachable. Sits below the nav so the nav stays the primary action bar. */
.page-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 6px 20px;
    background: var(--bg);
    border-top: 1px solid var(--border);
    /* Was 10 — too small next to the 12px model-accuracy line in
       the middle. 11 reads cleanly and stays a quiet step below
       the calibration line, preserving the hierarchy. */
    font-size: 11px;
    font-weight: 500;
    color: var(--text-dim);
    letter-spacing: 0.04em;
    flex-shrink: 0;
}
.page-footer a {
    color: var(--text-dim);
    text-decoration: none;
    border-bottom: 1px dotted var(--border);
    transition: color 150ms ease, border-color 150ms ease;
}
.page-footer a:hover {
    color: var(--text);
    border-bottom-color: var(--text);
}
.page-footer .build-meta {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}
.page-footer .version {
    font-variant-numeric: tabular-nums;
    color: var(--accent-action);
    font-weight: 600;
    letter-spacing: 0.08em;
}

/* "Model: 42% top-pick · Brier 0.13 · over 7,067 PAs · how" — the
   calibration line. Sits in the middle of the footer so it reads as
   a piece of evidence between the data credits (left) and source +
   version (right). */
.page-footer .model-accuracy {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text);
    font-weight: 500;
    letter-spacing: 0.02em;
    font-size: 12px;
}
.page-footer .model-accuracy strong {
    color: var(--accent-win);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}
.page-footer .model-accuracy .ma-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent-win);
}
.page-footer .model-accuracy .ma-link {
    color: var(--text-dim);
    margin-left: 2px;
}
.page-footer .model-accuracy .ma-link:hover {
    color: var(--text);
}
.page-footer .model-accuracy .ma-variant {
    color: var(--text-dim);
    font-size: 11px;
    cursor: help;
    border-bottom: 1px dotted var(--text-dim);
}

/* ── GAME VIEW ─────────────────────────────────────────────────── */

.game-view {
    flex: 1;
    overflow: auto;
    /* Bottom gutter so the fixed strip/launcher clear the last
       PA block — same 100px applied to other long views. */
    padding: 12px 0 100px;
    display: flex;
    flex-direction: column;
    /* User feedback: 'it feels very close.' Scale down the whole game
       view ~10% so cards / field / cards-pane breathe. zoom is the
       right primitive — unlike transform: scale it reflows the
       layout so click targets / hover / scroll all stay aligned with
       the visual representation. Chrome / Safari / Edge support it
       natively; Firefox 126+ also supports it. */
    zoom: 0.9;
}
.game-view .empty { padding: 48px 16px; }

.back-link {
    color: var(--accent-action);
    text-decoration: none;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.12em;
    padding: 0 32px 10px;
    align-self: flex-start;
    transition: color 150ms ease;
}
.back-link:hover { color: var(--text); }

/* Game-view ticker. Thin strip at the top showing every other game on the
   slate so you can keep an eye on the scoreboard while you're inside one
   game. Click to swap. Horizontal scrolls if the slate is wider than the
   viewport. Sticks to the top so it stays visible when the Game view itself
   scrolls. */
.ticker {
    position: sticky;
    top: 0;
    z-index: 5;
    display: flex;
    gap: 4px;
    padding: 6px 12px 8px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    overflow-x: auto;
    overflow-y: hidden;
    margin: 0 0 18px;
    scrollbar-width: thin;
}
.ticker::-webkit-scrollbar { height: 6px; }
.ticker::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

.ticker-game {
    flex-shrink: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 10px;
    align-items: center;
    padding: 5px 9px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 4px;
    text-decoration: none;
    color: inherit;
    min-width: 96px;
    transition: border-color 120ms ease, background 120ms ease;
}
.ticker-game:hover {
    border-color: var(--accent-action);
    background: var(--surface-2);
}
.ticker-game.active {
    border-color: var(--accent-action);
    background: var(--surface-2);
    box-shadow: 0 0 0 1px var(--accent-action);
}
.ticker-game[data-status="Live"] .t-state {
    color: var(--accent-live);
}

.ticker-game .t-teams {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}
.ticker-game .t-row {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.15;
}
.ticker-game .t-abbr {
    color: var(--text);
    letter-spacing: 0.01em;
}
.ticker-game .t-score {
    color: var(--text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.ticker-game[data-status="Preview"] .t-score {
    color: var(--text-dim);
    font-weight: 550;
}
.ticker-game .t-state {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--text-dim);
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
}

/* When the ticker is present, the back link sits just above it and the
   game-pane gets a small side gutter. */
.game-view .game-pane {
    padding: 0 32px;
}

.game-pane {
    display: grid;
    grid-template-columns: 1fr;
    gap: 36px;
    justify-items: center;
    align-items: start;
    /* Cap the whole live view at a comfortable max — without this the
       grid columns sprawl on ultra-wide displays and leave a giant
       empty band to the LEFT of the field. Centered so the layout
       breathes on every screen size. */
    max-width: 1800px;
    margin: 0 auto;
    width: 100%;
}
@media (min-width: 820px) {
    .game-pane {
        /* Field area is the centerpiece — give it a slightly bigger
           share than the WE/market panel so the stadium silhouette
           dominates the live view. */
        grid-template-columns: minmax(0, 11fr) minmax(0, 8fr);
        justify-items: stretch;
        gap: 36px;
    }
    /* Asymmetric scroll, per user spec:
         - Scrolling over the RIGHT panel scrolls ONLY the right panel,
           the field/rail stay put.
         - Scrolling over the LEFT (field area) scrolls the whole
           game-view as normal — so you can still get to the bottom
           of the page (footer / about / etc.) by scrolling the field.
       Implementation: the field column is just normal flow. The
       card-pane (right) caps its own height to the viewport and
       enables internal vertical scroll, so wheel events delivered
       over it pump its internal scroll. overscroll-behavior: contain
       stops a fast right-side scroll from escaping into the page
       once the card-pane bottoms out. */
    .game-pane > .card-pane {
        align-self: start;
        max-height: calc(100vh - 140px);
        overflow-y: auto;
        overscroll-behavior: contain;
        scrollbar-width: thin;
        scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
        /* tiny right gutter so the scrollbar doesn't clip card content */
        padding-right: 6px;
    }
    .game-pane > .card-pane::-webkit-scrollbar { width: 8px; }
    .game-pane > .card-pane::-webkit-scrollbar-thumb {
        background: rgba(255, 255, 255, 0.18);
        border-radius: 4px;
    }
    .game-pane > .card-pane::-webkit-scrollbar-track { background: transparent; }
}

/* ── FIELD ────────────────────────────────────────────────────── */

.field-pane {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    width: 100%;
}
.field-pane .field-canvas {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    order: 1;
}
.field-pane .field-narrative {
    width: 100%;
    order: 2;     /* below the canvas at narrow widths (same as before) */
}
.field-pane .field-narrative .this-inning { margin: 0; }

/* Two-column live view: the "this-inning" play-by-play promotes from
   below-the-field to a left rail beside the field, and the field SVG
   stops getting capped at 500px so the stadium silhouette fills the
   center column. Empty space on the LEFT of the field becomes the
   live narrative the user is actually following — what just happened
   this frame. */
@media (min-width: 1200px) {
    /* Only games with a live this-inning strip get the 2-column rail.
       Final / Preview games keep the single-column field-canvas so
       the centered field doesn't get pushed to the right of a blank
       sidebar slot. Narrative column kept tight (220-260px) so the
       field gets the rest of the column to stretch into. */
    .field-pane.has-narrative {
        display: grid;
        grid-template-columns: minmax(220px, 260px) minmax(0, 1fr);
        align-items: start;
        gap: 20px;
    }
    .field-pane.has-narrative .field-narrative {
        /* Independent scroll on the left rail — symmetric to the
           right .card-pane treatment. User can scroll through the
           inning's play-by-play (and any future left-rail content)
           without moving the field or affecting the right column. */
        position: sticky;
        top: 60px;
        width: auto;
        grid-column: 1;
        order: unset;
        max-height: calc(100vh - 140px);
        overflow-y: auto;
        overscroll-behavior: contain;
        scrollbar-width: thin;
        scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
        padding-right: 6px;
    }
    .field-pane.has-narrative .field-narrative::-webkit-scrollbar { width: 8px; }
    .field-pane.has-narrative .field-narrative::-webkit-scrollbar-thumb {
        background: rgba(255, 255, 255, 0.18);
        border-radius: 4px;
    }
    .field-pane.has-narrative .field-narrative::-webkit-scrollbar-track { background: transparent; }
    .field-pane.has-narrative .field-canvas {
        width: 100%;
        grid-column: 2;
        order: unset;
    }
}

/* Per-park photo backdrop: when we have a free photo of the home park, it sits
   behind the field as immersive ambiance (darkened so the field + data stay
   legible). The angled photo and the top-down diagram can't merge 1:1, so the
   photo is mood, the diagram is the data. .has-park-photo gates it. */
/* 3D ballpark model (field3d.js) — the WebGL canvas sits over the field box;
   the SVG still defines the size but is hidden beneath it. */
.field-pane.has-3d .field-canvas { position: relative; }
.field-pane.has-3d .field { visibility: hidden; }
.field3d-mount {
    position: absolute;
    inset: 0;
    z-index: 3;
    border-radius: var(--radius);
    overflow: hidden;
    background: #0b1220;
}
.field-pane.has-park-photo .field-canvas { position: relative; }
.field-pane.has-park-photo .park-backdrop {
    position: absolute;
    inset: -8px;
    background-size: cover;
    background-position: center;
    border-radius: calc(var(--radius) + 8px);
    filter: brightness(0.42) saturate(1.05);
    z-index: 0;
    pointer-events: none;
}
.field-pane.has-park-photo .field-canvas > *:not(.park-backdrop) { position: relative; z-index: 1; }
/* Let the photo breathe through the field's own stadium bowl + seating. */
.field-pane.has-park-photo .field .stadium-bowl { opacity: 0.30; }
.field-pane.has-park-photo .field .seating { opacity: 0.45; }
.field {
    width: 100%;
    /* User feedback 2026-06-02: 'make the field proportionately
       smaller so you can see what's below it without scrolling.'
       Cap the field at 540px so the stadium silhouette doesn't eat
       the entire viewport, and 'RECENT 30' / 'Top Nth · X out ·
       bases · count' below the field become visible without
       scrolling. Centered via the parent flex column. */
    max-width: 540px;
    margin: 0 auto;
    aspect-ratio: 1;
    display: block;
    filter: drop-shadow(0 4px 16px rgba(0, 0, 0, 0.5));
    border-radius: var(--radius);
    overflow: hidden;
}

/* Stadium bowl backdrop — replaces the transparent SVG background
   with a dark-concrete radial gradient so the field sits inside a
   "ballpark" rather than floating on the page color. */
.field .stadium-bowl {
    fill: url(#stadium-bowl);
}

/* Seating decks behind the outfield wall and along the foul lines.
   Three concentric rings — lower → upper → outer concourse — get
   progressively darker so the bowl reads as depth from above. */
.field .stadium-concourse {
    fill: #131A2A;
    stroke: rgba(255, 255, 255, 0.04);
    stroke-width: 0.5;
}
.field .stadium-upper {
    fill: #1C2436;
    stroke: rgba(255, 255, 255, 0.06);
    stroke-width: 0.5;
}
.field .stadium-lower {
    fill: #2B3450;
    stroke: rgba(255, 255, 255, 0.04);
    stroke-width: 0.5;
}

/* Foul-territory dirt — warm tan band between the foul lines and
   the lower bowl, including the catcher's-box area behind home plate. */
.field .foul-dirt {
    fill: #8A6A40;
    opacity: 0.78;
}

.field .outfield-grass {
    fill: url(#grass-radial);
    stroke: var(--border);
    stroke-width: 1;
}

/* Outfield mowing pattern — realistic alternating light/dark concentric
   stripes centered on home plate (abutting 40px bands at low opacity), clipped
   to fair territory. Subtle, not the old single heavy black ribbing. */
.field .grass-stripes circle {
    fill: none;
    stroke-width: 40;
    pointer-events: none;
}
.field .grass-stripes .stripe-dark  { stroke: rgba(0, 0, 0, 0.055); }
.field .grass-stripes .stripe-light { stroke: rgba(255, 255, 255, 0.038); }
.field .warning-track {
    fill: var(--dirt-dark);
}
.field .basepath {
    stroke: var(--dirt);
    stroke-width: 11;
    stroke-linejoin: miter;
    fill: none;
    opacity: 0.85;
}
.field .infield-grass {
    fill: url(#grass-radial-inner);
}
.field .foul-line {
    stroke: var(--chalk);
    stroke-width: 1.5;
    fill: none;
}
.field .mound {
    fill: var(--dirt);
    stroke: var(--dirt-dark);
    stroke-width: 0.5;
}
.field .rubber { fill: var(--chalk); }

.field .base {
    fill: var(--chalk);
    stroke: var(--text-dim);
    stroke-width: 0.5;
    transition: fill 200ms ease, filter 200ms ease;
}
.field .base[data-occupied="true"] {
    fill: var(--accent-win);
    stroke: var(--accent-win);
    filter: drop-shadow(0 0 8px rgba(34, 197, 94, 0.8));
}
.field .base.home {
    fill: var(--chalk);
}

.field .foul-pole {
    fill: #FCD34D;
}

/* Dugouts along the 1B and 3B baselines — dark recessed rectangles
   parallel to the foul lines, just on the foul side. The "home" team
   dugout is the 1B side by MLB convention (visiting team on 3B). */
.field .dugout rect {
    fill: #0A0F1C;
    stroke: rgba(255, 255, 255, 0.18);
    stroke-width: 0.6;
}
.field .dugout-home rect {
    fill: #11192C;          /* faint warm tint for home dugout */
}

/* Bullpens — pitchers' mounds in foul territory beyond each baseline.
   Drawn as small dirt rectangles with a rounded shape to suggest the
   bullpen mound area without cluttering the field. */
.field .bullpen rect {
    fill: var(--dirt);
    stroke: var(--dirt-dark);
    stroke-width: 0.5;
    opacity: 0.85;
}

/* Center-field scoreboard — sits just outside the deepest CF wall.
   Mirrors what every park has there: away/inning/home, big numerals,
   thin dividers. Dark panel, bright text. */
.field .cf-scoreboard .sb-bg {
    fill: #050810;
    stroke: rgba(255, 220, 120, 0.18);
    stroke-width: 0.6;
}
.field .cf-scoreboard .sb-divider {
    stroke: rgba(255, 220, 120, 0.22);
    stroke-width: 0.6;
}
.field .cf-scoreboard .sb-team {
    fill: #FCD34D;
    font-family: 'Inter', sans-serif;
    font-size: 7.5px;
    font-weight: 700;
    letter-spacing: 0.10em;
}
.field .cf-scoreboard .sb-runs {
    fill: #FFFFFF;
    font-family: 'Inter', sans-serif;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.02em;
}
.field .cf-scoreboard .sb-inning {
    fill: #FFFFFF;
    font-family: 'Inter', sans-serif;
    font-size: 8.5px;
    font-weight: 600;
    letter-spacing: 0.08em;
}
.field .cf-scoreboard .sb-status {
    fill: rgba(255, 255, 255, 0.55);
    font-family: 'Inter', sans-serif;
    font-size: 5.5px;
    font-weight: 600;
    letter-spacing: 0.12em;
}

/* Stadium light towers in the four corners. Each is a small mast
   with a glowing head — yellower / brighter during live games to
   suggest the lights are on. */
.field .light-tower .lt-bracket {
    fill: #2A3142;
}
.field .light-tower .lt-head {
    fill: #FCD34D;
    opacity: 0.65;
    filter: drop-shadow(0 0 4px rgba(252, 211, 77, 0.5));
}
.field-pane[data-we-intensity] .light-tower .lt-head {
    opacity: 0.95;
    filter: drop-shadow(0 0 7px rgba(252, 211, 77, 0.75));
}

/* Park-specific warning track — drawn as a thick darker stroke inset
   from the wall by ~12 ft so the outfield silhouette stays accurate. */
.field .warning-track-park {
    fill: none;
    stroke: var(--dirt-dark);
    stroke-width: 9;
    stroke-linejoin: round;
    opacity: 0.55;
}

/* Posted distance numerals (310, 379, 420 …) at the canonical wall
   reference points. Small / dim so they read as park labels, not
   game state. */
.field .field-dist {
    fill: rgba(255, 255, 255, 0.55);
    font-family: 'Inter', sans-serif;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    paint-order: stroke;
    stroke: rgba(0, 0, 0, 0.65);
    stroke-width: 2;
}

/* Park name strip across the top of the field — the most "broadcast"
   element on the SVG. */
.field .field-park-name {
    fill: rgba(255, 255, 255, 0.75);
    font-family: 'Inter', sans-serif;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.18em;
    paint-order: stroke;
    stroke: rgba(0, 0, 0, 0.6);
    stroke-width: 3;
    text-transform: uppercase;
}

/* Park flavor chips — roof, turf, elevation, landmark — displayed
   under the field SVG so each park's character (Coors's altitude,
   Tropicana's dome, Fenway's Green Monster) is one-glance obvious. */
.field-park-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 8px 12px 0;
}
.fpc {
    display: inline-flex;
    align-items: center;
    height: 22px;
    padding: 0 8px;
    border-radius: 11px;
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-dim);
    font-family: 'Inter', sans-serif;
    font-size: 10px;
    font-weight: 550;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.fpc-dome        { background: rgba(168, 85, 247, 0.18);  color: #D8B4FE; }
.fpc-retractable { background: rgba(99, 102, 241, 0.18);  color: #A5B4FC; }
.fpc-turf        { background: rgba(34, 197, 94, 0.14);   color: #86EFAC; }
.fpc-elev        { background: rgba(245, 158, 11, 0.18);  color: #FCD34D; }
.fpc-landmark    { background: rgba(220, 38, 38, 0.18);   color: #FCA5A5; }

/* Iconic-park landmarks — Fenway's Green Monster, Yankees's short
   porch, Wrigley's ivy, Oracle's McCovey Cove. Drawn over the wall. */
.field .park-landmark {
    fill: none;
    stroke-linecap: round;
}
.field .park-landmark.monster {
    stroke: #166534;   /* deep monster green */
    stroke-width: 7;
    filter: drop-shadow(0 0 4px rgba(22, 101, 52, 0.7));
}
.field .park-landmark.short-porch {
    stroke: #DC2626;   /* yankees red hint */
    stroke-width: 3;
    stroke-dasharray: 4 2;
    opacity: 0.85;
}
.field .park-landmark.ivy {
    stroke: #4D7C0F;   /* ivy green */
    stroke-width: 4;
    opacity: 0.8;
}
.field .park-landmark.cove {
    stroke: #38BDF8;   /* San Francisco bay blue */
    stroke-width: 5;
    opacity: 0.7;
    filter: drop-shadow(0 0 6px rgba(56, 189, 248, 0.5));
}

.field .runner-name {
    fill: var(--text);
    font-family: 'Inter', sans-serif;
    font-size: 7.5px;
    font-weight: 550;
    letter-spacing: 0.02em;
    paint-order: stroke;
    stroke: var(--bg);
    stroke-width: 2.2;
}

/* Clean broadcast-style player name tags INSIDE the SVG — a subtle dark pill
   so the field stays informative without big stroked text on the dirt.
   Pitcher at the mound, batter in his box. */
.field .field-nametag rect {
    fill: rgba(8, 12, 20, 0.82);
    stroke: rgba(255, 255, 255, 0.14);
    stroke-width: 1;
}
.field .field-nametag .fnt-name {
    fill: #FFFFFF;
    font-family: 'Inter', sans-serif;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}
.field .field-nametag .fnt-sub {
    fill: rgba(255, 255, 255, 0.62);
    font-family: 'Inter', sans-serif;
    font-size: 8.5px;
    font-weight: 600;
    letter-spacing: 0.08em;
}
.field .field-nametag.fnt-batter .fnt-name { fill: #FCD34D; }   /* yellow batter */
.field .field-nametag.fnt-batter rect { stroke: rgba(252, 211, 77, 0.30); }

/* Field | Pitch view toggle (MLB.tv-style) + the two switchable views. */
.field-canvas { position: relative; }
.field-view-toggle {
    position: absolute; top: 10px; right: 10px;
    z-index: 6; display: inline-flex; gap: 2px; padding: 3px;
    background: rgba(12, 18, 30, 0.82); border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 999px; backdrop-filter: blur(4px);
}
.fv-btn {
    appearance: none; border: 0; cursor: pointer;
    padding: 6px 16px; border-radius: 999px; background: transparent;
    color: var(--text-dim); font: 600 13px 'Inter', sans-serif;
    text-transform: uppercase; letter-spacing: 0.03em; transition: background 0.15s, color 0.15s;
}
.field-pane.view-field .fv-btn[data-fv="field"],
.field-pane.view-pitch .fv-btn[data-fv="pitch"] { background: var(--accent-action); color: #fff; }
/* Switch which view shows. */
.field-pane.view-pitch .field { visibility: hidden; }
.field-pane.view-field .pitch-view { display: none; }
.pitch-view {
    position: absolute; inset: 0; z-index: 4;
    display: flex; align-items: center; justify-content: center;
    flex-direction: column; padding: 12px;
}
/* MLB Gameday-style pitch graphic for the main Pitch view. */
.pitch-scene {
    width: 100%; max-width: 540px;
    display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.ps-stage {
    position: relative; width: 100%; aspect-ratio: 600 / 446;
    border-radius: 14px; overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.10);
    box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5);
}
.ps-scene { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.ps-plate { fill: #eef1f4; stroke: rgba(0, 0, 0, 0.22); stroke-width: 1.5; }
.ps-box { fill: none; stroke: rgba(255, 255, 255, 0.30); stroke-width: 2; }
/* Batter: uniformed body in team colors with the player's real headshot. */
.bz-shadow { fill: rgba(0, 0, 0, 0.32); }
.bz-pants, .bz-torso2, .bz-sleeve, .bz-bat { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.bz-pants { stroke: #d2d6db; stroke-width: 19; }
.bz-torso2 { stroke-width: 37; }   /* stroke set inline (team jersey color) */
.bz-sleeve { stroke-width: 11; }   /* stroke set inline (team jersey color) */
.bz-bat { stroke: #c08a4e; stroke-width: 9; }
.bz-helmet { stroke: rgba(0, 0, 0, 0.22); stroke-width: 1; }
/* Strike-zone 3D box */
.ps-zone-back { fill: none; stroke: rgba(150, 195, 255, 0.35); stroke-width: 1.5; }
.ps-zone-face2 { fill: rgba(70, 150, 240, 0.10); stroke: rgba(150, 195, 255, 0.30); stroke-width: 1; }
.ps-zone { fill: rgba(70, 150, 240, 0.16); stroke: rgba(185, 218, 255, 0.95); stroke-width: 3; }
.ps-grid { stroke: rgba(200, 226, 255, 0.45); stroke-width: 1.5; }
.ps-num { font: 700 14px 'Inter', sans-serif; fill: #fff; pointer-events: none; }
/* Hot zones: per-cell OPS color (MLB red→blue) painted on the 3×3 face. */
.ps-hz { transition: fill 0.4s ease; cursor: help; }
.ps-legend {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: center;
    font: 600 11px 'Inter', sans-serif; color: var(--text-dim); letter-spacing: 0.03em;
}
.ps-leg-label { text-transform: uppercase; }
.ps-leg-scale { display: inline-flex; align-items: center; gap: 3px; }
.ps-leg-scale em { font-style: normal; color: var(--text-faint); margin: 0 2px; }
.ps-leg-scale i { width: 13px; height: 11px; border-radius: 2px; display: inline-block; }
.ps-pitch { cursor: help; }
.ps-ring { fill: none; stroke: #fff; stroke-width: 3; filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.7)); }
.ps-incoming {
    fill: #fff; opacity: 0; offset-distance: 0%;
    filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.95));
}
.pitch-scene.pitch-throw .ps-incoming { animation: ps-fly 0.5s ease-in forwards; }
.pitch-scene.pitch-throw .ps-latest {
    transform-box: fill-box; transform-origin: center;
    animation: ps-dot-in 0.25s ease 0.42s both;
}
@keyframes ps-fly {
    0%   { offset-distance: 0%;   opacity: 0.25; r: 3; }
    25%  { opacity: 1; }
    100% { offset-distance: 100%; opacity: 1; r: 9; }
}
@keyframes ps-dot-in {
    from { opacity: 0; transform: scale(0.2); }
    to   { opacity: 1; transform: scale(1); }
}
.ps-head {
    font: 700 13px 'Inter', sans-serif; letter-spacing: 0.04em;
    color: var(--text); text-transform: uppercase; text-align: center;
}
.ps-empty { font-size: 12px; color: var(--text-faint); }
@media (prefers-reduced-motion: reduce) {
    .pitch-scene.pitch-throw .ps-incoming,
    .pitch-scene.pitch-throw .ps-latest { animation: none; }
    .ps-incoming { opacity: 0; }
}
.pv-empty { color: var(--text-faint); font-size: 13px; }

/* Pitcher (at the mound) + batter (at the plate) name tags on the field —
   small, with a dark outline so they read over grass/dirt without a pill. */
.field .field-name {
    font-family: 'Inter', sans-serif; font-size: 11px; font-weight: 600;
    letter-spacing: 0.01em; paint-order: stroke;
    stroke: rgba(8, 12, 20, 0.92); stroke-width: 3.2; stroke-linejoin: round;
}
.field .fn-pitcher { fill: #e8eef7; }
.field .fn-batter { fill: #FCD34D; }

/* Ball-in-play: hit spray line + landing marker, drawn inside the field SVG. */
.hit-fx { pointer-events: none; }
.hit-arc {
    fill: none; stroke: #FCD34D; stroke-width: 3; stroke-linecap: round;
    opacity: 0.92; filter: drop-shadow(0 0 4px rgba(252, 211, 77, 0.5));
}
.hit-spot { fill: rgba(252, 211, 77, 0.26); }
.hit-core { fill: #FCD34D; stroke: #fff; stroke-width: 1.5; }
/* The ball itself — hidden at rest; only visible mid-flight during play-pop. */
.hit-ball { fill: #fff; opacity: 0; offset-distance: 0%;
    filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.95)); }

/* On a fresh ball in play: the arc draws, the ball flies along it to the
   landing spot, then the landing marker pops. After play-pop ends the arc +
   marker persist as a static "where it went" overlay (ball stays hidden). */
.field-pane.play-pop .hit-arc {
    stroke-dasharray: 660; stroke-dashoffset: 660;
    animation: hit-draw 0.9s cubic-bezier(0.4, 0.7, 0.3, 1) forwards;
}
.field-pane.play-pop .hit-ball {
    animation: hit-fly 0.9s cubic-bezier(0.4, 0.7, 0.3, 1) forwards;
}
.field-pane.play-pop .hit-spot { animation: spot-pop 0.5s ease 0.82s both; }
.field-pane.play-pop .hit-core { animation: core-pop 0.6s ease 0.82s both; }
@keyframes hit-draw { to { stroke-dashoffset: 0; } }
@keyframes hit-fly {
    0%   { offset-distance: 0%;   opacity: 1; }
    85%  { opacity: 1; }
    100% { offset-distance: 100%; opacity: 0; }
}
@keyframes spot-pop { 0% { r: 0; opacity: 0; } 60% { opacity: 1; } 100% { r: 11; opacity: 1; } }
@keyframes core-pop { 0% { r: 0; } 55% { r: 9; } 100% { r: 4.5; } }

/* Play card as a thin bar across the whole bottom of the field (single line).
   Shows in both views and fades out ~10s after a play (see handlePlayBlurb). */
.play-blurb {
    position: absolute; left: 3%; right: 3%; bottom: 12px;
    z-index: 6; text-align: center;
    background: rgba(10, 15, 24, 0.90); border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 10px; padding: 7px 16px; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
    font-size: 13px; line-height: 1.3;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    transition: opacity 0.8s ease;
}
.play-blurb.pb-faded { opacity: 0; pointer-events: none; }
.pb-desc { font-weight: 600; color: #e8eef7; }
.pb-meta { font-size: 11px; color: var(--accent-win); margin-left: 7px; letter-spacing: 0.02em; }

/* Pitch-section game-state bar (score / inning / count / outs). */
.ps-state {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    font: 600 13px 'Inter', sans-serif; color: var(--text); letter-spacing: 0.02em;
}
.ps-state b { font-weight: 800; }
.ps-st-inn { color: var(--text-dim); text-transform: uppercase; font-size: 12px; }
.ps-st-dot { color: var(--text-faint); }
.ps-st-cnt { font-variant-numeric: tabular-nums; }
.ps-st-outs { color: var(--text-dim); }
.field-pane.play-pop .play-blurb { animation: blurb-pop 0.5s ease 0.7s both; }
@keyframes blurb-pop {
    0% { transform: translateX(-50%) translateY(10px) scale(0.92); opacity: 0; }
    100% { transform: translateX(-50%) translateY(0) scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .field-pane.play-pop .hit-arc,
    .field-pane.play-pop .hit-ball,
    .field-pane.play-pop .hit-spot,
    .field-pane.play-pop .hit-core,
    .field-pane.play-pop .play-blurb { animation: none; }
}

/* Strike-zone plot (catcher's view) — current at-bat's pitches in the zone. */
.strike-zone { margin: 8px 0 4px; }
.sz-head {
    font-size: 10.5px; color: var(--text-dim);
    text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 5px;
}
.sz-svg { width: 156px; height: 204px; display: block; }
.sz-box { fill: rgba(255, 255, 255, 0.045); stroke: rgba(255, 255, 255, 0.55); stroke-width: 1.6; }
.sz-grid { stroke: rgba(255, 255, 255, 0.16); stroke-width: 1; }
.sz-plate { fill: rgba(255, 255, 255, 0.9); stroke: rgba(0, 0, 0, 0.35); stroke-width: 0.8; }
.sz-num { font: 700 9px 'Inter', sans-serif; fill: #fff; pointer-events: none; }
.sz-pitch { cursor: help; }
.sz-empty { text-align: center; font-size: 11px; color: var(--text-faint); margin-top: 6px; }

/* Explain-on-hover tooltip (any element with data-tip). See initTips(). */
.dc-tip {
    position: fixed;
    z-index: 9999;
    max-width: 268px;
    padding: 9px 12px;
    background: rgba(12, 18, 30, 0.97);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 8px;
    color: #e8eef7;
    font-size: 12.5px;
    line-height: 1.42;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55);
    pointer-events: none;
    opacity: 0;
    transform: translateY(3px);
    transition: opacity 0.12s ease, transform 0.12s ease;
}
.dc-tip.visible { opacity: 1; transform: translateY(0); }
/* Signal that a stat label is explainable. */
[data-tip] { cursor: help; }
.ts-key[data-tip] {
    border-bottom: 1px dotted rgba(255, 255, 255, 0.28);
    padding-bottom: 1px;
}

/* Count + outs broadcast chip in the upper-right of the SVG. */
.field .field-count-chip rect {
    fill: rgba(11, 18, 32, 0.85);
    stroke: rgba(255, 255, 255, 0.15);
    stroke-width: 1;
}
.field .fcc-count {
    fill: #FFFFFF;
    font-family: 'Inter', sans-serif;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.04em;
}
.field .fcc-outs {
    fill: rgba(255, 255, 255, 0.65);
    font-family: 'Inter', sans-serif;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

/* State banner under the field for Final / Preview games. */
.field-state-banner {
    margin: 12px 0 6px;
    text-align: center;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--text);
    padding: 8px 14px;
    border-radius: var(--radius);
    background: rgba(148, 163, 184, 0.1);
}
.field-state-banner.final {
    background: rgba(148, 163, 184, 0.18);
    color: var(--text);
}
.field-state-banner.preview,
.field-state-banner.scheduled {
    background: rgba(56, 189, 248, 0.12);
    color: var(--accent-action);
}

/* WE intensity hint — a green glow ringing the field when decisive */
.field-pane[data-we-intensity] .field {
    filter:
        drop-shadow(0 4px 16px rgba(0, 0, 0, 0.5))
        drop-shadow(0 0 calc(var(--we-intensity, 0) * 24px) rgba(34, 197, 94, calc(var(--we-intensity, 0) * 0.4)));
}

/* ── SITUATION + PLAYER ROWS ──────────────────────────────────── */

.situation {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 13px;
    font-weight: 550;
    color: var(--text);
    padding: 8px 16px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 999px;
}
.situation .dot { color: var(--text-dim); }
.situation .state-label {
    color: var(--text-dim);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.15em;
}

.player-row {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 14px;
    color: var(--text);
    width: 100%;
    max-width: 500px;
    padding: 10px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.player-row-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.player-row-stats {
    font-size: 11px;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
    line-height: 1.2;
}

/* AT BAT + PITCHING side-by-side so both are visible above-the-fold on
   wider screens. Stacks back to one column on narrow viewports. */
.matchup-pair {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
    width: 100%;
    max-width: 760px;
}
.matchup-pair .player-row { max-width: none; }
@media (min-width: 720px) {
    .matchup-pair {
        grid-template-columns: 1fr 1fr;
    }
}
/* Rail variant — lives in the narrow LEFT sidebar above the
   play-by-play so the user can see who's hitting and who's pitching
   without scrolling. Always stacked single-column (narrow rail). */
.field-narrative .matchup-pair-rail {
    grid-template-columns: 1fr;
    max-width: none;
    margin-bottom: 14px;
}
.field-narrative .matchup-pair-rail .player-row {
    padding: 6px 9px;
    font-size: 11px;
    gap: 8px;
}
.field-narrative .matchup-pair-rail .player-row strong { font-size: 12px; }
.field-narrative .matchup-pair-rail .player-row .pr-avatar {
    flex: 0 0 28px;
    width: 26px;
    height: 26px;
}
.field-narrative .matchup-pair-rail .player-row .label {
    font-size: 10px;
    letter-spacing: 0.12em;
}

/* Live View pitch-by-pitch — same look as the Gamecast pitch rows
   but for the IN-PROGRESS at-bat. Compact list, color-coded by pitch
   result (ball / strike / foul / in-play). */
.current-pitches {
    width: 100%;
    max-width: 760px;
    margin-top: 6px;
    padding: 10px 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.current-pitches .cp-head {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 4px;
}
.current-pitches .cp-row {
    display: grid;
    grid-template-columns: 18px 70px 60px 1fr 40px;
    gap: 8px;
    align-items: baseline;
    padding: 4px 6px;
    border-radius: 4px;
    font-size: 12px;
    line-height: 1.3;
    color: var(--text);
}
.current-pitches .cp-row + .cp-row { border-top: 1px solid var(--border); }
.current-pitches .cp-num {
    color: var(--text-faint);
    font-size: 10px;
    font-weight: 600;
}
.current-pitches .cp-type    { font-weight: 600; }
.current-pitches .cp-velo    { color: var(--text-dim); font-variant-numeric: tabular-nums; }
.current-pitches .cp-velo .dim { font-size: 10px; color: var(--text-faint); margin-left: 2px; }
.current-pitches .cp-result  { color: var(--text-dim); font-size: 12px; }
.current-pitches .cp-count   {
    color: var(--text-dim);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    text-align: right;
}
.current-pitches .cp-row.ball     { background: rgba(59, 130, 246, 0.07); }
.current-pitches .cp-row.strike   { background: rgba(220, 38, 38, 0.10);  }
.current-pitches .cp-row.foul     { background: rgba(245, 158, 11, 0.08); }
.current-pitches .cp-row.in-play  { background: rgba(34, 197, 94, 0.10); }
.player-row .label {
    color: var(--text);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    flex: 0 0 72px;
}
/* Small circular avatar in the AT BAT / PITCHING rows — links to
   the player profile. MLB CDN spot photos are 7KB, lazy-loaded,
   gracefully fade to a neutral circle if the image fails. */
.player-row .pr-avatar {
    flex: 0 0 48px;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--bg);
    border: 1px solid var(--border);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.player-row .pr-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    display: block;
}
.player-row .pr-avatar-empty {
    /* nothing inside; just a neutral circle */
}
.player-row strong {
    color: var(--text);
    font-weight: 550;
    flex: 1;
    font-size: 14px;
}
.player-row .hand {
    color: var(--accent-action);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    padding: 3px 8px;
    background: rgba(59, 130, 246, 0.15);
    border-radius: 4px;
}

/* ── CONTEXT CARD ─────────────────────────────────────────────── */

.card-pane { width: 100%; }

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px 22px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    /* Was hard-capped at 420px which left the right column with a
       narrow card stacked in the middle and 240+ px of dead space
       beside it (visible as "scroll to see everything" since cards
       could only ever stack). Bumped so the right column actually
       uses its real width. */
    max-width: 580px;
    margin: 0 auto;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

/* Side-by-side grid for sub-cards INSIDE the headline card. Used
   to pair the projected-WE slot and the end-of-game forecast slot
   so they share a horizontal row instead of forcing the user to
   scroll past both stacked vertically. */
.card .card-side-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
}
.card .card-side-grid > div { min-width: 0; }
@media (min-width: 1100px) {
    .card .card-side-grid {
        grid-template-columns: 1fr 1fr;
        align-items: start;
    }
    .card .card-side-grid > div:empty { display: none; }
}

.card .subject {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.15em;
    text-transform: uppercase;
}

/* "LIVE" pill on the WE card — same visual grammar as the header pill,
   smaller and inline. Pulsing dot signals "this number is fresh." */
.card .subject .we-live {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 9px;
    background: var(--accent-live);
    color: #fff;
    border-radius: 10px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.18em;
    line-height: 1;
}
.card .subject .we-live-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #fff;
    animation: pulse 1.5s ease-in-out infinite;
}

/* Projected-WE block — sits between the current WE bar and the
   evidence line in the WE card. Shows where the WE is headed if the
   current PA unfolds as the matchup engine predicts, plus the
   leverage of the PA (gap between current and projected). */
.projected-we {
    margin-top: 14px;
    padding: 10px 12px;
    background: var(--surface-2);
    border-left: 2px solid var(--accent-action);
    border-radius: 0 4px 4px 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 11px;
    line-height: 1.4;
}
.projected-we .pw-headline {
    display: flex;
    align-items: baseline;
    gap: 6px;
    flex-wrap: wrap;
    color: var(--text);
    font-weight: 500;
}
.projected-we .pw-headline strong {
    color: var(--text);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}
.projected-we .pw-arrow {
    font-weight: 700;
    font-size: 11px;
}
.projected-we .pw-arrow.up   { color: var(--accent-win); }
.projected-we .pw-arrow.down { color: var(--accent-live); }
.projected-we .pw-arrow.flat { color: var(--text-dim); }
/* Per-pitch count badge on the projected-WE headline — same style as
   the matchup-card count-aware badge, smaller. Sits next to the WE%
   so it reads as "this number is keyed to this exact count." */
.projected-we .pw-count {
    display: inline-block;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--accent-action);
    background: rgba(59, 130, 246, 0.12);
    padding: 1px 5px;
    border-radius: 3px;
    cursor: help;
    font-variant-numeric: tabular-nums;
}
.projected-we .pw-lev {
    margin-left: auto;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--accent-action);
    text-transform: uppercase;
}
.projected-we .pw-range {
    color: var(--text-dim);
    font-weight: 500;
    font-size: 11px;
}
.projected-we .pw-range strong {
    color: var(--text);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

/* ── BULLPEN-AWARE FORECAST ────────────────────────────────────────
   The Monte Carlo end-of-game projection that uses THIS team's actual
   lineup + matchup engine + predicted reliever sequence. Subtle green
   tint to signal "forward-looking — the edge over public engines."
   Sits just below the projected-WE block. */
.forecast-we {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 12px;
    padding: 10px 12px;
    background: rgba(34, 197, 94, 0.05);
    border: 1px solid rgba(34, 197, 94, 0.18);
    border-radius: var(--radius);
    font-size: 11px;
    line-height: 1.4;
}
.forecast-we .fwe-headline {
    display: flex;
    align-items: baseline;
    gap: 6px;
    flex-wrap: wrap;
    color: var(--text);
    font-weight: 500;
}
.forecast-we .fwe-headline strong {
    color: var(--text);
    font-weight: 700;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}
.forecast-we .fwe-arrow-pre {
    font-weight: 700;
}
.forecast-we .fwe-arrow-pre.up   { color: var(--accent-win); }
.forecast-we .fwe-arrow-pre.down { color: var(--accent-live); }
.forecast-we .fwe-arrow-pre.flat { color: var(--text-dim); }
.forecast-we .fwe-tag {
    margin-left: auto;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent-win);
    background: rgba(34, 197, 94, 0.12);
    padding: 1px 6px;
    border-radius: 3px;
    cursor: help;
}
.forecast-we .fwe-chain {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
    color: var(--text-dim);
    font-weight: 550;
    font-size: 11px;
}
.forecast-we .fwe-pitcher {
    color: var(--text);
    cursor: help;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    vertical-align: middle;
}
.forecast-we .fwe-photo {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--bg);
    object-fit: cover;
    object-position: center top;
}
.forecast-we .fwe-photo-empty {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--bg);
}
.forecast-we .fwe-name {
    color: var(--text);
    text-decoration: none;
    border-bottom: 1px dotted var(--text-dim);
}
.forecast-we a.fwe-name:hover {
    color: var(--accent-action);
    border-bottom-color: currentColor;
}
.forecast-we .fwe-arrow {
    color: var(--text-dim);
    opacity: 0.5;
    font-size: 10px;
}
.forecast-we .fwe-meta {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 500;
    font-style: italic;
}
.forecast-we .fwe-chain-label {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin-right: 4px;
}
.forecast-we .fwe-role {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 550;
    margin-left: 3px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* "Why is X favored?" — one-liner under the bar labels that explains
   the WE in plain English (bases, outs, count, lead). Replaces the
   "what does this number mean?" blank stare. */
.card .why-line {
    margin-top: 6px;
    padding: 6px 10px;
    background: rgba(148, 163, 184, 0.06);
    border-left: 2px solid var(--accent-action);
    color: var(--text);
    font-size: 12px;
    line-height: 1.45;
    font-style: italic;
    border-radius: 0 var(--radius) var(--radius) 0;
}

/* ── TEAM STRENGTH CARD ─────────────────────────────────────────────
   Two-team comparison showing the data feeding the team-strength
   WE adjustment. Sits below the why-line, above the projected/forecast
   blocks. Only shown when the adjustment is meaningful (≥ 1pp). */
.team-strength {
    margin-top: 10px;
    padding: 10px 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.team-strength .ts-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 8px;
    flex-wrap: wrap;
}
.team-strength .ts-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text-dim);
    text-transform: uppercase;
}
.team-strength .ts-summary {
    font-size: 11px;
    color: var(--text);
    font-weight: 500;
}
.team-strength .ts-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}
.team-strength .ts-side {
    background: var(--bg);
    border-radius: calc(var(--radius) - 2px);
    padding: 8px 10px;
}
.team-strength .ts-side-head {
    display: flex;
    align-items: baseline;
    gap: 6px;
    margin-bottom: 6px;
    padding-bottom: 5px;
    border-bottom: 1px solid var(--border);
}
.team-strength .ts-abbr {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--text);
}
.team-strength .ts-record {
    font-size: 11px;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}
.team-strength .ts-streak {
    margin-left: auto;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    padding: 1px 5px;
    border-radius: 2px;
    background: rgba(148, 163, 184, 0.12);
    color: var(--text-dim);
}
.team-strength .ts-streak-win  { color: var(--accent-win); background: rgba(34, 197, 94, 0.12); }
.team-strength .ts-streak-loss { color: var(--accent-live); background: rgba(239, 68, 68, 0.12); }

.team-strength .ts-rows {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.team-strength .ts-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}
.team-strength .ts-key {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.team-strength .ts-val {
    color: var(--text);
    font-weight: 600;
}
.team-strength .ts-pct {
    color: var(--text-dim);
    font-weight: 500;
    font-size: 10px;
}
.team-strength .ts-row-bold {
    padding-top: 3px;
    border-top: 1px solid var(--border);
    margin-top: 2px;
}
.team-strength .ts-row-bold .ts-key,
.team-strength .ts-row-bold .ts-val {
    color: var(--accent-action);
}

/* ── THIS INNING strip ──────────────────────────────────────────────
   Plays from the current half-inning, oldest first, ending with the
   live "NOW" row for the at-bat in progress. Sits under the field
   pane's diamond + AT BAT / PITCHING rows on the Live View. */
.this-inning {
    margin-top: 14px;
    padding: 10px 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

/* Rail bets card — left-rail companion to AT BAT / PITCHING that
   shows positions on the current at-bat with per-bet progress bars.
   Same surface treatment as .this-inning so it visually belongs in
   the rail stack. Progress markup is shared with the drawer rows
   (.bot-progress*) so styling stays consistent. */
.rail-bets-card {
    margin-top: 14px;
    padding: 10px 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.rail-bets-card[data-practice="true"] {
    background: rgba(34, 197, 94, 0.05);
    border-color: rgba(34, 197, 94, 0.28);
}
.rail-bets-head {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 6px;
    cursor: pointer;
    user-select: none;
}
/* Collapsed by default: header only, body hidden until expanded. */
.rail-bets-card.is-collapsed .rail-bets-head { margin-bottom: 0; }
.rail-bets-card.is-collapsed .rail-bets-body { display: none; }
.rail-bets-headsum {
    margin-left: auto;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-dim);
    white-space: nowrap;
}
.rail-bets-chev {
    flex: 0 0 auto;
    color: var(--text-faint);
    font-size: 11px;
    transition: transform 0.15s ease;
}
.rail-bets-card:not(.is-collapsed) .rail-bets-chev { transform: rotate(90deg); }
.rail-bets-card:not(.is-collapsed) .rail-bets-headsum { display: none; }
.rail-bets-tag {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.14em;
    padding: 2px 6px;
    border-radius: 4px;
    background: rgba(56, 189, 248, 0.16);
    color: var(--accent-action, #38BDF8);
}
.rail-bets-card[data-practice="true"] .rail-bets-tag {
    background: rgba(34, 197, 94, 0.18);
    color: #4ADE80;
}
.rail-bets-title {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-dim);
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rail-bets-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    font-size: 10.5px;
    color: var(--text-dim);
}
.rail-bets-count {
    font-variant-numeric: tabular-nums;
}
.rail-bets-cost {
    font-variant-numeric: tabular-nums;
}
.rail-bets-toggle {
    appearance: none;
    margin-left: auto;
    background: rgba(56, 189, 248, 0.12);
    border: 1px solid rgba(56, 189, 248, 0.3);
    color: var(--accent-action, #38BDF8);
    font-family: inherit;
    font-size: 10px;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 999px;
    cursor: pointer;
}
.rail-bets-toggle:hover {
    background: rgba(56, 189, 248, 0.22);
}
.rail-bet-pos { color: #4ADE80; font-variant-numeric: tabular-nums; }
.rail-bet-neg { color: #F87171; font-variant-numeric: tabular-nums; }
.rail-bets-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.rail-bet-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 6px 8px;
    background: rgba(15, 23, 42, 0.55);
    border: 1px solid rgba(148, 163, 184, 0.12);
    border-radius: 6px;
}
.rail-bet-head {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
}
.rail-bet-side {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.06em;
    padding: 2px 5px;
    border-radius: 3px;
}
.rail-bet-side-yes {
    background: rgba(34, 197, 94, 0.18);
    color: #4ADE80;
}
.rail-bet-side-no {
    background: rgba(248, 113, 113, 0.18);
    color: #F87171;
}
.rail-bet-label {
    flex: 1;
    min-width: 0;
    color: var(--text);
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rail-bet-state {
    font-size: 10px;
    font-variant-numeric: tabular-nums;
    color: var(--text-dim);
    white-space: nowrap;
}
.rail-bet-open  { color: var(--text-dim); }
.rail-bet-won   { color: #4ADE80; font-weight: 600; }
.rail-bet-lost  { color: #F87171; font-weight: 600; }
/* Live mark-to-market block: 2-line stack with the live P/L delta
   on top (colored) and the entry → live cents underneath in dim. */
.rail-bet-live {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-end;
    line-height: 1.1;
    gap: 2px;
}
.rail-bet-mark {
    font-weight: 600;
    font-size: 11px;
}
.rail-bet-entry {
    color: var(--text-dim);
    font-size: 9.5px;
}
.rail-bet-row .bot-progress {
    margin: 0;
    padding: 0;
    border-top: none;
}
.rail-bet-sell {
    appearance: none;
    align-self: flex-end;
    margin-top: 4px;
    background: rgba(248, 113, 113, 0.14);
    border: 1px solid rgba(248, 113, 113, 0.32);
    color: #F87171;
    font-family: inherit;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.04em;
    padding: 3px 9px;
    border-radius: 999px;
    cursor: pointer;
    font-variant-numeric: tabular-nums;
}
.rail-bet-sell:hover {
    background: rgba(248, 113, 113, 0.24);
    color: #FCA5A5;
}
.rail-bet-sell:disabled {
    opacity: 0.6;
    cursor: progress;
}
.rail-bet-row .bot-progress-row {
    font-size: 10px;
}
/* Inline meter — always rendered for open bets so the user sees the
   bar shape even before the first boxscore tick lands. */
.rail-meter {
    margin-top: 4px;
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.rail-meter-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    font-size: 10px;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}
.rail-meter-stat strong {
    color: var(--text);
    font-weight: 600;
}
.rail-meter-status {
    font-size: 9.5px;
    letter-spacing: 0.04em;
}
.rail-meter-track {
    position: relative;
    height: 4px;
    background: rgba(148, 163, 184, 0.14);
    border-radius: 2px;
    overflow: hidden;
}
.rail-meter-fill {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    border-radius: 2px;
    transition: width 250ms;
}
.rail-meter-fill-yes { background: #22C55E; }
.rail-meter-fill-no  { background: #F59E0B; }
.rail-bets-empty {
    margin: 4px 0 0;
    font-size: 10.5px;
    color: var(--text-dim);
    font-style: italic;
}
.this-inning .ti-head {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 8px;
}
.this-inning .ti-row {
    display: grid;
    /* Two-row layout: top row is chevron · outcome · avatar · batter.
       Description wraps onto its own line UNDER the batter name so
       narrow rails don't push the desc into a tall thin column.
       User direction (2026-06-05): 'Put this under his name. … clean
       this up so no words overlap.' */
    grid-template-columns: 10px 40px 28px minmax(0, 1fr);
    grid-template-areas:
        "chev outcome avatar batter"
        ".    .       desc   desc";
    gap: 2px 8px;
    align-items: center;
    padding: 4px 0;
    font-size: 12px;
    line-height: 1.4;
}
.this-inning .ti-row-chev   { grid-area: chev; }
.this-inning .ti-outcome    { grid-area: outcome; }
.this-inning .ti-photo,
.this-inning .ti-photo-empty { grid-area: avatar; }
.this-inning .ti-batter     { grid-area: batter; min-width: 0; }
.this-inning .ti-desc {
    grid-area: desc;
    color: var(--text-dim);
    font-size: 11px;
    line-height: 1.35;
    padding-top: 1px;
    /* Empty descs collapse so the row stays single-line. */
}
.this-inning .ti-desc:empty { display: none; }
.ti-row-chev {
    color: var(--text-dim);
    font-size: 9px;
    text-align: center;
}
.ti-row-chev-blank { visibility: hidden; }
.ti-row-clickable { cursor: pointer; }
.ti-row-clickable:hover { background: rgba(56, 189, 248, 0.05); }
.ti-row-pitches {
    margin: 4px 0 4px 18px;
    padding: 4px 6px;
    background: rgba(15, 23, 42, 0.55);
    border-left: 2px solid rgba(56, 189, 248, 0.35);
    border-radius: 0 4px 4px 0;
}
.this-inning .ti-photo {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--bg);
    object-fit: cover;
    object-position: center top;
    display: block;
}
.this-inning .ti-photo-empty {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--bg);
    display: block;
}
.this-inning .ti-row + .ti-row {
    border-top: 1px solid rgba(255,255,255,0.04);
}
.this-inning .ti-outcome {
    text-align: center;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: rgba(148, 163, 184, 0.1);
    color: var(--text-dim);
    padding: 2px 4px;
    border-radius: 3px;
    font-variant-numeric: tabular-nums;
}
.this-inning .ti-out  { background: rgba(239, 68, 68, 0.15);  color: var(--accent-live); }
.this-inning .ti-walk { background: rgba(59, 130, 246, 0.15); color: var(--accent-action); }
.this-inning .ti-hit  { background: rgba(34, 197, 94, 0.18);  color: var(--accent-win); }
.this-inning .ti-batter {
    color: var(--text);
    font-weight: 550;
    white-space: nowrap;
}
.this-inning .ti-batter a {
    color: var(--text);
    text-decoration: none;
    border-bottom: 1px dotted var(--text-dim);
}
.this-inning .ti-batter a:hover {
    color: var(--accent-action);
    border-bottom-color: currentColor;
}
.this-inning .ti-desc {
    color: var(--text-dim);
    font-size: 11px;
    line-height: 1.4;
}

/* Live pitch sequence for the current PA — same row shape as the
   gamecast pitch rows, sized down to fit the narrow Live-View rail. */
.this-inning .ti-pitches {
    margin: 6px 0 4px;
    padding: 6px 0 2px;
    border-top: 1px solid rgba(255,255,255,0.04);
    border-bottom: 1px solid rgba(255,255,255,0.04);
}
.this-inning .ti-pitches-head {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.12em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 4px;
}
.this-inning .ti-pitches .pa-pitch-row,
.ti-row-pitches .pa-pitch-row {
    /* Type column was 1fr so 'Changeup' filled its cell edge-to-edge
       and visually crashed into the velo (user feedback 2026-06-05:
       'Slide the mph to the right'). max-content sizes the type to
       its own text width and lets the gap actually breathe. Result
       column gets the leftover space. */
    grid-template-columns: 18px max-content minmax(0, max-content) minmax(0, 1fr) 24px;
    gap: 12px;
    font-size: 11px;
    padding: 3px 0;
}
.this-inning .ti-pitches .pa-pitch-velo,
.this-inning .ti-pitches .pa-pitch-result,
.this-inning .ti-pitches .pa-pitch-type,
.ti-row-pitches .pa-pitch-velo,
.ti-row-pitches .pa-pitch-result,
.ti-row-pitches .pa-pitch-type {
    font-size: 11px;
}
.this-inning .ti-pitches .pa-pitch-num,
.ti-row-pitches .pa-pitch-num {
    font-size: 10px;
}
.this-inning .ti-now {
    background: rgba(59, 130, 246, 0.06);
    margin: 4px -12px -10px;
    padding: 6px 12px 8px;
    border-radius: 0 0 var(--radius) var(--radius);
    border-top: 1px solid rgba(59, 130, 246, 0.18);
}
.this-inning .ti-now-chip {
    background: var(--accent-action);
    color: white;
}

.card .situation-line {
    color: var(--text);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.01em;
}

.card .question {
    color: var(--text);
    font-size: 14px;
    font-weight: 500;
    margin-top: 4px;
}

/* Count-aware badge on the matchup card — sits inline with the
   "What's about to happen?" question to make it clear that the
   prediction is reading the live pitch count, not just batter-vs-
   pitcher averages. Refreshes every pitch via hydrateMatchup. */
.matchup-card .count-aware-badge {
    display: inline-block;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent-action);
    background: rgba(59, 130, 246, 0.12);
    padding: 2px 6px;
    border-radius: 3px;
    margin-left: 8px;
    vertical-align: middle;
    cursor: help;
}

/* Form strip on the matchup card — hot/cold pills for batter and/or
   pitcher when their recent (last 30 days) hit-rate has meaningfully
   diverged from their season baseline. Sits just below the subject
   line so it's visually attached to "who's batting / pitching." */
/* Matchup-card subject row — small circular avatars next to each
   player name, with player-link click-through. Same MLB CDN spot
   photos as the at-bat / pitching rows on the field pane. */
.matchup-card .subject {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
}
.matchup-card .mc-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--bg);
    border: 1px solid var(--border);
    display: inline-flex;
    flex-shrink: 0;
    text-decoration: none;
}
.matchup-card .mc-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    display: block;
}
.matchup-card .mc-vs {
    color: var(--text-dim);
    font-weight: 550;
    margin: 0 4px;
}

.matchup-card .form-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 6px 0 8px;
}
.matchup-card .form-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 2px 8px;
    border-radius: 99px;
    cursor: help;
}
.matchup-card .form-pill.form-hot {
    color: var(--accent-live);
    background: rgba(239, 68, 68, 0.12);
    border: 1px solid rgba(239, 68, 68, 0.3);
}
.matchup-card .form-pill.form-cold {
    color: #60A5FA;
    background: rgba(59, 130, 246, 0.10);
    border: 1px solid rgba(59, 130, 246, 0.3);
}

.card .answer {
    display: flex;
    align-items: baseline;
    gap: 10px;
    font-size: 34px;
    font-weight: 700;
    letter-spacing: -0.025em;
    font-variant-numeric: tabular-nums;
    color: var(--accent-win);
    line-height: 1;
}
.card .answer strong { font-weight: 700; }

.card .bar {
    height: 6px;
    background: var(--surface-2);
    position: relative;
    overflow: hidden;
    border-radius: 3px;
}
.card .bar span {
    display: block;
    height: 100%;
    background: var(--accent-win);
    transition: width 400ms ease;
}

.card .bar-labels {
    display: flex;
    justify-content: space-between;
    font-size: 10px;
    color: var(--text-dim);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.card .evidence {
    color: var(--text-dim);
    font-size: 12px;
    line-height: 1.55;
    border-top: 1px solid var(--border);
    padding-top: 12px;
}

.card .read {
    color: var(--text);
    font-size: 13px;
    line-height: 1.55;
    font-style: italic;
    font-weight: 400;
}

/* ── WE TRACE CARD ────────────────────────────────────────────── */
/* The win-expectancy curve over the game. One point per completed
   half-inning. Visual companion to the "WE right now" number above. */
.card-pane > .trace-card { margin-top: 20px; }

.trace-card .trace-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}
.trace-card .trace-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.18em;
    color: var(--accent-action);
    text-transform: uppercase;
}
.trace-card .trace-meta {
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.04em;
    color: var(--text-dim);
    text-align: right;
}
.trace-card .trace-svg {
    width: 100%;
    height: auto;
    display: block;
    margin: 4px 0 6px;
}
.trace-card .trace-axis {
    display: flex;
    justify-content: space-between;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.14em;
    color: var(--text-dim);
    text-transform: uppercase;
    margin-bottom: 8px;
}
.trace-card .trace-foot {
    font-size: 12px;
    color: var(--text);
    padding-top: 8px;
    border-top: 1px solid var(--border);
    line-height: 1.4;
}
.trace-card .trace-foot strong {
    color: var(--accent-win);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

/* Chart wrap holds the SVG + the absolutely-positioned tooltip so the
   tooltip's coordinates can be wrap-relative. */
.trace-card .trace-chart-wrap {
    position: relative;
    width: 100%;
}

/* Interactive markers — dim until hovered. The biggest-swing marker
   and the final/current point stay bright so they're discoverable
   without scrubbing. */
.trace-card .trace-marker {
    opacity: 0.35;
    cursor: pointer;
    transition: opacity 120ms ease, r 120ms ease;
}
.trace-card .trace-marker.biggest {
    opacity: 1;
    filter: drop-shadow(0 0 4px rgba(239, 68, 68, 0.55));
}
.trace-card .trace-marker.final {
    opacity: 1;
}
.trace-card .trace-marker:hover,
.trace-card .trace-marker:focus {
    opacity: 1;
    outline: none;
}

/* Chart-area hover overlay — transparent rect on top of the SVG that
   captures pointer events for the WHOLE chart, not just the small per-
   PA dots. pointer-events: all (not the default visiblePainted) so
   that mousemove fires over the transparent fill. cursor:crosshair to
   signal "this whole surface is interactive." */
.trace-card .trace-overlay {
    pointer-events: all;
    cursor: crosshair;
}

/* Guide line + follower dot drawn by the chart-hover handler. Both
   pointer-events: none so they don't block the overlay's hover. */
.trace-card .trace-guide,
.trace-card .trace-guide-dot {
    pointer-events: none;
}

/* Existing markers stay clickable (for pin-on-click and keyboard
   tabbing) but their pointer-events default doesn't get in the way
   of the overlay because they sit on top of it in SVG paint order. */
.trace-card .trace-marker { cursor: pointer; }

/* Tooltip — absolutely positioned inside trace-chart-wrap. JS computes
   left/top to keep it inside the chart bounds. pointer-events: auto so
   the batter / pitcher names inside it are clickable; the mouseout
   handlers in app.js are aware of the marker↔tooltip boundary and don't
   hide when the cursor moves between them. */
.trace-card .trace-tooltip {
    position: absolute;
    z-index: 4;
    min-width: 200px;
    max-width: 280px;
    background: var(--bg);
    border: 1px solid var(--accent-action);
    border-radius: 4px;
    padding: 8px 10px;
    font-size: 11px;
    line-height: 1.4;
    color: var(--text);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
    pointer-events: auto;
}
.trace-card .trace-tooltip[hidden] { display: none !important; }
.trace-card .tt-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
    font-variant-numeric: tabular-nums;
    margin-bottom: 6px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.trace-card .tt-inning {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--accent-action);
    text-transform: uppercase;
}
.trace-card .tt-score {
    color: var(--text);
    font-weight: 600;
    font-size: 12px;
}
.trace-card .tt-we {
    color: var(--accent-win);
    font-weight: 700;
    font-size: 12px;
}
.trace-card .tt-swing {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--accent-live);
    text-transform: uppercase;
}
.trace-card .tt-event {
    font-weight: 600;
    color: var(--text);
    font-size: 12px;
    margin-bottom: 4px;
}
.trace-card .tt-players {
    color: var(--text-dim);
    font-weight: 500;
    margin-bottom: 4px;
    font-size: 10px;
    letter-spacing: 0.03em;
    display: flex;
    align-items: center;
    gap: 5px;
    flex-wrap: wrap;
}
.trace-card .tt-link-with-photo {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.trace-card .tt-photo {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--bg);
    object-fit: cover;
    object-position: center top;
    display: block;
}
.trace-card .tt-photo-empty {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--bg);
    display: block;
}
.trace-card .tt-desc {
    color: var(--text);
    font-weight: 400;
    font-size: 11px;
    line-height: 1.5;
}

/* Pitch-by-pitch sequence inside the trace tooltip — sits below the
   event/description lines. Tight grid: number, type code, velocity,
   result, count-after. Color the result so the eye can sweep down the
   pitch column and find the action without reading. */
.trace-card .tt-pitches {
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid var(--border);
}
.trace-card .tt-pitches-head {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 4px;
}
.trace-card .tt-pitch {
    display: grid;
    grid-template-columns: 14px 22px 48px 1fr 26px;
    gap: 6px;
    align-items: baseline;
    font-size: 10px;
    line-height: 1.4;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}
.trace-card .tp-num     { color: var(--text-dim); text-align: right; }
.trace-card .tp-type    { color: var(--text); font-weight: 600; }
.trace-card .tp-velo    { color: var(--text-dim); }
.trace-card .tp-res     { font-weight: 500; }
.trace-card .tp-count   { color: var(--text-dim); text-align: right; font-weight: 550; }

/* Result coloring — same accents we use elsewhere so the eye learns
   the palette across the app. */
.trace-card .tp-ball           { color: var(--accent-action); }
.trace-card .tp-strike-called  { color: var(--accent-live);   }
.trace-card .tp-strike-swing   { color: var(--accent-live);   font-weight: 600; }
.trace-card .tp-strike-foul    { color: var(--text-dim);      }
.trace-card .tp-in-play        { color: var(--accent-win);    font-weight: 600; }
.trace-card .tp-hbp            { color: var(--accent-live);   }

/* Situation strip — outs dots, bases diamond, base-state label. Sits
   between the head row and the event line. */
.trace-card .tt-situation {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
    color: var(--text-dim);
    font-size: 10px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.trace-card .tt-outs {
    display: inline-flex;
    gap: 3px;
    align-items: center;
}
.trace-card .tt-outs-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: transparent;
    border: 1px solid var(--text-dim);
}
.trace-card .tt-outs-dot.on {
    background: var(--text);
    border-color: var(--text);
}
.trace-card .tt-bases {
    color: var(--text-dim);
    flex-shrink: 0;
}
.trace-card .tt-bases-label {
    color: var(--text);
    font-weight: 550;
}

/* WE delta chip — small +/- next to the WE% when this PA isn't the
   biggest swing. Red for negative (home WE down), green for positive. */
.trace-card .tt-delta {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 0 4px;
    border-radius: 2px;
}
.trace-card .tt-delta-up   { color: var(--accent-win);  background: rgba(34, 197, 94, 0.12); }
.trace-card .tt-delta-down { color: var(--accent-live); background: rgba(239, 68, 68, 0.12); }

/* Player-name links inside the tooltip — same affordance as the
   recent-PA list, sized to fit the tooltip. */
.trace-card .tt-link {
    color: var(--accent-action);
    text-decoration: none;
    border-bottom: 1px dotted currentColor;
}
.trace-card .tt-link:hover {
    color: var(--accent-win);
}

/* "Biggest swing" call-out below the chart — text version of the
   highlighted marker, always visible without needing to hover. */
.trace-card .trace-biggest {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 6px 0 10px;
    padding: 6px 10px;
    background: rgba(239, 68, 68, 0.08);
    border: 1px solid rgba(239, 68, 68, 0.25);
    border-radius: 4px;
    font-size: 11px;
    color: var(--text);
    line-height: 1.4;
}
.trace-card .trace-biggest strong {
    color: var(--accent-live);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}
.trace-card .trace-biggest .tb-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent-live);
    flex-shrink: 0;
}

/* ── RECAP CARD ──────────────────────────────────────────────── */
/* Appears on Final games above the matchup card. LLM-generated narrative
   that explicitly leans on our predicted-vs-actual data — "the model
   gave Judge's HR just 4%" type beats no other recap engine writes. */
.card-pane > .recap-card { margin-top: 20px; }

.recap-card .recap-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}
.recap-card .recap-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.18em;
    color: var(--accent-win);
    text-transform: uppercase;
}
.recap-card .recap-meta {
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.06em;
    color: var(--text-dim);
    text-transform: uppercase;
}
.recap-card .recap-body {
    color: var(--text);
    font-size: 14px;
    line-height: 1.6;
}
.recap-card .recap-body p { margin-bottom: 10px; }
.recap-card .recap-body p:last-child { margin-bottom: 0; }
.recap-card .recap-foot {
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    font-size: 10px;
    color: var(--text-dim);
    letter-spacing: 0.02em;
}
.recap-card .recap-link {
    color: var(--accent-action);
    text-decoration: none;
    border-bottom: 1px dotted rgba(59, 130, 246, 0.4);
}
.recap-card .recap-link:hover { border-bottom-color: var(--accent-action); }
.recap-card .recap-empty {
    color: var(--text-dim);
    font-size: 12px;
    font-style: italic;
    padding: 6px 0;
}

/* ── MATCHUP CARD ─────────────────────────────────────────────── */

.card-pane > .matchup-card { margin-top: 20px; }

/* "+N batter PA from this season's daily ingest" — the visible-evidence
   line for the auto-learning pipeline. Lights up only when daily_pa
   actually contributed rows; the pulse dot mirrors the LIVE indicator
   so the eye reads "this is current". */
.matchup-card .live-sample {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
    padding: 8px 10px;
    background: rgba(34, 197, 94, 0.08);
    border: 1px solid rgba(34, 197, 94, 0.25);
    border-radius: 4px;
    font-size: 10px;
    font-weight: 550;
    color: var(--text);
    letter-spacing: 0.04em;
    font-variant-numeric: tabular-nums;
}
.matchup-card .live-sample .dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent-win);
    animation: pulse 1.5s ease-in-out infinite;
    flex-shrink: 0;
}

/* "What have they actually done this season?" — descriptive outcome
   counts pulled from daily_pa, sitting below the predicted distribution.
   Strictly observed, not predicted — the honest counterpoint to the
   model's prediction above. Limited to whatever days are in daily_pa. */
.matchup-card .recent-form {
    margin-top: 12px;
    padding: 12px 14px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* Sabermetric player stat cards — replaces the raw '296 PA — 73 K · 26
   BB · 10 HR · 60 H · 136 OUT' text dump per user feedback. Shows the
   slash line up top, then horizontal rate bars (K% / BB% / ISO for
   batters; K% / BB% / BAA / HR-rate for pitchers) anchored at the
   league average. Inspired by MLB.com player cards + Savant percentile
   sliders. */
.player-stat-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.psc-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.psc-name {
    font-size: 14px;
    font-weight: 700;
    color: var(--text);
}
.psc-meta {
    font-size: 11px;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}

/* Slash-line tiles — batter card only */
.psc-slash {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
}
.psc-slash-tile {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 8px 4px;
    text-align: center;
}
.psc-slash-tile.psc-slash-ops {
    background: rgba(56, 189, 248, 0.08);
    border-color: rgba(56, 189, 248, 0.25);
}
.psc-slash-num {
    font-size: 15px;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
}
.psc-slash-key {
    font-size: 10px;
    font-weight: 600;
    color: var(--text-dim);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    margin-top: 2px;
}

/* Rate bars — show player's value as fill, league avg as a tick. */
.psc-bars {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.psc-rate {
    display: grid;
    grid-template-columns: 64px 1fr 56px;
    align-items: center;
    gap: 10px;
    font-size: 12px;
}
.psc-rate-label {
    font-size: 10px;
    font-weight: 600;
    color: var(--text-dim);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.psc-rate-val {
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--text);
}
.psc-rate-track {
    position: relative;
    height: 8px;
    background: rgba(148, 163, 184, 0.12);
    border-radius: 4px;
    overflow: visible;
}
.psc-rate-fill {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    border-radius: 4px;
    background: var(--text-dim);
    transition: width 200ms ease, background 200ms ease;
}
.psc-rate-marker {
    position: absolute;
    top: -2px;
    bottom: -2px;
    width: 2px;
    background: rgba(255, 255, 255, 0.45);
    transform: translateX(-1px);
}
.psc-rate.better  .psc-rate-fill { background: #22C55E; }
.psc-rate.better  .psc-rate-val  { color: #34D399; }
.psc-rate.worse   .psc-rate-fill { background: #EF4444; }
.psc-rate.worse   .psc-rate-val  { color: #F87171; }
.psc-rate.neutral .psc-rate-fill { background: rgba(148, 163, 184, 0.4); }
.matchup-card .recent-form-head {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.12em;
    color: var(--text-dim);
    text-transform: uppercase;
}
.matchup-card .rf-row {
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    gap: 12px;
    align-items: baseline;
    font-size: 12px;
}
.matchup-card .rf-row .rf-label {
    color: var(--text);
    font-weight: 600;
    white-space: nowrap;
}
.matchup-card .rf-row .rf-stats {
    color: var(--text);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
}

.outcome-table {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-variant-numeric: tabular-nums;
}

/* Each outcome row is a <details> so it expands inline to show the
   per-component breakdown. <summary> wears the .outcome-row class so the
   collapsed look stays identical to the previous flat row. */
.outcome-detail {
    /* Smooth open/close. <details> doesn't animate height natively, but
       the breakdown panel handles its own fade-in below. */
}
.outcome-detail > summary {
    list-style: none;
    cursor: pointer;
    user-select: none;
}
.outcome-detail > summary::-webkit-details-marker { display: none; }
.outcome-detail > summary::marker { content: ""; }

.outcome-row {
    display: grid;
    grid-template-columns: 110px 1fr 42px 14px;
    gap: 10px;
    align-items: center;
    font-size: 12px;
    padding: 2px 0;
    border-radius: 4px;
    transition: background 120ms ease;
}
.outcome-detail > summary:hover .outcome-row {
    background: var(--surface-2);
}

.outcome-label {
    color: var(--text);
    font-weight: 500;
}

.outcome-bar {
    display: block;
    height: 8px;
    background: var(--surface-2);
    overflow: hidden;
    border-radius: 4px;
}
.outcome-bar > span {
    display: block;
    height: 100%;
    background: var(--accent-action);
    transition: width 400ms ease;
}

.outcome-detail:first-child .outcome-bar > span {
    background: var(--accent-win);
}
.outcome-detail:first-child .outcome-label {
    color: var(--accent-win);
    font-weight: 600;
}

.outcome-pct {
    color: var(--text-dim);
    text-align: right;
    font-size: 11px;
    font-weight: 550;
}
.outcome-detail:first-child .outcome-pct {
    color: var(--text);
    font-weight: 600;
}

.outcome-caret {
    color: var(--text-dim);
    font-size: 10px;
    text-align: center;
    transition: transform 200ms ease, color 120ms ease;
}
.outcome-detail[open] > summary .outcome-caret {
    transform: rotate(180deg);
    color: var(--accent-action);
}

/* The expanded breakdown — three component rates + the combined number,
   each on its own row with a one-line narrative on the right. */
.outcome-breakdown {
    margin: 8px 0 4px 14px;
    padding: 10px 12px;
    background: var(--surface-2);
    border-left: 2px solid var(--accent-action);
    border-radius: 0 4px 4px 0;
    display: flex;
    flex-direction: column;
    gap: 5px;
    font-size: 11px;
    animation: outcome-breakdown-in 200ms ease;
}
@keyframes outcome-breakdown-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.bd-row {
    display: grid;
    grid-template-columns: 64px 48px minmax(0, 1fr);
    gap: 10px;
    align-items: baseline;
}
.bd-label {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.bd-value {
    color: var(--text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    text-align: right;
}
.bd-note {
    color: var(--text-dim);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bd-row.total {
    padding-top: 5px;
    border-top: 1px solid var(--border);
    margin-top: 2px;
}
.bd-row.total .bd-label,
.bd-row.total .bd-value {
    color: var(--accent-action);
}
.bd-row.total .bd-note {
    color: var(--text);
    font-weight: 550;
    white-space: normal;
}

/* ── MARKETS PANE ──────────────────────────────────────────────────
   The fourth tab — every public prediction-market line we can pull
   (Polymarket, Kalshi, Manifold, Odds API), grouped by question with
   our model's WE compared side-by-side against cross-source consensus.
   Mirrors the gamecast/boxscore pane chrome. */

.markets-pane {
    padding: 0 32px;
    flex: 1;
    min-height: 0;
    /* Without min-width:0 a flex item with grid content can shrink to
       its min-content width and the grid then can't fan out to fill the
       row. This was why the Markets tab showed one column on a wide
       desktop. */
    min-width: 0;
    width: 100%;
}
.markets-loading,
.markets-pane .empty,
.markets-empty {
    text-align: center;
    color: var(--text-dim);
    padding: 60px 16px;
    font-size: 13px;
    letter-spacing: 0.04em;
}
.markets-empty-title {
    color: var(--text);
    font-size: 14px;
    font-weight: 550;
    margin-bottom: 6px;
    letter-spacing: 0;
    text-transform: none;
}
.markets-empty-sub {
    max-width: 480px;
    margin: 0 auto;
    line-height: 1.5;
    letter-spacing: 0;
    text-transform: none;
}

.markets {
    display: flex;
    flex-direction: column;
    gap: 22px;
    padding-bottom: 32px;
}

/* HEADLINE — our model side by side with market consensus. The "edge"
   row underneath tells the user where we disagree in plain English. */
.markets-header {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px 22px;
}
.markets-headline {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 24px;
}
/* 3-way header layout: ours / market / Savant side-by-side */
.markets-headline.three-way {
    grid-template-columns: 1fr 1fr 1fr;
    text-align: center;
}
.markets-headline.three-way .markets-side {
    padding: 8px 0;
    border-radius: var(--radius);
}
.markets-headline.three-way .markets-side[data-key="market"] {
    background: rgba(148, 163, 184, 0.06);
}

/* New 3-column header where the middle column is a stacked list of
   every book we pull from (not a single consensus number). User
   explicitly asked for every market's live odds. */
.markets-headline.three-col {
    grid-template-columns: 1fr 1.4fr 1fr;
    text-align: center;
    align-items: stretch;
    gap: 16px;
}
.markets-headline.three-col .markets-side {
    padding: 12px 14px;
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
}
.markets-headline.three-col .markets-side-books {
    background: rgba(148, 163, 184, 0.06);
    align-items: stretch;
    text-align: left;
}
.markets-headline.three-col .markets-side-books .markets-side-label {
    text-align: center;
    margin-bottom: 6px;
}
.msrc-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.msrc-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 5px 8px;
    border-radius: 4px;
    text-decoration: none;
    color: inherit;
    transition: background 80ms ease;
}
.msrc-row:hover { background: rgba(56, 189, 248, 0.08); }
.msrc-name {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 2px 7px;
    border-radius: 4px;
    background: var(--bg);
    color: var(--text-dim);
    flex-shrink: 0;
}
.msrc-name-bovada     { background: rgba(220, 38, 38, 0.18);   color: #FCA5A5; }
.msrc-name-polymarket { background: rgba(67, 56, 202, 0.2);    color: #A5B4FC; }
.msrc-name-kalshi     { background: rgba(34, 197, 94, 0.18);   color: #6EE7B7; }
.msrc-name-manifold   { background: rgba(245, 158, 11, 0.18);  color: #FCD34D; }
.msrc-name-odds_api   { background: rgba(56, 189, 248, 0.18);  color: #7DD3FC; }
.msrc-name-pinnacle   { background: rgba(217, 70, 239, 0.18);  color: #F0ABFC; }
.msrc-name-smarkets   { background: rgba(20, 184, 166, 0.18);  color: #5EEAD4; }
.msrc-name-sxbet      { background: rgba(168, 85, 247, 0.18);  color: #D8B4FE; }
.msrc-name-thescore   { background: rgba(249, 115, 22, 0.18);  color: #FED7AA; }
.msrc-name-espn_dk    { background: rgba(220, 38, 38, 0.22);   color: #FECACA; }
/* VegasInsider grid — each book on the page gets its own chip. Brand
   accents loosely match the operator (DK orange, FD blue, MGM gold,
   Caesars maroon, Bet365 green, HardRock gold, Fanatics teal, Rivers
   navy) so the firehose stays scannable across 8 retail US books. */
.msrc-name-vi_draftkings   { background: rgba(53, 169, 80, 0.20);  color: #86EFAC; }
.msrc-name-vi_fanduel      { background: rgba(37, 99, 235, 0.22);  color: #93C5FD; }
.msrc-name-vi_betmgm       { background: rgba(212, 175, 55, 0.22); color: #FDE68A; }
.msrc-name-vi_caesars      { background: rgba(139, 30, 63, 0.30);  color: #FCA5A5; }
.msrc-name-vi_bet365       { background: rgba(22, 163, 74, 0.22);  color: #BBF7D0; }
.msrc-name-vi_hardrock     { background: rgba(202, 138, 4, 0.22);  color: #FDE68A; }
.msrc-name-vi_fanatics     { background: rgba(14, 116, 144, 0.22); color: #A5F3FC; }
.msrc-name-vi_riverscasino { background: rgba(30, 64, 175, 0.28);  color: #BFDBFE; }
.msrc-quote {
    display: inline-flex;
    align-items: baseline;
    gap: 10px;
    font-variant-numeric: tabular-nums;
}
.msrc-am {
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
}
.msrc-am-empty { color: var(--text-faint); }
.msrc-pct {
    font-size: 11px;
    color: var(--text-dim);
    min-width: 44px;
    text-align: right;
}
.msrc-empty {
    color: var(--text-faint);
    font-style: italic;
    font-size: 11px;
    text-align: center;
    padding: 8px 0;
}

/* Click-to-expand "Market consensus" button + all-books panel that
   drops in below the header. Replaces the previous static middle
   column. User clicks → sees every book + market source individually. */
.markets-side-clickable {
    background: none;
    border: none;
    font: inherit;
    color: inherit;
    text-align: center;
    cursor: pointer;
    padding: 12px 14px;
    border-radius: var(--radius);
    transition: background 80ms ease;
}
.markets-side-clickable:hover {
    background: rgba(56, 189, 248, 0.08);
}
.markets-side-caret {
    font-size: 11px;
    color: var(--accent-action);
    margin-left: 4px;
}
.markets-side-cta {
    margin-top: 6px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--accent-action);
    text-transform: uppercase;
}

/* Expanded all-books panel below the header. Per-source cards in a
   responsive grid. */
.markets-all-books {
    margin-top: 14px;
    background: rgba(148, 163, 184, 0.05);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.mab-head-strip {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.mab-head-strip strong {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text);
}
.mab-meta { font-size: 11px; color: var(--text-dim); }
.mab-empty {
    color: var(--text-faint);
    font-style: italic;
    text-align: center;
    padding: 16px;
}
.mab-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 10px;
}
.mab-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.mab-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.mab-src.msrc-name { font-size: 11px; padding: 3px 9px; }
.mab-rows { display: flex; flex-direction: column; gap: 6px; }
.mab-row {
    display: grid;
    grid-template-columns: 50px 1fr;
    gap: 8px;
    align-items: center;
}
.mab-row-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--text-dim);
}
.mab-row-cells {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.mab-cell {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    font-size: 11px;
}
.mab-cell-name {
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mab-cell-odds {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    flex-shrink: 0;
}
.mab-cell-am {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}
.mab-cell-pct {
    font-size: 10px;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}
.mab-row-empty { color: var(--text-faint); }
.mab-row-empty-msg { font-size: 10px; font-style: italic; }

/* Condensed prop card — same player + same stat at multiple
   thresholds rendered as ONE card with a chip selector. Click a
   chip → odds + Buy buttons update to that threshold. */
.condensed-prop .prop-count-chip {
    margin-left: auto;
    padding: 2px 8px;
    background: rgba(56, 189, 248, 0.10);
    color: var(--accent-action);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    border-radius: 999px;
    text-transform: uppercase;
}
.condensed-prop .prop-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 10px 14px 4px;
    background: rgba(0, 0, 0, 0.15);
    border-bottom: 1px solid var(--border);
}
.condensed-prop .prop-chip {
    appearance: none;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border);
    color: var(--text-dim);
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    font-family: inherit;
    font-variant-numeric: tabular-nums;
    transition: background 100ms, color 100ms, border-color 100ms;
}
.condensed-prop .prop-chip:hover {
    color: var(--text);
    border-color: rgba(56, 189, 248, 0.4);
    background: rgba(56, 189, 248, 0.08);
}
.condensed-prop .prop-chip.active {
    background: var(--accent-action);
    color: white;
    border-color: var(--accent-action);
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.18);
}
.condensed-prop .prop-active-pane {
    padding: 6px 0 0;
}
.mab-cell-loading {
    color: var(--text-faint);
    font-size: 11px;
    letter-spacing: 0.2em;
    animation: mab-pulse 1.4s ease-in-out infinite;
}
.mab-cell-empty {
    color: var(--text-faint);
    font-size: 10px;
    font-style: italic;
}
@keyframes mab-pulse {
    0%, 100% { opacity: 0.3; }
    50%      { opacity: 0.9; }
}
.mab-link {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--accent-action);
    text-decoration: none;
    align-self: flex-end;
}
.mab-link:hover { text-decoration: underline; }
.markets-side-sub {
    font-size: 10px;
    color: var(--text-faint);
    margin-top: 3px;
    letter-spacing: 0.04em;
}
.markets-edge.edge-all-agree {
    background: rgba(16, 185, 129, 0.14);
    color: #34D399;
}
.markets-edge.edge-small-edge {
    background: rgba(148, 163, 184, 0.12);
    color: var(--text-dim);
}
.markets-edge.edge-big-edge {
    background: rgba(244, 114, 182, 0.14);
    color: #F472B6;
}

/* Sub-tab navigation (Game Lines / Player Props / Team Props).
   Researched: DK, FD, BetMGM, Action Network all use a sticky-ish
   horizontal tab bar at the top of their game pages. */
.markets-tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--border);
    padding-bottom: 4px;
}
.markets-tab {
    flex: 1;
    background: transparent;
    border: none;
    color: var(--text-dim);
    padding: 10px 12px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
    border-radius: var(--radius) var(--radius) 0 0;
    border-bottom: 2px solid transparent;
    transition: color 80ms ease, border-color 80ms ease, background 80ms ease;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}
.markets-tab:hover { color: var(--text); background: rgba(148, 163, 184, 0.04); }
.markets-tab.active {
    color: var(--accent-action);
    border-bottom-color: var(--accent-action);
}
.markets-tab-count {
    font-size: 10px;
    font-weight: 600;
    background: rgba(148, 163, 184, 0.12);
    color: var(--text-dim);
    padding: 1px 7px;
    border-radius: 99px;
}
.markets-tab.active .markets-tab-count {
    background: rgba(56, 189, 248, 0.18);
    color: var(--accent-action);
}
.markets-tab-body {
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding-top: 6px;
}

/* Stat-type sub-tabs inside Player Props / Team Props.
   Visually a smaller, secondary version of .markets-tabs — same
   bottom-border accent on the active one, but the row scrolls
   horizontally because there can be 8+ categories. */
.prop-stat-tabs {
    display: flex;
    gap: 2px;
    overflow-x: auto;
    border-bottom: 1px solid var(--border);
    padding-bottom: 2px;
    margin: 0 0 6px;
    scrollbar-width: thin;
}
.prop-stat-tabs::-webkit-scrollbar { height: 4px; }
.prop-stat-tabs::-webkit-scrollbar-thumb {
    background: rgba(148, 163, 184, 0.25);
    border-radius: 4px;
}
.prop-stat-tab {
    flex: 0 0 auto;
    background: transparent;
    border: none;
    color: var(--text-dim);
    padding: 7px 12px;
    font-size: 11px;
    font-weight: 550;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    transition: color 80ms ease, border-color 80ms ease, background 80ms ease;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}
.prop-stat-tab:hover {
    color: var(--text);
    background: rgba(148, 163, 184, 0.04);
}
.prop-stat-tab.active {
    color: var(--accent-action);
    border-bottom-color: var(--accent-action);
}
.prop-stat-tab-count {
    font-size: 10px;
    font-weight: 600;
    background: rgba(148, 163, 184, 0.12);
    color: var(--text-dim);
    padding: 1px 6px;
    border-radius: 99px;
    min-width: 16px;
    text-align: center;
}
.prop-stat-tab.active .prop-stat-tab-count {
    background: rgba(56, 189, 248, 0.18);
    color: var(--accent-action);
}
/* Hide every pane that isn't active. The render emits all of them
   so the local DOM-swap click handler can flip .active without a
   re-render. */
.prop-stat-pane { display: none; }
.prop-stat-pane.active { display: block; }

/* Player-prop filter input */
.markets-filter {
    display: flex;
    gap: 8px;
    align-items: center;
}
.markets-filter-input {
    flex: 1;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
    padding: 10px 14px;
    font-size: 13px;
    font-family: inherit;
}
.markets-filter-input:focus {
    outline: none;
    border-color: var(--accent-action);
}
.markets-filter-input::placeholder { color: var(--text-faint); }
.markets-filter-clear {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-dim);
    padding: 8px 14px;
    border-radius: var(--radius);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
}
.markets-filter-clear:hover { color: var(--text); }

/* Alternate-lines expander */
.markets-alt-toggle {
    background: rgba(148, 163, 184, 0.06);
    border: 1px dashed rgba(148, 163, 184, 0.2);
    color: var(--text-dim);
    padding: 8px 14px;
    border-radius: var(--radius);
    font-size: 12px;
    font-weight: 550;
    cursor: pointer;
    align-self: flex-start;
}
.markets-alt-toggle:hover { color: var(--text); border-color: var(--text-dim); }
.markets-alt-toggle.is-open {
    background: rgba(56, 189, 248, 0.08);
    border-color: rgba(56, 189, 248, 0.3);
    color: var(--accent-action);
}
.markets-alts-wrap {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.markets-side-label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 6px;
}
.markets-side-num {
    font-size: 30px;
    font-weight: 600;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.markets-vs {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.12em;
    color: var(--text-faint);
    text-transform: uppercase;
}
.markets-edge {
    margin-top: 14px;
    padding: 10px 14px;
    border-radius: var(--radius);
    font-size: 13px;
    font-weight: 550;
    text-align: center;
}
.markets-edge.edge-flat {
    background: rgba(148, 163, 184, 0.12);
    color: var(--text-dim);
}
.markets-edge.edge-us-higher {
    background: rgba(16, 185, 129, 0.14);
    color: #34D399;
}
.markets-edge.edge-market-higher {
    background: rgba(244, 114, 182, 0.14);
    color: #F472B6;
}
.markets-subhead {
    margin-top: 6px;
    text-align: center;
    color: var(--text-faint);
    font-size: 11px;
    letter-spacing: 0.04em;
}

/* SECTIONS — one per question type (moneyline, spread, total, props…) */
.markets-section { display: flex; flex-direction: column; gap: 10px; }
.markets-section-title {
    margin: 0;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-dim);
}
.markets-rows {
    display: grid;
    /* auto-fit collapses empty tracks; min 240px lets up to 5 columns
       fit on a desktop. Smaller cards work better now that Bovada
       alternate handicaps are split into separate 2-outcome rows. */
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px;
    width: 100%;
}

/* ROW — one prediction-market quote, regardless of source. Source
   chip in the corner makes provenance visible at a glance. */
.market-row {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 14px 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.market-row-head {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.market-source {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 2px 7px;
    border-radius: 4px;
    background: var(--bg);
    color: var(--text-dim);
}
.market-source-polymarket { background: rgba(67, 56, 202, 0.2);  color: #A5B4FC; }
.market-source-kalshi     { background: rgba(34, 197, 94, 0.18); color: #6EE7B7; }
.market-source-manifold   { background: rgba(245, 158, 11, 0.18); color: #FCD34D; }
.market-source-odds_api   { background: rgba(56, 189, 248, 0.18); color: #7DD3FC; }
.market-status {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 2px 6px;
    border-radius: 4px;
    background: rgba(244, 114, 182, 0.18);
    color: #F472B6;
}
.market-title {
    flex: 1;
    min-width: 0;
    color: var(--text);
    text-decoration: none;
    font-size: 13px;
    font-weight: 550;
    line-height: 1.35;
}
.market-title:hover { text-decoration: underline; }

.market-outcomes {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
/* Sportsbook-style outcome row. Two columns: NAME | (AMERICAN ODDS +
   IMPLIED %). Mirrors ESPN BET, DraftKings, FanDuel conventions —
   American odds are the universal price, implied probability is the
   comparison number against our model. */
.market-outcome {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
    font-size: 13px;
    padding: 6px 0;
}
.market-outcome + .market-outcome {
    border-top: 1px solid rgba(255, 255, 255, 0.04);
}
.market-outcome.is-favorite .mo-name { font-weight: 600; }
.market-outcome.is-favorite .mo-american { color: var(--accent-win); }
.mo-name {
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 550;
}
.mo-odds-block {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 1px;
    min-width: 70px;
}
.mo-american {
    font-variant-numeric: tabular-nums;
    color: var(--text);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.02em;
}
.mo-implied {
    font-variant-numeric: tabular-nums;
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 550;
    letter-spacing: 0.04em;
}
.mo-no-quote {
    color: var(--text-faint);
    font-size: 10px;
    font-style: italic;
}

/* Model-vs-market row. Single line under the YES/NO outcomes inside a
   condensed prop card: MODEL | +250 | 28% | EDGE +4 pts ↗.
   Color coded by edge direction so the user can spot live mispricings
   at a glance: green = our model is more bullish than the market
   (buy YES), red = more bearish (buy NO), grey = within ±2 pts. */
.model-row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 5px 8px;
    margin-top: 4px;
    border-radius: 6px;
    background: rgba(148, 163, 184, 0.06);
    border: 1px solid rgba(148, 163, 184, 0.10);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}
.model-row-tag {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    color: var(--text-dim);
    background: rgba(56, 189, 248, 0.10);
    padding: 1px 6px;
    border-radius: 3px;
    color: var(--accent-action);
}
.model-row-american {
    font-weight: 700;
    font-size: 13px;
    color: var(--text);
    letter-spacing: 0.02em;
}
.model-row-pct {
    font-weight: 550;
    color: var(--text-dim);
    font-size: 11px;
}
.model-row-edge {
    margin-left: auto;
    color: var(--text-dim);
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.model-row-edge strong { font-weight: 700; color: var(--text); }
.model-edge-arrow { font-size: 12px; }

/* Edge tints. ±2 pts is "noise"; beyond that we paint the row so the
   color directs the eye to live mispricings without the user having
   to read the number. */
.model-row.model-edge-yes {
    background: rgba(34, 197, 94, 0.08);
    border-color: rgba(34, 197, 94, 0.22);
}
.model-row.model-edge-yes .model-row-edge strong,
.model-row.model-edge-yes .model-edge-arrow { color: var(--accent-win); }
.model-row.model-edge-no {
    background: rgba(239, 68, 68, 0.07);
    border-color: rgba(239, 68, 68, 0.22);
}
.model-row.model-edge-no .model-row-edge strong,
.model-row.model-edge-no .model-edge-arrow { color: var(--accent-live); }
.model-row.model-edge-flat {
    /* default tint already grey/blue — no override */
}
.market-meta {
    font-size: 10px;
    color: var(--text-faint);
    letter-spacing: 0.04em;
}
.markets-footnote {
    text-align: center;
    color: var(--text-faint);
    font-size: 11px;
    line-height: 1.5;
    padding: 12px 16px 0;
}

/* Per-game Markets tab: when futures/series WOULD have shown for one
   of the two teams, route the user to that team's page instead. */
.markets-team-link-note {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    justify-content: center;
    padding: 14px 16px;
    border-top: 1px dashed var(--border);
    border-bottom: 1px dashed var(--border);
    margin: 4px 0;
}
.markets-team-link-note a {
    color: var(--accent-action);
    text-decoration: none;
    font-weight: 600;
    font-size: 12px;
    letter-spacing: 0.04em;
}
.markets-team-link-note a:hover { text-decoration: underline; }


/* Per-game market-consensus pill — sits on the Live View card between
   the forecast WE slot and the evidence line. Compact, tappable, and
   takes the user to the full Markets tab. Hidden when no market yet. */
.mc-pill {
    margin-top: 12px;
    padding: 12px 14px;
    border-radius: var(--radius);
    background: rgba(148, 163, 184, 0.06);
    border: 1px solid var(--border);
}
.mc-pill.mc-pill-we_higher    { background: rgba(16, 185, 129, 0.08); border-color: rgba(16, 185, 129, 0.25); }
.mc-pill.mc-pill-market_higher{ background: rgba(244, 114, 182, 0.08); border-color: rgba(244, 114, 182, 0.25); }
.mc-pill-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
}
.mc-pill-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-dim);
}
.mc-pill-link {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--accent-action);
    text-decoration: none;
}
.mc-pill-link:hover { text-decoration: underline; }
.mc-pill-row {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 12px;
}
.mc-pill-num { text-align: center; }
.mc-pill-num-val {
    font-size: 17px;
    font-weight: 600;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.mc-pill-num-key {
    font-size: 10px;
    color: var(--text-dim);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    margin-top: 2px;
}
.mc-pill-vs {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.12em;
    color: var(--text-faint);
    text-transform: uppercase;
}
.mc-pill-verdict {
    margin-top: 8px;
    text-align: center;
    font-size: 11px;
    color: var(--text);
    font-weight: 550;
}
.mc-pill-verdict-we_higher    { color: #34D399; }
.mc-pill-verdict-market_higher{ color: #F472B6; }

/* Supplementary line chips below the moneyline — total runs O/U and
   run-line spread. Each shows the question, the line, the consensus
   probability, and the source. Click jumps into the Markets tab. */
.mc-pill-extras {
    margin-top: 10px;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: center;
}
.mc-line-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 9px;
    border-radius: 99px;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text);
    text-decoration: none;
    font-size: 11px;
    transition: border-color 80ms ease;
}
.mc-line-chip:hover { border-color: var(--accent-action); }
.mc-line-chip .mc-line-key {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
}
.mc-line-chip .mc-line-val { font-weight: 550; }
.mc-line-chip .mc-line-pct {
    font-variant-numeric: tabular-nums;
    color: var(--accent-action);
    font-weight: 600;
}
.mc-line-chip .mc-line-src {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-faint);
}

/* Matchup-card prop strip — player props for the current batter +
   pitcher rendered under the outcome distribution. Sits inside the
   matchup card so the user sees model vs market for both sides. */
.mc-prop-strip:not(:empty) {
    margin-top: 14px;
    padding: 12px;
    border-radius: var(--radius);
    background: rgba(148, 163, 184, 0.05);
    border: 1px dashed rgba(148, 163, 184, 0.2);
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.mc-prop-strip-head {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.1em;
    color: var(--text-dim);
    text-transform: uppercase;
}
.mc-prop-strip-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.mc-prop-strip-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--text-dim);
    text-transform: uppercase;
}
.mc-prop-strip-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.mc-prop-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border-radius: 99px;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text);
    text-decoration: none;
    font-size: 11px;
    font-weight: 550;
}
.mc-prop-chip:hover { border-color: var(--accent-action); }
.mc-prop-chip-side {
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mc-prop-chip-pct {
    font-variant-numeric: tabular-nums;
    color: var(--accent-action);
    font-weight: 600;
}
.mc-prop-chip-src {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-faint);
}


/* ── MARKETS DASHBOARD (sidebar nav) ────────────────────────────
   Top-level surface — every public MLB market in one place, polling
   every 20s. Reuses .markets-section / .market-row from the per-game
   markets pane so the visual language stays consistent. */

.markets-view {
    /* Bottom gutter 100px so the fixed widgets clear the last
       game-card row — see .leaders-view. */
    padding: 10px 20px 100px;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
}
.markets-view .empty { padding: 48px 16px; }
.markets-dashboard {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: 1700px;
    margin: 0 auto;
}
.md-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.md-title {
    margin: 0;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text);
}
.md-sub {
    font-size: 11px;
    color: var(--text-dim);
}
.md-sources {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 2px;
}
.md-source-chip {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 3px 8px;
    border-radius: 4px;
    background: var(--bg);
    color: var(--text-dim);
}
.md-source-chip-polymarket { background: rgba(67, 56, 202, 0.2);  color: #A5B4FC; }
.md-source-chip-kalshi     { background: rgba(34, 197, 94, 0.18); color: #6EE7B7; }
.md-source-chip-manifold   { background: rgba(245, 158, 11, 0.18); color: #FCD34D; }
.md-source-chip-odds_api   { background: rgba(56, 189, 248, 0.18); color: #7DD3FC; }
.md-meta {
    font-size: 11px;
    color: var(--text-faint);
    letter-spacing: 0.04em;
}
.md-footnote {
    margin-top: 8px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    color: var(--text-faint);
    font-size: 11px;
    line-height: 1.5;
}

/* One card per MLB game on the dashboard. Sportsbook convention
   (DK / FD / BetMGM): teams + start time at top, three columns
   side-by-side for moneyline / spread / total, props chips at
   the bottom. Grid of these fans out across the page. */
.md-games {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 8px;
}
.md-game-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 8px 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    transition: border-color 80ms ease, transform 80ms ease;
    text-decoration: none;
    color: inherit;
}
.md-game-card:hover {
    border-color: rgba(56, 189, 248, 0.4);
    transform: translateY(-1px);
}
.md-game-card-live { border-color: rgba(239, 68, 68, 0.3); }
.md-game-card-final { opacity: 0.7; }
.md-game-status {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.1em;
    padding: 2px 6px;
    border-radius: 4px;
}
.md-game-status-live {
    background: rgba(239, 68, 68, 0.18);
    color: var(--accent-live);
}
.md-game-status-final {
    background: rgba(148, 163, 184, 0.12);
    color: var(--text-dim);
}
.md-game-meta { display: flex; align-items: baseline; gap: 6px; }
.md-game-cta {
    margin-left: auto;
    color: var(--accent-action);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
}
.md-game-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}
.md-game-teams {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-variant-numeric: tabular-nums;
}
.md-game-away, .md-game-home {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--text);
}
.md-game-at {
    color: var(--text-faint);
    font-size: 11px;
    font-weight: 550;
}
.md-game-time {
    color: var(--text-dim);
    font-size: 10px;
    font-variant-numeric: tabular-nums;
}
.md-game-lines {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    /* Tightened gap so each column has more pixel budget for its
       outcome rows — was 6, now 4. */
    gap: 4px;
    /* min-width: 0 on each child column so its content (long odds
       like -9999, "no offers") can shrink instead of overflowing
       the card's right edge. */
}
.md-game-col {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.md-game-col-label {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 1px;
}
/* Outcome row is now a tappable BUTTON (was a div) — click prefills
   the inline bet calculator below with this side. Style strips
   default button chrome so it visually matches the old row. */
button.md-game-outcome {
    appearance: none;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid var(--border);
    border-radius: 6px;
    margin: 2px 0;
    cursor: pointer;
    width: 100%;
    text-align: left;
    color: inherit;
    font: inherit;
    transition: background 120ms, border-color 120ms, transform 80ms;
}
button.md-game-outcome:hover {
    background: rgba(59, 130, 246, 0.10);
    border-color: rgba(59, 130, 246, 0.45);
}
button.md-game-outcome:active { transform: translateY(1px); }

.md-game-outcome {
    /* Vertical stack: name + tiny logo on row 1, odds on row 2.
       overflow hidden on the cell so any pathological content
       cannot extend past the border (the user has seen multiple
       times when a -9999 squeezed past). */
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1px;
    font-size: 10px;
    padding: 4px 6px;
    min-width: 0;
    overflow: hidden;
}
.md-game-outcome.is-fav .md-game-out-name { font-weight: 600; }
.md-game-outcome.is-fav .md-game-out-am { color: var(--accent-win); }
/* Auto-scroll (marquee) for odds labels too long for the box, so the full
   text (e.g. "Over 8.5 runs") is readable. applyOddsMarquee() in app.js wraps
   the content and adds .is-marquee + the --md-shift distance only when the
   label actually overflows. Ping-pong (alternate) returns it to the start. */
.md-game-out-name.is-marquee { text-overflow: clip; }
.md-name-scroll {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
}
.md-game-out-name.is-marquee .md-name-scroll {
    /* Scroll to the end, hold, then SNAP back to the start (no scroll-back) —
       the 100%->0% loop boundary is instant since it's not 'alternate'. */
    animation: md-name-marquee 5.5s ease-in-out infinite;
    will-change: transform;
}
@keyframes md-name-marquee {
    0%, 15%   { transform: translateX(0); }                       /* pause at start */
    85%, 100% { transform: translateX(var(--md-shift, 0px)); }    /* scroll to end + hold, then reset */
}
@media (prefers-reduced-motion: reduce) {
    .md-game-out-name.is-marquee .md-name-scroll { animation: none; }
}
.md-game-out-name {
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100%;
    font-size: 10px;
    font-weight: 550;
    /* Logo + label inline. Renderer prepends an .md-team-logo img. */
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
}
.md-game-out-odds {
    /* In the vertical layout: am + pct sit side by side on a
       second line, full-width, right-aligned so values column-
       align nicely between sibling rows. */
    display: flex;
    flex-direction: row;
    align-items: baseline;
    gap: 4px;
    width: 100%;
    justify-content: flex-end;
    flex-shrink: 0;
    overflow: hidden;
}
.md-game-out-am {
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    /* Tightened 13 → 12 — long odds like +9900 / -9999 now fit
       comfortably even in the 240px-min card with the pct beside. */
    font-size: 10px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.md-game-out-pct {
    color: var(--text-dim);
    font-size: 9px;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

/* Small team logo for inline use next to abbreviations — picked
   up by the markets cards, score tiles, and anywhere else we say
   "MIA" / "WSH" / etc. Logos are served by ESPN's CDN keyed by
   lowercase MLB tri-code; the renderer falls back to a hidden img
   if a code isn't recognized. */
.team-logo,
.md-team-logo {
    width: 18px;
    height: 18px;
    object-fit: contain;
    flex-shrink: 0;
    display: inline-block;
    vertical-align: middle;
}
.team-logo-sm,
.md-team-logo-sm {
    width: 14px;
    height: 14px;
}
.md-game-empty {
    color: var(--text-faint);
    font-size: 11px;
    font-style: italic;
    padding: 4px 0;
}
/* Inline bet calculator — side selector, $ stake input, live-computed
   payout, Place via Kalshi button. Standard sportsbook pattern. */
.md-bet-calc {
    margin-top: 14px;
    padding: 10px 12px;
    background: rgba(34, 197, 94, 0.05);
    border: 1px solid rgba(34, 197, 94, 0.18);
    border-radius: 8px;
}
.md-bet-row {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 0.9fr) minmax(0, 1.0fr) auto;
    gap: 10px;
    align-items: end;
}
@media (max-width: 720px) {
    .md-bet-row {
        grid-template-columns: 1fr;
    }
}
.md-bet-lbl {
    display: block;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 4px;
}
.md-bet-side, .md-bet-stake {
    display: flex;
    flex-direction: column;
}
.md-bet-side select {
    padding: 8px 10px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 5px;
    color: var(--text);
    font-size: 12px;
    font-family: inherit;
    cursor: pointer;
}
.md-bet-side select:focus {
    outline: none;
    border-color: var(--accent-action);
}
.md-bet-stake-wrap {
    display: flex;
    align-items: center;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 5px;
    padding: 0 8px;
}
.md-bet-stake-wrap:focus-within {
    border-color: var(--accent-action);
}
.md-bet-dollar {
    color: var(--text-faint);
    font-size: 13px;
    margin-right: 2px;
}
.md-bet-stake input {
    appearance: none;
    -moz-appearance: textfield;
    background: transparent;
    border: none;
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
    font-family: inherit;
    font-variant-numeric: tabular-nums;
    padding: 8px 0;
    width: 100%;
    min-width: 0;
}
.md-bet-stake input::-webkit-inner-spin-button,
.md-bet-stake input::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.md-bet-stake input:focus { outline: none; }

.md-bet-payout {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    font-variant-numeric: tabular-nums;
    font-size: 14px;
    color: var(--text);
}
.md-bet-payout strong {
    color: var(--accent-win);
    font-weight: 700;
    font-size: 15px;
}
.md-bet-total {
    font-size: 10px;
    color: var(--text-faint);
    margin-top: 2px;
}

.md-bet-place {
    appearance: none;
    background: var(--accent-win);
    color: #0B1220;
    border: none;
    border-radius: 6px;
    padding: 10px 14px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    cursor: pointer;
    font-family: inherit;
    text-transform: uppercase;
    transition: background 120ms, transform 80ms;
}
.md-bet-place:hover:not(:disabled) {
    background: #16A34A;
    transform: translateY(-1px);
}
.md-bet-place:disabled {
    background: rgba(255, 255, 255, 0.08);
    color: var(--text-faint);
    cursor: not-allowed;
}

.md-game-teams-link {
    text-decoration: none;
    color: inherit;
}

.md-game-foot {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 10px;
    align-items: center;
}
.md-game-chip {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 3px 8px;
    border-radius: 99px;
    background: rgba(56, 189, 248, 0.1);
    color: var(--accent-action);
    text-decoration: none;
}
.md-game-chip-dim {
    background: rgba(148, 163, 184, 0.1);
    color: var(--text-dim);
}
.md-unmatched {
    margin-top: 8px;
    padding-top: 16px;
    border-top: 1px dashed var(--border);
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.md-section-title {
    margin: 0;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-dim);
}

/* Pointer card on the dashboard that explains where futures went —
   each team's page. Subtle dashed border so it reads as an aside, not
   a section heading. */
.md-futures-pointer {
    margin-top: 14px;
    padding: 12px 14px;
    border: 1px dashed rgba(148, 163, 184, 0.25);
    border-radius: var(--radius);
    color: var(--text-dim);
    font-size: 12px;
    line-height: 1.5;
}
.md-futures-pointer strong {
    color: var(--text);
    display: block;
    margin-bottom: 4px;
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.md-futures-pointer a {
    color: var(--accent-action);
    text-decoration: none;
}
.md-futures-pointer a:hover { text-decoration: underline; }

@media (max-width: 600px) {
    .markets-view { padding: 16px 14px 48px; }
    .md-title { font-size: 17px; }
}


/* ── TEAM VIEW ───────────────────────────────────────────────────
   Reached by clicking a team in standings. Surfaces futures (WS,
   ALCS/NLCS, division, season wins) and player props for the team's
   roster. Futures intentionally do NOT live on the live game tracker
   per user feedback — only game-day lines there.
*/

.team-view {
    padding: 18px 32px 64px;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
}
.team-view .empty { padding: 48px 16px; }
.team-doc {
    display: flex;
    flex-direction: column;
    gap: 18px;
    max-width: 1080px;
    margin: 0 auto;
}
.team-header {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--border);
}
.team-header-name {
    margin: 0;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text);
}
.team-header-meta {
    color: var(--text-dim);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}
.team-section {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.team-section-title {
    margin: 0;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-dim);
}
.team-section-rows {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
    gap: 8px;
}
.team-market-row {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 12px;
    text-decoration: none;
    color: var(--text);
    display: flex;
    flex-direction: column;
    gap: 6px;
    transition: border-color 80ms ease;
}
.team-market-row:hover { border-color: var(--accent-action); }
.team-market-head {
    display: flex;
    align-items: center;
    gap: 8px;
}
.team-market-src {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 2px 7px;
    border-radius: 4px;
    background: var(--bg);
    color: var(--text-dim);
}
.team-market-src-polymarket { background: rgba(67, 56, 202, 0.2);  color: #A5B4FC; }
.team-market-src-kalshi     { background: rgba(34, 197, 94, 0.18); color: #6EE7B7; }
.team-market-src-manifold   { background: rgba(245, 158, 11, 0.18); color: #FCD34D; }
.team-market-src-odds_api   { background: rgba(56, 189, 248, 0.18); color: #7DD3FC; }
.team-market-title {
    flex: 1;
    min-width: 0;
    font-size: 12px;
    font-weight: 550;
    line-height: 1.35;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.team-market-pct {
    font-variant-numeric: tabular-nums;
    color: var(--accent-action);
    font-weight: 600;
    font-size: 13px;
}
.team-market-bar {
    height: 4px;
    background: var(--bg);
    border-radius: 2px;
    overflow: hidden;
}
.team-market-bar-fill {
    height: 100%;
    background: var(--accent-action);
    border-radius: 2px;
    transition: width 200ms ease;
}
.team-footnote {
    color: var(--text-faint);
    font-size: 11px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}

/* Tonight's-game card on the team page. Bridge between team-context
   (futures, season props) and the live PA-by-PA companion. */
.team-today-game {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.team-today-game-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.team-today-game-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    color: var(--text-dim);
    text-transform: uppercase;
}
.team-today-game-link {
    color: var(--accent-action);
    text-decoration: none;
    font-weight: 600;
    font-size: 13px;
}
.team-today-game-link:hover { text-decoration: underline; }
.team-today-game-state {
    color: var(--text);
    font-size: 14px;
    font-weight: 550;
}
.team-today-game-ours {
    color: var(--text-dim);
    font-size: 12px;
}

/* Empty-state hint for The Odds API setup. Renders ONLY when the
   ODDS_API_KEY isn't set — gives the user the exact wrangler command
   to wire it up. */
.odds-api-hint {
    background: rgba(56, 189, 248, 0.06);
    border: 1px dashed rgba(56, 189, 248, 0.3);
    border-radius: var(--radius);
    padding: 14px 16px;
    color: var(--text);
}
.odds-api-hint-title {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: #7DD3FC;
    text-transform: uppercase;
    margin-bottom: 6px;
}
.odds-api-hint-body {
    font-size: 12px;
    line-height: 1.5;
    color: var(--text-dim);
    margin: 0 0 8px 0;
}
.odds-api-hint-body strong { color: var(--text); }
.odds-api-hint-steps {
    margin: 0 0 8px 18px;
    padding: 0;
    color: var(--text);
    font-size: 12px;
    line-height: 1.7;
}
.odds-api-hint-steps a {
    color: #7DD3FC;
    text-decoration: none;
    border-bottom: 1px dotted currentColor;
}
.odds-api-hint-steps code,
.odds-api-hint-foot code {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 1px 6px;
    font-size: 11px;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    color: var(--text);
}
.odds-api-hint-foot {
    margin: 0;
    color: var(--text-faint);
    font-size: 11px;
    line-height: 1.5;
}

.team-link {
    color: var(--text);
    text-decoration: none;
    border-bottom: 1px dotted var(--text-dim);
}
.team-link:hover {
    color: var(--accent-action);
    border-bottom-color: currentColor;
}


@media (max-width: 600px) {
    .team-view { padding: 14px 14px 48px; }
    .team-header-name { font-size: 17px; }
    .team-section-rows { grid-template-columns: 1fr; }
}


/* ── RESPONSIVE / MOBILE ───────────────────────────────────────── */

@media (max-width: 600px) {
    header { padding: 10px 14px; }
    header h1 { font-size: 14px; }
    nav .nav-item { padding: 10px 0; font-size: 10px; letter-spacing: 0.08em; }
    nav .nav-item .num { margin-right: 4px; }
    main.board { padding: 12px 10px 14px; }
    .standings-view, .leaders-view, .mvp-view {
        padding: 14px 14px 24px;
    }
    .page-footer {
        flex-direction: column;
        align-items: flex-start;
        gap: 3px;
        padding: 7px 14px;
    }
    .ticker { padding: 6px 10px 8px; margin: 0 0 14px; }
    .back-link { padding: 0 14px 8px; }
    .game-view .game-pane { padding: 0 14px; }
    .markets-pane { padding: 0 14px; }
    .markets-headline { grid-template-columns: 1fr; gap: 12px; text-align: center; }
    .markets-vs { display: none; }
    .markets-side-num { font-size: 24px; }
    .markets-rows { grid-template-columns: 1fr; }
}

@media (max-width: 420px) {
    :root { --tile-w: 92vw; }
    nav .nav-item .num { display: none; }
    nav .nav-item { letter-spacing: 0.1em; }
}


/* ═══════════════════════════════════════════════════════════════
   KALSHI in-site trading UI
   - Connect modal (email + password → bearer token in localStorage)
   - Account strip (balance, sign out) rendered into [data-kalshi-strip]
   - Buy YES / Buy NO inline buttons on each Kalshi market card
   - Bet confirmation modal
   - Toast notifications
   See web/public/kalshi.js for the wiring.
   ═══════════════════════════════════════════════════════════════ */

/* Modal overlay (used by both connect modal and bet modal). */
.kalshi-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(11, 18, 32, 0.78);
    backdrop-filter: blur(4px);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}
.kalshi-modal {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 24px 26px;
    max-width: 440px;
    width: 100%;
    box-shadow: 0 18px 60px rgba(0, 0, 0, 0.6);
    position: relative;
    color: var(--text);
}
.kalshi-modal h2 {
    margin: 0 0 8px;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: 0.02em;
}
.kalshi-modal .km-sub {
    margin: 0 0 12px;
    font-size: 12px;
    color: var(--text-dim);
    line-height: 1.45;
}
.kalshi-modal .km-sub-trust {
    padding: 8px 10px;
    background: rgba(56, 189, 248, 0.06);
    border: 1px solid rgba(56, 189, 248, 0.18);
    border-radius: 4px;
    color: var(--text-dim);
    font-size: 11px;
}
.kalshi-modal .km-steps {
    margin: 0 0 12px;
    padding-left: 22px;
    font-size: 12px;
    color: var(--text-dim);
    line-height: 1.6;
}
.kalshi-modal .km-steps li { margin-bottom: 3px; }
.kalshi-modal .km-steps a {
    color: var(--accent-action);
    text-decoration: none;
}
.kalshi-modal .km-steps a:hover { text-decoration: underline; }
.kalshi-modal .km-steps strong { color: var(--text); }
.kalshi-modal .km-field textarea {
    padding: 10px 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 11px;
    font-family: ui-monospace, "SF Mono", Consolas, monospace;
    line-height: 1.4;
    resize: vertical;
    min-height: 100px;
}
.kalshi-modal .km-field textarea:focus {
    outline: none;
    border-color: var(--accent-action);
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.18);
}
.kalshi-modal .km-close {
    position: absolute;
    top: 10px;
    right: 12px;
    background: transparent;
    border: none;
    color: var(--text-dim);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 4px;
    transition: color 120ms, background 120ms;
}
.kalshi-modal .km-close:hover {
    color: var(--text);
    background: rgba(255, 255, 255, 0.06);
}

.kalshi-modal .km-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 14px;
}
.kalshi-modal .km-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.kalshi-modal .km-field > span {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.14em;
    color: var(--text-dim);
    text-transform: uppercase;
}
.kalshi-modal .km-field input {
    padding: 10px 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 14px;
    font-family: inherit;
}
.kalshi-modal .km-field input:focus {
    outline: none;
    border-color: var(--accent-action);
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.18);
}
.kalshi-modal .km-hint {
    font-size: 10px;
    color: var(--text-faint);
    margin-top: 2px;
}

.kalshi-modal .km-max-btn {
    margin-left: 8px;
    padding: 1px 8px;
    border-radius: 999px;
    background: rgba(34, 197, 94, 0.14);
    color: var(--accent-win);
    border: 1px solid rgba(34, 197, 94, 0.35);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
    font-family: inherit;
    vertical-align: middle;
    transition: background 120ms, transform 80ms;
}
.kalshi-modal .km-max-btn:hover {
    background: rgba(34, 197, 94, 0.22);
    transform: translateY(-1px);
}
.kalshi-modal .km-max-btn:active { transform: translateY(0); }

.kalshi-modal .km-total {
    padding: 10px 12px;
    background: rgba(34, 197, 94, 0.08);
    border: 1px solid rgba(34, 197, 94, 0.2);
    border-radius: 6px;
    font-size: 13px;
    color: var(--text);
    margin-top: 4px;
}
.kalshi-modal .km-total strong {
    color: var(--accent-win);
    font-size: 15px;
    font-weight: 700;
}

.kalshi-modal .km-error {
    padding: 8px 10px;
    background: rgba(239, 68, 68, 0.12);
    border: 1px solid rgba(239, 68, 68, 0.3);
    border-radius: 4px;
    font-size: 12px;
    color: #FECACA;
    margin: 4px 0 0;
}
.kalshi-modal .km-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 6px;
}
.kalshi-modal .km-actions button {
    padding: 10px 18px;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background 120ms, border-color 120ms;
    font-family: inherit;
}
.kalshi-modal .km-cancel {
    background: transparent;
    color: var(--text-dim);
    border-color: var(--border);
}
.kalshi-modal .km-cancel:hover { background: rgba(255, 255, 255, 0.04); color: var(--text); }
.kalshi-modal .km-submit {
    background: var(--accent-action);
    color: white;
}
.kalshi-modal .km-submit:hover  { background: #2563EB; }
.kalshi-modal .km-submit:disabled {
    background: rgba(255, 255, 255, 0.1);
    color: var(--text-faint);
    cursor: not-allowed;
}

.kalshi-modal code {
    background: var(--bg);
    padding: 1px 5px;
    border-radius: 3px;
    font-size: 11px;
    font-family: ui-monospace, "SF Mono", Consolas, monospace;
}

/* Strip container — gives the account strip breathing room inside the
   Markets tab header area. */
.markets-kalshi-strip {
    margin: 12px 0;
    display: flex;
    justify-content: flex-start;
}

/* Account strip — displayed in the [data-kalshi-strip] container. */
.kalshi-strip {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 12px;
    color: var(--text);
    width: fit-content;
}
.kalshi-strip-disconnected .ks-cta {
    background: transparent;
    border: 1px dashed rgba(56, 189, 248, 0.5);
    color: var(--accent-action);
    padding: 8px 16px;
    border-radius: 999px;
    cursor: pointer;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    font-family: inherit;
    transition: background 120ms;
}
.kalshi-strip-disconnected .ks-cta:hover {
    background: rgba(56, 189, 248, 0.08);
}
.kalshi-strip .ks-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: #86EFAC;          /* kalshi green-ish accent */
    text-transform: uppercase;
}
.kalshi-strip .ks-balance {
    font-variant-numeric: tabular-nums;
    color: var(--text-dim);
}
.kalshi-strip .ks-balance strong {
    color: var(--accent-win);
    font-weight: 700;
    font-size: 13px;
    margin-left: 4px;
}
.kalshi-strip .ks-email {
    color: var(--text-faint);
    font-size: 11px;
}
.kalshi-strip .ks-signout {
    background: transparent;
    border: none;
    color: var(--text-dim);
    cursor: pointer;
    font-size: 11px;
    text-decoration: underline;
    font-family: inherit;
    padding: 2px 4px;
}
.kalshi-strip .ks-signout:hover { color: var(--accent-live); }

/* Inline bet buttons on Kalshi market rows. */
.ks-bet-row {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 8px;
}
/* Two side-by-side Buy buttons. Stake is set ONCE in the global
   widget (pinned to document.body) and applies to every Buy button. */
.ks-bet-buttons {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

/* Global stake widget — pinned to document.body so the markets pane
   re-render (every 8s) and the game-view re-render (every 5s) can't
   wipe the input mid-type. Shown only when #markets-pane is in the
   DOM (handled by syncGlobalStakeWidgetVisibility). */
.global-stake-widget {
    position: fixed;
    /* Slide below the page header (~48px tall — 12px padding + 24px
       content + 12px padding) so the LIVE pill at the top-right
       stays clickable. Was top: 16px, which laid right over it. */
    top: 64px;
    right: 16px;
    z-index: 9000;
    display: none;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    background: rgba(15, 23, 42, 0.95);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
    font-size: 11px;
    color: var(--text-dim);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 600;
    backdrop-filter: blur(4px);
}
.global-stake-widget.is-visible { display: inline-flex; }
.global-stake-widget .gsw-label { white-space: nowrap; }
.global-stake-widget .gsw-prefix {
    color: var(--text-dim);
    font-size: 13px;
    font-weight: 600;
    text-transform: none;
}
.global-stake-widget .gsw-input {
    width: 80px;
    padding: 6px 8px;
    background: rgba(15, 23, 42, 0.85);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
    font-family: inherit;
    font-variant-numeric: tabular-nums;
    text-align: right;
}
.global-stake-widget .gsw-input:focus {
    outline: none;
    border-color: var(--accent-action);
    background: rgba(15, 23, 42, 0.98);
}
.global-stake-widget .gsw-help {
    color: var(--text-faint);
    font-size: 10px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0.04em;
    max-width: 120px;
    line-height: 1.2;
}
.ks-bet-btn {
    flex: 1 1 0;
    padding: 8px 12px;
    border-radius: 6px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
    border: 1px solid transparent;
    font-family: inherit;
    transition: background 120ms, border-color 120ms, transform 80ms;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}
.ks-bet-btn-action {
    font-size: 11px;
    letter-spacing: 0.04em;
}
.ks-bet-btn-win {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.02em;
    opacity: 0.85;
    font-variant-numeric: tabular-nums;
    text-transform: none;
}
.ks-bet-btn:hover { transform: translateY(-1px); }
.ks-bet-btn:active { transform: translateY(0); }
.ks-bet-yes {
    background: rgba(34, 197, 94, 0.14);
    color: var(--accent-win);
    border-color: rgba(34, 197, 94, 0.35);
}
.ks-bet-yes:hover { background: rgba(34, 197, 94, 0.22); }
.ks-bet-no {
    background: rgba(239, 68, 68, 0.14);
    color: var(--accent-live);
    border-color: rgba(239, 68, 68, 0.35);
}
.ks-bet-no:hover { background: rgba(239, 68, 68, 0.22); }
.ks-bet-disconnected {
    background: transparent;
    border: 1px dashed var(--border);
    color: var(--text-dim);
}
.ks-bet-disconnected:hover {
    border-color: var(--accent-action);
    color: var(--accent-action);
}

/* Toast notifications (bottom-right, auto-dismiss). */
.ks-toasts {
    position: fixed;
    right: 16px;
    bottom: 20px;
    z-index: 1100;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: flex-end;
    pointer-events: none;
}
.ks-toast {
    padding: 10px 14px;
    border-radius: 6px;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    font-size: 12px;
    font-weight: 550;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
    transform: translateX(120%);
    transition: transform 220ms ease, opacity 220ms ease;
    opacity: 0;
    pointer-events: auto;
    max-width: 360px;
}
.ks-toast-show { transform: translateX(0); opacity: 1; }
.ks-toast-ok   { border-left: 3px solid var(--accent-win); }
.ks-toast-err  { border-left: 3px solid var(--accent-live); }


/* ═══════════════════════════════════════════════════════════════
   Bet modal take/post toggle + orderbook info
   ═══════════════════════════════════════════════════════════════ */

.km-mode-tabs {
    display: flex;
    gap: 0;
    margin: 16px 0 12px;
    border-bottom: 1px solid var(--border);
}
.km-mode-tab {
    background: transparent;
    border: none;
    color: var(--text-dim);
    padding: 10px 14px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    font-family: inherit;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 120ms, border-color 120ms;
}
.km-mode-tab:hover { color: var(--text); }
.km-mode-tab.active {
    color: var(--accent-action);
    border-bottom-color: var(--accent-action);
}

.km-mode-explainer {
    font-size: 11px;
    color: var(--text-faint);
    font-style: italic;
}

/* Orderbook info card inside take-mode */
.km-orderbook-info {
    padding: 10px 12px;
    background: rgba(56, 189, 248, 0.06);
    border: 1px solid rgba(56, 189, 248, 0.18);
    border-radius: 6px;
    margin-bottom: 12px;
    font-size: 12px;
}
.km-ob-loading {
    color: var(--text-faint);
    font-style: italic;
}
.km-ob-row {
    display: flex;
    align-items: baseline;
    gap: 8px;
}
.km-ob-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--text-dim);
    text-transform: uppercase;
}
.km-ob-val {
    color: var(--accent-win);
    font-weight: 700;
    font-size: 17px;
    font-variant-numeric: tabular-nums;
}
.km-ob-qty {
    color: var(--text-dim);
    font-size: 11px;
}
.km-ob-empty {
    color: var(--text-dim);
    line-height: 1.5;
    font-size: 12px;
}
.km-ob-empty strong { color: var(--accent-live); display: block; margin-bottom: 4px; }
.km-ob-empty em { font-style: italic; color: var(--text); }

.km-hint-warn {
    color: #FCA5A5;
    background: rgba(239, 68, 68, 0.08);
    padding: 4px 8px;
    border-radius: 3px;
    margin-top: 4px;
    display: block;
}


/* ═══════════════════════════════════════════════════════════════
   My Kalshi panel — balance + open orders + cancel
   Lives at the top of the markets dashboard.
   ═══════════════════════════════════════════════════════════════ */

.ks-mybets {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 8px 12px;
    margin-bottom: 6px;
}
.ks-mybets-disconnected .ks-mybets-empty {
    margin: 8px 0 0;
    font-size: 13px;
    color: var(--text-dim);
}
.ks-mybets-disconnected .ks-cta {
    background: transparent;
    border: 1px dashed rgba(56, 189, 248, 0.5);
    color: var(--accent-action);
    padding: 6px 12px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    font-family: inherit;
    margin-right: 6px;
    vertical-align: middle;
}
.ks-mybets-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    color: #86EFAC;
    text-transform: uppercase;
    margin-bottom: 4px;
}
.ks-mybets-refresh {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-dim);
    width: 24px;
    height: 24px;
    border-radius: 50%;
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    font-family: inherit;
    transition: color 120ms, border-color 120ms, transform 220ms;
}
.ks-mybets-refresh:hover {
    color: var(--text);
    border-color: var(--accent-action);
    transform: rotate(90deg);
}

.ks-mybets-grid {
    display: grid;
    grid-template-columns: 150px 1fr;
    gap: 14px;
    align-items: center;
}
@media (max-width: 720px) {
    .ks-mybets-grid { grid-template-columns: 1fr; }
}

.ks-mybets-key {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 6px;
}
.ks-mybets-balance-val {
    color: var(--accent-win);
    font-size: 17px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}
.ks-mybets-orders-empty {
    font-size: 12px;
    color: var(--text-faint);
    font-style: italic;
}
.ks-mybets-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}
.ks-mybets-table thead th {
    text-align: left;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-faint);
    padding: 6px 8px;
    border-bottom: 1px solid var(--border);
}
.ks-mybets-table tbody td {
    padding: 8px;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.ks-mybets-table tbody tr:last-child td { border-bottom: none; }
.ks-mybets-ticker {
    background: var(--bg);
    padding: 2px 6px;
    border-radius: 3px;
    font-size: 10px;
    font-family: ui-monospace, "SF Mono", Consolas, monospace;
}
.ks-mybets-side {
    font-size: 10px;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 999px;
    letter-spacing: 0.06em;
}
.ks-mybets-side-yes {
    background: rgba(34, 197, 94, 0.18);
    color: var(--accent-win);
}
.ks-mybets-side-no {
    background: rgba(239, 68, 68, 0.18);
    color: var(--accent-live);
}
.ks-mybets-cancel {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-dim);
    padding: 4px 10px;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    cursor: pointer;
    font-family: inherit;
    text-transform: uppercase;
    transition: color 120ms, border-color 120ms, background 120ms;
}
.ks-mybets-cancel:hover {
    color: var(--accent-live);
    border-color: var(--accent-live);
    background: rgba(239, 68, 68, 0.08);
}
.ks-mybets-cancel:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}


/* (Deal-finder styles removed along with the widget — the global
   stake widget at top-right + per-game inline bet calculators
   replaced its workflow.) */


/* ═══════════════════════════════════════════════════════════════
   Health indicator + panel
   - Small colored dot pinned bottom-right that polls /api/health
     every 30s and flashes when a service degrades.
   - Click opens a detail panel listing every check + latency.
   ═══════════════════════════════════════════════════════════════ */

.health-indicator {
    position: fixed;
    right: 14px;
    bottom: 50px;          /* above the bottom nav, doesn't overlap toasts */
    width: 12px;
    height: 12px;
    border-radius: 50%;
    z-index: 950;
    cursor: pointer;
    transition: background 200ms, box-shadow 200ms, transform 200ms;
    box-shadow: 0 0 0 2px var(--bg), 0 0 8px rgba(0,0,0,0.6);
}
.health-indicator:hover { transform: scale(1.3); }
.health-indicator.ok        { background: var(--accent-win); }
.health-indicator.ok:hover  { box-shadow: 0 0 0 2px var(--bg), 0 0 14px rgba(34, 197, 94, 0.7); }
.health-indicator.degraded  {
    background: #FCD34D;
    animation: health-pulse 2.4s ease-in-out infinite;
}
.health-indicator.degraded:hover { box-shadow: 0 0 0 2px var(--bg), 0 0 14px rgba(252, 211, 77, 0.8); }
.health-indicator.down      {
    background: var(--accent-live);
    animation: health-pulse 1.2s ease-in-out infinite;
}
.health-indicator.down:hover { box-shadow: 0 0 0 2px var(--bg), 0 0 14px rgba(239, 68, 68, 0.8); }
.health-indicator.unknown   { background: var(--text-faint); opacity: 0.6; }

@keyframes health-pulse {
    0%,100% { box-shadow: 0 0 0 2px var(--bg), 0 0 4px currentColor; }
    50%     { box-shadow: 0 0 0 2px var(--bg), 0 0 16px currentColor; }
}

.health-panel-overlay {
    position: fixed;
    inset: 0;
    background: rgba(11, 18, 32, 0.78);
    backdrop-filter: blur(4px);
    z-index: 951;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}
.health-panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 22px 24px;
    max-width: 600px;
    width: 100%;
    position: relative;
    color: var(--text);
    box-shadow: 0 18px 60px rgba(0,0,0,0.6);
}
.health-panel h3 {
    margin: 0 0 8px;
    font-size: 15px;
    font-weight: 700;
    display: flex;
    align-items: center;
    gap: 10px;
}
.health-panel-close {
    position: absolute;
    top: 12px;
    right: 14px;
    background: transparent;
    border: none;
    color: var(--text-dim);
    font-size: 22px;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 4px;
    line-height: 1;
}
.health-panel-close:hover { color: var(--text); background: rgba(255, 255, 255, 0.06); }

.health-panel-sub {
    font-size: 11px;
    color: var(--text-dim);
    margin: 0 0 14px;
}
.health-panel-empty {
    font-size: 12px;
    color: var(--text-dim);
    font-style: italic;
}
.health-panel-recheck {
    margin-top: 14px;
    background: var(--accent-action);
    color: white;
    border: none;
    border-radius: 6px;
    padding: 8px 16px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    letter-spacing: 0.04em;
}
.health-panel-recheck:hover { background: #2563EB; }
.health-panel-recheck:disabled { opacity: 0.6; cursor: not-allowed; }

.health-pill {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 3px 8px;
    border-radius: 999px;
}
.health-pill-ok   { background: rgba(34, 197, 94, 0.18);  color: var(--accent-win); }
.health-pill-down { background: rgba(239, 68, 68, 0.18);  color: var(--accent-live); }

.health-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
    margin-top: 4px;
}
.health-table thead th {
    text-align: left;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-faint);
    padding: 6px 8px;
    border-bottom: 1px solid var(--border);
}
.health-table tbody td {
    padding: 8px;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.health-table tbody tr:last-child td { border-bottom: none; }
.health-table tbody tr.row-ok td:nth-child(2)   { color: var(--accent-win); }
.health-table tbody tr.row-down td:nth-child(2) { color: var(--accent-live); font-weight: 700; }
.health-table .health-err {
    color: var(--text-faint);
    font-size: 11px;
    font-family: ui-monospace, "SF Mono", Consolas, monospace;
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.health-table code {
    background: var(--bg);
    padding: 2px 6px;
    border-radius: 3px;
    font-size: 11px;
    font-family: ui-monospace, "SF Mono", Consolas, monospace;
}

/* Degraded banner — pinned to top of viewport when health checker
   detects a service is failing. Auto-shown / hidden by health.js
   based on /api/health response. */
.health-degraded-banner {
    position: fixed;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 952;
    background: rgba(252, 211, 77, 0.14);
    border: 1px solid rgba(252, 211, 77, 0.4);
    color: #FCD34D;
    padding: 8px 14px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 550;
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: 90vw;
    backdrop-filter: blur(6px);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
    animation: hdb-slide-in 280ms ease-out;
}
.health-degraded-banner .hdb-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #FCD34D;
    box-shadow: 0 0 8px rgba(252, 211, 77, 0.7);
    animation: health-pulse 1.6s ease-in-out infinite;
    flex-shrink: 0;
}
.health-degraded-banner .hdb-text strong { color: #FEF3C7; }
.health-degraded-banner .hdb-dismiss {
    background: transparent;
    border: none;
    color: #FCD34D;
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
    padding: 0 4px;
    opacity: 0.7;
}
.health-degraded-banner .hdb-dismiss:hover { opacity: 1; }
@keyframes hdb-slide-in {
    from { opacity: 0; transform: translate(-50%, -20px); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}


/* ═══════════════════════════════════════════════════════════════
   Auth — sign-in pill (top-left near logo), modal, signed-in menu
   ═══════════════════════════════════════════════════════════════ */

.auth-header-widget {
    position: fixed;
    top: 12px;
    left: 220px;            /* sits next to DIAMOND:CONTEXT logo */
    z-index: 9100;
    display: flex;
    align-items: center;
    gap: 8px;
}
/* "Connect Kalshi →" pill — visible whenever the signed-in user
   has NOT yet stored Kalshi API credentials. Disappears the moment
   Kalshi.isConnected() flips to true (a MutationObserver in
   auth.js re-renders on the credential change). */
.auth-kalshi-cta {
    appearance: none;
    background: rgba(34, 197, 94, 0.14);
    border: 1px solid rgba(34, 197, 94, 0.35);
    color: var(--accent-win);
    padding: 5px 12px;
    border-radius: 999px;
    font: inherit;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background 120ms, transform 80ms, border-color 120ms;
}
.auth-kalshi-cta:hover {
    background: rgba(34, 197, 94, 0.22);
    transform: translateY(-1px);
}
.auth-kalshi-cta:active { transform: translateY(0); }
.auth-signin-btn {
    appearance: none;
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-dim);
    padding: 5px 14px;
    border-radius: 999px;
    font: inherit;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    cursor: pointer;
    transition: color 120ms, border-color 120ms, background 120ms;
}
.auth-signin-btn:hover {
    color: var(--text);
    border-color: var(--accent-action);
    background: rgba(56, 189, 248, 0.06);
}
.auth-pill {
    appearance: none;
    background: rgba(15, 23, 42, 0.85);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 4px 10px 4px 4px;
    border-radius: 999px;
    font: inherit;
    font-size: 12px;
    font-weight: 550;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    transition: border-color 120ms, background 120ms;
}
.auth-pill:hover {
    border-color: var(--accent-action);
    background: rgba(15, 23, 42, 0.95);
}
.auth-avatar {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--accent-action);
    color: #0B1220;
    font-size: 11px;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.auth-email {
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.auth-caret {
    color: var(--text-dim);
    font-size: 10px;
}
.auth-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    min-width: 220px;
    background: rgba(15, 23, 42, 0.98);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 6px;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(6px);
}
.auth-menu-email {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
    padding: 6px 10px 4px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 4px;
    max-width: 240px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.auth-menu-item {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text);
    font: inherit;
    font-size: 12px;
    width: 100%;
    padding: 8px 10px;
    text-align: left;
    border-radius: 5px;
    cursor: pointer;
    transition: background 120ms, color 120ms;
}
.auth-menu-item:hover {
    background: rgba(56, 189, 248, 0.10);
    color: var(--text);
}
.auth-menu-danger {
    color: var(--accent-live);
}
.auth-menu-danger:hover {
    background: rgba(239, 68, 68, 0.10);
    color: var(--accent-live);
}

/* Sign-in modal */
.auth-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.65);
    backdrop-filter: blur(4px);
    z-index: 9500;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.auth-modal {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 32px;
    max-width: 420px;
    width: 100%;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
}
.auth-modal-close {
    position: absolute;
    top: 12px;
    right: 12px;
    background: transparent;
    border: none;
    color: var(--text-dim);
    font-size: 20px;
    cursor: pointer;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    transition: background 120ms, color 120ms;
}
.auth-modal-close:hover {
    background: rgba(148, 163, 184, 0.1);
    color: var(--text);
}
.auth-modal-title {
    font-size: 20px;
    font-weight: 700;
    margin: 0 0 6px;
    color: var(--text);
}
.auth-modal-sub {
    color: var(--text-dim);
    font-size: 13px;
    line-height: 1.5;
    margin: 0 0 20px;
}
.auth-form {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.auth-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.auth-field-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-dim);
}
.auth-field input {
    background: rgba(15, 23, 42, 0.7);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text);
    padding: 10px 12px;
    font: inherit;
    font-size: 13px;
    transition: border-color 120ms;
}
.auth-field input:focus {
    outline: none;
    border-color: var(--accent-action);
    box-shadow: 0 0 0 3px rgba(56, 189, 248, 0.15);
}
.auth-error {
    color: var(--accent-live);
    font-size: 12px;
    padding: 8px 12px;
    background: rgba(239, 68, 68, 0.08);
    border: 1px solid rgba(239, 68, 68, 0.25);
    border-radius: 6px;
}
.auth-submit {
    appearance: none;
    background: var(--accent-action);
    color: #0B1220;
    border: none;
    border-radius: 8px;
    padding: 11px 16px;
    font: inherit;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: background 120ms, transform 80ms;
}
.auth-submit:hover { background: #0EA5E9; transform: translateY(-1px); }
.auth-submit:active { transform: translateY(0); }
.auth-submit:disabled { opacity: 0.6; cursor: wait; transform: none; }
.auth-modal-footnote {
    font-size: 11px;
    color: var(--text-faint);
    margin-top: 16px;
    text-align: center;
    line-height: 1.4;
}
.auth-sent-icon {
    font-size: 40px;
    text-align: center;
    margin-bottom: 8px;
}
.auth-modal-tip {
    color: var(--text-dim);
    font-size: 12px;
    margin-top: 16px;
    text-align: center;
    line-height: 1.5;
}
.auth-link {
    appearance: none;
    background: none;
    border: none;
    color: var(--accent-action);
    font: inherit;
    font-size: inherit;
    cursor: pointer;
    padding: 0;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.auth-link:hover { color: #0EA5E9; }


/* Kalshi connection guide modal */
.kalshi-guide-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(4px);
    z-index: 9600;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 40px 20px;
    overflow-y: auto;
}
.kalshi-guide {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 36px 40px;
    max-width: 680px;
    width: 100%;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
}
.kalshi-guide-close {
    position: absolute;
    top: 16px;
    right: 16px;
    background: transparent;
    border: none;
    color: var(--text-dim);
    font-size: 22px;
    cursor: pointer;
    width: 30px;
    height: 30px;
    border-radius: 50%;
}
.kalshi-guide-close:hover { background: rgba(148, 163, 184, 0.12); color: var(--text); }
.kalshi-guide-head h2 {
    font-size: 22px;
    font-weight: 700;
    margin: 0 0 6px;
    color: var(--text);
}
.kalshi-guide-sub {
    color: var(--text-dim);
    font-size: 14px;
    margin: 0 0 28px;
    line-height: 1.5;
}
.kalshi-guide-steps {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 28px;
}
.kalshi-guide-steps > li {
    display: grid;
    grid-template-columns: 44px 1fr;
    gap: 16px;
    align-items: flex-start;
}
.kg-step-num {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--accent-action);
    color: #0B1220;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    font-weight: 700;
    margin-top: 2px;
}
.kg-step-body h3 {
    font-size: 15px;
    font-weight: 600;
    margin: 0 0 8px;
    color: var(--text);
}
.kg-step-body p {
    color: var(--text);
    font-size: 13px;
    line-height: 1.6;
    margin: 0 0 10px;
}
.kg-step-body a {
    color: var(--accent-action);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.kg-step-body code {
    background: rgba(15, 23, 42, 0.7);
    border: 1px solid var(--border);
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 12px;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    color: var(--accent-action);
}
.kg-list {
    margin: 4px 0 12px;
    padding-left: 22px;
    color: var(--text);
    font-size: 13px;
    line-height: 1.7;
}
.kg-tip {
    color: var(--text-dim) !important;
    font-size: 12px !important;
    background: rgba(56, 189, 248, 0.05);
    border-left: 3px solid var(--accent-action);
    padding: 8px 12px !important;
    border-radius: 0 6px 6px 0;
    margin-top: 8px !important;
}
.kg-warn {
    color: var(--text) !important;
    font-size: 12px !important;
    background: rgba(239, 68, 68, 0.06);
    border-left: 3px solid var(--accent-live);
    padding: 10px 12px !important;
    border-radius: 0 6px 6px 0;
    margin-top: 8px !important;
}
.kalshi-guide-foot {
    margin-top: 28px;
    display: flex;
    justify-content: flex-end;
}
.kalshi-guide-dismiss {
    appearance: none;
    background: var(--accent-win);
    color: #0B1220;
    border: none;
    border-radius: 8px;
    padding: 10px 20px;
    font: inherit;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}
.kalshi-guide-dismiss:hover { background: #16A34A; }

/* "Full step-by-step guide" link inside the Connect Kalshi modal */
.km-sub-help {
    font-size: 12px;
    color: var(--text-dim);
    margin-top: -6px;
    margin-bottom: 16px;
}
.km-help-link {
    appearance: none;
    background: none;
    border: none;
    color: var(--accent-action);
    font: inherit;
    font-size: 12px;
    cursor: pointer;
    padding: 0 0 0 4px;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.km-help-link:hover { color: #0EA5E9; }


/* ═══════════════════════════════════════════════════════════════
   AutoBot — floating launcher button + Bets/Bot drawer
   ═══════════════════════════════════════════════════════════════ */

.bot-launcher {
    position: fixed;
    bottom: 78px;          /* sits above the bottom nav */
    right: 16px;
    z-index: 9000;
    appearance: none;
    background: rgba(15, 23, 42, 0.95);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 10px 16px;
    border-radius: 999px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(4px);
    transition: transform 120ms, border-color 120ms;
}
.bot-launcher:hover {
    transform: translateY(-2px);
    border-color: var(--accent-action);
}
.bot-launcher-icon { font-size: 15px; }
.bot-launcher-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent-win);
    box-shadow: 0 0 8px rgba(34, 197, 94, 0.7);
    animation: bot-pulse 1.6s ease-in-out infinite;
}
@keyframes bot-pulse {
    0%,100% { opacity: 1; }
    50%     { opacity: 0.4; }
}

/* Docked side-panel mode — user direction (2026-06-05): drawer
   shouldn't blur the rest of the screen, it should take the right
   side of the page and let the rest of the content stay interactive.
   Container is now anchored to the right edge with no backdrop;
   pointer-events pass through anywhere except the drawer itself, so
   the page underneath stays clickable. body.bot-drawer-open adds
   padding-right so the page reflows left of the panel instead of
   being hidden behind it. */
.bot-drawer-overlay {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 560px;
    max-width: 100vw;
    z-index: 9500;
    pointer-events: none;
    display: flex;
    justify-content: flex-end;
}
body.bot-drawer-open {
    padding-right: 560px;
}
.bot-drawer {
    width: 560px;
    max-width: 100vw;
    height: 100%;
    background: var(--surface);
    border-left: 1px solid var(--border);
    overflow-y: auto;
    box-shadow: -8px 0 32px rgba(0, 0, 0, 0.4);
    display: flex;
    flex-direction: column;
    pointer-events: auto;
}
/* Fixed bottom-right widgets: when the drawer is docked they would
   otherwise hide behind the panel. Hide the launcher (its job is to
   open the drawer, which is already open); slide any active-bets
   pill that's anchored to the right edge over by the drawer width. */
body.bot-drawer-open .bot-launcher { display: none; }

/* Bottom active-bets pill is redundant inside a game view — the rail
   bets card already shows every position on this game with progress
   bars. User feedback (2026-06-05): it was overlapping the rail's
   past-PA list. Hide it whenever the game view is on screen. */
body:has(#game-view:not([hidden])) .active-bets-strip { display: none !important; }

/* Mobile: fall back to the old full-cover behavior, since a 560px
   docked panel + the page content won't both fit. */
@media (max-width: 980px) {
    body.bot-drawer-open { padding-right: 0; }
    .bot-drawer-overlay {
        top: 0; right: 0; bottom: 0; left: 0;
        width: 100%;
        background: rgba(0, 0, 0, 0.55);
        backdrop-filter: blur(4px);
        pointer-events: auto;
    }
    body.bot-drawer-open .bot-launcher { display: inline-flex; }
}
.bot-drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 24px;
    border-bottom: 1px solid var(--border);
}
.bot-drawer-head h2 {
    font-size: 17px;
    font-weight: 700;
    letter-spacing: 0.04em;
    margin: 0;
}
.bot-drawer-close {
    background: transparent;
    border: none;
    color: var(--text-dim);
    font-size: 22px;
    cursor: pointer;
    width: 30px;
    height: 30px;
    border-radius: 50%;
}
.bot-drawer-close:hover { background: rgba(148, 163, 184, 0.1); color: var(--text); }

/* Header actions row — mailbox + close. */
.bot-drawer-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Mailbox button (replaces the old Questions tab). Lives in the
   drawer header; click opens a popover with the notification list. */
.bot-mailbox {
    position: relative;
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-dim);
    font-size: 14px;
    cursor: pointer;
    width: 36px;
    height: 30px;
    border-radius: 8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 120ms, color 120ms, border-color 120ms;
}
.bot-mailbox:hover {
    background: rgba(148, 163, 184, 0.1);
    color: var(--text);
}
.bot-mailbox-icon {
    font-size: 14px;
    line-height: 1;
}
.bot-mailbox-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    background: rgba(148, 163, 184, 0.25);
    color: var(--text-dim);
    border-radius: 999px;
    font-size: 9px;
    font-weight: 700;
    min-width: 16px;
    height: 16px;
    line-height: 16px;
    padding: 0 4px;
    text-align: center;
}
.bot-mailbox-badge.has-unread {
    background: var(--accent-live);
    color: #fff;
}

/* Mailbox popover — slides down from the header, sits above the
   tab content. Click 'close' or toggle the button to hide. */
.bot-mailbox-popover {
    position: absolute;
    top: 64px;       /* below the header */
    right: 16px;
    width: min(420px, calc(100% - 32px));
    max-height: calc(100% - 88px);
    overflow-y: auto;
    background: var(--surface, #0F172A);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
    z-index: 10;
}
.bot-mailbox-popover[hidden] { display: none; }
.bot-mailbox-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
}
.bot-mailbox-title {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
}
.bot-mailbox-actions {
    display: flex;
    align-items: center;
    gap: 6px;
}
.bot-mailbox-close {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text-dim);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    width: 24px;
    height: 24px;
    border-radius: 4px;
}
.bot-mailbox-close:hover {
    background: rgba(148, 163, 184, 0.1);
    color: var(--text);
}

.bot-drawer-tabs {
    display: flex;
    gap: 2px;
    padding: 0 16px;
    border-bottom: 1px solid var(--border);
    /* Horizontal scroll fallback for narrow viewports / when more
       tabs are added — scrollbar hidden, mask hints at content. */
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}
.bot-drawer-tabs::-webkit-scrollbar { display: none; }
.bot-tab {
    flex: 0 0 auto;
    background: transparent;
    border: none;
    color: var(--text-dim);
    padding: 11px 9px;
    font: inherit;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
    transition: color 120ms, border-color 120ms;
}
.bot-tab:hover { color: var(--text); }
.bot-tab.active { color: var(--accent-action); border-bottom-color: var(--accent-action); }
.bot-tab-count {
    background: rgba(148, 163, 184, 0.15);
    color: var(--text-dim);
    padding: 1px 7px;
    border-radius: 99px;
    font-size: 10px;
    font-weight: 600;
}
.bot-tab.active .bot-tab-count {
    background: rgba(56, 189, 248, 0.18);
    color: var(--accent-action);
}
/* Unread badge — bright red when notifications need attention. */
.bot-tab-count.bot-tab-unread.has-unread {
    background: rgba(239, 68, 68, 0.85);
    color: #fff;
    box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.25);
}

/* ── Questions / notifications pane ────────────────────────────── */
.bot-questions-empty {
    text-align: center;
    padding: 40px 20px;
}
.bot-questions-empty p { margin: 8px 0; color: var(--text-dim); }
.bot-questions-empty .bot-help {
    font-size: 12px;
    max-width: 420px;
    margin: 12px auto 0;
    line-height: 1.5;
}
.bot-questions-head {
    display: flex;
    gap: 8px;
    margin-bottom: 12px;
}
.bot-notif-mark-all,
.bot-notif-clear-all {
    background: rgba(148, 163, 184, 0.12);
    border: 1px solid rgba(148, 163, 184, 0.25);
    color: var(--text-dim);
    padding: 4px 12px;
    border-radius: 6px;
    font-size: 11px;
    cursor: pointer;
}
.bot-notif-mark-all:hover,
.bot-notif-clear-all:hover { color: var(--text); }

.bot-notif-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.bot-notif {
    border: 1px solid rgba(148, 163, 184, 0.18);
    border-left: 3px solid var(--text-dim);
    background: rgba(15, 23, 42, 0.45);
    border-radius: 6px;
    padding: 10px 12px;
    transition: opacity 0.2s ease;
}
.bot-notif.is-read { opacity: 0.55; }
.bot-notif.notif-error  { border-left-color: #ef4444; }
.bot-notif.notif-warn   { border-left-color: #f59e0b; }
.bot-notif.notif-info   { border-left-color: #38bdf8; }
.bot-notif.notif-question { border-left-color: #a855f7; }

.bot-notif-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    margin-bottom: 4px;
}
.bot-notif-title {
    font-weight: 600;
    color: var(--text);
    font-size: 13px;
}
.bot-notif-count {
    background: rgba(239, 68, 68, 0.2);
    color: #fca5a5;
    padding: 1px 6px;
    border-radius: 99px;
    font-size: 10px;
    margin-left: 6px;
}
.bot-notif-ts {
    font-size: 10px;
    color: var(--text-dim);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.bot-notif-body {
    color: var(--text-dim);
    font-size: 12px;
    line-height: 1.5;
    margin-bottom: 8px;
}
.bot-notif-actions {
    display: flex;
    gap: 8px;
    align-items: center;
}
.bot-notif-action {
    background: rgba(56, 189, 248, 0.15);
    color: var(--accent-action);
    border: 1px solid rgba(56, 189, 248, 0.3);
    padding: 3px 10px;
    border-radius: 5px;
    font-size: 11px;
    text-decoration: none;
}
.bot-notif-action:hover {
    background: rgba(56, 189, 248, 0.25);
}
.bot-notif-mark {
    background: transparent;
    color: var(--text-dim);
    border: 1px solid rgba(148, 163, 184, 0.2);
    padding: 3px 10px;
    border-radius: 5px;
    font-size: 11px;
    cursor: pointer;
}
.bot-notif-mark:hover { color: var(--text); }

/* ── Practice mode (paper trading) ──────────────────────────────── */
.bot-practice-head {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
    margin-bottom: 16px;
    padding: 12px 14px;
    background: rgba(56, 189, 248, 0.06);
    border: 1px solid rgba(56, 189, 248, 0.2);
    border-radius: 8px;
}
.bot-practice-mode-on {
    background: rgba(34, 197, 94, 0.2);
    color: #22C55E;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    padding: 5px 12px;
    border-radius: 5px;
    font-size: 11px;
}

/* Card-style practice summary banner. Four stat tiles side-by-side
   instead of one wrapped sentence. Easier to scan at a glance. */
.bot-practice-summary {
    display: grid;
    grid-template-columns: auto repeat(4, 1fr);
    gap: 12px;
    align-items: stretch;
    padding: 12px;
    background: rgba(56, 189, 248, 0.04);
    border: 1px solid rgba(56, 189, 248, 0.18);
    border-radius: 10px;
    margin-bottom: 12px;
}
.bot-practice-summary-tag {
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(34, 197, 94, 0.18);
    color: #22C55E;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 6px 14px;
    border-radius: 6px;
    font-size: 11px;
}
.bot-practice-stat {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.bot-practice-stat-label {
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
}
.bot-practice-stat-val {
    font-size: 18px;
    font-weight: 700;
    color: var(--text);
    line-height: 1.1;
}
.bot-practice-stat-sub {
    font-size: 11px;
    color: var(--text-dim);
}
@media (max-width: 720px) {
    .bot-practice-summary {
        grid-template-columns: 1fr 1fr;
    }
    .bot-practice-summary-tag {
        grid-column: 1 / -1;
    }
}

/* 50/50 ML / props split-bar — lives below the summary banner.
   Two thin progress bars showing open exposure against each
   kind's cap. Reminds the user that ML budget is reserved even
   if it's not currently being spent. */
.bot-split-bar {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px 12px;
    margin: -4px 0 12px;
    background: rgba(15, 23, 42, 0.5);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.bot-split-bar-row {
    display: grid;
    grid-template-columns: 110px 1fr 130px;
    align-items: center;
    gap: 10px;
    font-size: 11px;
}
.bot-split-bar-label {
    font-weight: 600;
    color: var(--text);
    letter-spacing: 0.04em;
}
.bot-split-bar-track {
    position: relative;
    height: 8px;
    background: rgba(148, 163, 184, 0.15);
    border-radius: 999px;
    overflow: hidden;
}
.bot-split-bar-fill {
    position: absolute;
    top: 0; left: 0; bottom: 0;
    border-radius: 999px;
    transition: width 240ms;
}
.bot-split-bar-fill-ml {
    background: linear-gradient(90deg, #38BDF8, #22C55E);
}
.bot-split-bar-fill-prop {
    background: linear-gradient(90deg, #A78BFA, #F472B6);
}
.bot-split-bar-numbers {
    text-align: right;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}
@media (max-width: 540px) {
    .bot-split-bar-row {
        grid-template-columns: 90px 1fr 100px;
    }
}

/* Active / History toggle on the Practice pane. Pill group
   centered above the bets list. */
.bot-filter-pills {
    display: flex;
    gap: 6px;
    margin-bottom: 10px;
}
.bot-filter-pill {
    appearance: none;
    background: rgba(15, 23, 42, 0.6);
    border: 1px solid rgba(148, 163, 184, 0.22);
    color: var(--text-dim);
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 6px 12px;
    border-radius: 999px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background 120ms, color 120ms, border-color 120ms;
}
.bot-filter-pill:hover {
    background: rgba(30, 41, 59, 0.85);
    color: var(--text);
}
.bot-filter-pill.is-on {
    background: rgba(56, 189, 248, 0.18);
    border-color: rgba(56, 189, 248, 0.45);
    color: var(--accent-action, #38BDF8);
}
.bot-filter-pill-count {
    background: rgba(148, 163, 184, 0.18);
    color: inherit;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 700;
}
.bot-practice-mode-off {
    color: var(--text-dim);
    font-size: 12px;
    flex: 1 1 auto;
}
.bot-practice-toggle {
    padding: 7px 14px;
    border-radius: 6px;
    border: 1px solid;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.bot-practice-toggle.is-off {
    background: rgba(34, 197, 94, 0.15);
    color: #22C55E;
    border-color: rgba(34, 197, 94, 0.4);
}
.bot-practice-toggle.is-on {
    background: rgba(148, 163, 184, 0.12);
    color: var(--text);
    border-color: rgba(148, 163, 184, 0.3);
}
.bot-practice-reset {
    background: transparent;
    color: var(--text-dim);
    border: 1px solid rgba(148, 163, 184, 0.25);
    padding: 6px 10px;
    border-radius: 5px;
    font-size: 11px;
    cursor: pointer;
}
.bot-practice-reset:hover { color: var(--text); }
.bot-practice-summary {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin-bottom: 16px;
}
.bot-practice-stat {
    background: rgba(15, 23, 42, 0.45);
    border: 1px solid rgba(148, 163, 184, 0.15);
    border-radius: 6px;
    padding: 10px 12px;
    text-align: center;
}
.bot-practice-stat-num {
    font-size: 18px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    color: var(--text);
    margin-bottom: 2px;
}
.bot-practice-stat-lbl {
    font-size: 10px;
    color: var(--text-dim);
    letter-spacing: 0.05em;
    text-transform: uppercase;
}
/* Pending approval queue */
.bot-pending-section {
    margin-bottom: 20px;
}
.bot-pending-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: #fbbf24;
    margin-bottom: 10px;
    padding: 8px 12px;
    background: rgba(251, 191, 36, 0.1);
    border: 1px solid rgba(251, 191, 36, 0.3);
    border-radius: 6px;
}
.bot-pending-clear {
    background: transparent;
    color: var(--text-dim);
    border: 1px solid rgba(148, 163, 184, 0.25);
    padding: 4px 10px;
    border-radius: 4px;
    font-size: 11px;
    cursor: pointer;
}
.bot-pending-clear:hover { color: var(--text); }
.bot-pending-card {
    background: rgba(15, 23, 42, 0.65);
    border: 2px solid rgba(251, 191, 36, 0.35);
    border-radius: 8px;
    padding: 14px 16px;
    margin-bottom: 12px;
}
.bot-pending-head-row {
    display: grid;
    grid-template-columns: 1fr auto auto auto auto;
    gap: 10px;
    align-items: center;
    font-size: 13px;
    margin-bottom: 10px;
    padding-bottom: 10px;
    border-bottom: 1px solid rgba(148, 163, 184, 0.1);
}
.bot-pending-label {
    color: var(--text);
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bot-pending-size,
.bot-pending-cost {
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
    font-size: 12px;
}
.bot-pending-ts {
    color: var(--text-dim);
    font-size: 11px;
}
.bot-pending-reasoning {
    margin-bottom: 12px;
}
.bot-pending-actions {
    display: flex;
    gap: 8px;
    margin-bottom: 8px;
}
.bot-pending-approve,
.bot-pending-decline {
    padding: 8px 16px;
    border-radius: 6px;
    border: none;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    transition: background 120ms;
}
.bot-pending-approve {
    background: #22C55E;
    color: #fff;
    flex: 1;
}
.bot-pending-approve:hover { background: #16a34a; }
.bot-pending-decline {
    background: rgba(239, 68, 68, 0.18);
    color: #fca5a5;
    border: 1px solid rgba(239, 68, 68, 0.4);
    flex: 1;
}
.bot-pending-decline:hover {
    background: rgba(239, 68, 68, 0.3);
    color: #fff;
}
.bot-pending-note-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.bot-pending-note-label {
    font-size: 10px;
    color: var(--text-dim);
}
.bot-pending-note-input {
    background: rgba(15, 23, 42, 0.6);
    border: 1px solid rgba(148, 163, 184, 0.25);
    color: var(--text);
    padding: 6px 10px;
    border-radius: 4px;
    font-size: 12px;
    width: 100%;
    box-sizing: border-box;
}

/* Bankroll block */
.bot-practice-bankroll {
    margin-bottom: 16px;
    padding: 14px 16px;
    background: rgba(34, 197, 94, 0.08);
    border: 1px solid rgba(34, 197, 94, 0.25);
    border-radius: 8px;
}
.bot-practice-bankroll-row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 10px;
}
.bot-practice-bankroll-label {
    color: var(--text-dim);
    font-size: 11px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    font-weight: 600;
}
.bot-practice-bankroll-amt {
    font-size: 22px;
    font-weight: 800;
    color: #22C55E;
    font-variant-numeric: tabular-nums;
}
.bot-practice-bankroll-of {
    color: var(--text-dim);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}
.bot-practice-bankroll-bar {
    height: 6px;
    background: rgba(148, 163, 184, 0.15);
    border-radius: 999px;
    overflow: hidden;
    margin-bottom: 10px;
}
.bot-practice-bankroll-fill {
    height: 100%;
    background: linear-gradient(90deg, #22C55E, #4ade80);
    border-radius: 999px;
    transition: width 200ms ease;
}
.bot-practice-bankroll-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
}
.bot-practice-bankroll-input {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    color: var(--text-dim);
}
.bot-practice-bankroll-input input {
    background: rgba(15, 23, 42, 0.6);
    border: 1px solid rgba(148, 163, 184, 0.25);
    color: var(--text);
    padding: 4px 8px;
    border-radius: 4px;
    width: 70px;
    font-variant-numeric: tabular-nums;
}

/* Expandable practice cards */
.bot-practice-list-head {
    font-size: 11px;
    color: var(--text-dim);
    margin-bottom: 8px;
    letter-spacing: 0.04em;
}
.bot-practice-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.bot-practice-card {
    background: rgba(15, 23, 42, 0.45);
    border: 1px solid rgba(148, 163, 184, 0.12);
    border-radius: 6px;
    overflow: hidden;
}
.bot-practice-card[open] {
    border-color: rgba(56, 189, 248, 0.4);
    background: rgba(15, 23, 42, 0.65);
}
.bot-practice-summary-row {
    display: grid;
    grid-template-columns: 1fr auto auto auto auto auto auto;
    gap: 10px;
    align-items: center;
    padding: 8px 12px;
    cursor: pointer;
    font-size: 12px;
    list-style: none;
}
.bot-practice-summary-row::-webkit-details-marker { display: none; }
.bot-practice-summary-row::before {
    content: "▶";
    color: var(--text-dim);
    font-size: 9px;
    margin-right: 2px;
    transition: transform 120ms;
}
.bot-practice-card[open] .bot-practice-summary-row::before {
    transform: rotate(90deg);
}
.bot-practice-bet {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text);
    font-weight: 500;
}
.bot-practice-size,
.bot-practice-cost,
.bot-practice-livebid {
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}
.bot-practice-pnl {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    min-width: 60px;
    text-align: right;
}
.bot-practice-time {
    font-size: 10px;
    color: var(--text-dim);
    min-width: 50px;
    text-align: right;
}

/* Reasoning panel inside expanded card */
.bot-practice-detail {
    padding: 0 14px 14px;
    border-top: 1px solid rgba(148, 163, 184, 0.1);
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.bot-reasoning-section {
    background: rgba(15, 23, 42, 0.45);
    border: 1px solid rgba(148, 163, 184, 0.1);
    border-radius: 6px;
    padding: 10px 12px;
    margin-top: 12px;
}
.bot-reasoning-h {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent-action);
    margin-bottom: 8px;
}
.bot-reasoning-rows > div {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 3px 0;
    font-size: 12px;
    border-bottom: 1px solid rgba(148, 163, 184, 0.05);
}
.bot-reasoning-rows > div:last-child { border-bottom: none; }
.bot-reasoning-rows span { color: var(--text-dim); }
.bot-reasoning-rows strong { color: var(--text); font-variant-numeric: tabular-nums; }
.bot-factor-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px dashed rgba(148, 163, 184, 0.15);
}
.bot-factor-row {
    display: grid;
    grid-template-columns: 130px 60px 40px 1fr;
    gap: 8px;
    align-items: center;
    font-size: 11px;
}
.bot-factor-row.bot-factor-absent {
    opacity: 0.4;
    grid-template-columns: 130px 1fr;
}
.bot-factor-name { color: var(--text); }
.bot-factor-state { color: var(--text-dim); font-style: italic; }
.bot-factor-adjust { font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }
.bot-factor-weight { color: var(--text-dim); font-size: 10px; }
.bot-factor-value { color: var(--text-dim); font-size: 10px; }
.bot-gate-list {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}
.bot-gate-chip {
    background: rgba(34, 197, 94, 0.12);
    color: #22C55E;
    border: 1px solid rgba(34, 197, 94, 0.2);
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 10px;
}

/* ── Simple bot ON/OFF button ───────────────────────────────────── */
.bot-onoff {
    margin-bottom: 12px;
}
.bot-onoff-btn {
    width: 100%;
    padding: 16px 20px;
    border: none;
    border-radius: 10px;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: background 120ms, color 120ms;
}
.bot-onoff-btn.is-off {
    background: rgba(148, 163, 184, 0.12);
    color: var(--text);
    border: 2px solid rgba(148, 163, 184, 0.25);
}
.bot-onoff-btn.is-off:hover {
    background: rgba(34, 197, 94, 0.15);
    border-color: rgba(34, 197, 94, 0.4);
    color: #22C55E;
}
.bot-onoff-btn.is-on {
    background: rgba(34, 197, 94, 0.18);
    color: #22C55E;
    border: 2px solid #22C55E;
    box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.1);
}
.bot-onoff-btn.is-on:hover {
    background: rgba(239, 68, 68, 0.18);
    border-color: #ef4444;
    color: #ef4444;
}

/* Emergency actions collapsed by default — no more banner clutter. */
.bot-emergency-fold {
    margin-top: 16px;
    padding: 10px 12px;
    background: rgba(148, 163, 184, 0.05);
    border-radius: 6px;
    border: 1px solid rgba(148, 163, 184, 0.1);
}
.bot-emergency-fold summary {
    cursor: pointer;
    color: var(--text-dim);
    font-size: 11px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    font-weight: 600;
}
.bot-emergency-fold[open] summary { margin-bottom: 10px; }
.bot-emergency-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

/* ── Global kill banner ─────────────────────────────────────────── */
.bot-kill-banner {
    margin: 0 0 20px 0;
    padding: 16px 18px;
    background: rgba(239, 68, 68, 0.15);
    border: 2px solid rgba(239, 68, 68, 0.6);
    border-radius: 8px;
    box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.08);
}
.bot-kill-title {
    font-weight: 800;
    font-size: 14px;
    letter-spacing: 0.06em;
    color: #fca5a5;
    margin-bottom: 8px;
}
.bot-kill-body {
    font-size: 12px;
    color: var(--text-dim);
    line-height: 1.5;
    margin-bottom: 12px;
}
.bot-kill-actions {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
}
.bot-emergency-cancel,
.bot-emergency-sellall {
    background: #ef4444;
    color: #fff;
    border: none;
    padding: 8px 16px;
    border-radius: 6px;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
}
.bot-emergency-sellall { background: #dc2626; }
.bot-emergency-cancel:hover,
.bot-emergency-sellall:hover { background: #b91c1c; }
.bot-emergency-cancel:disabled,
.bot-emergency-sellall:disabled { opacity: 0.5; cursor: not-allowed; }
.bot-kill-warning {
    margin-top: 10px;
    font-size: 11px;
    color: #fca5a5;
    line-height: 1.4;
    font-style: italic;
}
.bot-emergency-kalshi {
    color: #fca5a5;
    text-decoration: underline;
    font-size: 12px;
    font-weight: 600;
}
.bot-emergency-kalshi:hover { color: #fff; }

/* ── Apply recommended defaults block ──────────────────────────── */
.bot-settings-recos {
    margin-top: 20px;
    padding: 14px 16px;
    background: rgba(34, 197, 94, 0.06);
    border: 1px solid rgba(34, 197, 94, 0.25);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.bot-reset-recos {
    align-self: flex-start;
    background: rgba(34, 197, 94, 0.15);
    color: #22C55E;
    border: 1px solid rgba(34, 197, 94, 0.4);
    padding: 7px 14px;
    border-radius: 6px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.bot-reset-recos:hover {
    background: rgba(34, 197, 94, 0.25);
}
.bot-settings-recos small {
    color: var(--text-dim);
    font-size: 11px;
    line-height: 1.5;
}

/* ── Recent fires strip (Bets tab, last 5 min) ─────────────────── */
.bot-recent-section {
    margin: 16px 0 20px;
    padding: 12px 14px;
    background: rgba(56, 189, 248, 0.05);
    border: 1px solid rgba(56, 189, 248, 0.2);
    border-radius: 8px;
}
.bot-recent-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent-action);
    margin-bottom: 8px;
}
.bot-recent-hint {
    font-size: 10px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: var(--text-dim);
}
.bot-recent-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.bot-recent-row {
    display: flex;
    flex-direction: column;
    font-size: 12px;
    border-bottom: 1px solid rgba(148, 163, 184, 0.08);
}
.bot-recent-row:last-child { border-bottom: none; }
.bot-recent-row.is-open {
    background: rgba(56, 189, 248, 0.04);
}
.bot-recent-row.is-dead {
    opacity: 0.55;
    background: rgba(248, 113, 113, 0.04);
}
.bot-recent-row.is-dead .bot-recent-label {
    text-decoration: line-through;
}
.bot-dead-badge {
    background: rgba(248, 113, 113, 0.18);
    color: #F87171;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.08em;
    padding: 2px 6px;
    border-radius: 3px;
}
.bot-recent-row-head-wrap {
    display: flex;
    align-items: stretch;
}
.bot-recent-row-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex: 1;
    min-width: 0;
    appearance: none;
    background: transparent;
    border: none;
    color: inherit;
    font-family: inherit;
    text-align: left;
    padding: 8px 4px;
    cursor: pointer;
    gap: 8px;
    transition: background 100ms;
}
.bot-recent-row-head:hover {
    background: rgba(148, 163, 184, 0.06);
}
.bot-recent-jump {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    margin-left: 4px;
    color: var(--text-dim);
    text-decoration: none;
    font-size: 14px;
    border-radius: 4px;
    transition: background 120ms, color 120ms;
}
.bot-recent-jump:hover {
    background: rgba(56, 189, 248, 0.15);
    color: var(--accent-action, #38BDF8);
}
.bot-recent-chevron {
    color: var(--text-dim);
    font-size: 10px;
    width: 12px;
    flex-shrink: 0;
}
.bot-recent-label {
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    min-width: 0;
}
.bot-recent-meta {
    display: flex;
    gap: 10px;
    align-items: center;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}
.bot-recent-detail {
    padding: 10px 16px 14px 28px;
    border-top: 1px dashed rgba(148, 163, 184, 0.15);
    background: rgba(15, 23, 42, 0.4);
}
.bot-recent-detail[hidden] { display: none; }

/* Baseball-day section header — collapsible group of bets from
   the same slate. Today defaults open; older days default closed
   so the user can scrub by day without scrolling through
   hundreds of rows. */
.bot-day-section {
    border-bottom: 1px solid rgba(148, 163, 184, 0.1);
}
.bot-day-section:last-child {
    border-bottom: none;
}
.bot-day-head {
    appearance: none;
    background: rgba(15, 23, 42, 0.55);
    border: none;
    color: var(--text);
    font-family: inherit;
    width: 100%;
    text-align: left;
    padding: 10px 14px;
    cursor: pointer;
    display: grid;
    grid-template-columns: 12px auto auto 1fr;
    gap: 10px;
    align-items: baseline;
    border-top: 1px solid rgba(148, 163, 184, 0.12);
    transition: background 100ms;
}
.bot-day-head:hover {
    background: rgba(56, 189, 248, 0.06);
}
.bot-day-chevron {
    color: var(--text-dim);
    font-size: 10px;
}
.bot-day-label {
    font-weight: 700;
    font-size: 13px;
    letter-spacing: 0.02em;
}
.bot-day-count {
    color: var(--text-dim);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}
.bot-day-summary {
    color: var(--text-dim);
    font-size: 11px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.bot-day-rows {
    padding: 0 6px;
}
.bot-day-rows[hidden] {
    display: none;
}

/* Per-game subsection inside a day. Visually subordinate to the
   day header — same grid but smaller, dimmer, indented body. */
.bot-game-section {
    border-top: 1px solid rgba(148, 163, 184, 0.08);
}
.bot-game-section:first-child {
    border-top: none;
}
.bot-game-head-wrap {
    display: flex;
    align-items: center;
    gap: 6px;
    padding-right: 10px;
    background: rgba(15, 23, 42, 0.35);
}
.bot-game-head {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text);
    font-family: inherit;
    flex: 1;
    text-align: left;
    padding: 6px 14px 6px 24px;
    cursor: pointer;
    display: grid;
    grid-template-columns: 10px auto auto 1fr;
    gap: 8px;
    align-items: baseline;
    transition: background 100ms;
}
.bot-game-head:hover {
    background: rgba(56, 189, 248, 0.05);
}
.bot-game-chevron {
    color: var(--text-dim);
    font-size: 9px;
}
.bot-game-label {
    font-weight: 600;
    font-size: 11.5px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text);
}
.bot-game-count {
    color: var(--text-dim);
    font-size: 10.5px;
    font-variant-numeric: tabular-nums;
}
.bot-game-summary {
    color: var(--text-dim);
    font-size: 10.5px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.bot-game-jump {
    color: var(--accent-action, #38BDF8);
    text-decoration: none;
    font-size: 12px;
    padding: 2px 6px;
    border-radius: 4px;
}
.bot-game-jump:hover {
    background: rgba(56, 189, 248, 0.12);
}
.bot-game-rows {
    padding: 2px 6px 6px 18px;
}
.bot-game-rows[hidden] {
    display: none;
}

/* Inline progress strip on each open bet row. Mimics the live
   progress sportsbooks show on pending wagers: 'K: 3 / 5 — 2 more
   to win' plus a thin bar that fills as the player accumulates
   the stat. YES bets fill green (toward win); NO bets fill amber
   (toward loss). */
.bot-progress {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 4px 16px 10px 28px;
    border-top: 1px dashed rgba(148, 163, 184, 0.1);
}
.bot-recent-row.is-open .bot-progress {
    border-bottom: 1px dashed rgba(148, 163, 184, 0.1);
}
.bot-progress-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 11px;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
}
.bot-progress-stat {
    letter-spacing: 0.04em;
}
.bot-progress-stat strong {
    color: var(--text);
    font-weight: 700;
}
.bot-progress-status {
    font-weight: 600;
    letter-spacing: 0.02em;
}
.bot-progress-track {
    position: relative;
    height: 4px;
    background: rgba(148, 163, 184, 0.18);
    border-radius: 999px;
    overflow: hidden;
}
.bot-progress-fill {
    position: absolute;
    top: 0; left: 0; bottom: 0;
    border-radius: 999px;
    transition: width 300ms;
}
.bot-progress-fill-yes {
    background: linear-gradient(90deg, #22C55E, #38BDF8);
}
.bot-progress-fill-no {
    background: linear-gradient(90deg, #F59E0B, #f87171);
}
.bot-recent-detail a {
    color: var(--accent-action, #38BDF8);
    text-decoration: none;
}
.bot-recent-detail a:hover {
    text-decoration: underline;
}
.bot-recent-meta .bet-side-yes { color: #22C55E; font-weight: 600; }
.bot-recent-meta .bet-side-no  { color: #f59e0b; font-weight: 600; }
.bot-recent-ts {
    font-size: 10px;
    color: var(--text-dim);
}

.bot-tab-pane {
    display: none;
    padding: 20px 24px 40px;
    overflow-y: auto;
}
.bot-tab-pane.active { display: block; }

.bot-section { margin-bottom: 28px; }
.bot-section h3 {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-dim);
    margin: 0 0 10px;
}

.bot-empty {
    color: var(--text-dim);
    font-size: 13px;
    line-height: 1.6;
    padding: 40px 0;
    text-align: center;
}
.bot-empty-sub { color: var(--text-faint); font-size: 12px; margin-top: 6px; }

.bot-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}
.bot-table th {
    text-align: left;
    font-weight: 600;
    color: var(--text-dim);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    padding: 6px 8px 6px 0;
    border-bottom: 1px solid var(--border);
}
.bot-table td {
    padding: 8px 8px 8px 0;
    border-bottom: 1px solid rgba(148, 163, 184, 0.08);
    color: var(--text);
}
.bot-ticker {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    /* Monospace already reads ~1px narrower than the surrounding
       proportional 12px cell text, so 11px keeps it as a secondary
       glyph without looking shrunken. */
    font-size: 11px;
    color: var(--text-dim);
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.bot-pl-pos { color: var(--accent-win); font-weight: 600; }
.bot-pl-neg { color: var(--accent-live); font-weight: 600; }

/* Settled-bet badges on the Practice tab. Show WON/LOST inline
   with the row meta so a glance distinguishes graded results
   from open mark-to-market estimates. */
.bot-result-badge {
    display: inline-block;
    font-size: 10px;
    font-weight: 700;
    padding: 1px 6px;
    border-radius: 4px;
    letter-spacing: 0.5px;
    margin-right: 4px;
}
.bot-result-won  { background: var(--accent-win); color: #07120a; }
.bot-result-lost { background: var(--accent-live); color: #1a0707; }

/* Source pill — tags each active bet as bot- or user-placed.
   10px so the badge sits visually one step below the 12px cell
   text it accompanies, not two — 9px next to 12 felt like an
   afterthought. */
.bet-src {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    line-height: 1.4;
    text-align: center;
    min-width: 30px;
}
.bet-src-bot {
    background: rgba(245, 158, 11, 0.16);
    color: #f59e0b;
    border: 1px solid rgba(245, 158, 11, 0.42);
}
.bet-src-user {
    background: rgba(34, 197, 94, 0.16);
    color: var(--accent-win);
    border: 1px solid rgba(34, 197, 94, 0.42);
}
.bot-section-sub {
    font-size: 10px;
    font-weight: 550;
    letter-spacing: 0.04em;
    text-transform: none;
    color: var(--text-faint);
    margin-left: 8px;
}

/* ── Active Bets bottom strip ──────────────────────────────────── */
/* Slim horizontal strip pinned above the bottom nav. Shows one chip
   per active position with a DraftKings-style progress fill on
   player props. Right edge stops at 200px so it doesn't crash into
   the 🎯 Active Bets launcher at bottom-right. */
.active-bets-strip {
    position: fixed;
    left: 16px;
    bottom: 84px;
    z-index: 5000;
    display: none;
    align-items: center;
    gap: 8px;
    /* No wrapper box around the pill + chips. User direction
       (2026-06-04): 'I dont want this box there. Just leave the
       practice button.' The toggle pill has its own border/bg;
       any chips that render keep their own pill styling too. */
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
.active-bets-strip.is-visible { display: flex; }

.abs-title {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.14em;
    color: var(--text-dim);
    text-transform: uppercase;
    white-space: nowrap;
    padding-right: 10px;
    border-right: 1px solid rgba(148, 163, 184, 0.18);
}

/* Bottom-left open/close pill on the strip. Always visible — when
   the chips are hidden it's the only thing that remains, becoming
   the affordance to bring them back. */
.abs-toggle {
    appearance: none;
    background: rgba(15, 23, 42, 0.7);
    border: 1px solid rgba(148, 163, 184, 0.25);
    color: var(--text-dim);
    font-family: inherit;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    padding: 4px 10px 4px 8px;
    border-radius: 999px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
    transition: background 120ms, border-color 120ms, color 120ms;
    flex-shrink: 0;
}
.abs-toggle:hover {
    background: rgba(30, 41, 59, 0.95);
    border-color: rgba(148, 163, 184, 0.45);
    color: var(--text);
}
.abs-toggle-icon {
    font-size: 9px;
    color: var(--accent-action);
    letter-spacing: 0;
}

/* When collapsed: strip shrinks to fit only the toggle pill AND
   slides to bottom-center so the pill doesn't cover the leftmost
   column of whatever view the user is on (Leaders cards, MVP rows,
   Board tiles). The launcher stays bottom-right; together they
   form a quieter bottom row that lets the content underneath
   read through. */
.active-bets-strip.is-collapsed {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    padding: 0;
    background: transparent;
}

.abs-chips {
    display: flex;
    align-items: center;
    gap: 8px;
    overflow-x: auto;
    overflow-y: hidden;
    flex: 1;
    /* Visible-but-thin custom scrollbar. */
    scrollbar-width: thin;
    scrollbar-color: rgba(148, 163, 184, 0.3) transparent;
}
.abs-chips::-webkit-scrollbar { height: 6px; }
.abs-chips::-webkit-scrollbar-thumb {
    background: rgba(148, 163, 184, 0.25);
    border-radius: 3px;
}

.abs-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    background: rgba(30, 41, 59, 0.6);
    border: 1px solid rgba(148, 163, 184, 0.15);
    border-radius: 8px;
    text-decoration: none;
    color: var(--text);
    font-size: 10px;
    font-weight: 550;
    line-height: 1.2;
    flex-shrink: 0;
    cursor: pointer;
    transition: background 120ms, border-color 120ms, transform 120ms;
    white-space: nowrap;
}
.abs-chip:hover {
    background: rgba(51, 65, 85, 0.75);
    border-color: rgba(148, 163, 184, 0.35);
    transform: translateY(-1px);
}
.abs-chip.is-hit {
    background: rgba(34, 197, 94, 0.12);
    border-color: rgba(34, 197, 94, 0.45);
}

.abs-src {
    display: inline-block;
    padding: 1px 5px;
    border-radius: 999px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.06em;
    min-width: 22px;
    text-align: center;
}
.abs-src-bot {
    background: rgba(245, 158, 11, 0.18);
    color: #f59e0b;
}
.abs-src-user {
    background: rgba(34, 197, 94, 0.18);
    color: var(--accent-win);
}

.abs-label {
    font-weight: 600;
    color: var(--text);
}

/* DraftKings-style progress bar — gradient fill that resolves green
   when the leg hits its target. */
.abs-progress {
    display: inline-block;
    width: 34px;
    height: 6px;
    background: rgba(15, 23, 42, 0.7);
    border-radius: 999px;
    overflow: hidden;
    border: 1px solid rgba(148, 163, 184, 0.18);
    position: relative;
}
.abs-progress-bar {
    display: block;
    height: 100%;
    background: linear-gradient(90deg, var(--accent-action) 0%, #f59e0b 100%);
    border-radius: 999px;
    transition: width 240ms ease-out;
}
.abs-progress-bar.hit {
    background: linear-gradient(90deg, var(--accent-win) 0%, #4ade80 100%);
}
.abs-progress-text {
    font-size: 10px;
    color: var(--text-dim);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    letter-spacing: 0;
}
.abs-progress-pending { color: var(--text-faint); }

.abs-price {
    font-size: 10px;
    color: var(--text-dim);
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    letter-spacing: 0;
}
.abs-pl {
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.abs-pl-pos { color: var(--accent-win); }
.abs-pl-neg { color: var(--accent-live); }
.abs-arrow {
    color: var(--text-faint);
    font-size: 12px;
    margin-left: 2px;
    transition: color 120ms, transform 120ms;
}
.abs-chip:hover .abs-arrow {
    color: var(--accent-action);
    transform: translateX(2px);
}

.abs-close {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text-faint);
    font-size: 17px;
    line-height: 1;
    padding: 4px 8px;
    cursor: pointer;
    border-radius: 6px;
    transition: color 120ms, background 120ms;
}
.abs-close:hover {
    color: var(--text);
    background: rgba(148, 163, 184, 0.12);
}

/* Strip "history" badge on recent-only chips (Kalshi reports no
   active position; we're surfacing the last few from the log). */
.abs-chip-recent {
    background: rgba(30, 41, 59, 0.45);
    border-style: dashed;
}
.abs-history-tag {
    display: inline-block;
    padding: 1px 5px;
    border-radius: 4px;
    background: rgba(148, 163, 184, 0.18);
    color: var(--text-faint);
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.12em;
}

/* Compact for narrow viewports — chip footprint shrinks but stays
   readable. The strip is horizontally scrollable so even 10 bets
   on a phone scroll cleanly. */
@media (max-width: 900px) {
    .active-bets-strip { right: 16px; bottom: 76px; }
    .abs-title { display: none; }
    .abs-progress { width: 44px; }
    .abs-label { font-size: 10.5px; }
}

/* Drawer status banner — surfaces Kalshi connection + raw counts so
   "I placed bets, why's it empty" is at least diagnosable. */
.bot-status-banner {
    margin-bottom: 16px;
    padding: 8px 12px;
    background: rgba(15, 23, 42, 0.6);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 11px;
    color: var(--text-dim);
}
.bot-status-row {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.bot-status-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 999px;
}
.bot-status-ok { background: var(--accent-win); box-shadow: 0 0 6px rgba(34, 197, 94, 0.6); }

/* State pills in the Recently placed table. We never assert CLOSED —
   we only know HELD (in positions) / RESTING (in open orders) /
   PLACED (we tried, can't see it on Kalshi right now).
   10px so they sit even with the source pill alongside them. */
.bet-state {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    line-height: 1.4;
}
.bet-state-held {
    background: rgba(34, 197, 94, 0.16);
    color: var(--accent-win);
}
.bet-state-resting {
    background: rgba(56, 189, 248, 0.16);
    color: var(--accent-action);
}
.bet-state-placed {
    background: rgba(148, 163, 184, 0.14);
    color: var(--text-dim);
}

/* Result pills for settled bets — shown in the History tab in place
   of the state pill once Kalshi has resolved the market. */
.bet-result {
    display: inline-block;
    padding: 2px 7px;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.04em;
    line-height: 1.4;
    font-variant-numeric: tabular-nums;
}
.bet-result-won {
    background: rgba(34, 197, 94, 0.18);
    color: var(--accent-win);
    border: 1px solid rgba(34, 197, 94, 0.42);
}
.bet-result-lost {
    background: rgba(239, 68, 68, 0.16);
    color: var(--accent-live);
    border: 1px solid rgba(239, 68, 68, 0.4);
}

/* Diagnostic strip at top of History — shows how many Kalshi records
   landed and how many actually mapped to our local fires. When fires
   show as PLACED but the user knows they won, this line tells us why
   (ticker mismatch, no settlement, pagination, etc.). */
.bot-history-diag {
    font-size: 10px;
    color: var(--text-dim);
    background: rgba(15, 23, 42, 0.5);
    border: 1px dashed var(--border);
    border-radius: 4px;
    padding: 6px 10px;
    margin-bottom: 14px;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    line-height: 1.6;
}

/* History tab — fires grouped by calendar day, each day getting
   its own card with a header showing the date, total bet count,
   and that day's W-L + net P/L (when there are settled bets). */
.bot-history-day {
    margin-bottom: 18px;
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    background: rgba(15, 23, 42, 0.45);
}
.bot-history-day-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    background: rgba(15, 23, 42, 0.7);
    border-bottom: 1px solid var(--border);
}
.bot-history-day-title {
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.bot-history-day-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.005em;
}
.bot-history-day-meta {
    font-size: 10px;
    font-weight: 500;
    color: var(--text-dim);
    letter-spacing: 0.04em;
}
.bot-history-day-summary {
    display: flex;
    align-items: center;
    gap: 10px;
}
.bot-history-day-record {
    font-size: 12px;
    font-weight: 600;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
}
.bot-history-day-pnl {
    font-size: 14px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    padding: 2px 8px;
    border-radius: 4px;
    background: rgba(15, 23, 42, 0.6);
}
.bot-history-day .bot-table { margin: 0; }

/* Day-by-day pagination controls at the bottom of the History pane.
   'Show 7 more days' / 'Show all' lets the user navigate further
   back in time without dumping 100+ day-sections at once. */
.bot-history-load-more {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 18px 12px 24px;
    text-align: center;
}
.bot-history-load-more-hint {
    font-size: 12px;
    color: var(--text-dim);
    letter-spacing: 0.02em;
}
.bot-history-load-more-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: center;
}
.bot-history-load-btn {
    appearance: none;
    background: rgba(56, 189, 248, 0.12);
    border: 1px solid rgba(56, 189, 248, 0.3);
    color: var(--accent-action, #38BDF8);
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 8px 16px;
    border-radius: 999px;
    cursor: pointer;
    transition: background 120ms, border-color 120ms;
}
.bot-history-load-btn:hover {
    background: rgba(56, 189, 248, 0.2);
    border-color: rgba(56, 189, 248, 0.5);
}
.bot-history-load-btn-alt {
    background: transparent;
    color: var(--text-dim);
    border-color: rgba(148, 163, 184, 0.25);
}
.bot-history-load-btn-alt:hover {
    background: rgba(148, 163, 184, 0.1);
    color: var(--text);
    border-color: rgba(148, 163, 184, 0.4);
}
.bot-history-day .bot-table th,
.bot-history-day .bot-table td {
    padding-left: 14px;
}

/* Performance pane — the page you open every morning.
   Headline grid of 6 stat cards, sparkline of the last 14 days,
   then breakdowns by stat type / edge band / source. */
.bot-perf-headline {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
    gap: 8px;
    margin-bottom: 20px;
}
.bot-perf-stat {
    background: rgba(15, 23, 42, 0.6);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.bot-perf-stat-label {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    color: var(--text-dim);
}
.bot-perf-stat-value {
    font-size: 18px;
    font-weight: 600;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
}
.bot-perf-stat-win {
    border-color: rgba(34, 197, 94, 0.35);
    background: linear-gradient(180deg, rgba(34, 197, 94, 0.08) 0%, rgba(15, 23, 42, 0.6) 60%);
}
.bot-perf-stat-win .bot-perf-stat-value { color: var(--accent-win); }
.bot-perf-stat-lose {
    border-color: rgba(239, 68, 68, 0.30);
    background: linear-gradient(180deg, rgba(239, 68, 68, 0.06) 0%, rgba(15, 23, 42, 0.6) 60%);
}
.bot-perf-stat-lose .bot-perf-stat-value { color: var(--accent-live); }

/* Inline P/L bar (sample column in the breakdown tables). */
.bot-perf-bar {
    width: 100%;
    height: 6px;
    background: rgba(148, 163, 184, 0.10);
    border-radius: 999px;
    overflow: hidden;
}
.bot-perf-bar span {
    display: block;
    height: 100%;
    border-radius: 999px;
    transition: width 240ms ease;
}

/* 14-day P/L sparkline. */
.bot-perf-spark {
    width: 100%;
    height: auto;
    display: block;
    margin: 8px 0 4px;
}

/* EOD review modal — center overlay, table layout. */
.bot-eod-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(6px);
    z-index: 11000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px;
}
.bot-eod-content {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 24px 28px;
    max-width: 720px;
    width: 100%;
    max-height: 80vh;
    overflow-y: auto;
    color: var(--text);
}
.bot-eod-content header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border);
}
.bot-eod-content header h3 {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
}
.bot-eod-close {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text-dim);
    font-size: 20px;
    cursor: pointer;
    line-height: 1;
}
.bot-eod-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 12px;
    padding: 12px;
    background: rgba(15, 23, 42, 0.6);
    border-radius: 6px;
    margin-bottom: 16px;
    font-size: 12px;
    color: var(--text-dim);
}
.bot-eod-summary strong {
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
}
.bot-eod-content h4 {
    margin: 16px 0 8px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    color: var(--text-dim);
}
.bot-eod-review {
    background: rgba(56, 189, 248, 0.14);
    border: 1px solid rgba(56, 189, 248, 0.4);
    color: var(--accent-action);
    padding: 4px 10px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
    font-family: inherit;
}
.bot-eod-review:hover {
    background: rgba(56, 189, 248, 0.22);
}

/* Decisions pane — factor chips show each signal's adjustment
   to the probability estimate. Green = positive (push us toward
   bet), red = negative (push toward skip), gray = neutral. */
.bot-factor-row {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    align-items: center;
}
.bot-factor-chip {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 3px;
    background: rgba(148, 163, 184, 0.14);
    color: var(--text-dim);
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 0.02em;
    line-height: 1.4;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
}
.bot-factor-chip.is-pos {
    background: rgba(34, 197, 94, 0.16);
    color: var(--accent-win);
}
.bot-factor-chip.is-neg {
    background: rgba(239, 68, 68, 0.16);
    color: var(--accent-live);
}
.bot-decision-reason {
    font-size: 9px;
    color: var(--text-faint);
    font-style: italic;
    margin-left: 4px;
}

/* Action pills on the Kalshi fills table — BUY in action-blue,
   SELL in accent-win green so the pair reads as 'entered/exited.'
   10px matches the rest of the badge family. */
.bot-fill-action {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 4px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    line-height: 1.4;
}
.bot-fill-buy {
    background: rgba(56, 189, 248, 0.18);
    color: var(--accent-action);
}
.bot-fill-sell {
    background: rgba(34, 197, 94, 0.18);
    color: var(--accent-win);
}
.bot-time-ago {
    /* Match the 11px other secondary table cells use — was 10
       which clashed with the bumped 10px state pill alongside. */
    font-size: 11px;
    color: var(--text-faint);
    font-variant-numeric: tabular-nums;
}
.bot-table-history td { padding: 6px 8px 6px 0; }
.bot-exit-btn, .bot-cancel-btn {
    appearance: none;
    background: rgba(34, 197, 94, 0.14);
    border: 1px solid rgba(34, 197, 94, 0.35);
    color: var(--accent-win);
    padding: 4px 10px;
    border-radius: 6px;
    font: inherit;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
}
.bot-exit-btn:hover { background: rgba(34, 197, 94, 0.22); }
.bot-cancel-btn {
    background: rgba(239, 68, 68, 0.10);
    border-color: rgba(239, 68, 68, 0.30);
    color: var(--accent-live);
}
.bot-cancel-btn:hover { background: rgba(239, 68, 68, 0.18); }
.bot-exit-btn:disabled, .bot-cancel-btn:disabled { opacity: 0.55; cursor: wait; }

/* Bot pane: toggle + settings + log */
.bot-toggle-row {
    display: flex;
    align-items: center;
    gap: 12px;
    justify-content: space-between;
    padding: 14px 0;
    border-bottom: 1px solid var(--border);
    margin-bottom: 14px;
}
.bot-toggle {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    cursor: pointer;
}
.bot-toggle input { display: none; }
.bot-toggle-slider {
    position: relative;
    width: 44px;
    height: 24px;
    background: rgba(148, 163, 184, 0.25);
    border-radius: 999px;
    transition: background 120ms;
}
.bot-toggle-slider::before {
    content: "";
    position: absolute;
    top: 2px; left: 2px;
    width: 20px; height: 20px;
    background: #fff;
    border-radius: 50%;
    transition: transform 120ms;
}
.bot-toggle input:checked + .bot-toggle-slider {
    background: var(--accent-win);
}
.bot-toggle input:checked + .bot-toggle-slider::before {
    transform: translateX(20px);
}
.bot-toggle-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
}

/* Mode banner — appears under the bot ON/OFF row to surface a
   non-default operating mode that would otherwise hide in
   settings. Currently used for moneyline-only test mode. */
.bot-mode-banner {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 12px;
    margin: 8px 0;
    border-radius: 6px;
    font-size: 12px;
}
.bot-mode-banner strong {
    font-size: 12px;
    letter-spacing: 0.04em;
}
.bot-mode-banner span {
    font-size: 11px;
    color: var(--text-dim);
}
.bot-mode-banner-ml {
    background: rgba(56, 189, 248, 0.08);
    border: 1px solid rgba(56, 189, 248, 0.28);
    color: #38BDF8;
}
.bot-mode-banner-ml span { color: rgba(186, 230, 253, 0.85); }

/* Practice / Live mode segmented control. Replaces the old single
   toggle (which was ambiguous — 'off + LIVE' could be read two
   ways). Both modes always visible; the active one is filled,
   the inactive one is dim. Click the inactive one to switch. */
.bot-mode-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    padding: 10px 12px;
    margin: 10px 0;
    border-radius: 8px;
    border: 1px solid transparent;
    background: rgba(15, 23, 42, 0.4);
}
.bot-mode-row.is-practice {
    background: rgba(34, 197, 94, 0.08);
    border-color: rgba(34, 197, 94, 0.3);
}
.bot-mode-row.is-real {
    background: rgba(245, 158, 11, 0.08);
    border-color: rgba(245, 158, 11, 0.3);
}
.bot-mode-label-row {
    display: flex;
    align-items: center;
    gap: 10px;
}
.bot-mode-prefix {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-dim);
}
.bot-mode-segmented {
    display: inline-flex;
    background: rgba(15, 23, 42, 0.7);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 3px;
    gap: 2px;
}
.bot-mode-seg {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text-dim);
    font-family: inherit;
    padding: 6px 14px;
    border-radius: 999px;
    cursor: pointer;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
    line-height: 1.1;
    transition: background 120ms, color 120ms;
}
.bot-mode-seg:hover {
    color: var(--text);
}
.bot-mode-seg-title {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
}
.bot-mode-seg-sub {
    font-size: 9px;
    letter-spacing: 0.02em;
    opacity: 0.85;
}
.bot-mode-seg.is-active {
    color: #07120a;
    background: var(--accent-win);
    box-shadow: 0 0 0 1px var(--accent-win), 0 2px 8px rgba(34, 197, 94, 0.35);
}
.bot-mode-row.is-real .bot-mode-seg.is-active {
    color: #1a0f00;
    background: #F59E0B;
    box-shadow: 0 0 0 1px #F59E0B, 0 2px 8px rgba(245, 158, 11, 0.35);
}
.bot-mode-bankroll {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-dim);
}
.bot-mode-bankroll-label {
    letter-spacing: 0.04em;
}
.bot-mode-bankroll input {
    width: 80px;
    background: rgba(15, 23, 42, 0.7);
    border: 1px solid var(--border);
    color: var(--text);
    border-radius: 6px;
    padding: 4px 8px;
    font-family: inherit;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}
.bot-kill {
    appearance: none;
    background: var(--accent-live);
    color: white;
    border: none;
    padding: 7px 14px;
    border-radius: 6px;
    font: inherit;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    cursor: pointer;
    box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.5);
    animation: bot-kill-pulse 1.8s ease-in-out infinite;
}
@keyframes bot-kill-pulse {
    0%,100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.5); }
    50%     { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
}
.bot-kill:hover { background: #DC2626; }

.bot-status-line {
    font-size: 12px;
    color: var(--text-dim);
    line-height: 1.6;
    margin: 0 0 10px;
}
.bot-status-line strong { color: var(--text); }

.bot-settings summary {
    cursor: pointer;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    color: var(--text-dim);
    padding: 8px 0;
    user-select: none;
}
.bot-settings summary::marker { color: var(--accent-action); }
.bot-settings-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    padding: 12px 0;
}
.bot-settings-grid label {
    display: flex;
    flex-direction: column;
    gap: 5px;
    font-size: 11px;
}
.bot-settings-grid label > span:first-child {
    font-weight: 600;
    color: var(--text-dim);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.bot-settings-grid input[type="number"] {
    background: rgba(15, 23, 42, 0.7);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 7px 10px;
    color: var(--text);
    font: inherit;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}
.bot-settings-grid input[type="number"]:focus {
    outline: none;
    border-color: var(--accent-action);
}
.bot-settings-grid small {
    color: var(--text-faint);
    font-size: 10px;
    line-height: 1.4;
}
.bot-checkbox-label {
    flex-direction: row !important;
    align-items: center;
    grid-column: 1 / -1;
    gap: 10px !important;
}
.bot-checkbox-label input[type="checkbox"] {
    width: 18px; height: 18px;
}
.bot-settings-note {
    color: var(--text-faint);
    font-size: 11px;
    line-height: 1.6;
    margin-top: 8px;
    padding: 10px 12px;
    background: rgba(56, 189, 248, 0.05);
    border-left: 3px solid var(--accent-action);
    border-radius: 0 6px 6px 0;
}

.bot-log-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
}
.bot-log-actions {
    display: flex;
    gap: 12px;
    align-items: center;
}
/* Activity row buttons now look like ACTUAL buttons rather than
   links — same chip family the EOD review button uses, with
   matching click feedback. The user couldn't tell they were
   clickable before. */
.bot-clear-log,
.bot-export-fires,
.bot-copy-all {
    background: rgba(56, 189, 248, 0.10);
    border: 1px solid rgba(56, 189, 248, 0.35);
    color: var(--accent-action);
    font: inherit;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 4px 10px;
    border-radius: 4px;
    cursor: pointer;
    transition: background 120ms, border-color 120ms;
}
.bot-clear-log:hover,
.bot-export-fires:hover,
.bot-copy-all:hover {
    background: rgba(56, 189, 248, 0.20);
    border-color: rgba(56, 189, 248, 0.55);
}
.bot-clear-log:active,
.bot-export-fires:active,
.bot-copy-all:active {
    transform: translateY(1px);
}
.bot-clear-log {
    background: rgba(239, 68, 68, 0.10);
    border-color: rgba(239, 68, 68, 0.35);
    color: var(--accent-live);
}
.bot-clear-log:hover {
    background: rgba(239, 68, 68, 0.20);
    border-color: rgba(239, 68, 68, 0.55);
}
.bot-copy-all {
    background: rgba(34, 197, 94, 0.10);
    border-color: rgba(34, 197, 94, 0.35);
    color: var(--accent-win);
}
.bot-copy-all:hover {
    background: rgba(34, 197, 94, 0.20);
    border-color: rgba(34, 197, 94, 0.55);
}

/* Inline flash state on bot buttons — used as REDUNDANT
   confirmation feedback so the user sees something happen even if
   the toast layer fails for any reason. Briefly overrides the
   button's base color with a bright accent ring + bg. */
.btn-flash-ok {
    background: rgba(34, 197, 94, 0.32) !important;
    border-color: rgba(34, 197, 94, 0.85) !important;
    color: #fff !important;
    box-shadow: 0 0 0 1px rgba(34, 197, 94, 0.4),
                0 0 16px rgba(34, 197, 94, 0.4);
    transition: background 120ms, border-color 120ms, box-shadow 120ms;
}
.btn-flash-err {
    background: rgba(239, 68, 68, 0.32) !important;
    border-color: rgba(239, 68, 68, 0.85) !important;
    color: #fff !important;
    box-shadow: 0 0 0 1px rgba(239, 68, 68, 0.4),
                0 0 16px rgba(239, 68, 68, 0.4);
    transition: background 120ms, border-color 120ms, box-shadow 120ms;
}

/* ── EDGES (rendered inside the Markets dashboard) ──────────────
   Ranked list of mispriced player props. Each row is a clickable
   link into the game's Markets tab. Tier-colored magnitude badge
   on the right (strong / moderate / marginal). */

/* Sub-tab toggle in the Markets header — switches between
   'Game Lines' (the existing dashboard) and 'Edges' (this list).
   Same visual language as the Leaders mode toggle. */
.markets-sub-toggle {
    display: inline-flex;
    background: rgba(15, 23, 42, 0.7);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 2px;
    margin: 0 0 0 12px;
    align-self: flex-start;
}
.markets-sub-btn {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text-dim);
    font: inherit;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    padding: 5px 12px;
    border-radius: 999px;
    cursor: pointer;
    transition: background 120ms, color 120ms;
}
.markets-sub-btn:hover { color: var(--text); }
.markets-sub-btn.active {
    background: var(--accent-action);
    color: #0B1220;
}

.edges-list {
    list-style: none;
    margin: 0;
    padding: 0;
    counter-reset: edge;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.edge-row {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    transition: border-color 120ms, transform 120ms, background 120ms;
}
.edge-row:hover {
    border-color: rgba(56, 189, 248, 0.45);
    transform: translateX(2px);
}
.edge-row-strong {
    border-left: 3px solid var(--accent-win);
}
.edge-row-moderate {
    border-left: 3px solid #f59e0b;
}
.edge-row-marginal {
    border-left: 3px solid var(--text-dim);
    opacity: 0.85;
}

.edge-link {
    display: grid;
    grid-template-columns: 28px minmax(120px, 1.6fr) minmax(120px, 1.4fr) minmax(120px, 1fr) 72px;
    gap: 10px;
    align-items: center;
    padding: 8px 12px;
    text-decoration: none;
    color: inherit;
    font-size: 12px;
}

.edge-rank {
    color: var(--text-dim);
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: right;
}
.edge-row-strong .edge-rank { color: var(--accent-win); }

.edge-player-block {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}
.edge-player {
    color: var(--text);
    font-weight: 600;
    font-size: 13px;
    letter-spacing: -0.005em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.edge-matchup {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.04em;
}

.edge-prop {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    flex-wrap: wrap;
}
.edge-threshold {
    color: var(--text);
    font-weight: 700;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}
.edge-stat {
    color: var(--text-dim);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.10em;
    text-transform: uppercase;
}
.edge-side {
    padding: 1px 6px;
    border-radius: 3px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.10em;
    text-transform: uppercase;
}
.edge-side-over {
    background: rgba(34, 197, 94, 0.14);
    color: var(--accent-win);
}
.edge-side-under {
    background: rgba(245, 158, 11, 0.14);
    color: #f59e0b;
}

.edge-probs {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
}
.edge-prob-cell {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0;
}
.edge-prob-label {
    font-size: 8px;
    color: var(--text-dim);
    font-weight: 700;
    letter-spacing: 0.10em;
    text-transform: uppercase;
}
.edge-prob-val {
    font-size: 13px;
    color: var(--text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.edge-prob-dim {
    color: var(--text-dim);
    font-weight: 500;
}

.edge-magnitude {
    text-align: right;
    font-weight: 800;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
    padding: 3px 8px;
    border-radius: 4px;
}
.edge-mag-strong {
    background: rgba(34, 197, 94, 0.18);
    color: var(--accent-win);
}
.edge-mag-moderate {
    background: rgba(245, 158, 11, 0.16);
    color: #f59e0b;
}
.edge-mag-marginal {
    background: rgba(148, 163, 184, 0.14);
    color: var(--text-dim);
}

.edges-foot {
    font-size: 10px;
    color: var(--text-faint);
    line-height: 1.5;
    padding: 8px 0 0;
    max-width: 640px;
    border-top: 1px solid var(--border);
    margin-top: 4px;
}

/* Narrow viewports — collapse columns. */
@media (max-width: 700px) {
    .edge-link {
        grid-template-columns: 24px 1fr 60px;
        grid-template-rows: auto auto;
    }
    .edge-player-block { grid-row: 1; grid-column: 2; }
    .edge-rank { grid-row: 1; grid-column: 1; }
    .edge-magnitude { grid-row: 1; grid-column: 3; }
    .edge-prop  { grid-row: 2; grid-column: 1 / 4; }
    .edge-probs { grid-row: 2; grid-column: 3; }
}


/* Bot's own toast layer — a real popup, not a console fallback.
   Moved to TOP-CENTER (was bottom-80) so it can't be hidden
   behind the bottom nav, active-bets strip, or drawer footer.
   Scales in with a slight bounce so it actually catches the eye. */
.bot-toasts {
    position: fixed;
    top: 80px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 99999;       /* above EVERYTHING — drawer, modal, nav, nav-strip */
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: center;
    pointer-events: none;
}
.bot-toast {
    padding: 14px 22px;
    border-radius: 10px;
    background: rgba(11, 18, 32, 0.96);
    color: var(--text);
    border: 1px solid var(--border);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.01em;
    box-shadow:
        0 12px 32px rgba(0, 0, 0, 0.55),
        0 0 0 1px rgba(148, 163, 184, 0.06);
    backdrop-filter: blur(8px);
    opacity: 0;
    transform: translateY(16px) scale(0.96);
    transition: opacity 220ms ease, transform 240ms cubic-bezier(0.34, 1.56, 0.64, 1);
    max-width: 540px;
    pointer-events: auto;
    line-height: 1.4;
}
.bot-toast.bot-toast-show {
    opacity: 1;
    transform: translateY(0) scale(1);
}
.bot-toast-ok {
    border-color: rgba(34, 197, 94, 0.5);
    color: var(--accent-win);
    background: linear-gradient(180deg, rgba(34, 197, 94, 0.10) 0%, rgba(11, 18, 32, 0.96) 60%);
    box-shadow:
        0 12px 32px rgba(0, 0, 0, 0.55),
        0 0 0 1px rgba(34, 197, 94, 0.18),
        0 0 24px rgba(34, 197, 94, 0.12);
}
.bot-toast-err {
    border-color: rgba(239, 68, 68, 0.55);
    color: var(--accent-live);
    background: linear-gradient(180deg, rgba(239, 68, 68, 0.10) 0%, rgba(11, 18, 32, 0.96) 60%);
    box-shadow:
        0 12px 32px rgba(0, 0, 0, 0.55),
        0 0 0 1px rgba(239, 68, 68, 0.22),
        0 0 24px rgba(239, 68, 68, 0.14);
}
.bot-log {
    background: rgba(15, 23, 42, 0.5);
    border: 1px solid var(--border);
    border-radius: 8px;
    max-height: 280px;
    overflow-y: auto;
}
.bot-log-row {
    display: grid;
    grid-template-columns: 70px 1fr;
    gap: 10px;
    padding: 6px 12px;
    font-size: 11px;
    border-bottom: 1px solid rgba(148, 163, 184, 0.06);
}
.bot-log-row:last-child { border-bottom: none; }
.bot-log-time {
    color: var(--text-faint);
    font-variant-numeric: tabular-nums;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 10px;
}
.bot-log-msg {
    color: var(--text);
    line-height: 1.4;
    word-break: break-word;
}
.bot-log-buy  .bot-log-msg { color: var(--accent-win); }
.bot-log-sell .bot-log-msg { color: var(--accent-action); }
.bot-log-err  .bot-log-msg { color: var(--accent-live); }
.bot-log-halt .bot-log-msg { color: var(--accent-live); font-weight: 600; }


/* ── TRACK RECORD + HOW IT WORKS PAGES ─────────────────────────── */

.page-view {
    /* body has overflow:hidden so each view manages its own scroll.
       flex:1 fills the available column height; overflow-y:auto lets
       the page scroll when content exceeds the viewport. Without these,
       Track Record / How It Works / About were stuck at top with no
       way to reach the lower sections (2026-06-12). */
    flex: 1;
    overflow-y: auto;
    max-width: 1100px;
    margin: 0 auto;
    padding: 32px 24px 80px;
    /* Full block width so the scrollbar lives at the column's right
       edge regardless of the inner content size. */
    width: 100%;
    box-sizing: border-box;
}

.page-head {
    margin-bottom: 32px;
}
.page-head h1 {
    font-size: 32px;
    font-weight: 800;
    letter-spacing: 0.04em;
    margin: 0 0 8px;
    color: var(--text);
}
.page-head .page-sub {
    color: var(--text-dim);
    font-size: 14px;
    margin: 0;
    max-width: 720px;
}
.page-loading {
    color: var(--text-dim);
    font-size: 14px;
    padding: 24px;
}

/* Hero stats grid */
.tr-hero {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 14px;
    margin-bottom: 32px;
}
.tr-stat {
    padding: 18px 20px;
    background: rgba(15, 23, 42, 0.6);
    border: 1px solid var(--border);
    border-radius: 10px;
}
.tr-stat-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-dim);
    margin-bottom: 6px;
}
.tr-stat-val {
    font-size: 28px;
    font-weight: 800;
    color: var(--text);
    line-height: 1.15;
}
.tr-stat-sub {
    font-size: 11px;
    color: var(--text-dim);
    margin-top: 4px;
}
.tr-pos { color: var(--accent-win); }
.tr-neg { color: var(--accent-live); }

/* Tables */
.tr-section { margin-bottom: 32px; }
.tr-section h2,
.hiw-section h2 {
    font-size: 16px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--text);
    margin: 0 0 12px;
}
.tr-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    margin-bottom: 12px;
    background: rgba(15, 23, 42, 0.4);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
}
.tr-table th, .tr-table td {
    padding: 8px 12px;
    text-align: left;
    border-bottom: 1px solid rgba(148, 163, 184, 0.08);
}
.tr-table th {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
    background: rgba(15, 23, 42, 0.6);
}
.tr-table tr:last-child td { border-bottom: none; }
.tr-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Historical coverage table — 115 years would otherwise push the page
   ~3K px tall, so we cap the height and scroll the body. Sticky thead
   keeps the column labels visible while scrolling. The live-current-
   season row gets a subtle accent so it reads as "right now". */
.hc-scroll {
    max-height: 460px;
    overflow-y: auto;
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 14px;
}
.hc-scroll .hc-table { margin: 0; }
.hc-table thead th {
    position: sticky;
    top: 0;
    background: var(--surface-2, #0f172a);
    z-index: 1;
}
.hc-table tr.hc-live td {
    background: rgba(34, 197, 94, 0.08);
}
.hc-live-tag {
    display: inline-block;
    padding: 1px 6px;
    margin-left: 6px;
    border-radius: 4px;
    background: #22C55E;
    color: #0B1220;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    vertical-align: middle;
}

/* How-it-works sections */
.hiw-section {
    margin-bottom: 36px;
    padding: 20px 22px;
    background: rgba(15, 23, 42, 0.4);
    border: 1px solid var(--border);
    border-radius: 10px;
}
.hiw-section p {
    color: var(--text);
    font-size: 14px;
    line-height: 1.5;
    margin: 0 0 14px;
}
.hiw-takeaway {
    margin-top: 12px;
    padding: 10px 14px;
    background: rgba(56, 189, 248, 0.08);
    border-left: 3px solid var(--accent-action, #38BDF8);
    border-radius: 4px;
    font-size: 13px;
    color: var(--text);
}

/* Footer */
.tr-foot {
    margin-top: 32px;
    padding-top: 24px;
    border-top: 1px solid var(--border);
    color: var(--text-dim);
    font-size: 13px;
}
.tr-foot p {
    margin: 0 0 8px;
}
.tr-link {
    color: var(--accent-action, #38BDF8);
    text-decoration: none;
    border-bottom: 1px dotted currentColor;
}
.tr-link:hover { border-bottom-style: solid; }
.tr-empty {
    padding: 32px 24px;
    text-align: center;
    background: rgba(15, 23, 42, 0.4);
    border: 1px dashed var(--border);
    border-radius: 8px;
    color: var(--text-dim);
}

/* ── WATCH TAB ─────────────────────────────────────────────────────────
   The MLB.tv launcher. Cards mirror the Board's tile look but end in a
   Watch button instead of being a link to the game view. */
.watch-view {
    /* Fill the space between header and bottom nav and scroll internally.
       Full width (like .leaders-view) — no centered 1100px column — so the
       whole slate spreads across the screen instead of leaving big empty
       margins. (Theater mode overlays this area separately when watching.) */
    flex: 1;
    overflow-y: auto;
    min-height: 0;
    padding: 16px 24px 100px;
}
.watch-head {
    margin-bottom: 16px;
}
.watch-title {
    margin: 0 0 4px;
    font-size: 1.25rem;
    letter-spacing: 0.02em;
}
.watch-sub {
    margin: 0 0 12px;
    color: var(--text-dim);
    font-size: 0.9rem;
    max-width: 60ch;
}
.watch-ext {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border-radius: 999px;
    font-size: 0.82rem;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-dim);
}
.watch-ext .dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: 0 0 auto;
}
.watch-ext.ok    { color: var(--text); }
.watch-ext.ok .dot      { background: var(--accent-win); box-shadow: 0 0 6px var(--accent-win); }
.watch-ext.missing .dot { background: var(--text-faint); }
.watch-ext code {
    background: var(--surface-2);
    padding: 1px 5px;
    border-radius: 4px;
    font-size: 0.78rem;
}

/* Setup / install guide (collapsible) in the Watch tab */
.watch-setup {
    margin-top: 12px;
    max-width: 680px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface-2);
    overflow: hidden;
}
.watch-setup > summary {
    cursor: pointer;
    padding: 11px 14px;
    font-weight: 600;
    font-size: 0.86rem;
    color: var(--text);
    list-style: none;
}
.watch-setup > summary::-webkit-details-marker { display: none; }
.watch-setup[open] > summary { border-bottom: 1px solid var(--border); }
.watch-setup-body { padding: 12px 16px 4px; font-size: 0.84rem; color: var(--text-dim); }
.watch-setup-body ol { margin: 0; padding-left: 20px; }
.watch-setup-body li { margin-bottom: 12px; line-height: 1.5; }
.watch-setup-body code {
    background: var(--surface); padding: 1px 5px; border-radius: 4px; font-size: 0.8rem;
}
.watch-setup-body pre {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 10px 12px;
    margin: 8px 0 0;
    font-size: 0.78rem;
    overflow-x: auto;
    color: var(--text);
}
.watch-setup-body a { color: var(--accent, #4f8cff); }
.watch-setup-foot {
    margin: 4px 0 12px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    color: var(--text);
}

.watch-grid {
    display: grid;
    /* Pack more games per row (was --tile-w ≈ 2 wide) so the full slate
       fits on one screen — same density as the other sections. */
    grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
    gap: 12px;
}
.watch-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px;
}
.watch-card.is-watchable { cursor: pointer; transition: border-color .15s, background .15s; }
.watch-card.is-watchable:hover { border-color: var(--accent-live, #e8554e); background: var(--surface-2); }
.watch-card .matchup { display: flex; flex-direction: column; gap: 6px; }
.watch-card .team {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.watch-card .team-id { display: flex; align-items: center; gap: 8px; }
.watch-card .team .name { font-weight: 600; }
.watch-card .team .score { font-variant-numeric: tabular-nums; color: var(--text-dim); }
.watch-state {
    font-size: 0.78rem;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.watch-btn {
    margin-top: auto;
    width: 100%;
    padding: 7px;
    border: 0;
    border-radius: 6px;
    background: var(--accent-action);
    color: #fff;
    font-weight: 600;
    font-size: 0.82rem;
    cursor: pointer;
    transition: filter 0.15s ease, opacity 0.15s ease;
}
.watch-btn:hover { filter: brightness(1.1); }
.watch-btn:disabled { opacity: 0.7; cursor: default; }
.watch-btn.is-live { background: var(--accent-live); }

/* Sign-in prompt — shown when the extension finds the MLB.tv session has
   expired. One click to re-login; never handles the password itself. */
.watch-login-toast {
    position: fixed;
    left: 50%;
    bottom: 76px; /* clear of the bottom nav */
    transform: translateX(-50%);
    z-index: 1000;
    display: flex;
    align-items: center;
    gap: 12px;
    max-width: min(560px, calc(100vw - 24px));
    padding: 12px 14px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
    font-size: 0.86rem;
    color: var(--text);
}
.watch-login-toast a {
    flex: 0 0 auto;
    padding: 6px 12px;
    border-radius: 6px;
    background: var(--accent-action);
    color: #fff;
    text-decoration: none;
    font-weight: 600;
}
.watch-login-toast a:hover { filter: brightness(1.1); }
.watch-login-toast .wlt-x {
    flex: 0 0 auto;
    background: none;
    border: 0;
    color: var(--text-faint);
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 2px;
}
.watch-login-toast .wlt-x:hover { color: var(--text); }

/* Upcoming game on the Watch tab — not yet streamable, so a muted start-time
   chip stands in for the Watch button. */
.watch-soon {
    margin-top: auto;
    width: 100%;
    padding: 9px;
    text-align: center;
    border-radius: 6px;
    background: var(--surface-2);
    border: 1px dashed var(--border);
    color: var(--text-faint);
    font-size: 0.84rem;
    font-weight: 600;
}

/* Test-mode banner note on the Watch tab. */
.watch-test-note {
    margin-top: 10px;
    padding: 8px 12px;
    border-radius: 8px;
    background: rgba(59, 130, 246, 0.12);
    border: 1px solid var(--accent-action);
    color: var(--text-dim);
    font-size: 0.82rem;
}

/* ── PERSISTENT WATCH WIDGET ───────────────────────────────────────────
   Always-on launcher pinned bottom-right on every page. Hands the featured
   game to the Watch extension (corner picture-in-picture). */
.dcw-widget {
    position: fixed;
    right: 16px;
    top: 60px;               /* top-right, just below the 47px header — clear
                                of the crowded bottom bar (nav / bets / launcher) */
    z-index: 5200;
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: 320px;
    padding: 8px 10px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
    font-size: 0.82rem;
    color: var(--text);
}
.dcw-grip { font-size: 1rem; flex: 0 0 auto; }
.dcw-info { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.dcw-teams { font-weight: 600; white-space: nowrap; }
.dcw-at { color: var(--text-faint); font-weight: 400; }
.dcw-status { font-size: 0.72rem; color: var(--text-dim); white-space: nowrap; }
.dcw-live { color: var(--accent-live); font-weight: 700; }
.dcw-label { color: var(--text-dim); }
.dcw-btn {
    flex: 0 0 auto;
    border: 0;
    border-radius: 6px;
    background: var(--accent-action);
    color: #fff;
    font-weight: 600;
    font-size: 0.8rem;
    padding: 7px 12px;
    cursor: pointer;
}
.dcw-btn.is-live { background: var(--accent-live); }
.dcw-btn:hover { filter: brightness(1.1); }
.dcw-setup { font-size: 0.7rem; color: var(--text-faint); cursor: pointer; text-decoration: underline; }
.dcw-x {
    flex: 0 0 auto;
    background: none; border: 0; color: var(--text-faint);
    font-size: 1.05rem; line-height: 1; cursor: pointer; padding: 0 2px;
}
.dcw-x:hover { color: var(--text); }

/* Collapsed state — a small TV icon (never fully hidden, so it can't be lost). */
.dcw-widget.is-collapsed {
    padding: 0;
    gap: 0;
    background: transparent;
    border: none;
    box-shadow: none;
}
.dcw-grip-btn {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 1px solid var(--border);
    background: var(--surface-2);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
}
.dcw-grip-btn:hover { filter: brightness(1.15); }

#dcw-setup-panel {
    position: fixed;
    right: 16px;
    top: 112px;              /* just below the top-right widget */
    z-index: 5300;
    width: min(360px, calc(100vw - 32px));
    padding: 14px 16px;
    background: var(--surface);
    border: 1px solid var(--accent-action);
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
    color: var(--text);
    font-size: 0.84rem;
}
.dcw-panel-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.dcw-panel-x { background: none; border: 0; color: var(--text-faint); font-size: 1.1rem; cursor: pointer; }
.dcw-panel-sub { color: var(--text-dim); margin: 0 0 10px; font-size: 0.8rem; }
.dcw-steps { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; }
.dcw-steps code { background: var(--surface-2); padding: 1px 5px; border-radius: 4px; font-size: 0.76rem; }
.dcw-steps a { color: var(--accent-action); }
.dcw-panel-foot { margin: 10px 0 0; font-size: 0.78rem; color: var(--text-faint); }

/* ── FULL-SCREEN THEATER (bottom Watch tab) ─────────────────────────────
   Distraction-free: hide ALL app chrome and side content and show only the
   game's field (ballpark + live score / inning / count / baserunners) on its
   own screen. The MLB.tv video (Fullscreen or PiP) is the focus. */
body.dc-theater > header,
body.dc-theater > nav,
body.dc-theater > .page-footer,
body.dc-theater .active-bets-strip,
body.dc-theater .bot-launcher,
body.dc-theater .dcw-widget,
body.dc-theater .auth-header-widget,
body.dc-theater .health-indicator,
body.dc-theater .global-stake-widget,
body.dc-theater .game-view > .back-link,
body.dc-theater .game-view > .ticker,
body.dc-theater .game-view > .game-mode-toggle,
body.dc-theater .field-pane > .field-narrative,
body.dc-theater .game-pane > .card-pane {
    display: none !important;
}
body.dc-theater .game-view { padding: 0; max-width: none; height: 100vh; overflow: hidden; }
body.dc-theater .game-pane { display: block; height: 100vh; padding: 0; }
body.dc-theater .field-pane { display: block; height: 100vh; }
body.dc-theater .field-pane > .field-canvas {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    width: 100%;
    max-width: 1100px;
    margin: 0 auto;
    padding: 0;
}

/* ── FIELD-SHIFT WATCH (in-game / board Watch) ──────────────────────────
   Keep the whole game view; just shift the field down to open space above it
   where you manually drag the MLB.tv PiP. Cards/panels stay put. */
body.dc-watching .field-pane > .field-canvas {
    padding-top: 44vh;
    align-self: start;
    transition: padding-top .3s ease;
}
#dcw-exit-theater {
    position: fixed;
    top: 60px;
    left: 16px;
    z-index: 5400;
    padding: 6px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text-dim);
    font: 600 12px system-ui, sans-serif;
    cursor: pointer;
}
#dcw-exit-theater:hover { color: var(--text); }

/* "Save video spot" — sits just right of the Exit chip while watching. Drag
   the MLB.tv window where you want it, click this, and the extension stores
   those exact bounds to reuse for every game. */
#dcw-save-pos {
    position: fixed;
    top: 60px;
    left: 150px;
    z-index: 5400;
    padding: 6px 14px;
    border: 1px solid var(--accent, #4f8cff);
    border-radius: 999px;
    background: var(--accent, #4f8cff);
    color: #fff;
    font: 600 12px system-ui, sans-serif;
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}
#dcw-save-pos:hover { filter: brightness(1.08); }

/* On the game view the red "▶ Watch" tab is the watch control, so hide the
   floating widget there (avoid two Watch buttons on one screen). */
body:has(#game-view:not([hidden])) .dcw-widget { display: none !important; }
/* The Watch tab IS the watch UI — hide the floating launcher there so it
   doesn't cover the cards/header. Same on Hot (cards have their own Watch
   buttons now). */
body:has(#watch-view:not([hidden])) .dcw-widget { display: none !important; }
body:has(#hot-view:not([hidden])) .dcw-widget { display: none !important; }
