/* Sections, in order: Colours, Base, Layout and navigation, Text, Controls,
   Filter forms, Tables, Values in tables and figures, Listings and their pages,
   Standings and clubs, Player page, Championship, Championship round,
   Narrow screens. */

@font-face {
  font-family: Inter;
  src: url("/static/inter.236018d7b12608e4.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}

/* The headings' face: condensed, as a scoreboard is. One weight, the only one
   they use. */
@font-face {
  font-family: "Barlow Semi Condensed";
  src: url("/static/barlow-semi-condensed.9d06ad80d61aee6d.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}

/* ==== Colours ==== */

/* Every colour the site uses is named here, once per theme; the rules below
   only refer to these names. The light theme is the default, and the dark one
   applies once the visitor picks it. The site's two colours come from the
   table: its green, and the orange of the ball for what needs the eye (the
   keyboard's place, a table's order). */
:root {
  color-scheme: light;

  --bg: #e8ece6;
  --surface: #fff;
  --surface-hover: #f2f6f1;
  --text: #15241f;
  --text-muted: #56675f;
  --text-faint: #5b6a63;
  --border: #e3e9e4;
  --border-strong: #c9d4cd;
  --pane-line: #bfccc3;
  --shadow: 0 1px 2px rgb(20 40 30 / 5%), 0 2px 8px rgb(20 40 30 / 4%);

  --accent: #176447;
  --accent-hover: #0e4631;
  --on-accent: #fff;
  --ball: #d8650b;

  --nav-bg: #0f4637;
  --nav-fg: rgb(255 255 255 / 70%);
  --nav-fg-strong: #fff;
  --nav-hover: rgb(255 255 255 / 6%);
  --nav-current: rgb(255 255 255 / 13%);
  --nav-current-shadow: inset 0 0 0 1px rgb(255 255 255 / 10%), 0 1px 2px rgb(0 0 0 / 15%);
  --nav-line: rgb(0 0 0 / 12%);

  --gain: #176447;
  --loss: #b42318;
  --win-row: #ecf7ef;
  --win-row-hover: #e1f2e6;
  --loss-row: #fcefee;
  --loss-row-hover: #f9e2e0;
  --playoff: #765600;
  --playoff-row: #fff3c4;
  --chip-bg: #edf1ed;

  --notice-bg: #fff3c4;
  --notice-fg: #4a421f;
  --notice-border: #e6cf8a;

  color: var(--text);
  background: var(--bg);
  font-family: Inter, system-ui, sans-serif;
  font-synthesis: none;
  line-height: 1.5;
}

/* The dark theme. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0e1513;
  --surface: #151f1c;
  --surface-hover: #1b2824;
  --text: #e3ebe7;
  --text-muted: #9fb0a8;
  --text-faint: #87988f;
  --border: #243330;
  --border-strong: #354842;
  --pane-line: var(--border);
  --shadow: 0 1px 2px rgb(0 0 0 / 30%);

  --accent: #6fd0a0;
  --accent-hover: #a2e4c3;
  --on-accent: #07261a;
  --ball: #ff9a45;

  --nav-bg: #0b2d23;
  --nav-line: rgb(255 255 255 / 6%);
  --gain: #6fd0a0;
  --loss: #ff8f84;
  --win-row: rgb(111 208 160 / 7%);
  --win-row-hover: rgb(111 208 160 / 12%);
  --loss-row: rgb(255 143 132 / 7%);
  --loss-row-hover: rgb(255 143 132 / 12%);
  --playoff: #f1d36f;
  --playoff-row: #3a3214;
  --chip-bg: #22322d;

  --notice-bg: #3a3214;
  --notice-fg: #f1e3a8;
  --notice-border: #5f5220;
}

/* ==== Base ==== */

* {
  box-sizing: border-box;
}

/* The layout is made for the narrowest phones; below them, the page scrolls
   rather than squeezes. */
body {
  min-width: 20rem;
  margin: 0;
}

/* The headings and the site's name are set apart by their face; the text and
   the figures keep Inter. The condensed face runs smaller than Inter at a size,
   so its sizes are larger for the same weight on the page. */
h1,
h2,
.brand {
  font-family: "Barlow Semi Condensed", Inter, system-ui, sans-serif;
  font-weight: 600;
}

/* A step above the section headings, as they are above the text. */
h1 {
  margin: 0;
  font-size: clamp(1.35rem, 2.4vw, 1.5rem);
  line-height: 1.2;
}

h2 {
  margin-top: 1.5rem;
  font-size: 1.35rem;
}

a {
  color: var(--accent);
  text-decoration: none;
  text-underline-offset: 0.2em;
}

a:hover {
  color: var(--accent-hover);
  text-decoration: underline;
}

/* Read by assistive technology, not drawn. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Controls that need scripts wait for them; the submit buttons stand in for
   them until then, and step aside once they run. */
html:not(.js) .needs-js,
.js .filter-submit {
  display: none;
}

/* The ring marks where the keyboard is, so it is drawn where a pointer would
   not have put it. */
input:focus-visible,
select:focus-visible,
button:focus-visible,
a:focus-visible,
.table-wrap:focus-visible {
  outline: 3px solid var(--ball);
  outline-offset: 3px;
}

/* Only a slow request dims what it replaces: a fast one is swapped before the
   delay runs out, so it neither fades nor repaints. */
.htmx-request {
  opacity: 0.65;
  transition: opacity 0s 0.2s;
}

/* ==== Layout and navigation ==== */

/* The way past the navigation for a visitor who would otherwise tab through it
   on every page. It waits off-screen until the keyboard reaches it. */
.skip-link {
  position: absolute;
  top: 0.5rem;
  left: -100vw;
  z-index: 1;
  padding: 0.6rem 1rem;
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--surface);
}

.skip-link:focus {
  left: 0.5rem;
}

.site-shell {
  display: grid;
  grid-template-columns: 13.5rem minmax(0, 1fr);
  min-height: 100vh;
}

/* The navigation is the table's green. */
.site-nav {
  display: flex;
  position: sticky;
  top: 0;
  flex-direction: column;
  align-self: start;
  min-height: 100vh;
  padding: 1.1rem 1.25rem;
  color: var(--nav-fg-strong);
  border-right: 1px solid var(--nav-line);
  background: var(--nav-bg);
}

.mobile-about,
.mobile-nav,
.mobile-sort,
.mobile-list-wrap,
.mobile-match-table,
.mobile-standing-cell,
.mobile-rounds,
.mobile-sets {
  display: none;
}

/* The content fills the pane's height, so a short page keeps its footer at
   the bottom of the window. */
.content-pane {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 100vh;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--nav-fg-strong);
  font-size: 1.3rem;
  text-decoration: none;
}

/* Barlow's capitals sit 0.05em below the middle of its line, so the logo is
   lowered as much to meet them. */
.brand img {
  translate: 0 0.05em;
}

.brand:hover {
  color: var(--nav-fg-strong);
  text-decoration: none;
}

/* The current page is lifted out of the column as a card; its neighbours
   stay muted until pointed at. */
.primary-nav {
  display: grid;
  gap: 1px;
  margin-top: 1.75rem;
  margin-left: -0.6rem;
}

.primary-nav a {
  padding: 0.45rem 0.6rem;
  border-radius: 6px;
  color: var(--nav-fg);
  font-size: 0.95rem;
  font-weight: 500;
  text-decoration: none;
  transition: color 0.12s, background-color 0.12s;
}

.primary-nav a:hover {
  color: var(--nav-fg-strong);
  background: var(--nav-hover);
  text-decoration: none;
}

.primary-nav a[aria-current="page"] {
  color: var(--nav-fg-strong);
  background: var(--nav-current);
  box-shadow: var(--nav-current-shadow);
}

/* The theme switch waits at the foot of the navigation, as quiet as its links. */
.theme-toggle {
  display: grid;
  place-items: center;
  width: 44px;
  min-height: 44px;
  margin: auto 0 0 -0.6rem;
  padding: 0;
  border: 0;
  border-radius: 6px;
  color: var(--nav-fg);
  background: transparent;
}

.theme-toggle:hover {
  color: var(--nav-fg-strong);
  background: var(--nav-hover);
}

.theme-toggle svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The icon shows the theme a press leads to. */
.theme-toggle .icon-sun,
[data-theme="dark"] .theme-toggle .icon-moon {
  display: none;
}

[data-theme="dark"] .theme-toggle .icon-sun {
  display: block;
}

.content-column {
  width: min(100%, 1100px);
  margin: 0 auto;
  padding-inline: clamp(1.25rem, 3vw, 2.5rem);
}

main {
  flex: 1 0 auto;
}

/* The page's own pane, parted from the rest by a hairline, as the navigation
   is by its colour: where the page sits, and what it is. */
.page-header {
  border-bottom: 1px solid var(--pane-line);
  background: color-mix(in srgb, var(--surface) 45%, var(--bg));
}

.page-header .content-column {
  padding-block: 1.25rem;
}

/* The trail ends at the page's parent: the title below names the page. */
.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  margin: 0 0 0.35rem;
  padding: 0;
  list-style: none;
  font-size: 0.875rem;
}

.breadcrumbs li + li::before {
  margin-inline: 0.45rem;
  color: var(--text-faint);
  content: "›";
}

.breadcrumbs a {
  color: var(--text-muted);
}

.breadcrumbs a:hover {
  color: var(--accent-hover);
}

.page-body {
  padding-block: 1.75rem 3rem;
}

.page-body > :first-child {
  margin-top: 0;
}

.notice {
  width: 100%;
  margin: 0;
  border-bottom: 1px solid var(--notice-border);
  color: var(--notice-fg);
  background: var(--notice-bg);
  font-size: 0.85rem;
}

.notice .content-column {
  padding-block: 0.7rem;
}

.site-footer {
  border-top: 1px solid var(--pane-line);
  color: var(--text-muted);
  font-size: 0.85rem;
}

.site-footer p {
  margin: 0;
}

.site-footer .content-column {
  padding-block: 1rem;
}

/* ==== Text ==== */

.error-message {
  max-width: 45rem;
  line-height: 1.65;
}

.prose {
  max-width: 42rem;
}

.prose h2 {
  margin-top: 1.75rem;
}

.prose p,
.prose ul {
  line-height: 1.7;
}

.intro-copy {
  max-width: 42rem;
  margin: 0;
  color: var(--text-muted);
  font-size: 1.05rem;
  line-height: 1.65;
}

.empty {
  padding: 1rem;
  color: var(--text-muted);
  text-align: center;
}

/* ==== Controls ==== */

input,
select,
button {
  min-height: 44px;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  color: inherit;
  font: inherit;
}

input,
select {
  min-width: 0;
  width: 100%;
  background: var(--surface);
}

input:hover,
select:hover {
  border-color: var(--text-faint);
}

button {
  padding-inline: 1.1rem;
  border-color: var(--accent);
  color: var(--on-accent);
  background: var(--accent);
  font-weight: 600;
  cursor: pointer;
}

button:hover {
  border-color: var(--accent-hover);
  background: var(--accent-hover);
}

/* ==== Filter forms ==== */

/* A filter form: the fields that narrow the rows, then any choice among a few. */
.filter-form {
  display: grid;
  gap: 0.75rem;
  margin: 1rem 0 0.5rem;
}

/* Where no field needs the width, the bar and the choice share a line. */
.filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
}

/* A choice among a few is one outlined control, as the bar is, its segments
   parted by hairlines and the chosen one marked as the phone's sort order is.
   Past what the width holds, it scrolls. */
.filter-segments {
  display: flex;
  min-width: 0;
  max-width: 100%;
  margin: 0;
  padding: 0;
  overflow-x: auto;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.filter-segments label {
  display: grid;
  place-items: center;
  min-height: 44px;
  padding: 0 0.9rem;
  color: var(--text-muted);
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
}

.filter-segments label + input + label {
  border-left: 1px solid var(--border);
}

.filter-segments label:hover {
  color: var(--text);
  background: var(--surface-hover);
}

.filter-segments input:checked + label {
  color: var(--accent);
  background: var(--surface-hover);
  font-weight: 650;
}

/* The radio itself is not drawn, so its segment shows where the keyboard is.
   The control's box would hide a ring drawn outside the segment. */
.filter-segments input:focus-visible + label {
  outline: 3px solid var(--ball);
  outline-offset: -3px;
}

/* The fields are one outlined bar, parted by hairlines. */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  overflow: hidden;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.filter-bar > * + * {
  border-left: 1px solid var(--border);
}

/* Inside the bar, a field's own box gives way to the bar's, and the bar's box
   would hide a ring drawn outside its parts. A checkbox is too small to hold
   one, and leaves room around it for its own. */
.filter-bar input:not([type="checkbox"]),
.filter-bar select {
  border: 0;
  border-radius: 0;
  background: transparent;
}

.filter-bar :focus-visible:not([type="checkbox"]) {
  outline-offset: -3px;
}

.filter-search {
  display: flex;
  flex: 1 1 14rem;
  align-items: center;
  padding-left: 0.8rem;
}

.filter-search-icon {
  flex: none;
  fill: none;
  stroke: var(--text-faint);
  stroke-width: 2;
  stroke-linecap: round;
}

.filter-search input {
  padding-left: 0.6rem;
}

/* A list drawn as the site's other fields, its arrow in the search's icon
   style. */
.filter-select {
  position: relative;
  display: flex;
  align-items: center;
}

.filter-select select {
  padding-right: 2.4rem;
  font-variant-numeric: tabular-nums;
  appearance: none;
  cursor: pointer;
}

.filter-select-icon {
  position: absolute;
  right: 0.8rem;
  fill: none;
  stroke: var(--text-faint);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

/* A checkbox sits beside its label and keeps the hit area of a form control. */
.filter-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  padding: 0 0.9rem;
}

.filter-toggle input {
  width: 1.15rem;
  height: 1.15rem;
  min-height: 0;
  margin: 0;
  padding: 0;
  accent-color: var(--accent);
}

.filter-submit {
  border-radius: 0;
}

/* ==== Tables ==== */

/* A wide table is read by scrolling it, which the keyboard can only do once the
   box holding it can be focused. */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

table {
  width: 100%;
  border-collapse: collapse;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  line-height: 1.35;
}

/* Tabular figures would space a date's hyphens as wide as its digits. */
td.date {
  font-variant-numeric: normal;
}

th,
td {
  padding: 0.8rem;
  border-bottom: 1px solid var(--border);
  text-align: center;
}

tbody tr:last-child td {
  border-bottom: 0;
}

/* Headers label the columns and step back from the rows they label. */
th {
  color: var(--text-muted);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: normal;
  border-bottom-color: var(--border-strong);
}

/* A raised superscript otherwise grows its cell's line box, which drops that
   header below the ones beside it. */
th sup {
  line-height: 0;
}

tbody tr:hover {
  background: var(--surface-hover);
}

/* Names in a table are its links; they read as text until pointed at. */
td a {
  color: var(--text);
  font-weight: 500;
}

td a:hover {
  color: var(--accent);
}

.name {
  text-align: left;
}

.rank,
.affiliation {
  text-align: center;
  white-space: nowrap;
}

td.rank {
  color: var(--text-faint);
}

td.affiliation {
  color: var(--accent);
  font-weight: 700;
}

td.rank,
td.affiliation {
  width: 3em;
}

.number {
  text-align: right;
}

.compact-table th,
.compact-table td {
  padding: 0.35rem 0.65rem;
  vertical-align: middle;
}

/* The table's box gives its edge columns a margin of their own. */
.compact-table th:first-child,
.compact-table td:first-child {
  padding-left: 1rem;
}

.compact-table th:last-child,
.compact-table td:last-child {
  padding-right: 1rem;
}

/* A header that reorders its table reads as a header, not as a link among the
   rows. Its link fills the cell, so the whole header takes the click, and keeps
   its arrow beside it. The arrow repeats `aria-sort`, so it is kept from screen
   readers. */
.compact-table th.sortable {
  padding: 0;
}

.compact-table th.sortable a {
  display: block;
  padding: 0.35rem 0.65rem;
  color: inherit;
  font-weight: inherit;
  white-space: nowrap;
}

.compact-table th.sortable:first-child a {
  padding-left: 1rem;
}

.compact-table th.sortable:last-child a {
  padding-right: 1rem;
}

.compact-table th.sortable a:hover {
  color: var(--text);
  background: var(--surface-hover);
  text-decoration: none;
}

.compact-table th[aria-sort] a {
  color: var(--text);
}

/* The table's box clips a ring drawn outside the cell. */
.compact-table th.sortable a:focus-visible {
  outline-offset: -3px;
}

th[aria-sort="ascending"] a::after {
  content: " ↑" / "";
  color: var(--ball);
}

th[aria-sort="descending"] a::after {
  content: " ↓" / "";
  color: var(--ball);
}

/* ==== Values in tables and figures ==== */

.points-decimal.muted {
  color: var(--text-faint);
  font-weight: 500;
}

/* A classement is a label more than a quantity: a chip, scanned down the column. */
.classification {
  display: inline-block;
  min-width: 2.4em;
  padding: 0.05em 0.45em;
  border-radius: 999px;
  background: var(--chip-bg);
  font-size: 0.85em;
  font-weight: 600;
  text-align: center;
}

/* A change says which way it went, in the standing and in the history alike. */
.change-gain {
  color: var(--gain);
}

.change-loss {
  color: var(--loss);
}

/* Nothing gained or lost, and nothing to read closely: grey says so. */
.change-zero {
  color: var(--text-faint);
}

.family-name {
  font-synthesis: small-caps;
  font-variant-caps: small-caps;
}

/* A walkover or a withdrawn player: a side, but no one to read about. */
.placeholder {
  color: var(--text-faint);
}

/* ==== Listings and their pages ==== */

/* The notes on a table, above or below it: what it holds, how to read it, and
   where the next page is. They are drawn on the page rather than on a card, a
   step below the tables and fields, in one size and colour, their text in line
   with the text of the table's first column. */
.listing-bar,
.standings-legend {
  --note-inset: calc(1rem + 1px);

  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 1.25rem;
  min-height: 2.25rem;
  margin: 0.25rem 0;
  padding-inline: var(--note-inset);
  color: var(--text-muted);
  font-size: 0.8125rem;
}

/* The count at its start, the page turners at its end. The line keeps the
   height of the turners whether or not it has them, so the rows below never
   move. */
.listing-bar {
  justify-content: space-between;
}

/* Under a heading, the line keeps the same distance below it whatever the
   heading's own margin, and sits closer to the table it counts. */
h2 + .listing-bar {
  min-height: 0;
  margin: 1.125rem 0 0.5rem;
}

/* The page turners and the page between them. A turner is a round button of its
   own, its ring set in the inset so its arrow ends in line with the table's
   last column. */
.pager {
  display: inline-flex;
  align-items: center;
  margin-right: -0.5rem;
}

.pager-position {
  padding: 0 0.35rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.pager-button {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  color: var(--accent);
  font-size: 1.25rem;
  line-height: 1;
}

a.pager-button:hover {
  color: var(--accent-hover);
  background: color-mix(in srgb, var(--text) 7%, transparent);
  text-decoration: none;
}

/* A turner with no page that way keeps its place, spent. */
span.pager-button {
  color: var(--border-strong);
}

/* ==== Standings and clubs ==== */

/* A reordered table, or another page of it, holds other rows: its columns keep
   the widths the headers give them rather than follow the rows, and names wrap
   instead. Below its minimum width, the table scrolls rather than squeezes. */
.standings-table,
.clubs-table {
  table-layout: fixed;
}

.standings-table {
  min-width: 34rem;
}

.clubs-table {
  min-width: 26rem;
}

.standings-table td.name,
.clubs-table td.name {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* The figures are short, and the names beside them get the room they leave. */
.standings-table th.rank {
  width: 3.75rem;
}

.standings-table th.classement-column {
  width: 4.25rem;
}

.standings-table th.points-column {
  width: 5.75rem;
}

.clubs-table th.affiliation {
  width: 8rem;
}

.clubs-table th.number {
  width: 7rem;
}

/* ==== Player page ==== */

.standing-missing {
  max-width: 45rem;
  margin: 0;
  color: var(--text-muted);
}

/* Says that the figures marked were not published, so they are not read as
   the official ranking of a phase that does not carry this player. */
.standing-note {
  max-width: 45rem;
  margin: 0.5rem 0 0;
  color: var(--text-muted);
  font-size: 0.875rem;
}

.declared-mark {
  margin-left: 0.1em;
  color: var(--text-muted);
}

/* The row a link from a ranking or a match lands on, marked on its edge. */
.player-standings tr {
  scroll-margin-top: 1rem;
}

.player-standings tr:target {
  background: var(--surface-hover);
}

.player-standings tr:target td:first-child {
  box-shadow: inset 3px 0 0 var(--accent);
}

.section-heading {
  margin: 1.75rem 0 0.5rem;
}

.match-history .participant {
  min-width: 140px;
  white-space: normal;
}

/* The competition names the context of a match, not what the row is read for. */
.match-history td.competition {
  color: var(--text-muted);
  font-size: 0.875rem;
  text-align: left;
}

/* Matches of one day are one group; a firmer rule starts the next. */
.match-history tr.date-separator td {
  border-top: 2px solid var(--border-strong);
}

/* The change a match made is what the row is read for; the opponent's
   classement beside it stays plain, as it does in the standings. */
.match-history td.change,
.player-standings td.change {
  font-weight: 700;
}

/* Each match tints its row with its result, so a run of wins or losses reads
   down the table. */
.match-history tr.match-win {
  background: var(--win-row);
}

.match-history tr.match-loss {
  background: var(--loss-row);
}

.match-history tr.match-win:hover {
  background: var(--win-row-hover);
}

.match-history tr.match-loss:hover {
  background: var(--loss-row-hover);
}

td.outcome {
  font-weight: 600;
}

.match-win td.outcome,
.match-win .outcome {
  color: var(--gain);
}

.match-loss td.outcome,
.match-loss .outcome {
  color: var(--loss);
}

/* ==== Championship ==== */

/* The rank and the points take no more room than their figures; the teams get
   the rest. */
.division-standings th.rank,
.division-standings td.rank,
.division-standings th.number,
.division-standings td.number,
.division-standings th.outcome,
.division-standings td.outcome {
  width: 1%;
  white-space: nowrap;
}

/* The whole cell takes the outcome's colours; the legend, only its code. */
.standing-outcome {
  font-weight: 600;
  white-space: nowrap;
}

.standing-outcome.promotion {
  color: var(--gain);
  background: var(--win-row);
}

.standing-outcome.playoff {
  color: var(--playoff);
  background: var(--playoff-row);
}

.standing-outcome.relegation {
  color: var(--loss);
  background: var(--loss-row);
}

.division-standings .outcome {
  text-align: center;
}

.standings-legend {
  list-style: none;
}

.standings-legend .standing-outcome {
  background: none;
}

/* Each round is its own body; a firmer rule sets it off from the one before. */
.team-matches tbody + tbody {
  border-top: 2px solid var(--border-strong);
}

/* A round's number and date belong to its first row but reach down to its
   last, so the rule that spares the table's last row a border misses them. */
.team-matches tbody:last-child :is(td.round, td.date) {
  border-bottom: 0;
}

.team-matches td.round {
  width: 3em;
  color: var(--text);
  font-weight: 700;
}

.team-matches td.date {
  color: var(--text-muted);
}

.team-matches td.round,
.team-matches td.date {
  background: var(--surface);
}

.team-matches .score {
  font-weight: 600;
  text-align: center;
}

.team-matches .team-home {
  text-align: right;
}

.team-matches .team-away {
  text-align: left;
}

.team-matches .winner,
.team-matches .winner a {
  font-weight: 700;
}

.team-matches .forfeit {
  color: var(--text-faint);
  font-weight: normal;
}

/* ==== Championship round ==== */

/* Each encounter is a card: its teams and score head the sheet of its games. */
.encounter {
  margin: 1rem 0 1.5rem;
  padding: 1rem 0 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow);
  scroll-margin-top: 1rem;
  overflow: hidden;
}

.encounter:target {
  border-color: var(--accent);
}

.encounter-teams {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: baseline;
  gap: 0.75rem;
  margin: 0;
  padding: 0 1rem;
  font-size: 1.3rem;
}

.encounter-teams .team-home {
  text-align: right;
}

.encounter-teams .score {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.encounter-teams a {
  color: var(--text);
}

.encounter .winner,
.encounter .winner a {
  font-weight: 700;
}

/* Winning and losing teams read in the colours of the match history, on the
   division's fixtures as on its rounds. */
:is(.encounter-teams, .team-matches) .winner,
:is(.encounter-teams, .team-matches) .winner a {
  color: var(--gain);
}

:is(.encounter-teams, .team-matches) .loser,
:is(.encounter-teams, .team-matches) .loser a {
  color: var(--loss);
}

.encounter-games td.winner {
  background: var(--win-row);
}

.encounter-games td.loser {
  background: var(--loss-row);
}

.encounter .forfeit {
  color: var(--text-faint);
  font-weight: normal;
}

.encounter-date {
  margin: 0.25rem 0 0.75rem;
  color: var(--text-muted);
  font-size: 0.875rem;
  text-align: center;
}

.encounter > .empty {
  margin: 0;
  padding: 0 1rem 1rem;
  text-align: center;
}

/* The sheet sits flush in its card, which already draws the box. */
.encounter .table-wrap {
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
  box-shadow: none;
}

/* Fixed columns line the sheets of a round up, card after card. Below its
   minimum width a sheet scrolls rather than break names mid-word. */
.encounter-games {
  table-layout: fixed;
  min-width: 36rem;
}

.encounter-games td.name {
  white-space: normal;
}

.encounter-games .rank {
  width: 3.25rem;
}

.encounter-games .team-home {
  text-align: right;
}

.encounter-games .score {
  width: 4.5rem;
  font-weight: 600;
}

.encounter-games .set {
  width: 3rem;
  font-weight: 600;
}

/* ==== Narrow screens ==== */

@media (max-width: 800px) {
  .site-shell {
    display: block;
  }

  /* The navigation takes the top of the window, so the pane no longer fills it. */
  .content-pane {
    min-height: 0;
  }

  .site-nav {
    display: grid;
    position: static;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.5rem;
    min-height: 0;
    padding: 0.75rem 1.25rem 0.25rem;
    border-right: 0;
    border-bottom: 1px solid var(--nav-line);
  }

  .primary-nav {
    display: flex;
    grid-column: 1 / -1;
    grid-row: 2;
    flex-wrap: wrap;
    margin: 0 0 0 -0.65rem;
  }

  .primary-nav a {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0.5rem 0.65rem;
  }

  .theme-toggle {
    grid-column: 2;
    grid-row: 1;
    margin: 0;
  }

  .page-header .content-column {
    padding-block: 1rem;
  }

  .page-body {
    padding-top: 1.5rem;
  }
}

@media (max-width: 600px) {
  :root {
    background: var(--nav-bg);
    overflow: hidden;
  }

  /* The shell scrolls while the navigation stays in the page's layout. */
  body {
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
    background: var(--bg);
  }

  .site-shell {
    flex: 1 1 auto;
    min-height: 0;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior-y: contain;
  }

  .site-nav {
    grid-template-columns: minmax(0, 1fr) auto auto;
    gap: 0.25rem;
    padding: 0.5rem 0.75rem;
  }

  .primary-nav {
    display: none;
  }

  .mobile-about {
    display: grid;
    grid-column: 2;
    grid-row: 1;
    place-items: center;
    min-height: 44px;
    padding: 0 0.5rem;
    border-radius: 6px;
    color: var(--nav-fg);
    font-size: 0.875rem;
  }

  .mobile-about:is(:hover, [aria-current="page"]) {
    color: var(--nav-fg-strong);
    background: var(--nav-hover);
    text-decoration: none;
  }

  .theme-toggle {
    grid-column: 3;
  }

  .mobile-nav {
    display: grid;
    flex: none;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    padding: 0.25rem 0.5rem;
    border-top: 1px solid var(--nav-line);
    background: var(--nav-bg);
    box-shadow: 0 -2px 12px rgb(0 0 0 / 10%);
  }

  .mobile-nav a {
    display: grid;
    place-items: center;
    min-height: 3.25rem;
    border-radius: 8px;
    color: var(--nav-fg);
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
  }

  .mobile-nav a[aria-current="page"] {
    color: var(--nav-fg-strong);
    background: var(--nav-current);
    box-shadow: var(--nav-current-shadow);
  }

  .mobile-nav a:not([aria-current="page"]):hover {
    color: var(--nav-fg-strong);
    background: var(--nav-hover);
    text-decoration: none;
  }

  .content-column {
    padding-inline: 0.75rem;
  }

  /* On a narrow screen the search takes a row of its own, above the rest. */
  .filter-search {
    flex-basis: 100%;
  }

  .filter-search ~ * {
    flex: 1 1 auto;
    border-top: 1px solid var(--border);
  }

  .filter-search + * {
    border-left: 0;
  }

  .mobile-sort {
    display: block;
    margin: 0.5rem 0;
  }

  /* The label reads as a note on the list, as its count does above it. */
  .mobile-sort > span {
    display: block;
    margin-bottom: 0.3rem;
    padding-inline: calc(0.75rem + 1px);
    color: var(--text-muted);
    font-size: 0.8125rem;
  }

  .mobile-sort-options {
    display: flex;
    overflow: hidden;
    border: 1px solid var(--border-strong);
    border-radius: 8px;
    background: var(--surface);
    box-shadow: var(--shadow);
  }

  .mobile-sort-options a {
    display: grid;
    flex: 1 1 0;
    place-items: center;
    min-width: 0;
    min-height: 44px;
    padding: 0.35rem 0.2rem;
    color: var(--text);
    font-size: 0.75rem;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
  }

  .mobile-sort-options a:last-child {
    flex-grow: 1.5;
  }

  .mobile-sort-options a + a {
    border-left: 1px solid var(--border);
  }

  .mobile-sort-options a:hover {
    background: var(--surface-hover);
  }

  .mobile-sort-options a[aria-current="true"] {
    color: var(--accent);
    background: var(--surface-hover);
    font-weight: 650;
  }

  /* The phone's cards take their text in by less than the tables. */
  .listing-bar,
  .standings-legend {
    --note-inset: calc(0.75rem + 1px);
  }

  .mobile-list-wrap {
    display: block;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    box-shadow: var(--shadow);
  }

  .mobile-list-heading {
    display: grid;
    gap: 0.6rem;
    padding: 0.4rem 0.75rem;
    border-bottom: 1px solid var(--border-strong);
    color: var(--text-muted);
    font-size: 0.75rem;
    font-weight: 600;
  }

  .mobile-list-heading span:last-child {
    text-align: right;
  }

  .mobile-player-list-heading,
  .mobile-player-list a {
    grid-template-columns: 2rem minmax(0, 1fr) auto;
  }

  .mobile-player-list-heading span:first-child {
    text-align: center;
  }

  .mobile-club-list-heading,
  .mobile-club-list a {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .mobile-list {
    display: block;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .mobile-match-table {
    display: block;
  }

  .desktop-match-table {
    display: none;
  }

  .mobile-match-table table {
    table-layout: auto;
  }

  .mobile-match-table .match-history td {
    padding-block: 0.55rem;
    vertical-align: top;
  }

  .mobile-match-table .match-history :is(th, td) {
    padding-inline: 0.35rem;
  }

  .mobile-match-table .match-history :is(th, td):first-child {
    padding-left: 0.65rem;
  }

  .mobile-match-table .match-history :is(th, td):last-child {
    padding-right: 0.65rem;
  }

  .mobile-match-table .participant {
    min-width: 0;
    overflow-wrap: anywhere;
  }

  .mobile-match-context span,
  .mobile-match-opponent,
  .mobile-match-table .competition,
  .mobile-match-table .outcome,
  .mobile-match-table .change {
    display: block;
  }

  .mobile-match-context span:last-child,
  .mobile-match-table .competition {
    color: var(--text-muted);
    font-size: 0.75rem;
  }

  .mobile-match-context,
  .mobile-match-table td.number {
    white-space: nowrap;
  }

  .mobile-match-table .competition {
    margin-top: 0.2rem;
  }

  .mobile-match-table .competition a {
    color: inherit;
    font-weight: inherit;
  }

  .mobile-match-table .classification {
    margin-left: 0.3rem;
  }

  .mobile-match-table .outcome {
    font-size: 0.75rem;
    font-weight: 600;
  }

  .mobile-match-table .change {
    font-weight: 700;
    white-space: nowrap;
  }

  .mobile-list li + li {
    border-top: 1px solid var(--border);
  }

  .mobile-list a {
    display: grid;
    align-items: center;
    gap: 0.6rem;
    min-height: 3.75rem;
    padding: 0.45rem 0.75rem;
    color: var(--text);
    text-decoration: none;
  }

  .mobile-list a:hover {
    background: var(--surface-hover);
  }

  .mobile-player-rank {
    color: var(--text-faint);
    font-size: 0.85rem;
    text-align: center;
  }

  .mobile-player-main,
  .mobile-player-points,
  .mobile-club-main {
    display: grid;
    min-width: 0;
  }

  :is(.mobile-player-main, .mobile-club-main) strong {
    font-weight: 650;
    overflow-wrap: anywhere;
  }

  .mobile-player-meta {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.35rem;
    color: var(--text-muted);
    font-size: 0.8rem;
  }

  .mobile-club-meta {
    color: var(--text-muted);
    font-size: 0.8rem;
  }

  .mobile-club-players {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
  }

  .mobile-player-club {
    min-width: 0;
    overflow-wrap: anywhere;
  }

  .mobile-player-classification {
    flex: none;
    padding: 0 0.4em;
    border-radius: 999px;
    background: var(--chip-bg);
    font-weight: 600;
  }

  .mobile-player-points {
    display: block;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    white-space: nowrap;
  }

  .mobile-player-points small {
    display: block;
    color: var(--text-muted);
    font-size: 0.7rem;
    font-weight: 500;
    text-align: right;
  }

  .desktop-table,
  .desktop-match-table {
    display: none;
  }

  /* A trail link keeps a finger's reach, the pane's padding taking it in. */
  .breadcrumbs ol {
    margin: -0.75rem 0 -0.4rem;
  }

  .breadcrumbs li {
    display: flex;
    align-items: center;
  }

  .breadcrumbs a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  .player-standings-wrap {
    overflow-x: auto;
  }

  .player-standings {
    table-layout: fixed;
    white-space: normal;
  }

  .player-standings :is(th, td):not(.mobile-standing-cell) {
    display: none;
  }

  .player-standings .mobile-standing-cell {
    display: table-cell;
  }

  .player-standings :is(th, td).mobile-standing-phase {
    width: 38%;
    text-align: left;
  }

  .player-standings :is(th, td).mobile-standing-points {
    width: 39%;
    text-align: right;
  }

  .player-standings :is(th, td).mobile-standing-classification {
    width: 23%;
    text-align: right;
  }

  .player-standings th.mobile-standing-cell {
    padding-block: 0.4rem;
    font-size: 0.75rem;
  }

  .player-standings th.mobile-standing-cell .mobile-standing-subhead {
    display: block;
    font-size: 0.7rem;
    font-weight: 400;
  }

  .player-standings td.mobile-standing-cell {
    padding-block: 0.55rem;
    font-size: 0.83rem;
    vertical-align: top;
  }

  .player-standings td.mobile-standing-phase strong {
    display: block;
    white-space: nowrap;
  }

  .player-standings td.mobile-standing-phase a {
    display: block;
    color: var(--text-muted);
    font-size: 0.75rem;
    overflow-wrap: anywhere;
  }

  .mobile-standing-values {
    white-space: nowrap;
  }

  .player-standings td.mobile-standing-points > .change {
    display: block;
    font-size: 0.75rem;
    font-weight: 700;
  }

  .player-standings tr:target td.mobile-standing-phase {
    box-shadow: inset 3px 0 0 var(--accent);
  }

  /* A division's rounds are cards, each match a line of its teams either side
     of the score, as on the round's own page. */
  .mobile-rounds {
    display: grid;
    gap: 0.75rem;
  }

  .mobile-round {
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    box-shadow: var(--shadow);
  }

  .mobile-round-heading {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin: 0;
    padding: 0 0.75rem;
    border-bottom: 1px solid var(--border-strong);
    color: var(--text-muted);
    font-size: 0.8rem;
  }

  .mobile-round-heading a {
    display: flex;
    align-items: center;
    min-height: 44px;
    color: var(--text);
    font-size: 0.95rem;
    font-weight: 700;
  }

  .mobile-round ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .mobile-round li {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    gap: 0.5rem;
    padding: 0.2rem 0.75rem;
    font-size: 0.9rem;
  }

  .mobile-round li + li {
    border-top: 1px solid var(--border);
  }

  .mobile-round .team-home {
    text-align: right;
  }

  .mobile-round a {
    color: var(--text);
  }

  .mobile-round .score {
    display: grid;
    place-items: center;
    min-width: 3.5rem;
    min-height: 44px;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    white-space: nowrap;
  }

  .mobile-round .winner,
  .mobile-round .winner a {
    color: var(--gain);
    font-weight: 700;
  }

  .mobile-round .loser,
  .mobile-round .loser a {
    color: var(--loss);
  }

  .mobile-round .forfeit {
    color: var(--text-faint);
    font-weight: normal;
  }

  /* A game's sets leave their columns for a line under its score, so the
     sheet fits the screen. */
  .encounter-games {
    min-width: 0;
  }

  .encounter-games .rank {
    width: 2.25rem;
  }

  .encounter-games .score {
    width: 5.25rem;
    padding-inline: 0.15rem;
  }

  .encounter-games .set {
    display: none;
  }

  .encounter-games :is(th, td) {
    padding-inline: 0.4rem;
  }

  .mobile-sets {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0 0.25rem;
    font-size: 0.7rem;
    font-weight: 600;
  }

  .encounter-teams {
    gap: 0.5rem;
    padding-inline: 0.75rem;
    font-size: 1.15rem;
  }
}
