/*
 * Base layer — the reset, the element defaults, the type scale, the page
 * frame, the chrome and the controls.
 *
 * Everything here is written against tokens.css and nothing here defines a
 * token. That is not a preference: this file loads after the token file, so a
 * `:root` block here would silently win the cascade, which is exactly how a
 * commit that fixed two measured contrast failures once shipped without
 * changing a single rendered colour.
 *
 * Split of responsibility: this file owns the shell a reader sees on every
 * route. components.css owns the things inside it.
 */

/* ------------------------------------------------------------------ faces */

/*
 * Self-hosted, and only the subsets the site uses: Latin and Latin Extended,
 * which covers every club and player name on the board (Ž, ł, ğ, ő and the
 * rest). All three are SIL Open Font License. Offside Figures is built from
 * Big Shoulders; see public/fonts/README.md. Its weight ranges map the three
 * static cuts onto the whole weight axis, so any weight the page asks for
 * finds the nearest cut rather than a synthesised one.
 */
@font-face {
  font-family: 'Big Shoulders Display';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/fonts/bigshoulders-latin-ext.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: 'Big Shoulders Display';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/fonts/bigshoulders-latin.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: 'Caveat';
  font-style: normal;
  font-weight: 500 700;
  font-display: swap;
  src: url('/fonts/caveat-latin.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: 'Geist';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/geist-latin-ext.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: 'Geist';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/geist-latin.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: 'Offside Figures';
  font-style: normal;
  font-weight: 100 649;
  font-display: swap;
  src: url('/fonts/offside-figures-600.woff2') format('woff2');
  unicode-range: U+0030-0039, U+002B-002E, U+003A, U+0025, U+2013, U+2212;
}
@font-face {
  font-family: 'Offside Figures';
  font-style: normal;
  font-weight: 650 749;
  font-display: swap;
  src: url('/fonts/offside-figures-700.woff2') format('woff2');
  unicode-range: U+0030-0039, U+002B-002E, U+003A, U+0025, U+2013, U+2212;
}
@font-face {
  font-family: 'Offside Figures';
  font-style: normal;
  font-weight: 750 900;
  font-display: swap;
  src: url('/fonts/offside-figures-800.woff2') format('woff2');
  unicode-range: U+0030-0039, U+002B-002E, U+003A, U+0025, U+2013, U+2212;
}

/*
 * Stand-ins shaped like the real faces, for the moment before they load.
 * The overrides match each face's ascent and descent, so the line boxes are
 * the same height before and after the swap and nothing below a headline
 * jumps when the font arrives.
 */
@font-face {
  font-family: 'Big Shoulders Fallback';
  src: local('Arial Narrow'), local('ArialNarrow'), local('Roboto Condensed'), local('DejaVu Sans Condensed'), local('Arial');
  ascent-override: 98.4%;
  descent-override: 21.3%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Geist Fallback';
  src: local('Arial'), local('Helvetica Neue'), local('Roboto'), local('DejaVu Sans');
  size-adjust: 104%;
  ascent-override: 96.6%;
  descent-override: 28.4%;
  line-gap-override: 0%;
}

/* ------------------------------------------------------------------ reset */

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

html {
  -webkit-text-size-adjust: 100%;
  /* Kerning always, never a faked bold or italic, and the ligatures and
     contextual forms each face was drawn with. */
  font-kerning: normal;
  font-synthesis: none;
  text-rendering: optimizeLegibility;
  /* The board is long and the fixture page has anchors in it. */
  scroll-padding-top: calc(var(--header-h) + var(--space-5));
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--pitch);
  color: var(--chalk);
  font-family: var(--body);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
  font-feature-settings: var(--features-text);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /*
   * Deliberately NOT `overflow-x: hidden`.
   *
   * The old base hid horizontal overflow, which does not remove it — it
   * removes the evidence of it. Three pixels of sideways scroll sat on every
   * fixture page for a whole release behind that one declaration. If something
   * here pushes the page wide, it should be visible and fixed, not swept under
   * the viewport.
   */
}

img, svg, video { max-width: 100%; display: block; }
img { height: auto; }

a { color: inherit; text-decoration: none; }
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible,
summary:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
/*
 * The focus ring wants a radius to sit against, but only on things that have
 * none of their own. Setting it on every `a:focus-visible` rounded the board
 * row to 4px the moment it took focus, because the row's own rule sets the
 * ring and not the radius, so this one still won that property.
 */
a:not([class]):focus-visible,
button:not([class]):focus-visible,
summary:focus-visible { border-radius: var(--radius-sm); }

button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }

[hidden] { display: none !important; }

::selection { background: var(--floodlight); color: var(--chalk); }

/* Firefox-flavoured scrollbars on the dense surfaces, so a board with a
   hundred rows in it does not get a bright grey gutter down the side. */
* { scrollbar-color: var(--stand-hi) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--stand-hi); border-radius: var(--radius-pill); }
::-webkit-scrollbar-track { background: transparent; }

/* ------------------------------------------------------------- typography */

/*
 * One display face with a width axis, and a body face. Emphasis is carried by
 * width and size rather than by weight, which is why the weight ceiling is 600
 * — a page where everything is 800 reads as loud rather than as confident.
 *
 * Sentence case, not uppercase. Uppercase display type is the house style of
 * every tipster site there is, and it costs a reader about a third of their
 * reading speed on anything longer than three words.
 */
.display {
  margin: 0;
  font-family: var(--display);
  font-weight: var(--weight-bold);
  font-optical-sizing: auto;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-3xl);
  text-wrap: balance;
}
h1.display { font-size: var(--text-3xl); letter-spacing: var(--tracking-3xl); }
h2.display { font-size: var(--text-xl); letter-spacing: var(--tracking-xl); line-height: var(--leading-snug); }
h3.display { font-size: var(--text-lg); letter-spacing: var(--tracking-md); line-height: var(--leading-snug); }

/*
 * The front door, and only the front door.
 *
 * Sized against the column it sits in, not against the viewport. `11vw` on a
 * 1440px screen is 158px of type inside a 544px column, which is four and a
 * half characters a line: the headline stops being a headline and becomes a
 * wall. A container query measures the thing that actually constrains it.
 *
 * Named `.xl` rather than `.hero` because the section is also called `.hero`,
 * and `.hero { border-bottom }` was landing on the `<h1>` as well — a stray
 * hairline under the headline that took a computed-style dump to find.
 */
.display.xl {
  font-size: clamp(2.5rem, 12cqw, 4.5rem);
  letter-spacing: var(--tracking-hero);
  font-variation-settings: 'wdth' var(--wide);
}

/*
 * The annotation voice.
 *
 * Rationed on purpose: the brand's own asides and sign-offs, never a number,
 * a price, a scoreline or a control. A marker hand labelling data stops being
 * a voice and becomes a font choice.
 */
.hand {
  font-family: var(--hand);
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.25;
}

.lede {
  margin: 0;
  max-width: 54ch;
  color: var(--chalk-2);
  font-size: var(--text-lg);
  line-height: var(--leading-normal);
  text-wrap: pretty;
}

/* Long strings that have to hold a narrow column: club names, prices. */
.tight-set { font-variation-settings: 'wdth' var(--tight); }

/* ------------------------------------------------------------ page frame */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/*
 * One register, and it is dense.
 *
 * The old split -- an airy front door and a dense board -- was the wrong read.
 * The reference is uniformly tight: every surface is a working surface, and the
 * breathing room comes from the photography rather than from empty space.
 */
.section { padding-block: var(--space-8); }
.section.tight { padding-block: var(--space-6) var(--space-8); }
.section.dense { padding-block: var(--space-7) var(--space-9); }
.section.open { padding-block: var(--space-9); }

.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-5);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.section-head p {
  margin: var(--space-3) 0 0;
  color: var(--chalk-2);
  font-size: var(--text-md);
  max-width: 52ch;
}
.section.dense .section-head { margin-bottom: var(--space-6); }
.section.dense .section-head p { margin-top: var(--space-2); font-size: var(--text-sm); }

.narrow { max-width: var(--maxw-read); margin-inline: auto; }

/* ---------------------------------------------------------------- header */

.top {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--pitch);
  background: color-mix(in srgb, var(--pitch) 88%, transparent);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom: var(--border) solid var(--hairline);
  padding-top: env(safe-area-inset-top, 0px);
}
/* A translucent header over a light photograph is unreadable. Where the
   browser cannot blur, it gets the solid ground instead of a wash. */
@supports not (backdrop-filter: blur(1px)) {
  .top { background: var(--pitch); }
}

/*
 * Three tracks, so the rail is centred on the page rather than on whatever is
 * left over.
 *
 * It was a flex row with `margin-inline: auto` on the rail, which centres it
 * between the mark and the controls -- and those are not the same width, so
 * the rail sat seventy-four pixels left of the middle of the page at 1440.
 * Equal outer tracks put it dead centre and hold it there as the controls
 * change width, which they do: the plan tag appears on sign-in and the
 * primary button disappears on a small screen.
 */
.top-inner {
  max-width: var(--maxw);
  margin-inline: auto;
  min-height: var(--header-h);
  padding: var(--space-2) var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-5);
}
.top-inner .brand { justify-self: start; }
.top-inner .top-right { justify-self: end; }

.brand { display: inline-flex; align-items: center; flex: none; }
/*
 * The wordmark: the offside line drawn through the name.
 *
 * Three marks preceded it. Three diagonal strokes said nothing. A raised
 * linesman's flag read as an icon rather than a name. A hand-drawn ring
 * standing in for the "o" was the telestrator, which is the product's voice
 * but not its subject, and a circle among condensed capitals read as a
 * stray "O".
 *
 * The subject is the call, and the purest picture of a call in football is
 * the line: the one the broadcaster draws across the pitch to show whether a
 * forward was level. Here it is drawn through the word itself, between "off"
 * and "side", in the one colour on the site that belongs to us, running a
 * little past the capitals top and bottom the way the broadcast line runs
 * off the players. The mark (see .mark and public/icon.svg) is the same
 * idea as a symbol: a ball, the line through it, and the sliver of the ball
 * past the line in violet.
 *
 * Set in the display face at its heaviest, tracked a touch open because Big
 * Shoulders at 800 closes up at small sizes. ".win" drops to the quiet
 * colour: it is the address, not the name.
 */
.wordmark {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--display);
  font-weight: var(--weight-black);
  font-size: var(--text-xl);
  line-height: 1;
  letter-spacing: 0.012em;
  color: var(--chalk);
  white-space: nowrap;
}
.wm-line {
  align-self: stretch;
  width: max(2px, 0.075em);
  margin: -0.14em 0.07em -0.1em 0.075em;
  border-radius: 1px;
  background: var(--floodlight-hi);
}
.wm-tld { color: var(--chalk-3); letter-spacing: 0.005em; }
.brand:hover .wm-line { background: var(--floodlight); }

/* The mark, where there is room for a symbol: the footer, the icons. */
.brand-symbol { width: auto; height: 36px; aspect-ratio: 578 / 462; flex: none; color: var(--chalk); }

/*
 * A pill rail, with the current route as a filled pill.
 *
 * The reference puts its navigation in a single rounded trough and fills the
 * active item solid — light pill, dark label — rather than underlining it. It
 * reads as a control rather than as a list of links, which is what a product's
 * navigation should look like, and it survives being three items or eight.
 */
.nav {
  display: flex;
  align-items: center;
  gap: 2px;
  flex: 0 0 auto;
  padding: 3px;
  border-radius: var(--radius);
  background: rgba(247, 244, 237, 0.05);
}
/* Above the burger breakpoint the header button already says this, so the nav
   would otherwise carry it twice. Declared here, before the media query that
   shows it, because both rules have the same specificity and the later one
   would win whatever the width. */
.nav a.nav-only-menu { display: none; }
.nav a {
  padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--chalk-2);
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.nav a:hover { color: var(--chalk); background: rgba(247, 244, 237, 0.06); }
.nav a.on { color: var(--pitch); background: var(--chalk); }

.top-right { display: flex; align-items: center; gap: var(--tap-gap); flex: none; }
/* Search, one tap from every page. */
.search-link {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--tap); height: var(--tap); border-radius: 50%; color: var(--chalk-2);
}
.search-link svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.search-link:hover, .search-link[aria-current="page"] { color: var(--chalk); background: var(--terrace); }
.search-link:focus-visible { outline: none; box-shadow: var(--focus-ring); }
/* The header's right side is flex: none, so its buttons can hold one line. */
.top-right .btn { white-space: nowrap; }

/*
 * What tier the reader is on, stated rather than implied.
 *
 * Squared and quiet on the free tier, accent-filled on a membership. It is a
 * link both ways: free goes to what it costs, member goes to the account, so
 * the tag is never a dead end.
 */
.plan-tag {
  display: inline-flex;
  align-items: center;
  padding: 4px var(--space-3);
  border: var(--border) solid var(--rule-firm);
  border-radius: var(--radius-sm);
  font-size: var(--text-2xs);
  font-weight: var(--weight-black);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--chalk-2);
  white-space: nowrap;
}
.plan-tag:hover { color: var(--chalk); border-color: var(--chalk-3); }
.plan-tag.on { background: var(--floodlight); border-color: var(--floodlight); color: #fff; }

.live {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  color: var(--chalk-3);
  white-space: nowrap;
}
.live i {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.live.ok { color: var(--chalk-2); }
.live.ok i { background: var(--won); animation: ping 2.6s var(--ease-in-out) infinite; }
@keyframes ping {
  0%   { box-shadow: 0 0 0 0 rgba(61, 180, 104, 0.5); }
  70%  { box-shadow: 0 0 0 6px rgba(61, 180, 104, 0); }
  100% { box-shadow: 0 0 0 0 rgba(61, 180, 104, 0); }
}

.burger {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: var(--tap);
  height: var(--tap);
  margin-right: calc(var(--space-3) * -1);
}
.burger span {
  display: block;
  width: 18px; height: 2px;
  margin: 3px 0;
  border-radius: var(--radius-pill);
  background: var(--chalk);
  transition: transform var(--dur-fast) var(--ease-out), opacity var(--dur-fast) linear;
}
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

@media (max-width: 940px) {
  .nav {
    position: fixed;
    inset: calc(var(--header-h) + env(safe-area-inset-top, 0px)) 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--space-4) var(--gutter) var(--space-7);
    background: var(--stand);
    border-bottom: var(--border) solid var(--rule);
    box-shadow: var(--elev-3);
  }
  .nav:not(.open) { display: none; }
  /*
   * With the rail behind the burger there is no element between the mark and
   * the controls, so the `margin-inline: auto` that centres the rail on a
   * laptop goes with it -- and the whole header collapsed to the left edge
   * with a third of the bar empty beside it. The controls take the free space
   * instead, which is where they sit at every other width anyway.
   */
  /* Two tracks with the rail gone, so the controls still end up on the right
     edge rather than hard against the mark. */
  .top-inner { grid-template-columns: minmax(0, 1fr) auto; }
  .nav a { padding: var(--space-4); font-size: var(--text-lg); }
  .nav a.on::after { display: none; }
  .nav a.on { color: var(--floodlight-hi); }
  .burger { display: flex; }
  .live { display: none; }
  /* Only in the menu, and only where there is a menu. */
  .nav a.nav-only-menu { display: block; color: var(--floodlight-hi); }
}
@media (max-width: 560px) {
  .top-right .btn-primary { display: none; }
}
/*
 * The header on a phone: the name, the account button and the menu, and
 * nothing that can collide with them. The name keeps its own width (it used
 * to sit in a column allowed to shrink to nothing, so the tally and the plan
 * tag slid over the top of it), and the smaller items leave in order of how
 * little they are missed.
 */
@media (max-width: 940px) {
  .top-inner { grid-template-columns: auto minmax(0, 1fr); }
  .top-right { min-width: 0; justify-content: flex-end; }
}
/* Scoped under .top-right so it outranks .tally further down this file. */
@media (max-width: 680px) { .top-right .tally { display: none; } }
@media (max-width: 440px) {
  .top-right .plan-tag { display: none; }
  .wordmark { font-size: 1.375rem; }
  .top-right { gap: var(--space-3); }
}

/* --------------------------------------------------------------- buttons */

/*
 * No gradients. A gradient-filled pill button is the single most reliable tell
 * of a page nobody art-directed, and the old primary carried two of them.
 * Flat fills, one hairline, a 1px lift on press.
 */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  min-height: var(--tap);
  padding: var(--space-3) var(--space-6);
  border: var(--border) solid transparent;
  border-radius: var(--radius);
  font-family: var(--body);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-instant) var(--ease-out);
}
.btn:active { transform: translateY(1px); }
.btn svg { width: 15px; height: 15px; flex: none; }
.btn[disabled] { opacity: 0.5; pointer-events: none; }

/*
 * A button that is doing something: it keeps its colour, says what it is
 * doing, and turns a small wheel so a tap that takes a second does not read as
 * a tap that did nothing. Any button can wear it (see `busy()` in app.js).
 */
.btn.is-busy[disabled], .btn-gsi.is-busy:disabled { opacity: 1; cursor: progress; }
.spin {
  display: inline-block; flex: none;
  width: 1em; height: 1em;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spin { animation-duration: 2s; } }

/*
 * The default action carries the accent, as the reference's "watch live" does.
 * A colourless page needs one place the eye is told to go, and on a dark ground
 * a solid accent is that place.
 */
.btn-primary { background: var(--floodlight); color: #fff; }
.btn-primary:hover { background: var(--floodlight-hi); color: var(--pitch); }

/* Maximum contrast, no colour — for the one button that takes money. */
.btn-light { background: var(--chalk); color: var(--pitch); }
.btn-light:hover { background: #fff; }

/* A square button for an icon on its own, beside a primary. */
.btn-icon {
  width: var(--tap);
  min-width: var(--tap);
  padding: 0;
  background: rgba(247, 244, 237, 0.06);
  border-color: var(--hairline);
  color: var(--chalk);
}
.btn-icon:hover { background: rgba(247, 244, 237, 0.12); }
.btn-icon svg { width: 16px; height: 16px; }

/*
 * The one that takes money.
 *
 * Dark ink on the light violet rather than white on the mid violet: the first
 * measures 6.0:1, the second 4.5:1, and the difference is visible at a glance
 * on a phone in daylight.
 */
.btn-accent { background: var(--floodlight-hi); color: var(--pitch); }
.btn-accent:hover { background: #a68fff; }

.btn-ghost {
  background: transparent;
  color: var(--chalk);
  border-color: var(--rule-firm);
}
.btn-ghost:hover { background: var(--terrace); border-color: var(--chalk-3); }

.btn-quiet { background: transparent; color: var(--chalk-2); padding-inline: var(--space-4); }
.btn-quiet:hover { color: var(--chalk); }

.btn-danger { background: transparent; color: var(--lost); border-color: var(--rule); }
.btn-danger:hover { border-color: var(--lost); background: rgba(203, 49, 49, 0.1); }

.btn-sm { min-height: 34px; padding: var(--space-2) var(--space-5); font-size: var(--text-xs); }

.btn-lg { min-height: 46px; padding: var(--space-4) var(--space-7); font-size: var(--text-md); }

.btn-google {
  background: var(--terrace);
  color: var(--chalk);
  border-color: var(--rule-firm);
}
.btn-google:hover { background: var(--stand-hi); }

/*
 * Nothing that refuses to wrap may sit beside flexible content.
 *
 * A button with `white-space: nowrap` makes its min-content width a floor that
 * the parent, then the grid, then the document all have to honour. That is
 * literally where the three pixels of sideways scroll came from. Buttons wrap.
 */
.btn { white-space: normal; text-wrap: balance; }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--tap-gap); }

/* ----------------------------------------------------------------- forms */

.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field label {
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--chalk-2);
}
.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: var(--tap);
  padding: var(--space-3) var(--space-5);
  background: var(--pitch);
  color: var(--chalk);
  border: var(--border) solid var(--rule-firm);
  border-radius: var(--radius);
  font-size: var(--text-md);
  transition: border-color var(--dur-fast) var(--ease-out);
}
.field input::placeholder { color: var(--chalk-3); }
.field input:hover { border-color: var(--chalk-3); }
.field input:focus-visible { outline: none; box-shadow: var(--focus-ring); border-color: var(--floodlight); }

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

.foot { border-top: var(--border) solid var(--hairline); background: var(--stand); }

.foot-top {
  max-width: var(--maxw);
  margin-inline: auto;
  padding: var(--space-11) var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-7);
  flex-wrap: wrap;
  border-bottom: var(--border) solid var(--hairline);
}
.foot-cta { min-width: 0; }
.foot-cta .display { font-size: var(--text-3xl); }
.foot-cta p {
  margin: 0 0 var(--space-1);
  color: var(--floodlight-hi);
  font-family: var(--hand);
  font-size: var(--text-2xl);
  font-weight: 600;
}

.foot-inner {
  max-width: var(--maxw);
  margin-inline: auto;
  padding: var(--space-9) var(--gutter) calc(var(--space-9) + env(safe-area-inset-bottom, 0px));
  display: grid;
  gap: var(--space-8);
}
.foot-cols {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-7);
  padding-bottom: var(--space-8);
  border-bottom: var(--border) solid var(--hairline);
}
.foot-col h4 {
  margin: 0 0 var(--space-4);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--chalk);
}
.foot-col a {
  display: block;
  padding: var(--space-2) 0;
  font-size: var(--text-sm);
  color: var(--chalk-2);
}
.foot-col a:hover { color: var(--chalk); }
/* The cookie settings control is a button, because it opens something rather
   than going somewhere, dressed as the links around it. */
.foot-link {
  display: block;
  padding: var(--space-2) 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--text-sm);
  color: var(--chalk-2);
  cursor: pointer;
  text-align: left;
}
.foot-link:hover { color: var(--chalk); }

.socials { display: flex; gap: var(--space-3); margin-top: var(--space-2); }
.socials a {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border: var(--border) solid var(--rule);
  border-radius: 50%;
  color: var(--chalk-2);
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.socials a:hover { color: var(--chalk); border-color: var(--rule-firm); }
.socials svg { width: 15px; height: 15px; }

.foot-brand { display: inline-flex; align-items: center; gap: var(--space-4); color: var(--chalk-2); }
.foot-brand .wordmark { font-size: var(--text-2xl); }
.foot-about { max-width: 60ch; margin: var(--space-4) 0 0; font-size: var(--text-sm); color: var(--chalk-3); }
.foot-stats { display: flex; gap: var(--space-9); flex-wrap: wrap; }
.foot-stats div b {
  display: block;
  font-family: var(--display);
  font-weight: var(--weight-bold);
  font-size: var(--text-xl);
  font-variation-settings: 'wdth' var(--condensed);
}
.foot-stats div span { font-size: var(--text-xs); color: var(--chalk-3); }

/*
 * Where we think the reader is.
 *
 * Stated, not asked. Nobody arrives at a football site wanting to pick a
 * country out of a list of forty, and a control that has to be used before
 * the page is right is a page that is wrong by default. The device already
 * knows, so this is a sentence rather than a form.
 */
.region-pick {
  margin-top: var(--space-6);
  font-size: var(--text-xs);
  color: var(--chalk-3);
}
.region-pick b { color: var(--chalk-2); font-weight: var(--weight-medium); }

.foot-note {
  margin: 0;
  max-width: 76ch;
  font-size: var(--text-xs);
  line-height: var(--leading-normal);
  color: var(--chalk-3);
}
.foot-note a { color: var(--chalk-2); text-decoration: underline; text-underline-offset: 2px; }
.foot-note a:hover { color: var(--chalk); }

@media (max-width: 760px) {
  .foot-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); }
  .foot-stats { gap: var(--space-7); }
}

/* ------------------------------------------------------------ utilities */

.spinner {
  padding: var(--space-12) 0;
  text-align: center;
  color: var(--chalk-3);
  font-size: var(--text-sm);
}
.empty {
  padding: var(--space-9) var(--space-7);
  text-align: center;
  color: var(--chalk-2);
  background: var(--stand);
  border: var(--border) solid var(--rule);
  border-radius: var(--radius);
}
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.stack { display: flex; flex-direction: column; }
.rows { display: flex; flex-direction: column; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/*
 * Today's tally, in the header: how many calls landed and missed so far. It
 * is the one number a returning reader wants on every page, and it is a link
 * to the record. Hidden until there is something to count.
 */
.tally {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px var(--space-3);
  border: var(--border) solid var(--hairline);
  border-radius: var(--radius-sm);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  color: var(--chalk-3);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.tally b { font-weight: var(--weight-black); color: var(--chalk); }
.tally b.won { color: var(--won); }
.tally b.live { color: var(--lost); }
.tally:hover { color: var(--chalk-2); border-color: var(--rule); }



/* ------------------------------------------------------------ typesetting */

/*
 * The rules a typesetter applies by hand, applied everywhere.
 *
 * Headlines are balanced, so a two-line headline breaks into two lines of
 * similar length instead of a full line and an orphaned word. Paragraphs are
 * set "pretty", which stops a single word sitting alone on the last line.
 * Punctuation hangs, so a paragraph that opens with a quote mark keeps its
 * left edge on the letters. Numbers in data are equal width everywhere,
 * through the figures font for the display face and the tnum feature for
 * Geist.
 */
h1, h2, h3, h4, .display, .freecall-sel, .row-sel, .verdict-head .sel { text-wrap: balance; }
p, li, dd, figcaption, blockquote { text-wrap: pretty; hanging-punctuation: first allow-end last; }
table, .tbl, .odds, .price, .row-goals, .slip-odds, .mc-count, [data-countdown] {
  font-feature-settings: var(--features-data);
  font-variant-numeric: tabular-nums lining-nums;
}


/*
 * Reading text. The pundit's paragraphs are the product, so they are set to
 * be read: a size up from the interface, generous leading, a measure of
 * about sixty-six characters, and hyphenation (British English, set on the
 * <html> element) so a narrow phone column keeps an even right edge instead
 * of a ragged one with rivers in it.
 */
.narrative, .why p, .prose p, .prose li, .recap-why p, .read p {
  font-size: var(--text-read);
  line-height: var(--leading-read);
  max-width: var(--measure);
  hyphens: auto;
  -webkit-hyphens: auto;
  hyphenate-limit-chars: 7 3 3;
}
.read p { font-size: var(--text-md); line-height: var(--leading-normal); }

/*
 * Capitals, when a label is set in them, need air: they were drawn to sit
 * beside lower case and crowd each other alone. One tracking value for all of
 * them, and the size a step down so a label never shouts over its content.
 */
.panel-head span, .mark, .live-badge, .plan-tag, .track, .freecall-tag, .rep-heads { letter-spacing: var(--tracking-caps); }

/*
 * The display face's own figures sit a hair high against its capitals;
 * nudging a big number down by a fraction of an em puts it on the same
 * optical baseline as a team name beside it.
 */
.row-goals, .fx-line .gf { position: relative; top: 0.02em; }

/* Trim the half-leading off the wordmark so it centres in the header on its
   capitals, not on its line box. Progressive: ignored where unsupported. */
@supports (text-box: trim-both cap alphabetic) {
  .wordmark { text-box: trim-both cap alphabetic; }
}
