:root {
  --bg: #0d1117;
  --bg-card: #161b22;
  --bg-card-2: #1c2230;
  --border: #2d333b;
  --text: #e6edf3;
  --text-dim: #8b949e;
  --text-faint: #586069;
  --live: #f85149;
  --soon: #e3b341;
  --advance: #3fb950;
  --third: #d29922;
  --accent: #58a6ff;
  --win: #3fb950;
  --upset: #f0883e;
  --notice: var(--upset); /* simulator notice — same color as upsets, per theme */
  --on-accent: #0d1117; /* text on an --accent background (accent is light here) */
  --pa: #58a6ff;        /* prob bar: away win */
  --pd: #545d68;        /* prob bar: draw */
  --ph: #3fb950;        /* prob bar: home win */
  --zebra: rgba(255, 255, 255, 0.02);
  --table-line: rgba(45, 51, 59, 0.5);
  --topbar-bg: rgba(13, 17, 23, 0.95);
  --mstar-dim: rgba(88, 166, 255, 0.65);
  --yc: #e3b341;       /* yellow-card chip */
}

html[data-theme="light"] {
  --bg: #f6f8fa;
  --bg-card: #ffffff;
  --bg-card-2: #eaeef2;
  --border: #d0d7de;
  --text: #1f2328;
  --text-dim: #57606a;
  --text-faint: #8c959f;
  --live: #d1242f;
  --soon: #9a6700;
  --advance: #1a7f37;
  --third: #9a6700;
  --accent: #0969da;
  --win: #1a7f37;
  --upset: #bc4c00;
  --on-accent: #ffffff; /* accent is dark blue here, so white reads well */
  --pa: #218bff;
  --pd: #afb8c1;
  --ph: #2da44e;
  --zebra: rgba(0, 0, 0, 0.03);
  --table-line: rgba(208, 215, 222, 0.6);
  --topbar-bg: rgba(246, 248, 250, 0.95);
  --mstar-dim: rgba(9, 105, 218, 0.55);
  --yc: #f2c100;
}

html[data-theme="pitch"] {
  --bg: #0a3d1e;
  --bg-card: #0e4a25;
  --bg-card-2: #14592e;
  --border: #1d7a3e;
  --text: #f0fff4;
  --text-dim: #a7d7b4;
  --text-faint: #6fae7f;
  --live: #ff5d5d;
  --soon: #ffd23f;
  --advance: #8effa9;
  --third: #ffd23f;
  --accent: #ffe14d;
  --win: #8effa9;
  --upset: #ff9d42;
  --on-accent: #0a3d1e; /* dark text on the yellow accent */
  --pa: #5fb8ff;
  --pd: rgba(255, 255, 255, 0.28);
  --ph: #ffe14d;
  --zebra: rgba(255, 255, 255, 0.04);
  --table-line: rgba(29, 122, 62, 0.5);
  --topbar-bg: rgba(8, 51, 25, 0.95);
  --mstar-dim: rgba(255, 225, 77, 0.6);
  --yc: #ffd23f;
}

html[data-theme="party"] {
  --bg: #1a0b2e;
  --bg-card: #2a1245;
  --bg-card-2: #3b1a5e;
  --border: #5b2d91;
  --text: #fdf0ff;
  --text-dim: #d9a7f0;
  --text-faint: #9a6cc9;
  --live: #ff5c8a;
  --soon: #ffd166;
  --advance: #2dffb3;
  --third: #ffd166;
  --accent: #ff4ecd;
  --win: #2dffb3;
  --upset: #ff8c42;
  --on-accent: #ffffff; /* white on the magenta accent */
  --pa: #29d2ff;
  --pd: #8d6ab8;
  --ph: #2dffb3;
  --zebra: rgba(255, 255, 255, 0.03);
  --table-line: rgba(91, 45, 145, 0.5);
  --topbar-bg: rgba(26, 11, 46, 0.95);
  --mstar-dim: rgba(255, 78, 205, 0.6);
  --yc: #ffd166;
}

/* mown-grass stripes */
html[data-theme="pitch"] body {
  background-image: repeating-linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.02) 0 90px,
    transparent 90px 180px
  );
}
/* ball bouncing behind the content — movement is JS-driven (app.js) so it
   can be kicked; clicks are hit-tested at the document level */
#pitch-ball {
  display: none;
  position: fixed;
  left: 0;
  top: 0;
  z-index: -1;
  pointer-events: none;
  user-select: none;
  font-size: 54px;
  line-height: 1;
  opacity: 0.22;
  will-change: transform;
}
html[data-theme="pitch"] #pitch-ball { display: block; }

/* animated neon gradient backdrop — drifting glow blobs over a morphing
   base gradient */
html[data-theme="party"] body {
  background-image:
    radial-gradient(circle at 20% 20%, rgba(255, 78, 205, 0.18), transparent 45%),
    radial-gradient(circle at 80% 70%, rgba(41, 210, 255, 0.16), transparent 45%),
    radial-gradient(circle at 55% 90%, rgba(45, 255, 179, 0.12), transparent 45%),
    linear-gradient(125deg, #2a0e44, #1a0b2e, #0e2447, #2a0e44);
  background-size: 150% 150%, 150% 150%, 150% 150%, 260% 260%;
  background-attachment: fixed;
  animation: party-bg-shift 17s ease-in-out infinite;
}
@keyframes party-bg-shift {
  0%, 100% { background-position: 0% 0%, 100% 100%, 50% 100%, 0% 50%; }
  50% { background-position: 100% 100%, 0% 0%, 100% 0%, 100% 50%; }
}
html[data-theme="party"] body::before {
  content: "";
  position: fixed;
  /* oversized and centred so the continuous spin always fills the viewport
     and the confetti never scrolls off-screen */
  top: 50%;
  left: 50%;
  width: 170vmax;
  height: 170vmax;
  margin: -85vmax 0 0 -85vmax;
  z-index: -1;
  pointer-events: none;
  opacity: 0.55;
  background-image:
    radial-gradient(circle, #ff4ecd 2.2px, transparent 2.7px),
    radial-gradient(circle, #29d2ff 1.9px, transparent 2.4px),
    radial-gradient(circle, #ffd166 2.4px, transparent 2.9px),
    radial-gradient(circle, #2dffb3 1.7px, transparent 2.2px);
  background-size: 210px 230px, 170px 190px, 240px 260px, 150px 170px;
  background-position: 0 0, 60px 80px, 120px 40px, 30px 120px;
  /* spin the field + twinkle the dots (opacity pulse) */
  animation: party-confetti-spin 22s linear infinite, party-twinkle 2.6s ease-in-out infinite;
  will-change: transform, opacity;
}
@keyframes party-confetti-spin {
  to { transform: rotate(360deg); }
}
@keyframes party-twinkle {
  0%, 100% { opacity: 0.32; }
  50% { opacity: 0.7; }
}
/* gradient only on the wordmark — never clip the ⚽ emoji, or iOS Safari
   leaves it stuck transparent (invisible) after switching themes */
html[data-theme="party"] .topbar h1 .wordmark {
  background: linear-gradient(90deg, #ff4ecd, #ffd166, #2dffb3, #29d2ff, #ff4ecd);
  background-size: 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: rainbow-slide 6s linear infinite;
}
@keyframes rainbow-slide {
  to { background-position: 300% 0; }
}
html[data-theme="party"] .topbar h1 .logo {
  display: inline-block; /* required for transform on the inline emoji */
  animation: party-ball-spin 2s linear infinite;
}
@keyframes party-ball-spin {
  to { transform: rotate(360deg); }
}
html[data-theme="party"] .topbar {
  border-bottom: none;
}
html[data-theme="party"] .topbar::after {
  content: "";
  display: block;
  height: 2px;
  background: linear-gradient(90deg, #ff4ecd, #ffd166, #2dffb3, #29d2ff, #ff4ecd);
  background-size: 200% 100%;
  animation: rainbow-slide 8s linear infinite;
}
html[data-theme="party"] .live-card:not(.pre):not(.ft) {
  animation: party-glow 3s ease-in-out infinite;
}
@keyframes party-glow {
  0%, 100% { box-shadow: 0 0 14px rgba(255, 78, 205, 0.4); border-color: #ff4ecd; }
  50% { box-shadow: 0 0 18px rgba(41, 210, 255, 0.5); border-color: #29d2ff; }
}
html[data-theme="party"] .section h2::after {
  content: "🎉";
  font-size: 13px;
}
/* sections with metadata: the h2 wraps on mobile (.sub is full-width), which
   would push the trailing 🎉 to its own line — append it to the metadata's
   inline flow instead so it stays on the metadata line */
html[data-theme="party"] .section h2:has(.sub)::after { content: none; }
html[data-theme="party"] .section h2 .sub::after { content: " 🎉"; font-size: 13px; }
@media (prefers-reduced-motion: reduce) {
  html[data-theme="party"] body,
  html[data-theme="party"] body::before,
  html[data-theme="party"] .topbar h1 .wordmark,
  html[data-theme="party"] .topbar h1 .logo,
  html[data-theme="party"] .topbar::after,
  html[data-theme="party"] .live-card:not(.pre) {
    animation: none;
  }
}

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

/* ---------- goal celebration ---------- */
.confetti-layer {
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  overflow: hidden;
}
.confetti-ball {
  position: absolute;
  top: -50px;
  line-height: 1;
  will-change: transform;
  animation-name: goal-confetti-fall;
  animation-timing-function: linear;
  animation-iteration-count: 1;
}
@keyframes goal-confetti-fall {
  from { transform: translate3d(0, -50px, 0) rotate(0deg); }
  to { transform: translate3d(var(--drift, 0), 108vh, 0) rotate(var(--spin, 360deg)); }
}
.live-card.celebrate {
  border-color: var(--win);
  animation: goal-glow 1s ease-in-out infinite;
}
@keyframes goal-glow {
  0%, 100% { box-shadow: 0 0 9px 1px rgba(63, 185, 80, 0.45); border-color: var(--win); }
  50% { box-shadow: 0 0 24px 7px rgba(63, 185, 80, 0.85); border-color: #7ee787; }
}
.live-card .score.goal-pop {
  color: var(--win);
  /* same duration/curve/peak as goal-glow so the score and border
     pulse in sync */
  animation: goal-pop 1s ease-in-out infinite;
  display: inline-block;
  transform-origin: center;
}
@keyframes goal-pop {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.35); }
}
@media (prefers-reduced-motion: reduce) {
  .live-card.celebrate { animation: none; box-shadow: 0 0 14px 3px rgba(63, 185, 80, 0.6); }
  .live-card .score.goal-pop { animation: none; }
}

html {
  --anchor-scroll-offset: 56px;
  scroll-behavior: smooth;
  scroll-padding-top: var(--anchor-scroll-offset);
}
/* The header controls always sit in the sticky bar, so focusing one (e.g.
   opening the theme picker) should never scroll the page. scroll-padding-top
   otherwise makes the browser scroll up to "reveal" them on focus; a negative
   scroll-margin cancels that. (Anchor navigation targets the sections, not
   these, so it's unaffected.) */
.topbar a, .topbar button, .topbar select { scroll-margin-top: -200px; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.4;
}

/* ---------- top bar ---------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--topbar-bg);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}
.topbar-inner {
  max-width: 1500px;
  margin: 0 auto;
  padding: 8px 16px;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.topbar h1 { font-size: 17px; white-space: nowrap; }
.tabs { display: flex; gap: 4px; }
.tabs a {
  color: var(--text-dim);
  text-decoration: none;
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 600;
}
/* only on real hover devices — otherwise a tapped link keeps :hover on touch
   (sticky hover) and, since it looks identical to .active, two tabs appear
   selected after you scroll away from the one you tapped */
@media (hover: hover) {
  .tabs a:hover { color: var(--text); background: var(--bg-card-2); }
}
/* subtle selected state: full-strength text (whiter in dark, darker in light)
   rather than the accent colour, with the same soft pill background */
.tabs a.active { color: var(--text); background: var(--bg-card-2); }
.notify-wrap { position: relative; flex: none; }
.notify-toggle {
  min-width: 58px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  flex: none;
  background: var(--bg-card);
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0 4px;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.notify-toggle:hover { border-color: var(--text-faint); color: var(--text); }
.notify-toggle.active {
  border-color: var(--accent);
  color: var(--accent);
}
.notify-toggle.blocked,
.notify-toggle:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.notify-label {
  font-size: 11px;
  font-weight: 700;
}
.notify-pop {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 150;
  width: min(280px, calc(100vw - 20px));
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-card);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  color: var(--text-dim);
  font-size: 12px;
  line-height: 1.35;
}
.notify-pop b {
  display: block;
  color: var(--text);
  margin-bottom: 3px;
}
.notify-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 9px;
}
.notify-actions button {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 8px;
  background: var(--bg-card-2);
  color: var(--text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.notify-actions button:first-child { border-color: var(--accent); color: var(--accent); }
.theme-wrap {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 14px;
}
.theme-select {
  background: var(--bg-card);
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 3px 6px;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
}
.theme-select:hover { border-color: var(--text-faint); }
.status {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--text-faint);
}
.live-count {
  color: var(--live);
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 5px;
}
.live-count::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--live);
  animation: pulse 1.5s infinite;
}

main { max-width: 1500px; margin: 0 auto; padding: 12px 16px 40px; }

.offline-banner {
  background: rgba(227, 179, 65, 0.12);
  border: 1px solid var(--soon);
  color: var(--soon);
  border-radius: 8px;
  padding: 9px 14px;
  margin-bottom: 14px;
  font-size: 13px;
  font-weight: 600;
}

.section { margin-bottom: 28px; }
.section h2 {
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.section h2 .sub {
  font-size: 11px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-faint);
}
.hidden { display: none !important; }

.loading {
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--text-faint);
  font-size: 13px;
  padding: 14px 2px;
}
.spinner {
  width: 14px;
  height: 14px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  flex-shrink: 0;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 2.5s; }
}

.pulse-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--live);
  animation: pulse 1.5s infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(248, 81, 73, 0.6); }
  70% { box-shadow: 0 0 0 7px rgba(248, 81, 73, 0); }
  100% { box-shadow: 0 0 0 0 rgba(248, 81, 73, 0); }
}

/* ---------- live games ---------- */
.live-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
  gap: 10px;
}
.live-card {
  background: var(--bg-card);
  border: 1px solid var(--live);
  border-radius: 10px;
  padding: 12px 14px;
  box-shadow: 0 0 12px rgba(248, 81, 73, 0.15);
}
.live-card.pre {
  border-color: var(--soon);
  box-shadow: 0 0 12px rgba(227, 179, 65, 0.12);
}
.live-card .clock.soon { color: var(--soon); }
.soon-banner {
  background: rgba(227, 179, 65, 0.1);
  border-radius: 5px;
  padding: 3px 8px;
  margin-bottom: 7px;
  color: var(--soon);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-variant-numeric: tabular-nums;
}
.live-card .score.zero { color: var(--text-faint); }
.live-card.ft {
  border-color: var(--border);
  box-shadow: none;
}
.live-card .clock.ft {
  color: var(--win);
  font-size: 10.5px;
  letter-spacing: 0.06em;
}
.live-card .team-row.winner .score { color: var(--win); }
.live-card .team-row.loser { color: var(--text-dim); }
.live-card .team-row.loser .score { font-weight: 600; }
.live-card .match-meta {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--text-dim);
  margin-bottom: 8px;
}
.live-card .clock {
  color: var(--live);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.live-card .team-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 0;
  font-size: 16px;
  font-weight: 600;
}
.live-card .team-row .score {
  margin-left: auto;
  font-size: 20px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.no-live {
  color: var(--text-faint);
  font-size: 13px;
  padding: 10px 0;
}

.flag {
  width: 22px; height: 22px;
  object-fit: contain;
  flex-shrink: 0;
}
.flag.small { width: 17px; height: 17px; }

/* ---------- upcoming ---------- */
/* ---------- upcoming filters ---------- */
.filter-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.filter-bar select {
  background: var(--bg-card);
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 8px;
  font-size: 12.5px;
  font-family: inherit;
  cursor: pointer;
  max-width: 180px;
}
.filter-bar select:hover { border-color: var(--text-faint); }
.filter-bar select:has(option:checked:not([value=""])) {
  color: var(--accent);
  border-color: var(--accent);
}
.filter-clear {
  background: none;
  border: none;
  color: var(--text-faint);
  font-size: 12px;
  cursor: pointer;
  padding: 4px 6px;
}
.filter-clear:hover { color: var(--text); }

.day-header {
  font-size: 12px;
  font-weight: 700;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 14px 0 4px;
  padding-bottom: 3px;
  border-bottom: 1px solid var(--border);
}
.day-header:first-child { margin-top: 0; }

.up-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 10px;
  border-radius: 7px;
  border: 1px solid transparent;
  font-size: 13.5px;
}
.up-row:nth-child(even) { background: var(--zebra); }
.up-row.soon {
  background: rgba(227, 179, 65, 0.09);
  border-color: rgba(227, 179, 65, 0.45);
}
.up-row.mq1 { box-shadow: inset 3px 0 0 rgba(88, 166, 255, 0.55); }
.up-row.mq2 {
  box-shadow: inset 3px 0 0 rgba(88, 166, 255, 0.9);
  background: rgba(88, 166, 255, 0.06);
}
.up-row.mq2.soon { background: rgba(227, 179, 65, 0.09); }
.mstar {
  color: var(--mstar-dim);
  font-size: 11px;
  flex-shrink: 0;
}
.mstar.mq2 { color: var(--accent); }
.mstar[data-tip] { cursor: help; }
.up-row .kick {
  width: 62px;
  flex-shrink: 0;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  font-size: 12.5px;
  white-space: nowrap;
}
.up-row .countdown {
  width: 88px;
  flex-shrink: 0;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  font-size: 12.5px;
}
.up-row.soon .countdown { color: var(--soon); }
.up-row .matchup {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  min-width: 0;
  flex: 1 1 auto;
}
.up-row .matchup .vs { color: var(--text-faint); font-weight: 400; font-size: 11px; }
.up-row .matchup span.tname {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.up-row .tag {
  flex-shrink: 0;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--text-dim);
  background: var(--bg-card-2);
  border-radius: 4px;
  padding: 2px 6px;
  white-space: nowrap;
}
/* subtle per-group colour: a faint tint of the group's hue, just enough
   to differentiate at a glance without drawing the eye */
.up-row .tag.grp {
  background: color-mix(in srgb, var(--grp) 11%, var(--bg-card-2));
}
.up-row .extra {
  flex-shrink: 0;
  font-size: 11.5px;
  color: var(--text-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 30%;
}

/* ---------- goal details ---------- */
.goals {
  display: flex;
  flex-wrap: wrap;
  column-gap: 12px;
  row-gap: 2px;
  margin-top: 7px;
  font-size: 11px;
  color: var(--text-dim);
}
.goals.col { flex-direction: column; margin-top: 0; }
.goal-line { white-space: nowrap; }
.goal-line b {
  color: var(--text-faint);
  font-weight: 700;
  font-size: 10px;
}
.goals-pop {
  display: none;
  position: absolute;
  top: calc(100% + 3px);
  left: 0;
  min-width: 100%;
  z-index: 70;
  background: var(--bg-card-2);
  border: 1px solid var(--border);
  border-radius: 7px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
  padding: 7px 10px;
}
.result-card:hover .goals-pop,
.bracket-match:hover .goals-pop { display: block; }
.goals-pop .pop-meta {
  font-size: 10.5px;
  color: var(--text-faint);
  margin-bottom: 4px;
}
.goals-pop .pop-upset { color: var(--upset); font-weight: 700; }

/* ---------- booking chips ---------- */
.cards {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
  cursor: help;
}
.cards i {
  display: inline-block;
  width: 8px;
  height: 11px;
  border-radius: 2px;
}
.cards .yc { background: var(--yc); }
.cards .rc { background: var(--live); }
.cards b {
  font-size: 10px;
  font-weight: 700;
  color: var(--text-dim);
  margin-right: 2px;
}

/* ---------- win probability bars ---------- */
.prob {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  width: 156px;
}
.pbar {
  display: inline-flex;
  width: 70px;
  height: 6px;
  border-radius: 3px;
  overflow: hidden;
  background: var(--bg-card-2);
  flex-shrink: 0;
}
.pbar.wide { flex: 1 1 auto; width: auto; min-width: 0; height: 7px; }
.pbar i { display: block; height: 100%; }
.pbar .pa { background: var(--pa); }
.pbar .pd { background: var(--pd); }
.pbar .ph { background: var(--ph); }
.pfav {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.live-prob {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}
.live-prob .plab {
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.live-prob .pa-t { color: var(--pa); }
.live-prob .ph-t { color: var(--ph); }
/* the whole odds component (and any .has-tip element) is a tooltip target */
.prob, .live-prob, .has-tip { position: relative; cursor: help; }
.has-tip { white-space: nowrap; }
.psrc {
  font-size: 9px;
  font-weight: 700;
  font-style: normal;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  flex-shrink: 0;
}
.prob:hover .psrc,
.live-prob:hover .psrc { color: var(--text-dim); }
.ptip {
  visibility: hidden;
  opacity: 0;
  /* keep the tooltip alive briefly after mouseout so an imperfect
     path into it can recover (it stays hoverable during the delay) */
  transition: opacity 0.12s ease, visibility 0s linear 0.4s;
  position: absolute;
  bottom: 100%;
  right: -4px;
  z-index: 60;
  background: var(--bg-card-2);
  border: 1px solid var(--border);
  border-radius: 7px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
  padding: 7px 10px;
  white-space: nowrap;
  font-size: 11px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-dim);
  line-height: 1.6;
}
.prob:hover .ptip,
.live-prob:hover .ptip,
.has-tip:hover .ptip,
.ptip:hover {
  visibility: visible;
  opacity: 1;
  transition-delay: 0s;
}
/* invisible bridge below the tooltip so diagonal mouse paths stay inside */
.ptip::after {
  content: "";
  position: absolute;
  top: 100%;
  left: -14px;
  right: -14px;
  height: 18px;
}
.ptip b { color: var(--text); font-weight: 700; }
.ptip a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}
.ptip a:hover { text-decoration: underline; }

.show-more {
  margin-top: 8px;
  background: var(--bg-card);
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 14px;
  font-size: 12.5px;
  cursor: pointer;
}
.show-more:hover { color: var(--text); border-color: var(--text-faint); }

/* ---------- results ---------- */
.results-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 6px;
}

/* ---------- top scorers ---------- */
.scorers-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 6px;
}
.scorer-row {
  display: flex;
  align-items: baseline; /* all text sits on the same baseline */
  gap: 8px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 6px 10px;
  font-size: 13px;
}
/* baseline alignment seats the flag's bottom on the text baseline, ~4px above
   the text's visual bottom (the font descent) — nudge it down to match */
.scorer-row .flag.small {
  position: relative;
  top: 4px;
}
.scorer-row .rank {
  width: 16px;
  text-align: right;
  color: var(--text-faint);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.scorer-row .goals {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--win);
  min-width: 12px;
  text-align: right;
}
.scorer-row .sname {
  font-weight: 600;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.result-card {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 6px 10px;
  font-size: 13px;
  position: relative;
}
.result-card.upset { border-color: var(--upset); }
.upset-pill {
  position: absolute;
  top: -8px;
  right: 8px;
  background: var(--bg);
  border: 1px solid var(--upset);
  border-radius: 5px;
  color: var(--upset);
  font-size: 8.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  padding: 1px 6px;
  line-height: 1.4;
}
.bm-upset { color: var(--upset); font-weight: 800; }
.result-card .res-team {
  display: flex;
  align-items: center;
  gap: 5px;
  font-weight: 600;
  flex: 1;
  min-width: 0;
}
.result-card .res-team span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.result-card .res-team.right { justify-content: flex-end; }
.result-card .res-score {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  padding: 1px 7px;
  background: var(--bg-card-2);
  border-radius: 5px;
}
.result-card .res-team.loser { color: var(--text-dim); font-weight: 500; }

/* ---------- groups ---------- */
.groups-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(255px, 1fr));
  gap: 10px;
}
.group-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 9px;
  overflow: hidden;
}
.group-card h3 {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-size: 12.5px;
  padding: 6px 10px;
  background: var(--bg-card-2);
  color: var(--accent);
  letter-spacing: 0.04em;
}
.group-card h3 .gavg {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text-faint);
}
.group-card table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.group-card th {
  font-size: 10px;
  color: var(--text-faint);
  font-weight: 600;
  text-align: center;
  padding: 3px 2px;
}
.group-card th.tcol { text-align: left; padding-left: 10px; }
.group-card td {
  padding: 4px 2px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  border-top: 1px solid var(--table-line);
}
.group-card td.tcol {
  text-align: left;
  padding-left: 10px;
  color: var(--text);
  font-weight: 600;
}
.group-card td.tcol .cell {
  display: flex;
  align-items: center;
  gap: 6px;
}
.group-card .frank {
  font-size: 8.5px;
  font-weight: 600;
  color: var(--text-faint);
  margin-left: 3px;
  cursor: help;
}
.group-card td.pts { color: var(--text); font-weight: 700; }
.group-card tr.adv td.tcol { box-shadow: inset 3px 0 0 var(--advance); }
.group-card tr.third td.tcol { box-shadow: inset 3px 0 0 var(--third); }

/* ---------- 3rd-place race ---------- */
.thirds-table {
  width: 100%;
  max-width: 560px;
  border-collapse: collapse;
  font-size: 13px;
}
.thirds-table th {
  font-size: 10px;
  color: var(--text-faint);
  font-weight: 600;
  text-align: center;
  padding: 4px 3px;
}
.thirds-table th.rk, .thirds-table th.tcol { text-align: left; }
.thirds-table td {
  padding: 5px 3px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  border-top: 1px solid var(--table-line);
}
.thirds-table td.rk { color: var(--text-faint); width: 1.6em; text-align: left; }
.thirds-table td.tcol { text-align: left; color: var(--text); font-weight: 600; }
.thirds-table td.tcol .cell { display: flex; align-items: center; gap: 6px; }
.thirds-table .frank {
  font-size: 8.5px; font-weight: 600; color: var(--text-faint); margin-left: 3px; cursor: help;
}
.thirds-table td.pts { color: var(--text); font-weight: 700; }
.thirds-table tr.adv td.tcol { box-shadow: inset 3px 0 0 var(--advance); }
.thirds-table tr.out td { color: var(--text-faint); }
.thirds-table tr.out td.tcol { color: var(--text-dim); box-shadow: inset 3px 0 0 var(--border); }
.thirds-table tr.cut td { border-bottom: 2px solid var(--accent); }
.thirds-note {
  color: var(--text-dim);
  font-size: 11px;
  line-height: 1.5;
  margin-top: 8px;
  max-width: 560px;
}

/* ---------- bracket ---------- */
.bracket-scroll { overflow-x: auto; padding-bottom: 8px; }
.bracket {
  display: flex;
  gap: 18px;
  min-width: max-content;
  align-items: stretch;
}
.round-col {
  display: flex;
  flex-direction: column;
  width: 210px;
  flex-shrink: 0;
}
.round-col h3 {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  text-align: center;
  margin-bottom: 8px;
}
.round-col .matches {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  flex: 1;
  gap: 8px;
}
.bracket-match {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 9px;
  font-size: 12.5px;
  position: relative;
}
.bracket-match.live {
  border-color: var(--live);
  box-shadow: 0 0 10px rgba(248, 81, 73, 0.15);
}
.bracket-match.soon { border-color: rgba(227, 179, 65, 0.55); }
.bracket-match .bm-meta {
  font-size: 10px;
  color: var(--text-faint);
  display: flex;
  justify-content: space-between;
  gap: 4px; /* keep the location and date/time from touching on narrow cards */
  margin-bottom: 3px;
}
.bracket-match .bm-meta .bm-live { color: var(--live); font-weight: 700; }
.bracket-match .bm-team {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 2px 0;
  font-weight: 600;
}
.bracket-match .bm-team .bm-score {
  margin-left: auto;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* keep multi-word team names (e.g. "South Korea") on one line, truncating with
   an ellipsis rather than wrapping in the narrow cards */
.bracket-match .bm-team > span:first-of-type {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.bracket-match .bm-team.placeholder { color: var(--text-faint); font-weight: 500; }
.bracket-match .bm-team.projected { color: var(--text); font-weight: 600; }
.bracket-match .bm-team.projected .bm-proj-cap {
  color: var(--text-faint);
  font-weight: 500;
  font-size: 10px;
}
.bracket-match .bm-team.projected .bm-proj-pct {
  margin-left: auto;
  color: var(--accent);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* "as it stands" fill: a deterministic current-standings occupant, with a
   lock badge (and green emphasis) for teams that have already qualified */
.bracket-match .bm-team.asit .bm-asit-tag {
  margin-left: auto;
  font-size: 11px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.bracket-match .bm-team.asit.locked { color: var(--win); }
.bracket-match .bm-team.asit.locked .bm-proj-name { font-weight: 700; }
.bracket-match .bm-team.asit.locked .bm-asit-tag { color: var(--win); }
.bracket-match .bm-team.loser { color: var(--text-dim); font-weight: 500; }
.bracket-match .bm-team.winner .bm-score { color: var(--win); }
.bracket-match .bm-winner {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  padding-top: 5px;
  border-top: 1px solid var(--table-line);
  font-weight: 700;
  color: var(--win);
}
.bracket-match .bm-winner .bm-win-pct {
  margin-left: auto;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
/* body-mounted tooltip targets: projected bracket probabilities and matchup stars */
.bracket-match [data-tip],
.mstar[data-tip] {
  cursor: help;
}
.tap-tip {
  position: absolute;
  z-index: 100;
  width: max-content;
  max-width: min(230px, calc(100vw - 16px));
  background: var(--bg-card-2);
  border: 1px solid var(--border);
  border-radius: 7px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
  padding: 7px 10px;
  font-size: 11px;
  font-weight: 400;
  line-height: 1.5;
  white-space: pre-line;   /* honor "\n" so multi-card lists show one per line */
  overflow-wrap: break-word;
  color: var(--text-dim);
  pointer-events: none;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* ---------- footer ---------- */
footer {
  text-align: center;
  font-size: 11.5px;
  color: var(--text-faint);
  padding: 14px;
  border-top: 1px solid var(--border);
}
.error-note { color: var(--live); margin-left: 8px; }
footer a {
  color: var(--text-dim);
  text-decoration: none;
}
footer a:hover { color: var(--accent); text-decoration: underline; }

/* ---------- responsive ---------- */
/* TV listings are the lowest-priority metadata — drop them first, before
   the full mobile reflow kicks in */
@media (max-width: 900px) {
  .up-row .extra .tv { display: none; }
}

/* header status is lower priority than the theme picker, which must always
   stay on the nav's line. Drop the "updated at" time first, then the live
   badge, before either can push the theme picker to a new line. */
@media (max-width: 820px) {
  #last-updated { display: none; }
}
@media (max-width: 700px) {
  #live-count { display: none; }
}

@media (max-width: 640px) {
  body { font-size: 13px; }
  .topbar-inner { padding: 6px 10px; gap: 8px; }
  .topbar h1 { font-size: 15px; }
  .status { display: none; }
  /* wrapped nav row: tabs at the left edge, theme picker at the right */
  .tabs { margin-left: 0; }
  .theme-wrap { margin-left: auto; }
  .notify-toggle { min-width: 32px; width: 32px; padding-inline: 4px; }
  .notify-label { display: none; }
  /* section-header metadata gets its own line instead of wrapping mid-text */
  .section h2 { flex-wrap: wrap; row-gap: 0; }
  .section h2 .sub { flex-basis: 100%; margin-top: 0; }
  .tabs a { padding: 4px 7px; font-size: 12px; }
  main { padding: 10px 10px 30px; }
  /* deterministic two-line layout: teams + win prob on line 1, the rest
     of the metadata (time, countdown, location, group) on line 2 */
  .up-row {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    grid-template-areas:
      "matchup matchup matchup prob"
      "kick countdown extra tag";
    column-gap: 8px;
    row-gap: 4px;
    padding: 6px 8px;
  }
  /* venue sits beside the time/countdown; TV listings stay desktop-only */
  .up-row .extra {
    display: block;
    grid-area: extra;
    min-width: 0;
    max-width: none;
    justify-self: stretch;
    font-size: 11.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* venue shows "City, State"; it ellipsizes if it can't fit the cell */
  .up-row .extra .tv { display: none; }
  .up-row .kick { grid-area: kick; width: auto; font-size: 11.5px; }
  .up-row .countdown { grid-area: countdown; width: auto; font-size: 11.5px; }
  /* a countdown is only meaningful for games today/tomorrow on mobile */
  .up-row:not(.near) .countdown { display: none; }
  /* the hidden countdown's empty column leaves a gap on both sides, so pull
     the location back by one gap to match the time→countdown spacing */
  .up-row:not(.near) .extra { margin-left: -8px; }
  /* set the "soon" game off from the next row */
  .up-row.soon { margin-bottom: 2px; }
  .up-row .matchup { grid-area: matchup; }
  .up-row .prob { grid-area: prob; width: auto; justify-self: end; min-width: 0; gap: 4px; }
  /* compact bar so the win prob doesn't crowd the team names on line 1 */
  .up-row .prob .pbar { width: 40px; }
  .up-row .prob .psrc { display: none; }
  .up-row .tag { grid-area: tag; justify-self: end; }
  /* keep the filter controls on one line: share the row equally and let
     the selects ellipsize their labels */
  .filter-bar { flex-wrap: nowrap; gap: 6px; }
  .filter-bar select {
    flex: 1 1 0;
    min-width: 0;
    max-width: none;
    font-size: 11.5px;
    padding: 4px 3px;
  }
  .filter-clear { font-size: 0; padding: 4px 2px; flex-shrink: 0; }
  .filter-clear::after { content: "✕"; font-size: 14px; }
  /* tight to content now that column-gap handles spacing */
  .up-row .countdown { width: auto; }
  .live-grid { grid-template-columns: 1fr; }
  .round-col { width: 185px; }
}

/* below 500px the header is two rows: the title + the notification bell (top
   right) on the first, the nav and theme picker on the second. The title's
   flex-basis leaves just enough room for the bell so the nav wraps below. */
@media (max-width: 500px) {
  .topbar h1 { order: 1; flex: 0 1 calc(100% - 48px); }
  .notify-wrap { order: 2; margin-left: auto; }   /* top-right of the first row */
  .tabs { order: 3; margin-left: 0; }
  .theme-wrap { order: 4; }   /* margin-left:auto (from ≤640) keeps it right on row 2 */
}

/* ---- Monte Carlo simulation notice + panel ---- */
.sim-notice {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 12px;
  font-size: 0.78rem;
  color: var(--notice);
}
.sim-notice.hidden { display: none; }
.sim-notice a { color: var(--notice); font-weight: 600; text-decoration: underline; }
.sim-notice-x {
  flex: none;
  background: transparent;
  border: none;
  color: var(--notice);
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  /* bigger tap target so it isn't fiddly on iOS */
  padding: 6px 10px;
  margin: -4px 0;
}
.sim-notice-x:hover { color: var(--text); }

.sim-panel {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  margin-bottom: 18px;
}
.sim-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.sim-run {
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  border-radius: 7px;
  padding: 8px 14px;
  font-size: 0.92rem;
  font-weight: 600;
  cursor: pointer;
}
.sim-run:hover { filter: brightness(1.08); }
.sim-run:disabled { opacity: 0.6; cursor: progress; }
.sim-clear {
  background: transparent;
  color: var(--text-dim);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 7px 12px;
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
}
.sim-clear:hover { color: var(--text); border-color: var(--text-dim); }
.sim-clear.hidden { display: none; }
/* the bracket header carries the As-it-stands toggle alongside the title (it's
   independent of the Simulate action below); on mobile the toggle wraps to its
   own line under the title */
.bracket-head {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 14px;
  margin-bottom: 4px;
}
.bracket-head h2 { margin-bottom: 0; min-width: 0; }
/* the As-it-stands description, a subtitle under the bracket header (the
   simulate status line is separate, inside the Simulate button container) */
.bracket-sub { color: var(--text-dim); font-size: 0.85rem; margin: 0 0 12px; }

/* a switch, not a button — it toggles the bracket view rather than running an
   action like the Simulate button below */
.asit-toggle {
  display: inline-flex;
  align-items: center;
  flex: none;
  gap: 8px;
  background: transparent;
  border: none;
  padding: 6px 2px;
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
  color: var(--text-dim);
  cursor: pointer;
}
.asit-toggle:hover { color: var(--text); }
.asit-toggle .asit-switch {
  position: relative;
  flex: none;
  width: 36px;
  height: 20px;
  border-radius: 10px;
  background: var(--border);
  transition: background 0.15s ease;
}
.asit-toggle .asit-switch::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
  transition: transform 0.15s ease;
}
.asit-toggle.active { color: var(--text); }
.asit-toggle.active .asit-switch { background: var(--accent); }
.asit-toggle.active .asit-switch::after { transform: translateX(16px); }
.asit-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
.sim-status { color: var(--text-dim); font-size: 0.85rem; }
.sim-results { margin-top: 18px; }
.sim-results.hidden { display: none; }
.sim-h3 {
  font-size: 0.95rem;
  margin: 16px 0 8px;
}
.sim-h3:first-child { margin-top: 4px; }
.sim-sub { color: var(--text-dim); font-weight: 400; font-size: 0.78rem; margin-left: 6px; }

.sim-table-scroll { overflow-x: auto; }
.sim-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.86rem;
}
.sim-table th, .sim-table td {
  padding: 5px 8px;
  text-align: right;
  border-bottom: 1px solid var(--table-line);
  white-space: nowrap;
}
.sim-table th { color: var(--text-dim); font-weight: 600; }
.sim-table th[data-sort] { cursor: pointer; user-select: none; }
.sim-table th[data-sort]:hover { color: var(--text); }
.sim-table th.sim-sorted { color: var(--text); }
.sim-table th .sim-arrow { font-size: 0.72em; margin-left: 2px; }
.sim-table th.sim-team, .sim-table td.sim-team { text-align: left; }
.sim-team { display: flex; align-items: center; gap: 7px; }
.sim-champ { color: var(--win); font-weight: 700; }

.sim-note { color: var(--text-dim); font-size: 0.76rem; line-height: 1.5; margin-top: 14px; }
