/*
 * Southside Elite Strength.
 *
 * Ported from the Astro build's token config. Every value below is one of
 * that project's tokens; nothing here was picked afresh. If a value needs to
 * change it should change in both places, or the two builds drift.
 *
 * Deliberately hand-authored rather than compiled from Tailwind: a WordPress
 * theme that needs `npm run build` before anyone can adjust a colour is a
 * theme nobody adjusts. The tokens are declared once as custom properties and
 * everything else composes them.
 */

/* ---------------------------------------------------------------- *
 * Faces. Archivo must be the `wdth` build: display type is narrowed on
 * the width axis rather than fattened on weight, which is what makes it
 * read hard without turning into a slab. The weight-only build carries
 * no font-stretch descriptor and would silently ignore it.
 * ---------------------------------------------------------------- */
@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo-latin-wdth.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'InterVar';
  src: url('../fonts/inter-latin-wght.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Neutral ramp. Pure neutral (R=G=B) on purpose — a tinted grey fights
     greyscale photography. */
  --iron-50: #f7f7f7;
  --iron-100: #ededed;
  --iron-200: #d6d6d6;
  --iron-300: #b4b4b4;
  --iron-400: #9b9b9b;
  --iron-500: #6a6a6a;
  --iron-600: #4a4a4a;
  --iron-700: #2e2e2e;
  --iron-800: #191919;
  --iron-900: #0b0b0b;
  --iron-950: #000000;

  /* Spacing — 4px grid, named steps only. `hair` is 1px and is a divider,
     not spacing: a grid with gap:1px over a rule-coloured background draws
     hairlines between cells with no nth-child bookkeeping. */
  --s-hair: 1px;
  --s-3xs: 0.25rem;
  --s-2xs: 0.5rem;
  --s-xs: 0.75rem;
  --s-sm: 1rem;
  --s-md: 1.5rem;
  --s-lg: 2rem;
  --s-xl: 2.5rem;
  --s-2xl: 3rem;
  --s-3xl: 4rem;
  --s-4xl: 5rem;
  --s-5xl: 6rem;
  --s-6xl: 8rem;

  --radius-button: 3px;

  --font-display: 'Archivo', ui-sans-serif, system-ui, sans-serif;
  --font-sans: 'InterVar', ui-sans-serif, system-ui, -apple-system, Arial, sans-serif;

  --content-lg: 68rem;
  --content-md: 52rem;

  --duration: 200ms;
}

/* Semantic roles, re-pointed per band by [data-tone]. A component asks for
   var(--fg-strong) and never needs to know which band it is sitting on. */
:root,
[data-tone='default'] {
  --surface: var(--iron-950);
  --surface-raised: var(--iron-900);
  --surface-border: var(--iron-800);
  --fg: var(--iron-200);
  --fg-strong: #ffffff;
  --fg-muted: var(--iron-400);
}
[data-tone='raised'] {
  --surface: var(--iron-900);
  --surface-raised: var(--iron-950);
  --surface-border: var(--iron-700);
  --fg: var(--iron-200);
  --fg-strong: #ffffff;
  --fg-muted: var(--iron-400);
}
/* The one place the page flips to white. With no accent hue in the palette,
   inverting the band *is* the emphasis. */
[data-tone='inverse'],
[data-tone='accent'] {
  --surface: #ffffff;
  --surface-raised: var(--iron-50);
  --surface-border: var(--iron-200);
  --fg: var(--iron-700);
  --fg-strong: var(--iron-950);
  --fg-muted: var(--iron-500);
}

*,
*::before,
*::after {
  box-sizing: border-box;
  border-color: var(--surface-border);
}

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

body {
  margin: 0;
  background: var(--surface);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

a {
  color: inherit;
}

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  /* Condensed caps with negative tracking squeeze the word space to a
     hairline -- "MEMBERSHIP PRICING" read as one word. */
  word-spacing: 0.14em;
  font-stretch: 88%;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--fg-strong);
  margin: 0;
  line-height: 1.15;
  text-wrap: balance;
}

p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

/* ---------------------------------------------------------------- *
 * Layout
 * ---------------------------------------------------------------- */
.shell {
  width: 100%;
  max-width: var(--content-lg);
  margin-inline: auto;
  padding-inline: var(--s-md);
}
@media (min-width: 768px) {
  .shell { padding-inline: var(--s-lg); }
}

.section {
  width: 100%;
  background: var(--surface);
  color: var(--fg);
  padding-block: var(--s-xl);
}
@media (min-width: 768px) {
  .section {
    padding-block: var(--s-2xl);
  }
}
@media (min-width: 1024px) {
  .section {
    padding-block: var(--s-3xl);
  }
}
.stack { display: flex; flex-direction: column; }
.stack--2xs { gap: var(--s-2xs); }
.stack--xs { gap: var(--s-xs); }
.stack--sm { gap: var(--s-sm); }
.stack--md { gap: var(--s-md); }
.stack--lg { gap: var(--s-lg); }
.stack--xl { gap: var(--s-xl); }
.stack--2xl { gap: var(--s-2xl); }

.grid { display: grid; gap: var(--s-sm); grid-template-columns: 1fr; }
.grid--lg { gap: var(--s-lg); }
@media (min-width: 768px) {
  .grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---------------------------------------------------------------- *
 * Type roles
 * ---------------------------------------------------------------- */
/* The overline, lifted from the logo lockup `·ELITE STRENGTH·`. The middots
   are a type style, so they live here and not in the copy. */
.eyebrow {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--fg-muted);
}
.eyebrow::before { content: '\00b7\00a0'; }
.eyebrow::after { content: '\00a0\00b7'; }

.lede {
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--fg);
  max-width: 40ch;
}
.muted { color: var(--fg-muted); }
.measure { max-width: 68ch; }
.num { font-variant-numeric: tabular-nums; }

.h-page { font-size: 2.25rem; }
.h-section { font-size: 1.75rem; }
.h-card { font-size: 1.125rem; }
@media (min-width: 768px) {
  .h-page { font-size: 3.5rem; }
  .h-section { font-size: 2.25rem; }
  .h-card { font-size: 1.25rem; }
}

/* ---------------------------------------------------------------- *
 * Display type. The bigger the headline, the narrower the width
 * axis -- never fatter. Weight stays 800 throughout; this is what
 * makes the type read hard without turning into a slab, carried
 * beyond just the hero.
 * ---------------------------------------------------------------- */
.d-1, .d-2 {
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--fg-strong);
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 0.94;
  margin: 0;
  text-wrap: balance;
}
.d-1 { font-stretch: 62%; font-size: clamp(3rem, 5vw + 2.1rem, 7.5rem); }
.d-2 { font-stretch: 70%; font-size: clamp(2.1rem, 3vw + 1.2rem, 3.75rem); }

/* ---------------------------------------------------------------- *
 * Wordmark. Interim, set in type: the only logo artwork available is a
 * photograph of a banner. Swap for vector art when it exists.
 * ---------------------------------------------------------------- */
.wordmark { display: flex; flex-direction: column; gap: var(--s-3xs); text-decoration: none; }
.wordmark__name {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 70%;
  text-transform: uppercase;
  font-size: 1.125rem;
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--fg-strong);
}
.wordmark__strap {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--fg-muted);
  border-top: 1px solid var(--iron-700);
  padding-top: var(--s-3xs);
}
.wordmark__strap::before { content: '\00b7\00a0'; }
.wordmark__strap::after { content: '\00a0\00b7'; }
@media (min-width: 768px) { .wordmark__name { font-size: 1.375rem; } }

/* ---------------------------------------------------------------- *
 * Buttons — 3px corners, the only rounding in the system.
 * ---------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2xs);
  min-height: 3rem;
  padding: 0.875rem var(--s-md);
  border-radius: var(--radius-button);
  border: 1px solid transparent;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration) ease, color var(--duration) ease,
    border-color var(--duration) ease;
}
.btn--primary {
  background: var(--fg-strong);
  color: var(--surface);
  border-color: var(--fg-strong);
}
.btn--primary:hover { background: var(--fg); border-color: var(--fg); }
.btn--secondary {
  background: transparent;
  color: var(--fg-strong);
  border-color: var(--fg-strong);
}
.btn--secondary:hover { background: var(--fg-strong); color: var(--surface); }
/* border-color is fg-muted, NOT surface-border: the latter is near-invisible
   on a raised band, which is how ghost buttons once disappeared entirely. */
.btn--ghost {
  background: transparent;
  color: var(--fg-strong);
  border-color: var(--fg-muted);
}
.btn--ghost:hover { border-color: var(--fg-strong); }
.btn--sm { min-height: 2.5rem; padding-block: 0.5rem; font-size: 0.75rem; }

/* ---------------------------------------------------------------- *
 * Cards
 * ---------------------------------------------------------------- */
.card {
  background: var(--surface-raised);
  border: 1px solid var(--surface-border);
  border-radius: 0;
  padding: var(--s-md);
  display: flex;
  flex-direction: column;
  gap: var(--s-2xs);
}
@media (min-width: 768px) { .card { padding: var(--s-lg); } }
.card--featured { border-color: var(--fg-strong); }
.card__list { display: flex; flex-direction: column; gap: var(--s-3xs); }
.card__list li {
  font-size: 0.9375rem;
  color: var(--fg);
  padding-left: var(--s-sm);
  position: relative;
}
.card__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.7em;
  width: 6px;
  height: 1px;
  background: var(--fg-muted);
}

.price { display: flex; align-items: baseline; gap: var(--s-3xs); }
.price strong {
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 88%;
  font-size: 2.5rem;
  line-height: 1;
  color: var(--fg-strong);
  font-variant-numeric: tabular-nums;
}
.price span { font-size: 0.8125rem; color: var(--fg-muted); }

/* ---------------------------------------------------------------- *
 * Hero
 *
 * The mark, the copy and the stat strip are siblings in one column. The
 * copy is pushed down with margin-top:auto rather than the column being
 * end-justified, so the mark stays in the flow and cannot be overlapped
 * however tall the headline grows — an absolutely positioned mark did
 * exactly that at desktop with a three-line headline.
 * ---------------------------------------------------------------- */
.hero {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  min-height: 100svh;
  overflow: hidden;
  border-bottom: 1px solid var(--iron-700);
}
/* The interior hero carries no photograph, so it has to paint its own band.
   Without this it is transparent and the data-tone on it does nothing —
   membership and contact lost the tonal step between the hero and the first
   section, and both read as one undifferentiated black slab. */
.hero--interior {
  min-height: 0;
  padding-block: var(--s-3xl) var(--s-2xl);
  background: var(--surface);
}
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 50%;
  filter: grayscale(1) contrast(1.22) brightness(0.62);
}
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image:
    linear-gradient(to top, #000 0%, rgb(0 0 0 / 0.72) 34%, rgb(0 0 0 / 0.15) 72%),
    linear-gradient(to right, rgb(0 0 0 / 0.7) 0%, rgb(0 0 0 / 0) 65%);
}
.hero__inner {
  position: relative;
  z-index: 1;
  margin-top: auto;
  padding-block: var(--s-lg);
  display: flex;
  flex-direction: column;
  gap: var(--s-lg);
}
@media (min-width: 768px) { .hero__inner { padding-block: var(--s-2xl); } }
.hero__headline {
  /* Scales with the phone: at a fixed 4rem "EVERYTHING" ran to the very
     edge of a 375px screen. */
  font-size: clamp(2.75rem, 14.5vw, 4rem);
  line-height: 0.86;
  letter-spacing: -0.03em;
  font-stretch: 84%;
}
.hero__headline span { display: block; }
@media (min-width: 768px) { .hero__headline { font-size: 7.5rem; } }
@media (min-width: 1024px) { .hero__headline { font-size: 9.5rem; } }
.hero__actions { display: flex; flex-direction: column; gap: var(--s-2xs); }
@media (min-width: 768px) {
  .hero__actions { flex-direction: row; align-items: flex-start; }
}

/* ---------------------------------------------------------------- *
 * Photography. Forced monochrome so the colour phone shots sit in the
 * same world as the black-and-white ones, without anyone having to
 * convert a new upload first.
 * ---------------------------------------------------------------- */
.photo { filter: grayscale(1) contrast(1.18) brightness(0.9); }

/* Duotone: black to chalk, mapped through luminance rather than a flat
   desaturate. Holds shadow detail flat greyscale crushes -- load-bearing
   on a 1100px iPhone photo of a dim warehouse. Filter defs live once in
   header.php. */
.photo.duo { filter: url(#duo) contrast(1.08); }

.figure { display: flex; flex-direction: column; gap: var(--s-2xs); min-width: 0; }
.figure img {
  width: 100%;
  border: 1px solid var(--surface-border);
  object-fit: cover;
  aspect-ratio: 4 / 3;
}
.figure--band img { aspect-ratio: 21 / 9; }
.figure figcaption {
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-500, var(--iron-500));
}

/* A full-bleed strip between sections, used as a breath. Deliberately
   carries no overlaid text: a band with a headline becomes a second hero
   and competes with the real one. Taller on a phone, because a 21:9 slice
   of a portrait snapshot is a band of floor. */
.mediaband { overflow: hidden; }
.mediaband img { width: 100%; object-fit: cover; aspect-ratio: 4 / 3; }
@media (min-width: 768px) { .mediaband img { aspect-ratio: 21 / 9; } }

/* ---------------------------------------------------------------- *
 * FAQ. <summary> must be a direct child of <details> — nesting it inside
 * a wrapper renders the row as a bare "Details" marker.
 * ---------------------------------------------------------------- */
.faq { border-top: 1px solid var(--surface-border); }
.faq details { border-bottom: 1px solid var(--surface-border); }
.faq summary {
  cursor: pointer;
  list-style: none;
  padding-block: var(--s-md);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-sm);
  font-family: var(--font-display);
  font-stretch: 88%;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 1rem;
  color: var(--fg-strong);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; color: var(--fg-muted); font-weight: 400; }
.faq details[open] summary::after { content: '\2013'; }
.faq__answer { padding-bottom: var(--s-md); color: var(--fg-muted); max-width: 68ch; }

/* ---------------------------------------------------------------- *
 * Header / footer
 * ---------------------------------------------------------------- */
.siteheader {
  position: relative;
  z-index: 20;
  background: var(--iron-950);
  border-bottom: 1px solid var(--surface-border);
}
.siteheader__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-sm);
  padding-block: var(--s-sm);
}
.nav { display: none; }
@media (min-width: 768px) { .nav { display: block; } }
.nav__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-md);
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav a {
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--fg-muted);
  transition: color var(--duration) ease;
}
.nav a:hover, .nav a[aria-current='page'] { color: var(--fg-strong); }
.siteheader .btn { display: none; }
@media (min-width: 768px) { .siteheader .btn { display: inline-flex; } }

/* Phone nav: a plain row under the mark. No JS, no drawer — four links
   fit, and a hamburger for four links is theatre. */
.nav--phone { display: block; padding-bottom: var(--s-2xs); }
.siteheader .nav--phone .nav__list { gap: 0; justify-content: space-between; }
.nav--phone a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--fg-muted);
}
.nav--phone a:hover, .nav--phone a[aria-current='page'] { color: var(--fg-strong); }
@media (min-width: 768px) { .nav--phone { display: none; } }

.sitefooter {
  background: var(--iron-950);
  border-top: 1px solid var(--surface-border);
  padding-block: var(--s-2xl);
  color: var(--fg-muted);
  font-size: 0.875rem;
}
.sitefooter { font-size: 0.9375rem; }
.sitefooter a { text-decoration: none; }
/* One rhythm for every line in a column: each is a 44px row, so links are
   full-size tap targets and plain lines sit on the same beat. */
.sitefooter__col { display: flex; flex-direction: column; }
/* Plain lines run at body line-height, like an address. A link gets a 44px
   tap row that hangs BELOW its text (text top-aligned), so the first line
   of every column still starts on the same line, and consecutive links are
   8px apart. */
.sitefooter__col > .eyebrow { margin-bottom: var(--s-xs); }
.sitefooter__col > p { text-wrap: pretty; }
.sitefooter__col > p > a {
  /* 44px tap area from padding cancelled by negative margin: the target
     is full size but adds no invisible height to the layout, so the
     visible gaps are the real gaps. */
  display: inline-block;
  padding-block: 0.625rem;
  margin-block: -0.625rem;
}
.sitefooter__col > p:has(> a) + p:has(> a) { margin-top: calc(1.25rem + var(--s-2xs)); }
.sitefooter__col > p:not(.eyebrow):not(:has(> a)) + p:has(> a) { margin-top: var(--s-xs); }
.sitefooter__bottom > p { font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; }
.sitefooter__nav { flex: 1 1 100%; }
@media (min-width: 768px) { .sitefooter__nav { flex: 0 1 auto; } }
.sitefooter__nav .nav__list { display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 0 var(--s-lg); }
@media (min-width: 768px) { .sitefooter__nav .nav__list { justify-content: flex-start; gap: 0 var(--s-md); } }
.sitefooter__nav a {
  display: inline-flex; align-items: center; min-height: 2.75rem;
  font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
}
.sitefooter a:hover { color: var(--fg-strong); }
.sitefooter__grid { display: grid; gap: var(--s-2xl) var(--s-lg); grid-template-columns: 1fr; }
/* Three equal columns, each opening on the same label row; the brand sits
   above them rather than as a fourth column with a different first line. */
@media (min-width: 768px) { .sitefooter__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.sitefooter__brand { display: flex; flex-direction: column; gap: var(--s-2xs); max-width: 40ch; }
.sitefooter__bottom {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-md);
  justify-content: space-between;
  border-top: 1px solid var(--surface-border);
  padding-top: var(--s-md);
  font-size: 0.8125rem;
}

/* Hidden from sight, still read aloud. Clip rather than left:-9999px:
   shifting content off-canvas genuinely extends the scrollable area, which
   is both a horizontal-scroll bug waiting to happen and the wrong thing
   entirely in a right-to-left locale. */
.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border-radius: var(--radius-button);
  background: var(--fg-strong);
  color: var(--surface);
  padding: var(--s-2xs) var(--s-md);
  z-index: 50;
}
.skip-link:focus {
  width: auto;
  height: auto;
  overflow: visible;
  clip-path: none;
  left: var(--s-md);
  top: var(--s-md);
}

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

/* ================================================================== *
 * HOME PAGE
 *
 * Added after the home page was rebuilt around a single hero. The
 * brief that drove it: say powerlifting out loud, put the expansion on
 * the page, keep the heart hardcore while opening the door wider, and
 * stop being pretty. Rules here are 2-3px bars rather than hairlines,
 * photographs are pushed hard, and the labels are stencils. There is
 * not a single card on this page.
 * ================================================================== */

/* Grain. The room is used; the page should not look showroom-clean. */
.grain::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  opacity: 0.34;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* A stencil: the label as it would be sprayed on a crate or a plate rack. */
.stencil {
  display: inline-block;
  background: var(--fg-strong);
  color: var(--surface);
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 80%;
  text-transform: uppercase;
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  padding: 0.3rem 0.55rem 0.25rem;
  line-height: 1;
}
.stencil--ghost {
  background: transparent;
  color: var(--fg-strong);
  box-shadow: inset 0 0 0 2px var(--fg-strong);
}

/* ------------------------------------------------------------------ *
 * Slab: the numbered section header. One shape for every content
 * section on every page, replacing a stencil+heading pair that used
 * to repeat, identically, eight times down the home page alone. The
 * numbering is real: it is each page's own reading order, the same
 * way a spec sheet numbers its sections.
 * ------------------------------------------------------------------ */
.slab { margin-bottom: var(--s-lg); }
.slab__rule { display: flex; align-items: baseline; gap: var(--s-sm); margin-bottom: var(--s-2xs); }
.slab__num {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 82%;
  color: var(--fg-muted);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
  flex: none;
}
.slab__rule::after { content: ''; flex: 1; height: 1px; background: rgb(255 255 255 / 0.16); }
.slab__label {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--fg-muted);
  flex: none;
}
.slab__title {
  font-family: var(--font-display);
  word-spacing: 0.14em;
  font-weight: 800;
  font-stretch: 70%;
  font-size: clamp(2rem, 3vw + 1rem, 3.25rem);
  text-transform: uppercase;
  letter-spacing: -0.02em;
  color: var(--fg-strong);
  line-height: 0.96;
  margin: 0;
  text-wrap: balance;
}

/* ------------------------------------------------------------------ *
 * Sheet: one ruled-table idiom for the equipment list, the record
 * board, rates and passes, and brands -- a thick top rule, hairline
 * row separators, label left, figure right. Explicit grid-column on
 * every part rather than relying on auto-placement order: a row can
 * carry label+figure (rates), label+sub (equipment), or
 * label+figure+meta (boards), and auto-placement would put a
 * figure in the middle column whenever sub is absent.
 * ------------------------------------------------------------------ */
.sheet { border-top: 3px solid var(--fg-strong); width: 100%; }
.sheet__row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: var(--s-2xs) var(--s-md);
  padding-block: var(--s-sm);
  border-bottom: 1px solid var(--surface-border);
}
.sheet__label { grid-column: 1; }
.sheet__figure { grid-column: 2; }
.sheet__sub { grid-column: 1 / -1; }
.sheet__label {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 84%;
  text-transform: uppercase;
  color: var(--fg-strong);
  font-size: 1rem;
  letter-spacing: -0.005em;
}
.sheet__sub { font-size: 0.875rem; color: var(--fg-muted); max-width: 60ch; }
.sheet__sub + .sheet__sub { margin-top: 0.35rem; font-size: 0.8125rem; }
.sheet__sub strong { color: var(--fg-strong); }
.sheet__figure {
  font-family: var(--font-sans);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  font-size: 1rem;
  color: var(--fg-strong);
  text-align: right;
  white-space: nowrap;
}
.sheet__meta {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-md);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-muted);
  font-variant-numeric: tabular-nums;
}
.sheet__foot { padding-top: var(--s-sm); font-size: 0.8125rem; color: var(--fg-muted); max-width: 52ch; }
.sheet--featured { background: var(--iron-900); margin-inline: calc(-1 * var(--s-md)); padding-inline: var(--s-md); }
@media (min-width: 768px) {
  .sheet__row { grid-template-columns: 14rem 1fr auto; }
  .sheet__label { grid-column: 1; }
  .sheet__sub { grid-column: 2; }
  .sheet__figure { grid-column: 3; }
  .sheet__label { font-size: 1.0625rem; }
}

/* ------------------------------------------------------------------ *
 * The hero.
 * ------------------------------------------------------------------ */
.hero-home {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 88svh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.hero-home__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.hero-home__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.45) brightness(0.62);
}
.hero-home__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    rgb(0 0 0 / 0.96) 0%,
    rgb(0 0 0 / 0.45) 34%,
    rgb(0 0 0 / 0.08) 72%
  );
}
.hero-home__top {
  position: relative;
  z-index: 4;
  padding-top: var(--s-md);
}
.hero-home__bottom {
  position: relative;
  z-index: 4;
  padding-bottom: var(--s-sm);
}
/* A caption to the masthead, not a paragraph competing with it. One line on
   a wide screen; the call to action lives in the plate below, where it has an
   edge to sit against. */
.hero-home__say {
  color: var(--fg);
  font-size: 0.9375rem;
  line-height: 1.45;
  max-width: 40ch;
  margin-bottom: var(--s-sm);
}
@media (min-width: 768px) {
  .hero-home__say {
    font-size: 1.0625rem;
    max-width: none;
    margin-bottom: var(--s-2xs);
  }
}

/*
  The fitted masthead.

  `container-type: inline-size` goes on the CONTENT box -- inside the
  gutters, not outside -- so 1cqw is exactly one per cent of the width the
  headline actually has. That makes a single constant correct at every
  viewport, including above 1180px where the shell stops growing and a vw
  formula would keep scaling and overshoot.

  17cqw comes from the measured ratio of ink width to font size for this
  face at this width and tracking (about 5.855), plus a little margin.

  Verify it with scrollWidth, never with getBoundingClientRect: a nowrap
  line keeps its block box at the column width while the glyphs spill past
  it, so the rect reports a perfect fit while the last letter is cut off.
  scripts/render-check does this check.
*/
.fit {
  container-type: inline-size;
}
.hero-home__word {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 62%;
  text-transform: uppercase;
  color: var(--fg-strong);
  font-size: 17cqw;
  line-height: 0.78;
  letter-spacing: -0.02em;
  white-space: nowrap;
  margin: 0;
}

/* The plate: what this place is, in one line, immediately under the hero. */
.plate {
  border-top: 3px solid var(--fg-strong);
  border-bottom: 1px solid var(--surface-border);
  background: var(--surface);
}
.plate__in {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2xs) var(--s-md);
  align-items: center;
  padding-block: var(--s-2xs);
}
.plate__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem var(--s-md);
  align-items: center;
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 82%;
  text-transform: uppercase;
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  color: var(--fg-strong);
}
/* Full width on a phone, pushed to the far edge from tablet up. */
.plate__cta {
  width: 100%;
}
@media (min-width: 768px) {
  /* Stop wrapping the row: let the facts wrap inside themselves and shrink,
     so the button stays pinned to the right edge instead of dropping onto a
     line of its own and floating there. min-width:0 is what actually lets a
     flex item shrink below its content width. */
  .plate__in {
    flex-wrap: nowrap;
  }
  .plate__facts {
    flex: 0 1 auto;
    min-width: 0;
    /* The facts run 15px past the column once the button is beside them, so
       the separators tighten rather than the whole row wrapping. */
    gap: 0.4rem var(--s-sm);
  }
  .plate__cta {
    width: auto;
    flex: none;
    margin-left: auto;
  }
}
/* The separators only separate when the facts share a line. Stacked one per
   row on a phone they just dangle off the end of each line. */
.plate__sep {
  display: none;
  color: var(--iron-600);
}
@media (min-width: 768px) {
  .plate__sep {
    display: inline;
  }
}
@media (min-width: 768px) {
  /* The facts need 832px beside a 199px button in a 1024px column. At 1rem
     they run 31px over and "$65 a month" drops to a second line, which makes
     the bar look broken rather than full. */
  .plate__facts {
    font-size: 0.9375rem;
  }
}

/* ------------------------------------------------------------------ *
 * Figures: numbers set as graphics, not prose. auto-fit rather than a
 * fixed column count so the same block works whether it is carrying
 * 3 cells (the expansion) or 4 (the stats strip), with no empty
 * trailing grid cell either way.
 * ------------------------------------------------------------------ */
.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: 3px;
  background: var(--fg-strong);
  border: 3px solid var(--fg-strong);
}
.figures__cell {
  background: var(--surface);
  padding: var(--s-md);
}
.figures__cell dt {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 64%;
  font-size: clamp(1.75rem, 3vw + 1rem, 3rem);
  line-height: 1;
  color: var(--fg-strong);
  font-variant-numeric: tabular-nums;
}
.figures__cell dd {
  margin: 0.4rem 0 0;
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.callout {
  border-left: slab solid var(--fg-strong);
  padding-left: var(--s-md);
  max-width: 52ch;
}
.callout b {
  color: var(--fg-strong);
}

/* ------------------------------------------------------------------ *
 * The white band. With no accent hue, inverting the band is the
 * emphasis -- and it lands after the proof, so it widens the room
 * rather than softening it.
 * ------------------------------------------------------------------ */
.band-invert {
  border-top: 3px solid var(--fg-strong);
}

/* ================================================================== *
 * Photography as structure, not decoration.
 *
 * The first build put text on top of every photograph and then had to
 * scrim those photographs to 16% brightness to keep the text legible --
 * which meant the page carried three images and showed one. 17% of the
 * page was visible photography in a gym with a genuinely photogenic
 * room.
 *
 * So: nothing sits on a photograph except the hero. Everywhere else the
 * picture gets its own full-bleed band at full brightness and the words
 * sit on black underneath. Legible text and a visible room, instead of
 * a compromise that lost both.
 * ================================================================== */
.band {
  display: block;
  width: 100%;
  overflow: hidden;
  border-block: thick solid var(--fg-strong);
}
.band img {
  width: 100%;
  height: 54svh;
  object-fit: cover;
  display: block;
}
@media (min-width: 768px) {
  .band img {
    height: 66svh;
  }
}

/* Three photographs in the same full-bleed band, instead of stretching
   one past its resolution ceiling. Each frame lands under 500px CSS-wide
   at desktop, which a ~1100px source photo covers at 1x-2x, not 2.2x. */
.band--split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2px;
}
.band--split img { height: 38svh; }
@media (min-width: 768px) {
  .band--split { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .band--split img { height: 28rem; }
}

/* Text one side, photograph the other. The photograph is a real element
   here rather than a background, so it keeps its brightness. */
.split {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-lg);
  align-items: center;
}
@media (min-width: 900px) {
  .split {
    grid-template-columns: 1fr 1fr;
    gap: var(--s-2xl);
  }
  .split--wide-media {
    grid-template-columns: 1fr 1.15fr;
  }
}
.split__media img {
  width: 100%;
  height: 100%;
  min-height: 40svh;
  object-fit: cover;
  border: thick solid var(--fg-strong);
}
@media (min-width: 900px) {
  .split__media img {
    min-height: 30rem;
  }
}

/* ------------------------------------------------------------------ *
 * Home: hero title, actions, location, gallery, lightbox.
 * ------------------------------------------------------------------ */

/* The H1 names the service and the city for search; the banner line
   below it stays the biggest thing on the screen. */
.hero-home__title {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 75%;
  font-size: clamp(1.75rem, 2.4vw + 1rem, 3rem);
  line-height: 1;
  max-width: 18ch;
  margin-bottom: var(--s-xs);
}
.hero-home__actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--s-2xs);
  margin-top: var(--s-md);
}
@media (min-width: 768px) {
  .hero-home__actions { flex-direction: row; gap: var(--s-xs); }
}
.hero-home__bottom { padding-bottom: var(--s-xl); }
.hero-home__jumps { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0 var(--s-lg); width: 100%; }
@media (min-width: 768px) { .hero-home__jumps { width: auto; justify-content: flex-start; } }
.hero-home__say { max-width: 36rem; }

/* Full width on a phone, where it is the section's main action; its
   natural width from tablet up. */
.btn--block { width: 100%; }
@media (min-width: 768px) { .btn--block { width: auto; } }

/* A secondary action that is not a button: a 44px-tall text link. */
.textlink {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2.75rem;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--fg-strong);
}
.textlink:hover { text-decoration: underline; text-underline-offset: 0.3em; }

/* The banner line as the page's sign-off, fitted edge to edge. */
.signoff {
  background: var(--iron-950);
  padding-block: var(--s-3xl) var(--s-lg);
  overflow: hidden;
}
/* Dimmed: a sign-off, not a second call to action. Full white here was the
   biggest white shape on the screen right under the join button. */
.signoff .hero-home__word { color: var(--iron-700); }
/* Fitted on a phone; from tablet up capped at 7rem and left on the shell
   edge, so it never out-weighs the join button above it. */
@media (min-width: 768px) { .signoff .hero-home__word { font-size: min(17cqw, 7rem); } }

/* Anchored sections clear the header when jumped to from the nav. */
.anchor { scroll-margin-top: var(--s-md); }

.sheet__value { grid-column: 2; text-align: right; color: var(--fg-strong); font-weight: 600; }
@media (min-width: 768px) {
  .sheet__value { grid-column: 2 / -1; text-align: left; }
}
.nowrap { white-space: nowrap; }
.sheet--pairs .sheet__row { grid-template-columns: auto 1fr; }
.sheet--pairs .sheet__value {
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  column-gap: 0.3em;
  text-align: right;
}

.locate { display: grid; gap: var(--s-md); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) { .locate { gap: var(--s-xl); } }
@media (min-width: 900px) {
  .locate { grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); align-items: stretch; }
}
.locate__address {
  font-style: normal;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--fg);
}
.locate__address { color: var(--fg-strong); }
.locate__address strong { color: var(--fg-strong); }
.locate__address a { display: inline-block; padding-block: 0.625rem; margin-block: -0.625rem; }

/* One text-link style, everywhere a link sits in running text. */
.locate__address a,
.sitefooter__col a {
  color: var(--fg);
  text-decoration: underline;
  text-decoration-color: var(--iron-600);
  text-underline-offset: 3px;
}
.locate__address a:hover,
.sitefooter__col a:hover { color: var(--fg-strong); text-decoration-color: currentColor; }
.locate__actions { display: flex; flex-wrap: wrap; gap: var(--s-xs); }
.locate__map {
  border: 3px solid var(--fg-strong);
  aspect-ratio: 4 / 3;
  background: var(--iron-800);
}
/* min-height only beside the text: on a phone it would force the aspect
   ratio wider than the column (20rem tall = 427px wide). */
@media (min-width: 900px) { .locate__map { aspect-ratio: auto; min-height: 24rem; } }
.locate__map iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-height: inherit;
  border: 0;
  /* Monochrome to sit with the photography; still perfectly legible. */
  filter: grayscale(1) contrast(1.05);
}

/* Gallery: the first photograph large, the rest square. 9 photographs
   fill a 3-column grid exactly (4 + 8 cells) and a 2-column one too. */
.gallery {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 3px;
}
@media (min-width: 768px) {
  .gallery { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.gallery__item { aspect-ratio: 1; overflow: hidden; background: var(--iron-800); }
.gallery__item:first-child { grid-column: span 2; grid-row: span 2; }
.gallery__item a { display: block; height: 100%; }
.gallery__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 400ms ease;
}
.gallery__item a:hover img,
.gallery__item a:focus-visible img { transform: scale(1.04); }

.lightbox {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: 100vw;
  max-height: 100svh;
  width: 100%;
  height: 100%;
}
.lightbox::backdrop { background: rgb(0 0 0 / 0.92); }
.lightbox[open] { display: grid; place-items: center; }
.lightbox__img {
  max-width: calc(100vw - 2rem);
  max-height: calc(100svh - 6rem);
  width: auto;
  height: auto;
  object-fit: contain;
}
.lightbox__btn {
  position: fixed;
  width: 3rem;
  height: 3rem;
  border: 1px solid var(--iron-500);
  border-radius: var(--radius-button);
  background: var(--iron-950);
  color: #fff;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.lightbox__btn:hover { border-color: #fff; }
.lightbox__close { top: var(--s-sm); right: var(--s-sm); }
.lightbox__prev { bottom: var(--s-sm); left: var(--s-sm); }
.lightbox__next { bottom: var(--s-sm); right: var(--s-sm); }

/* ------------------------------------------------------------------ *
 * Pricing: a segmented switch over compact plan cards. Built for the
 * phone first -- one tab shows at most four short cards, each with the
 * name and price on a single line so the price is never hunted for.
 * ------------------------------------------------------------------ */
.pricing__tabs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  border: 1px solid var(--iron-600);
  /* The 1px gap over this colour draws the dividers, in both 2x2 and 1x4. */
  background: var(--iron-600);
  margin-bottom: var(--s-md);
}
@media (min-width: 480px) {
  .pricing__tabs { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.pricing__tabs[hidden] { display: none; }
.pricing__tabs [role='tab'] {
  min-height: 3rem;
  padding: 0 0.25rem;
  border: 0;
  border-radius: 0;
  padding-inline: var(--s-xs);
  background: var(--iron-950);
  color: var(--fg-muted);
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 80%;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.8125rem;
  cursor: pointer;
  transition: background-color var(--duration) ease, color var(--duration) ease;
}
.pricing__tabs [role='tab']:hover { color: var(--fg-strong); }
.pricing__tabs [role='tab'][aria-selected='true'] {
  background: var(--iron-800);
  color: #fff;
  box-shadow: inset 0 0 0 2px #fff;
}

.pricing__panel + .pricing__panel { margin-top: var(--s-xl); }
.pricing.is-tabbed .pricing__panel + .pricing__panel { margin-top: 0; }
.pricing__panel-title { font-size: 1.125rem; margin-bottom: var(--s-sm); }
.pricing.is-tabbed .pricing__panel-title {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

.plans {
  display: grid;
  gap: var(--s-xs);
  grid-template-columns: minmax(0, 1fr);
}
/* Two across at most: four 250px cards squeezed name and price together. */
@media (min-width: 640px) { .plans { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.plan {
  display: flex;
  flex-direction: column;
  gap: var(--s-2xs);
  padding: var(--s-md);
  background: var(--iron-950);
  border: 1px solid var(--surface-border);
}
.plan--featured { border-color: #fff; }
.plan__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s-sm);
}
.plan__name {
  font-size: 1rem;
  font-stretch: 84%;
  letter-spacing: 0;
}
.plan__price { flex: none; display: flex; align-items: baseline; gap: 0.2rem; white-space: nowrap; }
.plan__price strong {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 84%;
  font-size: 1.75rem;
  line-height: 1;
  color: var(--fg-strong);
  font-variant-numeric: tabular-nums;
}
.plan__price span { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-muted); }
.plan__desc { font-size: 0.9375rem; color: var(--fg-muted); line-height: 1.5; }
@media (min-width: 768px) {
  .plan__name { font-size: 1.125rem; }
  .plan__desc { font-size: 1.0625rem; }
}
.plan__list {
  display: flex;
  flex-direction: column;
  gap: var(--s-2xs);
  padding-top: var(--s-2xs);
  border-top: 1px solid var(--surface-border);
}
.plan__list li {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--iron-300);
}



/* A label and time ranges that wrap between ranges, never inside one. */
.hours-line { display: flex; flex-wrap: wrap; column-gap: 0.3em; }


/* The grand opening: the news, set as a poster line in the hero's top
   corner -- big condensed date under a solid label, ruled on the left.
   Not a white box: solid white is reserved for the join button. */
.opening {
  display: flex;
  flex-direction: column;
  gap: var(--s-2xs);
  padding-left: var(--s-sm);
  border-left: 4px solid #fff;
}
.opening__label {
  align-self: flex-start;
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 80%;
  font-size: 0.875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #fff;
}
.opening__date {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 70%;
  font-size: clamp(2.25rem, 4vw + 1rem, 4.5rem);
  line-height: 0.92;
  letter-spacing: -0.01em;
  word-spacing: 0.12em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 2px 24px rgb(0 0 0 / 0.5);
}
@media (min-width: 768px) {
  .opening { padding-left: var(--s-md); border-left-width: 6px; }
  .opening__label { font-size: 1rem; }
}

/* ------------------------------------------------------------------ *
 * Hero on a phone: the photograph at its own 4:3 shape, sharp, with the
 * grand opening on it and the headline and button on black below.
 * Covering a tall phone screen instead meant blowing a 1179px-wide photo
 * up ~2.5x -- visibly soft -- and cropping most of the floor away.
 * ------------------------------------------------------------------ */
@media (max-width: 767px) {
  .hero-home { min-height: 0; display: block; }
  .hero-home__media { position: relative; inset: auto; aspect-ratio: 4 / 3; z-index: 0; }
  .hero-home__scrim {
    inset: 0 0 auto 0;
    aspect-ratio: 4 / 3;
    z-index: 1;
    background: linear-gradient(to bottom, rgb(0 0 0 / 0.55) 0%, rgb(0 0 0 / 0) 55%, rgb(0 0 0 / 0.35) 100%);
  }
  .hero-home__top { position: absolute; top: 0; left: 0; right: 0; z-index: 4; }
  .hero-home__bottom { padding-top: var(--s-lg); background: var(--iron-950); }
  .opening__date { font-size: 2rem; }
}

/* ------------------------------------------------------------------ *
 * Phone menu: a 48px toggle in the header; the links drop down as a
 * full-width panel of large rows. Only once JS has run (.has-menu-js);
 * without it the links stay a plain visible row.
 * ------------------------------------------------------------------ */
.menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  margin-right: -0.75rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: #fff;
  cursor: pointer;
}
.menu-toggle[hidden] { display: none; }
@media (min-width: 768px) { .menu-toggle { display: none; } }
.menu-toggle__bars,
.menu-toggle__bars::before,
.menu-toggle__bars::after {
  display: block;
  width: 1.5rem;
  height: 2px;
  background: currentColor;
  transition: transform var(--duration) ease, opacity var(--duration) ease;
}
.menu-toggle__bars { position: relative; }
.menu-toggle__bars::before,
.menu-toggle__bars::after { content: ''; position: absolute; left: 0; }
.menu-toggle__bars::before { top: -7px; }
.menu-toggle__bars::after { top: 7px; }
.menu-toggle[aria-expanded='true'] .menu-toggle__bars { background: transparent; }
.menu-toggle[aria-expanded='true'] .menu-toggle__bars::before { transform: translateY(7px) rotate(45deg); }
.menu-toggle[aria-expanded='true'] .menu-toggle__bars::after { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 767px) {
  .has-menu-js .siteheader .nav--phone { display: none; padding-bottom: 0; }
  .has-menu-js .siteheader .nav--phone.is-open {
    display: block;
    border-top: 1px solid var(--surface-border);
    padding-block: var(--s-2xs) var(--s-md);
  }
  .has-menu-js .siteheader .nav--phone .nav__list { flex-direction: column; align-items: stretch; }
  .has-menu-js .siteheader .nav--phone a {
    display: flex;
    min-height: 3.25rem;
    font-family: var(--font-display);
    font-weight: 800;
    font-stretch: 80%;
    font-size: 1.5rem;
    letter-spacing: 0.02em;
    color: #fff;
    border-bottom: 1px solid var(--surface-border);
  }
  .has-menu-js .siteheader .nav--phone a[aria-current='page'] { color: var(--fg-muted); }
}

/* The logo: the gym's own mark, white on transparent. Sized by height so
   the lockup's small "ELITE STRENGTH" line stays legible. */
.brandmark { display: inline-flex; align-items: center; line-height: 0; }
.brandmark img { height: 2.75rem; width: auto; }
@media (min-width: 768px) { .brandmark img { height: 3.25rem; } }

/* The machine set: an even grid of portrait shots, one per machine --
   2 across on a phone, 4 from tablet up (28 photos fill both exactly). */
.gallery--even { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 768px) { .gallery--even { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.gallery--even .gallery__item { aspect-ratio: 3 / 4; }
.gallery--even .gallery__item:first-child { grid-column: auto; grid-row: auto; }

/* Each plan card's own text button: outlined (the one solid button stays
   the hero's), full width, pinned to the card's foot so a row of cards
   lines their buttons up. */
.plan__cta { width: 100%; margin-top: auto; }
.plan__cta::before { content: ''; display: block; }
.plan { padding-bottom: var(--s-md); }
.plan > .plan__cta { margin-top: auto; }
.plan > :nth-last-child(2) { margin-bottom: var(--s-sm); }

/* Membership terms: the fine print under the cards, as a ruled list --
   readable at body size, quieter than the cards above it. */
.terms { border-top: 1px solid var(--surface-border); padding-top: var(--s-md); }
.terms__title {
  font-size: 0.75rem;
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--fg-muted);
  margin-bottom: var(--s-xs);
}
.terms__list { display: flex; flex-direction: column; gap: var(--s-2xs); max-width: 60ch; }
.terms__list li {
  position: relative;
  padding-left: var(--s-sm);
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--fg);
}
.terms__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.7em;
  width: 6px;
  height: 1px;
  background: var(--fg-muted);
}
