/* One stylesheet, four sites. Each tenant sets its own tokens on :root
 * in its own page, which is the same arrangement the platform uses for
 * its themes -- and for the same reason: a tenant changes colours and
 * words, never layout.
 *
 * EVERY COLOUR PAIR HERE IS MEASURED, not chosen by eye. The pairs are
 * checked by _work/contrast_live.py against the rendered page, which
 * reads what the browser actually paints rather than what a variable
 * says. Saying "meets AA" in a comment is how a theme in this codebase
 * ended up rendering black text on a black background.
 */

/* THE FONT IS SERVED FROM THIS SITE (DPIA R7, 26 Sep 2026). Every page
   linked Google Fonts, so a visitor's address went to Google before they
   had made any choice -- against the owner's rule that nothing reaches a
   third party before consent. The face is now this origin's own file, in
   /shared/fonts/ (SIL Open Font License 1.1: see LICENCE.txt there), and
   because it is declared HERE rather than in each page's head, the composed
   pages, which load this stylesheet too, get the same face. Until the
   files are in place the system fallback is what draws. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("/shared/fonts/inter-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("/shared/fonts/inter-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --ink: #101913;
  --ink-soft: #3d4a41;
  --paper: #ffffff;
  --paper-warm: #f7f5f0;
  --line: #d9d5cc;
  --brand: #16513a;
  --brand-deep: #0d3324;
  --accent: #b4491f;
  --accent-soft: #fdf1ec;
  --ok: #1c6b45;
  /* BRAND AND ACCENT, AS TEXT. Separate tokens because --brand and
     --accent are picked to work as fills on this tenant's paper, and a
     tenant whose paper is nearly black needs lighter ones for words.
     The arena is exactly that case: its brand purple on its own
     background measured 2.65:1, and the audit caught it. Defaulting
     to the fill colours keeps every light-paper tenant unchanged. */
  --brand-text: var(--brand);
  --accent-text: var(--accent);
  /* THE EDGE OF A CONTROL -- an input, a quiet button, a slot -- which has
     to be seen to be used: 3:1 against the paper (WCAG 1.4.11). --line
     is a divider at about 1.4:1 and was doing this job too (measured on
     all four sites, 25 Sep 2026). From each tenant's own ink and paper,
     so it lands at 3.6:1 on the light sites and 5.1:1 on the arena. */
  --control-line: color-mix(in srgb, var(--ink-soft) 65%, var(--paper));
  --radius: 14px;
  --shadow: 0 1px 2px rgba(16, 25, 19, .06), 0 8px 24px rgba(16, 25, 19, .06);
  --font: "Inter var", Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  --display: var(--font);
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background: var(--paper);
  line-height: 1.6;
  font-size: 17px;
}

/* MOTION IS OPTIONAL. Everything that moves is behind this, because a
 * demo that cannot be watched by somebody with vestibular disorder is
 * a demo with an audience missing from the room. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- the skip link, first in the tab order ------------------------- */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--brand); color: #fff; padding: .75rem 1.25rem;
  border-radius: 0 0 var(--radius) 0; font-weight: 700;
}
.skip:focus { left: 0; }

/* A VISIBLE FOCUS RING EVERYWHERE, set once. The default ring is
 * removed by half the resets on the internet and then never replaced. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.wrap { width: min(1120px, 100% - 3rem); margin-inline: auto; }
@media (max-width: 640px) { .wrap { width: min(1120px, 100% - 2rem); } }

/* --- masthead ------------------------------------------------------ */
.masthead {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.masthead .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; min-height: 68px;
}
.brand { display: flex; align-items: center; gap: .7rem; text-decoration: none; color: inherit; }
.brand-mark {
  width: 36px; height: 36px; border-radius: 10px; flex: none;
  background: var(--brand); color: #fff;
  display: grid; place-items: center; font-weight: 800; font-size: .95rem;
}
.brand-name { font-weight: 800; letter-spacing: -.015em; font-size: 1.05rem; }
/* THE MENU IS TWO LISTS FROM THE CMS: the sections (`nav`) and the one
   account link (`utility`), which looks like a quiet button. */
.nav { display: flex; align-items: center; gap: .35rem; }
.nav ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; gap: .35rem;
}
.nav ul:empty { display: none; }
.nav a {
  color: var(--ink-soft); text-decoration: none; font-weight: 600;
  font-size: .93rem; padding: .6rem .7rem; border-radius: 9px;
  min-height: 44px; display: inline-flex; align-items: center;
}
.nav a:hover { background: var(--paper-warm); color: var(--ink); }
.nav a[aria-current="page"] { color: var(--ink); background: var(--paper-warm); }
.nav-util a {
  color: var(--ink); background: var(--paper); border: 1px solid var(--control-line);
  border-radius: 999px; padding: .6rem 1.15rem; font-weight: 700;
}

/* THE PHONE MENU BUTTON. Hidden until site.js shows it, so a page whose
   script failed keeps its links on screen rather than behind a button
   that does nothing. 44px each way, like every other control here. */
.nav-toggle {
  display: none;
  min-height: 44px; min-width: 44px; padding: .55rem .95rem;
  align-items: center; justify-content: center; gap: .55rem;
  border: 1px solid var(--ink-soft); border-radius: 999px;
  background: var(--paper); color: var(--ink);
  font: inherit; font-weight: 700; font-size: .93rem; cursor: pointer;
}
/* Three bars, drawn: no icon font, no character to mangle. */
.nav-toggle::before {
  content: ""; width: 18px; height: 2px; border-radius: 1px;
  background: currentColor; box-shadow: 0 -6px 0 currentColor, 0 6px 0 currentColor;
}
.nav-toggle[aria-expanded="true"]::before {
  height: 12px; width: 12px; background: none; box-shadow: none;
  border-top: 2px solid currentColor; border-left: 2px solid currentColor;
  transform: translateY(3px) rotate(45deg);
}
@media (max-width: 760px) {
  .masthead .wrap { flex-wrap: wrap; row-gap: 0; }
  .nav { flex-wrap: wrap; }
  .nav-toggle:not([hidden]) { display: inline-flex; }
  /* FOLDED ONLY WHEN THE BUTTON IS THERE TO OPEN IT. */
  .nav-toggle:not([hidden]) + .nav {
    display: none; width: 100%; flex-direction: column; align-items: stretch;
    padding: 0 0 .9rem; border-top: 1px solid var(--line);
  }
  .nav-toggle:not([hidden])[aria-expanded="true"] + .nav { display: flex; }
  .nav-toggle:not([hidden]) + .nav ul { flex-direction: column; align-items: stretch; gap: 0; }
  .nav-toggle:not([hidden]) + .nav a { width: 100%; }
  .nav-toggle:not([hidden]) + .nav .nav-util { margin-top: .5rem; }
  .nav-toggle:not([hidden]) + .nav .nav-util a { justify-content: center; }
}

/* --- buttons: one shape, three weights ----------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: .5rem; min-height: 44px; padding: .7rem 1.15rem;
  border-radius: 999px; border: 1px solid transparent;
  font: inherit; font-weight: 700; font-size: .94rem;
  text-decoration: none; cursor: pointer;
  transition: transform .12s ease, background .12s ease;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--brand); color: #fff; }
.btn-primary:hover { background: var(--brand-deep); }
.btn-accent { background: var(--accent); color: #fff; }
.btn-quiet {
  background: var(--paper); color: var(--ink); border-color: var(--control-line);
}
.btn-quiet:hover { background: var(--paper-warm); }
.btn[disabled] { opacity: .55; cursor: not-allowed; }

/* --- hero ---------------------------------------------------------- */
.hero {
  position: relative; overflow: hidden;
  background: var(--brand-deep); color: #fff;
}

/* A PHOTOGRAPH UNDER THE WORDS, and a scrim that makes them legible.
 *
 * THE SCRIM IS NOT DECORATION. Text over an image has no measurable
 * contrast -- the background is different under every letter -- so the
 * only honest way to put words on a picture is to guarantee a floor.
 * This one is opaque at the left, where the text sits, and clears to
 * the right so the picture is still a picture.
 *
 * VERIFIED BY SAMPLING PIXELS, not by reading a CSS variable:
 * _work/audit_hero_pixels.py renders the page and measures the darkest
 * and lightest pixels actually behind the heading. A contrast checker
 * that reads background-color sees the colour UNDER the image and
 * reports a pass it has not earned. */
.hero-photo {
  position: absolute; inset: 0; z-index: 0;
  background-size: cover; background-position: center;
}
.hero-photo::after {
  content: ""; position: absolute; inset: 0;
  /* HEAVY WHERE THE WORDS ARE, CLEAR WHERE THEY ARE NOT. The first
     version ran 94% to 40% and buried the photograph completely --
     measured as a background of exactly one colour behind the heading,
     worst 13.87:1 and best 13.87:1, which is the number a flat panel
     gives. A scrim with no variation under it is a scrim that has
     eaten the picture. */
  /* THE HAND-OFF IS AT 62%, NOT 38%. Measured: with the fade starting
     early the lead paragraph -- which runs wider than the heading --
     reached 4.04:1 against a 4.5 requirement, and the heading's
     background swung 5.9x across its own width. The text column ends
     around 60% of the viewport, so that is where the scrim may start
     letting go. */
  background: linear-gradient(100deg,
    color-mix(in srgb, var(--brand-deep) 93%, transparent) 0%,
    color-mix(in srgb, var(--brand-deep) 90%, transparent) 46%,
    color-mix(in srgb, var(--brand-deep) 84%, transparent) 62%,
    color-mix(in srgb, var(--brand-deep) 30%, transparent) 88%,
    color-mix(in srgb, var(--brand-deep) 10%, transparent) 100%);
}

/* THE DECORATIVE WASH IS FOR HEROES WITH NO PHOTOGRAPH. Left on, it
   sat above the picture at 85% opacity in solid brand colours and
   finished whatever the scrim had started. */
.hero:has(.hero-photo)::after { display: none; }
@media (max-width: 760px) {
  /* NARROWER SCREENS PUT TEXT OVER THE WHOLE IMAGE, so the scrim has
     to cover the whole image rather than fading across it. */
  .hero-photo::after {
    /* A phone puts the words across the whole image, so the scrim is
       flat rather than graded -- but lighter at the foot, where there
       is no text, so the photograph is still visible. */
    background: linear-gradient(180deg,
      color-mix(in srgb, var(--brand-deep) 88%, transparent) 0%,
      color-mix(in srgb, var(--brand-deep) 86%, transparent) 62%,
      color-mix(in srgb, var(--brand-deep) 55%, transparent) 100%);
  }
}
.hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  z-index: 1;
  background:
    radial-gradient(900px 400px at 15% -10%, color-mix(in srgb, var(--accent) 45%, transparent), transparent 60%),
    radial-gradient(700px 500px at 95% 110%, color-mix(in srgb, var(--brand) 80%, transparent), transparent 60%);
  opacity: .85;
}
.hero .wrap { position: relative; z-index: 2; padding: clamp(3rem, 9vw, 6.5rem) 0; }
.hero h1 {
  font-family: var(--display);
  font-size: clamp(2.2rem, 6vw, 4rem); line-height: 1.04;
  letter-spacing: -.03em; margin: 0 0 1rem; max-width: 18ch; font-weight: 800;
}
.hero p { font-size: clamp(1.05rem, 2.2vw, 1.3rem); max-width: 52ch; margin: 0 0 2rem; opacity: .95; }
.hero-actions { display: flex; flex-wrap: wrap; gap: .75rem; }
.eyebrow {
  display: inline-block; font-size: .8rem; font-weight: 800;
  letter-spacing: .13em; text-transform: uppercase;
  padding: .35rem .8rem; border-radius: 999px; margin-bottom: 1.25rem;
  background: rgba(255, 255, 255, .16); border: 1px solid rgba(255, 255, 255, .28);
}

/* --- sections ------------------------------------------------------ */
section { padding: clamp(2.5rem, 7vw, 5rem) 0; }
.section-alt { background: var(--paper-warm); }
h2 {
  font-family: var(--display); font-size: clamp(1.6rem, 3.6vw, 2.35rem);
  letter-spacing: -.022em; margin: 0 0 .5rem; font-weight: 800;
}
.lede { color: var(--ink-soft); max-width: 60ch; margin: 0 0 2rem; font-size: 1.05rem; }

.grid { display: grid; gap: 1.25rem; }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

.card {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.5rem; box-shadow: var(--shadow);
}
.card h3 { margin: 0 0 .5rem; font-size: 1.15rem; letter-spacing: -.012em; }
.card p { margin: 0; color: var(--ink-soft); }
.card-link { text-decoration: none; color: inherit; display: block; }
.card-link:hover { border-color: var(--brand); }
/* A TREATMENT'S PRICE: the figure, then what it is for, on one line. */
.card .price { margin-top: .75rem; color: var(--ink); }
.card .price strong { color: var(--brand-text); font-size: 1.1rem; }

/* --- booking ------------------------------------------------------- */
.booker {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden;
}
.booker-head {
  padding: 1.35rem 1.5rem; border-bottom: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 1rem; align-items: end;
}
.field { display: grid; gap: .35rem; }
.field label { font-size: .8rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); }
.field input, .field select {
  font: inherit; min-height: 44px; padding: .55rem .7rem;
  border: 1px solid var(--control-line); border-radius: 10px;
  background: var(--paper); color: var(--ink);
}
.booker-body { padding: 1.5rem; }
/* THE SIGN-IN CARD is a booker with no head or body inside it, so it
   carries its own padding: its labels and inputs sat on the border. */
.booker.signin { padding: 1.5rem; display: grid; gap: 1rem; max-width: 32rem; }
.booker.signin p { margin: 0; }

.slots { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); }
.slot {
  min-height: 48px; border-radius: 10px; border: 1px solid var(--control-line);
  background: var(--paper); font: inherit; font-weight: 700; cursor: pointer;
  display: grid; place-items: center; line-height: 1.2; padding: .4rem;
}
.slot:hover { border-color: var(--brand); background: var(--paper-warm); }
.slot[aria-pressed="true"] { background: var(--brand); color: #fff; border-color: var(--brand); }
.slot small { display: block; font-weight: 600; opacity: .85; font-size: .78rem; }

.note { color: var(--ink-soft); font-size: .95rem; }
.ok {
  border: 1px solid var(--ok); background: #eef7f2; color: #145033;
  border-radius: var(--radius); padding: 1rem 1.15rem; font-weight: 600;
}
.bad {
  border: 1px solid #a3301a; background: #fdf1ec; color: #7d2412;
  border-radius: var(--radius); padding: 1rem 1.15rem; font-weight: 600;
}

/* A SPINNER THAT SAYS SOMETHING. A bare animation tells a screen
 * reader nothing, so the live region carries the words and this is
 * decorative. */
.spinner {
  width: 18px; height: 18px; border-radius: 50%; flex: none;
  border: 2px solid var(--line); border-top-color: var(--brand);
  animation: spin .7s linear infinite; display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* --- footer -------------------------------------------------------- */
/* THE PAGE FOOTER, and only the page footer. Scoped to a direct child
   of body because <footer> is also the correct element for the
   attribution inside a <blockquote> -- and an unscoped rule painted
   one dark green on dark green, which is how a member's name became
   an empty rectangle. Found by looking at the page rather than by
   reading the stylesheet. */
body > footer { background: var(--brand-deep); color: #fff; padding: 3rem 0 2.5rem; }
body > footer a { color: #fff; }
/* THE FOOTER'S THREE SLOTS, each from the site entry; one the entry leaves
   empty takes no room (and draws no rule). */
.site-foot .wrap > :empty { display: none; }
.foot-name { margin: 0 0 .5rem; font-weight: 800; font-size: 1.05rem; letter-spacing: -.015em; }
.foot-links {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 0 1.5rem;
}
/* 44px, like every other target: they were 32 (the public walk). */
.foot-links a { min-height: 44px; display: inline-flex; align-items: center; font-weight: 600; }
.colophon {
  margin-top: 2.5rem; padding-top: 1.5rem;
  border-top: 1px solid rgba(255, 255, 255, .22);
  font-size: .86rem; opacity: .92;
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ------------------------------------------------------------------ */
/* My account                                                         */
/* ------------------------------------------------------------------ */

/* A table, because an order history IS tabular: a date, a state and an
   amount per row, compared down the columns. Cards would look tidier
   and would stop somebody scanning for the one that cost £94.30. */
.rows { width: 100%; border-collapse: collapse; margin-top: .5rem; }
.rows th, .rows td {
  text-align: left;
  padding: .7rem .8rem;
  border-bottom: 1px solid var(--line);
}
.rows th { font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; }
.rows tbody tr:last-child td { border-bottom: 0; }
/* A FIGURE IN A COLUMN reads from the right (27 Sep 2026: a class, where it
   was a style="" the composed pages' policy refuses). */
.rows .num { text-align: right; }

/* THE PITCH TYPE CHOSEN, as a card's border (caravan-booking.js), stated
   here rather than written into each card. */
.pitch-card { text-align: left; border: 2px solid var(--line); }
.pitch-card[aria-pressed="true"] { border-color: var(--brand); }

/* Label and value, side by side on a wide screen and stacked on a
   phone -- a definition list rather than a table because it is one
   thing described, not several compared. */
.detail { margin: 0; display: grid; gap: .1rem .9rem; }
.detail dt { font-weight: 600; }
.detail dd { margin: 0 0 .6rem; }
@media (min-width: 40rem) {
  .detail { grid-template-columns: max-content 1fr; }
  .detail dd { margin-bottom: .2rem; }
}

/* THE STATE IS A WORD, NOT A COLOUR. Colour is added on top for people
   who can use it, and removing it loses nothing: "confirmed" still
   reads as confirmed in monochrome, which is the whole test. */
.state {
  display: inline-block;
  margin: .2rem 0 0;
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--ink-soft, #5a5a5a);
}
.state-confirmed { color: var(--ok, #2f6b3c); }
/* AS TEXT, the accent's text token: the arena's fill orange is 3.6:1 on
   its own paper. */
.state-held { color: var(--accent-text); }
.state-cancelled, .state-expired { color: var(--bad, #8a2b20); }

.stay { margin: .15rem 0 0; }

.account-grid { display: grid; gap: 1.5rem; }
@media (min-width: 52rem) {
  .account-grid { grid-template-columns: 1fr 1fr; }
}

/* ------------------------------------------------------------------ */
/* The nightly calendar                                               */
/* ------------------------------------------------------------------ */

.cal { width: 100%; border-collapse: collapse; table-layout: fixed; }
.cal caption {
  text-align: left;
  font-weight: 700;
  font-size: 1.1rem;
  padding: 0 0 .6rem;
}
.cal th {
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  padding: .4rem 0;
  color: var(--ink-soft, #5a5a5a);
}
.cal td {
  border: 1px solid var(--line);
  vertical-align: top;
  height: 4.4rem;
  padding: 0;
}
.cal-empty { border-color: transparent; }
.cal-day { display: block; font-weight: 600; font-size: .85rem; }

/* THE PRICE IS THE POINT OF THE CELL, so it is the thing with size.
   A grid of identical numbered boxes is a calendar; a grid where the
   cost of each night is legible at a glance is a booking screen. */
.cal-price { display: block; font-weight: 700; font-size: .95rem; }
.cal-note {
  display: block;
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .03em;
}

/* NEVER COLOUR ALONE. Every state also carries its own word -- FULL,
   CLOSED, LOW -- so the calendar survives being printed, photocopied
   or read by somebody who does not see the difference between the
   greens and the reds. Removing the colour loses nothing. */
.cal-free { background: var(--paper, #fff); }
.cal-full, .cal-shut { color: var(--ink-soft, #6a6a6a); }
.cal-full { background: repeating-linear-gradient(
  45deg, transparent, transparent 5px,
  rgba(0, 0, 0, .05) 5px, rgba(0, 0, 0, .05) 10px); }
.cal-shut { background: var(--paper-warm); }
.cal-low .cal-note { color: var(--accent-text); }

.cal-pick {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 4.4rem;
  padding: .35rem .3rem;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.cal-pick:hover { background: var(--paper-warm); }
.cal-pick:focus-visible { outline: 3px solid var(--brand); outline-offset: -3px; }
.cal-pick[aria-pressed="true"] {
  background: var(--brand);
  color: #fff;
}

.cal-shut .cal-day, .cal-full .cal-day { padding: .35rem .3rem 0; }
.cal-shut .cal-note, .cal-full .cal-note { padding: 0 .3rem; }

/* A phone cannot show seven columns of this legibly, so it stops
   pretending to be a grid and becomes a list of nights. */
@media (max-width: 34rem) {
  .cal, .cal tbody, .cal tr, .cal td { display: block; width: auto; }
  .cal thead { display: none; }
  .cal td { height: auto; border-width: 0 0 1px; }
  .cal-empty { display: none; }
  .cal-pick { display: flex; gap: .7rem; align-items: baseline; }
  .cal-day::after { content: ""; }
}

/* ------------------------------------------------------------------ */
/* Visual furniture                                                   */
/*                                                                    */
/* Added because four sites that are all a hero, three cards and a    */
/* form look like four instances of one template -- which is exactly  */
/* what a prospect must not think, because the thing being sold is    */
/* that their site would look like THEIRS. Every piece below is       */
/* layout, and every colour in it comes from the tenant's own tokens. */
/* ------------------------------------------------------------------ */

/* THE NUMBERS BAND. A club's facts, large. "Eight courts, four
   floodlit, since 1934" does more work at a glance than a paragraph
   saying the same thing, and it is the cheapest way to make a page
   feel specific rather than generic. */
.figures {
  display: grid;
  gap: 1.5rem 2.5rem;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  padding: clamp(2rem, 5vw, 3rem) 0;
  border-block: 1px solid var(--line);
}
/* DOM ORDER IS "Courts, eight" -- label then value -- because that is
   how a definition list reads aloud and how it should. Visually the
   number wants to come first, so the pair is flipped in the layout
   rather than in the markup: column-reverse changes what the eye sees
   and nothing about what is read. */
.figures > div {
  display: flex;
  flex-direction: column-reverse;
  align-items: start;
}
.figures dd { margin: 0; }          /* browsers indent dd by default */
.figures dt { margin: 0; }

.figure-n {
  display: block;
  font-family: var(--display);
  font-size: clamp(2.1rem, 5vw, 3.1rem);
  line-height: 1;
  letter-spacing: -.03em;
  font-weight: 800;
  color: var(--brand-text);
}
.figure-l {
  display: block;
  margin-bottom: .45rem;
  font-size: .85rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* A SPLIT: words one side, a picture the other. Reverses on alternate
   sections so a page of them has rhythm rather than a column of
   identical rows. Stacks on a phone with the picture first, because a
   heading immediately under a photograph reads as its caption. */
.split {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}
@media (min-width: 52rem) {
  .split { grid-template-columns: 1fr 1fr; }
  .split-flip .split-media { order: 2; }
}
.split-media {
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  aspect-ratio: 4 / 3;
  background: var(--paper-warm) center/cover no-repeat;
}
.split h2 { margin-top: 0; }

/* A PULL QUOTE. One member's sentence, set large. Marked up as a
   blockquote with a cite so it is a quotation to a screen reader and
   not decorative large text. */
.quote {
  margin: 0;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  background: var(--paper-warm);
  border-radius: var(--radius);
  border-left: 4px solid var(--accent);
}
.quote p {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.15rem, 2.6vw, 1.5rem);
  line-height: 1.4;
  letter-spacing: -.015em;
}
.quote footer { margin-top: .9rem; font-size: .9rem; color: var(--ink-soft); }

/* A SECTION EYEBROW, distinct from the hero's: small, quiet, and used
   to give a long page landmarks that are not all the same size. */
.kicker {
  display: block;
  margin: 0 0 .5rem;
  font-size: .78rem;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent-text);
}

/* CARDS THAT LIFT, very slightly, and only for a pointer. The
   transform is behind prefers-reduced-motion with everything else. */
.card-link { transition: transform .18s ease, box-shadow .18s ease; }
@media (hover: hover) {
  .card-link:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
}

/* A BAND that inverts, for one section on a page. Used sparingly: two
   of these and the page is stripes. The text colour is set explicitly
   rather than inherited, because a tenant token changing under it is
   how white-on-white happens. */
.band {
  background: var(--brand-deep);
  color: #fff;
}
.band h2, .band h3 { color: #fff; }
.band .lede, .band p { color: rgba(255, 255, 255, .88); }
.band .btn-quiet { border-color: rgba(255, 255, 255, .55); color: #fff; }
.band .btn-quiet:hover { background: rgba(255, 255, 255, .12); }

/* The card the map has chosen, so the two halves agree. */
.card.is-on {
  border-color: var(--brand);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand) 35%, transparent);
}
