/* =========================================================================
   QNTM Fit Life - shared stylesheet
   Built to DESIGN-SPEC.md. Plain CSS, custom properties for tokens.
   Sections: 1 Reset  2 Tokens  3 Type  4 Layout  5 Nav  6 Buttons
   7 Cards  8 Hero  9 Full-bleed  10 Section patterns  11 Footer
   12 Utilities  13 Motion / a11y
   ========================================================================= */

/* ---------- 1. Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body, h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd { margin: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  min-height: 100vh;
  overflow-x: hidden; /* belt and braces against the 375px horizontal-scroll requirement */
  font-family: var(--font-body);
  color: var(--color-black);
  background: var(--color-white);
  line-height: 1.6;
}
img, picture, video { display: block; max-width: 100%; }
ul[class], ol[class] { list-style: none; padding: 0; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input, textarea, select { font: inherit; }

/* ---------- 2. Tokens ---------- */
:root {
  /* colour */
  --color-black: #1a1a1a;
  --color-white: #ffffff;
  --color-charcoal: #3a4248;
  --color-steel: #8b949e;
  --border-on-light: rgba(139, 148, 158, 0.25);
  --border-on-dark: rgba(139, 148, 158, 0.35);

  /* spacing scale, 8px base */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --space-10: 128px;

  /* type */
  --font-display: 'Oswald', 'Arial Narrow', sans-serif;
  --font-body: 'Montserrat', Arial, sans-serif;

  /* layout */
  --container-max: 1280px;
  --pad-mobile: 16px;
  --pad-tablet: 20px;
  --pad-desktop: 24px;

  /* motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---------- 3. Type ---------- */
.h1, .h2, .h3, .h4 { font-family: var(--font-display); color: inherit; text-transform: uppercase; }
.h1 {
  font-weight: 700;
  font-size: clamp(2.75rem, 2rem + 4vw, 5.5rem);
  line-height: 0.95;
  letter-spacing: -0.01em;
}
.h2 {
  font-weight: 700;
  font-size: clamp(2rem, 1.5rem + 2.5vw, 3.5rem);
  line-height: 1.0;
  letter-spacing: -0.005em;
  /* Added 2026-08-19. The gap below a heading is a design decision, not a
     per-page one. It used to be set inline on every h2, which drifted to five
     different values across the site. Set it once here; do not reintroduce
     inline margin-bottom on .h2. */
  margin-bottom: var(--space-4);
}
.h3 {
  font-weight: 600;
  font-size: clamp(1.375rem, 1.2rem + 0.8vw, 2rem);
  line-height: 1.05;
}
.h4 {
  font-weight: 600;
  font-size: 1.125rem;
  line-height: 1.15;
  letter-spacing: 0.04em;
}
.eyebrow {
  display: block;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.8125rem;
  line-height: 1.3;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  /* Desiree's spec addendum, fix round 2026-08: Steel Gray (#8b949e) on
     white measures ~3.07:1, below the 4.5:1 AA floor for text. Charcoal
     Slate (#3a4248) is the correct token for text on light backgrounds;
     Steel Gray stays correct for text on dark/photography backgrounds
     (still ~5-6:1 there, see the .hero/.fullbleed/.section--black override
     below) - this default covers every eyebrow that sits on a light
     section unless overridden. */
  color: var(--color-charcoal);
  margin-bottom: var(--space-3);
}
.hero .eyebrow,
.fullbleed .eyebrow,
.section--black .eyebrow {
  color: var(--color-steel);
}
.body-lg { font-family: var(--font-body); font-weight: 400; font-size: 1.125rem; line-height: 1.6; }
.body { font-family: var(--font-body); font-weight: 400; font-size: 1rem; line-height: 1.6; }
.body-sm { font-family: var(--font-body); font-weight: 400; font-size: 0.875rem; line-height: 1.5; }
.prose { max-width: 720px; }

/* Brand name mark: standalone "QNTM" mentions in running text (not the logo file). */
.brand-mark {
  font-family: var(--font-body);
  font-style: italic;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

/* ---------- 4. Layout ---------- */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--pad-mobile);
}
@media (min-width: 768px) { .container { padding-inline: var(--pad-tablet); } }
@media (min-width: 1024px) { .container { padding-inline: var(--pad-desktop); } }

.section { padding-block: var(--space-8); }
@media (min-width: 1024px) { .section { padding-block: var(--space-9); } }
.section--scale { padding-block: var(--space-8); }
/* The last-updated stamp is its own section now (see layout.js lastUpdated).
   It is a one-line footnote, so it must not claim a full section's height. */
.section--tight { padding-block: 0 var(--space-8); }
@media (min-width: 1024px) { .section--scale { padding-block: var(--space-10); } }

.section--white { background: var(--color-white); color: var(--color-black); }
.section--black { background: var(--color-black); color: var(--color-white); }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--color-white);
  color: var(--color-black);
  padding: var(--space-3) var(--space-5);
  font-family: var(--font-body);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.skip-link:focus {
  left: var(--space-4);
  top: var(--space-4);
}

/* Visible keyboard focus everywhere, dark or light background */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

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

/* ---------- 5. Nav ---------- */
.site-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  height: 72px;
  background: var(--color-black);
  display: flex;
  align-items: center;
}
@media (min-width: 1024px) { .site-nav { height: 88px; } }

.site-nav__inner {
  display: flex;
  align-items: center;
  width: 100%;
  /* Fixed 2026-08 fix round: justify-content:space-between distributed
     "leftover" space between exactly 3 items (logo, links list, CTA). Once
     the links list itself is wide (which it is, by design - lots of real
     URLs), there was almost no leftover space left to distribute, so the
     logo-to-first-link gap measured 0-0.4px at nearly every desktop width.
     An explicit gap is a hard floor flexbox cannot squeeze away, unlike
     space-between's leftover-space division. */
  gap: var(--space-6);
}

.site-nav__logo {
  /* Reserved area, never shrunk. This is also half of the aspect-ratio
     distortion fix below: the old space-between layout could flex-shrink
     the logo's containing link below the image's natural width once the
     nav ran tight (1024-1150px), and the global reset rule `img { max-width:
     100% }` then capped the image's rendered width to that shrunk box while
     height stayed CSS-fixed, squashing a 3.15:1 mark down to ~1.05:1. */
  flex-shrink: 0;
  display: inline-flex;
}
.site-nav__logo img {
  display: block;
  flex-shrink: 0;
  height: 40px;
  width: 126px; /* fixed, not auto - matches the source lockup's 3612:1145 (~3.1546:1) ratio at this height so a squeezed flex box can never distort it */
  object-fit: contain;
}
@media (min-width: 1024px) {
  .site-nav__logo img { height: 56px; width: 177px; }
}

.site-nav__links {
  display: none;
  align-items: center;
  gap: var(--space-4);
  list-style: none;
  flex: 1 1 auto;
  min-width: 0;
}
/* Desktop nav needs 1280px, not 1024px. Fixed 2026-08-11: the links were
   revealed from 1024px, but eight top-level items plus the Join Now CTA do not
   fit below roughly 1200px. The list overflowed its own container, clipping
   COMMUNITY to "CO" and hiding MORE behind the button - visible on ordinary
   laptop widths. Tightening font and gap in that band was already tried (the
   rule that used to sit on the next line) and was not enough. Below 1280 the
   hamburger is the honest answer. */
@media (min-width: 1280px) { .site-nav__links { display: flex; gap: var(--space-4); } }

.nav-link {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-white);
  white-space: nowrap;
  padding: var(--space-2) 0;
}

.nav-link:hover { color: var(--color-steel); }

.site-nav__group { position: relative; display: flex; align-items: center; }
.site-nav__group-toggle {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2);
  color: var(--color-white);
}
.site-nav__group-toggle svg { width: 12px; height: 12px; transition: transform 150ms var(--ease-out); }
.site-nav__group-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }

.site-nav__submenu {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 200px;
  background: var(--color-black);
  border: 1px solid var(--border-on-dark);
  padding: var(--space-3);
  display: none;
  flex-direction: column;
  gap: var(--space-3);
}
.site-nav__submenu.is-open { display: flex; }
.site-nav__submenu--right { left: auto; right: 0; }
.site-nav__group-label {
  display: inline-flex;
  align-items: center;
}

/* Found during fix-round verification: `.btn { display: inline-flex }` (section
   6, later in this file) has equal specificity to a plain `.site-nav__cta`
   selector and was winning the cascade by source order, so the CTA button
   was actually rendering at every width, including mobile, this whole time -
   a latent bug that only became visible as overflow once the nav gap and
   touch-target fixes below tightened the available space. `a.site-nav__cta`
   (element+class) has higher specificity than `.btn` (class only) and
   reliably wins regardless of source order. */
a.site-nav__cta { display: none; flex-shrink: 0; }
@media (min-width: 1280px) { a.site-nav__cta { display: inline-flex; } }

.site-nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  color: var(--color-white);
}
@media (min-width: 1280px) { .site-nav__toggle { display: none; } }
.site-nav__toggle svg { width: 24px; height: 24px; }
.site-nav__toggle .icon-close { display: none; }
.site-nav__toggle[aria-expanded="true"] .icon-open { display: none; }
.site-nav__toggle[aria-expanded="true"] .icon-close { display: block; }

.site-nav__mobile-panel {
  position: fixed;
  inset: 72px 0 0 0;
  background: var(--color-black);
  z-index: 99;
  display: none;
  overflow-y: auto;
  padding: var(--space-6) var(--pad-mobile) var(--space-8);
}
.site-nav__mobile-panel.is-open { display: block; }
@media (min-width: 1024px) { .site-nav__mobile-panel { display: none !important; } }

.site-nav__mobile-list { display: flex; flex-direction: column; gap: var(--space-5); }
.site-nav__mobile-list .nav-link { font-size: 1.125rem; }
.site-nav__mobile-sub { display: flex; flex-direction: column; gap: var(--space-4); padding-left: var(--space-5); margin-top: var(--space-3); border-left: 1px solid var(--border-on-dark); }
.site-nav__mobile-cta { margin-top: var(--space-6); }

/* ---------- 6. Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 14px 24px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.9375rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 0;
  border: 1.5px solid transparent;
  transition: background-color 175ms var(--ease-out), color 175ms var(--ease-out), border-color 175ms var(--ease-out);
  white-space: nowrap;
}
@media (min-width: 768px) { .btn { padding: 16px 32px; } }

.btn--primary-dark { background: var(--color-white); color: var(--color-black); border-color: var(--color-white); }
.btn--primary-dark:hover { background: transparent; color: var(--color-white); }

.btn--primary-light { background: var(--color-black); color: var(--color-white); border-color: var(--color-black); }
.btn--primary-light:hover { background: transparent; color: var(--color-black); }

.btn--outline-dark { background: transparent; color: var(--color-white); border-color: var(--color-white); }
.btn--outline-dark:hover { background: var(--color-white); color: var(--color-black); }

.btn--outline-light { background: transparent; color: var(--color-black); border-color: var(--color-black); }
.btn--outline-light:hover { background: var(--color-black); color: var(--color-white); }

.btn-row { display: flex; gap: var(--space-4); flex-wrap: wrap; }
@media (max-width: 767px) { .btn-row { flex-direction: column; gap: var(--space-3); } .btn-row .btn { width: 100%; } }

/* ---------- 7. Cards ---------- */
.card {
  border-radius: 0;
  border: 1px solid var(--border-on-light);
  padding: var(--space-5);
}
@media (min-width: 1024px) { .card { padding: var(--space-6); } }

.card--on-dark { border-color: var(--border-on-dark); background: var(--color-charcoal); color: var(--color-white); }

.checklist { display: flex; flex-direction: column; gap: var(--space-3); }
.checklist__item { display: flex; align-items: flex-start; gap: var(--space-3); }
.checklist__item svg { flex-shrink: 0; width: 20px; height: 20px; margin-top: 2px; color: var(--color-steel); }

/* ---------- 8. Hero ---------- */
.hero {
  position: relative;
  height: 100vh;
  min-height: 640px;
  max-height: 960px;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--color-black);
}
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media img, .hero__media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.hero__overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(26,26,26,0.35) 0%, rgba(26,26,26,0.15) 38%, rgba(26,26,26,0.78) 100%);
}
.hero__content {
  position: relative;
  z-index: 2;
  width: 100%;
  padding-bottom: var(--space-8);
}
@media (min-width: 1024px) { .hero__content { padding-bottom: var(--space-9); } }
.hero__content-inner { max-width: 640px; }
.hero__content .h1 {
  color: var(--color-white);
  text-shadow: 0 2px 24px rgba(0,0,0,0.5);
  margin-bottom: var(--space-6);
}
.hero__scroll-cue {
  position: absolute;
  bottom: var(--space-5);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  width: 1px;
  height: 32px;
  background: rgba(255,255,255,0.6);
  animation: hero-cue-fade 2s ease-in-out infinite;
}
@keyframes hero-cue-fade { 0%, 100% { opacity: 0.15; } 50% { opacity: 0.6; } }

/* ---------- 9. Full-bleed scale sections ---------- */
.fullbleed {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  color: var(--color-white);
}
.fullbleed__media { position: absolute; inset: 0; z-index: 0; }
.fullbleed__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; }
.fullbleed__overlay { position: absolute; inset: 0; z-index: 1; }
.fullbleed__overlay--edge { background: linear-gradient(180deg, rgba(26,26,26,0.15) 0%, rgba(26,26,26,0.65) 100%); }
.fullbleed__content { position: relative; z-index: 2; width: 100%; }
.fullbleed__content .h2, .fullbleed__content .h3 { text-shadow: 0 2px 20px rgba(0,0,0,0.45); }
.fullbleed__content .body-lg, .fullbleed__content .body { text-shadow: 0 2px 20px rgba(0,0,0,0.45); }
.fullbleed--center { justify-content: center; text-align: center; }
.fullbleed--left { justify-content: flex-start; }
.fullbleed--right { justify-content: flex-end; }
.fullbleed__block { max-width: 640px; }

/* Local scrim behind eyebrow labels on full-bleed photography, per
   DESIGN-SPEC.md section 6's text-legibility rule. Direct pixel sampling
   (see build report) measured the rack-row banner's eyebrow at 4.39:1
   against the raw photo, just under the 4.5:1 small-text AA floor. Rather
   than raising the section-wide gradient (which would flatten the photo
   everywhere), this tight, soft-edged scrim sits only behind the label
   itself, sized to content so it never affects layout or overflows. */
.fullbleed .eyebrow,
.hero .eyebrow {
  display: inline-block;
  padding: var(--space-1) var(--space-3);
  background: rgba(26, 26, 26, 0.45);
  border-radius: 0; /* rectangular discipline, section 8 - no exceptions */
}

.divider {
  min-height: 260px;
}
.divider .fullbleed__content { text-align: center; }

/* ---------- 10. Section patterns ---------- */

/* Value strip */
.value-strip__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}
@media (min-width: 768px) { .value-strip__grid { grid-template-columns: repeat(3, 1fr); } }
.value-strip__item { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); }
.value-strip__item svg { width: 36px; height: 36px; color: var(--color-steel); }

/* Membership tiers */
.tiers__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}
/* Fixed 2026-08 fix round: 3-up at 768px overflowed by ~183px - the cards'
   own min-content (checklist text, button labels) doesn't fit a ~221px
   column. Reflow to 2-up at tablet, 3-up only once there's real desktop
   room. The third card simply wraps to its own row at 768-1023px. */
@media (min-width: 768px) { .tiers__grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-5); } }
@media (min-width: 1024px) { .tiers__grid { grid-template-columns: repeat(3, 1fr); gap: var(--space-6); } }
.tier-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--color-charcoal);
  border: 1px solid var(--border-on-dark);
  padding: var(--space-5);
  /* The card carries its own dark background, so it must also carry its own
     text colour. Fixed 2026-08-11: colour was set only on __name and the
     checklist items, so anything else inherited from the surrounding section.
     On section--black that happened to look right; on section--white the price
     rendered black on charcoal and was almost unreadable. Setting it here means
     the card is self-contained in any section. */
  color: var(--color-white);
}
@media (min-width: 1024px) { .tier-card { padding: var(--space-6); } }
.tier-card--featured { border-top: 2px solid var(--color-white); }
.tier-card__badge {
  position: absolute;
  top: 0; right: 0;
  transform: translateY(-50%);
  background: var(--color-white);
  color: var(--color-black);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: var(--space-1) var(--space-3);
}
.tier-card__name { color: var(--color-white); margin-bottom: var(--space-4); }
.tier-card__features { flex: 1 1 auto; margin-bottom: var(--space-6); }
.tier-card__features .checklist__item { color: var(--color-white); }
.tier-card .btn { align-self: stretch; }

/* Personal training alternating split */
.split {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: center;
}
@media (min-width: 1024px) { .split { grid-template-columns: 1fr 1fr; gap: var(--space-7); } }
.split--reverse .split__media { order: 0; }
.split--reverse .split__text { order: 1; }
@media (min-width: 1024px) {
  .split--reverse .split__media { order: 1; }
  .split--reverse .split__text { order: 0; }
}
.split__media img { width: 100%; height: auto; object-fit: cover; }
.split__text .body-lg { margin-bottom: var(--space-5); }

/* Amenity grid */
.amenity-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}
@media (min-width: 768px) { .amenity-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .amenity-grid { grid-template-columns: repeat(4, 1fr); gap: var(--space-6); } }
.amenity-item { display: flex; flex-direction: column; gap: var(--space-3); }
.amenity-item svg { width: 32px; height: 32px; color: var(--color-steel); }
@media (min-width: 1024px) { .amenity-item svg { width: 36px; height: 36px; } }

/* GetWell feature */
.getwell {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-7);
}
@media (min-width: 1024px) { .getwell { grid-template-columns: 2fr 3fr; gap: var(--space-8); } }
.getwell__aside { display: flex; flex-direction: column; gap: var(--space-4); align-items: flex-start; }
/* Wrapper around the featured partner logo when it links out. align-self
   overrides the aside's align-items:flex-start, which would otherwise shrink
   the anchor to fit and collapse .partner-card-box's width:100%. */
.getwell__logo-link { align-self: stretch; display: block; }
.getwell__body > * + * { margin-top: var(--space-5); }
.getwell__services {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  margin: var(--space-5) 0;
}
@media (min-width: 640px) { .getwell__services { grid-template-columns: repeat(2, 1fr); } }

/* Partner logo card */
.partner-card-box {
  /* Spec target is a fixed 160x100 (mobile) / 240x140 (desktop) box, but a
     hard-fixed width breaks the "2-up, never 1-up, even at 375px" grid rule
     once card padding and grid gutter are accounted for. Fluid width capped
     at the spec's target size gives the same result whenever there's room,
     and shrinks gracefully instead of forcing horizontal scroll when there
     isn't (only below roughly 400px). */
  width: 100%;
  max-width: 160px;
  aspect-ratio: 8 / 5;
  height: auto;
  background: var(--color-white);
  border: 1px solid rgba(58, 66, 72, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-3);
  overflow: hidden; /* crops the per-logo scale-up below without growing the card, see .partner-logo--* */
}
@media (min-width: 1024px) { .partner-card-box { max-width: 240px; aspect-ratio: 12 / 7; } }
.partner-card-box img {
  max-width: 80%;
  max-height: 70%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* SHOULD-FIX 6, fix round 2026-08: a single fixed box does not read as
   equal weight when four source PNGs have wildly different internal
   padding. Measured (see build report) the actual visible-ink bounding box
   as a percentage of each canvas: GetWell ~100% fill (reads dense/heavy at
   any uniform scale), Shed ~80-90% fill, Spine Works ~66% fill height-wise,
   The Shop ~34% fill height-wise (a flat wordmark sitting in a mostly-empty
   square canvas). All four have their ink centred within ~1-3% of true
   centre, so a per-logo transform:scale() from the box's own centre grows
   or shrinks the visible mark while cropping only the transparent padding
   (via overflow:hidden above) - never the mark itself, and never
   recolouring or filtering the source file. Values tuned so all four read
   as roughly the same optical weight side by side; re-tune here only, never
   by touching the source PNGs. */
.partner-logo { transform: scale(1); transform-origin: center center; }
.partner-logo--getwell-health { transform: scale(0.8); }
.partner-logo--shed-fitness { transform: scale(0.95); }
.partner-logo--spine-works { transform: scale(1.15); }
.partner-logo--the-shop { transform: scale(1.75); }
.partners__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}
@media (min-width: 768px) { .partners__grid { gap: var(--space-5); } }
@media (min-width: 1024px) { .partners__grid { grid-template-columns: repeat(4, 1fr); gap: var(--space-6); } }
.partner-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  text-align: center;
  border: 1px solid var(--border-on-light);
  padding: var(--space-3);
  min-width: 0;
}
@media (min-width: 768px) { .partner-item { padding: var(--space-5); } }
.partner-item__name { font-weight: 600; }
.partner-item__relationship { color: var(--color-charcoal); } /* text on white, spec addendum */

/* Local orgs */
.orgs__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}
@media (min-width: 768px) { .orgs__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .orgs__grid { grid-template-columns: repeat(3, 1fr); } }

/* Events */
.events__notice { color: var(--color-charcoal); margin-bottom: var(--space-6); } /* text on white, spec addendum */
.events__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}
@media (min-width: 640px) { .events__grid { grid-template-columns: repeat(2, 1fr); } }
.event-card {
  border: 1px solid var(--border-on-light);
  background: var(--color-white);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
/* Only present in the DOM when an event actually has an image (see main.js).
   No flat placeholder block renders when it doesn't - an event card with no
   photo is simply text-only. */
.event-card__image {
  width: 100%;
  aspect-ratio: 3 / 2;
  overflow: hidden;
}
.event-card__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.event-card__meta { color: var(--color-charcoal); } /* text on white, spec addendum */
.pill {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--color-steel); /* non-text outline, 3:1 UI-component floor still clears */
  color: var(--color-charcoal); /* text on white, spec addendum */
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: transparent;
  align-self: flex-start;
}

/* Reviews */
.reviews__frame-wrap { margin-top: var(--space-6); margin-bottom: var(--space-6); }
.reviews__frame { width: 100%; border: 0; min-height: 480px; }

/* ---------- 11. Footer ---------- */
.site-footer { background: var(--color-black); color: var(--color-white); }
.site-footer__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  padding-block: var(--space-8);
}
@media (min-width: 1024px) { .site-footer__grid { grid-template-columns: repeat(4, 1fr); padding-block: var(--space-9); } }
.site-footer__col { display: flex; flex-direction: column; gap: var(--space-3); }
.site-footer__logo img { height: 44px; width: auto; margin-bottom: var(--space-3); }
.site-footer__heading { color: var(--color-steel); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; font-size: 0.8125rem; margin-bottom: var(--space-2); }
.site-footer__links { display: flex; flex-direction: column; gap: var(--space-2); }
.site-footer__bottom {
  border-top: 1px solid var(--border-on-dark);
  padding-block: var(--space-5);
}
.site-footer__bottom-inner { display: flex; flex-wrap: wrap; gap: var(--space-4); justify-content: space-between; align-items: center; }
/* Legal row. These have to stay legible, not be hidden greyed-out small print:
   Meta and Google both check the links are actually reachable. */
.site-footer__legal { display: flex; flex-wrap: wrap; gap: var(--space-4); list-style: none; margin: 0; padding: 0; }
.site-footer__legal a { text-decoration: underline; text-underline-offset: 3px; }

/* ---------- 12. Utilities ---------- */
.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.hidden { display: none !important; }

/* ---------- 13. Motion / a11y ---------- */
@media (prefers-reduced-motion: reduce) {
  .hero__scroll-cue { animation: none; opacity: 0.4; }
  * { scroll-behavior: auto !important; }
}

/* ============================================================
   RANK TURBO PAGE COMPONENTS
   Added 2026-08-10 to support the Core 30 page format standard
   (sops/seo/rank-turbo-page-build.md). Interior pages need a
   non-video hero, a lead-with-the-answer block, a real FAQ and a
   visible last-updated date. Tokens only, no new colours.
   ============================================================ */

/* --- Interior page hero. The video hero is home-only. --- */
.page-hero {
  position: relative;
  background: var(--color-black);
  color: var(--color-white);
  padding-block: var(--space-9) var(--space-8);
  overflow: hidden;
}
@media (min-width: 1024px) { .page-hero { padding-block: var(--space-10) var(--space-9); } }

.page-hero__media { position: absolute; inset: 0; z-index: 0; }
.page-hero__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.page-hero__overlay {
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(90deg, rgba(26,26,26,0.94) 0%, rgba(26,26,26,0.80) 45%, rgba(26,26,26,0.55) 100%);
}
.page-hero__content { position: relative; z-index: 2; }
.page-hero__inner { max-width: 46rem; }
.page-hero .h1 { margin-block: var(--space-3) 0; }

/* Breadcrumb. Also the visible partner to BreadcrumbList schema. */
.crumbs { font-family: var(--font-body); font-size: 0.8125rem; letter-spacing: 0.04em; text-transform: uppercase; }
.crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.crumbs li { display: flex; align-items: center; gap: var(--space-2); color: var(--color-steel); }
.crumbs li + li::before { content: "/"; color: var(--color-steel); }
.crumbs a { color: var(--color-steel); text-decoration: none; }
.crumbs a:hover, .crumbs a:focus-visible { color: var(--color-white); text-decoration: underline; }

/* --- Rule 1 of the format standard: lead with the answer. --- */
.answer-lead {
  border-left: 3px solid var(--color-charcoal);
  padding: var(--space-5) 0 var(--space-5) var(--space-5);
  margin-block: 0 var(--space-7);
  max-width: 60ch;
}
.section--black .answer-lead { border-left-color: var(--color-steel); }
.answer-lead > :first-child { margin-top: 0; }
.answer-lead > :last-child { margin-bottom: 0; }
.answer-lead p + p { margin-top: var(--space-4); }

/* --- Rule 6: a visible last-updated date. --- */
.meta-updated {
  display: block;
  font-family: var(--font-body);
  font-size: 0.875rem;
  color: var(--color-steel);
  margin-top: var(--space-7);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-on-light);
}
.section--black .meta-updated { border-top-color: var(--border-on-dark); }

/* --- Rule 5: a real FAQ. Native details/summary, no JS. --- */
.faq { max-width: 62rem; margin-inline: auto; }
.faq__item {
  border-bottom: 1px solid var(--border-on-light);
}
.section--black .faq__item { border-bottom-color: var(--border-on-dark); }
.faq__item:first-child { border-top: 1px solid var(--border-on-light); }
.section--black .faq__item:first-child { border-top-color: var(--border-on-dark); }

.faq__q {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-5);
  padding-block: var(--space-5);
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.375rem);
  line-height: 1.25;
  text-transform: uppercase;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q:focus-visible { outline: 2px solid var(--color-steel); outline-offset: 3px; }
.faq__q::after {
  content: "";
  flex: 0 0 auto;
  width: 14px; height: 14px;
  margin-top: 0.35em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 200ms var(--ease-out);
}
.faq__item[open] .faq__q::after { transform: rotate(-135deg); }
.faq__a { padding-bottom: var(--space-5); max-width: 68ch; }
.faq__a > :first-child { margin-top: 0; }
.faq__a > :last-child { margin-bottom: 0; }
.faq__a p + p { margin-top: var(--space-4); }

@media (prefers-reduced-motion: reduce) {
  .faq__q::after { transition: none; }
}

/* --- Pricing. Real figures are rule 4; they need somewhere to live. --- */
.tier-card__price {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 1.6rem + 1.6vw, 2.75rem);
  line-height: 1;
  margin-block: var(--space-2) var(--space-5);
  display: block;
}
.tier-card__price small {
  display: block;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.875rem;
  letter-spacing: normal;
  text-transform: none;
  color: var(--color-steel);
  margin-top: var(--space-2);
}

/* --- Plain data table, for terms, hours and price comparisons. --- */
.data-table { width: 100%; border-collapse: collapse; font-family: var(--font-body); font-size: 0.9375rem; }
.data-table caption { text-align: left; color: var(--color-steel); font-size: 0.875rem; padding-bottom: var(--space-3); }
.data-table th, .data-table td { text-align: left; padding: var(--space-4) var(--space-4) var(--space-4) 0; border-bottom: 1px solid var(--border-on-light); vertical-align: top; }
.section--black .data-table th, .section--black .data-table td { border-bottom-color: var(--border-on-dark); }
.data-table th { font-family: var(--font-display); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.data-table__wrap { overflow-x: auto; }

/* --- Callout, for the one thing on a page that must not be missed. --- */
.callout {
  background: var(--color-charcoal);
  color: var(--color-white);
  padding: var(--space-6);
  margin-block: var(--space-7);
  max-width: 68ch;
}
.callout > :first-child { margin-top: 0; }
.callout > :last-child { margin-bottom: 0; }
.callout .h4 { margin-bottom: var(--space-3); }

/* Inverted callout: white interior, gray border, dark text. For a callout that
   should read as important without going as loud as the solid charcoal block,
   e.g. the cancel-and-freeze box, where a heavy dark slab made the page's least
   celebratory content its most visually dominant. Border is --color-steel
   rather than the fainter --border-on-light so the box still has a defined
   edge on white; steel clears the 3:1 floor for a non-text UI outline. */
.callout--light {
  background: var(--color-white);
  color: var(--color-black);
  border: 1px solid var(--color-steel);
}

/* --- Numbered steps, for process explanations like parking validation. --- */
.steps { list-style: none; counter-reset: step; margin: 0; padding: 0; max-width: 64ch; }
.steps li { counter-increment: step; position: relative; padding-left: calc(var(--space-8) - var(--space-2)); padding-bottom: var(--space-5); }
.steps li::before {
  content: counter(step);
  position: absolute; left: 0; top: -0.1em;
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.75rem; line-height: 1;
  color: var(--color-steel);
}
.steps li:last-child { padding-bottom: 0; }

/* --- NAP block, for the footer and contact page. --- */
.nap { font-style: normal; }
.nap a { color: inherit; }

/* A 3-column comparison table must scroll inside its wrapper on narrow
   screens rather than squashing the labels to one word per line. */
.data-table { min-width: 34rem; }

/* Four-up value strip. The base grid is hard-coded to 3 columns, so a fourth
   item left an orphan on its own row. Added 2026-08-11 when the 18+ point was
   added to the home page; /advantage already had four items and was already
   rendering 3 plus an orphan, so this fixes that too. Placed after the base
   rules so it wins at every width. */
@media (min-width: 640px) {
  .value-strip__grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .value-strip__grid--4 { grid-template-columns: repeat(4, 1fr); }
}


/* Day pass cards. Added 2026-08-19.
   minmax(0,1fr) rather than 1fr: 1fr will not shrink a column below its
   min-content, so the longest button label ("Buy 30 Day Pass") was forcing
   its column wider and squeezing the other four.
   margin-bottom is space-7 to match the block-to-heading rhythm the callout
   component sets, so the heading that follows the grid is not crowded. */
.pass-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-bottom: var(--space-7);
}
@media (min-width: 600px)  { .pass-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .pass-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.pass-card {
  display: flex;
  flex-direction: column;
  background: var(--color-charcoal);
  border: 1px solid var(--border-on-dark);
  padding: var(--space-5);
  color: var(--color-white);
  text-align: center;
}
.pass-card__name {
  font-family: var(--font-display);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 1rem;
  letter-spacing: 0.04em;
  color: var(--color-white);
  margin: 0 0 var(--space-3);
}
.pass-card__price {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 2.25rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--space-3);
}
.pass-card__dur { font-size: 0.85rem; line-height: 1.5; color: #d8dde1; margin: 0 0 var(--space-3); }
.pass-card__note { font-size: 0.75rem; line-height: 1.5; color: var(--color-steel); margin: 0 0 var(--space-5); flex: 1 1 auto; }
.pass-card__btn { align-self: stretch; white-space: normal; overflow-wrap: break-word; }


/* Photo carousel. Added 2026-08-19 for Run Club on the community page.
   Built on scroll-snap so it works with no JavaScript at all: the track is a
   horizontally scrollable list and a person can swipe or drag it. The buttons
   are progressive enhancement layered on top, not the mechanism. */
.carousel { margin-top: var(--space-6); }
.carousel__viewport { overflow: hidden; }
.carousel__track {
  display: flex;
  gap: var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.carousel__track::-webkit-scrollbar { display: none; }
.carousel__slide {
  flex: 0 0 100%;
  scroll-snap-align: center;
  min-width: 0;
}
@media (min-width: 1024px) { .carousel__slide { flex-basis: 900px; max-width: 900px; margin-inline: auto; } }
.carousel__slide img { display: block; width: 100%; height: auto; }
.carousel__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-5);
  margin-top: var(--space-4);
}
.carousel__btn {
  background: transparent;
  border: 1px solid var(--color-white);
  color: var(--color-white);
  font-size: 1.125rem;
  line-height: 1;
  min-width: 48px;
  min-height: 48px;
  cursor: pointer;
}
.carousel__btn:hover { background: var(--color-white); color: var(--color-black); }
.carousel__btn:focus-visible { outline: 2px solid var(--color-white); outline-offset: 3px; }
.carousel__btn[disabled] { opacity: 0.35; cursor: default; }
.carousel__btn[disabled]:hover { background: transparent; color: var(--color-white); }
.carousel__count {
  font-family: var(--font-body);
  font-size: 0.875rem;
  color: var(--color-steel);
  margin: 0;
  font-variant-numeric: tabular-nums;
}
@media (prefers-reduced-motion: reduce) { .carousel__track { scroll-behavior: auto; } }


/* Logo panel. Added 2026-08-19 for the on-site healthcare section on the about
   page, where a partner's logo carries the point better than another shot of
   the training floor. Partner logos are black on transparent, so on a dark
   section they need a light ground: same white-card convention as
   .partner-card-box, sized for a split-layout media column rather than a
   four-across row. The logo is capped well below the panel width because these
   marks are visually dense and read as shouting at full bleed. */
.logo-panel {
  background: var(--color-white);
  border: 1px solid rgba(58, 66, 72, 0.15);
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
}
.logo-panel img {
  width: auto;
  height: auto;
  max-width: 62%;
  max-height: 62%;
  object-fit: contain;
}
@media (min-width: 1024px) { .logo-panel { aspect-ratio: 1 / 1; } }
