/* 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 {
	/* Charcoal with a breath of the stadium photo's teal (hue 205), muted so the panels sit on the
	   floodlit pitch as dark slabs rather than blue cards. */
	--night: #0e151b;
	--stand: #151d23;
	--stand-hi: #1e282e;
	--line: #2a353c;
	--chalk: #edf1f7;
	--mist: #8d9ba5;
	--pitch: #3bd671;
	--alarm: #ff3d52;
	--gold: #ffc83d;
	--ai: #6cc4ff;
	/* A price chip: a best price, lit like a board under floodlights. */
	--chip: linear-gradient(180deg, #2c3a44, #222d35);
	--chip-hover: linear-gradient(180deg, #364754, #2a3741);
	/* A price the prediction picks, lit in teal from the stadium's tones; the prediction itself
	   (spark, score, its card and chances) keeps the blue of --ai. Green stays for what is live. */
	--pick: #3fd4c2;
	--chip-pick: linear-gradient(180deg, rgba(63, 212, 194, .34), rgba(63, 212, 194, .16));
	--chip-edge: inset 0 1px rgba(255, 255, 255, .09), 0 1px 2px rgba(0, 0, 0, .45);
	--chip-pick-edge: inset 0 0 0 1px rgba(63, 212, 194, .6), 0 1px 2px rgba(0, 0, 0, .45);

	--c-chev: 20px;
	--c-star: 36px;
	--c-time: 48px;
	--star-icon: 21px;
	--edge: 16px;
	--top: 97px;
	--radius: 12px;
	/* A panel over the photo: a faint chalk edge and a soft shadow under it, so its corners hold
	   wherever the picture behind is as dark as the panel. */
	--lift: 0 0 0 1px rgba(237, 241, 247, .06), 0 12px 32px -16px rgba(0, 0, 0, .7);
	/* The desktop side column: three of twelve columns (a quarter less 12px) plus 30px for the chat. */
	--side: calc(25% + 18px);
	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;
}
/* Behind it all, a floodlit stadium at night, blurred and under the night blue so it never fights
   the text: Alex Simpson's photo from Unsplash (unsplash.com/photos/DOicNPBVSHs, free licence),
   fetched blurred at 1600px, 30 KB. It holds still while the page scrolls over it. The panels are
   solid, so it shows between and around them; the header and the sticky search band carry the same
   view of it, fixed too, so they read as see-through while rows still never show through them. */
:root { --backdrop: linear-gradient(rgba(14, 21, 27, .72), rgba(14, 21, 27, .86)) fixed, url("../img/stadium-night.webp") center / cover no-repeat fixed var(--night); }
body::before {
	content: "";
	position: fixed;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	background: var(--backdrop);
}
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 var(--edge); 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; }
	/* The page itself: the list, then a side column 30px wider than three of the twelve columns,
	   so the chat room has room. */
	.wrap.cols { grid-template-columns: minmax(0, 1fr) var(--side); }
	.wrap.cols > main, .wrap.cols > .side { grid-column: auto !important; }
}

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

/* Opaque, with the page's backdrop pinned behind it like the page's own: it looks see-through,
   but rows scrolling under it never show, as they did through the old blurred see-through bar. */
.top { position: sticky; top: 0; z-index: 10; background: var(--backdrop); border-bottom: 1px solid var(--line); }
/* Phone: brand and search on one row, tabs underneath. Desktop: the same two 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: minmax(0, 1fr) var(--side); grid-template-rows: 64px; grid-template-areas: none; column-gap: var(--edge); }
	.top-main { grid-column: 1; display: flex; align-items: center; align-self: stretch; gap: 32px; min-width: 0; }
	.top-in .search { grid-area: 1 / 2; 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)); }
.brand-t { display: grid; gap: 3px; }
.brand-t small { color: var(--mist); font-size: 11px; font-weight: 500; letter-spacing: .02em; white-space: nowrap; }
@media (max-width: 379px) { .brand-t small { display: none; } }

.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; } }
/* Up half a pixel: the flex line centres it a little below the middle of the label's capitals. */
.tab-starred::before { content: ""; width: 14px; height: 14px; margin-right: 2px; translate: 0 -.5px; background: currentColor; -webkit-mask: var(--star-fill) center / contain no-repeat; mask: var(--star-fill) center / contain no-repeat; }

/* The box is the outline, holding a magnifier, a country chip, the words and the cross to clear them. */
.search { grid-area: search; position: relative; justify-self: end; display: flex; align-items: center; gap: 8px; width: 100%; max-width: 260px; height: 36px; padding: 0 4px 0 12px; background: var(--stand); border: 1px solid var(--line); border-radius: 8px; }
.search::before { content: ""; flex: none; width: 15px; height: 15px; background: var(--mist); -webkit-mask: var(--glass) center / contain no-repeat; mask: var(--glass) center / contain no-repeat; }
.search:focus-within { border-color: var(--mist); }
.search:focus-within::before { background: var(--chalk); }
.search input { flex: 1; min-width: 0; height: 100%; padding: 0; background: transparent; border: 0; }
.search input::placeholder { color: var(--mist); }
.search input:focus { outline: none; }
.search input::-webkit-search-cancel-button { display: none; -webkit-appearance: none; }
.q-h { flex: none; color: var(--mist); font-size: 12px; white-space: nowrap; }
/* The cross, with its key beside it where there is a keyboard. It only shows on a lit box, so its
   hover takes the line colour. */
.q-x { display: flex; align-items: center; justify-content: center; gap: 7px; flex: none; min-width: 28px; height: 28px; padding: 0 8px; background: transparent; border: 0; border-radius: 6px; color: var(--mist); cursor: pointer; }
.q-x::before, .q-c::after { content: ""; width: 12px; height: 12px; background: currentColor; -webkit-mask: var(--cross) center / contain no-repeat; mask: var(--cross) center / contain no-repeat; }
.q-x::before { order: 1; flex: none; }
.q-x:hover { color: var(--chalk); background: var(--line); }
.q-x kbd { padding: 1px 5px; border: 1px solid var(--line); border-radius: 4px; font: inherit; font-size: 11px; line-height: 14px; }
.q-x:hover kbd { border-color: var(--mist); }
@media (hover: none), (pointer: coarse) {
	.q-x { padding: 0; }
	.q-x kbd { display: none; }
}
.q-c { display: inline-flex; align-items: center; gap: 6px; flex: none; max-width: 50%; height: 26px; padding: 0 8px 0 7px; background: var(--stand-hi); border: 1px solid var(--line); border-radius: 13px; color: var(--chalk); font-size: 13px; font-weight: 700; cursor: pointer; }
.q-c span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.q-c::after { width: 9px; height: 9px; flex: none; color: var(--mist); }
.q-c:hover::after { color: var(--chalk); }
/* The front page's search leads the list at full width. On desktop it stays in view with the
   list's strip and league bands stacked under it; hidden on Starred, they close the gap. */
.qbar { margin-bottom: 12px; }
/* As tall as a closed side panel, the chat's, so the box and the list under it line up with the
   side column's panels. */
.qbar .search { max-width: none; height: 48px; padding-left: calc(var(--edge) - 1px); border-color: transparent; border-radius: var(--radius); box-shadow: var(--lift); }
.qbar .search:focus-within { border-color: var(--mist); }
/* Lit while it narrows the list, by words or a country; its chip turns the other way to stand out. */
.search:has(input:not(:placeholder-shown), .q-c:not([hidden])) { background: var(--stand-hi); }
.search:has(input:not(:placeholder-shown), .q-c:not([hidden])) .q-c { background: var(--stand); }
@media (min-width: 900px) {
	/* Once it sticks it keeps the page's top gap above it (main's padding, pulled inside it), so it
	   holds still from the first pixel of scrolling instead of sliding up into a smaller gap. Under
	   it, the side column's gap between panels. */
	.qbar { position: sticky; top: var(--top); z-index: 4; margin: calc(-1 * var(--edge)) 0 0; padding: var(--edge) 0; background: var(--backdrop); }
	.qbar:not([hidden]) ~ .sheet .bar { top: calc(var(--top) + var(--edge) + 64px); }
	.qbar:not([hidden]) ~ .sheet .lg-h { top: calc(var(--top) + var(--edge) + 112px); }
	.qbar:not([hidden]) ~ .sheet .lg { scroll-margin-top: calc(var(--top) + var(--edge) + 112px); }
	/* A search hides the strip, so the bands stick right under the box. */
	.searching .qbar ~ .sheet .lg-h { top: calc(var(--top) + var(--edge) + 64px); }
	/* The stuck layers meet edge to edge, and on a scaled screen a fast scroll can open a hairline
	   between them that rows flash through. Each covers a pixel above it in the colour already
	   there: the header's border, the night under the box, the sheet under the strip. */
	.qbar { box-shadow: 0 -1px 0 var(--line); }
	.sheet .bar { box-shadow: 0 -1px 0 var(--night); }
	.sheet .lg-h { box-shadow: 0 -1px 0 var(--stand); }
}
/* What a search found, marked in the names (app.js). */
::highlight(q) { background-color: rgba(59, 214, 113, .3); color: var(--chalk); }
/* A league's flag on the board narrows it to the country. */
.sheet .flag[data-co] { cursor: pointer; }
/* 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: var(--edge); 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); }
/* The goal sound, on the Starred tab only: a bell in the same outline, struck through when off. */
/* The bell is pressed like a .seg button: a lit 26px disc inside the ring while the sound is on. */
.bell { display: grid; place-items: center; flex: none; width: 32px; height: 32px; padding: 2px; background: var(--chalk) content-box; border: 1px solid var(--line); border-radius: 16px; color: var(--night); cursor: pointer; }
.bell::before { content: ""; width: 16px; height: 16px; background: currentColor; -webkit-mask: var(--bell) center / contain no-repeat; mask: var(--bell) center / contain no-repeat; }
.bell[aria-pressed="false"] { background: transparent; color: var(--mist); }
.bell[aria-pressed="false"]::before { -webkit-mask-image: var(--bell-off); mask-image: var(--bell-off); }
.bell[aria-pressed="false"]:hover { color: var(--chalk); }
.bell[hidden] { display: none; }
/* Live and Starred list every live or starred match: no window, and nothing more to show. */
.own .win, .own .more { display: none; }
/* Clear all, on the Starred tab: asks in place, Yes in the alarm red. */
.clear[hidden], .clr-q[hidden], .clear [hidden] { display: none; }
.clr-q { display: inline-flex; align-items: center; }
.clr-n { padding: 0 8px 0 9px; color: var(--chalk); font-size: 13px; font-weight: 700; white-space: nowrap; }
.clear.asking { border-color: var(--alarm); }
.clear [data-clear="yes"] { background: var(--alarm); color: var(--chalk); }
.clear [data-clear="yes"]:hover { background: #ff5869; }
@media (max-width: 599px) {
	.ctl-l { display: none; }
	.seg button { padding: 0 9px; }
	/* With Top | All too, the pills need about 350px: the narrowest phones take it on a second
	   line rather than run off the edge. Phones don't stick the strip, so it may grow. */
	.bar { height: auto; min-height: 48px; }
	.ctl { flex-wrap: wrap; row-gap: 8px; padding: 8px 0; }
}
@media (max-width: 429px) { .seg button { padding: 0 7px; } }
/* The smallest phones, on the Starred tab: room for the bell beside the collapse button. */
@media (max-width: 379px) {
	.ctl { gap: 6px; }
	.seg button { padding: 0 7px; }
}

/* 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; }
/* Phones: the league is a strip across the top of the row, and everything else (star, time, teams,
   scores, pill) centres on the teams below it, so rows line up as if the strip were not there. The
   league line is the strip itself, 22px high with its name centred, pulled up into the row's top
   padding. Its grid row then collapses to nothing (a track never goes below 0), leaving only the
   4px gap under it, so the teams' top padding gives up those 4px: they start 8px under the strip,
   as far as they end above the row's foot. Absolutely placed parts move down by half the strip. */
@media (max-width: 599px) {
	.m:has(.m-lg) { min-height: 74px; padding-top: 22px; background-image: linear-gradient(var(--stand-hi) 22px, transparent 22px); }
	.m:has(.m-lg) .m-x { padding-top: 4px; }
	/* The font's caps sit low in their line, so the label centres 2px above the strip's middle. */
	.m-lg { height: 22px; margin-top: -26px; padding-bottom: 4px; }
	.m:has(.m-lg) :is(.m-o, .m-i) { top: calc(50% + 11px); }
}
/* Wider screens: beside the teams, left of the scores, where the row has room to spare. It steps
   aside while "Goal!" or "No 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, .m[data-ng] .m-lg { visibility: hidden; }
	/* A live row's minute sits there already, and the attack dot's column left of it, so its league
	   steps further left, 10px clear of the dot. */
	.m:is([data-b="live"], [data-b="fin"]) .m-lg { right: calc(var(--edge) + 100px); max-width: 30%; }
	/* With prices among the shown rows, every row's league steps left of the widest pill and guess,
	   so the leagues still end in one line whatever each row shows. app.js sets .odds as it filters:
	   a :has() over the shown rows rechecked the whole sheet on every row shown or hidden. */
	.sheet.odds .m-lg { right: calc(var(--edge) + 280px); max-width: 24%; }
	.sheet.odds .m:has(.m-lg) .m-n { max-width: calc(76% - 300px); }
	/* A narrow list keeps only the league's flag, which names it on hover, before the name would
	   run into a long team name: sooner when prices take the right of the row. Team names stop
	   short of the flag. */
	@container sheet (max-width: 560px) {
		.m-lgn { display: none; }
		.m[data-b="up"]:has(.m-lg) .m-n { max-width: calc(100% - 84px); }
	}
	@container sheet (max-width: 760px) {
		.sheet.odds .m-lgn { display: none; }
		.sheet.odds .m:has(.m-lg) .m-n { max-width: calc(100% - 304px); }
	}
}
.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 { container: sheet / inline-size; background: var(--stand); border-radius: var(--radius); box-shadow: var(--lift); 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; }
/* The flag and the clock below it centre between the star icon and the crests rather than in
   their column: the star's button leaves room right of its icon, so the column's own centre sits
   too far right. Padding on the right by that room moves them halfway back. */
.lg-h .flag { justify-self: center; margin-right: calc((var(--c-star) - var(--star-icon)) / 2); }

/* 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 league's name links to its page; the rest of the band folds it. */
a.lg-n { justify-self: start; max-width: 100%; }
a.lg-n:hover, a.lg-n:focus-visible { color: var(--pitch); text-decoration: underline; text-underline-offset: 3px; }
/* 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: 0; right: 0; 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 .m-t { padding-right: calc((var(--c-star) - var(--star-icon)) / 2); }
.m-t small { display: block; font-size: 11px; }
/* AM/PM after a 12-hour kickoff. */
.mer { margin-left: 2px; font-size: 10px; }
/* A live row's kickoff, in the time column its minute left for the score, and Live under it in
   the live green, as a finished row has its day over FT. */
.m-k { display: none; }
.m[data-b="live"] .m-k::after { content: "Live"; display: block; color: var(--pitch); font-size: 11px; font-weight: 700; }
.m[data-b="live"] .m-k { display: block; grid-column: 2; grid-row: 1; padding-right: calc((var(--c-star) - var(--star-icon)) / 2); color: var(--mist); font-size: 13px; line-height: 1.15; text-align: center; white-space: nowrap; }
/* An upcoming kickoff's digits sat half a pixel below the middle of the team names beside them.
   Upcoming only: two lines (a day over FT, a kickoff over Live) centre as they are, and a finished
   row's time holds the absolutely placed FT, which a translate would take as its frame. */
.m[data-b="up"] .m-t { translate: 0 -.5px; }
/* 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; }
/* One column the width of the row, however long a name: the names' limits are shares of it. */
.m-x { display: grid; grid-template-columns: minmax(0, 1fr); 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; }
/* Larger and bold on the name's line, the digits sat 1px below the name's letters. */
.m .m-s { top: -1px; }

.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. It stays put through a goal: "Goal!" takes its own spot to its left. */
.m-x { grid-column: 3; }
.m[data-b="live"] .m-t { position: absolute; top: 50%; right: calc(var(--edge) + 22px + 19px); translate: 0 -50%; padding-right: 0; 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% + 11px); } }
.m[data-b="live"] .m-n { max-width: calc(100% - 113px); }
/* Before kickoff the best prices sit in the same spot, as one pill: 1, X and 2. The row's link
   still takes the click. Once the match starts the pill goes; the Odds tab keeps the prices. */
.m-o { position: absolute; top: 50%; right: calc(var(--edge) + 22px); display: flex; gap: 4px; translate: 0 -50%; pointer-events: none; }
.m-og { display: flex; gap: 3px; }
.m-og > * { display: grid; justify-items: center; width: 44px; padding: 3px 0 4px; border-radius: 7px; background: var(--chip); box-shadow: var(--chip-edge); color: #fff; font-size: 13px; font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums; }
.m-og > [data-tip] { pointer-events: auto; cursor: pointer; }
/* Prices that open a bookmaker's site carry the outbound arrow, like links elsewhere. */
.m-og > a { position: relative; }
.m-og > a::after { content: ""; position: absolute; top: 3px; right: 3px; width: 9px; height: 9px; background: #c3cddb; -webkit-mask: var(--ext) center / contain no-repeat; mask: var(--ext) center / contain no-repeat; }
.m-og > a:hover::after { background: #fff; }
.m-og > a.ai::after { background: var(--pick); }
.m-og > [data-tip]:hover { background: var(--chip-hover); }
.m-o small { color: var(--mist); font-size: 10px; font-weight: 500; white-space: nowrap; }
/* The model's guess: its result and goal line lit in the pill, and its score beside a spark,
   which tells the chances on hover or focus. */
.m-og > .ai, .m-og > .ai[data-tip]:hover { background: var(--chip-pick); box-shadow: var(--chip-pick-edge); }
.m-og > .ai small { color: var(--pick); }
.ai-i { display: inline-block; flex: none; width: 14px; height: 14px; background: var(--ai); -webkit-mask: var(--spark) center / contain no-repeat; mask: var(--spark) center / contain no-repeat; font-style: normal; }
.m-ai { position: absolute; top: 50%; right: calc(var(--edge) + 22px + 202px); display: flex; align-items: center; gap: 4px; translate: 0 -50%; color: var(--ai); font-size: 13px; font-weight: 700; cursor: help; }
.m-ai:focus-visible { outline: 2px solid var(--ai); outline-offset: 2px; border-radius: 4px; }
.m:not([data-b="up"]) :is(.m-o, .m-ai) { display: none; }
.m[data-b="up"]:has(.m-o) .m-n { max-width: calc(100% - 218px); }
.m[data-b="up"]:has(.m-ai) .m-n { max-width: calc(100% - 280px); }
/* One tooltip for the page, placed by app.js beside what it explains. */
.tipbox { position: fixed; z-index: 40; 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; pointer-events: none; }
.tip-h { display: flex; align-items: center; gap: 6px; margin: 0 0 8px; color: var(--ai); font-weight: 700; }
.tip-l { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: 4px 16px; margin: 0; }
.tip-l dt { overflow: hidden; color: var(--mist); text-overflow: ellipsis; white-space: nowrap; }
.tip-l dd { margin: 0; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.tip-l .ai { color: var(--ai); }
.tip-l3 { grid-template-columns: minmax(0, 1fr) auto auto; align-items: baseline; column-gap: 10px; }
/* The bookmaker beside its price: same size and baseline, only lighter. */
.tip-l .tip-bk { color: var(--mist); font-weight: 500; text-align: left; }
.tip-h.tip-n { color: var(--chalk); }
/* A form result: the outcome in its colour, the day on the right. */
.tip-r[data-r="W"] { color: var(--pitch); }
.tip-r[data-r="L"] { color: var(--alarm); }
.tip-r small { margin-left: auto; padding-left: 16px; color: var(--mist); font-size: 12px; font-weight: 500; }
/* The predicted score on the heading's line, its ink lined up with the chances below: the "%" sign
   ends a little short of its box, so the score stands 2px in. */
.tip-s { margin: 0 2px 0 auto; padding-left: 16px; color: var(--chalk); font-size: 15px; font-variant-numeric: tabular-nums; }
.tip-t { margin: 0; color: var(--mist); white-space: pre-line; }
/* A text tip's first line is its heading. */
.tip-t::first-line { color: var(--chalk); font-weight: 700; }
.tip-sub { margin-left: auto; padding-left: 16px; color: var(--mist); font-size: 11px; font-weight: 500; }
.tip-f { margin: 8px 0 0; padding-top: 6px; border-top: 1px solid var(--line); color: var(--mist); font-size: 11px; }
.tipbox:has(.tip-t) { min-width: 0; }
@media (max-width: 599px) {
	.m-o { gap: 3px; }
	.m-og > * { width: 34px; font-size: 12px; }
	.m-og > a::after { top: 2px; right: 2px; width: 7px; height: 7px; }
	.m-o small { font-size: 9px; }
	.m[data-b="up"]:has(.m-o) .m-n, .m[data-b="up"]:has(.m-ai) .m-n { max-width: calc(100% - 175px); }
	/* No room beside the pill on a phone. Where the row has a league line (the Time view), the predicted
	   score sits on it, right-aligned over the pill; elsewhere it is left out, the picks lit in the pill
	   saying it. The pill stays centred in the row. */
	.m-ai { top: 0; height: 22px; right: calc(var(--edge) + 22px); width: 145px; justify-content: center; translate: none; font-size: 11px; line-height: 13px; gap: 3px; }
	.m-ai .ai-i { width: 10px; height: 10px; }
	.m[data-b="up"]:not(:has(.m-lg)) .m-ai { display: none; }
	.m[data-b="up"]:has(.m-ai) .m-lg { max-width: calc(100% - 56px); }
}
@media (max-width: 479px) {
	.m-og > :not(.ai), .m-og:not(:has(.ai)) { display: none; }
	.m-ai { width: 71px; }
	.m[data-b="up"]:has(.m-o) .m-n, .m[data-b="up"]:has(.m-ai) .m-n { max-width: calc(100% - 104px); }
	.m[data-b="up"]:not(:has(.m-og .ai)) .m-n { max-width: 100%; }
}
/* A finished row's FT takes the same spot; its kickoff stays in the time column. */
.m[data-b="fin"] .m-ft { position: absolute; top: 50%; right: calc(var(--edge) + 22px + 19px); translate: 0 -50%; font-size: 14px; }
.m[data-b="fin"] .m-t small { font-size: 13px; }
.m[data-b="fin"]:has(.m-ft) .m-n { max-width: calc(100% - 113px); }
/* A shoot-out's score carries its own count, "1 (4)", so the minute or FT steps left by that much. */
.m[data-b="live"]:has(.m-s.pen) .m-t, .m[data-b="fin"]:has(.m-s.pen) .m-ft { right: calc(var(--edge) + 22px + 19px + 44px); }
.m:is([data-b="live"], [data-b="fin"]):has(.m-s.pen) .m-n { max-width: calc(100% - 157px); }
.m[data-b="live"]:is([data-goal], [data-ng]):has(.m-s.pen) .m-n { max-width: calc(100% - 234px); }
@media (max-width: 599px) { .m[data-b="fin"]:has(.m-lg) .m-ft { top: calc(50% + 11px); } }
.m[data-b="live"]:is([data-goal], [data-ng]) .m-n { max-width: calc(100% - 190px); }

/* While betting is paused (the fast lane says so; never at a break) a gold padlock sits where the
   attack dot goes, 10px left of the minute, centred on its digits. The dot, which lasts seconds, and
   "Goal!" take its place while they show. */
.m[data-b="live"][data-lk]:not([data-att], [data-goal], [data-ng]) .m-t::before {
	content: "";
	display: inline-block;
	width: 13px;
	height: 15px;
	margin-right: 10px;
	background: var(--gold);
	vertical-align: -2.5px;
	-webkit-mask: var(--lock) center / contain no-repeat;
	mask: var(--lock) center / contain no-repeat;
}

/* While a mark shows, the minute sits above the row's link, so hovering it explains the mark;
   app.js passes the click on. */
.m[data-b="live"]:is([data-att], [data-lk]) .m-t { z-index: 1; cursor: help; }
/* 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. A goal ruled out
   by VAR is the same moment in white: "No goal", and the corrected number on a white box.

   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 attack dot; keeping the padding stops the score moving when the dot goes. */
[data-scored="h"] [data-side="h"] .m-s, [data-scored="a"] [data-side="a"] .m-s,
[data-ng="h"] [data-side="h"] .m-s, [data-ng="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. It appears at once and fades out with the
   wash and the badge; nothing moves.
   On a live row it is written just before the minute, which keeps its place; zero line height
   keeps the bigger word from shifting the minute. Other rows have no minute there, so it takes
   the minute's spot. */
.m-x { position: relative; }
.m[data-b="live"]:is([data-goal], [data-ng]):not([data-att]) .m-t::before {
	content: "Goal!";
	margin-right: 10px;
	color: #fff;
	font-size: 17px;
	font-weight: 700;
	line-height: 0;
	animation: goal-word 20s linear forwards;
}
.m[data-b="live"][data-ng]:not([data-att]) .m-t::before { content: "No goal"; }
.m:not([data-b="live"]):is([data-goal], [data-ng]) .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 20s linear forwards;
}
.m:not([data-b="live"])[data-ng] .m-x::after { content: "No goal"; }

/* The wash: the row, or the whole match card. It rides on the score box's marker and fades with
   it, so the red goes all at once. */
.m[data-scored], .mh[data-scored] { animation: goal-row 20s ease-in-out forwards; }
@keyframes goal-row {
	0%, 100% { background-color: transparent; }
	4%, 88% { background-color: rgba(255, 61, 82, .2); }
}
.mh[data-scored] { animation-name: goal-card; }
@keyframes goal-card {
	0%, 100% { background-color: var(--stand); }
	4%, 88% { background-color: #372234; }
}

/* The scoring side's number sits on a red badge for twenty seconds, fading with "Goal!" and the
   wash. It has its own marker (data-scored), which the wash shares. */
.m-s { isolation: isolate; }
[data-scored="h"] .m-s[data-s="h"], [data-scored="a"] .m-s[data-s="a"] { animation: goal-text 20s ease-out forwards; }
[data-ng="h"] .m-s[data-s="h"], [data-ng="a"] .m-s[data-s="a"] { animation: no-goal-text 20s ease-out forwards; }
[data-scored="h"] .m-s[data-s="h"]::before, [data-scored="a"] .m-s[data-s="a"]::before,
[data-ng="h"] .m-s[data-s="h"]::before, [data-ng="a"] .m-s[data-s="a"]::before {
	content: "";
	position: absolute;
	/* Set from the digit's ink, not its line: in the 18px line a figure stands 11px tall on the
	   baseline, 4px below the top, and starts after the 12px padding. That leaves 4px around it
	   left and right and 3.5px above and below. */
	inset: .5px -4px -.5px 8px;
	z-index: -1;
	border-radius: 4px;
	background: var(--alarm);
	animation: goal-badge 20s ease-out forwards;
}
/* 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 big number. */
.mh .m-s::before { inset: -6px -10px !important; border-radius: 10px !important; translate: 0 .06em; }
@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); }
}
/* The word keeps full strength while the wash holds, then goes with it. */
@keyframes goal-word {
	0%, 88% { opacity: 1; }
	100% { opacity: 0; }
}
@keyframes goal-text {
	0%, 90% { color: #fff; }
}
[data-ng] .m-s::before { background: var(--chalk) !important; }
@keyframes no-goal-text {
	0%, 90% { color: var(--night); }
}

/* Match card: the attack dot sits on the outer side of that team's number, and "Goal!" shows under
   the clock, which stays. It is placed out of the flow, so the card keeps its height. */
.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 .m-t { position: relative; }
.mh:is([data-goal], [data-ng]) .m-t::after { content: "Goal!"; position: absolute; top: 100%; left: 50%; translate: -50% 0; margin-top: 2px; color: #fff; font-size: 20px; font-weight: 700; white-space: nowrap; animation: goal-word 20s linear forwards; }
.mh[data-ng] .m-t::after { content: "No goal"; }

/* 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 {
	/* The stars sit with their centre (a regular star's, below the middle of its points) at the
	   middle of the box, so a star centred on a row looks centred. */
	--star-line: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2.8l2.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");
	--info: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='6.75' fill='none' stroke='black' stroke-width='1.5'/%3E%3Ccircle cx='8' cy='4.9' r='1'/%3E%3Crect x='7.25' y='6.9' width='1.5' height='4.6' rx='.75'/%3E%3C/svg%3E");
	--spark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 2l2.2 6.8L19 11l-6.8 2.2L10 20l-2.2-6.8L1 11l6.8-2.2zM19 14l1 3 3 1-3 1-1 3-1-3-3-1 3-1z'/%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");
	/* The goal sound, and the same struck through. */
	--bell: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 16.5V11a6 6 0 0 1 12 0v5.5l1.5 1.5h-15zM10 20.5a2 2 0 0 0 4 0' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	--bell-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 16.5V11a6 6 0 0 1 12 0v5.5l1.5 1.5h-15zM10 20.5a2 2 0 0 0 4 0M3.5 3.5l17 17' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	/* Betting paused on a live match. */
	--lock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 11V7.5a4 4 0 0 1 8 0V11' fill='none' stroke='black' stroke-width='2.4'/%3E%3Crect x='5' y='10.5' width='14' height='10.5' rx='2.5'/%3E%3C/svg%3E");
	/* The search box's magnifier and its cross to clear it. */
	--glass: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5' fill='none' stroke='black' stroke-width='2.6'/%3E%3Cpath d='M15.5 15.5L21 21' stroke='black' stroke-width='2.8' stroke-linecap='round'/%3E%3C/svg%3E");
	--cross: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 5l14 14M19 5L5 19' stroke='black' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E");
	/* A link that opens another site: an arrow out of a box. */
	--ext: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M14 4h6v6M20 4l-9 9M18 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5' fill='none' stroke='black' stroke-width='2.5' 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 2.8l2.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(#qbar, #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); box-shadow: var(--lift); overflow: hidden; }
/* A match in a list other than the live board: one line. When, then home and its score against
   score and away, then the competition where the list mixes them. Results drop the "FT". */
.sx-r { position: relative; display: grid; grid-template-columns: 92px minmax(0, 1fr) auto; align-items: center; column-gap: 12px; padding: 6px 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; }
/* A list that names competitions gives them a fixed column, so the middle of every row lines up. */
.sx-list:has(.sx-l) .sx-r { grid-template-columns: 92px minmax(0, 1fr) 150px; }
.sx-d { display: flex; align-items: baseline; gap: 6px; color: var(--mist); font-size: 12px; white-space: nowrap; }
.sx-d b { color: var(--chalk); font-weight: 500; }
.sx-d .m-t { font-size: 12px; }
.sx-r[data-b="fin"] .sx-d .m-t { display: none; }
.sx-t { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 6px; min-width: 0; }
.sx-t > span { display: flex; justify-content: space-between; gap: 6px; font-size: 13px; line-height: 18px; }
.sx-t > span + span { flex-direction: row-reverse; justify-content: flex-end; }
.sx-t > span + span::after { content: "–"; color: var(--mist); }
.sx-t > span + span .m-s { margin-left: 0; padding-left: 0; }
.sx-t .m-s { min-width: 1ch; }
.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 { max-width: 100%; overflow: hidden; color: var(--mist); font-size: 11px; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 599px) {
	.sx-r, .sx-list:has(.sx-l) .sx-r { grid-template-columns: 58px minmax(0, 1fr); column-gap: 10px; }
	.sx-d { flex-direction: column; align-items: flex-start; gap: 0; }
	.sx-l { display: none; }
}
.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; }
.sx-chip .crest { width: 18px; height: 18px; object-fit: contain; }
/* A team's competitions, under its name. */
.pg-plays { margin: -12px 0 24px; }

/* Breadcrumb: where the page sits under the home page; the page itself last, cut short if long. */
.crumbs { margin: 0 0 12px; color: var(--mist); font-size: 12px; }
.crumbs ol { display: flex; align-items: center; gap: 6px; min-width: 0; margin: 0; padding: 0; list-style: none; }
.crumbs li { flex: none; white-space: nowrap; }
.crumbs li + li::before { content: "›"; margin-right: 6px; color: #4a5b75; }
.crumbs li:last-child { flex: 0 1 auto; min-width: 0; overflow: hidden; color: var(--chalk); text-overflow: ellipsis; }
.crumbs a:hover, .crumbs a:focus-visible { color: var(--chalk); text-decoration: underline; text-underline-offset: 3px; }

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

.panel { margin-bottom: 16px; background: var(--stand); border-radius: var(--radius); box-shadow: var(--lift); }
.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; }
/* klaklak's room fills the panel edge to edge (its own padding is 8-12px at this width). Its size lives
   here because the security policy allows no style attributes. */
.chat { overflow: hidden; }
/* 80% of the window tall, at most 500px. Drawn at 90% so more fits: the frame is laid out 1/0.9 as
   big, scaled down, and the space the scaling frees is taken back with the margin. */
.chat { --chat-h: min(80svh, 500px); }
.chat iframe { display: block; width: calc(100% / .9); height: calc(var(--chat-h) / .9); margin-bottom: calc(var(--chat-h) / .9 * -.1); border: 0; transform: scale(.9); transform-origin: 0 0; }
.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) {
	/* Its scrollbar sits in the page margin, clear of the panels, which stay in line with the search box:
	   the gutter is always kept, and app.js measures it into --sb. */
	.side { position: sticky; top: var(--top); max-height: calc(100vh - var(--top)); overflow-y: auto; margin-right: -14px; padding-right: calc(14px - var(--sb, 0px)); scrollbar-gutter: stable; 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); box-shadow: var(--lift); overflow: hidden; }
/* Level with the competition line beside it: the middle of its capitals is 25.5px down the card. */
.mh > .star { position: absolute; top: 3.5px; 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; }

/* The expander is a glance under its row, so everything in it sits tighter than on the match page. */
/* The kickoff line sits midway between the row's edge and the tab labels' ink (13px either side). */
.xp-top { margin-bottom: -2px; padding-top: 10px; font-size: 12px; }
.xp .dt-tabs { gap: 18px; height: 36px; }
.xp .dt-tabs button { font-size: 13px; }
.xp .dt-p { padding: 4px var(--edge) 10px; }
.xp .dt-none { padding: 8px 0 10px; font-size: 13px; }
.xp .ev { min-height: 30px; font-size: 13px; }
.xp .ev-t small { font-size: 11px; line-height: 13px; }
.xp .ev-div { margin: 4px 0; padding: 3px; font-size: 11px; }
.xp .st { gap: 8px; padding-top: 8px; }
.xp .st-row { row-gap: 3px; font-size: 13px; }
.xp .st-row > span:not(.st-bar) { font-size: 12px; }
.xp .fm-h { margin: 8px 0 4px; font-size: 13px; }
.xp .h2h-sum { margin: 4px 0 8px; }
.xp .h2h-sum b { font-size: 18px; }
.xp .tbl { font-size: 13px; }
.xp .tbl caption { padding: 6px var(--edge) 4px; }
.xp .tbl th { padding: 4px 6px; }
.xp .tbl td { padding: 3px 6px; }
.xp .lu-list { gap: 2px; }
.xp .lu-list li { font-size: 13px; }
.xp .lu-h { margin: 6px 0 6px; font-size: 14px; }
.xp .lu-sub { margin: 10px 0 4px; }
/* The pitch lies flatter under a row, and its players are a size smaller; the match page keeps the full one. */
@media (min-width: 600px) {
	.xp .pt-f { aspect-ratio: 21 / 10; }
	.xp .pt-s { width: 26px; height: 26px; font-size: 12px; }
	.xp .pt-p { gap: 2px; }
	.xp .pt-n { font-size: 11px; }
}

/* ---- 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; }

/* ---- About and privacy: running text on one panel. Small caps tire the eye over paragraphs, so
   the text is in the system face and only the headings keep Barlow. ---- */

.doc > :not(.crumbs) { max-width: 68ch; }
.doc { padding: 20px var(--edge) 24px; background: var(--stand); border-radius: var(--radius); box-shadow: var(--lift); }
.doc h1 { margin-bottom: 16px; font-size: 26px; line-height: 1.15; }
.doc h2 { margin: 28px 0 8px; font-size: 17px; }
.doc p, .doc ul, .doc table { margin: 0 0 12px; font: 400 15px/1.6 system-ui, -apple-system, "Segoe UI", sans-serif; color: #d3dbe4; }
.doc ul { padding-left: 20px; }
.doc li + li { margin-top: 4px; }
.doc a { color: var(--chalk); text-decoration: underline; text-decoration-color: var(--mist); text-underline-offset: 3px; }
.doc a:hover { text-decoration-color: var(--chalk); }
.doc code { font-size: 14px; }
.doc-t { width: 100%; border-collapse: collapse; }
.doc-t th, .doc-t td { padding: 6px 12px 6px 0; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.doc-t th { color: var(--mist); font-weight: 600; }
.doc-t td:first-child { white-space: nowrap; font-family: ui-monospace, Consolas, monospace; font-size: 13px; }
.doc .doc-date { margin: 24px 0 0; color: var(--mist); font-size: 13px; }

/* ---- Footer: the way to About and Privacy on every page ---- */

.foot { padding-top: 8px; padding-bottom: 32px; color: var(--mist); font-size: 13px; }
.foot nav { display: flex; flex-wrap: wrap; gap: 4px 20px; margin-bottom: 8px; }
.foot a { color: var(--chalk); }
.foot a:hover, .foot a:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
.foot p { line-height: 1.5; }
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-h > a { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fm-r { display: flex; flex: none; align-items: center; gap: 12px; }
/* Goals per match beside the form: words on wide screens, just the two figures on phones. */
.fm-avg { color: var(--mist); font-size: 12px; font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums; cursor: help; }
.fm-avg b { color: var(--chalk); font-size: 13px; }
.fm-avg i::before { content: "\00a0\00b7\00a0"; font-style: normal; }
@media (max-width: 599px) { .fm-avg span { display: none; } .fm-avg i::before { content: "\00a0/\00a0"; } }
.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-best { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 12px; }
@media (max-width: 599px) { .od-best { grid-template-columns: minmax(0, 1fr); gap: 4px; } }
.od-g { min-width: 0; }
.od-h { display: flex; align-items: baseline; gap: 6px; margin: 10px 0 6px; color: var(--mist); font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.od-h small { color: var(--chalk); font-size: 11px; }
.od-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.od-two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.od-c { display: grid; gap: 1px; min-width: 0; padding: 7px 10px 6px; border-radius: 9px; background: var(--chip); box-shadow: var(--chip-edge); }
.od-c small { overflow: hidden; color: var(--mist); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
.od-k b { margin-right: 2px; color: var(--chalk); }
.od-c .od-p { color: #fff; font-size: 18px; line-height: 22px; font-variant-numeric: tabular-nums; }
.od-c[href]:hover { background: var(--chip-hover); }
.od-c.ai { background: var(--chip-pick); box-shadow: var(--chip-pick-edge); }
.od-c[href]::after, .od-t th a::after, .od-t td a::after { content: ""; display: inline-block; width: 9px; height: 9px; margin-left: 5px; background: currentColor; -webkit-mask: var(--ext) center / contain no-repeat; mask: var(--ext) center / contain no-repeat; }
/* The card's arrow floats in its top right corner, as on a price elsewhere. */
.od-c[href] { position: relative; }
.od-c[href]::after { position: absolute; top: 7px; right: 8px; width: 11px; height: 11px; margin: 0; background: #c3cddb; }
.od-c[href]:hover::after { background: #fff; }
.od-c[href] .od-k { padding-right: 14px; }
.od-c.ai[href]::after { background: var(--pick); }
.od-t td a::after { position: absolute; top: 4px; right: 3px; width: 8px; height: 8px; margin: 0; background: #c3cddb; }
.od-t td a:hover::after, .od-t td a:focus-visible::after { background: #fff; }
.od-t td:has(a) { position: relative; }
.od-c.ai .od-k, .od-c.ai .od-k b { color: var(--pick); }
/* The prediction: its score large, then each chance as a chip with a bar, the picks lit. */
.od-ai { margin-top: 12px; padding: 10px 12px 12px; border: 1px solid rgba(108, 196, 255, .22); border-radius: 10px; background: linear-gradient(180deg, rgba(108, 196, 255, .09), rgba(108, 196, 255, .02)); }
.od-ai-h { display: flex; align-items: center; gap: 6px; margin: 0 0 8px; color: var(--ai); font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.od-ai-s { margin-left: auto; color: #fff; font-size: 22px; line-height: 1; letter-spacing: 0; font-variant-numeric: tabular-nums; }
.od-ai-c { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
@media (max-width: 599px) { .od-ai-c { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.od-ch { display: grid; gap: 3px; min-width: 0; padding: 6px 8px 7px; border-radius: 8px; background: rgba(14, 21, 27, .55); }
.od-ch small { overflow: hidden; color: var(--mist); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
.od-ch small b { margin-right: 2px; color: var(--chalk); }
.od-ch-p { color: var(--chalk); font-size: 16px; line-height: 20px; font-variant-numeric: tabular-nums; }
.od-ch .ai-bar { height: 3px; --bar: var(--mist); background: linear-gradient(to right, var(--bar) var(--h, 0%), var(--line) var(--h, 0%)); }
.od-ch.ai { box-shadow: inset 0 0 0 1px rgba(108, 196, 255, .45); }
.od-ch.ai small, .od-ch.ai small b, .od-ch.ai .od-ch-p { color: var(--ai); }
.od-ch.ai .ai-bar { --bar: var(--ai); }

/* Every bookmaker, by name, so a visitor finds their own; the best price in each column is a chip. */
.od-tw { overflow-x: auto; border: 1px solid var(--line); border-radius: 10px; }
.od-t { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
.od-t th, .od-t td { height: 28px; padding: 0 6px; text-align: center; white-space: nowrap; }
.od-t thead th { height: 26px; background: rgba(255, 255, 255, .03); color: var(--mist); font-size: 11px; font-weight: 700; }
.od-t thead th.ai { color: var(--pick); }
.od-t tbody tr + tr > * { border-top: 1px solid var(--line); }
.od-t tbody tr:hover { background: rgba(255, 255, 255, .03); }
.od-t th:first-child { width: 99%; padding-left: 12px; font-weight: 500; text-align: left; }
.od-t tbody th { color: var(--chalk); }
.od-t td { width: 56px; color: #b9c4d4; }
.od-t td:last-child, .od-t thead th:last-child { padding-right: 10px; }
.od-t :is(th, td):nth-child(5) { border-left: 1px solid var(--line); }
.od-t a { display: block; }
.od-t a:hover { color: var(--chalk); text-decoration: underline; text-underline-offset: 3px; }
.od-t td.best { position: relative; z-index: 0; color: #fff; font-weight: 700; }
.od-t td.best::before { content: ""; position: absolute; inset: 3px 2px; z-index: -1; border-radius: 6px; background: var(--chip); box-shadow: var(--chip-edge); }
.od-note { margin-top: 10px; color: var(--mist); font-size: 11px; 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; }
/* An SVG mask, like the star: an upright "i" that looks the same in every font and system. */
.m-i::before { content: ""; display: block; width: 14px; height: 14px; margin: auto; background: currentColor; -webkit-mask: var(--info) center / contain no-repeat; mask: var(--info) center / contain no-repeat; }
.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; }
/* The minute right-aligned in a column just wide enough for "90+4'", so every scorer starts the
   same short way after it, and centred on the scorer and team lines together. */
.gp-g { display: grid; grid-template-columns: 34px minmax(0, 1fr); column-gap: 8px; padding: 4px 0; line-height: 16px; }
.gp-g b { grid-row: span 2; align-self: center; color: var(--pitch); text-align: right; font-variant-numeric: tabular-nums; }
.gp-g span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gp-g small { grid-column: 2; color: var(--mist); font-size: 11px; line-height: 13px; }
.gp-since, .gp-none { color: var(--mist); font-size: 12px; }
.gp-since { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--line); }
.gp-g + .gp-none { margin-top: 6px; }
/* A goal VAR took back: struck through and quiet, the decision under it. */
.gp-no b, .gp-no span { color: var(--mist); text-decoration: line-through; }

/* ---- 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); box-shadow: var(--lift); 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; }
/* A goal VAR took back keeps its place, struck through and greyed, with the decision under it. */
.ev-no .ev-t b { color: var(--mist); text-decoration: line-through; }
.ev-no[data-k="goal"] .ev-i, .ev-no[data-k="og"] .ev-i { background: var(--mist); }
.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; }
.lu-on { margin-left: 8px; color: var(--pitch); font-size: 12px; }
.pt + .lu { margin-top: 16px; }

/* Line-ups on a pitch, as on Flashscore: lying down with the home side on the left, standing up on
   phones with the home side on top. Each half lists its keeper's line first and places from the
   team's left; the flex directions turn both to face the other half. */
.pt { --pt-line: rgba(237, 241, 247, .16); display: grid; grid-template-areas: "h a" "f f"; gap: 8px 16px; margin-top: 8px; }
.pt-lb { display: flex; gap: 8px; align-items: baseline; min-width: 0; margin: 0; font-size: 14px; font-weight: 700; }
.pt-lb span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pt-lb b { flex: none; color: var(--mist); font-size: 13px; font-weight: 500; }
.pt-lh { grid-area: h; }
.pt-la { grid-area: a; justify-content: flex-end; }
.pt-f { grid-area: f; position: relative; display: flex; aspect-ratio: 3 / 2; overflow: hidden; border: 1px solid var(--pt-line); border-radius: 8px;
	background: repeating-linear-gradient(90deg, #11291f 0 10%, #133022 10% 20%); }
.pt-f::before { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; border-left: 1px solid var(--pt-line); }
.pt-f::after { content: ""; position: absolute; top: 50%; left: 50%; width: 18%; aspect-ratio: 1; translate: -50% -50%; border: 1px solid var(--pt-line); border-radius: 50%; }
.pt-t { --kit: #edf1f7; --kit-n: #0e151b; position: relative; display: flex; flex: 1; min-width: 0; }
.pt-a { --kit: #2f6fdf; --kit-n: #ffffff; flex-direction: row-reverse; }
/* The penalty area and the six-yard box at each goal. */
.pt-t::before, .pt-t::after { content: ""; position: absolute; top: 22%; bottom: 22%; width: 30%; border: 1px solid var(--pt-line); }
.pt-t::after { top: 38%; bottom: 38%; width: 10%; }
.pt-h::before, .pt-h::after { left: -1px; }
.pt-a::before, .pt-a::after { right: -1px; }
.pt-l { position: relative; z-index: 1; display: flex; flex: 1; flex-direction: column; justify-content: space-around; align-items: center; min-width: 0; }
.pt-a .pt-l { flex-direction: column-reverse; }
.pt-p { display: grid; justify-items: center; gap: 3px; width: 100%; max-width: 92px; min-width: 0; }
.pt-s { position: relative; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: var(--kit); color: var(--kit-n);
	box-shadow: 0 0 0 2px rgba(14, 21, 27, .55); font-size: 13px; font-weight: 700; }
.gk .pt-s { background: var(--gk, var(--kit)); color: var(--gk-n, var(--kit-n)); }
.pt-n { max-width: 100%; overflow: hidden; color: var(--chalk); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; text-shadow: 0 1px 2px rgba(0, 0, 0, .8); }
/* Marks around the shirt: goals top left, a card top right, going off bottom right. */
.pt-s i { position: absolute; }
.pt-g { top: -4px; left: -8px; width: 14px; height: 14px; border-radius: 50%; background: #fff; -webkit-mask: var(--ball) center / contain no-repeat; mask: var(--ball) center / contain no-repeat; }
.pt-g.og { top: auto; bottom: -4px; background: var(--alarm); }
.pt-g[data-n]::after { content: attr(data-n); position: absolute; left: -7px; top: 0; color: var(--chalk); font-size: 10px; font-style: normal; }
.pt-c { top: -4px; right: -5px; width: 9px; height: 12px; border-radius: 2px; background: var(--gold); }
.pt-c.rc { background: var(--alarm); }
.pt-o { right: -8px; bottom: -4px; width: 14px; height: 14px; background: var(--alarm); -webkit-mask: var(--swap) center / contain no-repeat; mask: var(--swap) center / contain no-repeat; }

/* 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) {
	.pt { grid-template-areas: "h" "f" "a"; }
	.pt-la { flex-direction: row-reverse; justify-content: flex-end; }
	.pt-f { flex-direction: column; aspect-ratio: 5 / 8; background: repeating-linear-gradient(180deg, #11291f 0 10%, #133022 10% 20%); }
	.pt-f::before { top: 50%; bottom: auto; left: 0; right: 0; border-left: 0; border-top: 1px solid var(--pt-line); }
	.pt-f::after { width: 28%; }
	.pt-t { flex-direction: column; min-height: 0; }
	.pt-a { flex-direction: column-reverse; }
	.pt-t::before, .pt-t::after { top: auto; bottom: auto; left: 22%; right: 22%; width: auto; height: 30%; }
	.pt-t::after { left: 38%; right: 38%; height: 10%; }
	.pt-h::before, .pt-h::after { top: -1px; }
	.pt-a::before, .pt-a::after { bottom: -1px; }
	.pt-l { flex-direction: row-reverse; }
	.pt-a .pt-l { flex-direction: row; }
	.pt-p { max-width: 72px; }
	.pt-n { font-size: 11px; }
	.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: 8px; padding-bottom: 8px; }
	.side { padding-top: 0; }
	.panel { margin-bottom: 8px; }
}

@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) {
	[data-scored] .m-s::before, [data-ng] .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; }
}
