/* Floodlit night match. Dark only, no framework.
   The match list is one sheet. Every league band and match row shares the same columns:
   star (--c-star), time (--c-time), then teams with the score on the right edge. Green means
   live; red is only ever a goal or a dangerous attack; gold is a favourite. */

/* The font carries two sets of vertical metrics (1000/200 and 1089/261). Windows and Linux can
   pick different ones and shift text a pixel or two; the overrides pin one set everywhere. */
@font-face { font-family: "Barlow SC"; font-weight: 500; font-display: swap; ascent-override: 100%; descent-override: 20%; line-gap-override: 0%; src: url("../fonts/barlow-sc-latin-500.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Barlow SC"; font-weight: 700; font-display: swap; ascent-override: 100%; descent-override: 20%; line-gap-override: 0%; src: url("../fonts/barlow-sc-latin-700.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Barlow SC"; font-weight: 500; font-display: swap; ascent-override: 100%; descent-override: 20%; line-gap-override: 0%; src: url("../fonts/barlow-sc-latin-ext-500.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Barlow SC"; font-weight: 700; font-display: swap; ascent-override: 100%; descent-override: 20%; line-gap-override: 0%; src: url("../fonts/barlow-sc-latin-ext-700.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; }

:root {
	--night: #0d1522;
	--stand: #141f30;
	--stand-hi: #1b283c;
	--line: #223047;
	--chalk: #edf1f7;
	--mist: #8595ac;
	--pitch: #3bd671;
	--alarm: #ff3d52;
	--gold: #ffc83d;

	--c-chev: 20px;
	--c-star: 36px;
	--c-time: 48px;
	--star-icon: 21px;
	--edge: 16px;
	--top: 97px;
	--radius: 12px;
	color-scheme: dark;
}

@media (min-width: 900px) { :root { --top: 65px; } }

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
/* Read by screen readers and search engines, not shown. */
.vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* The scrollbar is always there, so a short tab (Starred, a search) does not shift the page
   sideways when the scrollbar comes and goes. Phones overlay theirs, so this costs them nothing. */
html { -webkit-text-size-adjust: 100%; overflow-y: scroll; }

/* Moving between pages (a match, back to the list, a tab from a match page) fades instead of
   blanking and repainting, and the header holds still. Browsers without it just navigate. */
@media (prefers-reduced-motion: no-preference) {
	@view-transition { navigation: auto; }
	::view-transition-old(root), ::view-transition-new(root) { animation-duration: .15s; }
}
.top { view-transition-name: top; }
body {
	margin: 0;
	background: var(--night);
	color: var(--chalk);
	font: 500 14px/1.3 "Barlow SC", system-ui, -apple-system, "Segoe UI", sans-serif;
	font-variant-numeric: tabular-nums;
}
a { color: inherit; text-decoration: none; }
button, input, select { font: inherit; color: inherit; }
h1, h2, h3, p { margin: 0; }
img { display: block; flex: none; }
summary { list-style: none; cursor: pointer; }
/* The list and its controls behave like an app: clicking them never places a text cursor or
   highlights a team name. Details, team and league pages stay selectable. */
.top, .bar, .lg-h, .m, .sx-r, .dt-tabs, .panel > summary, .jump { -webkit-user-select: none; user-select: none; }
summary::-webkit-details-marker { display: none; }
:focus-visible { outline: 2px solid var(--chalk); outline-offset: -2px; border-radius: 6px; }

/* A chevron that points down when its panel is open. */
.chev::after, .panel > summary::after, .lg-h::after {
	content: "";
	width: 7px;
	height: 7px;
	border: solid var(--mist);
	border-width: 0 2px 2px 0;
	transform: translateY(-2px) rotate(45deg);
	transition: transform .15s;
}
details:not([open]) > .lg-h::after, details:not([open]) > summary::after { transform: rotate(-45deg); }

/* ---- Grid: 12 columns; children span all 12 until the md breakpoint ---- */

.wrap { max-width: 1080px; margin: 0 auto; padding: 0 16px; }
.cols { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 0 24px; align-items: start; }
.cols > * { grid-column: span 12; min-width: 0; }

@media (min-width: 900px) {
	.md-3 { grid-column: span 3 !important; }
	.md-4 { grid-column: span 4 !important; }
	.md-6 { grid-column: span 6 !important; }
	.md-8 { grid-column: span 8 !important; }
	.md-9 { grid-column: span 9 !important; }
}

/* ---- Top bar: brand and search, then tabs; one row on desktop ---- */

.top { position: sticky; top: 0; z-index: 10; background: rgba(13, 21, 34, .94); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line); }
/* Phone: brand and search on one row, tabs underneath. Desktop: the same 12 columns as the page,
   so the search box is exactly as wide as the side panel below it. */
.top-in { display: grid; grid-template-columns: auto 1fr; grid-template-rows: 52px 44px; grid-template-areas: "brand search" "tabs tabs"; align-items: center; column-gap: 16px; }
.top-main { display: contents; }
@media (min-width: 900px) {
	.top-in { grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: 64px; grid-template-areas: none; column-gap: 24px; }
	.top-main { grid-column: 1 / span 9; display: flex; align-items: center; align-self: stretch; gap: 32px; min-width: 0; }
	.top-in .search { grid-area: 1 / 10 / 2 / 13; max-width: none; }
}

.brand { grid-area: brand; display: flex; align-items: center; gap: 8px; font-size: 20px; font-weight: 700; line-height: 1; letter-spacing: -.01em; }
/* The stopwatch from the favicon, glowing like the live dot it is built around. */
.brand svg { width: 20px; height: 20px; flex: none; fill: currentColor; color: var(--pitch); filter: drop-shadow(0 0 5px rgba(59, 214, 113, .55)); }

.tabs { grid-area: tabs; display: flex; align-self: stretch; gap: 24px; overflow-x: auto; scrollbar-width: none; font-size: 15px; }
.tab { position: relative; display: flex; align-items: center; gap: 4px; padding-top: 5px; flex: none; color: var(--mist); font-weight: 700; white-space: nowrap; }
.tab:hover, .tab[aria-current] { color: var(--chalk); }
.tab[aria-current]::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; border-radius: 3px 3px 0 0; background: var(--chalk); }
.tab .n { font-size: 12px; font-weight: 500; color: var(--mist); }
.tab-live .n { color: var(--pitch); font-weight: 700; }
/* The star turns gold, like a starred match's, once there is something to follow; the label keeps
   the tabs' colours. */
.tab-starred.has::before { background: var(--gold); }
/* A goal in a followed match happened while the visitor was away and is not on screen yet. */
.tab-starred[data-unseen]::before { background: var(--alarm); animation: unseen 1.2s ease-in-out infinite; }
@keyframes unseen { 50% { opacity: .35; } }
.tab-starred::before { content: ""; width: 14px; height: 14px; margin-right: 2px; background: currentColor; -webkit-mask: var(--star-fill) center / contain no-repeat; mask: var(--star-fill) center / contain no-repeat; }

.search { grid-area: search; position: relative; justify-self: end; width: 100%; max-width: 260px; }
.search input { width: 100%; height: 36px; padding: 0 15px; background: var(--stand); border: 1px solid var(--line); border-radius: 8px; }
.search input::placeholder { color: var(--mist); }
.search input:focus { outline: none; border-color: var(--mist); }
/* Collapse or expand every league, from the list's top strip. */
.fold { display: grid; place-items: center; flex: none; width: 32px; height: 32px; margin-right: calc(4px - var(--edge)); padding: 0; background: transparent; border: 0; border-radius: 6px; color: var(--mist); cursor: pointer; }
.fold::before { content: ""; width: 18px; height: 18px; background: currentColor; -webkit-mask: var(--fold-in) center / contain no-repeat; mask: var(--fold-in) center / contain no-repeat; }
.fold[data-state="closed"]::before { -webkit-mask-image: var(--fold-out); mask-image: var(--fold-out); }
.fold:hover { color: var(--chalk); background: var(--stand-hi); }

main, .side { padding-top: 24px; padding-bottom: 48px; }

/* ---- The list's top strip: the window (hours either side of now) and collapse all ---- */

/* Inside the sheet, so the list and the side panel start on the same line. */
.bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; height: 48px; padding: 0 var(--edge); border-bottom: 1px solid var(--line); }
.ctl { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ctl-l { color: var(--mist); font-size: 13px; }
/* A segmented control: one outline, the chosen segment filled. */
.seg { display: inline-flex; flex: none; padding: 2px; border: 1px solid var(--line); border-radius: 16px; }
.seg button { height: 26px; padding: 0 11px; background: transparent; border: 0; border-radius: 13px; color: var(--mist); font-size: 13px; font-weight: 700; cursor: pointer; }
.seg button:hover { color: var(--chalk); }
.seg button[aria-pressed="true"] { background: var(--chalk); color: var(--night); }
@media (max-width: 599px) {
	.ctl-l { display: none; }
	.seg button { padding: 0 9px; }
}

/* The list by time: no league bands to fold or jump to, so each row names its competition. */
.by-time .fold { visibility: hidden; }
.m-lg { display: flex; align-items: center; gap: 6px; min-width: 0; color: var(--mist); font-size: 11px; line-height: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.m-lg .flag { width: 14px; height: 10px; }
/* Wider screens: beside the teams, left of the scores, where the row has room to spare. It steps
   aside while "Goal!" holds that spot. */
@media (min-width: 600px) {
	.m-lg { position: absolute; top: 50%; right: calc(var(--edge) + 58px); max-width: 38%; margin-top: -7px; justify-content: flex-end; font-size: 12px; }
	.m[data-goal] .m-lg { visibility: hidden; }
	/* A live row's minute sits there already, so its league steps further left. */
	.m[data-b="live"] .m-lg { right: calc(var(--edge) + 93px); max-width: 30%; }
}
.searching .bar, .searching .more { display: none; }
.more { display: block; width: 100%; height: 48px; background: transparent; border: 0; border-top: 1px solid var(--line); color: var(--mist); font-size: 14px; font-weight: 700; cursor: pointer; }
.more:hover { background: var(--stand-hi); color: var(--chalk); }

/* Desktop: the strip stays in view under the header while the list scrolls, and the league bands
   stick just below it. Phones let it scroll away: header, strip and band would take too much. */
@media (min-width: 900px) {
	.bar { position: sticky; top: var(--top); z-index: 3; background: var(--stand); }
	.sheet .lg-h { top: calc(var(--top) + 48px); }
	.sheet .lg { scroll-margin-top: calc(var(--top) + 48px); }
}

/* ---- The sheet: one panel, league bands, compact rows ---- */

/* overflow: clip rounds the corners without breaking the sticky league bands. */
.sheet { background: var(--stand); border-radius: var(--radius); overflow: clip; }
/* The band is the divider; only collapsed bands stacked on each other need a hairline between them. */
.lg:not([open]) + .lg { border-top: 1px solid var(--line); }

.lg-h { position: sticky; top: var(--top); z-index: 2; display: grid; grid-template-columns: var(--c-star) var(--c-time) minmax(0, 1fr) auto auto 32px; align-items: center; height: 40px; padding-right: 4px; background: var(--stand-hi); font-weight: 700; }
.lg-h .flag { justify-self: center; }

/* Rows and bands start a few pixels in, past the expand chevron's slot, which every row keeps so
   the stars line up whether it shows or not; the score already ends on the dividers' right end. */
.m, .lg-h { padding-left: calc(var(--edge) + var(--c-chev) - (var(--c-star) - var(--star-icon)) / 2); }
.lg-n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The country is its own right-aligned column, so countries line up down the page. */
.lg-c { padding-left: var(--edge); color: var(--mist); font-weight: 500; white-space: nowrap; }
.lg-count { min-width: 28px; color: var(--mist); font-size: 13px; font-weight: 500; text-align: right; }
.lg[open] .lg-count { visibility: hidden; }
.lg-h::after { justify-self: center; }

.flag { width: 20px; height: 15px; border-radius: 2px; object-fit: cover; }
span.flag { background: var(--line); }

.m { position: relative; display: grid; grid-template-columns: var(--c-star) var(--c-time) minmax(0, 1fr); align-items: center; min-height: 52px; transition: background-color .6s; }
.m::after { content: ""; position: absolute; left: var(--edge); right: var(--edge); bottom: 0; height: 1px; background: var(--line); }
/* No line under a league's last visible row; the script marks it, since filters hide rows after it. */
.m.last::after, .m:last-child::after, .m:has(+ .dev-bar)::after { display: none; }
.m:hover { background: rgba(255, 255, 255, .02); }

.m-t { color: var(--mist); font-size: 13px; text-align: center; line-height: 1.15; white-space: nowrap; }
.m-t small { display: block; font-size: 11px; }
/* Past kickoff with no live coverage: only Starred and search show it, under its kickoff time. */
.m.await .m-t::after { content: "Awaiting"; display: block; font-size: 11px; }
/* The match card lists the kickoff under the score, so its clock needs no day line. */
.mh .m-t small { display: none; }
.m-x { display: grid; gap: 4px; padding: 8px calc(var(--edge) + 22px) 8px 0; min-width: 0; }
.m-r { display: flex; align-items: center; gap: 8px; line-height: 18px; }
.m-n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.m-s { position: relative; flex: none; margin-left: auto; padding-left: 20px; font-size: 15px; font-weight: 700; text-align: right; }

.crest { width: 16px; height: 16px; flex: none; object-fit: contain; }
span.crest { display: grid; place-items: center; border-radius: 50%; background: var(--line); color: var(--mist); font-size: 9px; font-weight: 700; line-height: 1; }

/* Finished: the losing side steps back, so the result reads before the numbers do. */
.m-r.lo { color: var(--mist); }
.m-r.lo .m-s { font-weight: 500; }

/* Live: green minute and score, and a green edge on the row. */
.m[data-b="live"]::before { content: ""; position: absolute; left: 0; top: 10px; bottom: 10px; width: 3px; border-radius: 0 3px 3px 0; background: var(--pitch); }
.m[data-b="live"] .m-t, .m[data-b="live"] .m-s, .mh[data-b="live"] .m-t, .mh[data-b="live"] .m-s { color: var(--pitch); font-weight: 700; }

/* The clock's apostrophe blinks while the clock runs: a second on, a second off. */
.ap { font-style: normal; animation: tick 2s linear infinite; }
/* The match card counts seconds, which already shows the clock running. */
.mh .ap { animation: none; }
@keyframes tick {
	0%, 49% { opacity: 1; }
	50%, 100% { opacity: 0; }
}

/* A live row's minute leaves the time column for the middle of the row, just left of the scores,
   where the eye already is: 10px from a one-digit score, as the attack dot is from it. The names
   stop short of it, and "Goal!" takes its place while it shows. */
.m-x { grid-column: 3; }
.m[data-b="live"] .m-t { position: absolute; top: 50%; right: calc(var(--edge) + 22px + 19px); translate: 0 -50%; font-size: 14px; text-align: right; }
/* Phones list the league above the teams, so the minute centres on the team lines below it. */
@media (max-width: 599px) { .m[data-b="live"]:has(.m-lg) .m-t { top: calc(50% + 8px); } }
.m[data-b="live"] .m-n { max-width: calc(100% - 113px); }
.m[data-goal] .m-t { visibility: hidden; }
/* On a live row the attack dot sits just left of the minute, raised to the attacking side's line,
   so the score beside it never moves. */
.m[data-b="live"][data-att] .m-fx { display: none; }
.m[data-b="live"][data-att] .m-s { margin-left: auto; padding-left: 20px; }
.m[data-b="live"][data-att] .m-t::before {
	content: "";
	display: inline-block;
	width: 8px;
	height: 8px;
	margin-right: 10px;
	border-radius: 50%;
	background: var(--alarm);
	vertical-align: middle;
	animation: beacon 1.2s ease-out infinite;
}
.m[data-b="live"][data-att="h"] .m-t::before { translate: 0 -11px; }
.m[data-b="live"][data-att="a"] .m-t::before { translate: 0 11px; }

/* Red is only ever a moment: a pulsing dot beside the score on a dangerous attack, and on a goal
   "Goal!" and a red score box over a red wash that fades in, holds and fades out.

   In the list the attack dot lives in .m-fx, an empty element each team line carries just before
   its score. On the match card it hangs off the big number. */
.m-fx { display: none; font-style: normal; }
[data-att="h"] [data-side="h"] .m-fx, [data-att="a"] [data-side="a"] .m-fx {
	display: inline-flex;
	align-items: center;
	margin-left: auto;
}
[data-att="h"] [data-side="h"] .m-s, [data-att="a"] [data-side="a"] .m-s { margin-left: 0; padding-left: 12px; }
/* The badge outlives the wash; keeping the padding stops it changing width when the wash ends. */
[data-scored="h"] [data-side="h"] .m-s, [data-scored="a"] [data-side="a"] .m-s { padding-left: 12px; }

/* The dot, for attacks only: a goal ends the attack, so the script clears it the moment one lands. */
[data-att="h"] [data-side="h"] .m-fx::after, [data-att="a"] [data-side="a"] .m-fx::after, .mh[data-att] .m-s::after {
	content: "";
	flex: none;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: var(--alarm);
	animation: beacon 1.2s ease-out infinite;
}
@keyframes beacon {
	0% { box-shadow: 0 0 0 0 rgba(255, 61, 82, .7); }
	100% { box-shadow: 0 0 0 5px rgba(255, 61, 82, 0); }
}

/* "Goal!" sits in the middle of the row, between the two team lines and just left of the scores:
   the red score box already says which side scored. */
.m-x { position: relative; }
.m[data-goal] .m-x::after {
	content: "Goal!";
	position: absolute;
	top: 50%;
	right: calc(var(--edge) + 58px);
	margin-top: -12px;
	color: #fff;
	font-size: 17px;
	font-weight: 700;
	line-height: 22px;
	animation: goal-word 10s ease-out forwards;
}
@keyframes goal-word {
	0% { transform: scale(.6); opacity: 0; }
	4% { transform: scale(1.1); opacity: 1; }
	8% { transform: scale(1); }
	88% { opacity: 1; }
	100% { transform: scale(1); opacity: 0; }
}

/* The wash: the row, or the whole match card. */
.m[data-goal], .mh[data-goal] { animation: goal-row 10s ease-in-out forwards; }
@keyframes goal-row {
	0%, 100% { background-color: transparent; }
	6%, 75% { background-color: rgba(255, 61, 82, .2); }
}
.mh[data-goal] { animation-name: goal-card; }
@keyframes goal-card {
	0%, 100% { background-color: var(--stand); }
	6%, 75% { background-color: #372234; }
}

/* The scoring side's number sits on a red badge for fifteen seconds, outlasting the wash, so the
   new score is the last thing to settle. It has its own marker (data-scored) for that reason. */
.m-s { isolation: isolate; }
[data-scored="h"] .m-s[data-s="h"], [data-scored="a"] .m-s[data-s="a"] { animation: goal-text 15s ease-out forwards; }
[data-scored="h"] .m-s[data-s="h"]::before, [data-scored="a"] .m-s[data-s="a"]::before {
	content: "";
	position: absolute;
	inset: -2px -6px -2px 6px;
	z-index: -1;
	border-radius: 5px;
	background: var(--alarm);
	/* Digits have no descenders but the font reserves room for them, so the line box sits high on
	   the glyph. Nudging the badge down 0.06em centres it on the digit at any size. */
	translate: 0 .06em;
	animation: goal-badge 15s ease-out forwards;
}
.mh .m-s::before { inset: -6px -10px !important; border-radius: 10px !important; }
@keyframes goal-badge {
	0% { opacity: 0; transform: scale(.6); }
	3% { opacity: 1; transform: scale(1.12); }
	6% { transform: scale(1); }
	88% { opacity: 1; }
	100% { opacity: 0; transform: scale(1); }
}
@keyframes goal-text {
	0%, 90% { color: #fff; }
}

/* Match card: the attack dot sits on the outer side of that team's number, and "Goal!" takes the
   clock's place under the score. */
.mh .m-s { position: relative; }
.mh[data-att] .m-s::after { position: absolute; top: 50%; margin-top: -4px; display: none; }
.mh[data-att="h"] .m-s[data-s="h"]::after { display: block; right: calc(100% + 16px); }
.mh[data-att="a"] .m-s[data-s="a"]::after { display: block; left: calc(100% + 16px); }
.mh[data-goal] .m-t { font-size: 0 !important; }
.mh[data-goal] .m-t::after { content: "Goal!"; display: inline-block; color: #fff; font-size: 20px; font-weight: 700; animation: goal-word 10s ease-out forwards; }

/* The star is an SVG mask, centred exactly: font star glyphs sit off-centre in most typefaces. */
.star { display: grid; place-items: center; width: var(--c-star); height: 40px; padding: 0; border: 0; background: none; cursor: pointer; color: var(--mist); }
.star::before {
	content: "";
	width: var(--star-icon);
	height: var(--star-icon);
	background: currentColor;
	-webkit-mask: var(--star-line) center / contain no-repeat;
	mask: var(--star-line) center / contain no-repeat;
}
.star:hover { color: var(--chalk); }
.star[aria-pressed="true"] { color: var(--gold); }
.star[aria-pressed="true"]::before { -webkit-mask-image: var(--star-fill); mask-image: var(--star-fill); }
:root {
	--star-line: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3.2l2.7 5.5 6 .9-4.35 4.25 1.03 6-5.38-2.83-5.38 2.83 1.03-6L3.3 9.6l6-.9z' fill='none' stroke='black' stroke-width='1.8' stroke-linejoin='round'/%3E%3C/svg%3E");
	--fold-in: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 3.5l5 5 5-5M7 20.5l5-5 5 5' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	--fold-out: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 8.5l5-5 5 5M7 15.5l5 5 5-5' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	--ball: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke='black' stroke-width='2'/%3E%3Cpath d='M12 7.5l4.3 3.1-1.6 5h-5.4l-1.6-5z'/%3E%3C/svg%3E");
	--swap: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 20V5M3 9l4-4 4 4M17 4v15M13 15l4 4 4-4' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	--star-fill: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3.2l2.7 5.5 6 .9-4.35 4.25 1.03 6-5.38-2.83-5.38 2.83 1.03-6L3.3 9.6l6-.9z' stroke='black' stroke-width='1.8' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.empty { padding: 48px 0; color: var(--mist); text-align: center; }

/* ---- Search: the filtered board, then other days in the same sheet style ---- */

/* While searching, the results replace whatever else the main column holds. */
.searching main > :not(#board, #sx, #sx-board, #empty) { display: none; }
.sx { display: grid; gap: 8px; }
#board:not([hidden]) ~ .sx:not(:empty) { margin-top: 24px; }
.sx-h { padding: 0 2px 8px; color: var(--mist); font-size: 13px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.sx .sx-list + .sx-h { margin-top: 16px; }
.sx-list { background: var(--stand); border-radius: var(--radius); overflow: hidden; }
.sx-r { position: relative; display: grid; grid-template-columns: 84px minmax(0, 1fr); column-gap: 12px; row-gap: 4px; padding: 10px var(--edge); }
.sx-r + .sx-r::before { content: ""; position: absolute; top: 0; left: var(--edge); right: var(--edge); height: 1px; background: var(--line); }
.sx-r:hover, .sx-r:focus-visible { background: var(--stand-hi); outline: none; }
.sx-d { grid-row: span 2; display: grid; align-content: start; gap: 4px; color: var(--mist); font-size: 13px; }
.sx-d b { color: var(--chalk); font-weight: 500; }
.sx-t { display: grid; gap: 4px; min-width: 0; }
.sx-t > span { display: flex; justify-content: space-between; gap: 12px; font-size: 15px; }
.sx-t b { font-weight: 700; }
.sx-t .lo { color: var(--mist); }
.sx-t .lo b { font-weight: 500; }
.sx-n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sx-l { color: var(--mist); font-size: 12px; }
.sx-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.sx-chip { display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 14px; border-radius: 17px; background: var(--stand); font-size: 14px; font-weight: 700; }
.sx-chip:hover { background: var(--stand-hi); color: var(--pitch); }
.sx-chip .flag { width: 18px; height: 13px; }

/* ---- Side panels: collapsible, any number open ---- */

.panel { margin-bottom: 16px; background: var(--stand); border-radius: var(--radius); }
.panel > summary { display: flex; align-items: center; justify-content: space-between; height: 48px; padding: 0 var(--edge); font-weight: 700; }
.panel > summary::after { margin-right: 4px; }
/* Panel contents sit in an ordinary box: a <details> element's own layout ignores grid gaps and
   lets margins escape, which is what left the last field touching the edge. */
.panel-body { display: grid; gap: var(--edge); padding: 0 var(--edge) var(--edge); }
.prefs label { display: grid; gap: 8px; color: var(--mist); font-size: 13px; }
.prefs select { width: 100%; height: 36px; padding: 0 8px; background: var(--stand-hi); border: 1px solid var(--line); border-radius: 8px; color: var(--chalk); font-size: 14px; }
.jump { list-style: none; margin: 0; padding: 0 0 8px; }
.jump a { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 8px var(--edge); }
.jump a:hover { background: var(--stand-hi); }
.jump span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jump small { color: var(--mist); font-size: 13px; }
@media (max-width: 899px) { .comps { display: none; } }

/* Desktop: the side column stays in view while the list scrolls, so the competitions list can jump
   from league to league; it scrolls on its own when taller than the window. */
@media (min-width: 900px) {
	.side { position: sticky; top: var(--top); max-height: calc(100vh - var(--top)); overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
}
/* A league jumped to lands just under the sticky header. */
.lg { scroll-margin-top: var(--top); }

/* ---- Match page: one card, score in the middle, details along the bottom ---- */

.mh { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: start; gap: 16px; padding: 8px var(--edge) 0; background: var(--stand); border-radius: var(--radius); overflow: hidden; }
.mh > .star { position: absolute; top: 0; right: 0; width: 44px; height: 44px; }
.mh-comp { grid-column: 1 / -1; padding: 0 44px; line-height: 36px; text-align: center; }
.mh-comp a { font-weight: 700; }
.mh-comp a:hover { color: var(--pitch); }
.mh-comp span { margin-left: 8px; color: var(--mist); }
.mh-team { display: grid; justify-items: center; gap: 8px; padding-top: 8px; text-align: center; font-size: 16px; font-weight: 700; }
.mh-team img, .mh-crest { width: 56px; height: 56px; }
.mh-crest { display: grid; place-items: center; border-radius: 50%; background: var(--stand-hi); color: var(--mist); font-size: 22px; }
.mh-team .m-n { white-space: normal; }
.mh-mid { display: grid; justify-items: center; gap: 8px; padding-top: 16px; }
.mh-score { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 24px; font-size: 52px; font-weight: 700; line-height: 1; }
.mh-score .m-s { min-width: 0; margin: 0; padding: 0; font-size: inherit; }
.mh-score [data-s="h"] { text-align: right; }
.mh-score [data-s="a"] { text-align: left; }
.mh-score i { font-style: normal; font-weight: 500; color: var(--mist); }
.mh-mid .m-t { font-size: 15px; }
.mh[data-b="up"] .mh-score { display: none; }
.mh[data-b="up"] .m-t { color: var(--chalk); font-size: 32px; font-weight: 700; }
.mh-facts { grid-column: 1 / -1; display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 32px; margin: 24px calc(-1 * var(--edge)) 0; padding: 16px var(--edge); border-top: 1px solid var(--line); color: var(--mist); font-size: 13px; }
.mh-facts b { margin-left: 6px; color: var(--chalk); font-weight: 500; }

/* ---- Expander: a match's details opened under its row in the list ---- */

/* The chevron in the row's left slot, on matches that have details to open. */
.m-c { display: none; position: absolute; top: 0; bottom: 0; left: 4px; width: calc(var(--edge) + var(--c-chev) - 4px); padding: 0; background: none; border: 0; cursor: pointer; }
.m.xpd .m-c { display: grid; place-items: center; }
.m-c::after { content: ""; width: 7px; height: 7px; border: solid var(--mist); border-width: 0 2px 2px 0; transform: rotate(-45deg); transition: transform .15s; }
.m-c:hover::after, .m-c:focus-visible::after { border-color: var(--chalk); }
.m.xp-on .m-c::after { transform: translateY(-2px) rotate(45deg); }

.m.xp-on { background: var(--stand-hi); }
.m.xp-on::after { display: none; }
.xp { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); background: rgba(0, 0, 0, .18); }
.xp-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px var(--edge) 0; color: var(--mist); font-size: 13px; }
.xp-facts { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.xp-facts b { margin-left: 4px; color: var(--chalk); font-weight: 500; }
.xp-full { flex: none; font-weight: 700; }
.xp-full::after { content: " \2192"; }
.xp-full:hover { color: var(--chalk); }
.xp .dt { margin: 0; background: transparent; border-radius: 0; }
.xp .sx-list { margin: 0; }
.xp .dt-none { padding: 12px 0 16px; }
.ev-tm { display: none; }

/* ---- Team and league pages ---- */

.pg-h { display: flex; align-items: center; gap: 16px; margin-bottom: 24px; }
.pg-h img, .pg-h .mh-crest { flex: none; width: 56px; height: 56px; }
.pg-h .flag { width: 40px; height: 30px; }
.pg-h h1 { font-size: 26px; line-height: 1.15; }
.pg-sub { display: flex; align-items: center; gap: 10px; margin-top: 6px; color: var(--mist); font-size: 14px; }
a.mh-team:hover .m-n, .tbl-team a:hover, .fm-h > a:hover { color: var(--pitch); }

/* Form: the last five results, oldest first, as small lettered squares. */
.form { display: inline-flex; gap: 4px; }
.form a { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 4px; color: var(--night); font-size: 11px; font-weight: 700; }
.form a[data-r="W"] { background: var(--pitch); }
.form a[data-r="D"] { background: var(--mist); }
.form a[data-r="L"] { background: var(--alarm); color: #fff; }
.fm-h { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 12px 0 8px; font-size: 15px; }
.fm .sx-list { border: 1px solid var(--line); }

/* League table */
.tbl-box { padding: 4px 0; }
.tbl { width: 100%; border-collapse: collapse; font-size: 14px; font-variant-numeric: tabular-nums; }
.tbl caption { padding: 12px var(--edge) 6px; color: var(--mist); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-align: left; text-transform: uppercase; }
.tbl th { padding: 8px 6px; color: var(--mist); font-size: 12px; font-weight: 700; text-align: right; }
.tbl td { padding: 7px 6px; border-top: 1px solid var(--line); text-align: right; }
.tbl th:first-child, .tbl td:first-child { width: 36px; padding-left: var(--edge); color: var(--mist); text-align: left; }
.tbl th:last-child, .tbl td:last-child { padding-right: var(--edge); }
.tbl .tbl-team { width: 100%; max-width: 0; overflow: hidden; text-align: left; text-overflow: ellipsis; white-space: nowrap; }
.tbl tr[data-zone] td:first-child { box-shadow: inset 3px 0 0 var(--zone); }
.tbl tr[data-zone="up"] { --zone: var(--pitch); }
.tbl tr[data-zone="mid"] { --zone: #5b8def; }
.tbl tr[data-zone="down"] { --zone: var(--alarm); }
.tbl tr.tbl-on td { background: var(--stand-hi); font-weight: 700; }
.dt-p .tbl th:first-child, .dt-p .tbl td:first-child { padding-left: 4px; }
.dt-p .tbl th:last-child, .dt-p .tbl td:last-child { padding-right: 4px; }
@media (max-width: 599px) { .tbl-wdl { display: none; } }

/* Head-to-head: wins each side and draws, then the meetings. */
.h2h-sum { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 8px 0 12px; text-align: center; }
.h2h-sum span { display: grid; gap: 2px; min-width: 0; color: var(--mist); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.h2h-sum b { color: var(--chalk); font-size: 24px; }
.dt-p > .sx-list { border: 1px solid var(--line); }

/* Odds: home, draw and away side by side. */
.od-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 8px; }
.od-row span { display: grid; gap: 4px; min-width: 0; padding: 12px; border-radius: 8px; background: var(--stand-hi); text-align: center; }
.od-row small { overflow: hidden; color: var(--mist); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
.od-row b { font-size: 20px; }
.od-note { margin-top: 12px; color: var(--mist); font-size: 12px; text-align: center; }

/* ---- Goal info on starred rows: an "i" right of the scores, a small list of the goals ---- */

.m-i { display: none; position: absolute; z-index: 1; top: 50%; right: calc(var(--edge) - 7px); width: 26px; height: 26px; margin-top: -13px; padding: 0; background: transparent; border: 0; border-radius: 50%; color: var(--mist); cursor: pointer; }
.m-i::before { content: "i"; display: grid; place-items: center; width: 16px; height: 16px; margin: auto; border: 1.5px solid currentColor; border-radius: 50%; font: italic 700 11px/1 Georgia, serif; }
.m-i:hover, .m-i:focus-visible { color: var(--chalk); }
/* Starred matches with at least one goal. Every row keeps this column (see .m-x), so the scores
   line up whether the icon shows or not. */
.m.starred.has-goals .m-i { display: block; }

.gp { position: absolute; z-index: 30; min-width: 200px; max-width: 280px; padding: 10px 12px; background: var(--stand-hi); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 12px 30px rgba(0, 0, 0, .45); font-size: 13px; }
.gp-g { display: grid; grid-template-columns: 40px minmax(0, 1fr); column-gap: 8px; padding: 3px 0; }
.gp-g b { color: var(--pitch); }
.gp-g span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gp-g small { grid-column: 2; color: var(--mist); font-size: 11px; }
.gp-since, .gp-none { color: var(--mist); font-size: 12px; }
.gp-since { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--line); }

/* ---- Red cards: beside the team name, in the list and on the match card ---- */

.rc { display: inline-flex; align-items: center; gap: 3px; margin-left: 6px; flex: none; color: var(--alarm); font-size: 11px; font-style: normal; font-weight: 700; vertical-align: 1px; }
.rc::before { content: ""; width: 8px; height: 11px; border-radius: 1.5px; background: var(--alarm); }
.rc::after { content: attr(data-n); }
.rc[data-n="0"] { display: none; }
.rc[data-n="1"]::after { content: none; }

/* ---- Match details: Summary, Line-ups and Stats under the match card ---- */

#details:not(:empty) { margin-top: 16px; }
.dt { background: var(--stand); border-radius: var(--radius); overflow: hidden; }
.dt-tabs { display: flex; gap: 24px; height: 48px; padding: 0 var(--edge); overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--line); }
.dt-tabs button { position: relative; flex: none; padding: 0; background: none; border: 0; color: var(--mist); font-size: 15px; font-weight: 700; white-space: nowrap; cursor: pointer; }
.dt-tabs button:hover, .dt-tabs button[aria-selected="true"] { color: var(--chalk); }
.dt-tabs button[aria-selected="true"]::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; border-radius: 3px 3px 0 0; background: var(--chalk); }
.dt-p { padding: 8px var(--edge) 16px; }
.dt-none { padding: 24px 0 8px; color: var(--mist); text-align: center; }

/* Summary: home events on the left, away on the right, the minute between them. */
.ev { display: grid; grid-template-columns: minmax(0, 1fr) 56px minmax(0, 1fr); align-items: center; min-height: 44px; }
.ev-m { grid-area: 1 / 2; color: var(--mist); font-size: 13px; text-align: center; }
.ev-b { grid-row: 1; display: flex; align-items: center; gap: 10px; min-width: 0; }
.ev-h .ev-b { grid-column: 1; flex-direction: row-reverse; text-align: right; }
.ev-a .ev-b { grid-column: 3; }
.ev-t { display: grid; min-width: 0; }
.ev-t b, .ev-t small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-t small { color: var(--mist); font-size: 12px; }
.ev-s { flex: none; padding: 2px 6px; border-radius: 4px; background: var(--stand-hi); font-size: 13px; font-weight: 700; }
.ev-i { flex: none; width: 16px; height: 16px; background: var(--chalk); -webkit-mask: var(--ball) center / contain no-repeat; mask: var(--ball) center / contain no-repeat; }
.ev[data-k="og"] .ev-i { background: var(--alarm); }
.ev[data-k="miss"] .ev-i { background: var(--mist); }
.ev[data-k="yc"] .ev-i, .ev[data-k="rc"] .ev-i, .ev[data-k="y2"] .ev-i { width: 11px; height: 15px; margin: 0 2px; border-radius: 2px; -webkit-mask: none; mask: none; }
.ev[data-k="yc"] .ev-i { background: var(--gold); }
.ev[data-k="rc"] .ev-i { background: var(--alarm); }
.ev[data-k="y2"] .ev-i { background: linear-gradient(135deg, var(--gold) 50%, var(--alarm) 50%); }
.ev[data-k="sub"] .ev-i { background: var(--pitch); -webkit-mask-image: var(--swap); mask-image: var(--swap); }
.ev[data-k="var"] .ev-i { width: auto; height: auto; padding: 1px 4px; border-radius: 3px; background: var(--stand-hi); -webkit-mask: none; mask: none; }
.ev[data-k="var"] .ev-i::before { content: "VAR"; color: var(--mist); font-size: 10px; font-style: normal; font-weight: 700; }
.ev-div { margin: 8px 0; padding: 6px; border-radius: 6px; background: var(--stand-hi); color: var(--mist); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-align: center; text-transform: uppercase; }
.ev-div b { margin-left: 6px; color: var(--chalk); }

/* Line-ups: the two sides next to each other. */
.lu { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px; }
.lu-h { display: flex; justify-content: space-between; gap: 8px; margin: 8px 0 12px; font-size: 15px; }
.lu-h span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lu-h small { color: var(--mist); font-size: 13px; font-weight: 500; }
.lu-list { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.lu-list li { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; gap: 8px; font-size: 14px; }
.lu-n { color: var(--mist); text-align: right; }
.lu-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lu-pos { color: var(--mist); font-size: 12px; }
.lu-sub { margin: 16px 0 8px; color: var(--mist); font-size: 12px; letter-spacing: .04em; text-transform: uppercase; }
.lu-coach { margin-top: 12px; color: var(--mist); font-size: 13px; }
.lu-coach b { margin-left: 4px; color: var(--chalk); font-weight: 500; }

/* Stats: the two values either side of the name, a bar split by the home side's share. */
.st { display: grid; gap: 14px; padding-top: 16px; }
.st-row { display: grid; grid-template-columns: 56px minmax(0, 1fr) 56px; align-items: center; row-gap: 6px; font-size: 14px; }
.st-row > span:not(.st-bar) { color: var(--mist); font-size: 13px; text-align: center; }
.st-row > b:last-of-type { text-align: right; }
.st-bar { grid-column: 1 / -1; height: 4px; border-radius: 2px; background: linear-gradient(to right, var(--chalk) var(--h, 50%), var(--line) var(--h, 50%)); }

@media (max-width: 599px) {
	.lu { gap: 12px; }
	.lu-list li { grid-template-columns: 18px minmax(0, 1fr); font-size: 13px; }
	.lu-pos { display: none; }
}
@media (max-width: 599px) {
	.mh { gap: 8px; }
	.mh-team { font-size: 14px; }
	.mh-team img, .mh-crest { width: 40px; height: 40px; }
	.mh-score { font-size: 40px; gap: 8px; }
}

/* ---- One column: the sheet, the match card and the panels run edge to edge, giving names and
   scores the room. Their rows keep their own inner padding, so text never touches the edge. ---- */

@media (max-width: 899px) {
	.sheet, .mh, .panel, .sx-list, .dt { margin-left: -16px; margin-right: -16px; border-radius: 0; }
	.lg-h { border-radius: 0; }
	main { padding-top: 12px; padding-bottom: 16px; }
	.side { padding-top: 0; }
}

@media (max-width: 599px) {
	.tabs { gap: 18px; font-size: 14px; }
}

/* ---- Development test page ---- */

.dev-note { max-width: 62ch; margin-bottom: 24px; color: var(--mist); line-height: 1.45; }
.dev-bar { position: relative; display: flex; flex-wrap: wrap; gap: 8px; padding: 0 var(--edge) 16px calc(var(--edge) - (var(--c-star) - var(--star-icon)) / 2 + var(--c-star) + var(--c-time)); }
.dev-bar::after { content: ""; position: absolute; left: var(--edge); right: var(--edge); bottom: 0; height: 1px; background: var(--line); }
.dev-bar:last-child::after { display: none; }
.dev-bar button { height: 28px; padding: 0 10px; background: var(--stand-hi); border: 1px solid var(--line); border-radius: 6px; cursor: pointer; color: var(--mist); font-size: 12px; font-weight: 700; }
.dev-bar button:hover { border-color: var(--mist); color: var(--chalk); }
.dev-bar a { align-self: center; margin-left: 8px; color: var(--mist); font-size: 12px; font-weight: 700; }
.dev-bar a:hover { color: var(--chalk); }
.dev-h { margin: 32px 0 16px; color: var(--mist); font-size: 14px; font-weight: 700; }
.dev-bar-card { justify-content: center; padding: 16px 0 0; }
.dev-bar-card::after { display: none; }

/* Reduced motion drops movement (scaling, spreading rings, sliding chevrons) but keeps the blinks
   and colour flashes: they carry live state, and fading in place moves nothing. */
@media (prefers-reduced-motion: reduce) {
	.m[data-goal] .m-x::after, .mh[data-goal] .m-t::after { animation: none; }
	[data-scored] .m-s::before { animation-name: goal-badge-still; }
	.m-fx::after, .mh[data-att] .m-s::after, .m[data-att] .m-t::before { animation-name: beacon-still; }
	.m, .lg-h::after, .panel > summary::after, .m-c::after { transition: none; }
}
@keyframes beacon-still { 50% { opacity: .35; } }
@keyframes goal-badge-still {
	0%, 100% { opacity: 0; }
	3%, 88% { opacity: 1; }
}
