/* ===========================================================================
   King's Sports Centre / Powerhouse Gym

   ONE theme, committed. An earlier build split light and dark across the site
   and it read as an accident rather than a decision — mixing background tones
   mid-journey is the single fastest way to look unfinished.

   Palette is sampled from kingssportscentre.com, not invented:
     #2F2E2E  charcoal (their section background)
     #606060  mid grey (their most-used surface)
     #A8A8A8  light grey (their body text)
     #F4A111  logo gold, with #CC8908 as the deep tone
   Off-black grounds rather than #000, so photography and shadows have somewhere
   to sit.

   Type pairing is swappable — see src/lib/fonts.js and /fontlab. Default is
   Oswald over Public Sans. Weights sit at 600 with 700 reserved for the few
   places that genuinely need to shout; heavy weight plus uppercase compounds
   fast, and reads as shouting rather than confident.
   =========================================================================== */

/* Brand constants — identical in both themes. */
:root {
  --gold: #f4a111;
  --gold-deep: #cc8908;
  --gold-bright: #ffbe45;
  --red: #e03a3e;               /* Powerhouse franchise red, used sparingly */

  --radius: 4px;
  --radius-lg: 8px;

  /* Overridden inline on <body> by lib/fonts.js. These are the fallbacks. */
  --display: "Oswald", "Arial Narrow", Impact, sans-serif;
  --sans: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --display-tracking: .01em;

  --maxw: 1180px;
  --z-bar: 40;
  --z-tab: 50;
  --z-install: 60;
}

/* ---------------------------------------------------------------------------
   Two themes, assigned per page rather than per section.
   
   `.theme-dark`  — Powerhouse Gym: the gym page, the rates, the timetable and
                    every signed-in surface. Gold on off-black.
   `.theme-light` — King's Sports Centre: the front door, King's Kids, trainers,
                    contact. Warm and welcoming, because the people landing there
                    are families deciding whether to visit at all.

   A whole page commits to one, with the header and footer constant either way.
   The exception is `.zone-dark`, which drops the dark token set onto a single
   band: the front page is light, but the membership block and the photo wall
   belong to the gym, and they carry the gym's colours down with them. Both
   selectors share one token list, so a palette change cannot land on half the
   site.
   --------------------------------------------------------------------------- */

.theme-dark,
.zone-dark {
  --ground: #131211;
  --ground-2: #191817;
  --surface: #1d1c1a;
  --surface-2: #262421;
  --surface-3: #322f2b;
  --line: #2c2a27;
  --line-strong: #423e39;

  --ink: #f5f2ee;
  --ink-2: #c3bdb4;
  --ink-3: #a8a8a8;             /* their light grey, verbatim */
  --muted: #7d766d;

  --accent: var(--gold);
  --on-accent: #16120a;

  --ok: #4fbf82;
  --ok-soft: #16261d;
  --warn: #e0a33c;
  --warn-soft: #2a2113;
  --bad: #e5695c;
  --bad-soft: #2b1715;
  --track: #2a2724;

  --shadow-sm: 0 1px 2px rgba(8, 6, 4, .5);
  --shadow: 0 4px 10px rgba(8, 6, 4, .45), 0 16px 40px rgba(8, 6, 4, .4);
  --shadow-lg: 0 12px 30px rgba(8, 6, 4, .55), 0 40px 80px rgba(8, 6, 4, .5);
  --glow: 0 0 0 1px rgba(244, 161, 17, .35), 0 8px 30px rgba(244, 161, 17, .12);

  --scrim: linear-gradient(90deg, rgba(12, 11, 10, .96) 0%, rgba(12, 11, 10, .84) 42%, rgba(12, 11, 10, .38) 100%),
           linear-gradient(0deg, rgba(12, 11, 10, .9) 0%, transparent 45%);
}

.theme-light {
  --ground: #faf7f2;
  --ground-2: #f3ece1;
  --surface: #ffffff;
  --surface-2: #faf6f0;
  --surface-3: #efe7db;
  --line: #e7dece;
  --line-strong: #d0c3ad;

  --ink: #1c1a18;
  --ink-2: #4c4740;
  --ink-3: #6d675e;
  --muted: #8d867b;

  /* Logo gold is too pale for text on white; the deep tone carries it. */
  --accent: #a86e07;
  --on-accent: #16120a;

  --ok: #2e8f5c;
  --ok-soft: #e7f4ec;
  --warn: #9a6a12;
  --warn-soft: #fdf3e0;
  --bad: #b8382c;
  --bad-soft: #fceceb;
  --track: #e7ded0;

  --shadow-sm: 0 1px 2px rgba(60, 45, 25, .06);
  --shadow: 0 2px 6px rgba(60, 45, 25, .07), 0 14px 34px rgba(60, 45, 25, .08);
  --shadow-lg: 0 10px 26px rgba(60, 45, 25, .1), 0 34px 70px rgba(60, 45, 25, .12);
  --glow: 0 0 0 1px rgba(244, 161, 17, .55), 0 8px 26px rgba(244, 161, 17, .18);

  /* Lighter scrim: the hero photo should feel open, not sealed off. */
  --scrim: linear-gradient(90deg, rgba(20, 16, 12, .82) 0%, rgba(20, 16, 12, .6) 45%, rgba(20, 16, 12, .18) 100%),
           linear-gradient(0deg, rgba(20, 16, 12, .7) 0%, transparent 50%);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 16.5px;
  line-height: 1.62;
  color: var(--ink);
  background: var(--ground);
  padding-bottom: env(safe-area-inset-bottom);
  -webkit-font-smoothing: antialiased;
  position: relative;
}

/* Fine grain over the whole page. Flat dark UI looks like a slab of plastic;
   a little noise gives it a surface. */
.theme-dark body::after,
body.theme-dark::after {
  content: "";
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  opacity: .16;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
}
main, header, footer, section { position: relative; z-index: 2; }

/* --- Type ----------------------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 600;
  text-transform: uppercase;
  line-height: .98;
  /* Each pairing carries its own tracking — condensed faces need a little
     positive tracking in caps, heavy grotesques need negative. */
  letter-spacing: var(--display-tracking);
  margin: 0 0 .6rem;
  color: var(--ink);
  text-wrap: balance;
}
h1 { font-size: clamp(2.6rem, 7vw, 5.2rem); font-weight: 700; }
h2 { font-size: clamp(1.9rem, 4vw, 3rem); }
/* Card and panel titles drop the caps — uppercase everywhere flattens the
   hierarchy, and sentence case here makes h1/h2 read as the loud ones. */
h3 { font-size: 1.3rem; letter-spacing: 0; text-transform: none; }
h4 { font-size: 1.05rem; letter-spacing: .01em; text-transform: none; }
p { margin: 0 0 1rem; max-width: 68ch; text-wrap: pretty; }
a { color: var(--accent); text-underline-offset: 3px; }
small { font-size: .82rem; }
strong { font-weight: 600; }
::selection { background: var(--gold); color: var(--on-accent); }

:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* Data should never wobble as it updates. */
.num, .stat .v, .plan .price, .classcard .time, td, th, .meter-row { font-variant-numeric: tabular-nums; }

.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 1.2rem; }
.wrap-narrow { max-width: 680px; }

/* Section label. Tracked-out gold caps, no decorative rule. */
.kicker {
  font-family: var(--sans);
  font-size: .68rem; font-weight: 600;
  letter-spacing: .24em; text-transform: uppercase;
  color: var(--gold);
  margin-bottom: .7rem;
}

.lede { font-size: 1.1rem; color: var(--ink-2); }

/* --- Header --------------------------------------------------------------- */

.topbar {
  background: rgba(13, 12, 11, .92);
  backdrop-filter: blur(10px);
  position: sticky; top: 0; z-index: var(--z-bar);
  border-bottom: 1px solid var(--line);
}
.topbar-inner { display: flex; align-items: center; gap: 1rem; min-height: 68px; }

.brand { display: flex; align-items: center; gap: .65rem; text-decoration: none; color: #fff; }
.brand img { height: 40px; width: auto; display: block; }
.brand-text { display: flex; flex-direction: column; line-height: 1; }
.brand-text b {
  font-family: var(--display); font-size: 1.3rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .02em;
}
.brand-text span {
  font-size: .54rem; letter-spacing: .26em; text-transform: uppercase;
  color: var(--gold); margin-top: .25rem; font-weight: 600;
}

/* No wrapping: a second row of links inside a 68px bar overflows it. The
   burger takes over before the items would ever need to fold. */
.nav { margin-left: auto; display: flex; gap: 0; align-items: center; flex-wrap: nowrap; }
.nav a {
  color: var(--bar-ink); text-decoration: none; white-space: nowrap;
  padding: .5rem .6rem; font-size: .78rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em;
  border-bottom: 2px solid transparent; transition: color .15s, border-color .15s;
}
.nav a:hover { color: var(--bar-ink-strong); border-bottom-color: var(--bar-line); }
.nav a.on { color: var(--gold); border-bottom-color: var(--gold); }
.nav a.cta {
  background: var(--gold); color: var(--on-accent);
  border-bottom-color: var(--gold); margin-left: .4rem;
}
.nav a.cta:hover { background: var(--gold-bright); color: var(--on-accent); }


@media (max-width: 1180px) {
  .nav a, .menu-top { font-size: .7rem; padding: .4rem .42rem; letter-spacing: .05em; }
}
@media (max-width: 820px) {
  .nav a { font-size: .7rem; padding: .4rem .5rem; letter-spacing: .06em; }
  .brand-text span { display: none; }
  .brand img { height: 32px; }
}

/* --- Hero ----------------------------------------------------------------- */

.hero { position: relative; overflow: hidden; isolation: isolate; padding: clamp(3.5rem, 10vw, 7.5rem) 0; }
.hero-media { position: absolute; inset: 0; z-index: -2; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; object-position: center 38%; }
/* Scrim: dark enough to hold type, angled so the photo still reads. */
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--scrim);
}
.hero h1 { color: #fff; }
.hero h1 em { font-style: normal; color: var(--gold); display: block; }
.hero .kicker { color: var(--gold-bright); }
.hero .lede { color: rgba(255, 255, 255, .84); }

/* Hero copy is hardcoded white because the scrim behind it is always dark,
   whatever theme the page is in. The ghost button was still reaching for
   --ink, which on a light page is near-black on a dark photograph - the
   secondary action was effectively invisible. Give it the same fixed
   treatment as the headline. The gold panel variant overrides this below with
   higher specificity, because there the background is light. */
.hero .btn.ghost {
  color: #fff;
  border-color: rgba(255, 255, 255, .55);
  background: rgba(12, 11, 10, .28);
  backdrop-filter: blur(2px);
}
.hero .btn.ghost:hover {
  color: var(--gold);
  border-color: var(--gold);
  background: rgba(12, 11, 10, .5);
}
.hero p { color: rgba(255, 255, 255, .84); max-width: 46ch; font-size: 1.08rem; }
/* Left edge lines up with .wrap; only the measure is constrained. */
.hero-inner { max-width: 40rem; margin-left: 0; }

.hero-stats { display: flex; gap: 2.4rem; flex-wrap: wrap; margin-top: 2.2rem; }
.hero-stats div span {
  display: block; font-family: var(--display); font-weight: 700;
  font-size: 2.6rem; line-height: 1; color: var(--gold);
}
.hero-stats div small {
  text-transform: uppercase; letter-spacing: .16em;
  font-size: .62rem; color: var(--muted); font-weight: 600;
}

/* Compact hero for interior pages. */
.hero.slim { padding: clamp(2.5rem, 6vw, 4rem) 0; }
.hero.slim h1 { font-size: clamp(2.2rem, 5vw, 3.6rem); }

/* --- Sections ------------------------------------------------------------- */
/* Deliberately NOT alternating light/dark. Depth comes from surface steps. */

section.band { padding: clamp(2.5rem, 6vw, 4.5rem) 0; }
section.band.alt { background: var(--ground-2); border-block: 1px solid var(--line); }

/* Redeclaring the tokens changes what descendants resolve to; the band still
   has to paint its own ground, and the seam needs a line so two stacked zones
   do not merge into one slab. */
section.band.zone-dark {
  background: var(--ground);
  color: var(--ink);
  border-block: 1px solid var(--line);
}
section.band.zone-dark + section.band.zone-dark { border-top: 0; padding-top: 0; }

.section-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1rem; margin-bottom: 1.6rem; flex-wrap: wrap;
}
.section-head h2 { margin-bottom: 0; }
.section-head a {
  font-size: .74rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .14em; white-space: nowrap; text-decoration: none;
  border-bottom: 1px solid var(--line-strong); padding-bottom: .15rem;
}
.section-head a:hover { border-bottom-color: var(--gold); }

.grid { display: grid; gap: 1.1rem; }
.g2 { grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); }
.g3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.g4 { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
/* Pricing cards need width. At ~180px the blurbs wrap to four or five lines,
   heights diverge, and margin-top:auto turns the difference into dead space
   above the shorter cards' buttons. */
.planrow { grid-template-columns: repeat(auto-fit, minmax(252px, 1fr)); }

/* Asymmetric split — avoids the three-equal-columns default. */
.split { display: grid; gap: 1.6rem; grid-template-columns: 1.35fr .65fr; align-items: start; }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; } }

/* --- Cards ---------------------------------------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.3rem;
}
.card.tight { padding: .95rem; }
.card.raised { box-shadow: var(--shadow); }
.card.feature { border-color: var(--gold); box-shadow: var(--glow); }
.card h3 { margin-top: 0; }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin-bottom: .8rem; }

/* Photo-topped card. */
.photocard { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.photocard .shot { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--surface-2); }
.photocard .shot img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s cubic-bezier(.2,.7,.3,1); }
.photocard:hover .shot img { transform: scale(1.045); }
.photocard .shot::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(0deg, rgba(15, 13, 12, .82), transparent 58%);
}
.photocard .body { padding: 1rem 1.15rem 1.2rem; flex: 1; display: flex; flex-direction: column; }
.photocard .body .btn { margin-top: auto; }
.photocard .label {
  position: absolute; left: 0; bottom: 0; z-index: 2;
  padding: .7rem .9rem; font-family: var(--display); font-weight: 600;
  font-size: 1.25rem; text-transform: uppercase; color: #fff; letter-spacing: .01em;
}

/* --- Buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  background: var(--gold); color: var(--on-accent);
  border: 1px solid var(--gold);
  padding: .72rem 1.4rem; border-radius: var(--radius);
  font-family: var(--sans); font-weight: 600; font-size: .82rem;
  text-transform: uppercase; letter-spacing: .12em;
  text-decoration: none; cursor: pointer;
  transition: background .16s, transform .1s, border-color .16s, color .16s;
}
.btn:hover { background: var(--gold-bright); border-color: var(--gold-bright); }
.btn:active { transform: translateY(1px); }
.btn.ghost { background: transparent; color: var(--ink); border-color: var(--line-strong); }
.btn.ghost:hover { background: transparent; border-color: var(--gold); color: var(--gold); }
.btn.dark { background: var(--surface-2); color: var(--ink); border-color: var(--line-strong); }
.btn.dark:hover { background: var(--surface-3); border-color: var(--gold); }
.btn.danger { background: transparent; color: var(--bad); border-color: rgba(229, 105, 92, .45); }
.btn.danger:hover { background: var(--bad-soft); border-color: var(--bad); }
.btn.sm { padding: .4rem .8rem; font-size: .7rem; letter-spacing: .1em; }
.btn.lg { padding: .95rem 1.9rem; font-size: .9rem; }
.btn.block { width: 100%; }
.btn[disabled], .btn.disabled { opacity: .4; pointer-events: none; }
.btnrow { display: flex; gap: .7rem; flex-wrap: wrap; align-items: center; }

/* --- Forms ---------------------------------------------------------------- */

label {
  display: block; font-size: .68rem; font-weight: 600; color: var(--ink-3);
  margin-bottom: .35rem; text-transform: uppercase; letter-spacing: .12em;
}
input[type=text], input[type=email], input[type=password], input[type=tel],
input[type=date], input[type=time], input[type=number], input[type=search],
select, textarea {
  width: 100%; padding: .78rem .85rem;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  font: inherit; font-size: 16px;
  background: var(--ground-2); color: var(--ink);
  transition: border-color .15s, box-shadow .15s;
}
input::placeholder, textarea::placeholder { color: var(--muted); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(244, 161, 17, .18);
}
.field { margin-bottom: 1.1rem; }
.field-row { display: grid; gap: .85rem; grid-template-columns: 1fr 1fr; }
@media (max-width: 540px) { .field-row { grid-template-columns: 1fr; } }
.check { display: flex; gap: .65rem; align-items: flex-start; font-size: .88rem; font-weight: 400; color: var(--ink-2); text-transform: none; letter-spacing: 0; }
.check input { margin-top: .3rem; width: auto; flex: none; accent-color: var(--gold); }

/* --- Pills and alerts ----------------------------------------------------- */

.pill {
  display: inline-block; padding: .22rem .55rem; border-radius: 2px;
  font-size: .62rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; vertical-align: middle;
  border: 1px solid transparent;
}
.pill.gold { background: rgba(244, 161, 17, .13); color: var(--gold); border-color: rgba(244, 161, 17, .35); }
.pill.ok { background: var(--ok-soft); color: var(--ok); }
.pill.warn { background: var(--warn-soft); color: var(--warn); }
.pill.bad { background: var(--bad-soft); color: var(--bad); }
.pill.grey { background: var(--surface-2); color: var(--ink-3); }
.pill.tier1 { background: var(--surface-2); color: var(--ink-3); }
.pill.tier2 { background: rgba(244, 161, 17, .12); color: var(--gold); }
.pill.tier3 { background: var(--gold); color: var(--on-accent); }

.alert {
  padding: .9rem 1.1rem; border-radius: var(--radius);
  border-left: 3px solid; margin-bottom: 1.2rem; font-size: .9rem;
  background: var(--surface-2); color: var(--ink-2);
}
.alert.success { border-color: var(--ok); background: var(--ok-soft); }
.alert.error { border-color: var(--bad); background: var(--bad-soft); }
.alert.info { border-color: var(--gold); background: var(--warn-soft); }
.alert.warn { border-color: var(--warn); background: var(--warn-soft); }

.notice {
  font-size: .84rem; color: var(--ink-3); background: var(--ground-2);
  border: 1px solid var(--line); border-radius: var(--radius); padding: .8rem .95rem;
}
.wireflag {
  font-size: .8rem; color: var(--warn); background: var(--warn-soft);
  border: 1px dashed rgba(224, 163, 60, .45); border-radius: var(--radius); padding: .7rem .9rem;
}

/* --- Meters --------------------------------------------------------------- */

.meter { height: 6px; border-radius: 99px; background: var(--track); overflow: hidden; }
.meter > span { display: block; height: 100%; border-radius: 99px; transition: width .6s cubic-bezier(.4, 0, .2, 1); }
/* Scope the fill to .meter specifically. `.lvl-quiet > span` on its own also
   matches the label spans inside .meter-row, which carries the same lvl-* class
   — that paints solid colour blocks behind the text instead of filling a bar. */
.meter.lvl-quiet > span, .meter.lvl-low > span { background: var(--ok); }
.meter.lvl-medium > span { background: var(--gold); }
.meter.lvl-high > span { background: #e08a3c; }
.meter.lvl-full > span { background: var(--bad); }
.lvl-quiet .lbl, .lvl-low .lbl { color: var(--ok); }
.lvl-medium .lbl { color: var(--gold); }
.lvl-high .lbl { color: #e08a3c; }
.lvl-full .lbl { color: var(--bad); }
.meter-row {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: .68rem; margin-bottom: .35rem; gap: .5rem;
  text-transform: uppercase; letter-spacing: .1em;
}
.meter-row .lbl { font-weight: 600; }


/* --- Class rows ----------------------------------------------------------- */

.daygroup { margin-bottom: 1.9rem; }
.dayhead {
  position: sticky; top: 68px; z-index: 5;
  background: var(--ground); padding: .75rem 0 .55rem;
  font-family: var(--display); font-size: 1.3rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .02em;
  border-bottom: 2px solid var(--gold); margin-bottom: .8rem;
}
.dayhead .today {
  color: var(--gold); font-family: var(--sans); font-size: .6rem;
  letter-spacing: .2em; margin-left: .7rem; font-weight: 600;
}

.slot {
  display: grid; grid-template-columns: 92px 1fr auto; gap: 1rem; align-items: center;
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid transparent;
  border-radius: var(--radius); padding: .9rem 1.1rem; margin-bottom: .5rem;
  transition: border-color .16s, background .16s;
}
.slot:hover { border-left-color: var(--gold); background: var(--surface-2); }
.slot.cancelled { opacity: .45; }
.slot .when {
  font-family: var(--display); font-weight: 600; font-size: 1.5rem;
  color: var(--ink); line-height: 1;
}
.slot .when small {
  display: block; font-family: var(--sans); font-weight: 400;
  color: var(--muted); font-size: .68rem; margin-top: .2rem;
  text-transform: uppercase; letter-spacing: .08em;
}
.slot .what strong {
  display: block; font-family: var(--display); font-size: 1.28rem;
  font-weight: 600; text-transform: uppercase; letter-spacing: .01em; line-height: 1.1;
}
.slot .what .meta { color: var(--ink-3); font-size: .8rem; }
.slot .act { text-align: right; min-width: 150px; }
@media (max-width: 680px) {
  .slot { grid-template-columns: 72px 1fr; }
  .slot .when { font-size: 1.25rem; }
  .slot .act { grid-column: 1 / -1; text-align: left; }
  .slot .act .meter { margin-top: .4rem; }
}

/* --- Tables --------------------------------------------------------------- */

.tablewrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
}
table { width: 100%; border-collapse: collapse; font-size: .88rem; }
th, td { text-align: left; padding: .72rem .85rem; border-bottom: 1px solid var(--line); white-space: nowrap; }
th {
  background: var(--ground-2); font-size: .62rem; text-transform: uppercase;
  letter-spacing: .16em; color: var(--muted); font-weight: 600;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--surface-2); }
td.wrap-cell, th.wrap-cell { white-space: normal; }
td.price { font-family: var(--display); font-size: 1.15rem; font-weight: 600; color: var(--gold); }

/* Rate card, styled after the printed sheet. */
.ratecard .group td { border-bottom: 2px solid var(--line-strong); }
.ratecard .duration {
  font-family: var(--display); text-transform: uppercase;
  font-size: 1.05rem; font-weight: 600; color: var(--ink); letter-spacing: .04em;
}

/* --- Stats ---------------------------------------------------------------- */

.stat {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.1rem 1.15rem;
  border-top: 2px solid var(--gold);
}
.stat .k { font-size: .6rem; text-transform: uppercase; letter-spacing: .18em; color: var(--muted); font-weight: 600; }
.stat .v { font-family: var(--display); font-size: 2.3rem; font-weight: 700; line-height: 1.05; color: var(--ink); }
.stat .s { font-size: .74rem; color: var(--ink-3); }

/* --- Pricing -------------------------------------------------------------- */

/* Spacing is deliberate: the tier pill, the name and the price were reading as
   one clump, while the stretched .foot left a hole above the button. Give the
   top of the card room and even the rhythm out. */
.plan { display: flex; flex-direction: column; position: relative; padding: 1.6rem 1.5rem 1.5rem; }
.plan.featured { border-color: var(--gold); box-shadow: var(--glow); }
.plan .badge {
  position: absolute; top: -1px; right: -1px;
  background: var(--gold); color: var(--on-accent);
  font-size: .58rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
  padding: .3rem .75rem;
}
.plan > .pill { align-self: flex-start; margin-bottom: 1rem; }
.plan h3 { margin: 0 0 .2rem; line-height: 1.15; }
.plan .price {
  font-family: var(--display); font-size: 3rem; font-weight: 700;
  line-height: 1; margin: .7rem 0 .3rem; color: #fff;
}
.plan > p { margin-bottom: 1.4rem; line-height: 1.55; }
.plan .price span { font-family: var(--sans); font-size: .72rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .12em; }
.plan ul { list-style: none; padding: 0; margin: 1rem 0; font-size: .85rem; }
/* A small dot carries "included / not included" without a glyph shouting it.
   Gold means included, grey means extra — no arrows, ticks or crosses. */
.plan ul li { padding: .34rem 0 .34rem 1.15rem; position: relative; color: var(--ink-2); border-bottom: 1px solid var(--line); }
.plan ul li:last-child { border-bottom: 0; }
.plan ul li::before {
  content: ""; position: absolute; left: 0; top: 1.05em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--gold);
}
/* Excluded lines get a cross rather than a dimmer dot — a grey dot reads as a
   quieter bullet, not as "you do not get this". The text stays, so the steam
   room line still says what it costs. */
.plan ul li.no { color: var(--muted); }
.plan ul li.no::before {
  content: "\00d7";                 /* multiplication sign — present in every font */
  width: auto; height: auto; border-radius: 0; background: none;
  color: var(--bad);
  font-size: 1.05em; font-weight: 700; line-height: 1;
  top: .78em; left: -1px;
}
/* Pin CTAs to a common baseline across a row of cards. margin-top:auto does the
   aligning; padding-top guarantees a gap even when a card is the tall one and
   auto collapses to nothing. */
.plan .foot { margin-top: auto; padding-top: 1.4rem; }

/* --- Member app ----------------------------------------------------------- */

.appbar {
  background: rgba(13, 12, 11, .94); backdrop-filter: blur(10px);
  padding: .85rem 0; position: sticky; top: 0; z-index: var(--z-bar);
  border-bottom: 1px solid var(--line);
}
.appbar-inner { display: flex; align-items: center; gap: .85rem; }
.appbar img.mark { height: 32px; width: auto; }
.appbar h1 { font-size: 1.35rem; color: #fff; margin: 0; }
.appbar .who { margin-left: auto; font-size: .72rem; color: var(--muted); text-align: right; line-height: 1.4; }
.appbar .who a { color: var(--gold); font-weight: 600; }

.appmain { padding: 1.4rem 0 6rem; }

.tabbar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: var(--z-tab);
  background: rgba(18, 17, 16, .97); backdrop-filter: blur(12px);
  border-top: 1px solid var(--line);
  display: flex; padding-bottom: env(safe-area-inset-bottom);
}
.tabbar a {
  flex: 1; text-align: center; padding: .6rem .2rem .65rem;
  text-decoration: none; color: var(--muted);
  font-size: .58rem; font-weight: 600; text-transform: uppercase; letter-spacing: .1em;
  border-top: 2px solid transparent; transition: color .15s;
}
.tabbar a .ic { display: block; font-size: 1.3rem; line-height: 1.35; }
.tabbar a.on { color: var(--gold); border-top-color: var(--gold); }

/* --- Install prompt ------------------------------------------------------- */

.install {
  position: fixed; left: .85rem; right: .85rem; z-index: var(--z-install);
  bottom: calc(72px + env(safe-area-inset-bottom));
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line-strong); border-left: 3px solid var(--gold);
  border-radius: var(--radius); padding: .95rem 1.05rem;
  box-shadow: var(--shadow-lg); display: none;
}
.install.show { display: flex; gap: .85rem; align-items: center; }
.install .txt { flex: 1; font-size: .82rem; line-height: 1.45; color: var(--ink-3); }
.install .txt strong {
  display: block; font-family: var(--display); font-size: 1.15rem;
  text-transform: uppercase; color: #fff; letter-spacing: .01em;
}
.install button { flex: none; }
.install .x { background: none; border: 0; color: var(--muted); font-size: 1.4rem; cursor: pointer; padding: 0 .2rem; line-height: 1; }

/* --- Footer --------------------------------------------------------------- */

.footer {
  background: #0d0c0b; color: var(--muted); padding: 3rem 0 2rem;
  font-size: .86rem; margin-top: 3rem; border-top: 2px solid var(--gold);
}
.footer a { color: var(--ink-3); text-decoration: none; }
.footer a:hover { color: var(--gold); }
.footer h4 { color: #fff; font-size: .8rem; letter-spacing: .16em; margin-bottom: .8rem; }
.footer .tagline {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .18em;
  color: var(--gold); font-size: .85rem; margin-top: .5rem;
}

/* --- Utilities ------------------------------------------------------------ */

.kv { display: grid; grid-template-columns: auto 1fr; gap: .5rem 1.2rem; font-size: .88rem; align-items: baseline; }
.kv dt { color: var(--muted); text-transform: uppercase; font-size: .68rem; letter-spacing: .1em; font-weight: 600; }
.kv dd { margin: 0; font-weight: 600; text-align: right; }

.muted { color: var(--muted); }
.right { text-align: right; }
.center { text-align: center; }
.mt0 { margin-top: 0; } .mt1 { margin-top: .85rem; } .mt2 { margin-top: 1.7rem; }
.mb0 { margin-bottom: 0; } .mb1 { margin-bottom: .85rem; } .mb2 { margin-bottom: 1.7rem; }
.hr { height: 1px; background: var(--line); border: 0; margin: 1.3rem 0; }
.stack > * + * { margin-top: .85rem; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .85em; }

.skiplink {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--gold); color: var(--on-accent); padding: .6rem 1rem; font-weight: 600;
}
.skiplink:focus { left: .5rem; top: .5rem; }


/* --- Payment -------------------------------------------------------------- */

.payshell { min-height: 100dvh; display: flex; align-items: center; justify-content: center; background: var(--ground); padding: 1.5rem 1rem; }
.paycard { max-width: 510px; width: 100%; }
.gatewaychrome {
  background: #0b3d91; color: #fff; padding: .85rem 1rem;
  border-radius: var(--radius) var(--radius) 0 0;
  font-size: .84rem; display: flex; align-items: center; gap: .5rem;
}


/* --- Motion / print ------------------------------------------------------- */

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

@media print {
  .topbar, .tabbar, .footer, .install, .btnrow, .nav, body::after { display: none !important; }
  body { background: #fff; color: #000; }
  .card, .slot { border-color: #ccc; background: #fff; }
}

/* ===========================================================================
   Mural
   ---------------------------------------------------------------------------
   Modelled on the Gold's Gym "wood wall": a grid of uniform square tiles where
   photographs are interleaved with plain texture tiles, so it reads as a
   physical wall of framed pictures rather than a gallery widget.

   Theirs alternates photos with wood panelling. Ours alternates photos with
   brand tiles — charcoal carrying the crown, gold carrying a short line of
   copy — which keeps the identity in the wall instead of borrowing a texture
   that means nothing to King's.
   =========================================================================== */

.mural {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 6px;
  background: var(--line);
  padding: 6px;
  border-radius: var(--radius);
}
.mural .tile {
  position: relative;
  aspect-ratio: 1;
  overflow: hidden;
  background: var(--surface-2);
}
.mural .tile img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  filter: grayscale(.35) contrast(1.05);
  transition: transform .6s cubic-bezier(.2,.7,.3,1), filter .4s;
}
.mural .tile:hover img { transform: scale(1.06); filter: grayscale(0) contrast(1); }

/* A couple of tiles break the grid so the wall is not a perfect checkerboard. */
.mural .tile.wide { grid-column: span 2; aspect-ratio: 2 / 1; }
.mural .tile.big { grid-column: span 2; grid-row: span 2; aspect-ratio: 1; }

/* Brand tiles — the equivalent of their wood panels. */
.mural .tile.brand {
  display: flex; align-items: center; justify-content: center;
  background: var(--ground-2);
  border: 1px solid var(--line);
}
.mural .tile.brand img { width: 52%; height: auto; object-fit: contain; filter: none; opacity: .85; }
.mural .tile.brand:hover img { transform: none; }
.mural .tile.gold {
  background: var(--gold); color: var(--on-accent);
  font-family: var(--display); text-transform: uppercase;
  font-size: clamp(.85rem, 1.6vw, 1.5rem); font-weight: 600;
  letter-spacing: .06em; line-height: 1; text-align: center; padding: .5rem;
  flex-direction: column; gap: .2rem;
}
.mural .tile.gold small {
  font-family: var(--sans); font-size: .5rem; letter-spacing: .22em; font-weight: 500; opacity: .75;
}
.mural .tile.dark {
  background: var(--surface); color: var(--ink-3);
  font-family: var(--display); text-transform: uppercase;
  font-size: clamp(.8rem, 1.5vw, 1.35rem); letter-spacing: .06em;
  text-align: center; padding: .5rem; line-height: 1.05;
}
.mural .tile.dark b { color: var(--gold); display: block; font-weight: 600; }

@media (max-width: 900px) { .mural { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 560px) {
  .mural { grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px; }
  .mural .tile.big { grid-column: span 2; grid-row: span 2; }
}

/* --- Heritage timeline ---------------------------------------------------- */

.timeline { list-style: none; padding: 0; margin: 0; }
.timeline li {
  position: relative; padding: 0 0 1.4rem 1.9rem;
  border-left: 1px solid var(--line-strong);
}
.timeline li:last-child { border-left-color: transparent; padding-bottom: 0; }
.timeline li::before {
  content: ""; position: absolute; left: -4px; top: .45rem;
  width: 7px; height: 7px; border-radius: 50%; background: var(--gold);
}
.timeline .yr {
  font-family: var(--display); font-size: 1.45rem; font-weight: 600;
  color: var(--gold); line-height: 1; display: block; margin-bottom: .2rem;
}
.timeline p { margin: 0; color: var(--ink-2); font-size: .92rem; max-width: 46ch; }

.pullquote {
  border-left: 2px solid var(--gold);
  padding: .3rem 0 .3rem 1.2rem; margin: 1.6rem 0 0;
}
.pullquote p {
  font-family: var(--display); text-transform: none;
  font-size: 1.3rem; line-height: 1.3; color: var(--ink); margin: 0 0 .5rem;
}
.pullquote cite {
  font-style: normal; font-size: .66rem; letter-spacing: .2em;
  text-transform: uppercase; color: var(--muted); font-weight: 500;
}
/* Standing alone in the narrow column of a split, the quote has to carry the
   column on its own - a hairline rule and body-sized type read as an orphan. */
.pullquote.feature {
  border-left: 0; border-top: 2px solid var(--gold);
  padding: 1.2rem 0 0; margin: 0;
}
.pullquote.feature p { font-size: clamp(1.35rem, 2.2vw, 1.85rem); }
@media (max-width: 900px) { .pullquote.feature { margin-top: 1.6rem; } }

/* ===========================================================================
   Class cards
   ---------------------------------------------------------------------------
   Same anatomy as the pricing card, because it works: a pill, a title, one big
   display number, a dotted list of details, and a full-width action pinned to
   the bottom. For a class the big number is the start time rather than a price.

   The dense .slot row is kept for staff views, where scanning forty sessions
   matters more than presence.
   =========================================================================== */

.classgrid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(255px, 1fr)); }

.classcard {
  display: flex; flex-direction: column; position: relative;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.2rem;
  transition: border-color .16s, background .16s;
}
.classcard:hover { border-color: var(--line-strong); background: var(--surface-2); }
.classcard.is-booked { border-color: var(--gold); box-shadow: var(--glow); }
.classcard.is-cancelled { opacity: .5; }

.classcard .badge {
  position: absolute; top: -1px; right: -1px;
  background: var(--gold); color: var(--on-accent);
  font-size: .58rem; font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; padding: .28rem .7rem;
}
.classcard .badge.quiet { background: var(--surface-3); color: var(--ink-3); }

.classcard h3 { font-size: 1.2rem; margin: .55rem 0 0; }

.classcard .time {
  font-family: var(--display); font-size: 2.7rem; font-weight: 700;
  line-height: 1; color: #fff; margin: .35rem 0 .1rem;
  font-variant-numeric: tabular-nums;
}
.classcard .time span {
  font-family: var(--sans); font-size: .7rem; font-weight: 500;
  color: var(--muted); text-transform: uppercase; letter-spacing: .12em;
}

.classcard ul { list-style: none; padding: 0; margin: .9rem 0 .8rem; font-size: .84rem; }
.classcard ul li {
  padding: .3rem 0 .3rem 1.15rem; position: relative;
  color: var(--ink-2); border-bottom: 1px solid var(--line);
}
.classcard ul li:last-child { border-bottom: 0; }
.classcard ul li::before {
  content: ""; position: absolute; left: 0; top: 1em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--gold);
}
.classcard ul li.dim { color: var(--muted); }
.classcard ul li.dim::before {
  content: "\00d7";
  width: auto; height: auto; border-radius: 0; background: none;
  color: var(--bad);
  font-size: 1.05em; font-weight: 700; line-height: 1;
  top: .72em; left: -1px;
}

.classcard .foot { margin-top: auto; padding-top: .9rem; }
.classcard .foot .meter { margin-bottom: .7rem; }

/* ===========================================================================
   Membership finder
   ---------------------------------------------------------------------------
   Sixteen plans laid out flat is a wall, not a choice. Four questions narrow it
   to one or two. The full rate tables stay above as the reference — the finder
   is a way in, not a replacement for the card.

   Radios inside a real GET form, so it works with JavaScript off; app.js just
   auto-submits on change. Matching lives on the server only, so there is one
   implementation rather than two that can disagree.
   =========================================================================== */

.finder {
  background: var(--ground-2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: var(--radius);
  padding: 1.4rem 1.5rem;
  display: grid; gap: 1.3rem;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.finder fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
.finder legend {
  padding: 0; margin-bottom: .7rem;
  font-family: var(--sans); font-size: .68rem; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: var(--gold);
}
.finder .chips { display: flex; flex-wrap: wrap; gap: .4rem; }

.chip { display: inline-flex; margin: 0; cursor: pointer; }
.chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.chip span {
  display: inline-block;
  padding: .42rem .8rem;
  border: 1px solid var(--line-strong);
  border-radius: 99px;
  font-size: .8rem; font-weight: 500; color: var(--ink-2);
  transition: background .14s, border-color .14s, color .14s;
}
.chip:hover span { border-color: var(--gold); color: var(--gold); }
.chip input:checked + span {
  background: var(--gold); border-color: var(--gold);
  color: var(--on-accent); font-weight: 600;
}
.chip input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: 2px; }

.finder-actions { display: flex; gap: .6rem; align-items: flex-end; flex-wrap: wrap; }
.finder-result { margin-top: 1.6rem; }
.finder-result .found {
  font-family: var(--display); text-transform: uppercase;
  font-size: 1.15rem; letter-spacing: .02em; color: var(--ink);
  border-left: 3px solid var(--gold); padding-left: .85rem; margin-bottom: 1.1rem;
}
.finder-result .found strong { color: var(--gold); font-size: 1.5rem; }

/* --- More gold across the pricing cards ----------------------------------- */

.plan .price { color: var(--gold); }
.plan .price-sub {
  font-size: .76rem; color: var(--muted);
  text-transform: uppercase; letter-spacing: .1em; font-weight: 500;
  margin-bottom: .9rem; min-height: 1em;
}
.plan { border-top: 2px solid transparent; transition: border-color .16s, background .16s; }
.plan:hover { border-top-color: var(--gold); background: var(--surface-2); }
.plan.is-best {
  border-color: var(--gold); border-top-color: var(--gold);
  background: linear-gradient(180deg, rgba(244, 161, 17, .07), transparent 40%), var(--surface);
  box-shadow: var(--glow);
}
.plan.is-best .btn { box-shadow: 0 0 0 3px rgba(244, 161, 17, .16); }

/* Gold rule under every section heading, so the colour recurs down the page. */
.section-head h2::after {
  content: ""; display: block;
  width: 42px; height: 3px; background: var(--gold);
  margin-top: .6rem;
}

@media (max-width: 620px) {
  .finder { padding: 1.1rem 1.15rem; gap: 1.1rem; }
}

/* ===========================================================================
   Week agenda
   ---------------------------------------------------------------------------
   Seven day columns that scroll horizontally with snap points, so a phone shows
   two or three days and a desktop shows the whole week without a media query
   guessing at breakpoints. Arrows page a week at a time.

   Included vs premium is carried on the left edge: gold means it comes with the
   membership, outlined grey means pay per session. One accent colour still —
   introducing a second hue here would fight the fullness meters.
   =========================================================================== */

.agenda-bar {
  display: flex; align-items: center; gap: .8rem;
  margin-bottom: .9rem; flex-wrap: wrap;
}
.agenda-nav {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: none;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  color: var(--ink); text-decoration: none;
  font-size: 1.5rem; line-height: 1;
  transition: border-color .14s, color .14s, background .14s;
}
.agenda-nav:hover { border-color: var(--gold); color: var(--gold); background: var(--surface-2); }
.agenda-when { display: flex; flex-direction: column; line-height: 1.2; }
.agenda-when strong {
  font-family: var(--display); text-transform: uppercase;
  font-size: 1.15rem; letter-spacing: .02em; color: var(--ink); font-weight: 600;
}
.agenda-when small { color: var(--muted); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; }
.agenda-today { margin-left: auto; }

.legend {
  display: flex; gap: 1.4rem; flex-wrap: wrap;
  list-style: none; padding: 0; margin: 0 0 1rem;
  font-size: .78rem; color: var(--ink-3);
}
.legend li { display: flex; align-items: center; gap: .5rem; }
.legend .swatch { width: 14px; height: 14px; border-radius: 2px; flex: none; }
.legend .swatch.included { background: var(--gold); }
.legend .swatch.premium { background: transparent; border: 2px dashed var(--line-strong); }

/* A fixed number of columns is visible per breakpoint and the track is paged
   by transform. No side-scrolling: the arrows and a drag are the only way
   through, which keeps the day columns aligned to the frame every time. */
.agenda-viewport {
  --cols: 5;              /* Mon-Fri by default; the week is two pages */
  --agenda-gap: 8px;
  overflow: hidden;
  touch-action: pan-y;          /* let the page scroll vertically through it */
  cursor: grab;
}
.agenda-viewport.is-dragging { cursor: grabbing; }
.agenda-viewport.is-dragging .agenda { transition: none; }

@media (min-width: 1400px) { .agenda-viewport { --cols: 7; } }
@media (max-width: 1024px) { .agenda-viewport { --cols: 4; } }
@media (max-width: 620px)  { .agenda-viewport { --cols: 2; --agenda-gap: 6px; } }

.agenda {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - (var(--cols) - 1) * var(--agenda-gap)) / var(--cols));
  gap: var(--agenda-gap);
  transition: transform .34s cubic-bezier(.3, .7, .3, 1);
  will-change: transform;
}

/* Page indicator, only meaningful once the week does not fit in one frame. */
.agenda-dots { display: flex; gap: .35rem; justify-content: center; margin-top: .9rem; }
.agenda-dots button {
  width: 26px; height: 4px; border: 0; padding: 0; border-radius: 99px;
  background: var(--line-strong); cursor: pointer; transition: background .15s;
}
.agenda-dots button.on { background: var(--gold); }
.agenda-dots[hidden] { display: none; }

.agenda-day {
  background: var(--ground-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: .6rem;
  min-width: 0;
}
.agenda-day.is-today { border-color: var(--gold); background: var(--surface); }
.agenda-day.is-past { opacity: .48; }

.agenda-day header {
  display: flex; align-items: baseline; gap: .35rem;
  padding: .2rem .3rem .6rem;
  border-bottom: 1px solid var(--line); margin-bottom: .6rem;
}
.agenda-day header .dow {
  font-size: .64rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
}
.agenda-day header .dnum {
  font-family: var(--display); font-size: 1.35rem; font-weight: 600;
  color: var(--ink); line-height: 1;
}
.agenda-day header .mon { font-size: .64rem; color: var(--muted); text-transform: uppercase; letter-spacing: .1em; }
.agenda-day.is-today header .dnum { color: var(--gold); }
.badge-today {
  margin-left: auto; background: var(--gold); color: var(--on-accent);
  font-size: .52rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  padding: .16rem .4rem; border-radius: 2px;
}

.agenda-empty {
  color: var(--muted); font-size: .76rem; text-align: center;
  padding: 1.2rem .3rem; margin: 0; font-style: italic;
}

.agenda-item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  border-radius: 3px;
  padding: .6rem .65rem;
  margin-bottom: .5rem;
  transition: border-color .14s, background .14s;
}
.agenda-item:last-child { margin-bottom: 0; }
.agenda-item:hover { background: var(--surface-2); }
.agenda-item.premium { border-left-style: dashed; border-left-color: var(--line-strong); }
.agenda-item.is-booked { border-color: var(--gold); box-shadow: inset 0 0 0 1px rgba(244, 161, 17, .35); }
.agenda-item.is-cancelled { opacity: .5; }

.agenda-item .ai-time {
  font-family: var(--display); font-size: 1.15rem; font-weight: 600;
  color: var(--gold); line-height: 1; font-variant-numeric: tabular-nums;
}
.agenda-item.premium .ai-time { color: var(--ink-3); }
.agenda-item h4 {
  font-size: .95rem; margin: .3rem 0 .1rem; line-height: 1.15;
  text-transform: none; color: var(--ink);
}
.agenda-item .ai-meta { font-size: .74rem; color: var(--muted); margin-bottom: .5rem; }
.agenda-item .ai-note {
  font-size: .72rem; line-height: 1.4; color: var(--ink-3);
  background: var(--ground-2); border-radius: 3px;
  padding: .4rem .5rem; margin: 0 0 .5rem;
}
.agenda-item .ai-note strong { color: var(--gold); }
.agenda-item .meter-row { font-size: .6rem; margin-bottom: .25rem; }
.agenda-item .meter { margin-bottom: .5rem; }
.agenda-item form { margin: 0; }

@media (max-width: 640px) {
  .agenda-when strong { font-size: 1rem; }
  .agenda-day { padding: .45rem; }
  .agenda-item { padding: .5rem .55rem; }
  .agenda-item h4 { font-size: .88rem; }
  .agenda-item .ai-meta { font-size: .68rem; }
}


/* ===========================================================================
   Toggle card — two ways to buy the same thing
   ---------------------------------------------------------------------------
   Radios plus `:has()` do the switching, so it works with no JavaScript. Where
   `:has()` is unsupported both options simply render stacked: still usable and
   still accurate, just not toggled.
   =========================================================================== */

.togglecard { position: relative; }
.togglecard .tc-radio { position: absolute; opacity: 0; width: 0; height: 0; }

.tc-toggle {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 3px;
  background: var(--ground-2); border: 1px solid var(--line);
  border-radius: 99px; padding: 3px; margin: .85rem 0 1.05rem;
}
.tc-toggle label {
  text-align: center; cursor: pointer; margin: 0;
  padding: .45rem .4rem; border-radius: 99px;
  font-size: .68rem; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-3);
  transition: background .16s, color .16s;
  white-space: nowrap;
}
.tc-toggle label:hover { color: var(--gold); }

.tc-opt { display: flex; flex-direction: column; flex: 1; }

@supports selector(:has(*)) {
  .togglecard .tc-opt { display: none; }
  .togglecard:has(.tc-radio[data-i="0"]:checked) .tc-opt[data-i="0"],
  .togglecard:has(.tc-radio[data-i="1"]:checked) .tc-opt[data-i="1"],
  .togglecard:has(.tc-radio[data-i="2"]:checked) .tc-opt[data-i="2"] { display: flex; }
  .togglecard:has(.tc-radio[data-i="0"]:checked) .tc-toggle label[data-i="0"],
  .togglecard:has(.tc-radio[data-i="1"]:checked) .tc-toggle label[data-i="1"],
  .togglecard:has(.tc-radio[data-i="2"]:checked) .tc-toggle label[data-i="2"] {
    background: var(--gold); color: var(--on-accent);
  }
}

/* The input is visually hidden, so focus has to show on its label. */
.togglecard:has(.tc-radio[data-i="0"]:focus-visible) .tc-toggle label[data-i="0"],
.togglecard:has(.tc-radio[data-i="1"]:focus-visible) .tc-toggle label[data-i="1"],
.togglecard:has(.tc-radio[data-i="2"]:focus-visible) .tc-toggle label[data-i="2"] {
  outline: 2px solid var(--gold); outline-offset: 2px;
}

.tc-saving {
  background: rgba(79, 191, 130, .1);
  border: 1px solid rgba(79, 191, 130, .32);
  border-radius: var(--radius);
  color: var(--ok); font-size: .8rem; line-height: 1.4;
  padding: .5rem .65rem; margin-bottom: .85rem;
}
.tc-saving strong { color: var(--ok); font-weight: 700; }

.tc-note {
  font-size: .74rem; color: var(--muted); margin: .9rem 0 0;
  padding-top: .8rem; border-top: 1px solid var(--line);
}
.tc-note strong { color: var(--ink-2); }

/* --- The finder as a third card ------------------------------------------- */
/* Dashed edge so it reads as the alternative to the two priced cards rather
   than a third thing to buy. */

.findercard {
  border-style: dashed;
  border-color: var(--line-strong);
  background: transparent;
  text-decoration: none;
  text-align: center;
}
.findercard:hover { border-color: var(--gold); border-style: solid; background: var(--surface); }
.findercard:hover .btn { background: var(--gold); border-color: var(--gold); color: var(--on-accent); }
/* Only a title and a button live in here, so centre the pair as a group. The
   inherited .foot { margin-top: auto } would otherwise pin the button to the
   bottom and strand the title a third of the way down an empty column. */
.findercard { justify-content: center; }
.findercard h3 { margin: 0 auto; max-width: 15ch; font-size: 1.5rem; line-height: 1.15; }
.findercard .foot { margin-top: 1.15rem; padding-top: 0; }

/* --- Plan cards on tablet and phone --------------------------------------- */
/* auto-fit collapses to a single column on a phone, which turns three plans
   into a very long scroll. Force two columns and shrink the type to suit. */

/* Two cards stretched across the full container read as slabs; cap them. */
.planrow.pair { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 820px; }
.planrow.trio { grid-template-columns: repeat(3, minmax(0, 1fr)); }

@media (max-width: 1024px) {
  .planrow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .planrow.trio { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .planrow.trio .findercard {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    text-align: left;
  }
  .planrow.trio .findercard h3 { margin: 0; max-width: none; }
  .planrow.trio .findercard .foot { margin: 0; padding: 0; border: 0; flex: 0 0 auto; }
  .planrow.trio .findercard .btn { display: inline-flex; }
}

@media (max-width: 600px) {
  .planrow { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .7rem; }

  /* Plan cards go to one column on a phone. Two of them side by side left each
     card 163px wide - a price, a toggle and a button crushed into half a
     screen. Stacking full width is what every gym and subscription site does
     at this size, and it lets the type come back up to a readable scale. */
  .planrow.trio { grid-template-columns: 1fr; gap: .9rem; }
  .planrow.trio > .plan { padding: 1.3rem 1.15rem 1.15rem; }
  .planrow.trio .plan h3 { font-size: 1.25rem; }
  .planrow.trio .plan .price { font-size: 2.4rem; }
  .planrow.trio .plan .price span { font-size: .68rem; }
  .planrow.trio .plan .price-sub { font-size: .72rem; }
  .planrow.trio .plan > p { font-size: .84rem; }
  .planrow.trio .plan ul { font-size: .8rem; }
  .planrow.trio .plan .btn { padding: .7rem .8rem; font-size: .74rem; }
  .planrow.trio .tc-toggle label { font-size: .68rem; padding: .5rem .3rem; }
  .planrow.trio .tc-saving { font-size: .76rem; }
  .planrow.trio .tc-note { font-size: .74rem; }

  .planrow.trio .findercard { flex-direction: column; align-items: stretch; text-align: center; gap: .85rem; }
  .planrow.trio .findercard h3 { font-size: 1.15rem; }
  .planrow.trio .findercard .btn { display: block; }
  .plan { padding: 1rem .85rem .9rem; }
  .plan h3 { font-size: 1rem; }
  .plan .price { font-size: 1.9rem; margin: .45rem 0 .2rem; }
  .plan .price span { font-size: .6rem; letter-spacing: .08em; }
  .plan .price-sub { font-size: .64rem; letter-spacing: .06em; margin-bottom: .6rem; }
  .plan > p { font-size: .76rem; margin-bottom: .8rem; }
  .plan ul { font-size: .72rem; margin: .6rem 0; }
  .plan ul li { padding: .24rem 0 .24rem .95rem; }
  .plan ul li::before { width: 4px; height: 4px; top: .95em; }
  .plan .foot { padding-top: .9rem; }
  .plan .btn { padding: .55rem .6rem; font-size: .66rem; letter-spacing: .06em; }
  .plan .badge { font-size: .5rem; padding: .22rem .45rem; letter-spacing: .1em; }
  .plan .notice { padding: .45rem .55rem; }
  .tc-toggle { margin: .7rem 0 .85rem; padding: 2px; }
  .tc-toggle label { font-size: .58rem; padding: .38rem .25rem; letter-spacing: .04em; }
  .tc-saving { font-size: .68rem; padding: .4rem .5rem; }
  .tc-note { font-size: .66rem; }
}


/* ===========================================================================
   Amenity tiles
   ---------------------------------------------------------------------------
   Colour, a name, one line, a way through. Three per row.

   These carried photographs until it turned out the pictures did not match the
   labels. Colour blocks say exactly as much as we can actually stand behind,
   and read as a deliberate graphic panel rather than a stock-image grid.
   =========================================================================== */

.amenities {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

/* An odd tile count leaves the last one alone on its row. Let it run the full
   width instead - a deliberate banner rather than a gap. Which tile is orphaned
   depends on the column count, so the test has to change with the breakpoint. */
.amenities > :last-child:nth-child(3n + 1) { grid-column: 1 / -1; aspect-ratio: 3 / 1; }

.amenity-tile {
  position: relative;
  aspect-ratio: 1;
  display: flex;
  align-items: flex-end;
  padding: 1.1rem;
  border-radius: var(--radius);
  overflow: hidden;
  text-decoration: none;
  transition: transform .18s cubic-bezier(.2,.7,.3,1), box-shadow .18s, filter .18s;
}
a.amenity-tile:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
a.amenity-tile:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

.amenity-tile .body { position: relative; z-index: 2; display: flex; flex-direction: column; gap: .15rem; }
.amenity-tile b {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.3rem, 2.5vw, 1.95rem);
  text-transform: uppercase; letter-spacing: .01em; line-height: 1.02;
}
.amenity-tile small { font-size: .78rem; letter-spacing: .04em; }
.amenity-tile .cta {
  margin-top: .6rem;
  font-size: .64rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
}

/* The crown, oversized and faint, gives the flat colour some texture. */
.amenity-tile .crest {
  position: absolute; z-index: 1;
  right: -14%; top: -12%;
  width: 78%; aspect-ratio: 109 / 150;
  background: currentColor;
  -webkit-mask: url("/img/kings-logo-gold.svg") no-repeat center / contain;
  mask: url("/img/kings-logo-gold.svg") no-repeat center / contain;
  opacity: .07;
  pointer-events: none;
}

.amenity-tile.tone-dark {
  background: linear-gradient(160deg, #2f2e2e, #1b1a19);
  color: #fff;
}
.amenity-tile.tone-dark b { color: #fff; }
.amenity-tile.tone-dark small { color: rgba(255, 255, 255, .62); }
.amenity-tile.tone-dark .cta { color: var(--gold); }

.amenity-tile.tone-gold {
  background: linear-gradient(160deg, var(--gold-bright), var(--gold-deep));
  color: #16120a;
}
.amenity-tile.tone-gold b { color: #16120a; }
.amenity-tile.tone-gold small { color: rgba(22, 18, 10, .68); }
.amenity-tile.tone-gold .cta { color: #16120a; }

.amenity-tile.tone-outline {
  background: var(--surface);
  border: 1px solid var(--line-strong);
  color: var(--ink);
}
.amenity-tile.tone-outline b { color: var(--ink); }
.amenity-tile.tone-outline small { color: var(--muted); }
.amenity-tile.tone-outline .cta { color: var(--accent); }
.amenity-tile.tone-outline .crest { opacity: .09; }

@media (max-width: 760px) {
  .amenities { grid-template-columns: repeat(2, 1fr); gap: 7px; }
  /* Two columns now, so the three-column test no longer picks the right tile. */
  .amenities > :last-child:nth-child(3n + 1) { grid-column: auto; aspect-ratio: 1; }
  .amenities > :last-child:nth-child(odd) { grid-column: 1 / -1; aspect-ratio: 2 / 1; }
  .amenity-tile { padding: .8rem; }
  .amenity-tile small { font-size: .66rem; }
  .amenity-tile .cta { font-size: .58rem; letter-spacing: .12em; margin-top: .45rem; }
}

/* ===========================================================================
   Drop-down navigation
   ---------------------------------------------------------------------------
   King's own menu groups the sports under one heading and the gym under
   another. Opening is CSS-only - hover for pointers, :focus-within for
   keyboards - so the menu works before any script runs. On a phone the whole
   thing becomes a stacked panel behind a checkbox.
   =========================================================================== */

/* The topbar keeps its own fixed palette. It is dark on every page, so
   anything inside it that reached for a theme token came out near-black on
   near-black the moment a light page rendered. */
.topbar {
  --bar-ink: #a8a29a;
  --bar-ink-strong: #ffffff;
  --bar-surface: #1d1c1a;
  --bar-surface-2: #2a2724;
  --bar-line: #423e39;
}

.menu { position: relative; display: inline-flex; align-items: stretch; }
/* Buttons and links have to compute the same height, or the active underline
   sits on two different lines across one bar. */
.nav > a, .menu-top { line-height: 1.5; }
/* A <button>, so none of the `.nav a` rules reach it. Match them by hand. */
.menu-top {
  font-family: inherit; background: none; border: 0; cursor: pointer;
  color: var(--bar-ink);
  display: inline-flex; align-items: center; gap: .35rem; white-space: nowrap;
  padding: .5rem .6rem; font-size: .78rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em;
  border-bottom: 2px solid transparent; transition: color .15s, border-color .15s;
}
.menu-top:hover { color: var(--bar-ink-strong); border-bottom-color: var(--bar-line); text-decoration: none; }
/* The sports heading is an <a>; strip the link underline the nav gives links. */
a.menu-top { text-decoration: none; }
.menu-top.on { color: var(--gold); border-bottom-color: var(--gold); }
.menu-top .caret {
  width: 0; height: 0; border-left: 3.5px solid transparent; border-right: 3.5px solid transparent;
  border-top: 4px solid currentColor; opacity: .55; transition: transform .15s;
}
.menu:hover .caret, .menu:focus-within .caret { transform: rotate(180deg); opacity: 1; }

.menu-drop {
  position: absolute; top: 100%; left: 50%; transform: translate(-50%, 6px);
  min-width: 13.5rem; padding: .4rem;
  background: var(--bar-surface); border: 1px solid var(--bar-line);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  display: grid; gap: 1px; z-index: 60;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .14s, transform .14s, visibility .14s;
}
/* A gap between the button and the panel would close the menu mid-travel. */
.menu-drop::before { content: ""; position: absolute; left: 0; right: 0; top: -8px; height: 8px; }
.menu:hover .menu-drop,
.menu:focus-within .menu-drop {
  opacity: 1; visibility: visible; pointer-events: auto; transform: translate(-50%, 2px);
}
.menu-drop a {
  display: block; padding: .5rem .7rem; border-radius: calc(var(--radius) - 3px);
  font-size: .74rem; letter-spacing: .08em; white-space: nowrap; color: var(--bar-ink);
  border-bottom: 0;
}
.menu-drop a:hover {
  background: var(--bar-surface-2); color: var(--bar-ink-strong); text-decoration: none;
}
.menu-drop a.on { color: var(--accent); }

/* The last menu in the bar would run off the right edge if it centred itself
   on its button, so it hangs from the right instead. */
.menu-end .menu-drop { left: auto; right: 0; transform: translate(0, 6px); }
.menu-end:hover .menu-drop,
.menu-end:focus-within .menu-drop { transform: translate(0, 2px); }

/* The CTA keeps its gold block; the caret has to read against it. */
.menu-top.cta {
  background: var(--gold); color: var(--on-accent);
  border-bottom-color: var(--gold); margin-left: .4rem;
}
.menu-top.cta:hover { background: var(--gold-bright); color: var(--on-accent); border-bottom-color: var(--gold-bright); }
.menu-top.cta .caret { opacity: .7; }
.menu-end:hover .menu-top.cta .caret, .menu-end:focus-within .menu-top.cta .caret { opacity: 1; }

.menu-label {
  display: block; padding: .45rem .7rem .3rem;
  font-size: .58rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
}
.menu-sep { display: block; height: 1px; margin: .3rem .5rem; background: var(--bar-line); }

/* The burger and its checkbox only exist below the phone breakpoint. */
.navtoggle, .navburger { display: none; }

@media (max-width: 1080px) {
  .navburger {
    display: block; width: 34px; height: 34px; cursor: pointer;
    position: relative; margin-left: auto;
  }
  .navburger span, .navburger span::before, .navburger span::after {
    content: ""; position: absolute; left: 6px; right: 6px; height: 2px;
    /* The bar is dark on every page; --ink follows the page and turns the
       burger near-black on near-black the moment a light page loads. */
    background: var(--bar-ink-strong); transition: transform .18s, opacity .18s;
  }
  .navburger span { top: 16px; }
  .navburger span::before { top: -6px; left: 0; right: 0; }
  .navburger span::after { top: 6px; left: 0; right: 0; }
  .navtoggle:checked + .navburger span { background: transparent; }
  .navtoggle:checked + .navburger span::before { transform: translateY(6px) rotate(45deg); }
  .navtoggle:checked + .navburger span::after { transform: translateY(-6px) rotate(-45deg); }

  .topbar-inner { flex-wrap: wrap; }
  .nav {
    display: none; width: 100%; order: 3;
    flex-direction: column; align-items: stretch; gap: 0;
    padding: .5rem 0 1rem; border-top: 1px solid var(--line);
  }
  .navtoggle:checked ~ .nav { display: flex; }
  .nav > a, .menu { padding: .6rem .2rem; border-bottom: 1px solid var(--line); }
  .menu { display: block; }
  .menu-top { width: 100%; justify-content: space-between; }

  /* Nested panels have nowhere to float on a phone: show them inline. */
  .menu-drop {
    position: static; transform: none; opacity: 1; visibility: visible;
    pointer-events: auto; box-shadow: none; border: 0; background: none;
    min-width: 0; padding: .3rem 0 0 .8rem;
  }
  .menu:hover .menu-drop, .menu:focus-within .menu-drop { transform: none; }
  .menu-drop a { padding: .4rem 0; }
  .nav .cta { margin-top: .8rem; text-align: center; }
  .menu-end .menu-drop { right: auto; transform: none; }
  /* inline-flex shrinks the gold block to its text; in a stacked menu it has
     to run the full width like every other row. */
  .menu-top.cta { display: flex; width: 100%; justify-content: center; margin-left: 0; margin-top: .4rem; }
  .menu-label { padding-left: 0; }
  .menu-sep { margin-left: 0; }
}

/* ===========================================================================
   Facility pages
   =========================================================================== */

/* A brand panel for pages with no honest photograph of their subject. */
.hero.panel .hero-media { background: var(--ground-2); }
.hero.panel.tone-gold .hero-media {
  background: linear-gradient(135deg, var(--gold) 0%, #d98c07 55%, #b4700a 100%);
}
.hero.panel.tone-dark .hero-media { background: linear-gradient(135deg, #23211e 0%, #131211 100%); }
.hero.panel .hero-crest {
  position: absolute; right: -2%; top: 50%; transform: translateY(-50%);
  width: auto; height: 118%; object-fit: contain; opacity: .13;
}
.hero.panel.tone-gold .hero-crest { filter: brightness(0) invert(1); opacity: .22; }
.hero.panel.tone-gold { --scrim: linear-gradient(90deg, rgba(22, 18, 10, .5) 0%, rgba(22, 18, 10, .12) 70%); }
.hero.panel.tone-gold .kicker { color: #2a2008; }
.hero.panel.tone-gold h1, .hero.panel.tone-gold .lede { color: #17130a; }
.hero.panel.tone-gold h1 em { color: #fff; }
.hero.panel.tone-gold .hero-stats span { color: #17130a; }
.hero.panel.tone-gold .btn { background: #17130a; border-color: #17130a; color: var(--gold); }

@media (max-width: 700px) { .hero.panel .hero-crest { opacity: .09; right: -20%; } }

.fbody { display: grid; gap: 2rem; max-width: 46rem; }
.fblock h3 { margin: 0 0 .7rem; }
.fblock .tablewrap { margin: 0; }

.deflist { list-style: none; padding: 0; margin: 0; }
.deflist li {
  display: flex; flex-wrap: wrap; gap: .4rem 1rem; justify-content: space-between;
  padding: .6rem 0; border-bottom: 1px solid var(--line);
}
.deflist li:last-child { border-bottom: 0; }
.deflist b { font-weight: 600; }
.deflist span { color: var(--muted); font-size: .88rem; text-align: right; }
@media (max-width: 520px) { .deflist span { text-align: left; } }

/* ===========================================================================
   Rotating header
   ---------------------------------------------------------------------------
   Slides stack in a single grid cell, so the slider is as tall as its tallest
   slide and never jumps as it advances. Without JavaScript the first slide is
   simply the header - `.heroslider.js` is what turns the rest on.
   =========================================================================== */

.heroslider { position: relative; }
.heroslides { display: grid; }
.heroslide { grid-area: 1 / 1; }
/* Slides carry different amounts of copy, so left alone the header changes
   height as it rotates. The grid row is already as tall as the tallest slide;
   stretching each slide into it makes every one the same. */
.heroslide { display: grid; }
.heroslide > .hero { height: 100%; }
.heroslider .hero { min-height: clamp(30rem, 62vh, 44rem); }
@media (max-width: 700px) { .heroslider .hero { min-height: clamp(26rem, 74vh, 34rem); } }

.heroslider.js .heroslide {
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .7s ease, visibility .7s;
}
.heroslider.js .heroslide.is-on { opacity: 1; visibility: visible; pointer-events: auto; }

.heroslider-ui {
  position: absolute; left: 0; right: 0; bottom: 1.1rem; z-index: 4;
  display: flex; align-items: center; gap: .8rem;
  pointer-events: none;
}
.heroslider-ui > * { pointer-events: auto; }
.hs-dots { display: flex; gap: .4rem; margin-right: auto; }

/* Arrows sit against the left and right edges, vertically centred, which is
   where a hand reaches for them. The dots stay on the bottom rail. */
.hs-arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 5;
}
.hs-arrow[data-hs-prev] { left: clamp(.5rem, 2vw, 1.4rem); }
.hs-arrow[data-hs-next] { right: clamp(.5rem, 2vw, 1.4rem); }
.hs-dot {
  border: 0; background: none; padding: .45rem .25rem; cursor: pointer; line-height: 0;
}
.hs-dot span {
  display: block; width: 26px; height: 3px; border-radius: 2px;
  background: rgba(255, 255, 255, .38); transition: background .2s, width .2s;
}
.hs-dot:hover span { background: rgba(255, 255, 255, .7); }
.hs-dot.is-on span { background: var(--gold); width: 40px; }

.hs-arrow {
  width: 34px; height: 34px; flex: 0 0 auto; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, .3); border-radius: 50%;
  background: rgba(12, 11, 10, .4); color: #fff; font-size: .85rem;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, border-color .15s;
}
.hs-arrow:hover { background: rgba(12, 11, 10, .75); border-color: var(--gold); color: var(--gold); }

/* Arrows are a pointer affordance; on a phone the dots carry it. */
@media (max-width: 700px) {
  .hs-arrow { display: none; }
  .heroslider-ui { bottom: .6rem; }
  .hs-dot span { width: 18px; }
  .hs-dot.is-on span { width: 28px; }
}

@media (prefers-reduced-motion: reduce) {
  .heroslider.js .heroslide { transition: none; }
}

/* --- Photo amenity tiles --------------------------------------------------- */
/* A tile with a real photograph of its space. Tiles without one keep the
   colour block, so the grid mixes the two rather than faking a picture. */

.amenity-tile.has-photo { position: relative; overflow: hidden; }
.amenity-tile.has-photo .shot {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 0;
  filter: grayscale(.2) contrast(1.03) brightness(.72);
  transition: transform .6s cubic-bezier(.2,.7,.3,1), filter .35s;
}
.amenity-tile.has-photo:hover .shot { transform: scale(1.05); filter: grayscale(0) brightness(.62); }
/* The scrim is what keeps the caption legible over any photograph. */
.amenity-tile.has-photo::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(0deg, rgba(12, 11, 10, .92) 0%, rgba(12, 11, 10, .45) 45%, rgba(12, 11, 10, .12) 100%);
}
.amenity-tile.has-photo .body { position: relative; z-index: 2; }
.amenity-tile.has-photo .body b { color: #fff; }
.amenity-tile.has-photo .body small { color: rgba(255, 255, 255, .78); }
.amenity-tile.has-photo .body .cta { color: var(--gold); }

/* ===========================================================================
   Quick pay
   =========================================================================== */

/* The explanatory sidebar is gone, so the form stands on its own. Capped
   rather than full width: a four-field form stretched across a desktop reads
   as a spreadsheet. */
.paygrid { display: grid; grid-template-columns: minmax(0, 1fr); max-width: 34rem; }

.quickpay { max-width: 32rem; }
.quickpay .field { margin-bottom: 1.1rem; }
.quickpay label {
  display: block; margin-bottom: .35rem;
  font-size: .68rem; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 600; color: var(--ink-2);
}
.quickpay label .opt {
  letter-spacing: .06em; text-transform: none; font-weight: 400; color: var(--muted);
}
.quickpay input {
  width: 100%; padding: .75rem .85rem;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  font-family: inherit; font-size: 1rem;
  transition: border-color .15s, box-shadow .15s;
}
.quickpay input:focus {
  outline: none; border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(244, 161, 17, .18);
}
.quickpay input[aria-invalid="true"] { border-color: var(--bad); }
.quickpay .hint, .quickpay .err { display: block; margin-top: .35rem; font-size: .76rem; }
.quickpay .hint { color: var(--muted); }
.quickpay .err { color: var(--bad); }

/* The amount reads as money: the currency sits inside the field, and the
   figure is set in the display face so it is the thing you check. */
.quickpay .amountwrap { position: relative; display: flex; align-items: center; }
.quickpay .amountwrap .cur {
  position: absolute; left: .85rem; color: var(--muted);
  font-size: .82rem; letter-spacing: .04em; pointer-events: none;
}
.quickpay .amountwrap input {
  padding-left: 3.6rem;
  font-family: var(--display); font-size: 1.5rem; letter-spacing: .01em;
}

.paynote .steps {
  margin: .8rem 0 0; padding-left: 1.1rem;
  color: var(--ink-2); font-size: .88rem;
}
.paynote .steps li { padding: .25rem 0; }

/* ===========================================================================
   Staff console
   ---------------------------------------------------------------------------
   A desktop tool, not a page: it fills the window, the chrome is pinned, and
   only the working area scrolls. The bar and the rail keep their own dark
   palette regardless of the page theme - same reasoning as the public topbar,
   which turned near-black on near-black the moment a light page loaded.
   =========================================================================== */

.console {
  --rail-w: 246px;
  --bar-h: 60px;
  --con-ink: #a8a29a;
  --con-ink-strong: #ffffff;
  --con-bg: #16161c;
  --con-bg-2: #1e1f27;
  --con-line: #2c2d38;
  --con-on: #2b3350;

  min-height: 100vh;
  padding-top: var(--bar-h);
  padding-left: var(--rail-w);
  background: var(--ground);
  transition: padding-left .18s ease;
}

/* --- Top bar --------------------------------------------------------------- */

.console-bar {
  position: fixed; inset: 0 0 auto 0; height: var(--bar-h); z-index: 40;
  display: flex; align-items: center; gap: 1.2rem; padding: 0 1rem 0 0;
  background: var(--con-bg); border-bottom: 1px solid var(--con-line);
}
.console-brand {
  display: flex; align-items: center; gap: .6rem; text-decoration: none; color: #fff;
  width: var(--rail-w); flex: 0 0 auto; padding-left: 1.15rem;
  transition: width .18s ease;
}
.console-brand span { display: flex; flex-direction: column; line-height: 1; overflow: hidden; }
.console-brand b {
  font-family: var(--display); font-size: 1.1rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .02em; white-space: nowrap;
}
.console-brand small {
  font-size: .52rem; letter-spacing: .22em; text-transform: uppercase;
  color: var(--gold); margin-top: .22rem; white-space: nowrap;
}

.console-search {
  flex: 1 1 auto; max-width: 34rem; margin: 0 auto; position: relative;
  display: flex; align-items: center;
}
.console-search .ico { position: absolute; left: .8rem; color: var(--con-ink); pointer-events: none; }
.console-search input {
  width: 100%; padding: .55rem .9rem .55rem 2.5rem;
  background: var(--con-bg-2); color: #fff;
  border: 1px solid var(--con-line); border-radius: 8px;
  font-family: inherit; font-size: .88rem;
}
.console-search input::placeholder { color: var(--con-ink); }
.console-search input:focus {
  outline: none; border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(244, 161, 17, .16);
}

.console-who { display: flex; align-items: center; gap: .6rem; flex: 0 0 auto; }
.console-who .avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--gold); color: var(--on-accent);
  display: grid; place-items: center;
  font-family: var(--display); font-weight: 600; font-size: 1rem;
}
.console-who .who-text { display: flex; flex-direction: column; line-height: 1.15; }
.console-who .who-text b { color: #fff; font-size: .82rem; white-space: nowrap; }
.console-who .who-text small {
  color: var(--con-ink); font-size: .58rem; letter-spacing: .16em; text-transform: uppercase;
}
.console-who .who-out {
  color: var(--con-ink); padding: .4rem; border-radius: 6px; display: grid; place-items: center;
}
.console-who .who-out:hover { color: #fff; background: var(--con-bg-2); }

/* --- Rail ------------------------------------------------------------------ */

.console-rail {
  position: fixed; top: var(--bar-h); bottom: 0; left: 0; width: var(--rail-w); z-index: 39;
  background: var(--con-bg); border-right: 1px solid var(--con-line);
  display: flex; flex-direction: column; overflow-y: auto; overflow-x: hidden;
  transition: width .18s ease;
}

.rail-collapse {
  display: flex; align-items: center; gap: .7rem; cursor: pointer;
  padding: .85rem 1.15rem; color: var(--con-ink);
  font-size: .74rem; letter-spacing: .08em;
  border-bottom: 1px solid var(--con-line);
}
.rail-collapse:hover { color: #fff; }
.rail-collapse .ico { flex: 0 0 auto; transition: transform .18s ease; }

.rail-nav { padding: .6rem 0 1.5rem; }
.rail-group {
  padding: 1rem 1.15rem .35rem;
  font-size: .58rem; letter-spacing: .2em; text-transform: uppercase;
  color: #6b6c7a; font-weight: 600; white-space: nowrap;
}
.rail-link {
  display: flex; align-items: center; gap: .8rem;
  padding: .62rem 1.15rem; margin: 1px .5rem; border-radius: 8px;
  color: var(--con-ink); text-decoration: none;
  font-size: .88rem; white-space: nowrap;
  transition: background .13s, color .13s;
}
.rail-link .ico { flex: 0 0 auto; }
.rail-link:hover { background: var(--con-bg-2); color: #fff; text-decoration: none; }
.rail-link.on { background: var(--con-on); color: #fff; }
.rail-link.on .ico { color: var(--gold); }

/* Collapsed: an icon rail. Labels go, the tile stays square, and the title
   attribute is what names the destination on hover. */
.rail-toggle:checked ~ .console { --rail-w: 66px; }
.rail-toggle:checked ~ .console .console-brand span,
.rail-toggle:checked ~ .console .rail-link span,
.rail-toggle:checked ~ .console .rail-collapse span,
.rail-toggle:checked ~ .console .rail-group { display: none; }
.rail-toggle:checked ~ .console .rail-collapse { justify-content: center; padding-inline: 0; }
.rail-toggle:checked ~ .console .rail-collapse .ico { transform: rotate(180deg); }
.rail-toggle:checked ~ .console .rail-link { justify-content: center; padding-inline: 0; margin-inline: .55rem; }
.rail-toggle:checked ~ .console .console-brand { padding-left: 1.35rem; }

/* --- Working area ---------------------------------------------------------- */

.console-main { padding: 1.6rem clamp(1rem, 2.4vw, 2.2rem) 3rem; max-width: 1600px; }
.console-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem;
}
.console-head h1 {
  margin: 0; font-size: clamp(1.6rem, 2.6vw, 2.3rem); line-height: 1.05;
}
.console-sub { margin: .4rem 0 0; color: var(--muted); font-size: .92rem; }

/* Below a laptop the rail overlays instead of squeezing the table. */
@media (max-width: 1024px) {
  .console { padding-left: 66px; --rail-w: 66px; }
  .console-brand { width: 66px; }
  .console-brand span, .rail-link span, .rail-collapse span, .rail-group { display: none; }
  .rail-link, .rail-collapse { justify-content: center; padding-inline: 0; }
  .console-search { margin-left: 0; }
}
@media (max-width: 700px) {
  .console-who .who-text { display: none; }
  .console-search { max-width: none; }
}

/* --- Transaction ledger filters -------------------------------------------- */
/* A row, not a stacked form: it sits above a table and should cost one line. */

.ledger-filters {
  display: flex; align-items: flex-end; gap: 1rem; flex-wrap: wrap;
}
.ledger-filters .field { margin: 0; }
.ledger-filters .field:first-child { flex: 1 1 20rem; }
.ledger-filters label {
  display: block; margin-bottom: .3rem;
  font-size: .62rem; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 600; color: var(--muted);
}
.ledger-filters input, .ledger-filters select {
  width: 100%; padding: .5rem .7rem;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  font-family: inherit; font-size: .9rem;
}
.ledger-filters input:focus, .ledger-filters select:focus {
  outline: none; border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(244, 161, 17, .16);
}
.ledger-filters .field:last-of-type { display: flex; gap: .5rem; }
.ledger-filters > .pill { margin-left: auto; }

.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .78rem; }

/* ===========================================================================
   Facility bookings
   ---------------------------------------------------------------------------
   The week grid is a table on purpose: hours against days is tabular data, it
   reads correctly to a screen reader, and it beats a div grid the moment a
   column has to hold two bookings at once.
   =========================================================================== */

.viewtabs {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1.2rem;
}
.tabstrip { display: flex; gap: .25rem; background: var(--surface-2); padding: 3px; border-radius: 10px; }
.tabstrip .tab {
  padding: .45rem .9rem; border-radius: 8px; text-decoration: none;
  font-size: .82rem; font-weight: 600; color: var(--ink-2); white-space: nowrap;
}
.tabstrip .tab:hover { background: var(--surface); color: var(--ink); text-decoration: none; }
.tabstrip .tab.on { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }
.tabfilter select {
  padding: .45rem .7rem; background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  font-family: inherit; font-size: .85rem;
}

.weekbar {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-bottom: 1rem;
}
.weekbar-label { display: flex; align-items: baseline; gap: .5rem; margin-right: auto; }
.weekbar-label strong { font-family: var(--display); font-size: 1.1rem; }

/* --- The rink strip -------------------------------------------------------- */

.rinkstrip {
  display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap;
  padding: .9rem 1.1rem; margin-bottom: 1.2rem;
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--gold); border-radius: var(--radius);
  text-decoration: none; color: inherit;
}
.rinkstrip:hover { background: var(--surface-2); text-decoration: none; }
.rinkstrip strong { font-family: var(--display); font-size: 1.5rem; display: block; line-height: 1; }
.rinkstrip .meter { flex: 1 1 12rem; min-width: 8rem; }
.rinkstrip .btn { flex: 0 0 auto; margin-left: auto; }

/* --- Week grid ------------------------------------------------------------- */

.weekgrid { table-layout: fixed; width: 100%; min-width: 46rem; }
.weekgrid th, .weekgrid td { border: 1px solid var(--line); vertical-align: top; padding: 3px; }
.weekgrid thead th { text-align: center; padding: .5rem 3px; background: var(--surface-2); }
.weekgrid thead .dow {
  display: block; font-size: .6rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
}
.weekgrid thead .dnum { display: block; font-family: var(--display); font-size: 1.15rem; }
.weekgrid .hourcol {
  width: 4.5rem; text-align: right; padding-right: .6rem;
  font-size: .72rem; color: var(--muted); font-weight: 500;
  background: var(--surface-2); vertical-align: top;
}
.weekgrid tbody tr { height: 2.4rem; }
.weekgrid .is-today { background: rgba(244, 161, 17, .06); }
.weekgrid thead .is-today .dnum { color: var(--accent); }
.weekgrid .alldayrow td { background: var(--surface-2); min-height: 1.8rem; }

/* A booking chip. Colour carries the space, the label carries the customer. */
.bk {
  display: block; margin: 1px 0; padding: .18rem .35rem; border-radius: 4px;
  font-size: .68rem; line-height: 1.25; overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis;
  background: var(--surface-3); color: var(--ink-2);
  border-left: 3px solid var(--line-strong);
}
.bk b { font-weight: 700; }
/* A continued hour keeps the colour but drops the text: one hire, one label. */
.bk.cont { opacity: .55; }
.bk.cont b { opacity: .6; }

.bk.grp-KingPinBowling { background: #e8f0fb; color: #1c3f6e; border-left-color: #3f7fd0; }
.bk.grp-Squash { background: #e7f5ec; color: #1c5334; border-left-color: #3f9d63; }
.bk.grp-Rink { background: #fdf0dc; color: #6b4708; border-left-color: var(--gold); }
.bk.allday { background: #3a3733; color: #f5f2ee; border-left-color: var(--gold); }

.theme-dark .bk.grp-KingPinBowling { background: #17243a; color: #b9d3f4; }
.theme-dark .bk.grp-Squash { background: #14291d; color: #a9dcbe; }
.theme-dark .bk.grp-Rink { background: #2c2213; color: #f0cf95; }

.legend { display: flex; flex-wrap: wrap; gap: 1.2rem; font-size: .8rem; color: var(--ink-2); }
.legend-item { display: inline-flex; align-items: center; gap: .4rem; }
.legend .swatch { width: 14px; height: 14px; border-radius: 3px; display: inline-block; }
.legend .swatch.grp-KingPinBowling { background: #3f7fd0; }
.legend .swatch.grp-Squash { background: #3f9d63; }
.legend .swatch.grp-Rink { background: var(--gold); }
.legend .swatch.allday { background: #3a3733; }

/* --- Month calendar -------------------------------------------------------- */

.monthgrid {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden;
}
.mg-head {
  background: var(--surface-2); padding: .5rem; text-align: center;
  font-size: .6rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
}
.mg-cell {
  background: var(--surface); min-height: 7.5rem; padding: .4rem;
  display: flex; flex-direction: column; gap: 1px;
  text-decoration: none; color: inherit;
}
.mg-cell:hover { background: var(--surface-2); text-decoration: none; }
.mg-cell.faded { background: var(--ground-2); }
.mg-cell.faded .mg-day { opacity: .4; }
.mg-cell.is-today { box-shadow: inset 0 0 0 2px var(--gold); }
.mg-day {
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--display); font-size: 1rem; margin-bottom: .15rem;
}
.mg-count {
  font-family: var(--sans); font-size: .6rem; color: var(--muted);
  background: var(--surface-3); border-radius: 99px; padding: .05rem .35rem;
}
.mg-more { font-size: .62rem; color: var(--muted); padding-left: .35rem; }

@media (max-width: 780px) {
  .mg-cell { min-height: 5rem; }
  .mg-cell .bk { font-size: .6rem; }
}

/* --- Rink live view -------------------------------------------------------- */

.rinkgrid { display: grid; grid-template-columns: 1fr 1.1fr; gap: 1.4rem; align-items: start; }
@media (max-width: 900px) { .rinkgrid { grid-template-columns: 1fr; } }

.capcard { border-left: 3px solid var(--gold); }
.capbig { display: flex; align-items: baseline; gap: .5rem; margin: .3rem 0 .8rem; }
.capbig strong { font-family: var(--display); font-size: clamp(3rem, 8vw, 4.5rem); line-height: 1; }
.capbig span { font-family: var(--display); font-size: 1.5rem; color: var(--muted); }
.caprow { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; margin-top: .7rem; }

.checkinform { display: flex; gap: .5rem; flex-wrap: wrap; }
.checkinform input {
  flex: 1 1 12rem; padding: .6rem .8rem;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  font-family: inherit; font-size: .95rem;
}
.checkinform input:focus {
  outline: none; border-color: var(--gold); box-shadow: 0 0 0 3px rgba(244, 161, 17, .16);
}

.vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ===========================================================================
   Court self-booking
   =========================================================================== */

/* minmax(0, ...) on both tracks: a bare fr will not shrink below its content,
   and the "Two, allocated automatically" row in the sidebar was wide enough to
   push the whole column off the right of the page. */
.bookgrid {
  display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, .65fr);
  gap: 2.2rem; align-items: start;
}
/* Grid children default to min-width:auto, so the 14-day strip inside the left
   column made that column as wide as the strip and the whole page scrolled
   sideways. Letting the children shrink is what lets .daystrip's own
   overflow-x do its job. */
.bookgrid > * { min-width: 0; }
.booknote .deflist li { gap: .2rem .8rem; }
.booknote .deflist span { text-align: right; min-width: 0; }
@media (max-width: 900px) { .bookgrid { grid-template-columns: minmax(0, 1fr); gap: 1.6rem; } }

/* Length first: it decides which days and times can even be offered, so it
   sits above the day strip rather than beside the name fields. */
.lengthpick { display: flex; gap: .3rem; flex-wrap: wrap; margin-bottom: 1rem; }
.lenopt {
  padding: .45rem .9rem; border-radius: 99px; text-decoration: none;
  font-size: .8rem; font-weight: 600;
  color: var(--ink-2); background: var(--surface-2);
  border: 1px solid var(--line-strong);
  transition: background .13s, color .13s, border-color .13s;
}
.lenopt:hover { border-color: var(--gold); text-decoration: none; }
.lenopt.on { background: var(--gold); border-color: var(--gold); color: var(--on-accent); }

/* A whole-day hire is one choice, so it is one block rather than a grid. */
.alldaypick {
  display: flex; flex-direction: column; gap: .2rem;
  padding: 1.1rem 1.2rem; border-radius: var(--radius);
  border: 1px solid var(--gold); background: var(--surface);
  border-left-width: 3px;
}
.alldaypick strong { font-family: var(--display); font-size: 1.5rem; line-height: 1; }

/* Days as a strip: nobody should have to type a date to book a squash court. */
.daystrip { display: flex; gap: .4rem; overflow-x: auto; padding-bottom: .4rem; }
.daypick {
  flex: 0 0 auto; width: 4.6rem; padding: .6rem .3rem; text-align: center;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  text-decoration: none; color: var(--ink-2); background: var(--surface);
  transition: border-color .15s, background .15s;
}
.daypick:hover { border-color: var(--gold); text-decoration: none; }
.daypick.on { background: var(--gold); border-color: var(--gold); color: var(--on-accent); }
.daypick .dow {
  display: block; font-size: .58rem; letter-spacing: .14em;
  text-transform: uppercase; font-weight: 600;
}
.daypick .dnum { display: block; font-family: var(--display); font-size: 1.3rem; line-height: 1.1; }
.daypick small { display: block; font-size: .58rem; opacity: .75; }

.slotgrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
  gap: .5rem; border: 0; padding: 0; margin: 0;
}
@media (max-width: 480px) {
  .slotgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.slot {
  position: relative; display: flex; flex-direction: column; align-items: center;
  padding: .7rem .4rem; border-radius: var(--radius);
  border: 1px solid var(--line-strong); background: var(--surface);
  cursor: pointer; transition: border-color .13s, background .13s, box-shadow .13s;
}
.slot b { font-family: var(--display); font-size: 1.15rem; line-height: 1; }
.slot small { font-size: .62rem; letter-spacing: .06em; color: var(--muted); margin-top: .2rem; }
.slot input { position: absolute; opacity: 0; pointer-events: none; }
.slot:hover { border-color: var(--gold); }
.slot:has(input:checked) {
  border-color: var(--gold); background: var(--gold); color: var(--on-accent);
  box-shadow: 0 0 0 3px rgba(244, 161, 17, .2);
}
.slot:has(input:checked) small { color: var(--on-accent); opacity: .8; }
.slot:has(input:focus-visible) { box-shadow: 0 0 0 3px rgba(244, 161, 17, .35); }
/* Only one court left: worth saying, not worth alarming anyone. */
.slot.limited small { color: var(--warn); }

/* Blocked and past slots stay in the grid. A hole where a time should be reads
   as a broken page; "fully booked" reads as an answer. */
.slot.full, .slot.past {
  cursor: not-allowed; background: var(--surface-2);
  border-style: dashed; color: var(--muted);
}
.slot.full b, .slot.past b { opacity: .45; text-decoration: line-through; }
.slot.full small { color: var(--bad); }

.whoform { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 1rem; }
.whoform .field { margin: 0; }
.whoform label {
  display: block; margin-bottom: .3rem;
  font-size: .64rem; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 600; color: var(--ink-2);
}
.whoform label .opt { letter-spacing: .04em; text-transform: none; font-weight: 400; color: var(--muted); }
.whoform input {
  width: 100%; padding: .6rem .8rem;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  font-family: inherit; font-size: .95rem;
}
.whoform input:focus {
  outline: none; border-color: var(--gold); box-shadow: 0 0 0 3px rgba(244, 161, 17, .16);
}
