/* Matchday — components built on the tokens extracted from the mockups. */

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
html, body { overflow-x: clip; }
body {
  margin: 0; background: var(--fa-bg); color: var(--fa-ink);
  font-family: var(--fa-font); font-size: var(--fa-t-body); line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--fa-primary); outline-offset: 2px; border-radius: 6px; }
.num, .tnum { font-variant-numeric: tabular-nums; }

/* ============================================================
   The shell — juno's panel, wearing football clothes
   ============================================================
   Matchday was a phone layout stretched across a desktop: a top app bar, a
   row of tab pills, one 720px column down the middle. It also looked like a
   different product from everything else Feras runs.

   So the frame is juno's admin panel, part for part, because these apps
   should feel like one system:

     brand row → scope switcher → labelled sections with counts → quiet pair

   The scope switcher is the piece that carries the resemblance, and it is
   not decoration: juno narrows everything below it to one app, and this
   narrows everything below it to one competition. "All competitions" gets
   no tint and no bar — in juno the absence of the accent is itself the
   signal that nothing is being narrowed, and that reads the same here.

   What is skinned differently is only what football needs: a competition
   tint instead of an app tint, crests in the following list, and a live dot
   that means a followed team is playing right now.

   The one juno detail worth naming, because getting it wrong is what made
   the first attempt look like a different app: the active row is a SOFT
   GREY FILL, not a solid ink pill. juno never puts a black block in its
   sidebar.
   ============================================================ */

:root { --side: 260px; --fold: 1000px; --content: 1180px; }

.shell { min-height: 100vh; }

.side {
  position: fixed; inset: 0 auto 0 0; width: var(--side); z-index: 20;
  display: flex; flex-direction: column; overflow-y: auto;
  background: var(--fa-surface); border-right: 1px solid var(--fa-hairline);
}

/* ---- brand row ---- */
.side-brand {
  display: flex; align-items: center; gap: var(--fa-s-3);
  padding: var(--fa-s-4) var(--fa-s-4);
  border-bottom: 1px solid var(--fa-hairline);
  font-size: var(--fa-t-title2); font-weight: var(--fa-w-bold);
  letter-spacing: var(--fa-ls-display); color: var(--fa-ink);
}
.side-brand svg { width: 22px; height: 22px; flex: none; color: var(--fa-ink); }

/* ---- nav ---- */
.side-nav { display: flex; flex-direction: column; gap: 1px; padding: 0 var(--fa-s-3); }
.nav-label {
  font-size: 11px; font-weight: var(--fa-w-medium); text-transform: uppercase;
  letter-spacing: var(--fa-ls-caption); color: var(--fa-muted);
  padding: var(--fa-s-4) var(--fa-s-3) var(--fa-s-2);
}
.nav-label:first-child { padding-top: 0; }
.nav-item {
  width: 100%; display: flex; align-items: center; gap: var(--fa-s-3);
  padding: 8px var(--fa-s-3); border-radius: var(--fa-r-chip);
  font-size: 14px; color: var(--fa-ink-2); cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.nav-item svg { width: 16px; height: 16px; flex: none; fill: none;
  stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.nav-item img { width: 18px; height: 18px; object-fit: contain; flex: none; }
.nav-item > span { flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
/* …except a crest, which is also a span and was being stretched by that
   `flex: 1` into an ellipse with a squashed badge inside it. */
.nav-item > .crest { flex: none; }
.nav-item .crest img { width: 100%; height: 100%; }
.nav-item:hover { background: var(--fa-surface-2); }
.nav-item[aria-current="page"] {
  background: var(--fa-raised); color: var(--fa-ink); font-weight: var(--fa-w-medium);
}
.nav-count {
  margin-left: auto; font-size: 12px; color: var(--fa-muted);
  font-variant-numeric: tabular-nums;
}
.nav-count.live { color: var(--fa-live); font-weight: var(--fa-w-semi); }
.nav-blank { width: 18px; height: 18px; border-radius: 50%;
  background: var(--fa-surface-2); flex: none; }
/* A dot means that team is playing RIGHT NOW, derived from the matches on
   screen. There is no unread concept here, and a badge that merely looked
   like one would be decoration pretending to be information. */
.livedot { width: 7px; height: 7px; border-radius: 50%; background: var(--fa-live); flex: none; }
.nav-hint { padding: 2px var(--fa-s-3) var(--fa-s-2); font-size: 12px; color: var(--fa-muted); }

/* Two peers sharing a row — juno's "Security · Backups". */
.nav-pair { display: flex; align-items: center; gap: 2px; padding: var(--fa-s-3) var(--fa-s-3) 0; }
.nav-pair button {
  font: inherit; font-size: 14px; color: var(--fa-ink-2);
  border: 0; background: none; cursor: pointer; padding: 6px 0;
  transition: color .12s ease;
}
.nav-pair button:hover { color: var(--fa-ink); }
.nav-pair button[data-active] { color: var(--fa-ink); font-weight: var(--fa-w-medium); }
.nav-pair-sep { color: var(--fa-muted); font-size: 12px; padding: 0 4px; }

.side-foot {
  margin-top: auto; padding: var(--fa-s-4);
  border-top: 1px solid var(--fa-hairline);
  font-size: 12px; color: var(--fa-muted);
  display: flex; align-items: center; gap: var(--fa-s-2);
}

/* ---- page ---- */
.main { margin-left: var(--side); min-height: 100vh; display: flex; flex-direction: column; }

/* A reading column has a width past which it stops being one.
   Nothing capped this, so the page simply took the viewport: at 2000px a match
   row put the club name and its score 640px apart, and pairing them by eye
   meant crossing the gap. The topbar and footer are capped with it so the page
   keeps a single left edge instead of the heading starting somewhere the
   content does not. */
.topbar, #view, .foot { width: 100%; max-width: var(--content); margin-inline: auto; }
.topbar {
  display: flex; align-items: center; gap: var(--fa-s-4);
  padding: var(--fa-s-5) var(--fa-s-6) var(--fa-s-4);
}
.topbar-title { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.topbar-title h1 {
  margin: 0; font-size: var(--fa-t-title1); font-weight: var(--fa-w-bold);
  letter-spacing: var(--fa-ls-display); color: var(--fa-ink);
  display: flex; align-items: center; gap: var(--fa-s-3); flex-wrap: wrap;
}
.topbar-title p { margin: 0; font-size: var(--fa-t-footnote); color: var(--fa-muted); }
/* The competition the scores page has been narrowed to — a badge beside the
   heading, not part of it. With no rules at all it rendered in the heading's
   own 28px bold, so "Scores Premier League" read as the name of the page. The
   dot takes the competition's colour, which the markup has always set on
   `--tint` and nothing has ever used. */
.scope-tag {
  display: inline-flex; align-items: center; gap: 6px; vertical-align: middle;
  padding: 4px 10px; border-radius: var(--fa-r-pill);
  background: var(--fa-surface-2); border: 1px solid var(--fa-hairline);
  font-size: var(--fa-t-footnote); font-weight: var(--fa-w-regular);
  /* Ink, not muted: muted on this surface measures 2.91 in light, under the
     4.5 normal text needs. The badge stays secondary by size and shape. */
  letter-spacing: 0; color: var(--fa-ink);
}
/* The tint pulled away from the pill it sits on, which `--fa-ink` is by
   definition in either theme: the Premier League's #38003c is a fine dot on a
   pale pill and invisible on a dark one. */
.scope-dot {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: color-mix(in srgb, var(--tint) 45%, var(--fa-ink) 55%);
}
.topbar-search {
  display: flex; align-items: center; gap: var(--fa-s-2); height: 36px;
  width: min(360px, 30vw); flex: none;
  background: var(--fa-surface-2); border: 1px solid transparent;
  border-radius: var(--fa-r-chip); padding: 0 var(--fa-s-3);
}
.topbar-search:focus-within { border-color: var(--fa-ink); background: var(--fa-surface); }
.topbar-search svg { width: 16px; height: 16px; flex: none; fill: none;
  stroke: var(--fa-muted); stroke-width: 1.75; stroke-linecap: round; }
.topbar-search input {
  flex: 1; min-width: 0; border: 0; background: none; outline: none;
  font: inherit; font-size: var(--fa-t-body); color: var(--fa-ink);
}
.topbar-search input::placeholder { color: var(--fa-muted); }
.topbar-search kbd {
  font-family: var(--fa-font-num); font-size: 11px; color: var(--fa-muted);
  border: 1px solid var(--fa-hairline); border-radius: 5px; padding: 1px 5px;
}
.icon-btn {
  width: 32px; height: 32px; flex: none; display: grid; place-items: center;
  border: 0; background: transparent; border-radius: var(--fa-r-chip);
  cursor: pointer; color: var(--fa-ink-2);
}
.icon-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.icon-btn:hover { background: var(--fa-surface-2); }
/* display:grid beats the [hidden] attribute's display:none, so the back
   arrow sat on the home page pointing nowhere. */
.icon-btn[hidden] { display: none; }
/* The menu button exists only below the fold. */
.menu-btn { display: none; }
/* ---------- section header (EVENTS ... SEE ALL) ---------- */
.sec-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--fa-s-3);
  margin: var(--fa-s-6) 0 var(--fa-s-2);
}
.sec-head:first-child { margin-top: 0; }
.sec-head h2, .sec-head h3 {
  margin: 0; font-size: var(--fa-t-caption); font-weight: var(--fa-w-semi);
  letter-spacing: var(--fa-ls-caption); text-transform: uppercase; color: var(--fa-muted);
}
.sec-head a { font-size: var(--fa-t-caption); font-weight: var(--fa-w-semi);
  letter-spacing: var(--fa-ls-caption); text-transform: uppercase; color: var(--fa-primary); }
/* The quiet right-hand half of a section heading: "DraftKings", "23 entries". */
.sec-note { font-size: var(--fa-t-caption); color: var(--fa-muted); }
/* Unless the heading also has a link. Then space-between strands the note
   halfway across the row, where it reads as a third column rather than as a
   qualifier on the title it belongs to. */
.sec-head:has(.sec-more) .sec-note { margin-right: auto; }

.card {
  max-width: 100%;
  background: var(--fa-surface); border-radius: var(--fa-r-card);
  box-shadow: var(--fa-shadow-card); overflow: hidden; margin-bottom: var(--fa-s-3);
}
.card-pad { padding: var(--fa-s-4); }

/* ============================================================
   The three panes
   ============================================================
   Sidebar, list, rail. The rail is where a match opens when there is room
   beside the list it was opened from — on a narrow screen the same markup
   becomes the page, because it is the same question either way. */

.shell[data-rail] .main { margin-right: var(--rail); }
:root { --rail: 420px; }

.rail {
  position: fixed; inset: 0 0 0 auto; width: var(--rail); z-index: 15;
  overflow-y: auto; padding: var(--fa-s-5);
  background: var(--fa-surface); border-left: 1px solid var(--fa-hairline);
}
.rail[hidden] { display: none; }
.rail-close {
  position: sticky; top: 0; float: right; z-index: 2;
  width: 30px; height: 30px; border: 0; border-radius: 50%;
  background: var(--fa-surface-2); color: var(--fa-ink-2); cursor: pointer;
}

#view { padding: 0 var(--fa-s-6) var(--fa-s-8); flex: 1; }
.foot { padding: var(--fa-s-6); font-size: var(--fa-t-footnote); color: var(--fa-muted); }
/* The credits do not take part in loading. A skeleton is much shorter than the
   page it stands in for, so the footer sat mid-screen and was shoved down when
   the data arrived — the largest single layout shift on every page. It appears
   once, already in its final place, and nothing sits below it to be moved. */
.main:has(.skeleton-page, .skeleton-list, .skeleton-grid) .foot { display: none; }
/* Which commit this is. Quiet when it agrees with the disk, and not quiet at
   all when the process is running code older than the files it is serving. */
.build { font-variant-numeric: tabular-nums; }
.build.is-stale { color: var(--fa-loss); font-weight: 600; }

/* ---------- shared atoms ---------- */

.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.quiet { color: var(--fa-muted); font-size: var(--fa-t-footnote); margin: var(--fa-s-3) 0 0; }
.is-unknown { color: var(--fa-muted); font-weight: var(--fa-w-regular); }

.btn-quiet {
  display: inline-flex; align-items: center; gap: 6px; margin-top: var(--fa-s-3);
  padding: 7px 12px; border: 1px solid var(--fa-hairline); border-radius: var(--fa-r-chip);
  background: var(--fa-surface); color: var(--fa-ink); font-size: var(--fa-t-footnote);
  font-weight: var(--fa-w-medium); cursor: pointer;
}
.btn-quiet:hover { background: var(--fa-surface-2); }

.empty {
  display: grid; justify-items: start; gap: 4px; padding: var(--fa-s-6);
  background: var(--fa-surface); border-radius: var(--fa-r-card);
  border: 1px dashed var(--fa-hairline); color: var(--fa-muted);
  font-size: var(--fa-t-footnote);
}
.empty b { font-size: var(--fa-t-headline); color: var(--fa-ink); font-weight: var(--fa-w-semi); }
.empty.is-error { border-color: var(--fa-loss); }

.notice {
  display: flex; align-items: center; gap: var(--fa-s-3); flex-wrap: wrap;
  padding: 10px var(--fa-s-4); margin-bottom: var(--fa-s-3);
  background: var(--fa-surface-2); border-radius: var(--fa-r-chip);
  font-size: var(--fa-t-footnote); color: var(--fa-ink-2);
}
.notice .btn-quiet { margin: 0; padding: 4px 10px; }

.chip {
  display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px;
  border: 1px solid var(--fa-hairline); border-radius: var(--fa-r-pill);
  background: var(--fa-surface); color: var(--fa-ink-2);
  font-size: var(--fa-t-footnote); font-weight: var(--fa-w-medium); cursor: pointer;
  white-space: nowrap;
}
.chip:hover { background: var(--fa-surface-2); }
.chip.is-on { background: var(--fa-ink); border-color: var(--fa-ink); color: var(--fa-surface); }
.chip em { font-style: normal; font-variant-numeric: tabular-nums; opacity: .7; }
.seg { display: flex; gap: 6px; flex-wrap: wrap; }

.crumbs { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: var(--fa-t-footnote); color: var(--fa-muted); padding: var(--fa-s-2) 0 var(--fa-s-4); }
.crumbs a { color: var(--fa-primary); }
.crumbs i { font-style: normal; opacity: .5; }

.tabs {
  display: flex; gap: var(--fa-s-5); overflow-x: auto; scrollbar-width: none;
  border-bottom: 1px solid var(--fa-hairline); margin: var(--fa-s-5) 0 var(--fa-s-5);
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  padding: 0 2px 10px; white-space: nowrap; color: var(--fa-muted);
  font-size: var(--fa-t-body); font-weight: var(--fa-w-medium);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tab:hover { color: var(--fa-ink); }
.tab.is-on { color: var(--fa-primary); border-bottom-color: var(--fa-primary); font-weight: var(--fa-w-semi); }

.sec { margin: var(--fa-s-6) 0; }
.sec-more { font-size: var(--fa-t-caption); font-weight: var(--fa-w-semi);
  letter-spacing: var(--fa-ls-caption); text-transform: uppercase; color: var(--fa-primary); }
.sec-more i { font-style: normal; }

.season-sel select, .squad-sort select {
  height: 34px; padding: 0 var(--fa-s-3); border-radius: var(--fa-r-chip);
  border: 1px solid var(--fa-hairline); background: var(--fa-surface);
  color: var(--fa-ink); font: inherit; font-size: var(--fa-t-footnote); cursor: pointer;
}

/* Crests and portraits reserve their box before the image lands, so nothing
   reflows when a hundred of them arrive. */
.crest, .portrait {
  position: relative; display: inline-grid; place-items: center; flex: none;
  width: var(--size); height: var(--size); border-radius: 50%;
  background: var(--fa-surface-2); overflow: hidden;
}
.crest img, .portrait img { width: 100%; height: 100%; object-fit: contain; }
.portrait img { object-fit: cover; object-position: top center; }
.crest-fallback, .portrait-fallback {
  position: absolute; font-size: calc(var(--size) * .36); font-weight: var(--fa-w-semi);
  color: var(--fa-muted); letter-spacing: -.02em;
}
.crest img + .crest-fallback, .portrait img + .portrait-fallback { display: none; }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 1px;
  background: var(--fa-hairline); border-radius: var(--fa-r-card); overflow: hidden; }
.tile { background: var(--fa-surface); padding: var(--fa-s-4); display: grid; gap: 2px; }
.tile-v { font-size: var(--fa-t-title1); font-weight: var(--fa-w-bold); font-variant-numeric: tabular-nums; }
.tile-l { font-size: var(--fa-t-footnote); color: var(--fa-muted); }
.tile-s { font-size: 11px; color: var(--fa-muted); }

.form { display: inline-flex; gap: 3px; }
.form i, .form a {
  width: 20px; height: 20px; display: grid; place-items: center; border-radius: 5px;
  font-size: 11px; font-weight: var(--fa-w-bold); font-style: normal;
  background: var(--fa-surface-2); color: var(--fa-ink-2);
}
.form .f-w { background: color-mix(in srgb, var(--fa-win) 18%, transparent); color: var(--fa-win); }
.form .f-l { background: color-mix(in srgb, var(--fa-loss) 18%, transparent); color: var(--fa-loss); }
.form .f-d { background: var(--fa-surface-2); color: var(--fa-ink-2); }

.cmp-head { display: flex; justify-content: space-between; font-size: var(--fa-t-footnote);
  color: var(--fa-muted); margin-bottom: var(--fa-s-3); }
.cmp { display: grid; grid-template-columns: 56px 1fr 56px; align-items: center;
  gap: var(--fa-s-2); margin-bottom: var(--fa-s-4); }
.cmp-a, .cmp-b { font-variant-numeric: tabular-nums; font-weight: var(--fa-w-semi); font-size: var(--fa-t-body); }
.cmp-b { text-align: right; }
.cmp-label { text-align: center; font-size: var(--fa-t-footnote); color: var(--fa-muted); }
.cmp-bar { grid-column: 1 / -1; display: flex; gap: 3px; height: 5px; }
.cmp-bar i { border-radius: 3px; }
.cmp-bar i:first-child { background: var(--fa-primary); }
.cmp-bar i:last-child { background: var(--fa-dotted, var(--fa-surface-2)); }

.detail-rows { margin-top: var(--fa-s-4); }
.drow { display: flex; justify-content: space-between; padding: 11px 0;
  border-bottom: 1px solid var(--fa-hairline); font-size: var(--fa-t-body); }
.drow span { color: var(--fa-muted); }
.drow b { font-variant-numeric: tabular-nums; }

/* ---------- scores ---------- */

.shortcuts { display: flex; gap: var(--fa-s-3); overflow-x: auto; scrollbar-width: none;
  padding-bottom: var(--fa-s-2); margin-bottom: var(--fa-s-4); }
.shortcuts::-webkit-scrollbar { display: none; }
.shortcut {
  display: flex; align-items: center; gap: var(--fa-s-3); flex: none;
  padding: 10px var(--fa-s-4); border-radius: var(--fa-r-card);
  background: var(--fa-surface); border: 1px solid var(--fa-hairline);
  font-weight: var(--fa-w-semi); font-size: var(--fa-t-footnote);
}
.shortcut:hover { border-color: var(--fa-ink); }
.shortcut.is-add { color: var(--fa-muted); font-weight: var(--fa-w-regular); border-style: dashed; }
.s-plus { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  background: var(--fa-surface-2); font-weight: var(--fa-w-bold); }

.datebar { background: var(--fa-surface); border: 1px solid var(--fa-hairline);
  border-radius: var(--fa-r-card); margin-bottom: var(--fa-s-4); position: relative; }
.datebar-top { display: flex; align-items: center; justify-content: space-between;
  gap: var(--fa-s-3); padding: var(--fa-s-3) var(--fa-s-4); border-bottom: 1px solid var(--fa-hairline); }
.date-jump { display: flex; align-items: center; gap: var(--fa-s-2); border: 0; background: none;
  cursor: pointer; font-size: var(--fa-t-body); color: var(--fa-ink); padding: 4px 0; }
.date-jump svg { width: 16px; height: 16px; fill: none; stroke: var(--fa-muted);
  stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.date-jump .caret { width: 14px; height: 14px; }
.datebar-nav { display: flex; align-items: center; gap: 4px; }
.datebar-nav .btn-quiet { margin: 0; padding: 5px 10px; color: var(--fa-primary); border-color: transparent; }

.week { display: grid; grid-template-columns: repeat(7, 1fr); }
.day { display: grid; justify-items: center; gap: 3px; padding: 10px 2px 12px;
  border: 0; background: none; cursor: pointer; border-radius: var(--fa-r-tile); position: relative; }
.day:hover { background: var(--fa-surface-2); }
.d-wd { font-size: 11px; color: var(--fa-muted); text-transform: uppercase; letter-spacing: var(--fa-ls-caption); }
.d-num { font-size: var(--fa-t-headline); font-weight: var(--fa-w-semi); font-variant-numeric: tabular-nums; }
/* The colour goes on the cell, so everything in it inverts together — the
   weekday, the number, and the dot that says the day has been loaded. */
.day.is-on { background: var(--fa-ink); color: var(--fa-surface); }
.day.is-on .d-wd, .day.is-on .d-num { color: var(--fa-surface); }
.day.is-today .d-num { color: var(--fa-primary); }
.day.is-on.is-today .d-num { color: var(--fa-surface); }
/* `currentColor`, for the same reason the calendar's dot uses it: this app's
   primary IS its ink, so on the selected day — a cell filled with the ink —
   the dot was drawn in its own background and measured contrast 1. Every other
   day sat at 17.17. */
.d-dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.d-dot.is-none, .d-dot.is-unknown { background: transparent; }
.datebar-tz { margin: 0; padding: 0 var(--fa-s-4) var(--fa-s-3); font-size: 11px; color: var(--fa-muted); }

.cal { position: absolute; z-index: 40; top: 52px; left: var(--fa-s-4);
  width: 300px; padding: var(--fa-s-4); background: var(--fa-surface);
  border: 1px solid var(--fa-hairline); border-radius: var(--fa-r-card); box-shadow: var(--fa-shadow-sheet); }
.cal-head { display: flex; align-items: center; justify-content: space-between; gap: 4px; margin-bottom: var(--fa-s-3); }
.cal-head b { flex: 1; text-align: center; font-size: var(--fa-t-body); }
.cal-wd, .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-wd span { text-align: center; font-size: 10px; color: var(--fa-muted); padding-bottom: 4px; }
.cal-day { aspect-ratio: 1; border: 0; background: none; border-radius: 7px; cursor: pointer;
  font-size: var(--fa-t-footnote); font-variant-numeric: tabular-nums; color: var(--fa-ink-2); position: relative; }
.cal-day:hover { background: var(--fa-surface-2); }
/* `currentColor`, so the dot follows whatever the cell's own number is: muted
   on a plain day, inverted on the selected one, the accent on today. It was
   `--fa-primary`, which is the same colour as the selected cell's background —
   so the dot on the day you were looking at, the one day certain to be loaded,
   was the only one you could not see, under a legend promising dots. */
.cal-day[data-has]::after { content: ""; position: absolute; bottom: 3px; left: 50%; translate: -50% 0;
  width: 4px; height: 4px; border-radius: 50%; background: currentColor; }
.cal-day.is-on { background: var(--fa-ink); color: var(--fa-surface); }
.cal-day.is-today { color: var(--fa-primary); font-weight: var(--fa-w-bold); }
.cal-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--fa-s-2);
  margin-top: var(--fa-s-3); font-size: 11px; color: var(--fa-muted); }
.cal-foot .btn-quiet { margin: 0; padding: 4px 9px; }

.filters { display: flex; align-items: center; gap: 6px; margin-bottom: var(--fa-s-4); flex-wrap: wrap; }
.filters-count { margin-left: auto; font-size: var(--fa-t-footnote); color: var(--fa-muted); }

/* ---------- fixture rows ---------- */

.grp { background: var(--fa-surface); border: 1px solid var(--fa-hairline);
  border-radius: var(--fa-r-card); margin-bottom: var(--fa-s-4); overflow: hidden; }
.grp-head { display: flex; align-items: center; justify-content: space-between;
  padding: 11px var(--fa-s-4); border-bottom: 1px solid var(--fa-hairline); }
.grp-name { font-size: var(--fa-t-footnote); font-weight: var(--fa-w-semi); color: var(--fa-ink); }
a.grp-name:hover { color: var(--fa-primary); }
.grp-count { font-size: 11px; color: var(--fa-muted); }

.mr {
  position: relative; display: grid; align-items: center;
  grid-template-columns: 60px minmax(0, 1fr) auto auto; gap: var(--fa-s-3);
  padding: 10px var(--fa-s-4); border-bottom: 1px solid var(--fa-hairline);
}
.mr:last-child { border-bottom: 0; }
.mr:hover { background: var(--fa-surface-2); }
.mr.is-selected { background: var(--fa-primary-weak); box-shadow: inset 3px 0 0 var(--fa-primary); }
/* One link stretched across the row opens the match. The club links and the
   follow button sit above it — never inside it, because a link inside a link
   is invalid and unusable with a screen reader. */
.mr-open { position: absolute; inset: 0; z-index: 1; }
.mr-state { font-size: var(--fa-t-footnote); color: var(--fa-muted); display: flex;
  align-items: center; gap: 5px; font-variant-numeric: tabular-nums; }
/* A list that spans days says which day, and that does not fit the 60px a
   bare kickoff time needs. Widened per list rather than per row, so the left
   edge stays straight when a finished match sits above a scheduled one. */
.mr.has-day { grid-template-columns: 152px minmax(0, 1fr) auto auto; }
.mr-state abbr { text-decoration: none; }
.mr.is-live .mr-state { color: var(--fa-live); font-weight: var(--fa-w-semi); }
.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--fa-live); animation: pulse 1.6s infinite; }
@keyframes pulse { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .dot { animation: none; } }

/* The score belongs beside the club name, not at the far edge of a wide
   screen — a scoreline the eye has to travel to is a scoreline you read
   twice. */
.mr-teams { display: grid; gap: 5px; min-width: 0; max-width: 460px; }
.mr-team { display: flex; align-items: center; gap: var(--fa-s-3); min-width: 0; }
.mr-name { position: relative; z-index: 2; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-size: var(--fa-t-body); }
.mr-name:hover { color: var(--fa-primary); }
.mr-team.won .mr-name, .mr-team.won .mr-score { font-weight: var(--fa-w-semi); }
.mr-score { margin-left: auto; min-width: 22px; text-align: right;
  font-variant-numeric: tabular-nums; font-size: var(--fa-t-headline); }
.mr-agg { font-size: 11px; color: var(--fa-muted); white-space: nowrap; }

.follow-btn {
  position: relative; z-index: 2; display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--fa-hairline); background: var(--fa-surface); color: var(--fa-muted);
  border-radius: var(--fa-r-pill); padding: 5px 11px; cursor: pointer;
  font-size: var(--fa-t-footnote); font-weight: var(--fa-w-medium);
}
.follow-btn svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.75;
  stroke-linejoin: round; }
.follow-btn:hover { color: var(--fa-ink); border-color: var(--fa-ink); }
.follow-btn[aria-pressed="true"] { color: var(--fa-gold); border-color: currentColor; }
.follow-btn[aria-pressed="true"] svg { fill: currentColor; }
.follow-btn.is-compact span { display: none; }
.follow-btn.is-compact { padding: 6px; }

.day-head, .month-head { margin: var(--fa-s-5) 0 var(--fa-s-2); font-size: var(--fa-t-caption);
  text-transform: uppercase; letter-spacing: var(--fa-ls-caption); color: var(--fa-muted); }

/* ---------- match centre ---------- */

.mh-meta { display: flex; flex-wrap: wrap; gap: var(--fa-s-3); font-size: 11px;
  text-transform: uppercase; letter-spacing: var(--fa-ls-caption); color: var(--fa-muted); }
.mh-meta a { color: var(--fa-primary); }
.mh-score { display: grid; grid-template-columns: 1fr auto 1fr; align-items: start;
  gap: var(--fa-s-3); margin: var(--fa-s-5) 0 var(--fa-s-3); }
.mh-team { display: grid; justify-items: center; gap: 6px; text-align: center; }
.mh-team b { font-size: var(--fa-t-body); font-weight: var(--fa-w-semi); }
.mh-mid { display: grid; justify-items: center; gap: 4px; }
.mh-nums { font-size: var(--fa-t-score, 34px); font-weight: var(--fa-w-bold); font-variant-numeric: tabular-nums; }
.mh-nums i { font-style: normal; color: var(--fa-muted); margin: 0 4px; }
.mh-time { font-size: var(--fa-t-title2); font-weight: var(--fa-w-bold); }
.mh-state { font-size: 11px; padding: 2px 8px; border-radius: var(--fa-r-pill);
  background: var(--fa-surface-2); color: var(--fa-ink-2); }
.mh-state.is-live { background: var(--fa-live-weak); color: var(--fa-live); font-weight: var(--fa-w-semi); }
.mh-pens { font-size: 11px; color: var(--fa-muted); }
.mh-agg { display: flex; align-items: center; gap: var(--fa-s-3); flex-wrap: wrap;
  padding: 9px var(--fa-s-4); border-radius: var(--fa-r-chip); background: var(--fa-surface-2);
  font-size: var(--fa-t-footnote); }
.mh-agg span { color: var(--fa-muted); }
.mh-agg a { color: var(--fa-primary); margin-left: auto; }
.mh-venue { margin: var(--fa-s-3) 0 0; font-size: var(--fa-t-footnote); color: var(--fa-muted); text-align: center; }

.scorers { display: grid; grid-template-columns: 1fr 1fr; gap: var(--fa-s-4); margin: var(--fa-s-4) 0; }
.scorers ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 3px;
  font-size: var(--fa-t-footnote); color: var(--fa-ink-2); }
.scorers .a { text-align: right; }
.scorers i { font-style: normal; color: var(--fa-muted); font-size: 10px; }

/* A quieter bar. The markers were large enough to read as content in their own
   right, competing with the moments listed underneath; they are a summary, so
   they sit small and low until you point at one. */
.timeline { position: relative; height: 34px; margin: var(--fa-s-4) 0 var(--fa-s-5); }
.timeline .track { position: absolute; top: 11px; left: 0; right: 0; height: 2px;
  background: var(--fa-surface-2); border-radius: 2px; }
.timeline .ev {
  position: absolute; top: 3px; translate: -50% 0; line-height: 1;
  width: 18px; height: 18px; display: grid; place-items: center;
  border-radius: 50%; background: var(--fa-surface); box-shadow: 0 0 0 1px var(--fa-hairline);
  transition: transform .12s ease, box-shadow .12s ease;
}
.timeline .ev-dot { font-size: 10px; font-style: normal; line-height: 1; }
.timeline .ev:hover, .timeline .ev:focus-visible {
  transform: scale(1.35); box-shadow: 0 0 0 2px var(--fa-primary); z-index: 3; outline: none;
}
/* The label belongs to the marker, so it appears the instant you point at one
   rather than after the browser decides to show a tooltip. */
.ev-label {
  position: absolute; bottom: calc(100% + 7px); left: 50%; translate: -50% 0;
  padding: 4px 8px; border-radius: var(--fa-r-chip); white-space: nowrap;
  background: var(--fa-ink); color: var(--fa-surface); font-size: 11px; max-width: 260px;
  opacity: 0; pointer-events: none; transition: opacity .12s ease;
  box-shadow: var(--fa-shadow-card); z-index: 4;
}
.timeline .ev:hover .ev-label, .timeline .ev:focus-visible .ev-label { opacity: 1; }
/* A label on the first or last marker would run off the edge. */
.timeline .ev[data-edge="start"] .ev-label { left: 0; translate: 0 0; }
.timeline .ev[data-edge="end"] .ev-label { left: auto; right: 0; translate: 0 0; }
.timeline .scale { position: absolute; top: 22px; left: 0; right: 0; display: flex;
  justify-content: space-between; font-size: 10px; color: var(--fa-muted); }
@media (prefers-reduced-motion: reduce) {
  .timeline .ev, .ev-label { transition: none; }
  .timeline .ev:hover, .timeline .ev:focus-visible { transform: none; }
}

/* One column, every row the same shape. Mirroring the away side into its own
   half looked like a design and read like a mistake: half the rows sat in
   whitespace, the minute ended up furthest from the eye, and nothing lined up.
   Whose moment it was is a crest on the right, not a second layout. */
.key-events { margin: 0; padding: 0; list-style: none; }
.ke {
  display: grid; grid-template-columns: 30px 20px minmax(0, 1fr) 18px;
  align-items: center; gap: var(--fa-s-3);
  padding: 6px 0; border-bottom: 1px solid var(--fa-hairline);
}
.ke:last-child { border-bottom: 0; }
.ke-min { font-size: var(--fa-t-footnote); color: var(--fa-muted); font-variant-numeric: tabular-nums; }
.ke-ico { display: grid; place-items: center; line-height: 1; font-size: 13px; }
.ke-who { display: grid; font-size: var(--fa-t-footnote); min-width: 0; }
.ke-who a, .ke-who > :first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ke-who em { font-style: normal; font-size: 11px; color: var(--fa-muted); }
/* A club's own moments get its crest; the row is otherwise identical. */
.ke-crest { opacity: .85; }

.donuts { display: flex; gap: var(--fa-s-5); justify-content: center; margin: var(--fa-s-4) 0; }
.donut { display: grid; justify-items: center; gap: 2px; width: 90px; }
.donut svg { width: 70px; height: 70px; transform: rotate(-90deg); }
.donut circle { fill: none; stroke-width: 3.4; }
.d-bg { stroke: var(--fa-surface-2); }
.d-fg { stroke: var(--fa-primary); }
.donut b { font-size: var(--fa-t-headline); font-variant-numeric: tabular-nums; }
.donut span { font-size: 11px; color: var(--fa-muted); text-align: center; }

.h2h { font-size: var(--fa-t-footnote); color: var(--fa-ink-2); margin: 0 0 var(--fa-s-3); }
.form-row { display: flex; align-items: center; justify-content: space-between; gap: var(--fa-s-3);
  padding: 8px 0; border-bottom: 1px solid var(--fa-hairline); font-size: var(--fa-t-footnote); }

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

.side-switch { display: flex; gap: 6px; margin-bottom: var(--fa-s-4); }
.xi-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--fa-s-3);
  margin-bottom: var(--fa-s-3); font-size: var(--fa-t-footnote); }
.xi-head span { color: var(--fa-muted); }

.pitch {
  display: grid; grid-template-rows: repeat(var(--rows), 1fr); gap: var(--fa-s-3);
  padding: var(--fa-s-4) var(--fa-s-2); border-radius: var(--fa-r-card);
  background: var(--fa-pitch, #14532d); position: relative; overflow: hidden; min-height: 380px;
}
.pitch-lines { position: absolute; inset: 0; pointer-events: none; }
.pitch-lines i { position: absolute; border: 1.5px solid var(--fa-pitch-line, rgba(255,255,255,.18)); }
.p-circle { width: 90px; height: 90px; border-radius: 50%; top: 50%; left: 50%; translate: -50% -50%; }
.p-box { width: 46%; height: 62px; left: 27%; bottom: -1px; }
.p-box.is-far { bottom: auto; top: -1px; }
.pitch-row { display: flex; justify-content: space-evenly; align-items: center; position: relative; z-index: 1; }
.pp { display: grid; justify-items: center; gap: 2px; width: 76px; text-align: center; color: #fff; }
.pp .portrait { border: 2px solid rgba(255,255,255,.55); background: rgba(255,255,255,.14); }
.pp .portrait-fallback { color: #fff; }
.pp-num { position: absolute; margin-top: 26px; margin-left: 26px; font-size: 10px;
  background: #fff; color: #111; border-radius: 50%; width: 16px; height: 16px;
  display: grid; place-items: center; font-weight: var(--fa-w-bold); }
.pp-name { font-size: 11px; line-height: 1.25; text-shadow: 0 1px 2px rgba(0,0,0,.5); }
.pp-off { font-style: normal; font-size: 10px; opacity: .8; }
a.pp:hover .pp-name { text-decoration: underline; }
.xi-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); gap: var(--fa-s-3);
  padding: var(--fa-s-4); border-radius: var(--fa-r-card); background: var(--fa-pitch, #14532d); }

.subs { margin: 0; padding: 0; list-style: none; }
.sub a, .sub { display: flex; align-items: center; gap: var(--fa-s-3); padding: 7px 0;
  border-bottom: 1px solid var(--fa-hairline); font-size: var(--fa-t-footnote); }
.sub b { min-width: 20px; color: var(--fa-muted); font-variant-numeric: tabular-nums; }
.s-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.s-note { font-size: 11px; color: var(--fa-muted); }
.sub.came-on .s-note { color: var(--fa-win); }

/* ---------- club ---------- */

.club-hero, .comp-hero {
  position: relative; overflow: hidden; border-radius: var(--fa-r-card);
  padding: var(--fa-s-6); margin-bottom: var(--fa-s-4); color: var(--club-ink);
  background: linear-gradient(105deg, var(--club) 0%, var(--club-2) 100%);
  box-shadow: inset 0 0 0 1px var(--club-edge);
  min-height: 190px; display: grid; align-content: space-between; gap: var(--fa-s-4);
}
.ch-face { display: flex; align-items: center; gap: var(--fa-s-4); position: relative; z-index: 2; }
.ch-crest { background: var(--club-veil); box-shadow: 0 0 0 1px var(--club-edge); }
.ch-kicker { margin: 0; font-size: 11px; text-transform: uppercase; letter-spacing: var(--fa-ls-caption); opacity: .85; }
.club-hero h2, .comp-hero h2 { margin: 2px 0; font-size: var(--fa-t-display, 32px);
  font-weight: var(--fa-w-heavy); letter-spacing: var(--fa-ls-display); }
.ch-sub { margin: 0; font-size: var(--fa-t-footnote); opacity: .85; }
.ch-controls { display: flex; align-items: center; gap: var(--fa-s-3); position: relative; z-index: 2; flex-wrap: wrap; }
.ch-controls .follow-btn, .ch-controls select {
  background: var(--club-veil); border-color: var(--club-edge); color: var(--club-ink);
}
.ch-controls .follow-btn[aria-pressed="true"] { background: var(--club-ink); color: var(--club); }
/* The portrait bleeds off the right edge, cropped on the FACE — `top center`
   framed the top of the head and cut the chin, which is what made a hero
   photograph look like a mistake. */
.ch-star { position: absolute; right: 0; top: 0; bottom: 0; width: 38%; max-width: 340px; z-index: 1; }
.ch-star img { width: 100%; height: 100%; object-fit: cover; object-position: center 22%;
  mask-image: linear-gradient(to right, transparent, #000 42%); }
/* The tag names the player in the photograph, so it sits ON the photograph
   and cannot rely on the club's ink: a pale club has dark text and a pale kit
   behind it. It carries its own dark pill instead. */
.ch-star-tag {
  position: absolute; right: var(--fa-s-3); bottom: var(--fa-s-3); text-align: right;
  display: grid; gap: 1px; padding: 6px 10px; border-radius: var(--fa-r-chip);
  color: #fff; background: rgba(0,0,0,.55); backdrop-filter: blur(6px);
}
/* A hero with a photograph gets a scrim behind the club's name, so a pale
   club's dark text is not competing with a light photograph. */
.club-hero:has(.ch-star)::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(100deg, var(--club) 34%, transparent 72%);
}
.ch-star-tag em { font-style: normal; font-size: 10px; text-transform: uppercase;
  letter-spacing: var(--fa-ls-caption); opacity: .8; }
.ch-star-tag b { font-size: var(--fa-t-footnote); }
.comp-phase { padding: 5px 11px; border-radius: var(--fa-r-pill); background: var(--club-veil);
  font-size: var(--fa-t-footnote); }
/* The badge sits on a light plate so a dark competition crest is still legible
   on a dark hero — most are drawn for a white ground. */
.comp-badge {
  position: absolute; right: var(--fa-s-6); top: 50%; translate: 0 -50%;
  width: 96px; height: 96px; object-fit: contain; z-index: 2;
  background: rgba(255,255,255,.94); border-radius: 18px; padding: 10px;
  box-shadow: 0 2px 14px rgba(0,0,0,.16);
}
.grp-badge { width: 20px; height: 20px; object-fit: contain; vertical-align: -4px; margin-right: 7px; }
.grp-name { display: inline-flex; align-items: center; }

.club-grid { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); gap: var(--fa-s-5); }
.cg-side .sec:first-child { margin-top: var(--fa-s-6); }

.next-match { display: grid; gap: var(--fa-s-3); justify-items: center; text-align: center;
  padding: var(--fa-s-5); background: var(--fa-surface); border: 1px solid var(--fa-hairline);
  border-radius: var(--fa-r-card); }
.nm-comp { font-size: 11px; text-transform: uppercase; letter-spacing: var(--fa-ls-caption); color: var(--fa-muted); }
.nm-teams { display: flex; align-items: center; gap: var(--fa-s-5); }
.nm-teams b { font-size: var(--fa-t-title2); font-weight: var(--fa-w-bold); }
.nm-who { font-size: var(--fa-t-body); font-weight: var(--fa-w-semi); }
.nm-when { font-size: var(--fa-t-footnote); color: var(--fa-muted); }

.pcards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--fa-s-3); }
.pcard { display: grid; background: var(--fa-surface); border: 1px solid var(--fa-hairline);
  border-radius: var(--fa-r-card); overflow: hidden; }
.pcard:hover { border-color: var(--fa-ink); }
/* `place-items: center` used to sit here, and it stopped the image stretching
   to its box: with no definite height to resolve against, `height: 100%` fell
   back to the picture's own size, so a 330x463 portrait was laid out 313px
   tall inside a 140px window and simply overflowed. `overflow: hidden` then
   clipped whatever happened to land there — which is why three cards in a row
   cropped to three different parts of three players. `object-fit: cover` was
   never engaging at all.
   Absolute positioning gives the definite box that cover needs. */
.pcard-img { position: relative; height: 140px; background: var(--fa-surface-2); overflow: hidden; }
.pcard-img img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 18%;
}
/* The initials fallback still needs centring — it just does not want the
   layout mode that broke the photographs. */
.pcard-img .portrait { position: absolute; top: 50%; left: 50%; translate: -50% -50%; }
.pcard b { padding: var(--fa-s-3) var(--fa-s-3) 0; font-size: var(--fa-t-body); }
.pcard-role { padding: 0 var(--fa-s-3) var(--fa-s-3); font-size: 11px; color: var(--fa-muted); }
.pcard-nums { display: flex; gap: var(--fa-s-4); padding: var(--fa-s-3);
  border-top: 1px solid var(--fa-hairline); }
.pcard-nums i { font-style: normal; display: grid; font-size: 10px; color: var(--fa-muted); }
.pcard-nums b { padding: 0; font-size: var(--fa-t-headline); font-variant-numeric: tabular-nums; color: var(--fa-ink); }

.campaigns { display: grid; gap: 1px; background: var(--fa-hairline);
  border-radius: var(--fa-r-card); overflow: hidden; }
.campaign { display: grid; grid-template-columns: 1fr auto; gap: 2px; padding: var(--fa-s-3) var(--fa-s-4);
  background: var(--fa-surface); font-size: var(--fa-t-footnote); }
.campaign:hover { background: var(--fa-surface-2); }
.campaign b { font-weight: var(--fa-w-semi); }
.campaign span { font-size: 11px; color: var(--fa-muted); }
.campaign em { grid-row: 1 / 3; align-self: center; font-style: normal; font-size: 11px;
  color: var(--fa-primary); text-align: right; }

.mini-table { width: 100%; border-collapse: collapse; font-size: var(--fa-t-footnote); }
.mini-table th { text-align: left; font-weight: var(--fa-w-regular); color: var(--fa-muted);
  font-size: 11px; padding-bottom: 6px; }
.mini-table td { padding: 7px 0; border-top: 1px solid var(--fa-hairline); }
.mini-table td:first-child { width: 24px; color: var(--fa-muted); }
.mini-table td:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.mini-table a { display: flex; align-items: center; gap: var(--fa-s-2); }
.mini-table tr.is-me { background: var(--fa-primary-weak); }
/* A row highlighted so you can find your club should not be the least
   readable one on the panel. Muted grey on the highlight tint measures 2.69
   in light and 3.82 in dark, both under the 4.5 that normal text needs; the
   rank sitting inside the band was the worst cell in either table. */
.mini-table tr.is-me td, .standings tr.is-me td { color: var(--fa-ink); }

.camp-list { margin: var(--fa-s-3) 0 0; padding: 0; list-style: none; }
.camp-list li { display: flex; justify-content: space-between; padding: 7px 0;
  border-bottom: 1px solid var(--fa-hairline); font-size: var(--fa-t-footnote); }
.camp-list a { color: var(--fa-primary); }
.camp-list span { color: var(--fa-muted); }

/* ---------- squad ---------- */

.squad-controls, .clubs-controls { display: flex; align-items: center; gap: var(--fa-s-3);
  flex-wrap: wrap; margin-bottom: var(--fa-s-4); }
.squad-find input, .clubs-controls input {
  height: 34px; padding: 0 var(--fa-s-3); border-radius: var(--fa-r-chip);
  border: 1px solid var(--fa-hairline); background: var(--fa-surface); color: var(--fa-ink);
  font: inherit; font-size: var(--fa-t-footnote); min-width: 180px;
}
.squad-count { margin: 0 0 0 auto; font-size: var(--fa-t-footnote); color: var(--fa-muted); }
/* Its own line: a caveat wedged beside the count reads as part of the count. */
.squad-photo-note { flex-basis: 100%; margin: 0; font-size: 11px; }
.squad-group { margin: var(--fa-s-5) 0 var(--fa-s-3); font-size: var(--fa-t-caption);
  text-transform: uppercase; letter-spacing: var(--fa-ls-caption); color: var(--fa-muted); }

.pgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--fa-s-3); }
.pc { display: grid; justify-items: center; gap: 3px; padding: var(--fa-s-4) var(--fa-s-3);
  background: var(--fa-surface); border: 1px solid var(--fa-hairline);
  border-radius: var(--fa-r-card); position: relative; text-align: center; }
.pc:hover { border-color: var(--fa-ink); }
.pc-num { position: absolute; top: 8px; left: 10px; font-size: 11px; color: var(--fa-muted);
  font-variant-numeric: tabular-nums; }
.pc-name { font-size: var(--fa-t-footnote); font-weight: var(--fa-w-semi); }
.pc-pos { font-size: 10px; color: var(--fa-muted); }
.pc-stats { display: flex; gap: var(--fa-s-3); margin-top: 4px; }
.pc-stats i { font-style: normal; display: grid; font-size: 9px; color: var(--fa-muted); text-transform: uppercase; }
.pc-stats b { font-size: var(--fa-t-body); font-variant-numeric: tabular-nums; color: var(--fa-ink); }

.table-wrap { overflow-x: auto; }
.squad-table, .standings { width: 100%; border-collapse: collapse; font-size: var(--fa-t-footnote); }
.squad-table th, .standings th { text-align: left; padding: 8px var(--fa-s-2); color: var(--fa-muted);
  font-weight: var(--fa-w-regular); font-size: 11px; border-bottom: 1px solid var(--fa-hairline);
  white-space: nowrap; }
.squad-table td, .standings td { padding: 9px var(--fa-s-2); border-bottom: 1px solid var(--fa-hairline);
  font-variant-numeric: tabular-nums; }
.squad-table a, .standings .club a { display: flex; align-items: center; gap: var(--fa-s-2); }
.squad-table tr:hover, .standings tr:hover { background: var(--fa-surface-2); }

.cm-row { position: relative; }
.cm-comp { position: absolute; top: 4px; left: var(--fa-s-4); z-index: 2; font-size: 10px;
  color: var(--fa-muted); text-transform: uppercase; letter-spacing: var(--fa-ls-caption); }
.cm-row .mr { padding-top: 20px; background: var(--fa-surface); border: 1px solid var(--fa-hairline);
  border-radius: var(--fa-r-card); margin-bottom: 6px; }

/* `align-items: start` for the same reason the story grid needs it: a grid
   item stretches to its row, so a leaderboard with three names took the height
   of the one beside it with five. Arsenal's Goals board carried 82px of empty
   card under Ødegaard, and Saves — one goalkeeper — the same again. */
.boards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--fa-s-4); align-items: start; }
.board { background: var(--fa-surface); border: 1px solid var(--fa-hairline);
  border-radius: var(--fa-r-card); padding: var(--fa-s-4); }
.board h4 { margin: 0 0 var(--fa-s-3); font-size: var(--fa-t-caption); text-transform: uppercase;
  letter-spacing: var(--fa-ls-caption); color: var(--fa-muted); }
.board ol { margin: 0; padding: 0; list-style: none; counter-reset: n; }
.board li { display: flex; align-items: center; gap: var(--fa-s-2); padding: 6px 0;
  border-bottom: 1px solid var(--fa-hairline); font-size: var(--fa-t-footnote); }
.board li a, .board li .plain { display: flex; align-items: center; gap: var(--fa-s-2); flex: 1; min-width: 0; }
.board li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board li b { font-variant-numeric: tabular-nums; }

/* ---------- club directory ---------- */

.club-grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--fa-s-4); }

/* The crest sits IN the flow, above the name, rather than floating over it:
   absolutely positioning it meant "1. FC Union Berlin" ran straight through
   the badge on every club with a long name. */
.cc {
  position: relative; overflow: hidden; min-height: 150px; padding: var(--fa-s-4);
  border-radius: var(--fa-r-card); color: var(--club-ink);
  display: grid; grid-template-rows: auto 1fr auto; gap: 2px;
  background: linear-gradient(100deg, var(--club) 0%, var(--club-2) 100%);
}
/* A pale club keeps its own colour, so it needs an edge to sit on the page. */
.cc { box-shadow: inset 0 0 0 1px var(--club-edge); }

/* The stretched link is ABOVE the text, not below it. The text carried
   z-index: 3 against the link's 2, so the only clickable part of a card was
   the padding around the words — the card looked like a button and behaved
   like a picture. Nothing here raises itself above the link except the follow
   control, which has its own job. */
.cc-open { position: absolute; inset: 0; z-index: 3; border-radius: inherit; }
.cc-open:focus-visible { outline-offset: -3px; }
.cc-crest { background: var(--club-veil); box-shadow: 0 0 0 1px var(--club-edge); align-self: start; }
.cc-name { font-size: var(--fa-t-title2); font-weight: var(--fa-w-bold); align-self: end; line-height: 1.15; }
.cc-league { font-size: 11px; opacity: .8; }
.cc-go { font-size: 11px; opacity: .9; margin-top: 4px; }
.cc:hover .cc-go { opacity: 1; }
.cc .follow-btn { position: absolute; top: var(--fa-s-3); right: var(--fa-s-3); z-index: 4;
  background: var(--club-veil); border-color: var(--club-edge); color: var(--club-ink); }
/* Behind everything, including the link overlay. */
.cc-photo { position: absolute; right: 0; top: 0; bottom: 0; width: 46%; z-index: 1; pointer-events: none; }
.cc-photo img { width: 100%; height: 100%; object-fit: cover; object-position: center 18%;
  mask-image: linear-gradient(to right, transparent, #000 55%); }
/* Words stay legible over a photograph without a heavy scrim on every card. */
.cc-name, .cc-league, .cc-go { position: relative; z-index: 2; text-shadow: 0 1px 3px var(--club-shadow, transparent); }
/* The halo comes from the theme, which already decided whether this club's
   ink is light or dark — a dark glow behind dark text is not a scrim, it is
   a smudge. Two of the twelve photographed cards were wearing one. */
.cc:has(.cc-photo:not([hidden])) { --club-shadow: var(--club-halo); }
.cc:has(.cc-photo:not([hidden])) .cc-name { text-shadow: 0 1px 4px var(--club-halo), 0 0 10px var(--club-halo); }

.search-clubs { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--fa-s-3); }
.sc { display: flex; align-items: center; gap: var(--fa-s-3); padding: var(--fa-s-3);
  background: var(--fa-surface); border: 1px solid var(--fa-hairline); border-radius: var(--fa-r-card); }
.sc:hover { border-color: var(--fa-ink); }
.sc b { font-size: var(--fa-t-footnote); }
.sc span { margin-left: auto; font-size: 11px; color: var(--fa-muted); }

/* ---------- player ---------- */

.ph { position: relative; display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: var(--fa-s-5); padding: var(--fa-s-6); border-radius: var(--fa-r-card);
  background: var(--fa-ink); color: var(--fa-surface); overflow: hidden; margin-bottom: var(--fa-s-4); }
.ph-portrait { border: 3px solid rgba(255,255,255,.25); }
.ph-club { display: inline-flex; align-items: center; gap: var(--fa-s-2); font-size: var(--fa-t-footnote); opacity: .85; }
.ph h2 { margin: 4px 0; font-size: var(--fa-t-display, 32px); font-weight: var(--fa-w-heavy);
  letter-spacing: var(--fa-ls-display); }
.ph-sub, .ph-bio { margin: 0; font-size: var(--fa-t-footnote); opacity: .8; }
.ph-controls select { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.28); color: #fff; }
.ph-number { position: absolute; right: var(--fa-s-6); bottom: -18px; font-size: 108px;
  font-weight: var(--fa-w-heavy); opacity: .10; line-height: 1; z-index: 0; }
.ph-words, .ph-face, .ph-controls { position: relative; z-index: 1; }

.pa { display: grid; grid-template-columns: 58px auto 1fr auto auto auto; align-items: center;
  gap: var(--fa-s-3); padding: 9px var(--fa-s-3); border-bottom: 1px solid var(--fa-hairline);
  font-size: var(--fa-t-footnote); }
.pa:hover { background: var(--fa-surface-2); }
.pa-date { color: var(--fa-muted); }
.pa-opp { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pa-score { font-variant-numeric: tabular-nums; font-weight: var(--fa-w-semi); }
.pa-role, .pa-cons { font-size: 11px; color: var(--fa-muted); }

.career { margin: 0; padding: 0; list-style: none; }
.career li { display: flex; align-items: center; gap: var(--fa-s-3); padding: 8px 0;
  border-bottom: 1px solid var(--fa-hairline); font-size: var(--fa-t-footnote); }
.career span { margin-left: auto; color: var(--fa-muted); }

/* ---------- competitions ---------- */

.comp-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: var(--fa-s-3); }
.comp-card { display: grid; gap: 3px; padding: var(--fa-s-4); background: var(--fa-surface);
  border: 1px solid var(--fa-hairline); border-radius: var(--fa-r-card); }
.comp-card:hover { border-color: var(--club); }
/* Sized to the badge it stands in for, so a card without a crest does not sit
   12px shorter than the ones beside it and pull its heading out of line. */
.cc-mark { width: 44px; height: 44px; border-radius: 12px; background: var(--club);
  margin-bottom: var(--fa-s-2); display: grid; place-items: center;
  color: var(--club-ink); font-size: 15px; font-weight: var(--fa-w-bold); letter-spacing: .02em; }
/* The competition's own badge. On a white card it needs no plate; on a dark
   one it does, because most of these badges are drawn for a light ground. */
.cc-badge { width: 44px; height: 44px; object-fit: contain; margin-bottom: var(--fa-s-2); }
.comp-card b { font-size: var(--fa-t-body); }
.comp-card-sub { font-size: 11px; color: var(--fa-muted); }
.comp-card .cc-go { color: var(--fa-primary); opacity: 1; margin-top: var(--fa-s-3);
  padding-top: var(--fa-s-3); border-top: 1px solid var(--fa-hairline); font-size: 11px; }
.comp-region { margin-bottom: var(--fa-s-6); }

.round-list { margin: 0; padding: 0; list-style: none; }
.round-list li { display: flex; justify-content: space-between; padding: 7px 0;
  border-bottom: 1px solid var(--fa-hairline); font-size: var(--fa-t-footnote); }
.round-list span { color: var(--fa-muted); text-transform: capitalize; }
/* Wraps rather than scrolling. It scrolled with the scrollbar hidden, which
   was invisible but harmless while a league offered two chips — "All" and
   "Fixtures". Filed by month it offers eleven, wanting 1199px, so the last
   month was cut off at any width and nothing said the row could be moved. */
.round-picker { display: flex; flex-wrap: wrap; gap: 6px;
  padding-bottom: var(--fa-s-3); margin-bottom: var(--fa-s-3); }
.scope-line { margin: 0 0 var(--fa-s-4); font-size: 11px; text-transform: uppercase;
  letter-spacing: var(--fa-ls-caption); color: var(--fa-muted); }

/* ---------- standings ---------- */

.standings-head { display: flex; align-items: baseline; gap: var(--fa-s-3); margin-bottom: var(--fa-s-3); }
.standings-head b { font-size: var(--fa-t-headline); }
.standings-head span { font-size: var(--fa-t-footnote); color: var(--fa-muted); }
.standings .c { text-align: center; }
.standings .rank { position: relative; }
/* The band down the left edge is the provider's own qualification colour for
   this competition and this season — never a hardcoded top-four. */
.standings .rank.has-band::before { content: ""; position: absolute; left: 0; top: 4px; bottom: 4px;
  width: 3px; border-radius: 2px; background: var(--band); }
.standings .club { min-width: 150px; }
.standings .pts b { font-weight: var(--fa-w-bold); }
.standings tr.is-me { background: var(--fa-primary-weak); }
.table-group { margin: var(--fa-s-5) 0 var(--fa-s-2); font-size: var(--fa-t-body); }
.legend { display: flex; flex-wrap: wrap; gap: var(--fa-s-4); margin: var(--fa-s-4) 0 0; padding: 0;
  list-style: none; font-size: 11px; color: var(--fa-muted); }
.legend li { display: flex; align-items: center; gap: 6px; }
.legend i { width: 10px; height: 10px; border-radius: 3px; }

/* ---------- bracket ---------- */

/* Wraps rather than scrolling, for the same reason the round picker does: it
   scrolled with the scrollbar hidden, so on a phone 424px of it — three of the
   five rounds — sat off the edge with nothing saying the row could be moved.
   It is how you jump to a round; hiding half of it hides the navigation. */
.rounds-strip { display: flex; flex-wrap: wrap; gap: var(--fa-s-2); margin-bottom: var(--fa-s-4); }
.rs { flex: 1 0 150px; display: grid; gap: 2px; padding: 10px var(--fa-s-3); cursor: pointer;
  background: var(--fa-surface); border: 1px solid var(--fa-hairline); border-radius: var(--fa-r-card);
  text-align: center; }
.rs b { font-size: var(--fa-t-footnote); }
.rs span { font-size: 11px; color: var(--fa-muted); text-transform: capitalize; }
.rs.is-live b, .rs.is-live span { color: var(--fa-live); }

/* Horizontal on a wide screen, contained; a single column of rounds on a
   narrow one, so the page never scrolls sideways as a whole. */
.bracket { display: flex; gap: var(--fa-s-5); overflow-x: auto; padding-bottom: var(--fa-s-4); }
.br-round { flex: 0 0 270px; display: grid; gap: var(--fa-s-3); align-content: start; }
.br-round h4 { margin: 0; display: flex; justify-content: space-between; font-size: var(--fa-t-caption);
  text-transform: uppercase; letter-spacing: var(--fa-ls-caption); color: var(--fa-muted); }

.tc { position: relative; display: grid; gap: 6px; padding: var(--fa-s-3) var(--fa-s-4);
  background: var(--fa-surface); border: 1px solid var(--fa-hairline); border-radius: var(--fa-r-card); }
.tc:hover { border-color: var(--fa-ink); }
.tc.is-live { border-color: var(--fa-live); }
.tc-open { position: absolute; inset: 0; z-index: 1; }
.tc-team { display: flex; align-items: center; gap: var(--fa-s-2); font-size: var(--fa-t-footnote); }
.tc-team a { position: relative; z-index: 2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tc-team b { margin-left: auto; font-variant-numeric: tabular-nums; }
.tc-team.is-through { font-weight: var(--fa-w-semi); }
.tc-team.is-through a::after { content: " ✓"; color: var(--fa-win); }
.tc-team.is-leading b { color: var(--fa-primary); }
.tc-foot { display: flex; justify-content: space-between; padding-top: 6px;
  border-top: 1px solid var(--fa-hairline); font-size: 10px; color: var(--fa-muted); }
.tc-foot em { font-style: normal; color: var(--fa-primary); }

.td-head h2 { margin: 4px 0; font-size: var(--fa-t-title1); }
.td-head h2 i { font-style: normal; color: var(--fa-muted); }
.td-agg, .td-pens { display: inline-block; margin-right: var(--fa-s-3); padding: 4px 10px;
  border-radius: var(--fa-r-pill); background: var(--fa-surface-2); font-size: var(--fa-t-footnote); }
.td-state { margin: var(--fa-s-3) 0; font-size: var(--fa-t-footnote); color: var(--fa-ink-2); }
.td-legs { margin: var(--fa-s-4) 0; padding: 0; list-style: none; display: grid; gap: var(--fa-s-3); }
.td-legs a { display: grid; gap: 3px; padding: var(--fa-s-4); background: var(--fa-surface);
  border: 1px solid var(--fa-hairline); border-radius: var(--fa-r-card); }
.td-legs a:hover { border-color: var(--fa-ink); }
.tdl-when, .tdl-state { font-size: 11px; color: var(--fa-muted); }
.tdl-score { font-size: var(--fa-t-body); }
.tdl-score b { font-variant-numeric: tabular-nums; margin: 0 6px; }

/* ---------- news ---------- */

/* `align-items: start` so a card is as tall as its own story. A grid item
   stretches to its row by default, so a headline with no picture was given the
   height of the photographed card beside it and carried up to 152px of empty
   box under its byline — three of those in a row read as a loading state. */
.stories { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--fa-s-4); align-items: start; }
.story { display: grid; align-content: start; background: var(--fa-surface); border: 1px solid var(--fa-hairline);
  border-radius: var(--fa-r-card); overflow: hidden; }
.story:hover { border-color: var(--fa-ink); }
.story img { width: 100%; height: 150px; object-fit: cover; }
/* A feed's image URL is often dead or blocked. A broken-image icon is worse
   than no picture, so the card closes up around the words instead. */
.story[data-noimage] { grid-template-rows: auto; }
/* `align-content: start` so a card with no picture keeps its headline and its
   byline together at the top, instead of stretching them to the corners of a
   card sized by the pictures beside it. */
.st-words { display: grid; gap: 5px; padding: var(--fa-s-4); align-content: start; }
.st-words b { font-size: var(--fa-t-body); line-height: 1.35; }
.st-words em { font-style: normal; font-size: 11px; color: var(--fa-muted); }

/* ---------- skeletons ---------- */

.skeleton-page, .skeleton-list, .skeleton-grid { display: grid; gap: var(--fa-s-3); }
.skeleton-page::before, .skeleton-list::before, .skeleton-grid::before,
.skeleton-page::after, .skeleton-list::after {
  content: ""; display: block; border-radius: var(--fa-r-card);
  background: linear-gradient(90deg, var(--fa-surface-2) 25%, var(--fa-raised) 37%, var(--fa-surface-2) 63%);
  background-size: 400% 100%; animation: shimmer 1.4s ease infinite;
}
.skeleton-page::before { height: 180px; }
.skeleton-page::after { height: 320px; }
.skeleton-list::before { height: 96px; }
.skeleton-list::after { height: 280px; }
.skeleton-grid::before { height: 420px; }
@keyframes shimmer { to { background-position: -400% 0; } }
@media (prefers-reduced-motion: reduce) {
  .skeleton-page::before, .skeleton-page::after, .skeleton-list::before,
  .skeleton-list::after, .skeleton-grid::before { animation: none; }
}

/* ============================================================
   The folds
   ============================================================ */

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

/* The rail needs room beside the list; below this it BECOMES the page.
   `.main` still has to collapse when it does: it is `min-height: 100vh` with a
   footer, so hiding only the view left a full screen of nothing above the
   match and the match centre began exactly one viewport down. Opening a match
   on a phone showed a blank page. */
@media (max-width: 1180px) {
  .shell { display: flex; flex-direction: column; }
  .shell[data-rail] .main { margin-right: 0; min-height: 0; }
  .rail { position: static; width: auto; border-left: 0; border-top: 1px solid var(--fa-hairline); }
  .shell[data-rail] .main #view { display: none; }
  .shell[data-rail] .foot { display: none; }
  /* The heading goes with the list it names. Below this width the match centre
     IS the page — the list underneath is already hidden two lines up — and the
     topbar still read "Scores · Every competition, any day" over a match, a
     title for a screen the reader could not see. The pane names itself:
     competition, season, kickoff, both clubs. */
  .shell[data-rail] .topbar-title { display: none; }
  .shell[data-rail] .rail { min-height: calc(100vh - 72px); }
}

@media (max-width: 1060px) {
  .menu-btn { display: grid; }
  .main { margin-left: 0; }
  /* The sidebar does not disappear on a phone, it slides. Hiding it outright
     would leave the phone with no navigation at all. */
  .side { transform: translateX(-100%); transition: transform .22s ease;
    box-shadow: var(--fa-shadow-sheet); z-index: 60; }
  .side[data-open] { transform: none; }
  .side-backdrop { position: fixed; inset: 0; z-index: 50; background: rgba(0,0,0,.38); }
  @media (prefers-reduced-motion: reduce) { .side { transition: none; } }
  .topbar { padding: var(--fa-s-4); position: sticky; top: 0; z-index: 20;
    background: color-mix(in srgb, var(--fa-bg) 88%, transparent);
    backdrop-filter: saturate(180%) blur(20px);
    border-bottom: 1px solid var(--fa-hairline); }
  .topbar-title h1 { font-size: var(--fa-t-title2); }
  .topbar-search { width: 44px; }
  .topbar-search input, .topbar-search kbd { display: none; }
  #view, .rail { padding: var(--fa-s-4) var(--fa-s-4) 80px; }
  .foot { padding: var(--fa-s-5) var(--fa-s-4) var(--fa-s-8); }
  .ph { grid-template-columns: auto 1fr; }
  .ph-controls { grid-column: 1 / -1; }
  .ch-star { width: 38%; opacity: .9; }
  .br-round { flex-basis: 240px; }
}

@media (max-width: 620px) {
  .club-hero, .comp-hero { padding: var(--fa-s-4); min-height: 0; }
  .club-hero h2, .comp-hero h2, .ph h2 { font-size: var(--fa-t-title1); }
  .ch-star { position: relative; width: auto; height: 130px; grid-row: 1; }
  .ch-star img { mask-image: linear-gradient(to bottom, #000 60%, transparent); }
  .mr { grid-template-columns: 46px minmax(0, 1fr) auto; }
  /* On a phone the day wraps under the time rather than eating half the row. */
  .mr.has-day { grid-template-columns: 74px minmax(0, 1fr) auto; }
  .mr .follow-btn { display: none; }
  .pgrid { grid-template-columns: repeat(auto-fill, minmax(116px, 1fr)); }
  .pitch { min-height: 340px; }
  .pp { width: 62px; }
  .scorers { grid-template-columns: 1fr; }
  .squad-count { margin-left: 0; width: 100%; }
  .form-col { display: none; }
  /* The table fits the phone instead of scrolling sideways. Points is the
     column a league table exists for and it sat 47px past the right edge,
     reachable only by dragging the table. Every other column is a number that
     cannot be shortened, so the club name gives up its floor and truncates —
     it is the one cell with anything to give. */
  .standings .club { min-width: 0; }
  .standings .club a { min-width: 0; }
  .standings .club span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Auto table layout sizes a column to its longest name whatever the cell
     allows, so a cap is what actually makes room; the numeric columns give up
     a little padding rather than the club giving up more of its name. */
  .standings .club { max-width: 110px; }
  .standings th, .standings td { padding-left: 4px; padding-right: 4px; }
  .br-round { flex-basis: 84vw; }
}
