/* ——— broadcast-scoreboard minimalism ———
   One typeface (Archivo variable), one accent (signal red, liveness only),
   hairline rules instead of cards. Designed on a fixed 1920×1080 stage,
   scaled proportionally to the actual viewport. */

@font-face {
  font-family: 'Archivo';
  src: url('/fonts/archivo.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: block;
}

/* Warm-paper light theme is the default. */
:root,
:root[data-theme='light'] {
  --bg: #f3f1ec;
  --fg: #131210;
  --fg-dim: rgba(19, 18, 16, 0.64);
  --fg-faint: rgba(19, 18, 16, 0.42);
  --hairline: rgba(19, 18, 16, 0.30);
  --hairline-strong: rgba(19, 18, 16, 0.56);
  --accent: #d23a1f;
  --stage-glow: #ffffff;
  --wire: rgba(19, 18, 16, 0.46);
  --wire-dim: rgba(19, 18, 16, 0.12);
  --qualified-bg: rgba(19, 18, 16, 0.06);
  --card-bg: rgba(19, 18, 16, 0.05);
  --overlay-dim: rgba(19, 18, 16, 0.38);
  --booking: #cf9f00; /* yellow-card glyphs — the one non-accent color, semantic */
}

/* Dark theme (user toggle, and forced for night mode). Higher-contrast than the
   first pass: secondary text and hairlines were too faint to read across a
   room, so the dim/faint/hairline tones are all stronger here. */
:root[data-theme='dark'] {
  --bg: #08090a;
  --fg: #f8f7f4;
  --fg-dim: rgba(248, 247, 244, 0.66);
  --fg-faint: rgba(248, 247, 244, 0.40);
  --hairline: rgba(248, 247, 244, 0.28);
  --hairline-strong: rgba(248, 247, 244, 0.56);
  --accent: #f4502f;
  --stage-glow: #14171c;
  --wire: rgba(248, 247, 244, 0.44);
  --wire-dim: rgba(248, 247, 244, 0.10);
  --qualified-bg: rgba(248, 247, 244, 0.07);
  --card-bg: rgba(248, 247, 244, 0.06);
  --overlay-dim: rgba(0, 0, 0, 0.58);
  --booking: #f2c94c;
}

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

html,
body,
#root {
  height: 100%;
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: 'Archivo', 'Helvetica Neue', sans-serif;
  font-variant-numeric: tabular-nums;
  overflow: hidden;
}

/* fixed 1920×1080 stage, scaled to viewport via inline transform */
.viewport {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.stage {
  /* width/height set inline (fill the viewport, uniform scale — see useStageSize) */
  /* the transform makes this the containing block for absolute descendants
     (the match overlay relies on it); position:relative documents that role */
  position: relative;
  flex: none;
  display: flex;
  flex-direction: column;
  padding: 0 56px 40px;
  /* barely-there depth: a wide vignette, no flat black slab */
  background: radial-gradient(120% 90% at 50% 0%, var(--stage-glow) 0%, var(--bg) 58%);
}

/* maker's mark, just under the footer strip's top rule, right-aligned */
.credit {
  position: absolute;
  right: 0;
  top: 5px;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--fg-faint);
}

.connecting {
  height: 100%;
  display: grid;
  place-items: center;
  color: var(--fg-faint);
  font-size: 22px;
  letter-spacing: 0.4em;
  text-transform: uppercase;
}

/* ——— header ——— */

/* date | wordmark | clock — grid so the wordmark is truly centered even
   though the flanking columns differ in width */
.header {
  height: 96px;
  flex: none;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  border-bottom: 1px solid var(--hairline-strong);
}
.header .date { justify-self: start; }
.header .right { justify-self: end; }

/* the official wordmark is a solid-black image; render it through a mask so
   it wears the theme foreground (near-black on paper, off-white in dark) */
.header .wordmark {
  height: 26px;
  aspect-ratio: 960 / 87;
  background: var(--fg);
  -webkit-mask: url('/wc26-wordmark.webp') center / contain no-repeat;
  mask: url('/wc26-wordmark.webp') center / contain no-repeat;
}

.header .date {
  font-size: 19px;
  font-weight: 500;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--fg-dim);
}

.header .right {
  display: flex;
  align-items: baseline;
  gap: 18px;
}

.header .clock {
  font-size: 26px;
  font-weight: 600;
  letter-spacing: 0.08em;
}

.header .clock .secs {
  color: var(--fg-dim);
  font-weight: 400;
  font-size: 19px;
}

.staleness {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  align-self: center;
  background: var(--fg-dim);
}

/* theme toggle — browser view only, hidden on the mouseless kiosk */
.theme-toggle {
  display: none;
  width: 32px;
  height: 32px;
  padding: 0;
  align-self: center;
  border: 1px solid var(--hairline-strong);
  border-radius: 50%;
  background: none;
  color: var(--fg-dim);
  font: inherit;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  place-items: center;
}

@media (hover: hover) and (pointer: fine) {
  .theme-toggle {
    display: grid;
  }
}

.theme-toggle:hover {
  color: var(--fg);
  border-color: var(--fg-dim);
}

.staleness.stale {
  background: transparent;
  border: 1.5px solid var(--fg-dim);
}

.stale-text {
  font-size: 14px;
  letter-spacing: 0.12em;
  color: var(--fg-dim);
  align-self: center;
}

/* ——— group-day layout ——— */

.groupday {
  flex: 1;
  min-height: 0;
  display: grid;
  /* minmax(0, …) lets the track shrink to its share instead of growing to
     fit nowrap content — without it the left pane shoves standings off-screen */
  grid-template-columns: minmax(0, 1fr) 600px;
  gap: 0;
}

.matches-pane {
  padding: 36px 48px 0 0;
  border-right: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
}

.pane-label {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-bottom: 22px;
}

.pane-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 22px;
}

.pane-head .pane-label {
  margin-bottom: 0;
}

/* day-scrub arrows sit right beside the day label, not across the wide pane */
.matches-head {
  justify-content: flex-start;
  gap: 20px;
}

/* manual carousel arrows — browser view only, hidden on the mouseless kiosk */
.stand-nav {
  display: none;
  gap: 8px;
}

@media (hover: hover) and (pointer: fine) {
  .stand-nav {
    display: inline-flex;
  }
}

.stand-nav button {
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--hairline-strong);
  border-radius: 50%;
  background: none;
  color: var(--fg-dim);
  font: inherit;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
}

.stand-nav { align-items: center; }

.stand-nav button:hover:not(:disabled) {
  color: var(--fg);
  border-color: var(--fg-dim);
}

.stand-nav button:disabled {
  opacity: 0.3;
  cursor: default;
}

/* pill that jumps the schedule scrub straight back to today */
.stand-nav .day-today {
  width: auto;
  padding: 0 12px;
  border-radius: 15px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.2em;
}

.match-grid {
  flex: 1;
  min-height: 0;
  display: grid;
  /* density is chosen by measurement so content nearly fills the box; spread
     the small remaining slack evenly between rows */
  gap: 0 56px;
  align-content: space-evenly;
  /* safety net: clip within the grid box so an unusually tall row can never
     visually overlap the Yesterday/Tomorrow strips below it */
  overflow: hidden;
}

/* minmax(0,…) so wide no-wrap content (meta, stat line) can't blow a column
   past the pane — cards shrink and their content wraps/truncates instead */
.match-grid.cols-1 { grid-template-columns: minmax(0, 1fr); }
.match-grid.cols-2 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }

/* mild: just over a full fit — drop only the stat line, keep everything else
   at full size so the day still reads richly */
.match-grid.mild .match .statline { display: none; }

/* compact: 5–6 match days — keep teams/score/scorers AND the goal timeline
   (the at-a-glance record of when goals fell); drop only the stat line and
   trim type/spacing so 3 rows fit without overlap */
.match-grid.compact .match { padding: 11px 0 13px 24px; gap: 6px; }
.match-grid.compact .match .statline { display: none; }
.match-grid.compact .match .row .team { font-size: 26px; }
.match-grid.compact .match .row .num { font-size: 38px; min-width: 48px; }
.match-grid.compact .crest-box { width: 36px; height: 36px; }
.match-grid.compact .crest-box img { max-width: 36px; max-height: 36px; }
.match-grid.compact .match .scorers { font-size: 13px; padding-left: 56px; }
.match-grid.compact .match .tlbar { height: 22px; margin: 2px 0 0; }

/* dense: 7–8 match days (final group round, simultaneous kickoffs) */
.match-grid.dense .match { padding: 14px 0 16px 22px; gap: 8px; }
.match-grid.dense .match .row .team { font-size: 24px; }
.match-grid.dense .match .row .num { font-size: 34px; min-width: 44px; }
.match-grid.dense .crest-box { width: 32px; height: 32px; }
.match-grid.dense .crest-box img { max-width: 32px; max-height: 32px; }
.match-grid.dense .match .meta { font-size: 13px; }
.match-grid.dense .match .meta .status { font-size: 15px; }
.match-grid.dense .match .countdown { display: none; }

/* ——— match card: a ruled scorebug, not a box ——— */

.match {
  position: relative;
  padding: 18px 0 20px 26px;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0; /* allow the card to shrink so children can wrap/truncate */
}

.match::before {
  /* live edge: present but transparent so nothing shifts when it lights */
  content: '';
  position: absolute;
  left: 0;
  top: -1px;
  bottom: -1px;
  width: 3px;
  background: transparent;
}

.match.live::before {
  background: var(--accent);
}

.match .meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 4px 16px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

/* group · stadium · weather shows in full — wraps to a second line when long
   (cards have ample vertical room) rather than truncating or clipping */
.match .meta > span:first-child {
  min-width: 0;
  line-height: 1.5;
}

.match .meta .meta-right {
  flex: none;
}

.match .meta .status {
  font-size: 15px;
  letter-spacing: 0.1em;
  color: var(--fg-dim);
}

.match.live .meta .status {
  color: var(--accent);
  animation: livepulse 2.4s ease-in-out infinite;
}

@keyframes livepulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

.match .row {
  display: flex;
  align-items: center;
  gap: 18px;
}

.match .row .team {
  flex: 1;
  font-size: 30px;
  font-weight: 500;
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.match .row .num {
  font-size: 46px;
  font-weight: 650;
  line-height: 1;
  min-width: 58px;
  text-align: right;
}

.match .row .num .pens-note {
  font-size: 19px;
  font-weight: 500;
  color: var(--fg-dim);
  vertical-align: 18px;
  margin-left: 6px;
}

.match.upcoming .row .team,
.match.upcoming .crest-box { opacity: 0.62; }

.match .side {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.match .scorers {
  padding-left: 62px;
  font-size: 14px;
  letter-spacing: 0.04em;
  line-height: 1.5;
  color: var(--fg-dim);
  text-transform: uppercase;
  overflow-wrap: anywhere;
}

.match-grid.dense .match .scorers,
.match-grid.dense .match .tlbar,
.match-grid.dense .match .statline { display: none; }

/* ——— event timeline bar: lollipop markers anchored to the track ———
   home events stem upward, away events downward; goals are ringed dots,
   red cards are card-shaped accent marks */

.tlbar {
  position: relative;
  height: 36px;
  margin: 5px 0 3px;
}

.tl-track {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  background: var(--hairline-strong);
}

/* kickoff / HT / FT reference notches */
.tl-mark {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 1px;
  height: 7px;
  background: var(--fg-dim);
}

/* on a 120' track, 90' is the full-time boundary — mark it so the
   extra-time stretch reads as an added period */
.tl-mark.ft {
  height: 13px;
  width: 2px;
  background: var(--fg);
}

.tl-progress {
  position: absolute;
  left: 0;
  top: 50%;
  height: 1px;
  background: var(--fg);
}

/* stem from the track out to the glyph */
.tl-stem {
  position: absolute;
  width: 1px;
  background: var(--fg);
}

.tl-stem.top { bottom: 50%; height: 13px; }
.tl-stem.bottom { top: 50%; height: 13px; }

.tl-stem::after {
  content: '';
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}

.tl-stem.goal::after {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--fg);
  box-shadow: 0 0 0 2px var(--bg); /* ring separates dot from track/stems */
}

.tl-stem.goal.top::after { top: -8px; }
.tl-stem.goal.bottom::after { bottom: -8px; }

/* booking: a card-shaped chip, same size as the red so the two card types
   differ only by color */
.tl-stem.yellow { background: var(--booking); }
.tl-stem.yellow::after {
  width: 7px;
  height: 10px;
  border-radius: 1.5px;
  background: var(--booking);
  box-shadow: 0 0 0 2px var(--bg);
}
.tl-stem.yellow.top::after { top: -9px; }
.tl-stem.yellow.bottom::after { bottom: -9px; }

.tl-stem.red { background: var(--accent); }

.tl-stem.red::after {
  width: 7px;
  height: 10px;
  border-radius: 1.5px;
  background: var(--accent);
  box-shadow: 0 0 0 2px var(--bg);
}

.tl-stem.red.top::after { top: -9px; }
.tl-stem.red.bottom::after { bottom: -9px; }

.statline {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 26px;
}

.stat-pair {
  display: inline-flex;
  gap: 8px;
  align-items: baseline;
}

.sl-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--fg-faint);
}

.sl-value {
  font-size: 15px;
  font-weight: 500;
  color: var(--fg-dim);
}

/* ——— external links: browser view only ———
   hidden on hover-incapable displays (the mouseless kiosk) */

.meta-right {
  display: inline-flex;
  align-items: baseline;
  gap: 20px;
}

.extlink {
  display: none;
  color: var(--fg-faint);
  text-decoration: none;
  line-height: 0;
}

.extlink:hover {
  color: var(--fg);
}

@media (hover: hover) and (pointer: fine) {
  .extlink { display: inline-flex; align-items: center; }
}

/* ——— crest ——— */

.crest-box {
  width: 44px;
  height: 44px;
  flex: none;
  display: grid;
  place-items: center;
}

/* every flag renders as a uniform 3:2 rectangle (flags come from flagcdn now);
   object-fit: cover crops to that box so aspect ratios are consistent across the
   board, centred in the square crest-box. */
.crest-box img {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 2px;
  display: block;
}

.crest-box .monogram {
  width: 40px;
  height: 40px;
  border: 1px solid var(--hairline-strong);
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--fg-dim);
}

/* ——— tomorrow strip ——— */

.tomorrow {
  flex: none;
  border-top: 1px solid var(--hairline);
  padding: 18px 0 6px 26px;
  display: flex;
  gap: 36px;
  align-items: baseline;
  font-size: 17px;
  color: var(--fg-dim);
}

.tomorrow .label {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.3em;
  color: var(--fg-faint);
}

.tomorrow .fixture b {
  color: var(--fg);
  font-weight: 600;
}

/* ——— yesterday: compact result cards ——— */

.yday {
  flex: none;
  border-top: 1px solid var(--hairline);
  padding: 20px 0 8px 26px;
}

.yday .pane-label {
  margin-bottom: 16px;
}

/* equal columns that shrink to fit — never overflow the pane regardless of count */
.yday-cards {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 40px;
}

.ycard {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.ycard .ymeta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--fg-faint);
  white-space: nowrap;
}

/* label truncates rather than colliding with the HIGHLIGHTS/FT cluster */
.ycard .ymeta > span:first-child {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.ycard .ymeta > span:last-child {
  display: inline-flex;
  gap: 12px;
  flex: none;
}

.ycard .yside {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ycard .yside.loser .yrow { opacity: 0.45; }

.ycard .yrow {
  display: flex;
  align-items: center;
  gap: 12px;
}

.ycard .yrow .crest-box {
  width: 26px;
  height: 26px;
}

.ycard .yrow .crest-box img { max-width: 26px; max-height: 26px; }

.ycard .yrow .crest-box .monogram {
  width: 22px;
  height: 22px;
  font-size: 8px;
  letter-spacing: 0;
}

.ycard .ytla {
  flex: 1;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: 0.06em;
}

.ycard .yscore {
  font-size: 20px;
  font-weight: 700;
}

.ycard .yscore sup {
  font-size: 12px;
  font-weight: 500;
  color: var(--fg-dim);
  margin-left: 3px;
}

.ycard .yscorers {
  padding-left: 38px;
  font-size: 13px;
  letter-spacing: 0.05em;
  color: var(--fg-dim);
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* yesterday's results: winners lit, scores and losers dim */
.tomorrow.yesterday .fixture .won {
  color: var(--fg);
  font-weight: 600;
}

.tomorrow.yesterday .pens-tag {
  color: var(--fg-faint);
  font-size: 14px;
}

/* ——— standings rail ——— */

.standings-pane {
  padding: 36px 0 0 48px;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.standings-stack {
  flex: 1;
  position: relative;
}

.standings-layer {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  gap: 28px;
  overflow: hidden;
  /* all pages stay mounted (images stay decoded); only the active one shows */
  opacity: 0;
  pointer-events: none;
}

.standings-layer.active {
  opacity: 1;
  pointer-events: auto;
}

.group-table .group-name {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--hairline-strong);
  display: flex;
  justify-content: space-between;
}

.group-table .group-name .playing-today {
  color: var(--fg-faint);
  font-weight: 500;
  letter-spacing: 0.18em;
  font-size: 13px;
  align-self: center;
}

.group-table table {
  width: 100%;
  border-collapse: collapse;
}

.group-table td {
  padding: 8px 0;
  font-size: 20px;
  border-bottom: 1px solid var(--hairline);
}

/* qualification line under 2nd place */
.group-table tr:nth-child(2) td {
  border-bottom: 1px solid var(--hairline-strong);
}

.group-table tr:last-child td { border-bottom: none; }

.group-table .pos {
  width: 36px;
  color: var(--fg-faint);
  font-weight: 500;
}

.group-table .crest-cell { width: 44px; }

.group-table .crest-cell .crest-box {
  width: 30px;
  height: 30px;
}

.group-table .crest-cell img { max-width: 28px; max-height: 28px; }

.group-table .crest-cell .monogram {
  width: 26px;
  height: 26px;
  font-size: 9px;
}

.group-table .tla {
  font-weight: 600;
  letter-spacing: 0.06em;
}

.group-table .stat {
  width: 64px;
  text-align: right;
  color: var(--fg-dim);
  font-weight: 400;
}

.group-table .pts {
  width: 72px;
  text-align: right;
  font-weight: 700;
}

.group-table thead td {
  padding: 8px 0 6px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.2em;
  color: var(--fg-faint);
  border-bottom: none;
}

.standings-progress {
  flex: none;
  display: flex;
  gap: 8px;
  padding: 20px 0 4px;
}

.standings-progress .dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--fg-faint);
}

.standings-progress .dot.on { background: var(--fg-dim); }

/* golden boot: fixed section below the rotating standings, not in the carousel */
.boot-section {
  flex: none;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--hairline-strong);
}

/* qualified: a team that has clinched a top-2 spot. Subtle but clear — a faint
   highlight band across the row and a ✓ after the name. Stays monochrome (the
   red accent is reserved for liveness). */
.group-table tr.through td {
  background: var(--qualified-bg);
}

.group-table tr.through .tla::after {
  content: '✓';
  margin-left: 8px;
  font-size: 13px;
  color: var(--fg-dim);
  vertical-align: 1px;
}

.group-table tr.out td { opacity: 0.4; }

/* best-thirds: hairline cut after the 8th qualifier */
.group-table.thirds td { padding: 7px 0; font-size: 18px; }
.group-table.thirds tr.cutline td { border-bottom: 1px solid var(--hairline-strong); }

/* ——— takeover: full-screen broadcast moment ——— */

.takeover {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 40px;
  animation: takein 350ms ease-out;
}

@keyframes takein {
  from { opacity: 0; }
  to { opacity: 1; }
}

.take-label {
  font-size: 64px;
  font-weight: 800;
  font-stretch: 122%;
  letter-spacing: 0.42em;
  margin-right: -0.42em; /* re-center spaced caps */
  color: var(--accent);
}

.take-label.quiet { color: var(--fg-dim); }

.take-score {
  display: flex;
  align-items: center;
  gap: 36px;
}

.take-score .crest-box {
  width: 84px;
  height: 84px;
}

.take-score .crest-box img { max-width: 84px; max-height: 84px; }

.take-tla {
  font-size: 64px;
  font-weight: 650;
  letter-spacing: 0.08em;
}

.take-nums {
  font-size: 130px;
  font-weight: 750;
  line-height: 1;
  margin: 0 18px;
}

.take-detail {
  font-size: 30px;
  font-weight: 500;
  letter-spacing: 0.24em;
  color: var(--fg-dim);
  text-transform: uppercase;
}

/* ——— night mode ——— */

.night {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 26px;
}

.night-clock {
  font-size: 150px;
  font-weight: 250;
  letter-spacing: 0.06em;
  color: var(--fg-dim);
}

.night-date {
  font-size: 18px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

.night-next {
  margin-top: 30px;
  font-size: 16px;
  letter-spacing: 0.2em;
  color: var(--fg-faint);
}

/* ——— bracket ——— */

.bracket {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center; /* centre the tree + strips as a group; extra vertical
                              space (taller-than-16:9 screens) becomes even
                              breathing room instead of a letterbox band */
  padding-top: 22px;
}

/* the labels must track the FIXED 1808px cell geometry, not the stage width:
   on wider-than-16:9 viewports the stage grows (fill-viewport) and stretched
   labels would drift off the columns toward the right */
.round-labels {
  flex: none;
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  padding-bottom: 14px;
  width: 1808px;
  margin: 0 auto;
}
/* live-game bracket with the finished R32 columns dropped */
.round-labels.seven { grid-template-columns: repeat(7, 1fr); }

.round-labels span {
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: var(--fg-faint);
}

.round-labels .final-label {
  color: var(--fg-dim);
}

.bracket-area {
  position: relative;
  width: 1808px;
  height: 792px; /* keep in lockstep with H in Bracket.tsx */
  flex: none;
  margin: 0 auto; /* centred like the labels, so they stay in lockstep */
}

.wires {
  position: absolute;
  inset: 0;
}

.wires path {
  fill: none;
  stroke: var(--wire);
  stroke-width: 1.5;
}

.bcell {
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  padding: 5px 13px;
  border: 1px solid var(--hairline);
  border-radius: 4px;
  background: var(--bg);
}

/* real matches (teams known or a result) get a subtle fill so they anchor the
   eye; empty future cells keep just the outline + date, showing where the
   tournament is headed */
.bcell:not(.tbd) { background: var(--card-bg); }

.bcell.live { border-color: var(--hairline-strong); box-shadow: inset 3px 0 0 var(--accent); }

/* the FINAL is the destination — a stronger frame so the eye lands on the centre
   even before the finalists are known */
.bcell.final { border: 1.5px solid var(--hairline-strong); }

/* In an upcoming/TBD cell, dim only the EMPTY (still-unknown) slots. A team that
   has advanced — the latest winners — shows at full brightness so the live
   frontier of the bracket pops; an unknown opponent recedes. (Past results keep
   the winner-bold / loser-dimmed treatment below, so the two read differently.) */
/* dim the still-unknown slots — a lone TBD in a half-filled cell, or both in a
   future cell — while a team that has advanced stays bright */
.bcell.upcoming .brow.empty,
.bcell.tbd .brow { opacity: 0.3; }

.brow {
  display: flex;
  align-items: center;
  gap: 8px;
}

.brow .crest-box {
  width: 23px;
  height: 23px;
}

.brow .crest-box img { max-width: 23px; max-height: 23px; }

.brow .crest-box .monogram {
  width: 21px;
  height: 21px;
  font-size: 8px;
  letter-spacing: 0;
}

.brow .btla {
  flex: 1;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: 0.06em;
}

.brow .bscore {
  font-size: 19px;
  font-weight: 650;
}

.brow .bscore sup {
  font-size: 11px;
  font-weight: 500;
  color: var(--fg-dim);
  margin-left: 3px;
}

/* finished cell — the winner dominates: bold name + full-colour flag. the loser
   recedes: muted, lighter, and its flag desaturated, so the box reads at a
   glance as "this team went through". */
/* the winner is a touch larger than the loser — bigger name, flag and score —
   on top of being bolder and full-colour */
.bcell.finished .brow.winner .btla { font-weight: 800; font-size: 21px; }
.bcell.finished .brow.winner .bscore { font-size: 21px; }
.bcell.finished .brow.winner .crest-box { width: 26px; height: 26px; }
.bcell.finished .brow.winner .crest-box img { max-width: 26px; max-height: 26px; }
.bcell.finished .brow.loser { opacity: 0.38; }
.bcell.finished .brow.loser .btla { font-weight: 500; }
.bcell.finished .brow.loser .crest-box img { filter: grayscale(0.85); }

.bstatus {
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--fg);
  text-transform: uppercase;
}

.bcell.live .bstatus {
  color: var(--accent);
  animation: livepulse 2.4s ease-in-out infinite;
}

.third-label {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% + 113px);
  text-align: center;
  font-size: 11px;
  letter-spacing: 0.26em;
  color: var(--fg-faint);
}

/* countdown to the next kickoff — vertically centered in the empty band
   above the trophy (band = area top .. trophy at 50% − 112px = 284px) */
.next-card {
  position: absolute;
  top: 142px;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 11px;
  padding: 20px 18px;
  border: 1px solid var(--hairline);
  border-radius: 4px;
  background: var(--card-bg);
  text-align: center;
}
.nc-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.24em;
  color: var(--fg-faint);
}
.nc-teams {
  display: flex;
  align-items: center;
  gap: 9px;
}
.nc-teams img { width: 24px; height: 24px; object-fit: contain; }
.nc-tla { font-size: 23px; font-weight: 700; }
.nc-v { font-size: 13px; color: var(--fg-faint); }
.nc-when {
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-dim);
}
.nc-count {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* small World Cup trophy above the final box */
.trophy-wrap {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: calc(50% - 112px);
  display: flex;
  justify-content: center;
}
.trophy {
  height: 60px;
  width: auto;
}

/* ——— knockout live: full-width scoreboard banner + large bracket ——— */

.ko-stack {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding-top: 14px;
}

.ko-banner-row {
  flex: none;
  display: flex;
  gap: 64px;
}

.ko-banner {
  flex: 1;
  min-width: 0;
  border-left: 3px solid transparent;
  padding-left: 28px;
  display: flex;
  align-items: center;
  gap: 36px;
}

.ko-banner.live { border-left-color: var(--accent); }

/* scoreboard column (score, scorers, timeline, stats) beside the pitch map */
.kb-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.ko-banner .kb-meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  font-size: 15px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg);
}

.kb-status { display: flex; align-items: center; gap: 18px; }
.kb-min {
  color: var(--accent);
  font-size: 22px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
/* Google-scores-style liveness: a thin line under the live minute with a
   segment sweeping back and forth — reads as "in progress" at a distance
   without the text itself flashing */
.ko-banner.live .kb-min { position: relative; }
.ko-banner.live .kb-min::before {
  /* faint track */
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -7px;
  height: 2px;
  border-radius: 1px;
  background: var(--accent);
  opacity: 0.22;
}
.ko-banner.live .kb-min::after {
  /* sweeping segment: 40% wide, translateX(150%) puts its right edge at 100% */
  content: '';
  position: absolute;
  left: 0;
  bottom: -7px;
  height: 2px;
  width: 40%;
  border-radius: 1px;
  background: var(--accent);
  animation: kb-live-sweep 1.4s ease-in-out infinite alternate;
}
@keyframes kb-live-sweep {
  to { transform: translateX(150%); }
}

/* phase pill: extra-time half / shoot-out */
.kb-phase {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.16em;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 3px;
  padding: 3px 9px;
}

/* penalty shoot-out grid */
.pgrid {
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
  margin: 6px 0;
}
.pgrid-row { display: flex; align-items: center; gap: 16px; }
.pg-tla {
  width: 52px;
  text-align: right;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--fg-dim);
}
.pg-dots { display: flex; gap: 8px; }
.pdot {
  width: 17px;
  height: 17px;
  border-radius: 3px;
  border: 1.5px solid var(--fg-dim);
}
.pdot.made { background: var(--accent); border-color: var(--accent); }
.pdot.miss { background: transparent; }
.pdot.latest { animation: livepulse 1.6s ease-in-out infinite; }
.pg-count {
  width: 24px;
  font-size: 24px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.kb-score {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 40px;
}

.kb-team { display: flex; align-items: center; gap: 18px; flex: 1; min-width: 0; }
.kb-team.home { justify-content: flex-end; }
.kb-team.away { justify-content: flex-start; }

.kb-name {
  font-size: 40px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.kb-team .crest-box { width: 46px; height: 46px; flex: none; }
.kb-team .crest-box img { max-width: 46px; max-height: 46px; }
.kb-team .crest-box .monogram { width: 44px; height: 30px; font-size: 13px; }

.kb-nums { display: flex; align-items: center; gap: 22px; flex: none; }
.kb-num { font-size: 68px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1; }
.kb-num .kb-pen { font-size: 26px; font-weight: 600; color: var(--accent); vertical-align: super; margin-left: 3px; }
.kb-dash { font-size: 40px; color: var(--fg-dim); }

/* name + remaining-subs dashes stacked; dashes hug the name's edge */
.kb-name-col {
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}
.kb-name-col.home { align-items: flex-end; }
.kb-name-col.away { align-items: flex-start; }
.kb-subs { display: flex; gap: 5px; }
.kb-sub-dash {
  width: 16px;
  height: 4px;
  border-radius: 2px;
  background: var(--hairline);
}
.kb-sub-dash.left { background: var(--fg); }

/* a stat with a smaller qualifier stacked beneath (shots/on-target,
   possession/in-contest) */
.kb-stat-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
.kb-substat {
  font-size: 12px;
  letter-spacing: 0.12em;
  color: var(--fg-dim);
}

.kb-scorers {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  font-size: 17px;
  color: var(--fg);
}
.kb-scorers .kb-sc { flex: 1; min-width: 0; }
.kb-scorers .kb-sc:last-child { text-align: right; }

/* two simultaneous games: scale the banner type down so both fit side by side
   — and drop the pitch map, whose labels would be illegibly small at half
   width (the timeline bar and stats still carry the story) */
.ko-stack.two .kb-name { font-size: 30px; }
.ko-stack.two .kb-num { font-size: 50px; }
.ko-stack.two .kb-team .crest-box { width: 36px; height: 36px; }
.ko-stack.two .kb-stats { gap: 26px; font-size: 15px; }
.ko-stack.two .kb-pitch { display: none; }

.ko-banner .tlbar { height: 56px; margin: 2px 0; }
/* banner-scale glyphs: the card/dot markers read from across the room
   (the 36px group-card bar keeps the small set) */
.ko-banner .tl-track,
.ko-banner .tl-progress { height: 2px; }
.ko-banner .tl-mark { width: 2px; height: 11px; }
.ko-banner .tl-mark.ft { width: 3px; height: 19px; }
.ko-banner .tl-stem { width: 2px; }
.ko-banner .tl-stem.top { height: 17px; }
.ko-banner .tl-stem.bottom { height: 17px; }
.ko-banner .tl-stem.goal::after { width: 14px; height: 14px; }
.ko-banner .tl-stem.goal.top::after { top: -12px; }
.ko-banner .tl-stem.goal.bottom::after { bottom: -12px; }
.ko-banner .tl-stem.yellow::after { width: 10px; height: 14px; border-radius: 2px; }
.ko-banner .tl-stem.yellow.top::after { top: -13px; }
.ko-banner .tl-stem.yellow.bottom::after { bottom: -13px; }
.ko-banner .tl-stem.red::after { width: 10px; height: 14px; border-radius: 2px; }
.ko-banner .tl-stem.red.top::after { top: -13px; }
.ko-banner .tl-stem.red.bottom::after { bottom: -13px; }

/* ——— live pitch map: handheld-toy field, every shot at its real position ———
   surface + hairlines follow the theme (paper pitch by day, near-black at
   night); the accent marks goals and the newest attempt only */
.kb-pitch { flex: none; width: 588px; }
.kb-pitch svg { width: 100%; height: auto; display: block; }
.pp-surface { fill: var(--card-bg); stroke: var(--hairline-strong); stroke-width: 1.4; }
.pp-line { fill: none; stroke: var(--hairline-strong); stroke-width: 1.2; }
.pp-shot { fill: none; stroke: var(--fg); stroke-width: 1.4; }
.pp-goal { fill: var(--accent); }
.pp-foul { fill: none; stroke: var(--fg); stroke-width: 1.1; }
.pp-gate { fill: none; stroke: var(--hairline-strong); stroke-width: 1.6; }
.pp-ground { stroke: var(--hairline); stroke-width: 1; }
.pp-tla {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.12em;
  fill: var(--fg-dim);
}
.pp-sub {
  font-size: 9px;
  letter-spacing: 0.18em;
  fill: var(--fg-faint);
}
.pp-pulse {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.6;
  transform-box: fill-box;
  transform-origin: center;
  animation: pp-pulse 1.8s ease-out infinite;
}
@keyframes pp-pulse {
  0% { transform: scale(0.55); opacity: 0.95; }
  75% { transform: scale(1.3); opacity: 0; }
  100% { transform: scale(1.3); opacity: 0; }
}

.kb-stats {
  display: flex;
  justify-content: center;
  gap: 44px;
  font-size: 17px;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}
.kb-stats b {
  color: var(--fg);
  font-weight: 600;
  letter-spacing: 0.16em;
  margin-right: 8px;
}

.ko-bracket-full {
  flex: 1;
  min-height: 0;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  overflow: hidden;
}

/* full-width bracket: native geometry scaled to fill the width — much larger
   and more legible than the old side-column. origin top-center keeps it
   centered horizontally and anchored just under the banner. scaled down enough
   that the banner above and the golden-boot / today footer below both fit on a
   16:9 kiosk without clipping. */
.ko-bracket-full .bracket {
  width: 1808px;
  flex: none;
  padding-top: 0;
  transform: scale(var(--ko-scale, 0.66));
  transform-origin: top center;
}

.ko-bracket-full .third-label { display: none; }

/* golden-boot race + today's slate stay visible during a live game, filling the
   space below the scaled bracket */
.ko-footer {
  flex: none;
  display: flex;
  flex-direction: column;
}
.ko-footer .boot-strip { padding-top: 0; }
.ko-footer .today-strip { margin-top: 14px; }

/* ——— past-match detail overlay (click a finished bracket cell) ——— */

.bcell.clickable { cursor: pointer; }
.bcell.clickable:hover { border-color: var(--hairline-strong); }

/* backdrop is a direct child of the transform-scaled .stage, so inset:0 covers
   exactly the stage at every aspect ratio — never position:fixed or viewport
   units here (fixed anchors to the transformed ancestor; vw/vh shear) */
.match-overlay {
  position: absolute;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--overlay-dim);
  animation: mo-fade 160ms ease-out;
}
@keyframes mo-fade {
  from { opacity: 0; }
}

.mo-panel {
  width: 1600px; /* stage px — scales with everything else */
  max-width: calc(100% - 140px);
  background: var(--bg);
  border: 1px solid var(--hairline-strong);
  border-radius: 8px;
  padding: 34px 46px;
  box-shadow: 0 24px 90px rgba(0, 0, 0, 0.4);
  transform-origin: top left; /* grow-from-cell plays from the cell's corner */
}
/* the banner reused inside the panel drops its banner-row live-edge inset */
.mo-panel .ko-banner { border-left: none; padding-left: 0; }
/* accent means liveness only — a finished FT/AET/PENS label reads dim */
.mo-panel .kb-min { color: var(--fg-dim); }
/* a finished match must not blink forever: still the shoot-out and pitch pulses */
.mo-panel .pdot.latest { animation: none; }
.mo-panel .pp-pulse { display: none; }

/* ——— bottom strip: live detail or next fixture ——— */

.live-strip {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 120px;
  border-top: 1px solid var(--hairline);
  margin-top: 18px;
}

.live-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.live-item .live-row {
  display: flex;
  align-items: center;
  gap: 18px;
}

.possession {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 420px;
}

.possession .pct {
  font-size: 13px;
  color: var(--fg-dim);
  min-width: 34px;
  text-align: center;
}

.poss-bar {
  flex: 1;
  height: 3px;
  background: var(--fg-faint);
}

.poss-home {
  height: 100%;
  background: var(--fg);
}

.live-item .minute {
  font-size: 22px;
  font-weight: 650;
  color: var(--accent);
  min-width: 64px;
  text-align: right;
  animation: livepulse 2.4s ease-in-out infinite;
}

.live-item .lname {
  font-size: 26px;
  font-weight: 500;
}

.live-item .lscore {
  font-size: 40px;
  font-weight: 700;
  line-height: 1;
  margin: 0 6px;
}

.live-item .crest-box { width: 36px; height: 36px; }
.live-item .crest-box img { max-width: 36px; max-height: 36px; }

.next-strip {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-top: 1px solid var(--hairline);
  margin-top: 18px;
  font-size: 18px;
  letter-spacing: 0.14em;
  color: var(--fg-dim);
  text-transform: uppercase;
}

.next-strip b {
  color: var(--fg);
  font-weight: 650;
  margin: 0 4px;
}

/* today's full slate under the bracket */
/* minimal golden-boot line — top scorers, centred below the tree */
.boot-strip {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 26px;
  padding-top: 6px;
}
.boot-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: var(--fg-faint);
}
.boot-item { display: flex; align-items: center; gap: 8px; }
.boot-item .crest-box { width: 21px; height: 21px; }
.boot-name { font-size: 15px; font-weight: 600; letter-spacing: 0.03em; }
.boot-goals { font-size: 18px; font-weight: 700; color: var(--fg-dim); }

.today-strip {
  position: relative; /* anchors the .credit under the top rule */
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 60px;
  border-top: 1px solid var(--hairline);
  margin-top: 18px;
  padding-top: 16px;
}

/* shown when the strip is a future day's slate (rest day, no games today) */
/* the day's only game is live: no items, just the rule + maker's credit */
.today-strip.lone {
  height: 26px;
  padding-top: 0;
}

.today-daylabel {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-dim);
  margin-right: -18px; /* offset some of the 60px gap so it hugs its day */
}

.today-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  position: relative;
}

/* no accent bar on the live game — the ticking minute already signals it */

.today-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.today-row .crest-box { width: 28px; height: 28px; }
.today-row .crest-box img { max-width: 28px; max-height: 28px; }

.ttla {
  font-size: 23px;
  font-weight: 600;
  letter-spacing: 0.03em;
}
.ttla.win { color: var(--fg); }
.ttla.lose { color: var(--fg-faint); font-weight: 500; }

.tmid {
  min-width: 46px;
  text-align: center;
  font-size: 23px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  margin: 0 2px;
}
.tmid .tdash { color: var(--fg-dim); margin: 0 3px; }
.tmid .tpen { font-size: 14px; font-weight: 600; color: var(--fg-dim); vertical-align: super; margin-left: 1px; }

.tstatus {
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.tstatus .tmin {
  color: var(--accent);
  font-weight: 650;
  animation: livepulse 2.4s ease-in-out infinite;
}
.tstatus .tcount { color: var(--accent); font-weight: 650; letter-spacing: 0.1em; }

/* city · weather (or "Indoor") under each of today's games — no truncation */
.tmeta {
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--fg-faint);
  text-align: center;
  white-space: nowrap;
}

/* ——— champion ——— */

.champion-wrap {
  flex: 1;
  min-height: 0;
  position: relative;
  display: flex;
  flex-direction: column;
}

/* bracket recedes; the winning path stays lit */
.champion-wrap .bcell { opacity: 0.3; }
.champion-wrap .bcell.path { opacity: 1; border-color: var(--hairline-strong); }
.champion-wrap .wires path { stroke: var(--wire-dim); }
.champion-wrap .next-strip,
.champion-wrap .today-strip,
.champion-wrap .live-strip { visibility: hidden; }

.champion-overlay {
  position: absolute;
  left: 50%;
  top: 96px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  padding: 36px 72px;
  background: var(--bg);
}

.champ-crest .crest-box {
  width: 150px;
  height: 150px;
}

.champ-crest .crest-box img {
  max-width: 150px;
  max-height: 150px;
}

.champ-crest .crest-box .monogram {
  width: 130px;
  height: 130px;
  font-size: 34px;
}

.champ-name {
  font-size: 54px;
  font-weight: 750;
  font-stretch: 116%;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-align: center;
}

.champ-sub {
  font-size: 17px;
  font-weight: 500;
  letter-spacing: 0.34em;
  color: var(--fg-dim);
}

.champ-score {
  font-size: 26px;
  font-weight: 650;
  letter-spacing: 0.08em;
}
