/* futtoday — single-page fixture board
   Layout targets: dense but scannable rows, sticky day headers, ad slots that
   reserve their space up-front so nothing shifts when a creative loads. */

:root {
  color-scheme: light dark;

  --bg: #f6f7f9;
  --surface: #ffffff;
  --surface-2: #f0f2f5;
  --border: #e2e5ea;
  --border-strong: #cdd2da;
  --text: #12161c;
  --text-dim: #5b6472;
  --text-faint: #8a929e;
  --accent: #0a7d3f;
  --accent-soft: #e6f4ec;
  /* The away side of every home-vs-away comparison — stats bars, the
     predictions radar. Chosen to stay distinguishable from --accent for the
     commonest colour-vision deficiencies, where green-vs-red would not. */
  --accent-alt: #2563c9;
  --live: #d92d20;
  --live-soft: #fdeceb;
  --shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .04);

  --radius: 12px;
  --radius-sm: 8px;
  --shell: 1240px;
  --rail: 300px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0d1117;
    --surface: #151b23;
    --surface-2: #1c232d;
    --border: #262d38;
    --border-strong: #38404d;
    --text: #e8ecf1;
    --text-dim: #9aa5b4;
    --text-faint: #6e7889;
    --accent: #3fb950;
    --accent-soft: #14301d;
    --accent-alt: #58a6ff;
    --live: #ff6b60;
    --live-soft: #3a1714;
    --shadow: none;
  }
}

:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f6f7f9; --surface: #ffffff; --surface-2: #f0f2f5; --border: #e2e5ea;
  --border-strong: #cdd2da; --text: #12161c; --text-dim: #5b6472; --text-faint: #8a929e;
  --accent: #0a7d3f; --accent-soft: #e6f4ec; --accent-alt: #2563c9;
  --live: #d92d20; --live-soft: #fdeceb;
  --shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .04);
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0d1117; --surface: #151b23; --surface-2: #1c232d; --border: #262d38;
  --border-strong: #38404d; --text: #e8ecf1; --text-dim: #9aa5b4; --text-faint: #6e7889;
  --accent: #3fb950; --accent-soft: #14301d; --accent-alt: #58a6ff;
  --live: #ff6b60; --live-soft: #3a1714;
  --shadow: none;
}

*, *::before, *::after { box-sizing: border-box; }

/* Components below set explicit `display`, which would otherwise beat the
   user-agent rule for [hidden] and leave "hidden" elements on screen. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

a { color: inherit; }
img { max-width: 100%; }
button, input, select { font: inherit; color: inherit; }

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: 16px;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: #fff; padding: 10px 16px; border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; }

/* Off-screen but readable by assistive tech and crawlers. Used for the page h1,
   which the visual design carries as the logo image instead. Not display:none —
   that would hide it from screen readers and search engines too. */
.a11y-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

:where(button, select, input, a):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* --------------------------------------------------------------- masthead */

.masthead {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.masthead__inner {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 60px;
}
.brand {
  display: inline-flex; align-items: center;
  text-decoration: none;
}
.brand__logo {
  height: 34px; width: auto; display: block;
}

/* Two artworks rather than a filter: the wordmark is navy on light and near-white
   on dark, and no single CSS filter maps one to the other without wrecking the
   green. Both files together are ~14 KB, so the extra request is cheap.
   Each rule pairs the OS preference with the manual theme toggle, which wins. */
.brand__logo--dark { display: none; }
@media (prefers-color-scheme: dark) {
  .brand__logo--light { display: none; }
  .brand__logo--dark { display: block; }
}
:root[data-theme="light"] .brand__logo--light { display: block; }
:root[data-theme="light"] .brand__logo--dark { display: none; }
:root[data-theme="dark"] .brand__logo--light { display: none; }
:root[data-theme="dark"] .brand__logo--dark { display: block; }

@media (max-width: 560px) {
  .brand__logo { height: 28px; }
}

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

/* ------------------------------------------------------------ form pieces */

.field { display: inline-flex; flex-direction: column; gap: 3px; min-width: 0; }
.field__label {
  font-size: 10px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-faint);
}
/* Direct children only — the league panel nests its own inputs inside .field,
   and they must not inherit the select's caret background. */
.field > select, .field > input {
  appearance: none;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); padding: 7px 26px 7px 10px;
  max-width: 100%; min-width: 0; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 12px center, right 7px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.field > input[type="date"] { background-image: none; padding-right: 10px; }
.field--tz select { max-width: 190px; text-overflow: ellipsis; }

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: 999px; padding: 8px 14px; cursor: pointer;
  font-size: 13px; font-weight: 600; white-space: nowrap;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.chip:hover { border-color: var(--text-faint); }
.chip[aria-pressed="true"] {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.chip--ghost { background: transparent; font-weight: 500; }

/* -------------------------------------------------------------- range bar */

.rangebar {
  position: sticky; top: 0; z-index: 30;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(1.6) blur(10px);
  border-bottom: 1px solid var(--border);
}
.rangebar__inner {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 12px;
  padding-block: 10px;
}
.segmented {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 999px; overflow-x: auto; scrollbar-width: none;
}
.segmented::-webkit-scrollbar { display: none; }
.segmented__btn {
  appearance: none; background: transparent; border: 0; cursor: pointer;
  padding: 8px 16px; border-radius: 999px; white-space: nowrap;
  font-size: 13.5px; font-weight: 600; color: var(--text-dim);
}
.segmented__btn:hover { color: var(--text); }
.segmented__btn[aria-selected="true"] {
  background: var(--surface); color: var(--text); box-shadow: var(--shadow);
}

/* ---------------------------------------------------------------- filters */

.filters { padding-block: 14px 6px; }
.filters__row {
  display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap;
}
.search {
  position: relative; flex: 1 1 260px; min-width: 200px;
  display: flex; align-items: center;
}
.search__icon {
  position: absolute; left: 11px; width: 17px; height: 17px;
  fill: var(--text-faint); pointer-events: none;
}
.search input {
  width: 100%; appearance: none;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); padding: 9px 32px 9px 34px;
}
.search input::-webkit-search-cancel-button { display: none; }
.search__clear {
  position: absolute; right: 6px;
  background: none; border: 0; cursor: pointer; font-size: 20px; line-height: 1;
  color: var(--text-faint); padding: 2px 7px; border-radius: 6px;
}
.search__clear:hover { color: var(--text); }

/* ---------------------------------------------------------- league picker */

.leagues { position: relative; }
.leagues__btn {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); padding: 7px 10px;
  cursor: pointer; font-size: 15px; white-space: nowrap;
  max-width: 210px;
}
.leagues__btn:hover { border-color: var(--text-faint); }
.leagues__btn > span:first-child { overflow: hidden; text-overflow: ellipsis; }
.leagues__caret { color: var(--text-faint); font-size: 10px; }
.leagues__btn[aria-expanded="true"] { border-color: var(--accent); }

.leagues__panel {
  position: absolute; z-index: 50; top: calc(100% + 6px); right: 0;
  width: min(360px, calc(100vw - 32px));
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: 0 8px 28px rgba(8, 12, 20, .18), 0 2px 6px rgba(8, 12, 20, .1);
  padding: 10px;
  display: grid; gap: 8px;
}
@media (prefers-color-scheme: dark) {
  .leagues__panel { box-shadow: 0 10px 34px rgba(0, 0, 0, .6); }
}
:root[data-theme="dark"] .leagues__panel { box-shadow: 0 10px 34px rgba(0, 0, 0, .6); }

.leagues__actions { display: flex; gap: 6px; flex-wrap: wrap; }
.chip--mini { padding: 5px 11px; font-size: 12px; }

.leagues__panel input[type="search"] {
  width: 100%; appearance: none;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 7px 10px;
}
.leagues__panel input[type="search"]::-webkit-search-cancel-button { display: none; }

.leagues__list {
  max-height: min(46vh, 340px); overflow-y: auto;
  /* Flex column, not grid: an implicit grid column sizes to max-content, so
     long competition names pushed the rows (and the counts) past the panel. */
  display: flex; flex-direction: column; gap: 1px;
  /* Right inset keeps the counts clear of a macOS overlay scrollbar, which has
     zero width and so would otherwise sit straight on top of them. */
  margin: 0 -4px; padding: 0 12px 0 4px;
  overscroll-behavior: contain;
}
.leagues__group {
  font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-faint); padding: 8px 4px 3px; position: sticky; top: 0;
  background: var(--surface);
}
.leagues__row {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 5px; border-radius: 6px; cursor: pointer;
  font-size: 13.5px; line-height: 1.3;
}
.leagues__row:hover { background: var(--surface-2); }
.leagues__row input {
  accent-color: var(--accent);
  flex: none; margin: 0; cursor: pointer;
  width: 15px; height: 15px;
}
.leagues__row img { width: 17px; height: 17px; object-fit: contain; flex: none; }
/* min-width:0 is what actually lets a nowrap flex item shrink; without it the
   name pushes the count past the panel edge. */
.leagues__name {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.leagues__count {
  flex: none; padding-left: 8px;
  font-size: 11.5px; color: var(--text-faint); font-variant-numeric: tabular-nums;
}
.leagues__tag {
  flex: none;
  font-size: 9.5px; font-weight: 700; letter-spacing: .04em;
  padding: 2px 5px; border-radius: 4px;
  background: var(--accent-soft); color: var(--accent);
  box-shadow: 0 0 0 1px currentColor inset;
}
.leagues__row--empty .leagues__name { color: var(--text-dim); }
.leagues__hint { margin: 0; font-size: 11.5px; color: var(--text-faint); }

.filters__summary {
  margin: 10px 0 0; font-size: 13px; color: var(--text-dim); min-height: 19px;
}
.filters__summary b { color: var(--text); font-weight: 600; }

/* ----------------------------------------------------------------- layout */

.layout {
  display: grid; grid-template-columns: minmax(0, 1fr) var(--rail);
  gap: 24px; align-items: start; padding-block: 8px 40px;
}
.layout__main { min-width: 0; }
.layout__rail { position: sticky; top: 68px; }

@media (max-width: 1080px) {
  .layout { grid-template-columns: minmax(0, 1fr); }
  .layout__rail { display: none; }
}

/* ------------------------------------------------------------------ board */

.daygroup { margin-bottom: 22px; }
.daygroup__head {
  position: sticky; top: 55px; z-index: 20;
  display: flex; align-items: baseline; gap: 10px;
  padding: 10px 2px 8px; margin-bottom: 8px;
  /* Solid, not a fade — cards scrolling underneath would otherwise show through. */
  background: var(--bg);
}
.daygroup__title { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -.01em; }
.daygroup__count { font-size: 12.5px; color: var(--text-faint); }

.league {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: 10px;
  overflow: hidden;
}
.league__head {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 10px 14px; background: var(--surface-2);
  border: 0; border-bottom: 1px solid var(--border);
  cursor: pointer; text-align: left;
}
.league__crest {
  width: 20px; height: 20px; object-fit: contain; flex: none;
  background: transparent;
}
.league__flag {
  width: 18px; height: 13px; object-fit: cover; flex: none;
  border-radius: 2px; box-shadow: 0 0 0 1px var(--border) inset;
}
.league__name { font-weight: 650; font-size: 13.5px; letter-spacing: -.005em; }
.league__country { font-size: 12px; color: var(--text-dim); }
.league__round { font-size: 11.5px; color: var(--text-faint); margin-left: auto; padding-left: 10px; text-align: right; }
.league__chev { flex: none; color: var(--text-faint); transition: transform .15s ease; font-size: 11px; }
.league[data-collapsed="true"] .league__chev { transform: rotate(-90deg); }
.league[data-collapsed="true"] .league__body { display: none; }

.match {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr) auto;
  align-items: center; gap: 12px;
  padding: 9px 14px;
  border-top: 1px solid var(--border);
  cursor: pointer; /* the whole row opens the match detail panel */
}
.match:first-child { border-top: 0; }
.match:hover { background: var(--surface-2); }

.match__time {
  font-variant-numeric: tabular-nums;
  font-size: 13px; font-weight: 600; color: var(--text-dim);
  display: flex; flex-direction: column; gap: 2px;
}
.match__status {
  font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-faint);
}
.match--live .match__time { color: var(--live); }
.match--live .match__status { color: var(--live); }
.match__live-dot {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--live); margin-right: 4px; vertical-align: middle;
  animation: pulse 1.6s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .match__live-dot { animation: none; } }

.match__teams { display: grid; gap: 3px; min-width: 0; }
.team { display: flex; align-items: center; gap: 8px; min-width: 0; }
.team__crest { width: 18px; height: 18px; object-fit: contain; flex: none; }
.team__name {
  font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.team--winner .team__name { font-weight: 650; }
.team--loser .team__name { color: var(--text-dim); }

.match__score {
  display: flex; align-items: center; gap: 8px;
  font-variant-numeric: tabular-nums;
}
.score {
  display: grid; gap: 3px; text-align: right;
  font-size: 14px; font-weight: 700; min-width: 16px;
}
.score__pens { font-size: 11px; font-weight: 600; color: var(--text-faint); }
.match--live .score { color: var(--live); }
.match--upcoming .score { color: var(--text-faint); font-weight: 500; }

.badge {
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 3px 7px; border-radius: 5px;
  background: var(--surface-2); color: var(--text-dim);
}
.badge--live { background: var(--live-soft); color: var(--live); }

.match__venue {
  grid-column: 2 / -1;
  font-size: 11.5px; color: var(--text-faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

@media (max-width: 560px) {
  .match { grid-template-columns: 52px minmax(0, 1fr) auto; gap: 9px; padding: 9px 11px; }
  .team__name { font-size: 13.5px; }
  .league__round { display: none; }
  .match__venue { display: none; }
}

/* ------------------------------------------------------------------ states */

.state {
  text-align: center; padding: 40px 20px; color: var(--text-dim);
  background: var(--surface); border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
}
.state__title { margin: 0 0 6px; font-size: 16px; font-weight: 650; color: var(--text); }
.state__body { margin: 0 0 14px; font-size: 14px; }
.state--loading { display: flex; align-items: center; justify-content: center; gap: 10px; border-style: solid; }
.state--error { border-color: var(--live); }
.spinner {
  width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid var(--border-strong); border-top-color: var(--accent);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.sentinel { height: 1px; }
.more-hint { text-align: center; color: var(--text-faint); font-size: 13px; padding: 12px; }

/* --------------------------------------------------------------- ad slots */

/* Slots reserve height before a creative loads so the board never jumps. */
/* Slots reserve their height at all times — that is the whole point, and it is
   what stops a creative shifting the page when it loads. They are otherwise
   invisible: a bordered box labelled ADVERTISEMENT with nothing in it makes the
   page read as ad-heavy while showing no ads at all, which is the worst of both
   for a visitor and for an AdSense reviewer.

   The outline comes back only when no publisher id is configured, so the slots
   stay visible while developing. ads.js sets the attribute. */
.adslot {
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm);
  overflow: hidden;
}
:root[data-ads-unconfigured] .adslot {
  background: var(--surface-2);
  border: 1px dashed var(--border-strong);
  color: var(--text-faint);
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
}
:root[data-ads-unconfigured] .adslot:empty::after { content: "Advertisement"; }

/* Each slot declares the height it will need, but only *takes* it once a unit
   has mounted. Nothing mounts when there is no slot id, no consent, or an ad
   blocker — and reserving space for a creative that is never coming leaves a
   blank gap where content should be.
   Shift protection is unaffected: mountAd sets data-mounted before inserting
   the <ins>, so the box is already at full height when Google fills it. */
.adslot--leaderboard { --slot-h: 90px; margin-block: 12px; }
.adslot--rail       { --slot-h: 600px; }
.adslot--infeed     { --slot-h: 100px; margin-bottom: 10px; }
.adslot--anchor     { --slot-h: 50px; width: 100%; border: 0; border-radius: 0; }

.adslot[data-mounted="1"],
:root[data-ads-unconfigured] .adslot { min-height: var(--slot-h); }

@media (max-width: 560px) {
  .adslot--leaderboard { --slot-h: 100px; }
}

.anchor-ad {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: var(--surface); border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
}
.anchor-ad__close {
  position: absolute; top: -26px; right: 8px;
  width: 26px; height: 26px; border-radius: 50% 50% 0 0;
  background: var(--surface); border: 1px solid var(--border); border-bottom: 0;
  cursor: pointer; line-height: 1; font-size: 16px; color: var(--text-dim);
}
@media (min-width: 1081px) { .anchor-ad { display: none; } }
body.has-anchor-ad { padding-bottom: 62px; }

/* ------------------------------------------------------- consent + prose */

.consent {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  background: var(--surface);
  border-top: 1px solid var(--border-strong);
  box-shadow: 0 -6px 24px rgba(8, 12, 20, .16);
  padding: 12px 0 calc(12px + env(safe-area-inset-bottom));
}
.consent__inner {
  width: 100%; max-width: var(--shell); margin-inline: auto; padding-inline: 16px;
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
}
.consent__text { margin: 0; flex: 1 1 320px; font-size: 13.5px; color: var(--text-dim); }
.consent__text a { color: var(--text); }
.consent__actions { display: flex; gap: 8px; margin-left: auto; }
.chip--primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.chip--primary:hover { filter: brightness(1.08); }
body.has-consent-banner { padding-bottom: 92px; }
body.has-consent-banner .anchor-ad { bottom: 76px; }

/* Accept and Reject must carry identical visual weight — giving Accept the
   accent fill and leaving Reject plain is the single most commonly enforced
   dark pattern in EU consent decisions. Manage / Save stay as plain chips. */
.chip--decide {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
}
.chip--decide:hover { border-color: var(--accent); filter: brightness(.97); }
@media (prefers-color-scheme: dark) {
  .chip--decide:hover { filter: brightness(1.25); }
}

/* ------------------------------------------------------- consent settings */

.cpanel {
  position: fixed; inset: 0; z-index: 70;
  display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(8, 12, 20, .55);
}
.cpanel__box {
  width: 100%; max-width: 560px; max-height: min(84vh, 720px); overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius); box-shadow: 0 12px 40px rgba(8, 12, 20, .28);
  padding: 20px;
}
.cpanel__title { margin: 0 0 6px; font-size: 18px; letter-spacing: -.01em; }
.cpanel__intro { margin: 0 0 4px; font-size: 13px; color: var(--text-dim); }

.cpanel__row {
  display: flex; align-items: flex-start; gap: 16px;
  padding: 14px 0; border-bottom: 1px solid var(--border);
}
.cpanel__label { flex: 1 1 auto; }
.cpanel__label h3 { margin: 0 0 3px; font-size: 14px; }
.cpanel__label p { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--text-dim); }
.cpanel__control { flex: 0 0 auto; padding-top: 2px; }
.cpanel__always { font-size: 12px; font-weight: 600; color: var(--text-faint); }

.cpanel__actions {
  display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; padding-top: 16px;
}

/* Switches are real <button role="switch"> elements, so they inherit the
   global :focus-visible ring and work from the keyboard without extra wiring. */
.cswitch {
  width: 44px; height: 26px; padding: 3px; border-radius: 999px; cursor: pointer;
  background: var(--border-strong); border: 1px solid var(--border-strong);
  transition: background-color .14s ease, border-color .14s ease;
}
.cswitch__dot {
  display: block; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 2px rgba(16, 24, 40, .3);
  transition: transform .14s ease;
}
.cswitch[aria-checked="true"] { background: var(--accent); border-color: var(--accent); }
.cswitch[aria-checked="true"] .cswitch__dot { transform: translateX(18px); }

@media (max-width: 560px) {
  .cpanel__row { flex-wrap: wrap; gap: 8px; }
  .cpanel__actions .chip { flex: 1 1 auto; justify-content: center; }
}

.prose { max-width: 760px; padding-block: 26px 60px; }
.prose h1 { font-size: 26px; letter-spacing: -.02em; margin: 0 0 4px; }
.prose h2 { font-size: 17px; margin: 28px 0 6px; }
.prose p, .prose li { color: var(--text-dim); font-size: 15px; line-height: 1.6; }
.prose li { margin-bottom: 5px; }
.prose code {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 4px; padding: 1px 5px; font-size: 13px;
}
.prose h3 { font-size: 15px; margin: 20px 0 8px; }
.prose__table { width: 100%; border-collapse: collapse; margin: 4px 0 8px; }
.prose__table th, .prose__table td {
  text-align: left; vertical-align: top; padding: 9px 12px 9px 0;
  border-bottom: 1px solid var(--border);
  font-size: 13.5px; line-height: 1.55; font-weight: 400; color: var(--text-dim);
}
.prose__table thead th { font-weight: 600; color: var(--text); white-space: nowrap; }
.prose__table tbody th { font-weight: 600; color: var(--text); }
.prose__meta { font-size: 13px; color: var(--text-faint); margin-top: 0; }
.prose__note {
  background: var(--accent-soft); border: 1px solid var(--accent);
  border-radius: var(--radius-sm); padding: 11px 14px; margin: 18px 0;
  font-size: 14px; color: var(--text);
}
.prose__back { margin-top: 34px; }

.footer__links { margin: 8px 0 0; font-size: 12.5px; display: flex; gap: 8px; align-items: center; }
.footer__links a, .footer__linkbtn { color: var(--text-dim); }
.footer__linkbtn {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-size: 12.5px; text-decoration: underline;
}
.footer__linkbtn:hover { color: var(--text); }

/* ---------------------------------------------------------- match details */

/* z-index 55 puts the panel above the league picker (50) and the anchor ad
   (40) but below the consent banner (60) and its settings panel (70). Burying
   the consent gate under a fixture would be a compliance problem, not just an
   aesthetic one. */
.mpanel {
  position: fixed; inset: 0; z-index: 55;
  display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(8, 12, 20, .55);
}
.mpanel__box {
  width: 100%; max-width: 720px; max-height: min(88vh, 860px); overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius); box-shadow: 0 12px 40px rgba(8, 12, 20, .28);
}

.mpanel__head {
  position: sticky; top: 0; z-index: 1;
  background: var(--surface-2); border-bottom: 1px solid var(--border);
  padding: 12px 16px 14px;
}
.mpanel__bar { display: flex; align-items: center; gap: 10px; }
.mpanel__league {
  margin: 0; display: flex; align-items: center; gap: 7px; min-width: 0;
  font-size: 12.5px; font-weight: 600;
}
.mpanel__country { color: var(--text-dim); font-weight: 400; }
.mpanel__close {
  margin-left: auto; flex: none;
  width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border-strong);
  font-size: 17px; line-height: 1;
}
.mpanel__close:hover { border-color: var(--text-dim); }

.mpanel__meta {
  margin: 10px 0 0; display: flex; flex-wrap: wrap; gap: 4px 12px;
  font-size: 12px; color: var(--text-faint);
}

.mscore {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: start; gap: 12px;
  padding-top: 14px;
}
.mteam { display: grid; justify-items: center; gap: 7px; min-width: 0; text-align: center; }
.mteam__crest { width: 44px; height: 44px; object-fit: contain; }
.mteam__name { font-size: 14px; font-weight: 600; line-height: 1.3; }
.mteam--loser .mteam__name { color: var(--text-dim); font-weight: 500; }

.mscore__mid {
  display: grid; justify-items: center; gap: 3px;
  font-variant-numeric: tabular-nums; padding-top: 6px;
}
.mscore__goals { font-size: 30px; font-weight: 700; letter-spacing: -.02em; }
.mscore__dash { color: var(--text-faint); margin: 0 4px; font-weight: 500; }
.mscore__kick { font-size: 22px; font-weight: 650; }
.mscore__pens { font-size: 11.5px; color: var(--text-faint); }
.mscore__state {
  font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-faint);
}
.mscore__state--live { color: var(--live); }
.mscore--live .mscore__goals { color: var(--live); }
.mscore--upcoming .mscore__kick { color: var(--text-dim); }

.mpanel__body { padding: 4px 16px 16px; }

.msec { border-bottom: 1px solid var(--border); }
.msec:last-child { border-bottom: 0; }
.msec__head {
  padding: 13px 2px; cursor: pointer; list-style: none;
  font-size: 13px; font-weight: 650; letter-spacing: -.005em;
  display: flex; align-items: center; gap: 7px;
}
.msec__head::-webkit-details-marker { display: none; }
/* Hand-rolled marker: the native one cannot be positioned or recoloured, and
   sits on the wrong side in some engines. */
.msec__head::after {
  content: '▼'; margin-left: auto; font-size: 9px; color: var(--text-faint);
  transition: transform .15s ease;
}
.msec:not([open]) .msec__head::after { transform: rotate(-90deg); }
.msec__body { padding: 0 2px 15px; }
.msec__pending {
  margin: 0; display: flex; align-items: center; gap: 9px;
  font-size: 13px; color: var(--text-dim);
}
.msec__empty { margin: 0; font-size: 13px; color: var(--text-faint); }

@media (prefers-reduced-motion: reduce) {
  .msec__head::after { transition: none; }
}

/* ---- comparison bars ---- */

/* Home grows leftwards from the centre, away rightwards, so the eye can read
   which side is ahead without comparing two numbers. */
.cmp { display: grid; gap: 11px; }
.cmp__row {
  display: grid;
  grid-template-columns: 42px 1fr 42px;
  align-items: center; gap: 8px;
  font-variant-numeric: tabular-nums;
}
.cmp__val { font-size: 13px; font-weight: 650; }
.cmp__val--away { text-align: right; }
.cmp__label {
  text-align: center; font-size: 11.5px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cmp__track {
  grid-column: 1 / -1;
  display: flex; gap: 2px; height: 6px;
  background: var(--surface-2); border-radius: 3px; overflow: hidden;
}
.cmp__fill { height: 100%; }
.cmp__fill--home { background: var(--accent); border-radius: 3px 0 0 3px; }
.cmp__fill--away { background: var(--accent-alt); border-radius: 0 3px 3px 0; }

/* ---- timeline ---- */

/* A vertical timeline, newest first: the last thing to happen is the thing
   someone opening a match in play is looking for. Above 560px it becomes
   two-sided around a centre rule — home events left, away right — which is what
   carries the team without repeating a club name on every row. */
.tline { position: relative; }
.tline__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 11px; }
.tline__item {
  display: grid; grid-template-columns: 38px minmax(0, 1fr);
  gap: 9px; align-items: start;
}
.tline__min {
  font-size: 11.5px; font-weight: 700; color: var(--text-dim);
  font-variant-numeric: tabular-nums; text-align: right; padding-top: 1px;
}
.tline__body { display: flex; gap: 8px; min-width: 0; align-items: flex-start; }
.tline__icon { flex: none; display: flex; padding-top: 1px; }
.tline__icon svg { width: 15px; height: 15px; }
.tline__text { display: grid; gap: 1px; min-width: 0; }
.tline__who { font-size: 13px; font-weight: 550; }
.tline__note, .tline__team { font-size: 11px; color: var(--text-faint); }
.tline__item--home .tline__icon { color: var(--accent); }
.tline__item--away .tline__icon { color: var(--accent-alt); }

/* The fold. A native <details>, so it costs no JavaScript and no inline
   handler, which keeps the page CSP-clean. */
/* Grid with default stretch, so the nested list still fills the width and keeps
   its two-sided alignment; only the toggle itself is centred. The gap matches
   the list's own row gap, so an expanded fold is indistinguishable from one
   continuous timeline. */
.tline__earlier { margin-top: 11px; display: grid; gap: 11px; }
.tline__more {
  justify-self: center;
  cursor: pointer; list-style: none;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 11.5px; font-weight: 650; color: var(--text-dim);
}
.tline__more::-webkit-details-marker { display: none; }
.tline__more::after { content: '▾'; font-size: 9px; }
.tline__more:hover { border-color: var(--border-strong); color: var(--text); }

/* Only one of the two labels is ever shown. Once open the control drops below
   the events it revealed, where a "hide" belongs. */
.tline__earlier[open] .tline__more { order: 2; }
.tline__earlier[open] .tline__more::after { content: '▴'; }
.tline__earlier:not([open]) .tline__more--hide { display: none; }
.tline__earlier[open] .tline__more--show { display: none; }

@media (min-width: 561px) {
  /* Two-sided. The middle column is fixed and the flanks are equal fractions,
     so the column's centre is the box's centre — which is what lets the rule be
     a plain background gradient rather than a positioned element. */
  .tline__list {
    background: linear-gradient(var(--border), var(--border)) center / 2px 100% no-repeat;
  }
  .tline__item {
    grid-template-columns: minmax(0, 1fr) 52px minmax(0, 1fr);
    gap: 0; align-items: center;
  }
  /* Opaque, so the rule passes behind the row rather than through the minute. */
  .tline__min {
    grid-column: 2; text-align: center; padding: 2px 0;
    background: var(--surface);
  }
  .tline__item--home .tline__body {
    grid-column: 1; flex-direction: row-reverse; justify-content: flex-start;
    padding-right: 12px;
  }
  .tline__item--home .tline__text { text-align: right; }
  .tline__item--away .tline__body { grid-column: 3; padding-left: 12px; }
  /* Carried by the side of the rule instead; see the key above the list. */
  .tline__team { display: none; }
}

/* The key names the two sides of the rule. Below 561px there are no sides, and
   each row carries its own team label instead. */
.tline__key { display: none; }
@media (min-width: 561px) {
  .tline__key {
    display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 16px;
    margin: 0 0 12px; font-size: 11px; font-weight: 650;
  }
  .tline__keyitem { display: flex; align-items: center; gap: 6px; min-width: 0; }
  .tline__keyitem::before {
    content: ''; flex: none;
    width: 8px; height: 8px; border-radius: 50%; background: currentColor;
  }
  .tline__keyitem--home { color: var(--accent); }
  .tline__keyitem--away { color: var(--accent-alt); }
  .tline__keyitem--away::before { order: 1; }
}

/* ---- line-ups ---- */

.lineup { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.lineup__side { min-width: 0; }
.lineup__team {
  margin: 0 0 3px; font-size: 13px; font-weight: 650;
  display: flex; align-items: center; gap: 7px; min-width: 0;
}
.lineup__crest { width: 20px; height: 20px; object-fit: contain; flex: none; }
.lineup__meta {
  margin: 0 0 10px; display: flex; flex-wrap: wrap; gap: 4px 10px;
  font-size: 11.5px; color: var(--text-dim);
}
.lineup__formation {
  font-weight: 700; font-variant-numeric: tabular-nums;
  background: var(--accent-soft); color: var(--accent);
  border-radius: 4px; padding: 1px 6px;
}
.lineup__heading {
  margin: 12px 0 5px; font-size: 10.5px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--text-faint);
}
.lineup__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 3px; }
.lineup__player {
  display: grid; grid-template-columns: 20px minmax(0, 1fr) auto;
  align-items: center; gap: 8px;
  font-size: 12.5px;
}
.lineup__num {
  font-variant-numeric: tabular-nums; text-align: right;
  font-size: 11px; font-weight: 700; color: var(--text-faint);
}
.lineup__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lineup__pos {
  font-size: 9.5px; font-weight: 700; letter-spacing: .04em;
  color: var(--text-faint); background: var(--surface-2);
  border-radius: 3px; padding: 1px 4px;
}

@media (max-width: 560px) {
  .lineup { grid-template-columns: 1fr; gap: 18px; }
}

/* ---- head-to-head ---- */

.h2h__summary {
  margin: 0 0 10px; display: flex; flex-wrap: wrap; gap: 4px 14px;
  font-size: 12px; font-weight: 650;
}
.h2h__for { font-weight: 400; color: var(--text-faint); }
.h2h__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.h2h__row {
  display: grid; grid-template-columns: 20px minmax(0, 1fr) auto;
  align-items: baseline; gap: 3px 9px;
  font-size: 12.5px;
}
.h2h__mark {
  grid-row: 1 / 3;
  align-self: center; text-align: center;
  width: 20px; height: 20px; line-height: 20px; border-radius: 5px;
  font-size: 10px; font-weight: 700; color: #fff;
}
.h2h__mark--w { background: var(--accent); }
.h2h__mark--d { background: var(--border-strong); color: var(--text-dim); }
.h2h__mark--l { background: var(--live); }
.h2h__teams { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.h2h__teams b { font-variant-numeric: tabular-nums; }
.h2h__when { font-size: 11px; color: var(--text-faint); white-space: nowrap; }
.h2h__league {
  grid-column: 2 / -1; font-size: 11px; color: var(--text-faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- predictions ---- */

.pred__bar {
  display: flex; height: 26px; border-radius: var(--radius-sm); overflow: hidden;
  font-size: 11px; font-weight: 700; color: #fff;
}
.pred__seg {
  display: flex; align-items: center; justify-content: center;
  min-width: 0; overflow: hidden;
}
.pred__seg--home { background: var(--accent); }
.pred__seg--draw { background: var(--border-strong); color: var(--text-dim); }
.pred__seg--away { background: var(--accent-alt); }
.pred__legend {
  margin: 5px 0 0; display: flex; justify-content: space-between; gap: 8px;
  font-size: 11px; color: var(--text-dim);
}
.pred__legend span:nth-child(2) { text-align: center; }
.pred__legend span:last-child { text-align: right; }
.pred__advice {
  margin: 12px 0 0; padding: 9px 12px;
  background: var(--accent-soft); border-radius: var(--radius-sm);
  font-size: 12.5px; font-weight: 550;
}

.radar {
  margin-top: 14px;
  display: grid; grid-template-columns: minmax(0, 264px) minmax(0, 1fr);
  align-items: center; gap: 16px;
}
.radar__svg { width: 100%; height: auto; }
.radar__ring, .radar__spoke { fill: none; stroke: var(--border); stroke-width: 1; }
.radar__ring:last-of-type { stroke: var(--border-strong); }
.radar__area { stroke-width: 2; }
/* Low fill opacity so the two shapes read where they overlap, which is most of
   the chart for two evenly matched teams. */
.radar__area--home { fill: var(--accent); fill-opacity: .22; stroke: var(--accent); }
.radar__area--away { fill: var(--accent-alt); fill-opacity: .22; stroke: var(--accent-alt); }
.radar__label { fill: var(--text-dim); font-size: 10.5px; font-weight: 600; }

.radar__table { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.radar__table li {
  display: grid; grid-template-columns: minmax(0, 1fr) 44px 44px;
  gap: 8px; font-size: 12px; font-variant-numeric: tabular-nums;
}
.radar__table li span:not(.radar__key) { text-align: right; }
.radar__key { color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.radar__head {
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-faint); padding-bottom: 2px; border-bottom: 1px solid var(--border);
}
.radar__table li:not(.radar__head) span:nth-child(2) { color: var(--accent); font-weight: 650; }
.radar__table li:not(.radar__head) span:nth-child(3) { color: var(--accent-alt); font-weight: 650; }

@media (max-width: 560px) {
  .radar { grid-template-columns: 1fr; }
}

/* ---- odds ---- */

.odds__market { margin-bottom: 12px; }
.odds__name {
  margin: 0 0 5px; font-size: 10.5px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--text-faint);
}
.odds__values { display: flex; flex-wrap: wrap; gap: 6px; }
.odds__value {
  display: flex; align-items: baseline; gap: 7px;
  padding: 6px 10px; border-radius: var(--radius-sm);
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 12px; font-variant-numeric: tabular-nums;
}
.odds__pick { color: var(--text-dim); }
.odds__value b { font-weight: 700; }
/* A suspended price is still real information — the market exists, it is just
   not being taken right now — so it is dimmed rather than dropped. */
.odds__value--suspended { opacity: .45; text-decoration: line-through; }
.odds__note {
  margin: 12px 0 0; font-size: 11px; line-height: 1.5; color: var(--text-faint);
}

@media (max-width: 560px) {
  .mpanel { padding: 0; align-items: flex-end; }
  .mpanel__box { max-height: 92vh; border-radius: var(--radius) var(--radius) 0 0; border-bottom: 0; }
  .mteam__crest { width: 36px; height: 36px; }
  .mteam__name { font-size: 13px; }
  .mscore__goals { font-size: 26px; }
}

/* ----------------------------------------------------------------- footer */

.footer {
  border-top: 1px solid var(--border);
  background: var(--surface);
  padding-block: 22px 30px;
}
.footer__inner { display: grid; gap: 5px; }
.footer__brand {
  margin: 0 0 2px; font-size: 14px; color: var(--text-dim);
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
}
.footer__logo { height: 24px; }
.footer__meta, .footer__legal { margin: 0; font-size: 12.5px; color: var(--text-faint); }
.footer__meta a { color: var(--text-dim); }

/* Shown only when the hourly refresh job has stopped; see setUpdatedLabel(). */
.stale {
  margin: 8px 0 0; padding: 9px 13px;
  background: var(--live-soft); color: var(--live);
  border: 1px solid currentColor; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 500;
}
