/* ==========================================================================
   Page-level surfaces: heroes, page headers, the 404.

   These were per-page Astro `<style>` blocks. global.css already lists .hero,
   .page-header and .notfound among the INVERTED surfaces — but that block only
   flips the accent tokens (which gold is readable, which focus ring to use). It
   never gave any of them a background, a colour or padding, because each page
   carried its own. Without this file a hero is correctly told "you are on navy"
   and then rendered on cream, which is exactly how it looked.

   Ported verbatim from BAD_DNU, comments included — the gold-400 note below is
   a contrast decision, not a preference.
   ========================================================================== */

/* --- Hero (home) -------------------------------------------------------- */
.hero {
  background: var(--color-bg-invert);
  color: var(--color-text-invert);
  padding-block: var(--space-3xl);
  border-bottom: 5px solid var(--color-accent);
}

.hero h1 {
  font-size: var(--text-4xl);
  margin-top: var(--space-sm);
}

.hero .accent {
  /* gold-400, not --color-accent (gold-500): the hero sits on navy, where the
     eyebrow above it and the dog in the mark are both gold-400. Two different
     golds stacked read as a mistake. Also 10.28:1 on navy against 7.13:1. */
  color: var(--gold-400);
}

.hero .lead {
  max-width: 46ch;
  margin-top: var(--space-lg);
  font-size: var(--text-lg);
  color: var(--color-text-invert-muted);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-top: var(--space-xl);
}

/* --- Page header (inner pages) ------------------------------------------ */
.page-header {
  background: var(--color-bg-invert);
  color: var(--color-text-invert);
  padding-block: var(--space-2xl);
  border-bottom: 5px solid var(--color-accent);
}

.page-header h1 {
  margin-top: var(--space-sm);
}

.page-header .lead {
  max-width: 60ch;
  margin-top: var(--space-md);
  color: var(--color-text-invert-muted);
  font-size: var(--text-lg);
}

/* --- 404 ---------------------------------------------------------------- */
.notfound {
  background: var(--color-bg-invert);
  color: var(--color-text-invert);
  min-height: 60vh;
  display: flex;
  align-items: center;
}

.notfound h1 {
  font-size: var(--text-4xl);
  margin-top: var(--space-xs);
}

.notfound .lead {
  margin-top: var(--space-md);
  color: var(--color-text-invert-muted);
  font-size: var(--text-lg);
  max-width: 44ch;
}

/* AND A LINK INSIDE THAT SENTENCE IS UNDERLINED. Surface-token table, rule 11:
   `.notfound` is on the invert list, which sets `--color-link` to the same cream
   as the surrounding text. That is right in the header and the footer, where
   every link is one of a row of them, and wrong for one link in a line of prose —
   it renders as ordinary body text: present, focusable, clickable, and
   indistinguishable.

   Phase 14 put the first such link on this surface: the 500 page invites
   somebody to say what they were doing, and the address it invites them to use
   is a link in the middle of a sentence. Same treatment as
   `.event-banner-live a`, which is where this was found the first time. */
.notfound .lead a {
  text-decoration: underline;
  text-underline-offset: 0.2em;
  font-weight: 600;
}

.notfound .lead a:hover {
  color: var(--color-accent-on-light);
}

.notfound p:last-child {
  margin-top: var(--space-xl);
}

/* --- Home: hero photos --------------------------------------------------- */
/* Landscape dock shot across the top so the jumping dog is not cropped, with
   the two square tiles side by side beneath it. */
.hero-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: var(--space-2xl);
  align-items: center;
}

.hero-title {
  font-size: var(--text-4xl);
  margin-top: var(--space-sm);
}

.hero-lead {
  max-width: 46ch;
  margin-top: var(--space-lg);
  font-size: var(--text-lg);
  color: var(--color-text-invert-muted);
}

.hero-photos {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
}

/* An EMPTY tile is a navy-on-navy frame with a gold corner, so a slot pending
   photography reads as intentional rather than broken. `.has-photo` strips all
   of that back to the image — the frame is scaffolding, not a mount. */
.photo-tile {
  position: relative;
  display: flex;
  align-items: flex-end;
  padding: var(--space-md);
  margin: 0;
  border: 1px dashed color-mix(in srgb, var(--gold-400) 45%, transparent);
  border-radius: var(--radius-lg);
  background: linear-gradient(
    135deg,
    var(--navy-800) 0%,
    var(--navy-700) 55%,
    var(--navy-800) 100%
  );
  overflow: hidden;
}

.photo-tile::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 3.5rem;
  height: 3.5rem;
  background: linear-gradient(
    225deg,
    color-mix(in srgb, var(--gold-500) 55%, transparent) 0%,
    transparent 60%
  );
}

.photo-tile.has-photo {
  padding: 0;
  border: 0;
  background: var(--navy-900);
}

.photo-tile.has-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-tile.has-photo::after {
  display: none;
}

.photo-full {
  grid-column: 1 / -1;
  aspect-ratio: 16 / 9;
}

.photo-half {
  aspect-ratio: 1 / 1;
}

/* --- Home: mission and vision -------------------------------------------- */
.purpose {
  background: var(--color-bg-alt);
  border-bottom: 1px solid var(--color-border);
}

.purpose-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--space-lg);
}

.purpose-card {
  padding: var(--space-xl);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-top: 5px solid var(--color-accent);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.purpose-title {
  font-size: var(--text-2xl);
  color: var(--color-brand);
  margin-top: var(--space-2xs);
}

.purpose-statement {
  margin-top: var(--space-md);
  font-size: var(--text-lg);
  line-height: var(--leading-snug);
  color: var(--color-text);
  text-wrap: pretty;
}

/* --- Home: values --------------------------------------------------------- */
.values {
  background: var(--color-surface-alt);
}

.section-title {
  font-size: var(--text-3xl);
  color: var(--color-brand);
  margin-top: var(--space-2xs);
  margin-bottom: var(--space-xl);
}

.value-grid {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: var(--space-lg);
}

.value-card {
  padding: var(--space-lg);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.value-number {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  /* gold-700, not gold-500: this is TEXT on a light ground, where gold-500 is
     2.2:1. `--color-accent-on-light` is the token that says so. */
  color: var(--color-accent-on-light);
}

.value-title {
  font-size: var(--text-xl);
  color: var(--color-brand);
  margin-top: var(--space-2xs);
}

.value-body {
  margin-top: var(--space-xs);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* --- Home: about and the signature series -------------------------------- */
.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--space-2xl);
  align-items: start;
}

.about-copy p {
  color: var(--color-text-muted);
  max-width: 62ch;
}

/* A navy card on a cream page. It carries `class="invert"` in the template —
   see rule 1 of the surface-token table in CLAUDE.md. Without it an outline
   button or a plain link dropped in here would render navy-on-navy. */
.signature {
  padding: var(--space-xl);
  border-radius: var(--radius-lg);
  background: var(--color-bg-invert);
  color: var(--color-text-invert);
  border-left: 5px solid var(--color-accent);
}

.signature .eyebrow {
  color: var(--gold-400);
}

.signature-title {
  font-size: var(--text-2xl);
  margin-top: var(--space-2xs);
}

.signature-body {
  margin-top: var(--space-sm);
  color: var(--color-text-invert-muted);
  font-size: var(--text-sm);
}

/* --- Sport cards (home preview and the sports index) --------------------- */
.sports-preview {
  background: var(--color-bg-alt);
  border-block: 1px solid var(--color-border);
}

.sport-grid {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: var(--space-lg);
}

.sport-card {
  border: 1px solid var(--color-border);
  border-top: 5px solid var(--color-accent);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition);
}

.sport-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
}

.sport-card a {
  display: block;
  padding: var(--space-xl);
  color: var(--color-text);
}

.sport-card h2,
.sport-card h3 {
  font-size: var(--text-2xl);
  color: var(--color-brand);
}

.sport-tagline {
  margin-top: var(--space-2xs);
  font-weight: 600;
  color: var(--color-accent-on-light);
}

.sport-summary,
.sport-card p {
  margin-top: var(--space-sm);
  color: var(--color-text-muted);
}

.sport-card-cta {
  display: inline-block;
  margin-top: var(--space-md);
  font-weight: 700;
  text-transform: uppercase;
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wide);
  color: var(--color-accent-on-light);
}

/* --- Home: the next-event card ------------------------------------------- */
.next-event-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xl);
  padding: var(--space-xl);
  border: 1px solid var(--color-border);
  border-left: 5px solid var(--color-accent);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-sm);
}

.next-event-title {
  font-size: var(--text-2xl);
  color: var(--color-brand);
  margin-top: var(--space-2xs);
}

.next-event-summary {
  margin-top: var(--space-sm);
  color: var(--color-text-muted);
  max-width: 56ch;
}

.next-event-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

/* --- Sport detail --------------------------------------------------------- */
.sport-hero {
  background: var(--color-bg-invert);
  color: var(--color-text-invert);
  padding-block: var(--space-2xl);
  border-bottom: 5px solid var(--color-accent);
}

.sport-title {
  font-size: var(--text-4xl);
  margin-top: var(--space-xs);
}

.sport-hero .sport-tagline {
  margin-top: var(--space-sm);
  font-size: var(--text-xl);
  color: var(--color-text-invert-muted);
  font-weight: 400;
}

.sport-hero-image {
  width: 100%;
  height: clamp(220px, 38vw, 460px);
  object-fit: cover;
}

.rules-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-top: var(--space-xl);
}

/* --- News ----------------------------------------------------------------- */
.post-header {
  background: var(--color-bg-invert);
  color: var(--color-text-invert);
  padding-block: var(--space-2xl);
  border-bottom: 5px solid var(--color-accent);
}

.post-title {
  font-size: var(--text-3xl);
  margin-top: var(--space-xs);
}

.post-meta {
  margin-top: var(--space-md);
  color: var(--color-text-invert-muted);
  font-size: var(--text-sm);
}

.empty-state {
  font-size: var(--text-lg);
  color: var(--color-text-muted);
}

.news-list {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--space-lg);
}

.news-card {
  border: 1px solid var(--color-border);
  border-left: 5px solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition);
}

.news-card:hover {
  transform: translateX(4px);
  box-shadow: var(--shadow-md);
}

.news-card a {
  display: block;
  padding: var(--space-lg);
  color: var(--color-text);
}

.news-date {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-text-muted);
}

.news-card h2 {
  font-size: var(--text-xl);
  color: var(--color-brand);
  margin-top: var(--space-2xs);
}

.news-summary {
  margin-top: var(--space-xs);
  color: var(--color-text-muted);
}

.back-link {
  margin-top: var(--space-2xl);
  font-weight: 600;
}

/* --- Contact -------------------------------------------------------------- */
.contact-form {
  display: grid;
  gap: var(--space-lg);
}

.contact-form button {
  justify-self: start;
}

.direct-email {
  margin-top: var(--space-xl);
  color: var(--color-text-muted);
}

.flashes {
  display: grid;
  gap: var(--space-xs);
  margin-bottom: var(--space-lg);
}

/* --- Body-copy sections ------------------------------------------------- */
/* .section supplies the vertical rhythm (global.css). This gives the prose
   inside it a measure — a 1200px container with unconstrained paragraphs is
   ~150 characters a line, which is roughly twice a comfortable read. */
.section p {
  max-width: 68ch;
}

.section p + p {
  margin-top: var(--space-md);
}

/* The footer should sit at the bottom of a short page rather than half way up
   it with ground showing underneath. */
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* `main` is itself a column so a single full-bleed section can be told to take
   the slack. Without this, `main` grows to push the footer down and the leftover
   height renders as the page's own cream — which put a cream band between the
   navy 404 panel and the navy footer. */
body > main {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
}

/* Sections keep their natural height... */
body > main > * {
  flex: 0 0 auto;
}

/* ...except a page that is only one panel, which absorbs the remainder so its
   background reaches the footer. */
body > main > .notfound {
  flex: 1 0 auto;
}

/* ==========================================================================
   Rulebooks

   A contents rail beside the rules on desktop, stacked above them on mobile.
   Ported from the Astro pages' scoped styles — and those scoped blocks are
   exactly what went missing in Phase 1, so the whole of this section exists
   because a page's markup came across without its CSS once already.
   ========================================================================== */
.rules-layout {
  display: grid;
  grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
  gap: var(--space-2xl);
  align-items: start;
}

.rules-toc {
  position: sticky;
  top: calc(var(--header-height) + var(--space-md));
  /* A long rulebook's contents can outrun the viewport — scroll the RAIL, not
     the page, so the rules stay put beside it. */
  max-height: calc(100vh - var(--header-height) - var(--space-2xl));
  overflow-y: auto;
  padding: var(--space-lg);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-accent);
  border-radius: var(--radius-md);
}

.rules-toc-title {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-caps);
  color: var(--color-brand);
}

.rules-toc ul {
  list-style: none;
  margin: var(--space-sm) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  font-size: var(--text-sm);
}

.toc-top {
  margin-top: var(--space-xs);
  font-weight: 700;
}

.toc-top:first-child {
  margin-top: 0;
}

.toc-sub {
  padding-left: var(--space-md);
  border-left: 2px solid var(--color-border);
}

.toc-sub a {
  font-weight: 500;
  color: var(--color-text-muted);
}

.toc-sub a:hover {
  color: var(--color-link-hover);
}

/* Marks where the sport's own rules end and the org-wide rules begin. */
.toc-divider {
  margin-top: var(--space-md);
  padding-top: var(--space-xs);
  border-top: 1px solid var(--color-border);
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-caps);
  color: var(--color-accent-on-light);
}

.rules-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-top: var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-text-invert-muted);
}

.rules-version {
  font-weight: 700;
  color: var(--gold-400);
}

.rules-body {
  max-width: 70ch;
  /* A wide table scrolls inside itself rather than dragging the page sideways. */
  overflow-x: auto;
}

.org-rules {
  margin-top: var(--space-2xl);
  padding-top: var(--space-lg);
  border-top: 4px solid var(--color-accent);
}

.org-intro {
  padding: var(--space-md) var(--space-lg);
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.sport-rules-links {
  margin-top: var(--space-2xl);
  padding: var(--space-lg);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.sport-rules-title {
  font-size: var(--text-xl);
  color: var(--color-brand);
}

.sport-rules-links p {
  margin-top: var(--space-xs);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.sport-rules-links ul {
  margin-top: var(--space-sm);
  font-weight: 600;
}

/* ==========================================================================
   Prose — anything rendered from markdown

   Under Astro these lived in each page's scoped block with `:global()` on every
   selector, because the HTML came from a component rather than the template.
   Here the markdown is inserted into `.prose` and ordinary descendant selectors
   reach it, which is the same styling with none of the ceremony.
   ========================================================================== */
.prose h2,
.prose h3 {
  /* Jumping to a section from the contents must clear the sticky header. */
  scroll-margin-top: calc(var(--header-height) + var(--space-md));
}

/* Rulebooks are dense — headings have to be findable while scanning. */
.prose h2 {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: var(--text-2xl);
  color: var(--color-brand);
  margin-top: var(--space-xl);
  padding-top: var(--space-sm);
  border-top: 2px solid var(--color-border);
}

.prose h2:first-child {
  margin-top: 0;
  border-top: 0;
  padding-top: 0;
}

.prose h3 {
  font-size: var(--text-lg);
  color: var(--color-brand);
  margin-top: var(--space-lg);
}

.prose h4 {
  font-size: var(--text-base);
  color: var(--color-brand);
  margin-top: var(--space-md);
}

.prose p,
.prose ul,
.prose ol {
  margin-top: var(--space-sm);
}

.prose ul,
.prose ol {
  padding-left: var(--space-lg);
}

.prose li + li {
  margin-top: var(--space-2xs);
}

.prose hr {
  margin-top: var(--space-xl);
  border: 0;
  border-top: 1px solid var(--color-border);
}

.prose img {
  width: 100%;
  border-radius: var(--radius-md);
  margin-block: var(--space-xl);
}

.prose table {
  width: 100%;
  margin-top: var(--space-md);
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.prose th,
.prose td {
  text-align: left;
  padding: var(--space-xs) var(--space-sm);
  border-bottom: 1px solid var(--color-border);
}

.prose th {
  background: var(--color-surface-alt);
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  font-size: var(--text-xs);
}

/* ==========================================================================
   The waiver
   ========================================================================== */
.waiver-edition {
  color: var(--color-text-muted);
}

.block-title {
  font-size: var(--text-xl);
  color: var(--color-brand);
  margin-top: var(--space-2xl);
}

.waiver-clauses {
  display: grid;
  gap: var(--space-md);
  max-width: 68ch;
  margin-top: var(--space-md);
}

.clause {
  display: grid;
  gap: var(--space-xs);
}

.clause-heading {
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}

/* Small, because it is long — but never smaller than the body text of the page
   it sits on, and never in a muted colour. Legal text that is harder to read
   than the button beside it is legal text nobody read. */
.clause p {
  font-size: var(--text-sm);
}

.sign-form {
  display: grid;
  gap: var(--space-lg);
  margin-top: var(--space-2xl);
  padding: var(--space-lg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.sign-form .block-title {
  margin-top: 0;
}

.sign-form button {
  justify-self: start;
}

.field-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
}

.field-row .field {
  flex: 1 1 14rem;
}

.consent-choice {
  border: 0;
  padding: 0;
}

.consent-choice legend {
  font-weight: 700;
  margin-bottom: var(--space-xs);
}

.radio-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-2xs) 0;
}

.radio-row input {
  /* A radio is the one control here somebody taps with a wet thumb at a rail. */
  width: 1.15rem;
  height: 1.15rem;
  accent-color: var(--color-brand);
}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 900px) {
  .hero-inner,
  .about-grid {
    grid-template-columns: 1fr;
    gap: var(--space-xl);
  }
}

@media (max-width: 860px) {
  .rules-layout {
    grid-template-columns: 1fr;
    gap: var(--space-lg);
  }

  /* Stacked above the rules rather than beside them, so it must not stick — a
     sticky block at the top of a scrolling page covers what you scrolled to. */
  .rules-toc {
    position: static;
    max-height: none;
  }
}

@media (max-width: 560px) {
  .hero-photos {
    grid-template-columns: 1fr;
  }

  .photo-half {
    aspect-ratio: 16 / 9;
  }
}

/* ==========================================================================
   THE ACCOUNT AREA — /my/. Dogs live here.

   All on cream. NO navy surface is introduced in this block, deliberately: every
   navy surface has to be added to the inverted-surface list in global.css or its
   outline buttons render dark-on-navy, and that has now shipped broken twice
   (`.hero`/`.page-header`/`.notfound` in Phase 1, `.staff-hero` in Phase 3). The
   pages here reuse `.page-header`, which is already on the list.
   ========================================================================== */

.account-nav {
  margin-bottom: var(--space-lg);
  border-bottom: 1px solid var(--color-border);
}

.account-nav ul {
  display: flex;
  gap: var(--space-md);
  list-style: none;
  padding: 0;
  margin: 0;
  overflow-x: auto;
}

.account-nav a {
  display: inline-block;
  padding: var(--space-sm) 0;
  font-weight: 700;
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-muted);
  text-decoration: none;
  border-bottom: 3px solid transparent;
  white-space: nowrap;
}

.account-nav a[aria-current='page'] {
  color: var(--color-brand);
  border-bottom-color: var(--color-accent);
}

/* The waiver notice. A left border rather than a filled panel, so an unsigned
   waiver reads as a note and not as an error — nothing on this site refuses
   anybody over a waiver, and a red box would imply otherwise. */
.account-waiver {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-md);
  padding: var(--space-md) var(--space-lg);
  margin-bottom: var(--space-xl);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 5px solid var(--color-border-strong);
  border-radius: var(--radius-md);
}

.account-waiver p {
  margin: 0;
}

.account-waiver.is-signed {
  border-left-color: var(--color-success);
}

/* Gold as a FILL on the border, never as text on cream — `--color-accent` fails
   contrast as text here at 2.2:1, and `--color-accent-on-light` is the text token.
   A border is a fill. */
.account-waiver.is-unsigned {
  border-left-color: var(--color-accent);
}

.account-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-bottom: var(--space-lg);
}

.account-section-head h2 {
  margin: 0;
}

.account-tabs {
  display: flex;
  gap: var(--space-xs);
}

.account-tab {
  padding: var(--space-xs) var(--space-md);
  border: 2px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--color-text-muted);
  text-decoration: none;
}

.account-tab[aria-current='page'] {
  border-color: var(--color-brand);
  color: var(--color-brand);
}

/* --- Dog cards ---------------------------------------------------------- */

.dog-grid {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-lg);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: var(--space-md);
}

.dog-card {
  border: 1px solid var(--color-border);
  border-left: 5px solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition);
}

.dog-card:hover {
  transform: translateX(4px);
  box-shadow: var(--shadow-md);
}

.dog-card.is-archived {
  border-left-color: var(--color-border-strong);
}

/* The whole card is the link, so the target is the card and not four words of it —
   this list is used on a phone at a venue. */
.dog-card-link {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-md);
  text-decoration: none;
  color: inherit;
}

.dog-card-photo {
  flex: 0 0 auto;
  width: 4rem;
  height: 4rem;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface-alt);
  display: grid;
  place-items: center;
}

.dog-card-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The placeholder mark is a silhouette, not a photo — it is inset and not cropped,
   so it reads as "no photo yet" rather than as a failed image. */
.dog-card-photo .dog-card-placeholder {
  width: 62%;
  height: 62%;
  object-fit: contain;
  opacity: 0.35;
}

.dog-card-body {
  display: grid;
  gap: var(--space-2xs);
  min-width: 0;
}

/* THE BAD NUMBER READS FIRST, above the name. It is what the judge's sheet prints
   and what results quote, so a competitor should know it before anybody asks. */
.dog-card-number {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  color: var(--color-accent-on-light);
  font-weight: 700;
}

.dog-card-name {
  font-size: var(--text-lg);
  line-height: var(--leading-snug);
  overflow-wrap: anywhere;
}

.dog-card-meta {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.dog-card-flag {
  justify-self: start;
  padding: 0 var(--space-2xs);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-text-muted);
}

/* --- One dog ------------------------------------------------------------ */

.dog-detail {
  display: grid;
  grid-template-columns: 14rem 1fr;
  gap: var(--space-xl);
  align-items: start;
  margin-bottom: var(--space-lg);
}

.dog-detail-photo {
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface-alt);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
}

.dog-detail-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.dog-detail-photo .dog-card-placeholder {
  width: 55%;
  height: 55%;
  object-fit: contain;
  opacity: 0.3;
}

.dog-detail-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--space-md);
  margin: 0;
}

.dog-detail-facts dt {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-text-muted);
}

.dog-detail-facts dd {
  margin: var(--space-2xs) 0 0;
  font-size: var(--text-lg);
}

/* "permanent", "classifies nothing" — the two facts about this screen a competitor
   from another organisation will assume wrongly. Small, muted, and beside the value
   rather than in a hint below it, so it is read at the same time. */
.fact-note {
  display: block;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-text-muted);
}

.dog-detail-notes {
  margin-bottom: var(--space-lg);
}

/* --- Dog form ----------------------------------------------------------- */

.dog-form {
  display: grid;
  gap: var(--space-lg);
  margin-bottom: var(--space-lg);
}

/* Buttons and single-button forms side by side. The archive control is a POST form
   rather than a link, so this has to lay out forms as well as anchors. */
.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
  margin-bottom: var(--space-md);
}

.form-actions form {
  margin: 0;
}

@media (max-width: 640px) {
  /* The photo goes above the facts rather than beside them, and stops being a
     square that eats the whole screen. */
  .dog-detail {
    grid-template-columns: 1fr;
    gap: var(--space-lg);
  }

  .dog-detail-photo {
    max-width: 12rem;
  }

  .account-section-head {
    align-items: flex-start;
    flex-direction: column;
  }
}

/* Sign out sits at the far end of the account nav, and it is a FORM (sign-out is
   POST-only — a GET sign-out can be triggered by any image tag on any page). Styled
   to match the sibling links exactly so the row reads as one nav rather than three
   links and a button. */
.account-nav-signout {
  margin-left: auto;
}

.account-nav-signout form {
  margin: 0;
}

.account-nav-signout button {
  padding: var(--space-sm) 0;
  background: none;
  border: 0;
  border-bottom: 3px solid transparent;
  font-weight: 700;
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-muted);
  cursor: pointer;
}

.account-nav-signout button:hover {
  color: var(--color-brand);
}

/* ==========================================================================
   Events — Phase 6
   ==========================================================================
   NO RAW HEX IN HERE. Every colour is a token from global.css's :root, which is
   what makes Sun Mode and the navy invert flip work — a hardcoded colour follows
   neither. Surface-token table, rule 4.
   ========================================================================== */

/* --- A section on the alternate ground ------------------------------------ */
.section-alt {
  background: var(--color-surface-alt);
}

/* --- The event list ------------------------------------------------------- */
.event-list {
  list-style: none;
  padding: 0;
  margin-top: var(--space-xl);
  display: grid;
  gap: var(--space-lg);
  /* `auto-fill`, NOT `auto-fit`. With `auto-fit` the empty tracks collapse and a
     single card stretches to the full 1200px container — 190px tall, content
     hugging the left edge, reading as a broken banner rather than a card. BAD
     runs a handful of events a season and "one event on the calendar" is the
     ordinary state, not the edge case. */
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

.event-card {
  border: 1px solid var(--color-border);
  border-left: 5px solid var(--color-accent);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition), transform var(--transition);
}

.event-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

/* A cancelled event stays on the calendar — somebody booked a hotel — but it
   must not read as a live one. The muted left edge is the difference you see
   from across the list, before the badge is legible. */
.event-card.is-cancelled {
  border-left-color: var(--color-border-strong);
}

.event-card a {
  display: block;
  padding: var(--space-lg);
  color: inherit;
}

.event-card-title {
  font-size: var(--text-xl);
  color: var(--color-brand);
  margin-top: var(--space-xs);
}

.event-card-when {
  margin-top: var(--space-xs);
  font-weight: 700;
}

.event-card-where,
.event-card-runs {
  margin-top: var(--space-2xs);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* --- The phase badge ------------------------------------------------------
   Six phases, four looks. `upcoming` and `in_progress` are the two a competitor
   acts on, so they carry the accent; the rest are quieter on purpose. GOLD IS A
   FILL AND NEVER TEXT ON CREAM (2.2:1) — the filled badge puts navy on gold, and
   the text-only variants use --color-accent-on-light, which is gold-700.
   Surface-token table, rule 3. */
.event-phase {
  display: inline-block;
  padding: 0.15em 0.7em;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  background: var(--color-surface-alt);
  color: var(--color-text-muted);
}

.event-phase.phase-upcoming {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.event-phase.phase-in_progress {
  background: var(--color-brand);
  color: var(--color-text-invert);
}

.event-phase.phase-cancelled {
  background: var(--color-surface-alt);
  color: var(--color-error);
}

/* --- The event hero -------------------------------------------------------
   `.event-hero` IS ALREADY IN THE INVERT SELECTOR LIST in global.css — a forward
   declaration made in Phase 1. That list is what flips the accent tokens so an
   outline button on this navy is visible; without it the button renders
   dark-on-navy and is present, focusable, clickable and invisible. Do not also
   put `class="invert"` on the element: two mechanisms doing one job hides which
   one is load-bearing. Surface-token table, rule 1. */
.event-hero {
  background: var(--color-bg-invert);
  color: var(--color-text-invert);
  padding-block: var(--space-2xl);
  border-bottom: 5px solid var(--color-accent);
}

.event-title {
  font-size: var(--text-3xl);
  margin-top: var(--space-xs);
}

.event-when {
  margin-top: var(--space-sm);
  font-size: var(--text-xl);
  color: var(--color-text-invert);
}

.event-where {
  margin-top: var(--space-2xs);
  color: var(--color-text-invert-muted);
}

.event-phase-note {
  margin-top: var(--space-md);
  color: var(--color-text-invert-muted);
  max-width: 62ch;
}

/* --- Banners --------------------------------------------------------------
   The weather hold is the loudest thing on the page and sits above everything,
   including a cancellation: a dock that has gone quiet with no explanation
   empties a venue, and thirty minutes after the last strike is a real rule. */
.event-banner {
  padding-block: var(--space-md);
  font-size: var(--text-lg);
}

.event-banner-hold {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.event-banner-cancelled {
  background: var(--color-surface-alt);
  color: var(--color-text);
  border-bottom: 1px solid var(--color-border-strong);
}

/* "Running now" — quieter than the hold on purpose. A hold is an instruction and
   this is an invitation, and two full-width gold bands would leave neither of
   them meaning anything. NAVY GROUND, so it carries `class="invert"` in the
   template — surface-token table, rule 1: without the flip the link inside it
   renders navy-on-navy. */
.event-banner-live {
  background: var(--color-bg-invert);
  color: var(--color-text-invert);
}

/* AND ITS LINK IS UNDERLINED, because `.invert` sets `--color-link` to the same
   cream as the surrounding text. That is right for the header and the footer,
   where every link is a nav item in a row of them — and wrong here, where one
   link sits inside a sentence and rendered as ordinary prose: present,
   focusable, clickable, and indistinguishable. Found in a browser. It is rule
   1's failure mode wearing a different coat: the invert flip fixed the contrast
   and left the AFFORDANCE gone. */
.event-banner-live a {
  text-decoration: underline;
  text-underline-offset: 0.2em;
  font-weight: 600;
}

.event-banner-live a:hover {
  color: var(--color-accent-on-light);
}

/* --- The two-column body -------------------------------------------------- */
.event-layout {
  display: grid;
  gap: var(--space-xl);
  grid-template-columns: minmax(0, 2fr) minmax(260px, 1fr);
  align-items: start;
}

@media (max-width: 820px) {
  .event-layout {
    grid-template-columns: 1fr;
  }
}

/* Typed into a textarea by an admin, so the line breaks somebody typed are the
   line breaks that show. It is NOT markdown — see the note in the template. */
.event-description {
  white-space: pre-line;
  max-width: 68ch;
  margin-bottom: var(--space-xl);
}

.event-day {
  margin-top: var(--space-lg);
  padding-top: var(--space-lg);
  border-top: 1px solid var(--color-border);
}

.event-day-title {
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--color-brand);
}

.event-desk-hours {
  margin-top: var(--space-2xs);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.event-schedule {
  list-style: none;
  padding: 0;
  margin-top: var(--space-md);
}

.event-schedule-row {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr) auto;
  gap: var(--space-sm);
  padding-block: var(--space-xs);
  border-bottom: 1px solid var(--color-border);
}

@media (max-width: 640px) {
  .event-schedule-row {
    grid-template-columns: 6rem minmax(0, 1fr);
  }
  .event-schedule-judge {
    grid-column: 2;
  }
}

.event-schedule-time {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}

/* A run is the thing people came for; the handlers meeting and the lunch break
   are the things that tell them when to arrive. Both belong on the list, and the
   run is the one in bold. */
.event-schedule-row.is-run .event-schedule-label {
  font-weight: 700;
  color: var(--color-brand);
}

.event-schedule-judge {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.event-empty-day {
  margin-top: var(--space-sm);
  color: var(--color-text-muted);
  font-style: italic;
}

/* --- The runs table -------------------------------------------------------
   The wrapper scrolls, the page does not. A table with five columns on a phone
   is the classic source of a horizontally scrolling document. */
.event-table-wrap {
  overflow-x: auto;
  margin-top: var(--space-md);
}

.event-runs {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.event-runs th,
.event-runs td {
  padding: var(--space-xs) var(--space-sm);
  text-align: left;
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
}

.event-runs thead th {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-text-muted);
}

.event-runs tbody th {
  color: var(--color-brand);
}

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

.event-note {
  margin-top: var(--space-sm);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* --- The sidebar ---------------------------------------------------------- */
.event-facts {
  padding: var(--space-lg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.event-facts + .event-facts {
  margin-top: var(--space-lg);
}

.event-facts-title {
  font-size: var(--text-lg);
  color: var(--color-brand);
}

.event-facts dl {
  margin-top: var(--space-md);
}

.event-facts dl > div + div {
  margin-top: var(--space-md);
}

.event-facts dt {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-text-muted);
}

.event-facts dd {
  margin: 0;
  font-weight: 700;
}

.event-facts p {
  margin-top: var(--space-md);
}

.event-facts-note {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.event-flag {
  display: inline-block;
  margin-left: var(--space-2xs);
  padding: 0.05em 0.5em;
  border-radius: var(--radius-pill);
  background: var(--color-surface-alt);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-text-muted);
}

.event-address {
  line-height: var(--leading-normal);
}

/* The hold banner's three parts are separate blocks, not one sentence — a reason
   typed by staff has no guaranteed full stop at the end of it, and "Lightning
   within 10 miles Stay on site" is what one sentence produced. */
.event-banner-reason {
  display: block;
  font-weight: 700;
}

.event-banner-advice {
  display: block;
  font-size: var(--text-base);
}

/* ==========================================================================
   ENTRY, CHECKOUT AND A COMPETITOR'S ENTRIES — Phase 7
   The money surfaces a competitor sees.

   NO NEW NAVY SURFACE IN THIS BLOCK. Everything here sits on cream or on
   --color-surface, so nothing needs adding to the invert selector list in
   global.css (surface-token table, rule 1). `.page-header` is already on it and
   the entry form's own header uses it unchanged.

   No raw hex either (rule 4) — every colour below is a token.
   ========================================================================== */

.entry-notice {
  margin-bottom: var(--space-lg);
  padding: var(--space-md) var(--space-lg);
  border-left: 4px solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-surface-alt);
  font-size: var(--text-sm);
}

.entry-form {
  display: grid;
  gap: var(--space-xl);
}

/* One block per dog rather than a runs x dogs grid. A table stacks badly on a
   phone in a car park, which is where most of these are filled in. */
.entry-dog {
  padding: var(--space-lg);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.entry-dog-name {
  padding-inline: var(--space-xs);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  letter-spacing: var(--tracking-wide);
}

/* The BAD number, wherever it is printed beside a name. Monospaced by CLASS and
   never by column position — surface-token table, rule 8. */
.entry-dog-number {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.entry-runs {
  display: grid;
  gap: var(--space-xs);
  margin-top: var(--space-md);
  list-style: none;
  padding: 0;
}

.entry-choice {
  display: flex;
  /* `center`, not `baseline`. A checkbox's baseline is its bottom edge, so on a
     baseline row it floats visibly above the words it belongs to. */
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-md);
}

/* The whole row is the label, so the tap target is the row and not the 16px
   checkbox — this is filled in on a phone, one-handed, outdoors. */
label.entry-choice {
  cursor: pointer;
}

label.entry-choice:hover,
label.entry-choice:focus-within {
  border-color: var(--color-accent);
}

.entry-choice input[type='checkbox'] {
  width: 1.15rem;
  height: 1.15rem;
  accent-color: var(--color-brand);
}

.entry-choice.is-blocked,
.entry-choice.is-waitlist {
  border-style: dashed;
  color: var(--color-text-muted);
}

.entry-run-title {
  font-weight: 700;
  color: var(--color-text);
}

.entry-choice.is-blocked .entry-run-title {
  color: var(--color-text-muted);
}

.entry-run-when,
.entry-run-note {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* The link to a run's published running order, on its own line under the run
   label and its start time. A BLOCK and not a third inline note: the cell
   already carries two facts, and inline it rendered "Dive 1 9:00 AM Running
   order" as one run-on line in a narrow column. */
.entry-order-link {
  display: block;
  font-size: var(--text-sm);
}

.entry-price {
  margin-left: auto;
  font-weight: 700;
  /* gold-700, never gold-500: this is text on a light ground and gold-500 is
     2.2:1 there. Surface-token table, rule 3. */
  color: var(--color-accent-on-light);
}

.entry-flag {
  padding: 0.05em 0.5em;
  border-radius: var(--radius-pill);
  background: var(--color-surface-alt);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-text-muted);
}

.entry-flag-unpaid {
  background: var(--color-surface-alt);
  color: var(--color-error);
}

.entry-handler {
  padding: var(--space-lg);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.entry-section-title {
  padding-inline: var(--space-xs);
  font-family: var(--font-display);
  font-size: var(--text-lg);
}

.entry-radio {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin-top: var(--space-xs);
}

.entry-handler-fields {
  display: grid;
  gap: var(--space-md);
  margin-top: var(--space-md);
}

.entry-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  align-items: center;
}

.entry-terms {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.entry-waitlist {
  margin-top: var(--space-2xl);
}

.entry-waitlist-note {
  max-width: 62ch;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.entry-waitlist-list {
  display: grid;
  gap: var(--space-xs);
  margin-top: var(--space-md);
  list-style: none;
  padding: 0;
}

.entry-waitlist-list form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.entry-waitlist-label {
  font-weight: 600;
}

/* A wide table scrolls inside its own wrapper rather than making the page scroll
   sideways — the same shape the runs table on the staff event page uses. */
.entry-table-wrap {
  overflow-x: auto;
  /* Space BELOW as well as above: the next thing on the entries page is a
     section heading, and without it "Waitlists" sat flush against the last row
     of the table above it and read as part of it. */
  margin-block: var(--space-md) var(--space-xl);
}

.entry-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.entry-table th,
.entry-table td {
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-border);
  text-align: left;
  vertical-align: top;
}

.entry-table thead th {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-text-muted);
}

.entry-table tbody th {
  font-weight: 700;
}

.event-entry-action {
  margin-top: var(--space-md);
}

/* --- Checkout ----------------------------------------------------------- */

/* Deliberately the loudest thing on the sandbox page. It must be impossible to
   mistake BAD's stand-in for a real payment form. */
.checkout-sandbox-banner {
  margin-bottom: var(--space-lg);
  padding: var(--space-md) var(--space-lg);
  border: 2px dashed var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-surface-alt);
}

.checkout-panel {
  margin-top: var(--space-lg);
  padding: var(--space-lg);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.checkout-panel-title {
  font-size: var(--text-lg);
}

.checkout-lines {
  display: grid;
  gap: var(--space-xs);
  margin-top: var(--space-md);
  list-style: none;
  padding: 0;
}

.checkout-lines li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-md);
  padding-bottom: var(--space-xs);
  border-bottom: 1px solid var(--color-border);
}

.checkout-line-amount {
  font-weight: 700;
  white-space: nowrap;
}

.checkout-total {
  display: flex;
  justify-content: space-between;
  gap: var(--space-md);
  margin-top: var(--space-md);
  font-size: var(--text-lg);
}

.checkout-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-top: var(--space-lg);
}

.checkout-lede {
  max-width: 62ch;
  font-size: var(--text-lg);
}

/* --- Public results (Phase 11) ------------------------------------------ */

/* A heading and a closing paragraph that follow a table need their own top
   space: `.event-table-wrap` only has a top margin, so the next thing after a
   table sits flush against its last row. "Not ranked" read as a caption on the
   ranked table rather than a heading of its own, and the prize-money sentence
   read as another table row. Found by looking at the page. */
.results-heading,
.results-footnote {
  margin-top: var(--space-xl);
}
