:root {
  --fg: #111;
  --bg: #fff;
  --dim: #9a9a9a;
  --line: #111;
}
* { box-sizing: border-box; }
body {
  font-family: 'Space Mono', ui-monospace, Menlo, Consolas, monospace;
  color: var(--fg);
  background: var(--bg);
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  padding-bottom: 44px;   /* room for the fixed footer */
}
header {
  border-bottom: 3px solid var(--line);
  padding: 16px 22px;
  position: sticky;
  top: 0;
  background: var(--bg);
  z-index: 10;
}
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 24px; }
header h1 { margin: 0; font-size: 18px; letter-spacing: 1px; }
nav { white-space: nowrap; }
nav button {
  font-family: inherit; font-size: 12px; font-weight: 700;
  background: var(--bg); color: var(--fg); border: 2px solid var(--fg);
  padding: 5px 14px; margin-left: 8px; cursor: pointer; letter-spacing: 1px;
}
nav button.active { background: var(--fg); color: var(--bg); }
#meta { color: var(--dim); }
main { padding: 22px; }

/* live banner (sits in the header so it doesn't push content down) */
#livebar { display: flex; gap: 8px; flex-wrap: wrap; }
.livegame { font-family: inherit; font-size: 12px; font-weight: 700; letter-spacing: .5px; cursor: pointer;
  background: var(--bg); color: var(--fg); border: 2px solid var(--fg); padding: 4px 12px;
  display: inline-flex; align-items: center; gap: 6px; }
.livegame .livedot { color: #e0202a; animation: livepulse 1.4s ease-in-out infinite; }
.livegame .livesc { padding: 0 2px; }
.livegame .livemin { color: var(--dim); font-weight: 400; margin-left: 4px; }
.livegame.done { color: #888; border-color: #aaa; }
.livegame.done .livesc { color: #888; }
@keyframes livepulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

/* live popup */
.mpop.live { min-width: 260px; }
.mpop.live .livescore { font-size: 18px; font-weight: 700; text-align: center; margin: 4px 0 8px; }
.mpop .matches { margin-top: 6px; }
.mpop.live .livestats { border-collapse: collapse; width: 100%; font-size: 12px; margin-top: 8px; border-top: 1px solid var(--line); padding-top: 4px; }
.mpop.live .livestats td { padding: 2px 8px; }
.mpop.live .livestats .lsh { text-align: right; font-weight: 700; }
.mpop.live .livestats .lsl { text-align: center; color: var(--dim); font-size: 10px; letter-spacing: 1px; }
.mpop.live .livestats .lsa { text-align: left; font-weight: 700; }
.mpop.live .lsnone { color: var(--dim); font-size: 11px; text-align: center; }
.mpop .matches .bk.pending { color: #444; }   /* unplayed predictions in popups: darker, more legible */

/* intro / methodology */
/* width:0 + min-width:100% -> the intro fills the pane width (set by the groups)
   without its own long lines widening the pane; runs flush to the divider */
.intro { width: 0; min-width: 100%; box-sizing: border-box; margin: 0 0 14px; color: #333; }
.intro p { margin: 0 0 8px; }
.intro b { color: var(--fg); }
.intro code { background: #f0f0f0; padding: 0 4px; }
.intro .sw { padding: 0 6px; color: #111; font-weight: 700; }

/* two panes: groups (left) | interactive bracket (right) */
.cols { display: flex; gap: 0; align-items: flex-start; }
.groups-pane { flex: 0 0 auto; }   /* natural width on desktop -> no scrollbar (bracket scrolls on its own) */
/* divider line is the bracket pane's left border, so it spans the bracket's height
   only (it won't extend into empty space when an opened group makes the left taller) */
/* collapsed: keep the matches (score + win %), just hide the pred xG ± std columns.
   drop the two xG tracks so the remaining 5 cells stay aligned (home % score % away) */
.cols.lean .matches { grid-template-columns: max-content max-content 7ch max-content max-content; }
.cols.lean .matches .xg { display: none; }

/* groups: each group = standings (left) | matches (right), split by a divider */
.grid { display: flex; flex-direction: column; gap: 16px; }
.group { width: max-content; }
.group h2 { width: 100%; box-sizing: border-box; font-size: 14px; border-bottom: 2px solid var(--fg); padding-bottom: 4px; letter-spacing: 1px; margin: 0 0 12px; cursor: pointer; user-select: none; }
.group h2::before { content: "▾ "; }
.group.collapsed h2::before { content: "▸ "; }
.group.collapsed h2 { margin-bottom: 0; }
.gbody { display: flex; align-items: start; }
.group.collapsed .gbody { height: 0; overflow: hidden; }
.standings-side { padding: 4px 26px 4px 0; }
.matches-side { border-left: 2px solid var(--fg); padding: 4px 0 4px 26px; }

table.standings { border-collapse: collapse; font-size: 12px; }
table.standings td { padding: 1px 0; }
table.standings td.num { color: var(--dim); }
table.standings td.rank { padding-right: 8px; }
table.standings td.tm { font-weight: 700; padding-right: 6px; white-space: pre; }
table.standings td.r { text-align: right; padding-left: 10px; }
table.standings tr.hd td { color: var(--dim); font-size: 11px; font-weight: 400; border-bottom: 1px solid #ddd; padding-bottom: 2px; }
.chip { padding: 0 6px; color: #111; }

/* match rows: ONE shared grid (rows are display:contents) so columns align */
.matches {
  display: grid;
  grid-template-columns: max-content max-content max-content 7ch max-content max-content max-content;
  align-items: center;
  row-gap: 1px;
  white-space: nowrap;
}
.matches .row { display: contents; }
.matches .home { text-align: right; padding-right: 8px; }
.matches .away { text-align: left; padding-left: 8px; }
.matches .score { text-align: center; font-weight: 700; }
.matches .score.pending { color: var(--dim); font-weight: 400; }
.matches .lbl { color: var(--dim); font-size: 10px; text-align: center; }
.matches .xg, .matches .pr { text-align: center; }
.tm { font-weight: 700; }
.tm.lose { color: var(--dim); font-weight: 400; }
.bk { white-space: pre; padding: 1px 5px; }
.bk.pending { color: var(--dim); }

/* ===== interactive bracket (right pane) ===== */
.bpane { flex: 1 1 auto; min-width: 0; border-left: 2px solid var(--fg); margin-left: 30px; padding-left: 30px; }
.bpane-head { font-weight: 700; letter-spacing: 1px; border-bottom: 2px solid var(--fg); padding-bottom: 6px; margin-bottom: 14px; display: flex; align-items: center; gap: 10px; }
.bpane-head .hint { font-weight: 400; color: var(--dim); letter-spacing: 0; }
.bpane-head .reset { margin-left: auto; font-family: inherit; font-size: 11px; border: 1px solid var(--fg); background: var(--bg); padding: 3px 10px; cursor: pointer; }
.bpane-body { padding-bottom: 8px; }
/* boxes stay fixed above; the (large) bracket scrolls inside here */
.bscroll { overflow: auto; max-height: 78vh; border: 1px solid #eee; }

/* the three draggable seed boxes — one row */
.seedboxes { display: flex; gap: 14px; margin-bottom: 18px; flex-wrap: nowrap; align-items: flex-start; }
.seedbox { border: 1px solid #ccc; padding: 5px 7px; }
.seedbox h4 { margin: 0 0 4px; font-size: 9px; letter-spacing: 1px; color: var(--dim); font-weight: 700; }
.seeds { display: flex; flex-wrap: wrap; gap: 3px; max-width: 240px; }
.seed { border: 1px solid #bbb; padding: 0 4px; font-size: 10px; cursor: grab; white-space: nowrap; user-select: none; }
.seed:active { cursor: grabbing; }
.seed.sel { outline: 2px solid #1a7a3a; outline-offset: 1px; }   /* tap-selected (mobile) */

/* ===== symmetric bracket with elbow connectors ===== */
.ibracket { display: flex; gap: 18px; align-items: stretch; height: 560px; padding-top: 18px; box-sizing: border-box; width: max-content; }
.col { display: flex; flex-direction: column; height: 100%; }
.cells { flex: 1; display: flex; flex-direction: column; }
.cell { flex: 1; display: flex; align-items: center; position: relative; }
/* stage label sits just above its match card; left half is right-justified */
.mlabel { position: absolute; bottom: 100%; left: 0; padding-bottom: 3px; font-size: 9px; letter-spacing: 1px; color: var(--dim); font-weight: 700; white-space: nowrap; }
.lcol .mlabel { left: auto; right: 0; text-align: right; }

/* elbow connector: ] (left half) / [ (right half) in the inter-column gap; arms
   land on the two feeders' centres (25%/75%), bus touches this card's centre. */
.conn { position: absolute; top: 25%; height: 50%; width: 18px; border: 1px solid #bbb; pointer-events: none; }
.conn.cl { right: 100%; border-left: none; }
.conn.cr { left: 100%; border-right: none; }

/* centre: Final (vertically centred, lines out to both semis) + Third place below */
.col.center { position: relative; }
.col.center .cells { justify-content: center; }
.finalcard { position: relative; }
.finalcard::before, .finalcard::after { content: ''; position: absolute; top: 50%; width: 18px; border-top: 1px solid #bbb; }
.finalcard::before { right: 100%; }
.finalcard::after { left: 100%; }
.thirdwrap { position: absolute; top: calc(50% + 50px); left: 0; right: 0; }

/* model-performance heatmap (under the bracket) */
.perf { margin-top: 30px; }
.perf-head { font-weight: 700; letter-spacing: 1px; border-bottom: 2px solid var(--fg); padding-bottom: 6px; margin-bottom: 16px; display: flex; align-items: baseline; gap: 12px; }
.perf-metrics { font-weight: 400; color: var(--dim); letter-spacing: 0; font-size: 11px; }
.perf-grid { display: flex; gap: 18px; align-items: flex-start; }
.perf-heat { display: flex; gap: 18px; align-items: flex-start; overflow-x: auto; padding-bottom: 6px; }
.perf-stage { display: flex; flex-direction: column; gap: 6px; }
.perf-label { font-size: 9px; letter-spacing: 1px; color: var(--dim); font-weight: 700; white-space: nowrap; }
.perf-cols { display: flex; gap: 3px; align-items: flex-start; }
.perf-col { display: flex; flex-direction: column; gap: 3px; }
.perf-cell { width: 12px; height: 12px; border-radius: 2px; background: #ebedf0; }
.perf-cell[data-key] { cursor: pointer; }
.perf-cell[data-key]:hover { outline: 1px solid #777; outline-offset: 1px; }

/* over/underperformance box — grows to fill the space right of the heatmap */
.perf-form { margin-left: 18px; flex: 1 1 auto; min-width: 200px; }
.perf-form .seedbox { border: none; padding: 0; }   /* no outline -> title aligns with the stage labels */
.perf-form .seeds { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 4px; max-width: none; }
.perf-form .seed { text-align: center; min-width: 0; border: none; }

/* match-card popup (click a heatmap cell) */
.mpop { position: absolute; z-index: 50; background: var(--bg); border: 2px solid var(--fg); padding: 9px 11px; box-shadow: 3px 3px 0 rgba(0,0,0,.18); white-space: nowrap; }
.mpop-hd { font-weight: 700; font-size: 11px; letter-spacing: .5px; margin-bottom: 7px; }
.mpop-row { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.mpop .mtm { font-weight: 700; }
.mpop .mscore { font-weight: 700; padding: 0 4px; }

/* condensed match card: tight padding, smaller font for the xG/% values */
.bmatch2 { width: 100%; border: 1px solid #ccc; background: var(--bg); white-space: nowrap; position: relative; z-index: 1; box-sizing: border-box; }
.brow { display: grid; grid-template-columns: 3ch 1ch max-content max-content; gap: 3px; align-items: center; padding: 1px 4px; font-size: 10px; background: var(--tc, transparent); }
.brow + .brow { border-top: 1px solid #eee; }
.brow .bt { font-weight: 700; }
.brow.lose .bt { color: var(--dim); font-weight: 400; }
.brow .bsc { color: var(--dim); text-align: center; }
.brow .bx { color: #555; font-size: 8px; }
.brow.lose .bx { color: #aaa; }
.brow .bp { color: var(--dim); text-align: right; font-size: 8px; }
.brow[data-m] { cursor: grab; }
.brow.legal { background: #eef7ee; box-shadow: inset 0 0 0 1px #9c9; }
.brow.over { background: #d7efd7; }

/* bracket — dark */
body.dark { background: #121212; color: #e8e8e8; }
body.dark header, body.dark footer { background: #121212; border-color: #e8e8e8; }
body.dark nav button { background: #121212; color: #e8e8e8; border-color: #e8e8e8; }
body.dark nav button.active { background: #e8e8e8; color: #121212; }
body.dark #meta { color: #888; }
.bracket { display: flex; gap: 22px; overflow-x: auto; padding-bottom: 10px; }
.rnd { min-width: 230px; }
.rnd h2 { font-size: 13px; border-bottom: 2px solid currentColor; letter-spacing: 1px; margin: 0 0 8px; }
.bmatch { border: 1px solid #444; padding: 6px 8px; margin: 8px 0; font-size: 12px; white-space: nowrap; display: flex; gap: 6px; justify-content: space-between; }
.bmatch .tm { font-weight: 700; }
.bmatch .tm.win { background: #e8e8e8; color: #121212; padding: 0 4px; }
.bmatch .tm.lose { color: #777; font-weight: 400; }
.bmatch .lam { color: #777; }
.champion { font-size: 22px; font-weight: 700; margin: 24px 0 0; }

footer { position: fixed; bottom: 0; left: 0; right: 0; background: var(--bg); border-top: 3px solid var(--line); padding: 10px 22px; color: var(--dim); font-size: 11px; z-index: 10; }
footer a { color: var(--dim); }
body.dark footer a { color: #aaa; }

/* ===== mobile: stack groups on top, bracket below ===== */
@media (max-width: 820px) {
  main { padding: 14px; }
  .cols { flex-direction: column; align-items: stretch; }
  .groups-pane { width: 100%; }
  /* stacked: drop the left border/spacing, separate with a top border instead */
  .bpane { border-left: none; margin-left: 0; padding-left: 0; margin-top: 22px; padding-top: 18px; border-top: 2px solid var(--fg); }
  .seedboxes { flex-wrap: wrap; }             /* let the three boxes wrap on narrow screens */
  header { padding: 12px 14px; }
  footer { padding: 6px 12px; font-size: 9px; line-height: 1.35; }
  /* live banner: full-width swipe carousel (LIVE first) instead of wrapping/stacking */
  .topbar { flex-direction: column; align-items: stretch; gap: 8px; }
  #livebar { flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; }
  .livegame { flex: 0 0 auto; scroll-snap-align: start; }
  /* group card: stack matches UNDER the standings (no left-right swipe) */
  .gbody { flex-direction: column; }
  .standings-side { padding: 4px 0 12px; }
  .matches-side { border-left: none; border-top: 2px solid var(--fg); padding: 12px 0 4px; }
  /* match-card popup: pin to bottom-centre + scale so it always fits the screen */
  .mpop { position: fixed; left: 50% !important; right: auto; top: auto !important; bottom: 16px; transform: translateX(-50%); max-width: 94vw; }
  .mpop-row { font-size: 10px; }
  .mpop-hd { white-space: normal; }
  /* popups: condense so the prediction row (+ stats) fit inside the box */
  .mpop.live { min-width: 0; max-width: 94vw; }
  .mpop .matches { font-size: clamp(8px, 2.7vw, 12px); }
  .mpop .matches .bk { padding: 1px 3px; }
  .mpop.live .livestats { font-size: clamp(9px, 2.7vw, 12px); }
  .mpop.live .livestats td { padding: 2px 4px; }
  /* model performance: drop the FORM vs MODEL box below the heatmap, 6 across */
  .perf-grid { flex-direction: column; }
  .perf-form { margin-left: 0; margin-top: 18px; }
  .perf-form .seeds { grid-template-columns: repeat(6, 1fr); }
  /* scale the group tables to the viewport so they fill the width without overflow */
  table.standings { font-size: clamp(10px, 2.9vw, 12px); }
  .matches { font-size: clamp(8px, 2.9vw, 12px); }
  .matches .bk { padding: 1px 3px; }
  .matches .home { padding-right: 5px; }
  .matches .away { padding-left: 5px; }
  .matches .lbl { font-size: 8px; }
  .bpane-head { flex-wrap: wrap; }
}
