/* Mobile first. A dark hero band carries the answer and the clock; the body below is light or dark with the device.
   Colour has three jobs, kept apart. The brand's colour is the same on every page: the top bar, the mark, and the
   ring around whatever the keyboard is on. A sport's two colours, set on <body> as --h (its main hue) and --a (the
   accent hue of its clock), stay inside the hero and on small marks below it. Every other surface is neutral. */

/* --- The typeface: Archivo, served from this site. One file holds every weight from 100 to 900 and every width
   from 62% to 125%. The second file is only fetched by a page that uses letters from beyond western Europe. */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  src: url(/assets/fonts/archivo-latin-ext-wdth-normal.woff2) format("woff2");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,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: "Archivo";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  src: url(/assets/fonts/archivo-latin-wdth-normal.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;
}

:root { color-scheme: light dark; --ease: cubic-bezier(0.2, 0.7, 0.2, 1); }
body {
  /* The brand: a floodlight yellow-green, a hue no sport on the site uses. --bar is the top bar, --brand the
     bright mark on it, and --focus the ring round whatever the keyboard is on (dark on light, bright on dark);
     --focus-page is the ring for the body, kept so a sheet opened from the dark header can ask for it back. */
  --brand-hue: 118;
  --bar: oklch(14.5% 0.025 var(--brand-hue));
  --brand: oklch(90% 0.2 var(--brand-hue));
  --focus-page: oklch(46% 0.13 var(--brand-hue));
  --focus: var(--focus-page);
  /* Neutral surfaces and ink: the same under every sport. */
  --bg: oklch(97.5% 0.003 260);
  --surface: oklch(100% 0 0);
  --ink: oklch(21% 0.012 260);
  --muted: oklch(46% 0.012 260);
  --line: oklch(89% 0.006 260);
  --hover: oklch(94% 0.006 260);
  /* The sport's colours. --accent is for small marks on the neutral body; the rest belong to the hero. */
  --accent: oklch(52% 0.17 var(--h));
  --hero-1: oklch(15% 0.02 var(--h));
  --hero-2: oklch(23% 0.04 var(--h));
  --hero-ink: oklch(98% 0.005 var(--h));
  --glow: oklch(84% 0.17 var(--h));
  --hot: oklch(68% 0.24 var(--a));
  /* Type: six steps and nothing smaller than the first. Use these, not one-off sizes. */
  --t-small: 0.8125rem;
  --t-meta: 0.9375rem;
  --t-body: 1.0625rem;
  --t-lead: 1.3125rem;
  --t-title: 1.75rem;
  --t-display: clamp(2.5rem, 6vw, 3.75rem);
  /* One typeface in two voices. Display (headings, times, numerals) is condensed and heavy: say "condensed" in a
     font shorthand, or font-stretch: 75%, with a weight of 700 or 800. Reading text is normal width at 400, with
     600 for emphasis. */
  --font-display: "Archivo", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-text: "Archivo", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* Space between one thing and the next down the page: five steps. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 1rem;
  --space-4: 1.5rem;
  --space-5: 2.5rem;
  /* Corners: small for controls and rows, large for panels, and the pill. No others. */
  --r-small: 6px;
  --r-large: 12px;
  --r-pill: 999px;
  /* Anything tappable is at least this tall and wide on a touch screen. */
  --tap: 2.75rem;
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 var(--t-body)/1.5 var(--font-text);
}
@media (prefers-color-scheme: dark) {
  body {
    --focus-page: var(--brand);
    --bg: oklch(14% 0.006 260);
    --surface: oklch(19% 0.008 260);
    --ink: oklch(94% 0.005 260);
    --muted: oklch(72% 0.01 260);
    --line: oklch(29% 0.008 260);
    --hover: oklch(22% 0.01 260);
    --accent: oklch(78% 0.15 var(--h));
  }
}
/* The header and the hero are dark whatever the device's scheme, so the ring there is always the bright one. */
header, .hero { --focus: var(--brand); }

* { box-sizing: border-box; }
/* Without this, any rule that sets display would show an element the page has marked hidden. */
[hidden] { display: none !important; }
.wrap { max-width: 60rem; margin: 0 auto; padding: 0 1rem; }
/* A link in running text is the colour of the text; its underline is the sport's. */
a { color: inherit; text-decoration-color: var(--accent); text-decoration-thickness: 0.09em; text-underline-offset: 0.2em; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* --- The hero band */

.hero {
  position: relative;
  overflow: hidden;
  color: var(--hero-ink);
  padding: var(--space-3) 0 var(--space-4);
  background:
    radial-gradient(90% 70% at 95% 0%, oklch(62% 0.19 var(--h) / 0.38), transparent 60%),
    radial-gradient(70% 60% at 0% 100%, oklch(60% 0.24 var(--a) / 0.26), transparent 65%),
    linear-gradient(180deg, var(--hero-1), var(--hero-2));
}
.hero .wrap { position: relative; z-index: 1; }
.hero a { text-decoration-color: currentColor; }
.sport-icon { flex: none; width: 2rem; height: 2rem; }

/* --- Each sport's own background: its whole arena, to scale, in three dimensions (engine/backdrops.js).
   A camera is worked out the way a real one is. --p is the lens: the distance from the eye to the page, set to
   86% of the page's width, which gives a view about 60 degrees wide on any screen. --u is how many pixels a
   metre is drawn at before the lens enlarges or shrinks it; it only sets how much detail the drawings hold.
   The camera is a crane in three nested parts, each with one job, so each can move in one unbroken motion:
   .spin turns the arena to the direction faced and brings the point looked at to the centre; .tilt tips it
   to the angle looked down at; .scene sets it back by the camera's distance and applies the lens. */
.backdrop { --p: 86vw; --cx: 50%; --cy: 64%; --u: calc(170cqw / var(--w)); position: absolute; inset: 0; overflow: hidden; pointer-events: none; container-type: size; perspective: var(--p); perspective-origin: var(--cx) var(--cy); }
.scene, .tilt, .spin { position: absolute; left: 0; top: 0; transform-style: preserve-3d; transform-origin: 0 0; }
.scene { left: var(--cx); top: var(--cy); transform: translateZ(calc(var(--p) - var(--range1) * var(--u))); }
.tilt { transform: rotateX(var(--tilt1)); }
.spin { width: calc(var(--w) * var(--u)); height: calc(var(--d) * var(--u)); transform: rotateZ(var(--turn1)) translate3d(calc(var(--lx1) * var(--u) * -1), calc(var(--ly1) * var(--u) * -1), calc(var(--lz1) * var(--u) * -1)); }
/* The drawings are made once and kept, not redrawn as the camera moves. */
.spin svg { position: absolute; overflow: visible; will-change: transform; }
.spin .ground { inset: 0; width: 100%; height: 100%; }
.spin .up, .spin .flat { left: calc(var(--x) * var(--u)); top: calc(var(--y) * var(--u)); width: calc(var(--uw) * var(--u)); height: calc(var(--uh) * var(--u)); }
.spin .up { transform-origin: 50% 100%; transform: translate(-50%, -100%) rotateZ(var(--face)) rotateX(-90deg); }
.spin .flat { transform: translate(-50%, -50%) translateZ(calc(var(--lift) * var(--u))); }
/* On a phone the arena has a band of its own under the scoreboard; with room it stands beside it, where the
   country outline stands on an event's page. Nothing is ever drawn behind the scoreboard's numbers. */
.hero:has(> .backdrop) { padding-bottom: calc(var(--space-4) + 50vw); }
.backdrop { --cy: calc(100% - 33vw); }
@media (min-width: 44rem) {
  .hero:has(> .backdrop) { padding-bottom: var(--space-4); min-height: 24rem; }
  .backdrop { --cx: 73%; --cy: 50%; }
}
/* Surfaces take the sport's colour; lines and posts are white; shadows fall away from the light. Every width
   here is in metres, like the drawings: lines and posts are drawn a little heavier than life (30 cm) so they
   still show from high above, and the track is its real 12 metres wide. */
.backdrop .surround { fill: oklch(32% 0.06 var(--h) / 0.6); }
.backdrop .surface { fill: oklch(50% 0.13 var(--h) / 0.55); }
.backdrop .stripe { fill: oklch(100% 0 0 / 0.06); }
.backdrop .wicket { fill: oklch(86% 0.06 90 / 0.55); }
.backdrop .tarmac { fill: oklch(22% 0.01 var(--h) / 0.85); }
.backdrop .line { fill: none; stroke: oklch(100% 0 0 / 0.62); stroke-width: 0.3; }
.backdrop .faint { stroke: oklch(100% 0 0 / 0.25); }
.backdrop .dash { stroke: oklch(100% 0 0 / 0.4); stroke-dasharray: 2; }
.backdrop :is(.spot, .check) { fill: oklch(100% 0 0 / 0.85); }
.backdrop .shade { fill: oklch(0% 0 0 / 0.3); }
.backdrop .shade-line { fill: none; stroke: oklch(0% 0 0 / 0.4); stroke-width: 0.5; stroke-linecap: round; }
.backdrop .post { fill: none; stroke: oklch(100% 0 0 / 0.95); stroke-width: 0.3; stroke-linecap: round; stroke-linejoin: round; }
.backdrop .stump { fill: none; stroke: oklch(100% 0 0 / 0.95); stroke-width: 0.045; }
.backdrop .strand { fill: none; stroke: oklch(100% 0 0 / 0.5); stroke-width: 0.12; }
.backdrop .net { fill: oklch(100% 0 0 / 0.16); stroke: oklch(100% 0 0 / 0.45); stroke-width: 0.08; }
.backdrop .panel { fill: oklch(72% 0.06 var(--h) / 0.4); }
.backdrop .lamp { fill: oklch(100% 0 0 / 0.6); }
.backdrop .pad { fill: oklch(70% 0.2 var(--a) / 0.95); }
.backdrop .cloth { fill: oklch(8% 0 0 / 0.7); stroke: oklch(100% 0 0 / 0.8); stroke-width: 0.1; }
.backdrop .kerb { fill: none; stroke: oklch(100% 0 0 / 0.5); stroke-width: 13.6; }
.backdrop .track { fill: none; stroke: oklch(22% 0.01 var(--h) / 0.95); stroke-width: 12; }
.backdrop .pitlane { fill: none; stroke: oklch(22% 0.01 var(--h) / 0.85); stroke-width: 6; }

/* --- Teams: a flag where the checked list has one, and a chip with the team's code and colour */
.matchup { display: flex; align-items: center; gap: 0.7rem; margin: 0 0 var(--space-3); }
.side { display: inline-flex; align-items: center; gap: 0.5rem; text-decoration: none; }
.vs { font-weight: 600; opacity: 0.8; }
.flag { display: block; box-shadow: 0 0 0 1px oklch(100% 0 0 / 0.25), 0 3px 8px oklch(0% 0 0 / 0.35); }
.matchup .flag { width: 2.4rem; height: 1.8rem; }
.chip { display: inline-block; padding: 0.15rem 0.5rem; border-radius: var(--r-small); background: var(--c); color: var(--t); font: 800 condensed var(--t-small)/1.4 var(--font-display); box-shadow: 0 0 0 1px oklch(100% 0 0 / 0.25); }

/* --- Countdown clocks. Their numerals are sized in cqw, hundredths of the clock's own width. */
.clock { display: grid; grid-template-columns: repeat(4, max-content); justify-content: start; align-items: start; gap: 0.5rem min(2.6cqw, 1rem); font-variant-numeric: tabular-nums; }
.unit { display: grid; justify-items: center; gap: 0.35rem; }

/* Digital: lit segments on a dark panel */
.clock-digital .value { display: flex; gap: min(1cqw, 0.3rem); padding: min(2cqw, 0.7rem); border-radius: var(--r-small); background: #040705; box-shadow: inset 0 0 0 1px oklch(100% 0 0 / 0.1); }
.seg { display: block; height: min(10cqw, 4rem); }
.seg .on { fill: var(--hot); filter: drop-shadow(0 0 2px var(--hot)); }
.seg .off { fill: oklch(100% 0 0 / 0.07); }
.seg polygon { transition: fill 0.3s, filter 0.3s; }

/* Mission: a launch-control clock, T minus days:hours:minutes:seconds */
.clock-mission { grid-template-columns: repeat(5, max-content); gap: 0.4rem 0; width: fit-content; max-width: 100%; padding: min(4cqw, 1.3rem) min(4cqw, 1.5rem) min(3cqw, 1rem); border-radius: var(--r-small); background: #000; border: 2px solid #2c2c2c; color: var(--hot); text-shadow: 0 0 14px oklch(68% 0.24 var(--a) / 0.6); }
.clock-mission .clock-lead, .clock-mission .value { font-family: var(--font-display); font-stretch: 75%; font-size: min(11cqw, 5rem); font-weight: 700; line-height: 1; }
.clock-mission .clock-lead { grid-column: auto; margin-right: 0.3em; opacity: 1; }
.clock-mission .unit + .unit .value::before { content: ":"; margin: 0 0.12em; animation: blink 1s ease-in-out infinite alternate; }
@keyframes blink { from { opacity: 0.85; } to { opacity: 0.25; } }
.clock-mission .label { color: #b9b9b9; text-shadow: none; }

/* Flip: split-flap cards */
.clock-flip .value { display: flex; gap: min(1cqw, 0.3rem); perspective: 300px; }
.card { display: grid; place-items: center; width: 0.85em; height: 1.3em; border-radius: var(--r-small); font-family: var(--font-display); font-stretch: 75%; font-size: min(10cqw, 5rem); font-weight: 800; line-height: 1; color: #fff; background: linear-gradient(#34383a 0 49%, #000 49% 51%, #1d2022 51%); box-shadow: 0 3px 0 var(--hot), 0 6px 12px #0006; }
.card.flip { animation: flip 0.45s ease-out; }
.clock-flip .label { margin-top: 0.2rem; }
@keyframes flip { from { transform: rotateX(-85deg); opacity: 0.3; } to { transform: none; opacity: 1; } }

/* Rings: each unit as a dial that empties */
.clock-ring .value { position: relative; width: min(21cqw, 7rem); aspect-ratio: 1; }
.clock-ring svg { position: absolute; inset: 0; transform: rotate(-90deg); }
.track, .arc { fill: none; stroke-width: 3; }
.track { stroke: oklch(100% 0 0 / 0.15); }
.arc { stroke: var(--hot); stroke-linecap: round; transition: stroke-dashoffset 0.9s cubic-bezier(0.3, 0, 0.2, 1); }
.num { position: absolute; inset: 0; display: grid; place-items: center; font-family: var(--font-display); font-stretch: 75%; font-size: min(8.5cqw, 3rem); font-weight: 800; line-height: 1; }

/* --- Body */
.body { padding-top: var(--space-4); padding-bottom: var(--space-3); }
.body > :first-child > h2:first-child { margin-top: var(--space-2); }

/* --- Motion. Pages cross-fade into each other, and the hero arrives once, in three beats: the heading, the
   scoreboard, then the picture (the sport's drawing settling behind them, or the country's outline beside them
   with its marker dropping onto the venue). Nothing below the hero moves as the page opens. Everything is
   switched off for visitors who ask for reduced motion (at the end of this file).
   One rule keeps it calm: a thing that arrives with an animation answers the pointer with a transition, never
   with a second animation. When the pointer left, the first animation would start again and the thing would
   arrive afresh. */
@view-transition { navigation: auto; }
html { scroll-behavior: smooth; }
@keyframes rise { from { opacity: 0; transform: translateY(12px); } }
@keyframes pop { from { opacity: 0; transform: scale(0.96); } }
@keyframes settle { from { opacity: 0; } }
/* The opening move: a camera starts high above the whole arena at an angle and comes part of the way down
   towards the middle. Each part of the crane makes one unbroken motion from its first value to the scene's
   own resting one: the turn is slow and finishes first, after which the camera keeps facing the target while
   it finishes coming down and closing in. Nothing is joined from pieces, so nothing can jerk at a join. */
@keyframes spin { from { transform: rotateZ(var(--turn0)) translate3d(calc(var(--lx0) * var(--u) * -1), calc(var(--ly0) * var(--u) * -1), calc(var(--lz0) * var(--u) * -1)); } }
@keyframes tilt { from { transform: rotateX(var(--tilt0)); } }
@keyframes dolly { from { transform: translateZ(calc(var(--p) - var(--range0) * var(--u))); } }
.backdrop { animation: settle 1.6s var(--ease) 0.25s backwards; }
.scene { animation: dolly 3.9s cubic-bezier(0.4, 0, 0.1, 1) 0.3s backwards; }
.tilt { animation: tilt 3.9s cubic-bezier(0.45, 0, 0.25, 1) 0.3s backwards; }
.spin { animation: spin 2.7s cubic-bezier(0.4, 0, 0.3, 1) 0.3s backwards; }
.backdrop.seen :is(.scene, .tilt, .spin) { animation: none; }
.map img { animation: arrive 0.9s var(--ease) 0.3s backwards; }
.pin { animation: drop 0.5s var(--ease) 1.1s backwards; }

/* === Stream A: inside the hero (the time answer, clock, actions, map, forecast) === */

/* --- The line above the heading: the sport's icon, then the competition and the stage as separate pieces
   (the competition a link, the stage in plain lettering), then the event's state. */
.eyebrow { display: flex; align-items: center; gap: 0.6rem; margin: 0 0 var(--space-2); font-size: var(--t-small); font-weight: 600; line-height: 1.3; color: var(--glow); }
@media (min-width: 44rem) { .eyebrow { font-size: var(--t-meta); } }
.eyebrow .sport-icon { width: 1.5rem; height: 1.5rem; }
/* The words wrap among themselves when they must; the icon and the state keep their places at either end. */
.eb { min-width: 0; }
.eb[data-event] { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.7rem; }
.eb .stage { font-weight: 400; color: var(--hero-ink); }

/* --- The heading is the scoreboard's caption. On a phone it is kept small, so the time and the clock stay in view. */
h1 { margin: 0 0 var(--space-3); font: 800 condensed var(--t-title)/1.05 var(--font-display); text-wrap: balance; }
@media (min-width: 44rem) { h1 { font-size: var(--t-display); } }
/* A two-team heading is written in pieces, so a crest is never parted from its name at the end of a line. */
h1 span { display: inline-block; max-width: 100%; }
/* A team's name in a heading leads to that team's page: a line draws itself under the name the pointer is on. */
h1 a { text-decoration: none; background: linear-gradient(var(--glow), var(--glow)) 0 100% / 0 0.08em no-repeat; transition: background-size 0.3s var(--ease); }
/* A team's crest stands before its name, as tall as the letters and square. */
h1 .logo, h1 .flag { display: inline-block; margin-right: 0.25em; }
h1 .logo { width: 0.9em; height: 0.9em; padding: 0.07em; vertical-align: -0.1em; }
h1 .flag { width: auto; height: 0.74em; vertical-align: -0.03em; }
.next-name { margin: 0 0 var(--space-3); font: 700 condensed var(--t-lead)/1.2 var(--font-display); }

/* --- The hero's layout. On a phone it is one column: the caption, the scoreboard, then the host country's
   outline. With room to spare the outline stands beside the scoreboard in a column of its own. Either way
   nothing ever sits on top of the outline or its marker. */
.hero .wrap { display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; }
.hero .wrap > * { min-width: 0; }
.place { display: grid; justify-items: center; margin-top: var(--space-4); }
@media (min-width: 44rem) {
  .hero .wrap { grid-template-columns: minmax(20rem, 28rem) minmax(0, 1fr); column-gap: 2.5rem; }
  .hero .wrap > * { grid-column: 1 / -1; }
  .hero .wrap:has(> .place) > .details, .hero:has(> .backdrop) .wrap > .details { grid-column: 1; }
  .hero .wrap > .place { grid-column: 2; justify-items: start; margin-top: 0; }
}

/* --- The host country's outline, with a pulsing dot at the venue. On a phone it is held to a modest height;
   with room, it is as wide as its column allows, but a tall country (New Zealand) is still held in. */
.map { position: relative; width: min(100%, 22rem, calc(13rem * var(--r))); opacity: 0.9; }
@media (min-width: 44rem) { .map { width: min(100%, 33rem, calc(28rem * var(--r))); } }
.map img { display: block; width: 100%; height: 100%; transform-origin: 50% 50%; }
.pin { position: absolute; width: 0.7rem; height: 0.7rem; margin: -0.35rem 0 0 -0.35rem; border-radius: 50%; background: var(--hot); box-shadow: 0 0 0 2px oklch(100% 0 0 / 0.9); }
.pin::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--hot); animation: ping 2.2s ease-out 1.6s infinite; }
.pin b { position: absolute; left: 0.9rem; top: -0.3rem; font-size: var(--t-small); font-weight: 600; line-height: 1.2; white-space: nowrap; }
/* A venue near the right-hand edge has its name on the left of the dot, so it is not cut off. */
.pin.left b { left: auto; right: 0.9rem; }

/* --- The scoreboard: one panel in two parts. On top the answer (the date, the time, the venue); under it
   the clock. Without scripts there is no clock, and the answer is the whole panel. */
.answer, .countdown { max-width: 30rem; padding: 0.75rem 1rem; border: 1px solid oklch(100% 0 0 / 0.2); border-radius: var(--r-large); background: oklch(0% 0 0 / 0.4); }
/* The time is sized in cqw, hundredths of the panel's own width, so it is as large as the panel can hold. */
.answer { container-type: inline-size; }
.answer:has(+ .countdown:not([hidden])) { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.countdown { container-type: inline-size; border-top: 0; border-top-left-radius: 0; border-top-right-radius: 0; background: oklch(0% 0 0 / 0.62); }
/* With nothing beside it (no outline, no arena) and room to spare, the scoreboard lies on its side, as wide as
   the page's column: the answer on the left, the clock on the right. */
@media (min-width: 52rem) {
  .hero:not(:has(> .backdrop)) .wrap:not(:has(> .place)) > .details:has(> .countdown:not([hidden])) { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .hero:not(:has(> .backdrop)) .wrap:not(:has(> .place)) > .details:has(> .countdown:not([hidden])) > * { grid-column: 1 / -1; }
  .hero:not(:has(> .backdrop)) .wrap:not(:has(> .place)) > .details > .answer:has(+ .countdown:not([hidden])) { grid-column: 1; max-width: none; border-bottom-left-radius: var(--r-large); border-top-right-radius: 0; }
  .hero:not(:has(> .backdrop)) .wrap:not(:has(> .place)) > .details > .answer + .countdown:not([hidden]) { grid-column: 2; display: grid; align-content: center; justify-items: center; max-width: none; padding: 1rem 1.25rem; border-top: 1px solid oklch(100% 0 0 / 0.2); border-left: 0; border-top-right-radius: var(--r-large); border-bottom-left-radius: 0; }
}
.when-date { margin: 0 0 var(--space-2); font-size: var(--t-body); font-weight: 600; line-height: 1.3; }
/* The time. The first row is the big one: the reader's own time once the browser has drawn it, the venue's
   until then. The second, smaller row is the venue's time, or a note that the two are the same. */
.rows { display: grid; gap: var(--space-1); }
.trow { margin: 0; }
.trow.main { display: grid; gap: 0.1rem; }
.rows .tc-label { font-size: var(--t-meta); font-weight: 600; line-height: 1.3; color: var(--glow); }
.tc-when { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.5rem; }
.tc-time { font-family: var(--font-display); font-stretch: 75%; font-size: clamp(3rem, 21cqw, 5.5rem); font-weight: 800; line-height: 0.95; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tz { font: 700 condensed var(--t-lead)/1 var(--font-display); }
/* '+1 day': the reader's date is not the venue's. */
.day { align-self: center; padding: 0.1rem 0.55rem; border-radius: var(--r-pill); background: var(--hot); color: var(--hero-1); font-size: var(--t-small); font-weight: 600; line-height: 1.4; white-space: nowrap; }
.trow.sub { font-size: var(--t-meta); line-height: 1.4; font-variant-numeric: tabular-nums; opacity: 0.85; }
.tba { margin: 0; font: 800 condensed var(--t-title)/1.2 var(--font-display); }
/* The venue's line, with the forecast at its end: a small icon and the temperature. */
.where { display: flex; flex-wrap: wrap; align-items: center; gap: 0 0.7rem; margin: var(--space-2) 0 0; font-size: var(--t-meta); line-height: 1.4; }
.answer .where { padding-top: var(--space-2); border-top: 1px solid oklch(100% 0 0 / 0.14); }
.wx { display: inline-flex; align-items: center; gap: 0.3rem; font-weight: 600; font-variant-numeric: tabular-nums; cursor: help; }
.more-line { margin: var(--space-1) 0 0; font-size: var(--t-meta); }
.hero .more { color: var(--glow); font-weight: 600; }

/* --- The clock, the bottom half of the scoreboard. Four units always fit on one line, phone or desktop. */
.clock-lead { grid-column: 1 / -1; font-size: var(--t-meta); font-weight: 600; opacity: 0.85; }
.unit .label { font-family: var(--font-text); font-size: var(--t-small); font-weight: 400; line-height: 1.2; opacity: 0.85; }
/* Shown once the event has finished */
.clock-text { display: block; font: 800 condensed var(--t-title)/1.2 var(--font-display); }

/* --- Under the scoreboard: a row of small things to do (add to a calendar, embed, choose a clock face).
   The same small button opens the reader's settings in the header. */
.actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.act { display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem; min-height: 2rem; padding: 0.2rem 0.8rem; border: 1px solid oklch(100% 0 0 / 0.32); border-radius: var(--r-pill); background: transparent; color: inherit; font: 600 var(--t-small)/1.2 var(--font-text); text-decoration: none; white-space: nowrap; cursor: pointer; transition: background-color 0.15s, border-color 0.15s; }
.prefs-open .pre { font-weight: 400; opacity: 0.85; }
@media (max-width: 34rem) { .prefs-open .pre { display: none; } }

/* --- Sheets: what those buttons open (the embed code, the clock faces, the reader's settings). */
.sheet { width: min(24rem, calc(100vw - 2rem)); padding: 1.25rem; border: 1px solid var(--line); border-radius: var(--r-large); background: var(--surface); color: var(--ink); box-shadow: 0 24px 70px oklch(0% 0 0 / 0.5); font: 400 var(--t-meta)/1.5 var(--font-text); --focus: var(--focus-page); }
.sheet.embed-code { width: min(34rem, calc(100vw - 2rem)); }
.sheet:popover-open { animation: pop 0.2s ease-out both; }
.sheet::backdrop { background: oklch(0% 0 0 / 0.55); backdrop-filter: blur(3px); }
.sheet p { margin: 0 0 var(--space-3); color: var(--muted); }
.sheet .sheet-title { margin: 0 0 var(--space-3); font: 800 condensed var(--t-title)/1.1 var(--font-display); color: var(--ink); }
.sheet .sheet-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: var(--space-3) 0 0; }
.sheet label { display: grid; gap: var(--space-1); margin: 0 0 var(--space-3); font-weight: 600; }
.sheet select, .sheet textarea { display: block; width: 100%; padding: 0.6rem 0.7rem; border: 1px solid var(--line); border-radius: var(--r-small); background: var(--bg); color: var(--ink); font: 400 var(--t-body)/1.4 var(--font-text); }
.sheet textarea { font: 400 var(--t-small)/1.4 ui-monospace, "SF Mono", Menlo, Consolas, monospace; resize: vertical; }
.clock-picker { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.clock-picker button { min-height: 2.25rem; padding: 0.3rem 1rem; border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--bg); color: var(--ink); font: 600 var(--t-meta)/1.2 var(--font-text); cursor: pointer; transition: background-color 0.15s, border-color 0.15s; }
.clock-picker button[aria-pressed="true"] { background: var(--ink); color: var(--bg); border-color: transparent; }

/* --- The page shown inside another site's frame: the same time rows and clock with no panel around them,
   small enough to fit the frame height given in the embed code. */
body.embed { background: var(--hero-1); }
.embed .hero { min-height: 100vh; padding: 0.7rem 0.9rem; }
.embed h1 { margin: 0 0 var(--space-1); font-size: var(--t-lead); }
.embed .when-date { margin: 0; font-size: var(--t-small); }
.embed .rows { gap: 0; }
.embed .tc-label { font-size: var(--t-small); }
.embed .trow.main { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.6rem; }
.embed .tc-time { font-size: var(--t-title); line-height: 1.1; }
.embed .tz { font-size: var(--t-meta); }
.embed .trow.sub { font-size: var(--t-small); }
.embed .countdown { max-width: none; margin-top: var(--space-2); padding: 0; border: 0; background: none; }
.embed .clock { row-gap: 0.3rem; }
.embed .unit { gap: 0.2rem; }
/* Smaller clock faces, so the whole card fits the frame. */
.embed .seg { height: min(10cqw, 2.6rem); }
.embed .clock-mission .clock-lead, .embed .clock-mission .value { font-size: min(11cqw, 2.8rem); }
.embed .card { font-size: min(10cqw, 2.8rem); }
.embed .clock-ring .value { width: min(19cqw, 3.8rem); }
.embed .num { font-size: min(8cqw, 1.6rem); }
.embed .by { display: flex; gap: 0.8rem; margin: var(--space-2) 0 0; font-size: var(--t-small); opacity: 0.85; }
.embed .by a { color: var(--glow); }

/* --- On a touch screen anything tappable is at least a thumb tall and wide. Buttons grow; links inside a
   line of text keep their place and get a larger area to hit instead. */
@media (pointer: coarse) {
  .act, .clock-picker button, .sheet select, .sheet .button { min-height: var(--tap); min-width: var(--tap); }
  h1 a, .eb a, .next-name a, .hero .more, .matchup a.side, .embed .by a { position: relative; }
  h1 a::after, .eb a::after, .next-name a::after, .hero .more::after, .matchup a.side::after, .embed .by a::after { content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, var(--tap)); height: var(--tap); transform: translate(-50%, -50%); }
}
/* The pointer: a button or a tab lightens a step under it. Nothing moves. */
@media (hover: hover) {
  h1 a:hover { background-size: 100% 0.08em; }
  .act:hover { background: oklch(100% 0 0 / 0.14); border-color: oklch(100% 0 0 / 0.6); }
  .clock-picker button:not([aria-pressed="true"]):hover { background: var(--hover); border-color: var(--muted); }
}

/* === Stream B: lists (fixtures, matches, players, teams, status marks) === */

/* --- Where an event stands: on now, finished, or called off. Sits beside a name, on the hero or in a list. */
.status-mark { display: inline-block; padding: 0.1rem 0.55rem; border-radius: var(--r-pill); border: 1px solid transparent; font: 600 var(--t-small)/1.4 var(--font-text); white-space: nowrap; }
.status-mark.live { background: var(--hot); color: var(--hero-1); }
.status-mark.done { border-color: color-mix(in oklch, currentColor 45%, transparent); }
.status-mark.off { background: #ffd35c; color: #3d2c00; }

/* --- Headings in the body: sentence case, in the display voice, three sizes down from the page's heading. */
h2 { margin: var(--space-5) 0 var(--space-3); font: 800 condensed var(--t-title)/1.1 var(--font-display); }
h3 { margin: var(--space-4) 0 var(--space-2); font: 700 condensed var(--t-lead)/1.2 var(--font-display); }
h4 { margin: var(--space-3) 0 var(--space-1); font: 700 condensed var(--t-body)/1.3 var(--font-display); color: var(--muted); }
.field-note, .m-note { margin: var(--space-2) 0 0; font-size: var(--t-small); color: var(--muted); }

/* --- Timetables: a heading for each day, marked in the sport's colour, then hairline rows in columns: the
   time, the event, the place, and a stage or standing. Names are never cut short: they wrap. */
.fixtures ol { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.fixtures .fx-date { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 0.5rem; margin: var(--space-4) 0 var(--space-2); font: 700 condensed var(--t-lead)/1.2 var(--font-display); color: var(--ink); }
.fixtures .fx-date:first-child { margin-top: 0; }
.fx-date:not(.sub)::before { content: ""; align-self: center; width: 0.3rem; height: 1em; background: var(--accent); }
/* A day inside a wider section, such as a Saturday inside "This weekend". */
.fixtures .fx-date.sub { margin: var(--space-3) 0 var(--space-1); font-size: var(--t-body); color: var(--muted); }
.fixtures .fx-date + .sub { margin-top: 0; }
.fx-full { font: 400 var(--t-meta)/1.3 var(--font-text); color: var(--muted); }
.fx-row { border-bottom: 1px solid var(--line); }
/* The column of logos is only there on a board that has some, and the column of sports only where sports are mixed. */
.fixtures.marked { --mark: [mark] 1.75rem; }
.fixtures a { display: grid; grid-template-columns: var(--mark,) [time] 4.75rem [event] minmax(0, 1fr) [end] auto; column-gap: 0.6rem; align-items: start; padding: 0.6rem 0.25rem; text-decoration: none; transition: background-color 0.15s; }
.fx-mark { grid-column: mark; grid-row: 1 / span 2; display: grid; }
.fx-mark .logo, .fx-mark .sport-icon { width: 1.75rem; height: 1.75rem; }
.fx-mark .logo { padding: 0.15rem; }
.fx-time { grid-column: time; grid-row: 1 / span 2; display: grid; min-width: 0; }
.fx-time time { font: 700 condensed var(--t-lead)/1.5rem var(--font-display); font-variant-numeric: tabular-nums; white-space: nowrap; }
.fx-zone { font-size: var(--t-small); line-height: 1.35; color: var(--muted); }
.fx-event { grid-column: event; grid-row: 1; min-width: 0; font-size: var(--t-body); font-weight: 600; line-height: 1.5rem; overflow-wrap: anywhere; }
/* Two sides, each a crest and a full name. On a phone one stands above the other, crest first. */
.fx-event.pair { display: grid; gap: 0.25rem; }
.fx-side { display: flex; align-items: flex-start; gap: 0.4rem; min-width: 0; }
.fx-v { font-weight: 400; color: var(--muted); }
.fx-crest { flex: none; display: grid; place-items: center; width: 1.5rem; height: 1.5rem; }
.fx-crest:has(.chip) { width: auto; min-width: 1.5rem; }
.fx-crest .logo { width: 1.5rem; height: 1.5rem; padding: 0.1rem; }
.fx-crest .flag { width: 100%; height: auto; box-shadow: 0 0 0 1px var(--line); }
.fx-crest .chip { padding: 0 0.3rem; box-shadow: none; }
.fx-where { grid-column: event / -1; grid-row: 2; display: flex; flex-wrap: wrap; gap: 0 0.6rem; min-width: 0; margin-top: 0.15rem; font-size: var(--t-small); line-height: 1.35; color: var(--muted); }
.fx-sport { flex: none; font-weight: 600; color: var(--ink); }
.fx-place { min-width: 0; }
.fx-end { grid-column: end; grid-row: 1; display: flex; align-items: center; justify-content: flex-end; gap: 0.2rem 0.5rem; min-height: 1.5rem; font-size: var(--t-small); color: var(--muted); }
.fx-tag { display: none; }
/* Finished: quieter, still readable. */
.fx-row.done a { color: var(--muted); }
.fx-row.done .fx-sport { color: inherit; }
.fx-row.done .fx-mark, .fx-row.done .fx-crest { opacity: 0.6; }
@media (max-width: 47.99rem) {
  /* The second side is written name first, for the wide layout; here its crest leads like the first one's. The
     "v" between them is kept for screen readers only. */
  .fx-v + .fx-side { flex-direction: row-reverse; justify-content: flex-end; }
  .fx-v { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
}
@media (min-width: 48rem) {
  .fixtures.marked { --mark: [mark] 2.25rem; }
  .fixtures.several { --sport: [sport] 6rem; --end: 5.5rem; }
  .fixtures a { grid-template-columns: var(--mark,) [time] 6rem [event] minmax(0, 2fr) var(--sport,) [place] minmax(0, 1fr) [end] var(--end, 8rem); column-gap: 1rem; align-items: center; padding: 0.5rem; }
  .fx-mark, .fx-time { grid-row: 1; }
  .fx-mark .logo, .fx-mark .sport-icon { width: 2.25rem; height: 2.25rem; }
  /* With room for a line, the two sides face each other across the "v": crest, name, v, name, crest. */
  .fx-event.pair { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.1rem 0.4rem; }
  .fx-where { display: contents; }
  .fx-sport { grid-column: sport; grid-row: 1; }
  .fx-place { grid-column: place; grid-row: 1; }
  .fx-end { flex-wrap: wrap; text-align: right; }
  .fx-tag { display: inline; }
}
/* What is over on a year's schedule, and each group of teams, fold away under a line of their own. */
.fx-over, .teamgroup { border-top: 1px solid var(--line); }
.fx-over { margin-top: var(--space-4); }
.fx-over > summary, .teamgroup > summary { display: flex; align-items: center; gap: 0.6rem; padding: 0.6rem 0.25rem; font: 700 condensed var(--t-lead)/1.2 var(--font-display); cursor: pointer; transition: background-color 0.15s; }
.fx-over > summary::-webkit-details-marker, .teamgroup > summary::-webkit-details-marker { display: none; }
.fx-over > summary::after, .teamgroup > summary::after { content: ""; flex: none; width: 0.5rem; height: 0.5rem; margin: 0 0.4rem 0.2rem auto; border: solid var(--muted); border-width: 0 2px 2px 0; transform: rotate(45deg); transition: transform 0.15s; }
.fx-over[open] > summary::after, .teamgroup[open] > summary::after { transform: rotate(-135deg); margin-bottom: -0.2rem; }
.fx-over[open] > summary { margin-bottom: var(--space-2); }

/* --- Order of play: under each day, a column for each court, its matches numbered in the order they are played. */
.courts { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); gap: 0.2rem 2rem; align-items: start; }
.matchlist { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); counter-reset: match; }
.matchlist li { display: grid; grid-template-columns: var(--number,) 5rem minmax(0, 1fr); gap: 0 0.6rem; align-items: baseline; padding: 0.45rem 0.25rem; border-bottom: 1px solid var(--line); }
ol.matchlist { --number: 1.25rem; }
ol.matchlist li::before { content: counter(match); counter-increment: match; grid-row: span 2; font: 700 condensed var(--t-body)/1.3 var(--font-display); font-variant-numeric: tabular-nums; color: var(--muted); }
/* A draw has no times yet, so it has no column for them. */
ul.matchlist li:has(> .m-time:empty) { grid-template-columns: minmax(0, 1fr); }
ul.matchlist .m-time:empty { display: none; }
.m-time { grid-row: span 2; font: 700 condensed var(--t-body)/1.3 var(--font-display); font-variant-numeric: tabular-nums; }
.m-time small { display: block; font: 400 var(--t-small)/1.2 var(--font-text); color: var(--muted); }
.m-players { font-size: var(--t-meta); font-weight: 600; }
.m-players i { font-style: normal; font-weight: 400; color: var(--muted); }
.m-meta { display: flex; gap: 0.6rem; font-size: var(--t-small); color: var(--muted); }

/* --- The field: who is taking part, best first, as numbered rows that run down two or three columns. */
.field { list-style: none; margin: 0; padding: 0; columns: 15rem; column-gap: 2rem; }
.field li { display: flex; align-items: baseline; gap: 0.6rem; padding: 0.4rem 0.25rem; border-bottom: 1px solid var(--line); break-inside: avoid; }
.pos { flex: none; width: 1.5rem; font: 700 condensed var(--t-body)/1.3 var(--font-display); font-variant-numeric: tabular-nums; color: var(--muted); text-align: right; }
.field .who { font-weight: 600; }
.num-plate { margin-left: auto; min-width: 1.75rem; padding: 0 0.35rem; border-radius: var(--r-small); background: var(--ink); color: var(--bg); font: 700 condensed var(--t-meta)/1.5 var(--font-display); font-variant-numeric: tabular-nums; text-align: center; }

/* --- Teams on a sport's home page: a box to find one by name, then a folding group for each competition. */
.team-filter { display: flex; align-items: center; gap: 0.6rem; margin: 0 0 var(--space-3); font-size: var(--t-meta); }
.team-filter input { flex: 1; min-width: 0; max-width: 20rem; padding: 0.45rem 0.7rem; border: 1px solid var(--line); border-radius: var(--r-small); background: var(--surface); color: var(--ink); font: inherit; }
.team-none { margin-bottom: var(--space-3); }
.teams > .teamgroup:last-of-type { border-bottom: 1px solid var(--line); }
.tg-mark { flex: none; display: grid; place-items: center; min-width: 2rem; height: 2rem; }
.tg-mark .logo { width: 2rem; height: 2rem; padding: 0.15rem; }
.tg-mark .chip { padding: 0 0.3rem; line-height: 1.6; }
.tg-count { flex: none; font: 400 var(--t-small)/1.3 var(--font-text); color: var(--muted); }
.teamlist { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); gap: 0 1rem; }
@media (min-width: 48rem) { .teamlist { grid-template-columns: repeat(auto-fill, minmax(12.5rem, 1fr)); } }
.teamlist a { display: flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0.25rem; border-radius: var(--r-small); font-size: var(--t-meta); font-weight: 600; line-height: 1.3; text-decoration: none; transition: background-color 0.15s; }

/* --- Competitions on a sport's home page: cards, because each one opens a page. The logo sits in a square tile. */
.cards { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr)); gap: var(--space-2); }
.cards a { display: grid; grid-template-columns: 3rem minmax(0, 1fr) auto; gap: 0.1rem 0.8rem; align-content: start; height: 100%; padding: 0.8rem; border: 1px solid var(--line); border-radius: var(--r-large); background: var(--surface); text-decoration: none; transition: border-color 0.15s; }
.c-mark { grid-row: 1 / span 3; display: grid; place-items: center; width: 3rem; height: 3rem; overflow: hidden; border-radius: var(--r-small); background: #fff; box-shadow: 0 0 0 1px var(--line); }
.c-mark .logo { width: 3rem; height: 3rem; padding: 0.3rem; border-radius: 0; }
.c-mark .chip { display: grid; place-items: center; width: 100%; height: 100%; padding: 0; border-radius: 0; box-shadow: none; }
.c-name { grid-column: 2 / -1; font: 700 condensed var(--t-lead)/1.2 var(--font-display); }
.c-kind, .c-count, .c-next { font-size: var(--t-small); line-height: 1.4; color: var(--muted); }
.c-kind { grid-column: 2; }
.c-count { grid-column: 3; font-variant-numeric: tabular-nums; }
.c-next { grid-column: 2 / -1; color: var(--ink); }

/* The pointer: a row is shaded under it, and a card's edge darkens. Nothing moves. */
@media (hover: hover) {
  .fixtures a:hover, .teamlist a:hover, .fx-over > summary:hover, .teamgroup > summary:hover { background: var(--hover); }
  .cards a:hover { border-color: var(--muted); }
}
@media (pointer: coarse) {
  .fixtures a, .teamlist a, .fx-over > summary, .teamgroup > summary, .team-filter input { min-height: var(--tap); }
}

/* === Stream C: page frame (header, navigation, breadcrumb, footer, logo tiles) === */

/* --- The header: one dark band in the brand's colour on every page, in levels that look different. The top bar
   holds the brand, the sports as pills and the reader's settings. Under it come the breadcrumb, with anything on
   now beside it, and then the tabs of the section the page is in. Every row is one line: it scrolls sideways
   before it wraps. */
header { background: var(--bar); color: var(--hero-ink); font: 400 var(--t-small)/1.3 var(--font-text); }
header a { text-decoration: none; }
header ul, header ol { position: relative; display: flex; margin: 0; padding: 0; list-style: none; overflow-x: auto; scrollbar-width: none; white-space: nowrap; }
/* A row that scrolls would cut off a focus ring drawn outside a link, so in the header it is drawn inside. */
header a:focus-visible { outline-offset: -3px; }
.topbar { display: flex; align-items: center; gap: 0.5rem; }
/* The brand: a clock face in the brand's colour with its hands cut out of it, then the name. */
.brand { flex: none; display: inline-flex; align-items: center; gap: 0.45rem; min-height: var(--tap); font: 800 condensed var(--t-lead)/1 var(--font-display); }
.brand-mark { flex: none; width: 1.5rem; height: 1.5rem; }
.brand-mark .face { fill: var(--brand); }
.brand-mark .hands { stroke: var(--bar); }
/* On a phone the mark stands for the name, so the sports fit on the same line. Screen readers still get the name. */
@media (max-width: 34rem) { .brand span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } }

/* The sports. A link is as tall as the bar, so it is easy to tap; its pill is drawn smaller inside it. The row
   fades out at either end, where it scrolls under the brand and the settings. */
.sports { flex: 1; min-width: 0; }
.sports ul { gap: 0.4rem; padding: 0 0.6rem; mask-image: linear-gradient(90deg, transparent, #000 0.6rem, #000 calc(100% - 0.6rem), transparent); }
.sports a { position: relative; z-index: 0; display: inline-flex; align-items: center; gap: 0.35rem; min-height: var(--tap); padding: 0 0.7rem 0 0.4rem; font-weight: 600; }
.sports a::before, .follow::before, .prefs-open::before { content: ""; position: absolute; z-index: -1; inset: calc(50% - 0.95rem) 0; border-radius: var(--r-pill); border: 1px solid oklch(100% 0 0 / 0.18); background: oklch(100% 0 0 / 0.08); transition: background-color 0.15s, border-color 0.15s; }
.sports .sport-icon { width: 1.25rem; height: 1.25rem; }
.sports a[aria-current] { color: var(--bar); }
.sports a[aria-current]::before { background: var(--hero-ink); border-color: transparent; }
.sports a:focus-visible, .follow:focus-visible, .prefs-open:focus-visible { outline: none; }
.sports a:focus-visible::before, .follow:focus-visible::before, .prefs-open:focus-visible::before { outline: 3px solid var(--focus); outline-offset: 2px; }
/* Where the browser script puts the reader's time zone. It takes no room until it is filled. Its button is as
   tall as the bar, with its pill drawn smaller inside it, like a sport's. */
.prefs-mount { flex: none; margin-left: auto; }
.prefs-mount:empty { display: none; }
.prefs-open { position: relative; z-index: 0; min-height: var(--tap); border: 0; }
.prefs-open:hover { background: none; }

/* The breadcrumb, always one line. The page's own name, at the end, is cut short before anything else is. */
.context { display: flex; align-items: center; gap: 1rem; min-height: 2rem; }
.context > * { margin: 0; }
nav[aria-label="Breadcrumb"] { flex: 0 1 auto; min-width: 0; }
nav[aria-label="Breadcrumb"] ol { align-items: center; gap: 0.4rem; }
nav[aria-label="Breadcrumb"] li { flex: none; display: flex; align-items: center; gap: 0.4rem; opacity: 0.8; }
nav[aria-label="Breadcrumb"] li:last-child { flex: 0 1 auto; display: block; min-width: 3rem; overflow: hidden; text-overflow: ellipsis; opacity: 1; }
nav[aria-label="Breadcrumb"] li + li::before { content: "›"; }
nav[aria-label="Breadcrumb"] li + li:last-child::before { margin-right: 0.4rem; }
/* What is under way right now, beside the breadcrumb: a dot, the words, then a link for each event. */
.onnow { flex: 0 100 auto; display: flex; align-items: center; gap: 0.75rem; min-width: 0; margin-left: auto; overflow-x: auto; scrollbar-width: none; white-space: nowrap; }
.context > .onnow:first-child { margin-left: 0; }
.onnow span { font-weight: 600; }
.onnow span::before { content: ""; display: inline-block; width: 0.5rem; height: 0.5rem; margin-right: 0.4rem; border-radius: 50%; background: var(--hot); }
.onnow a { text-decoration: underline; text-decoration-color: currentColor; }

/* Tabs, one level down from the sports: a sport's competitions, or a group's sports. Underlined rather than
   pills, so the two levels do not look alike; the line under the current one is in the sport's colour. One row
   that scrolls sideways and fades out where it runs on, with the Follow button at its end. */
.tabrow { display: flex; align-items: center; gap: 0.75rem; }
.compnav { flex: 1; min-width: 0; }
.compnav ul { gap: 1.25rem; padding-right: 1.5rem; mask-image: linear-gradient(90deg, #000 calc(100% - 1.5rem), transparent); }
.compnav a { display: inline-flex; align-items: center; gap: 0.4rem; min-height: 2.75rem; border-bottom: 3px solid transparent; color: color-mix(in oklch, var(--hero-ink) 80%, transparent); font-weight: 600; transition: color 0.15s, border-color 0.15s; }
.compnav a[aria-current] { border-bottom-color: var(--glow); color: inherit; }
.compnav .sport-icon { width: 1.25rem; height: 1.25rem; }
.compnav .chip { display: inline-grid; place-items: center; min-width: 1.75rem; height: 1.75rem; padding: 0 0.3rem; }
/* Follow: a toggle, written hidden and shown by the browser script that makes it work. A star fills when it is on. */
.follow { position: relative; z-index: 0; flex: none; min-height: 2.75rem; padding: 0 0.75rem; border: 0; background: none; color: inherit; font: 600 var(--t-small)/1.2 var(--font-text); cursor: pointer; }
.follow::after { content: "\00a0\2606"; }
.follow[aria-pressed="true"] { color: var(--hero-1); }
.follow[aria-pressed="true"]::before { background: var(--glow); border-color: transparent; }
.follow[aria-pressed="true"]::after { content: "\00a0\2605"; }
@media (hover: hover) {
  .sports a:not([aria-current]):hover::before, .follow[aria-pressed="false"]:hover::before, .prefs-open:hover::before { background: oklch(100% 0 0 / 0.2); border-color: oklch(100% 0 0 / 0.4); }
  .compnav a:not([aria-current]):hover { color: inherit; border-bottom-color: oklch(100% 0 0 / 0.4); }
  nav[aria-label="Breadcrumb"] a:hover, .footnav a:hover { text-decoration: underline; }
}

/* --- Logo tiles. Every logo sits in the same square, contained and centred with even padding, so a wide wordmark
   takes no more room than a round crest. The plate is white, so a dark logo shows on the dark hero; a logo of pale
   lettering asks for a dark plate in logos.json. A rule that resizes a tile gives its width and its height, never
   one of them or a percentage, so the tile stays square wherever it stands. */
.logo { display: block; flex: none; width: 1.75rem; height: 1.75rem; padding: 0.2rem; border-radius: var(--r-small); background: #fff; object-fit: contain; }
.logo.big { width: 4.5rem; height: 4.5rem; padding: 0.5rem; border-radius: var(--r-large); }
.logo.on-dark { background: #14171c; box-shadow: 0 0 0 1px oklch(100% 0 0 / 0.22); }
.chip.big { padding: 0.5rem 1rem; border-radius: var(--r-large); font-size: var(--t-title); line-height: 1.2; }
.comphead { display: flex; align-items: center; gap: var(--space-3); margin: 0 0 var(--space-3); }
.comphead p { margin: 0; max-width: 34rem; font-size: var(--t-meta); }
.eventmark { margin: 0 0 var(--space-3); }
.teamhead .flag { width: 4rem; height: 3rem; }
.teamhead .chip { padding: 0.3rem 0.8rem; font-size: var(--t-lead); }

/* --- Buttons in the body: ink on the page, or an outline for the quieter one of a pair. */
.button { display: inline-flex; align-items: center; min-height: 2.5rem; padding: 0.4rem 1.1rem; border: 0; border-radius: var(--r-pill); background: var(--ink); color: var(--bg); font: 600 var(--t-meta)/1.2 var(--font-text); text-decoration: none; cursor: pointer; transition: background-color 0.15s; }
.button.quiet { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1px var(--line); }
p:has(> .button) { margin: var(--space-3) 0 0; }

/* --- Main page: the next events of what the reader follows, filled in by the browser. */
.following ol, .sportlist, .footnav ul { list-style: none; margin: 0; padding: 0; }
.following ol { display: grid; gap: var(--space-2); }
.following a { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0 1rem; padding: 0.55rem 0.8rem; border-radius: var(--r-small); background: var(--surface); border: 1px solid var(--line); text-decoration: none; transition: border-color 0.15s; }
.following b { font-weight: 600; }
.following time { font-size: var(--t-meta); color: var(--muted); font-variant-numeric: tabular-nums; }
/* --- The "page not found" page: every sport. */
.sportlist { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.sportlist a { display: inline-flex; align-items: center; gap: 0.45rem; padding: 0.4rem 0.9rem 0.4rem 0.5rem; border-radius: var(--r-pill); background: var(--surface); border: 1px solid var(--line); font-size: var(--t-meta); font-weight: 600; text-decoration: none; transition: border-color 0.15s; }
.sportlist .sport-icon { width: 1.5rem; height: 1.5rem; }

/* --- Event page: the events either side of this one on one line, then two ordinary links. */
.pager { margin-top: var(--space-5); padding-top: var(--space-3); border-top: 1px solid var(--line); font-size: var(--t-meta); }
/* Where nothing stands above it in the body, it needs no line and no gap to part it from anything. */
.body > .pager:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.pager p { display: flex; flex-wrap: wrap; gap: 0 1.25rem; margin: 0 0 var(--space-1); }
.pager a { min-width: 0; }
.pager-steps a { font-weight: 600; }
.pager [rel="next"] { margin-left: auto; text-align: right; }

/* --- The foot of the page: the site's sections, this sport's own, then the notice and the contact line. */
footer { margin-top: var(--space-5); padding: var(--space-4) 0 var(--space-5); border-top: 1px solid var(--line); font-size: var(--t-small); color: var(--muted); }
footer p { max-width: 70ch; margin: 0 0 var(--space-2); }
.footnav ul { display: flex; flex-wrap: wrap; gap: 0.1rem 1.1rem; margin-bottom: var(--space-2); }
.footnav a { text-decoration: none; }
.footnav:first-child a { color: var(--ink); font-weight: 600; }

/* The pointer: a button darkens or lightens a step, and a card's edge darkens. Nothing moves. */
@media (hover: hover) {
  .button:hover { background: color-mix(in oklch, var(--ink) 82%, var(--bg)); }
  .button.quiet:hover { background: var(--hover); }
  .following a:hover, .sportlist a:hover { border-color: var(--muted); }
}
@media (pointer: coarse) {
  .context a, footer a { display: inline-flex; align-items: center; min-height: var(--tap); }
  .compnav a, .follow, .sportlist a, .following a, .button { min-height: var(--tap); }
  .pager a { display: inline-flex; align-items: center; min-height: var(--tap); }
  .footnav ul { gap: 0 1.5rem; }
}

/* === Integration === */
/* A team page's "Next:" line carries each side's crest before its name, in the line of text. */
.next-name .fx-crest { display: inline-grid; margin-right: 0.3em; vertical-align: -0.2em; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
