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

/* Modern Header Styles */
/* --- Design tokens: one dark surface system --- */
:root {
  --bg: #0b0d10;
  --surface: #14171c;
  --surface-2: #1b1f26;
  --surface-3: #232a33;
  --border: #2a303a;
  --border-soft: #21262e;
  --text: #f2f4f7;
  --muted: #9aa4b2;
  --faint: #6b7280;
  --accent: #6366f1;
  --accent-hi: #818cf8;
  --accent-soft: rgba(99, 102, 241, 0.16);
  --good: #22c55e;
  --good-soft: rgba(34, 197, 94, 0.15);
  --bad: #ef4444;
  --bad-soft: rgba(239, 68, 68, 0.15);
  --warn: #f59e0b;
  --gold: #eab308;
  --radius: 12px;
  --radius-sm: 8px;
}

/* The shared shell (src/views/shell.js, shell.css), sized for this page:
   the dashboard's header is taller than the 56px bar the shell defaults
   to, with its own type steps per breakpoint below. These rules override
   shell.css (linked first) property by property; the mark, the left group
   and the slot's layout are the shell's own and are not repeated here. */
.mm-shell {
  position: sticky;
  top: 0;
  z-index: 1000;
  background: rgba(17, 20, 25, 0.85);
  backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid var(--border);
  padding: 0.6rem 1.5rem;
  /* Standalone iOS: the sticky header sits under the notch without
       this. calc() + the 0px fallback keeps a normal browser tab
       (insets are 0 there) byte-for-byte unchanged. */
  padding-top: calc(0.6rem + env(safe-area-inset-top, 0px));
  transition: border-color 0.3s ease;
}

.mm-shell.scrolled {
  border-bottom-color: var(--accent);
}

.mm-shell-in {
  max-width: 1200px;
  margin: 0 auto;
  /* The bar's own padding and floor are on .mm-shell above, not here. */
  padding: 0;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.mm-shell-brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--text);
  margin: 0;
  letter-spacing: -0.01em;
}

.week-badge {
  background: var(--surface-2);
  border: 1px solid var(--border);
  padding: 0.3rem 0.7rem;
  border-radius: 2rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.week-number {
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--text);
}

.week-dates {
  font-size: 0.8rem;
  color: var(--muted);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.mm-shell-right {
  /* shell.css's auto, kept: space-between places the slot at the right of
     the row, and should the row ever wrap, auto keeps the account control
     (E-10) at the right edge rather than parking it at the left with its
     menu hanging off the screen. */
  margin-left: auto;
  gap: 1rem;
}

.live-indicator {
  display: none;
  align-items: center;
  gap: 0.5rem;
  background: rgba(239, 68, 68, 0.9);
  padding: 0.25rem 0.75rem;
  border-radius: 1rem;
  animation: pulse 2s infinite;
}

.live-indicator.active {
  display: inline-flex;
}

.live-dot {
  width: 8px;
  height: 8px;
  background: white;
  border-radius: 50%;
  animation: blink 1.5s infinite;
}

.live-text {
  font-size: 0.75rem;
  font-weight: 600;
  color: white;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 0.9;
  }
  50% {
    opacity: 1;
  }
}

@keyframes blink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.3;
  }
}

/* Mobile responsive header */
@media (max-width: 640px) {
  .mm-shell {
    padding: 0.75rem;
  }

  .mm-shell-in {
    gap: 0.5rem;
  }

  .mm-shell-brand {
    font-size: 1.25rem;
  }

  .week-badge {
    padding: 0.25rem 0.5rem;
  }

  .week-number {
    font-size: 0.875rem;
  }

  .week-dates {
    display: none;
  }

  .week-dates-mobile {
    display: block;
    font-size: 0.75rem;
    color: rgba(255, 255, 255, 0.85);
    text-align: center;
    margin-top: 0.5rem;
    width: 100%;
  }
}

/* 320px — the smallest viewport this app targets, and the only one
   where the mark does not fit as drawn. Measured there: the header row
   has 264px of content width, of which the wordmark takes 147px, the
   week badge 63px and the two gaps 24px — leaving about 30px for a
   logo. The mark is 1.61x as wide as it is tall (its viewBox is
   100x62), so at 1.9em it wanted 61px and pushed "Monday Miracle" onto
   two lines, where the square emoji it replaced had fit on one.
   Trimming the type one step and the mark to 1.6em puts the row back
   to 253px and restores the single-line header. The cutoff is 340px so
   every current phone (360, 390, 393, 402, 430) keeps the full-size
   mark; only 320px pays for it. */
@media (max-width: 340px) {
  .mm-shell-brand {
    font-size: 1.05rem;
  }

  .mm-shell-mark {
    height: 1.6em;
  }
}

@media (min-width: 641px) {
  .week-dates-mobile {
    display: none;
  }
}

/* Tablet and up */
@media (min-width: 768px) {
  .mm-shell {
    padding: 1.25rem 1.5rem;
  }

  .mm-shell-brand {
    font-size: 1.75rem;
  }

  .week-badge {
    padding: 0.5rem 1rem;
  }
}

/* Desktop */
@media (min-width: 1024px) {
  .mm-shell {
    padding: 1.5rem 2rem;
  }

  .mm-shell-in {
    gap: 1rem;
  }

  .mm-shell-brand {
    font-size: 2rem;
  }
}

body {
  font-family:
    -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: var(--bg);
  min-height: 100vh;
  padding: 16px;
  /* Standalone iOS: without this the last deck row sits under the
       home-indicator bar. calc() + 0px fallback keeps a normal
       browser tab (no insets) at the original 16px. */
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  color: var(--text);
}

.container {
  max-width: 1400px;
  margin: 0 auto;
}

/* Connection toolbar — replaces the old white tagline + auth cards */
.auth-section {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding: 12px 4px 18px;
}

.conn-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 600;
  background: var(--good-soft);
  color: var(--good);
  border: 1px solid rgba(34, 197, 94, 0.3);
}
/* The connected state is a dot, not an emoji: one 8px token that reads the
   same at every size and in every font, where ✅ rendered as a coloured
   glyph the rest of the UI has nowhere else. `off` chips carry no dot —
   absence IS the unconnected state. */
.conn-chip:not(.off)::before {
  content: '';
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--good);
}
.conn-chip.off {
  background: var(--surface-2);
  color: var(--muted);
  border-color: var(--border);
}

.button {
  background: var(--accent);
  color: white;
  border: 1px solid transparent;
  padding: 9px 16px;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  cursor: pointer;
  transition: all 0.15s ease;
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  font-weight: 600;
}

.button:hover {
  background: var(--accent-hi);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px var(--accent-soft);
}

/* Secondary = neutral outline (NOT red — red is reserved for root-against) */
.button.secondary {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
}
.button.secondary:hover {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--surface-3);
  box-shadow: none;
}

/* --- Verdict strip: answer-first summary --- */
.verdict-strip {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 16px;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.verdict-label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
  margin-right: 2px;
}
.verdict-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  cursor: pointer;
}
.verdict-pill.for {
  border-color: rgba(34, 197, 94, 0.4);
}
.verdict-pill.against {
  border-color: rgba(239, 68, 68, 0.4);
}
.verdict-pill.conflict {
  border-color: rgba(245, 158, 11, 0.55);
}
.verdict-pill.game {
  border-color: rgba(79, 143, 247, 0.5);
}
.verdict-pill.game .verdict-dir,
.verdict-pill.game .verdict-pts {
  color: #4f8ff7;
}
.verdict-pill.conflict .verdict-dir,
.verdict-pill.conflict .verdict-pts {
  color: var(--warn);
}

/* --- Games to Watch (the game lens) --- */
.slate-section {
  margin: 16px 0 6px;
}
.slate-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-bottom: 10px;
  color: var(--muted);
  font-size: 0.72rem;
}
.slate-legend .legend-item {
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* League tag — muted chrome, never colour (colour = signal only), and an
   <abbr title> on a game card, so the UA's dotted underline goes (E-15). */
.lg {
  font-weight: 700;
  font-size: 0.69rem;
  letter-spacing: 0.05em;
  color: #8b93a7;
  font-style: normal;
  text-decoration: none;
}
.slate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(310px, 100%), 1fr));
  gap: 12px;
}
.game-card {
  background: var(--surface-2, #171e2e);
  border: 1px solid var(--border, #2a3348);
  border-radius: 12px;
  padding: 13px 14px;
}
.game-card.heat-warm {
  border-color: rgba(245, 158, 11, 0.55);
}
.game-card.heat-hot {
  border-color: rgba(239, 68, 68, 0.7);
  box-shadow: 0 0 16px rgba(239, 68, 68, 0.12);
}
.game-card.is-live {
  border-color: rgba(34, 197, 94, 0.7);
  animation: slatePulse 2.2s infinite;
}
@keyframes slatePulse {
  0%,
  100% {
    box-shadow: 0 0 0 rgba(34, 197, 94, 0);
  }
  50% {
    box-shadow: 0 0 12px rgba(34, 197, 94, 0.3);
  }
}
.game-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
}
.game-matchup {
  font-weight: 700;
  font-size: 0.94rem;
}
.game-when {
  display: block;
  color: var(--muted);
  font-size: 0.69rem;
  margin-top: 1px;
}
.game-verdict {
  font-size: 0.63rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  padding: 3px 8px;
  border-radius: 999px;
  white-space: nowrap;
}
.game-verdict.for {
  color: #22c55e;
  border: 1px solid rgba(34, 197, 94, 0.5);
}
.game-verdict.against {
  color: #ef4444;
  border: 1px solid rgba(239, 68, 68, 0.5);
}
.game-verdict.contested {
  color: #f59e0b;
  border: 1px solid rgba(245, 158, 11, 0.55);
}
.stake-bar {
  display: flex;
  height: 7px;
  border-radius: 999px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.06);
  margin: 10px 0 5px;
}
.stake-for {
  background: #22c55e;
}
.stake-against {
  background: #ef4444;
}
.stake-nums {
  display: flex;
  justify-content: space-between;
  font-size: 0.78rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  margin-bottom: 8px;
}
.p-for {
  color: #22c55e;
}
.p-against {
  color: #ef4444;
}
.slate-row {
  display: grid;
  grid-template-columns: minmax(min(12ch, 100%), 1fr) auto;
  align-items: baseline;
  column-gap: 12px;
  padding: 5px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
}
.slate-player {
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.25;
  overflow-wrap: break-word;
}
.slate-entries {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  column-gap: 10px;
  row-gap: 1px;
}
.entry {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  white-space: nowrap;
}
.entry .num {
  font-size: 0.81rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  min-width: 5ch;
  text-align: right;
}
/* Conflict: amber lives on the border/wash, never on text. */
.slate-row.conflict-row {
  background: rgba(245, 158, 11, 0.07);
  border-left: 3px solid #f59e0b;
  padding-left: 7px;
  margin-left: -7px;
  border-radius: 3px;
}
.slate-more {
  color: var(--muted);
  font-size: 0.76rem;
  padding-top: 4px;
}
.slate-finals {
  margin-top: 10px;
}
.slate-final-row {
  display: flex;
  justify-content: space-between;
  color: var(--muted);
  font-size: 0.8rem;
  padding: 4px 2px;
  opacity: 0.75;
}

/* The start hero (.start-hero, .hero-*, .linklike, .signin-card, the
   guide-active toggle on #topControls and the pills row that stands in
   for it) is hero.css, linked after this file as `dashboard-hero.css`. */

/* Reload restore: the cached guide paints instantly, so this pill is the
   only sign that the live scores are still on their way (and the only
   place we admit it when they never arrived). */
.guide-refresh {
  display: none;
  position: fixed;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  z-index: 70;
  align-items: center;
  gap: 8px;
  max-width: calc(100vw - 32px);
  padding: 8px 15px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: rgba(10, 14, 24, 0.93);
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 600;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
}
.guide-refresh.on {
  display: flex;
}
.guide-refresh::before {
  content: '';
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent-hi);
  animation: blink 1.2s ease-in-out infinite;
}
.guide-refresh.stale {
  color: var(--warn);
  border-color: rgba(245, 158, 11, 0.45);
}
.guide-refresh.stale::before {
  background: var(--warn);
  animation: none;
}

@media (max-width: 768px) {
  body.guide-active .verdict-strip {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    gap: 8px;
    padding: 8px 10px;
    margin-bottom: 10px;
  }
  body.guide-active .verdict-strip::-webkit-scrollbar {
    display: none;
  }
  body.guide-active .verdict-label {
    display: none;
  }
  body.guide-active .verdict-pill {
    padding: 4px 10px;
    flex: 0 0 auto;
  }
  body.guide-active .verdict-name {
    font-size: 0.8rem;
    white-space: nowrap;
  }
  body.guide-active .verdict-pts {
    font-size: 0.8rem;
  }
  body.guide-active .verdict-dir {
    font-size: 0.62rem;
    white-space: nowrap;
  }
}

/* --- Player lens columns (compact cards: one row per league + the game) --- */
.pp-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  padding: 2px 2px 8px;
}
.pp-head.scores {
  color: #8b7cf6;
}
.pp-head.conflict {
  color: #f59e0b;
}
.pp-head.for {
  color: #22c55e;
}
.pp-head.against {
  color: #ef4444;
}
.pp-head.played {
  color: #94a3b8;
}
.pp-count {
  color: var(--muted);
  font-weight: 700;
}
.pp-sub {
  font-size: 0.7rem;
  color: var(--muted);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}
.pp-card {
  background: var(--surface-2, #171e2e);
  border: 1px solid var(--border, #2a3348);
  border-radius: 12px;
  padding: 11px 13px;
  margin-bottom: 10px;
}
.pp-card.conflict {
  border-left: 3px solid #f59e0b;
}
.pp-card.for {
  border-left: 3px solid #22c55e;
}
.pp-card.against {
  border-left: 3px solid #ef4444;
}
.pp-card.played {
  border-left: 3px solid #94a3b8;
}
/* Played screen: a slim game header groups each game's player cards
   (matchup left, LIVE/FINAL right), newest game first. */
.played-game-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  margin: 14px 2px 6px;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--muted);
}
.pp-head + .played-game-head {
  margin-top: 2px;
}
.pp-card.flash {
  animation: ppFlash 1.4s ease;
}
@keyframes ppFlash {
  0% {
    background: rgba(255, 255, 255, 0.14);
  }
  100% {
    background: var(--surface-2, #171e2e);
  }
}
.pp-top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 12px;
  align-items: baseline;
}
.pp-name {
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.25;
  overflow-wrap: break-word;
}
.pp-total {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  font-size: 0.92rem;
}
.pp-total.conflict {
  color: #f59e0b;
}
.pp-meta {
  color: var(--muted);
  font-size: 0.72rem;
  margin-top: 2px;
}
.pp-live {
  color: #22c55e;
  font-weight: 700;
}
/* Banked-so-far, shown before the arrow to the updated projection.
   Muted and lighter so the eye lands on where the number is HEADING,
   with the actual available right next to it. */
.pp-now {
  color: var(--muted);
  font-weight: 600;
  opacity: 0.85;
}
.pp-arrow {
  color: var(--muted);
  opacity: 0.6;
  margin: 0 3px;
  font-weight: 400;
}
/* The pair needs more room than a lone figure, and must be free to
   wrap onto a second line on a narrow phone rather than overflow. */
.pp-row .num:has(.pp-arrow) {
  min-width: 11ch;
}
.stake-nums .pp-now,
.pp-total .pp-now {
  font-size: 0.92em;
}
.pp-rows {
  margin-top: 7px;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
}
/* Two cells, not three: the tag left of the name is gone (ch. 16 E-15). */
.pp-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 8px;
  align-items: baseline;
  padding: 4px 0;
}
.pp-row + .pp-row {
  border-top: 1px solid rgba(255, 255, 255, 0.04);
}
.pp-league {
  color: var(--muted);
  font-size: 0.78rem;
  overflow-wrap: break-word;
}
.pp-row .num {
  font-size: 0.83rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  min-width: 5ch;
  text-align: right;
}
.pp-empty {
  color: var(--muted);
  font-size: 0.85rem;
  padding: 14px 4px;
}
.pp-more {
  display: block;
  width: 100%;
  text-align: center;
  background: transparent;
  border: 1px dashed var(--border);
  color: var(--muted);
  border-radius: 10px;
  padding: 8px;
  cursor: pointer;
  font-size: 0.78rem;
}

/* League Scores grid. Its floor (and .slate-grid's, 330 -> 310) yields to the panel — 284 px at 320 (F-15) — and at 280 keeps three across in the arrows' 908 px track at 1024, as on main (F-16). */
.scores-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 12px;
}
.verdict-dir {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.verdict-pill.for .verdict-dir {
  color: var(--good);
}
.verdict-pill.against .verdict-dir {
  color: var(--bad);
}
.verdict-name {
  font-weight: 600;
  color: var(--text);
  font-size: 0.9rem;
}
.verdict-pts {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-size: 0.9rem;
}
.verdict-pill.for .verdict-pts {
  color: var(--good);
}
.verdict-pill.against .verdict-pts {
  color: var(--bad);
}

/* --- Win-probability bar (two-sided: you vs opponent) --- */
.winbar-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 12px 0 10px;
}
.winbar {
  flex: 1 1 auto;
  height: 6px;
  border-radius: 999px;
  background: var(--bad-soft);
  overflow: hidden;
}
.winbar-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--good);
  transition: width 0.6s ease;
}
.winbar-fill.low {
  background: var(--bad);
}
.winbar-pct {
  flex: 0 0 auto;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

/* --- Restrained card hover elevation --- */
.league-score-card {
  transition:
    transform 0.15s ease,
    box-shadow 0.15s ease,
    border-color 0.15s ease;
}
.league-score-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}

.status {
  padding: 15px;
  margin: 20px 0;
  border-radius: 8px;
  background: #f0fff4;
  border-left: 4px solid #48bb78;
  color: #22543d;
}

.loading {
  text-align: center;
  padding: 40px;
  color: #718096;
}

.spinner {
  border: 3px solid #e2e8f0;
  border-top: 3px solid #667eea;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  animation: spin 1s linear infinite;
  margin: 20px auto;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

@media (max-width: 768px) {
  .hero {
    font-size: 2em;
  }
  .rooting-guide {
    grid-template-columns: 1fr;
  }
}

/* League Scores Section */

.league-score-card {
  background: #1a1a1a;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 12px;
  border: 1px solid #2a2a2a;
}

/* PERSISTENT block on purpose. displayRootingGuide emits the markup
   below but injects no <style> of its own — it only replaces
   #rooting-display — so rules that live inside displayRootingMeter's
   injected stylesheet are undefined on the default dashboard. These
   three have to sit here, where every renderer sees them.

   They are a PAIR, and both renderers emit both elements: .league-name
   is the flex row, .league-name-text is the only thing in it allowed
   to shrink. Giving .league-name min-width:0 without an inner
   .league-name-text to clip just lets the name overflow its box and
   paint over whatever sits beside it. */
.league-name {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 14px;
  font-weight: 600;
  color: #fff;
}

/* One line, always: only the NAME gives way. A long league name used to
   push the badge onto a second line, which made that card's header
   taller than its neighbours' and knocked the whole grid row out of
   alignment. */
.league-name-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.platform-badge {
  flex: 0 0 auto;
  white-space: nowrap;
  color: #fff;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 10px;
  line-height: 1.4;
}
.platform-badge.espn {
  background: #cd4447;
}
.platform-badge.yahoo {
  background: #7849f7;
}
.platform-badge.imported {
  background: #00a86b;
}

.win-high {
  background: #00a86b;
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 600;
}

.win-medium {
  background: #ffa500;
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 600;
}

.win-low {
  background: #dc143c;
  color: white;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 600;
}

.matchup {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 12px;
  align-items: center;
}

.team {
  text-align: center;
}

.team.mine {
  border: 2px solid #00a86b;
  background: rgba(0, 168, 107, 0.1);
  border-radius: 8px;
  padding: 12px;
}

.team.opponent {
  border: 2px solid #444;
  background: rgba(255, 255, 255, 0.02);
  border-radius: 8px;
  padding: 12px;
}

.team-name {
  font-size: 12px;
  color: #999;
  margin-bottom: 4px;
}

.team-score {
  font-size: 28px;
  font-weight: 700;
  margin-bottom: 4px;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.team-projected {
  font-size: 14px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.vs {
  font-size: 12px;
  color: #666;
}

.point-differential {
  text-align: center;
  margin-top: 8px;
  font-size: 12px;
  color: #999;
}

.differential-value {
  font-weight: 600;
  color: #fff;
}

.differential-value.winning {
  color: #00a86b;
}

.differential-value.losing {
  color: #dc143c;
}

/* Clear rooting recommendations */

.confidence {
  font-size: 18px;
}

/* --- PWA: install hint + score-alert settings --- */
.mm-install-hint {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin: 0 0 14px;
  padding: 11px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--muted);
  font-size: 13px;
  line-height: 1.45;
}
.mm-install-actions {
  display: flex;
  gap: 14px;
  flex-shrink: 0;
}

.mm-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: rgba(0, 0, 0, 0.72);
  overflow-y: auto;
  /* Standalone mode puts the sheet under the notch otherwise. */
  padding: calc(24px + env(safe-area-inset-top, 0px)) 16px
    calc(24px + env(safe-area-inset-bottom, 0px));
}
.mm-modal-card {
  max-width: 30rem;
  margin: 0 auto;
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface);
  color: var(--text);
}
.mm-modal-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.mm-modal-head h2 {
  font-size: 1.15rem;
  margin: 0;
}
.mm-alert-lead {
  color: var(--muted);
  font-size: 13px;
  line-height: 1.5;
  margin: 6px 0 16px;
}
.mm-alert-note {
  color: var(--muted);
  font-size: 13.5px;
  line-height: 1.55;
  margin: 0 0 10px;
}
.mm-alert-steps {
  color: var(--muted);
  font-size: 13.5px;
  line-height: 1.7;
  margin: 0;
  padding-left: 1.2rem;
}
.mm-alert-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 9px 0;
  border-bottom: 1px solid var(--border-soft);
  font-size: 14px;
  cursor: pointer;
}
.mm-alert-row:last-child {
  border-bottom: 0;
}
.mm-alert-row small {
  display: block;
  color: var(--faint);
  font-size: 12px;
  margin-top: 2px;
  line-height: 1.4;
}
.mm-alert-row input[type='checkbox'] {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  accent-color: var(--accent);
}
.mm-alert-main {
  border-bottom: 1px solid var(--border);
  padding-bottom: 13px;
  margin-bottom: 4px;
}
.mm-alert-group {
  margin: 14px 0;
}
.mm-alert-label {
  color: var(--faint);
  font-size: 11px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  margin-bottom: 6px;
}
.mm-alert-quiet {
  color: var(--muted);
  font-size: 13.5px;
  line-height: 2.1;
}
.mm-modal select {
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text);
  font-size: 13.5px;
}
.mm-alert-group > select {
  width: 100%;
}
.mm-alert-status {
  min-height: 1.2em;
  margin-top: 12px;
  color: var(--muted);
  font-size: 12.5px;
}
