/* ==========================================================================
   Manhattan Grapple Club — CollegiateClub direction
   Design system: "Manhattan Grapple Club Design System" → templates/collegiate-club
   Athletic-club direction: Archivo Black, HARD corners, gold rules as structure,
   full-bleed centred hero, schedule board, numeral-forward.
   Sections and content are unchanged from the previous build; only the style is new.
   ========================================================================== */

/* ---------- Tokens ---------- */
:root {
  /* Colour — sampled from the badge. Unchanged by the restyle. */
  --ink:        #0B0B0C;
  --slate:      #17171A;
  --charcoal:   #232328;
  --gold:       #FDB71B;
  --gold-hi:    #FFC53D;
  --gold-dim:   #C98F14;
  --red:        #E81D2E;
  --red-hi:     #FF4D5A;
  --white:      #FFFFFF;
  --near-white: #E4E4EA;
  --muted:      #A3A3AD;
  --muted-2:    #C9C9D2;   /* list copy */
  --muted-3:    #8E8E99;   /* dense schedule copy — 6.07:1 on ink */
  /* The template's closed-day greys (#6A6A74 / #4E4E58) measure 3.50:1 and 2.39:1 —
     both fail AA, and "CLOSED" is real information: it tells you not to turn up.
     Lifted to the quietest values that still clear 4.5:1 on ink AND on the 3% wash
     the rest-day header sits on. Still visibly quieter than --muted (7.87:1). */
  --quiet:      #82828D;   /* closed-day label — 5.18:1 on ink, 4.93:1 on wash */
  --quiet-2:    #7C7C87;   /* closed-day text  — 4.77:1 on ink */
  --hairline:   rgba(255, 255, 255, 0.10);
  --hairline-2: rgba(255, 255, 255, 0.12);
  --gold-wash:  rgba(253, 183, 27, 0.16);
  --gold-wash-2:rgba(253, 183, 27, 0.18);
  --white-wash: rgba(255, 255, 255, 0.06);

  /* IBJJF adult belt ranks — IDENTITY colours for rank display only. NOT UI surfaces,
     and never a text colour: see the .belt block for why the swatch is decorative. */
  --belt-white:  #F7F5F1;
  --belt-blue:   #1F4FD8;
  --belt-purple: #6B2FBF;
  --belt-brown:  #6B4326;
  --belt-black:  #0B0B0C;
  --belt-bar:     #0B0B0C;
  --belt-bar-red: #E81D2E;

  /* Form fields need their own border token. --hairline-2 as a field border composites to
     roughly #303032, which is 1.49:1 against the field fill — WCAG 1.4.11 wants 3:1 for a
     component boundary, and a text input's border IS its boundary. #6A6A74 measures
     3.68:1 against --ink and 3.44:1 against --surface-alt. */
  --field-border: #6A6A74;

  --surface-page: var(--ink);
  --surface-alt:  #141416;   /* alt sections in this direction, not --slate */

  /* Type — Archivo Black display, Archivo body.
     CRITICAL: Archivo Black is a SINGLE-WEIGHT family registering as 400. Never request
     700/800/900 from it — that triggers synthetic bolding, the exact failure the earlier
     system-stack build hit. --weight-display is 400 and must stay 400. */
  --font-display: 'Archivo Black', 'Archivo', system-ui, -apple-system, sans-serif;
  --font-body: 'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --weight-display: 400;

  /* Archivo Black is far wider per character than system-ui, so every display size is
     smaller than the previous spec and clamped against real measurement. */
  --size-h1: clamp(36px, 6.2vw, 78px);
  --size-h2: clamp(30px, 4.2vw, 52px);
  --size-h3: clamp(18px, 2.2vw, 21px);
  --size-lede: clamp(16px, 4vw, 19px);
  --size-body: clamp(16px, 4vw, 17px);
  --size-price: clamp(64px, 8.4vw, 104px);
  --size-numeral: clamp(40px, 5vw, 64px);
  --size-time: 34px;

  --lh-display: 0.94;
  --lh-tight: 1.15;
  --lh-body: 1.6;

  --track-display: -0.03em;
  --track-display-sm: -0.02em;
  --track-eyebrow: 0.20em;
  --track-caps: 0.14em;
  --track-caps-tight: 0.10em;
  --track-cta: 0.06em;

  /* Space */
  --header-h: 76px;
  --gutter: 20px;
  /* Responsive again. A flat 88px meant 176px of padding between every section on a
     phone — desktop rhythm charged to mobile. 88px is preserved from ~1260px up. */
  --section-y: clamp(44px, 7vw, 88px);
  --max: 1200px;
  --max-narrow: 760px;

  /* Shape — hard corners. Photos keep the only radius, and it is 2px. */
  --r-none: 0px;
  --r-sm: 0px;
  --r-md: 0px;
  --r-lg: 2px;
  --r-pill: 0px;
  --rule-gold: 6px;   /* section headers, header underline, major dividers */
  --rule-edge: 2px;   /* panel and grid borders */
  --rule-gap: 2px;    /* the gap that becomes a hairline between grid cells */

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in:  cubic-bezier(0.4, 0, 1, 1);
}

@media (min-width: 768px) { :root { --gutter: 32px; } }

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
}

body {
  margin: 0;
  background: var(--surface-page);
  color: var(--white);
  font-family: var(--font-body);
  font-size: var(--size-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: rgba(253, 183, 27, 0.18);
  overflow-x: hidden;
}

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

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
  text-transform: uppercase;
  margin: 0 0 0.4em;
  text-wrap: balance;
  font-synthesis-weight: none; /* fail visibly rather than smear */
}
h1 { font-size: var(--size-h1); }
h2 { font-size: var(--size-h2); }
h3 { font-size: var(--size-h3); line-height: var(--lh-tight); letter-spacing: var(--track-display-sm); }

p { margin: 0 0 1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a { color: var(--gold); text-underline-offset: 3px; }
ul, ol { margin: 0; padding: 0; }
address { font-style: normal; }

/* ---------- A11y utilities ---------- */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: 12px; top: 12px; z-index: 100;
  background: var(--gold); color: var(--ink);
  padding: 12px 20px;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 13px; letter-spacing: var(--track-cta); text-transform: uppercase;
  text-decoration: none;
  transform: translateY(calc(-100% - 24px));
}
.skip-link:focus { transform: translateY(0); }

/* No border-radius here: it would apply to the ELEMENT, and this block must stay safe
   to move below the component rules. */
:where(a, button, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--white);
  outline-offset: 2px;
}

/* ---------- Layout ---------- */
.wrap {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap-narrow { max-width: var(--max-narrow); }
.center { text-align: center; }
/* For short compound terms that must not be split across lines by the automatic
   hyphen break — "No-Gi" reads as "NO-" / "GI" in a narrow display-type heading. */
.nowrap { white-space: nowrap; }

.section { padding-block: var(--section-y); }
.section-alt {
  background: var(--surface-alt);
  border-block: var(--rule-edge) solid var(--hairline-2);
}

/* ---------- Section header ----------
   The signature of this direction: a sequence number, an uppercase display heading,
   an optional right-aligned note, all sitting on a 6px gold rule. */
.secthead {
  display: flex; align-items: flex-end; gap: 20px;
  border-bottom: var(--rule-gold) solid var(--gold);
  padding-bottom: clamp(12px, 2.5vw, 18px);
  margin-bottom: clamp(22px, 4vw, 36px);
}
.secthead-n {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 15px; letter-spacing: 0.08em;
  color: var(--gold);
  flex: none;
  line-height: 1.4;
}
.secthead h2 { margin: 0; margin-right: auto; }
.secthead-note {
  color: var(--muted); font-size: 15px;
  margin: 0 0 6px; max-width: 36ch; text-align: right;
}
@media (max-width: 1024px) { .secthead-note { display: none; } }
@media (max-width: 640px) { .secthead { flex-wrap: wrap; gap: 10px; } }

/* Eyebrow with a leading gold rule — used where there is no numbered section header. */
.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 12px; font-weight: 700;
  letter-spacing: var(--track-eyebrow); text-transform: uppercase;
  color: var(--gold); margin: 0 0 20px;
}
.eyebrow::before {
  content: ""; display: block; flex: none;
  width: 36px; height: 2px; background: var(--gold);
}

.section-lede {
  color: var(--muted);
  max-width: 62ch;
  font-size: var(--size-lede);
  margin-bottom: 32px;
}

/* ---------- Buttons — rectangular, Archivo Black, uppercase ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 58px; padding: 0 32px;
  border-radius: var(--r-none);
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 15px; letter-spacing: var(--track-cta); text-transform: uppercase;
  text-align: center; text-decoration: none;
  border: var(--rule-edge) solid transparent;
  cursor: pointer;
  transition: transform 100ms var(--ease-out), background-color 140ms var(--ease-out),
              color 140ms var(--ease-out);
}
.btn-primary { background: var(--gold); color: var(--ink); }
.btn-secondary { background: transparent; color: var(--gold); border-color: var(--gold); }

@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover { background: var(--gold-hi); }
  .btn-secondary:hover { background: rgba(253, 183, 27, 0.10); }
}
.btn:active { transform: scale(0.985); }

.btn-sm { min-height: 48px; padding: 0 22px; font-size: 13px; }
.btn-lg { min-height: 66px; padding: 0 44px; font-size: 18px; }
.btn-block { display: flex; width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: clamp(18px, 4vw, 28px); }
@media (max-width: 479px) {
  .btn-row { flex-direction: column; align-items: stretch; }
  .btn-row .btn { width: 100%; }
}
.hero .btn-row { justify-content: center; }

/* ---------- Header — 6px gold underline ---------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--ink);
  border-bottom: var(--rule-gold) solid var(--gold);
}
.header-inner {
  display: flex; align-items: center; gap: 24px;
  min-height: var(--header-h);
}
.lockup {
  display: flex; align-items: center; gap: 12px;
  min-height: 44px;
  text-decoration: none; color: var(--white);
  margin-right: auto;
}
.lockup-badge { width: 46px; height: 47px; flex: none; }
.lockup-text { display: block; }
.lockup-name {
  display: block;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 17px; letter-spacing: 0.01em; text-transform: uppercase;
  line-height: 1.1;
  /* The two lines are set by an explicit <br>. nowrap stops a squeezed header adding a
     third by breaking "Grapple Club" — which is what happened at exactly 1025px. */
  white-space: nowrap;
}
.lockup-place {
  display: block;
  font-size: 10px; font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--gold); margin-top: 3px;
}

/* Clamped, not a flat 28px: the nav carries six items now that About is in it, and at
   exactly 1025px — where the desktop nav first appears — a flat 28px put the lockup, the
   six links and the trial CTA over the available width. This narrows the gap only where
   the space is actually tight and restores 28px on wide screens. */
.site-nav { display: none; gap: clamp(16px, 1.9vw, 28px); }
.site-nav a {
  display: inline-flex; align-items: center;
  min-height: 44px;
  color: var(--muted); text-decoration: none;
  font-size: 13px; font-weight: 700;
  letter-spacing: var(--track-caps-tight); text-transform: uppercase;
}
@media (hover: hover) and (pointer: fine) { .site-nav a:hover { color: var(--white); } }

.header-cta { display: none; }

/* ---------- Mobile menu ---------- */
.menu { position: relative; margin-left: auto; }

.menu-btn {
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  cursor: pointer; list-style: none;
}
.menu-btn::-webkit-details-marker { display: none; }

.menu-bars { position: relative; display: block; width: 24px; height: 2px; }
.menu-bars,
.menu-bars::before,
.menu-bars::after {
  background: var(--white);
  transition: transform 180ms var(--ease-out), background-color 120ms linear;
}
.menu-bars::before,
.menu-bars::after { content: ""; position: absolute; left: 0; width: 24px; height: 2px; }
.menu-bars::before { top: -7px; }
.menu-bars::after  { top: 7px; }
.menu[open] .menu-bars { background: transparent; }
.menu[open] .menu-bars::before { transform: translateY(7px) rotate(45deg); }
.menu[open] .menu-bars::after  { transform: translateY(-7px) rotate(-45deg); }

/* Explicit close state. Native <details> hiding does NOT survive an absolutely
   positioned `display: grid` child — without this the panel renders permanently. */
.menu:not([open]) .menu-panel { display: none; }

.menu-panel {
  position: absolute; top: calc(100% + 14px); right: 0;
  z-index: 60;
  width: min(82vw, 300px);
  display: grid; gap: 0;
  padding: 0;
  background: var(--ink);
  border: var(--rule-edge) solid var(--gold);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.7);
}
.menu-panel a {
  display: flex; align-items: center;
  min-height: 50px; padding: 0 18px;
  color: var(--white); text-decoration: none;
  font-size: 12px; font-weight: 700;
  letter-spacing: var(--track-caps-tight); text-transform: uppercase;
  border-bottom: 1px solid var(--hairline);
}
@media (hover: hover) and (pointer: fine) {
  .menu-panel a:not(.menu-cta):hover { background: var(--white-wash); }
}
/* `.menu-panel a` is (0,1,1) and beats `.btn-primary` (0,1,0) on `color`, painting the
   label white on gold — 1.76:1, the one pairing this system bans. Matching specificity
   is load-bearing, not tidiness. */
.menu-panel a.menu-cta {
  justify-content: center;
  min-height: 58px;
  background: var(--gold); color: var(--ink);
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 14px; letter-spacing: var(--track-cta);
  border-bottom: 0;
}

/* The trial button appears at 1025px — the desktop conversion path must never be
   absent, and the sticky mobile CTA is switched off from this width up. */
@media (min-width: 1025px) {
  .header-cta { display: inline-flex; }
  /* .menu carries margin-left:auto so it hugs the right on mobile. With the trial button
     now beside it and the nav still hidden (1025–1100), that second auto margin stranded
     the button in the middle of the header. The lockup's own margin-right:auto is enough
     to push this pair to the right edge. */
  .menu { margin-left: 0; }
}
/* The nav waits until 1160px. Measured, with the six items it now carries — About,
   Schedule, Gallery, First Class, Standards, Contact — the header row needs about
   1045px of content width; 1140px is where that first fits, and 1160px leaves real
   slack rather than four pixels of it.

   Note the ceiling this is measured against: `--max` caps `.wrap` at 1200px, so the
   header's content box stops growing at 1136px no matter how wide the window gets.
   A SEVENTH item does not fit at ANY width — it needs 1164px — which is why Pricing
   is not in this nav. It is still in the footer, in the mobile menu, and on the home
   page itself, and the trial button sits immediately to the right of these links.

   Below 1160px the hamburger takes over. It carries every link the desktop nav does,
   plus more, plus its own trial CTA, and the header's trial button is separately
   visible from 1025px — so nothing is lost at any width. */
@media (min-width: 1160px) {
  .menu { display: none; }
  .site-nav { display: flex; }
}

/* ---------- Hero — full-bleed, centred ---------- */
.hero {
  position: relative;
  isolation: isolate;
  min-height: 720px;
  display: flex; align-items: center; justify-content: center;
  text-align: center;
  overflow: hidden;
  border-bottom: var(--rule-gold) solid var(--gold);
}
/* .hero-inner supplies the padding; adding more here is what doubled it. */
@media (max-width: 768px) { .hero { min-height: 0; } }

.hero-bg { position: absolute; inset: 0; z-index: -1; }
.hero-bg img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* Selectors are `.hero-bg img.x`, NOT `.x` — a bare variant class is (0,1,0) and loses to
   `.hero-bg img` (0,1,1), which would leave BOTH crops rendered, stacked on each other. */
.hero-bg img.hero-landscape { display: block; object-position: 50% 66%; }
.hero-bg img.hero-portrait { display: none; object-position: 50% 58%; }
/* Art-direction swap gated on GEOMETRY, not a round number: the 4:3 landscape asset only
   gains vertical overflow — and so only responds to object-position — once its container
   is wider than 720 x 1.333 = 960px. Below that the full frame renders and the hero is
   mostly ceiling and ductwork. 1024 is 960 plus margin. */
@media (max-width: 1024px) {
  .hero-bg img.hero-landscape { display: none; }
  .hero-bg img.hero-portrait { display: block; }
}

.hero-bg::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg,
      rgba(11, 11, 12, 0.82) 0%,
      rgba(11, 11, 12, 0.58) 36%,
      rgba(11, 11, 12, 0.92) 100%),
    radial-gradient(120% 78% at 50% 46%, rgba(11, 11, 12, 0.32) 0%, rgba(11, 11, 12, 0.80) 100%);
}

/* One source of vertical padding, not two. This used to be a flat 84px which stacked
   with .hero's own 64px at mobile for 148px of dead space above the badge. */
.hero-inner { padding-block: clamp(36px, 7vw, 84px); }
.hero-badge {
  width: clamp(76px, 20vw, 138px);
  height: auto;
  margin: 0 auto clamp(14px, 3vw, 26px);
}

/* Eyebrow flanked by gold rules — hero only. */
.hero-eyebrow {
  display: flex; align-items: center; gap: 16px; justify-content: center;
  margin-bottom: clamp(14px, 3vw, 22px);
}
.hero-eyebrow::before,
.hero-eyebrow::after {
  content: ""; display: block;
  flex: 1; max-width: 170px; height: 2px; background: var(--gold);
}
.hero-eyebrow span {
  font-size: 12px; font-weight: 700;
  letter-spacing: 0.26em; text-transform: uppercase;
  color: var(--gold);
}

.hero h1 {
  margin: 0 0 8px;
  text-shadow: 0 2px 24px rgba(11, 11, 12, 0.6);
}
.hl { color: var(--gold); }

/* The kicker line: display face, gold, positive tracking — a counterweight to the h1. */
.hero-kicker {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: clamp(20px, 2.6vw, 34px);
  line-height: 1; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 clamp(16px, 3.5vw, 26px);
}

.hero-lede {
  color: var(--near-white);
  /* Was a flat 19px at the body's 1.6 line-height — five tall lines on a phone, the
     single largest block above the fold. Slightly smaller and tighter on mobile, and
     unchanged at 19px/1.5 from ~432px up. Still well above the 16px floor. */
  font-size: clamp(17px, 4.4vw, 19px);
  line-height: 1.5;
  max-width: 56ch;
  margin: 0 auto clamp(22px, 4.5vw, 32px);
  text-shadow: 0 1px 12px rgba(11, 11, 12, 0.6);
}
.hero-lede strong { color: var(--white); }

.hero-facts {
  list-style: none;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 10px 28px;
  margin-top: clamp(20px, 4.5vw, 34px);
  font-size: 11px; font-weight: 700;
  letter-spacing: var(--track-caps-tight); text-transform: uppercase;
  color: var(--near-white);
  text-shadow: 0 1px 10px rgba(11, 11, 12, 0.6);
}
.hero-facts li { display: flex; align-items: center; gap: 9px; }
.hero-facts li span {
  display: block; flex: none;
  width: 14px; height: 2px; background: var(--gold);
}

/* ---------- Panel grid ----------
   The structural device of this direction: the parent paints the hairline and the 2px gap
   lets it show through between cells. Cells must carry an opaque background. */
.panelgrid {
  display: grid;
  gap: var(--rule-gap);
  background: var(--hairline-2);
  border: var(--rule-edge) solid var(--hairline-2);
}
.panelgrid > * { background: var(--ink); }

/* ---------- Schedule ---------- */
.week-glance {
  list-style: none; margin: 0 0 24px; padding: 0;
  display: grid; grid-template-columns: repeat(7, 1fr);
  gap: var(--rule-gap);
  background: var(--hairline-2);
  border: var(--rule-edge) solid var(--hairline-2);
}
.week-glance li {
  background: var(--ink);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 10px 2px;
  min-width: 0;
}
.g-day {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--white);
}
.g-time { font-size: 11px; font-weight: 700; color: var(--gold); }
.week-glance .g-off .g-day { color: var(--quiet); }
.week-glance .g-off .g-time { color: var(--quiet-2); }
.week-glance li.is-next { background: var(--gold); }
.week-glance li.is-next .g-day,
.week-glance li.is-next .g-time { color: var(--ink); }
@media (min-width: 1025px) { .week-glance { display: none; } }

/* The week board */
.week {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(7, 1fr);
  gap: var(--rule-gap);
  background: var(--hairline-2);
  border: var(--rule-edge) solid var(--hairline-2);
}
.day {
  background: var(--ink);
  display: flex; flex-direction: column;
  min-width: 0;
}
.day-name {
  background: var(--white-wash);
  padding: 12px 14px;
  margin: 0;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 13px; letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--white);
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
}
.day-name abbr { text-decoration: none; border: 0; cursor: inherit; }

.day-body { padding: 20px 14px 24px; flex: 1; min-width: 0; }

.klass-time {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--size-time); line-height: 1;
  letter-spacing: var(--track-display); color: var(--gold);
  margin: 0 0 12px;
}
.klass-time .mer { font-size: 16px; }

.klass-name {
  font-size: 15px; line-height: var(--lh-tight);
  letter-spacing: 0; text-transform: uppercase;
  margin: 0 0 10px;
}
.klass-desc { color: var(--muted-3); font-size: 12px; line-height: 1.45; margin: 0; }

/* Rest days: quieter header, centred label. Present, because a closed weekend is information. */
.day-rest .day-name { background: rgba(255, 255, 255, 0.03); color: var(--quiet); }
.day-rest .day-body {
  display: flex; align-items: center; justify-content: center;
  min-height: 80px; padding: 20px 14px;
}
.rest {
  margin: 0; color: var(--quiet-2);
  font-size: 12px; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
}

/* Next / on-now marker: gold header bar plus an inset gold outline. Text carries meaning. */
.day.is-next {
  background: var(--surface-alt);
  outline: var(--rule-edge) solid var(--gold);
  outline-offset: calc(var(--rule-edge) * -1);
}
.day.is-next .day-name { background: var(--gold); color: var(--ink); }
.next-pill {
  font-family: var(--font-body);
  font-size: 10px; font-weight: 700;
  letter-spacing: var(--track-caps-tight); text-transform: uppercase;
  color: var(--ink);
  margin: 0;
}

.tag {
  display: inline-block;
  background: var(--gold-wash-2); color: var(--gold);
  font-size: 10px; font-weight: 700; line-height: 1.4;
  letter-spacing: var(--track-caps-tight); text-transform: uppercase;
  padding: 3px 8px;
  margin: 0 0 10px;
}
.tag-outline { background: var(--gold-wash-2); color: var(--gold); }
.day.is-next .tag-gold { display: none; }

@media (max-width: 1024px) {
  .week { grid-template-columns: repeat(2, 1fr); }
  /* Seven cells in two columns leaves slot 8 empty, and the grid paints its own background
     to fake the hairline gaps — so an empty slot renders as a filled panel, not nothing.
     Sunday spans the row: it closes the grid AND gives the free open mat the emphasis it
     already carries in the seven-column view. */
  .day-weekend { grid-column: 1 / -1; }
}
@media (max-width: 640px) { .week { grid-template-columns: 1fr; } }

/* ---------- Women's feature ---------- */
.section-feature {
  background: var(--surface-alt);
  border-top: var(--rule-gold) solid var(--gold);
  border-bottom: var(--rule-edge) solid var(--hairline-2);
}
.feature-grid { display: grid; gap: 32px; }
@media (min-width: 1025px) {
  .feature-grid { grid-template-columns: 460px 1fr; gap: 56px; align-items: center; }
}
.feature-inner { max-width: 60ch; }

.feature-lede {
  font-size: clamp(19px, 2.4vw, 24px);
  line-height: 1.4;
  color: var(--white);
  margin-bottom: 22px;
}
.section-feature p { color: var(--muted); }

.feature-chips {
  list-style: none;
  display: grid; gap: 0;
  margin: 0 0 24px;
  border-top: 1px solid var(--hairline-2);
}
/* now the last element in the feature column — no trailing gap to leave behind */
.feature-chips:last-child { margin-bottom: 0; }
.feature-chips li {
  display: flex; align-items: baseline; gap: 14px;
  padding: 13px 0;
  border-bottom: 1px solid var(--hairline-2);
  font-size: 15px; color: var(--muted-2);
}
.feature-chips li::before {
  content: counter(chip, decimal-leading-zero);
  counter-increment: chip;
  flex: none;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 12px; color: var(--gold);
}
.feature-chips { counter-reset: chip; }

/* ---------- Trial & pricing ---------- */
/* Panel grid: the parent paints the hairline and the 2px gap lets it show between cells. */
.cards {
  display: grid; gap: var(--rule-gap);
  background: var(--hairline-2);
  border: var(--rule-edge) solid var(--hairline-2);
}
@media (min-width: 900px) { .cards { grid-template-columns: 1.15fr 0.85fr; } }

.card {
  background: var(--ink);
  padding: 36px 32px;
  display: flex; flex-direction: column;
}
@media (max-width: 640px) { .card { padding: 26px 22px; } }

.card-eyebrow {
  font-size: 12px; font-weight: 700;
  letter-spacing: var(--track-eyebrow); text-transform: uppercase;
  color: var(--muted); margin: 0 0 18px;
}
.price {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--size-price); line-height: 0.82;
  letter-spacing: -0.045em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 6px;
}
.price-term {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 19px; letter-spacing: var(--track-display-sm); text-transform: uppercase;
  color: var(--white);
  margin: 0 0 26px;
}

/* Rule-separated BULLET list. Same rhythm as `.ticks` below, but the marker is the gold
   bar the hygiene lists use rather than a counter — `.ticks` numbers its items with
   `counter(tick, decimal-leading-zero)`, and these items are things to know rather than
   steps to perform in order. */
.bullets {
  list-style: none;
  display: grid; gap: 0;
  margin: 0;
  max-width: 68ch;
  border-top: 1px solid var(--hairline-2);
}
.bullets li {
  position: relative;
  padding: 15px 0 15px 28px;
  border-bottom: 1px solid var(--hairline-2);
  font-size: 15px; line-height: 1.55; color: var(--muted-2);
}
.bullets li::before {
  content: ""; position: absolute; left: 0; top: 0.85em;
  width: 14px; height: 2px; background: var(--gold);
}
.bullets-lg li { font-size: clamp(16px, 4vw, 18px); }
.bullets strong { color: var(--white); font-weight: 700; }

/* Trailing note under a section's main content — the internal-link sentence. */
.section-note {
  max-width: 68ch;
  margin: clamp(22px, 4vw, 32px) 0 0;
  color: var(--muted);
  font-size: 15px;
}

/* Numbered rule-separated list — the collegiate answer to a tick list. */
.ticks {
  list-style: none; counter-reset: tick;
  display: grid; gap: 0;
  margin: 0 0 30px;
  border-top: 1px solid var(--hairline-2);
}
.ticks li {
  counter-increment: tick;
  display: flex; gap: 14px;
  padding: 13px 0;
  border-bottom: 1px solid var(--hairline-2);
  font-size: 15px; color: var(--muted-2);
}
.ticks li::before {
  content: counter(tick, decimal-leading-zero);
  flex: none;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 12px; color: var(--gold);
  padding-top: 3px;
}
.card .btn { margin-top: auto; }

/* Paid plans — rule-separated rows, price in the display face. */
.plans {
  list-style: none;
  display: grid; gap: 0;
  margin: 0 0 24px;
  border-top: 1px solid var(--hairline-2);
}
.plan {
  padding: 20px 0;
  border-bottom: 1px solid var(--hairline-2);
}
.plan-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  margin-bottom: 8px;
}
.plan-name {
  font-size: 17px; line-height: var(--lh-tight);
  letter-spacing: var(--track-display-sm);
  color: var(--white);
  margin: 0;
}
.plan-price {
  flex: none;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: clamp(30px, 4vw, 40px); line-height: 0.9;
  letter-spacing: -0.035em;
  color: var(--gold);
  margin: 0;
}
.plan-per {
  font-size: 14px; letter-spacing: 0;
  color: var(--muted);
}
.plan-note { color: var(--muted); font-size: 14px; line-height: 1.5; margin: 0; }
.plan-note strong { color: var(--white); font-weight: 700; }

/* ---------- Location ---------- */
.location-grid { display: grid; gap: 32px; }
@media (min-width: 1025px) {
  .location-grid { grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
}
.address {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: clamp(28px, 3.6vw, 44px); line-height: 1.05;
  letter-spacing: -0.025em; text-transform: uppercase;
  margin: 0 0 28px;
}
.address .hl { color: var(--gold); }
/* Contact — rule-separated rows, label in caps, value in gold. Whole row is the target. */
.contact {
  list-style: none;
  display: grid; gap: 0;
  margin: 28px 0 0;
  border-top: 1px solid var(--hairline-2);
}
.contact li {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 56px;
  padding: 8px 0;
  border-bottom: 1px solid var(--hairline-2);
}
.contact-label {
  flex: none;
  margin: 0;
  font-size: 11px; font-weight: 700;
  letter-spacing: var(--track-eyebrow); text-transform: uppercase;
  color: var(--muted);
}
.contact-value {
  display: inline-flex; align-items: center;
  min-height: 44px;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: clamp(14px, 2vw, 19px);
  letter-spacing: var(--track-display-sm); text-transform: uppercase;
  color: var(--gold);
  text-decoration: none;
  text-align: right;
  /* the email is 32 characters — it must be allowed to break rather than overflow at 320px */
  overflow-wrap: anywhere;
}
/* An email address is DATA, not a display label. The direction uppercases display type,
   but rendering it as INFO@… implies the address itself is uppercase. Specificity is
   raised above `.contact-value` deliberately rather than relying on source order. */
.contact .contact-value-email {
  text-transform: none;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: clamp(13px, 1.7vw, 16px);
  letter-spacing: 0;
}
@media (hover: hover) and (pointer: fine) { .contact-value:hover { color: var(--gold-hi); } }

/* Wayfinding steps — numbered, rule-separated, matching the trial list idiom. */
.find-title {
  margin: 32px 0 0;
  padding-bottom: 12px;
  border-bottom: var(--rule-edge) solid var(--gold);
  color: var(--gold);
  font-size: clamp(16px, 2vw, 19px);
}
.find-steps {
  list-style: none; counter-reset: find;
  display: grid; gap: 0;
  margin: 0;
}
/* NOT a flex container. These items contain <strong>, and in a flex container every text
   run and every inline element becomes its own flex item — which shreds the copy to one
   fragment per line. The counter is absolutely positioned so the text stays in normal flow.
   (`.ticks` and `.feature-chips` can safely use flex because their content is plain text.) */
.find-steps li {
  counter-increment: find;
  position: relative;
  padding: 14px 0 14px 34px;
  border-bottom: 1px solid var(--hairline-2);
  font-size: 15px; line-height: 1.55; color: var(--muted);
}
.find-steps li::before {
  content: counter(find, decimal-leading-zero);
  position: absolute; left: 0; top: 17px;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 12px; color: var(--gold);
}
.find-steps strong { color: var(--white); font-weight: 700; }

.location-media { display: grid; gap: var(--rule-gap); align-content: start; }

.location-map {
  overflow: hidden;
  border: var(--rule-edge) solid var(--hairline-2);
  background: var(--charcoal);
  aspect-ratio: 4 / 3;
}
.location-map iframe { width: 100%; height: 100%; border: 0; display: block; }

/* ---------- Photos ---------- */
.photo {
  margin: 0;
  border: var(--rule-edge) solid var(--hairline-2);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--charcoal);
  position: relative;
}
.photo img { width: 100%; height: auto; object-fit: cover; }
.photo-wide img { aspect-ratio: 4 / 3; }
.photo-portrait img { aspect-ratio: 3 / 4; }
.photo figcaption {
  padding: 12px 16px;
  font-size: 11px; font-weight: 700;
  letter-spacing: var(--track-caps-tight); text-transform: uppercase;
  color: var(--muted);
  border-top: 1px solid var(--hairline-2);
  background: var(--ink);
}
/* `.photo figcaption` is (0,1,1) and beats a bare `.photo-chip` (0,1,0) on background,
   colour and border — the chip renders as the default caption bar without this. */
.photo figcaption.photo-chip {
  position: absolute; left: 0; bottom: 0;
  padding: 10px 16px;
  background: var(--gold); color: var(--ink);
  border: 0;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 12px; letter-spacing: 0.08em;
  /* The chip sits ON TOP of the photo. Where the photo is a lightbox link, a click
     landing on the chip would otherwise hit the caption and do nothing — so the whole
     image stays clickable, corner included. The chip is not interactive itself. */
  pointer-events: none;
}

/* ---------- Prose ----------
   Running body copy — the About section and the About page. Measure is capped at 68ch
   because the page is otherwise all panels and lists, and a full 1200px line of 17px
   body text is unreadable. */
.prose { display: grid; gap: 18px; max-width: 68ch; }
.prose p { margin: 0; color: var(--muted); line-height: var(--lh-body); }
.prose strong { color: var(--white); font-weight: 700; }
/* After `.prose p` so these win on cascade order rather than needing !important. */
.prose .prose-lede { color: var(--near-white); font-size: var(--size-lede); }
/* The closing line. Lifted out of --muted so a one-line sign-off doesn't read as the
   copy trailing off; not sized up, because it is a sign-off and not a second lede. */
.prose .prose-signoff { color: var(--white); font-weight: 700; }

/* ---------- Gallery ----------
   The panel grid again: a 2px gap over a hairline-coloured parent, so the gap
   becomes the divider. Same idiom as the week board and the standards. */
.gallery {
  list-style: none;
  display: grid; gap: var(--rule-gap);
  grid-template-columns: 1fr;
  background: var(--hairline-2);
  border: var(--rule-edge) solid var(--hairline-2);
  margin: 0;
}
@media (min-width: 620px)  { .gallery { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1025px) { .gallery { grid-template-columns: repeat(3, 1fr); } }

.gallery li { background: var(--ink); display: flex; }

.gal-item {
  position: relative;
  display: block;
  width: 100%;
  /* zoom-in is the standard, immediately-legible affordance for "this opens larger".
     It does the job a hover tint cannot do on its own. */
  cursor: zoom-in;
  line-height: 0;
}
.gal-item img {
  width: 100%; height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Gold wash on hover, pointer devices only — on touch there is no hover state to
   reveal it, and the images are self-evidently tappable in a gallery. */
@media (hover: hover) and (pointer: fine) {
  .gal-item::after {
    content: "";
    position: absolute; inset: 0;
    background: var(--gold);
    opacity: 0;
    transition: opacity 160ms var(--ease-out);
  }
  .gal-item:hover::after { opacity: 0.16; }
}
@media (prefers-reduced-motion: reduce) {
  .gal-item::after { transition: none; }
}

/* ---------- Lightbox ----------
   A native <dialog>. The browser supplies the modal semantics for free: focus is
   trapped inside it, the rest of the page goes inert, Escape closes it, and focus
   returns to the thumbnail that opened it. None of that is reimplemented here.

   Without JavaScript every thumbnail is still a plain link to the full-size image,
   so the gallery works with the dialog never opening at all. */
.lightbox {
  position: fixed;
  inset: 0;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  width: 100vw; height: 100vh;
  max-width: 100vw; max-height: 100vh;
  overflow: hidden;
  color: var(--white);
}
/* dvh, not vh: on mobile Safari 100vh is the tallest the viewport ever gets, so the
   caption bar would sit behind the browser's own toolbar. */
@supports (height: 100dvh) {
  .lightbox { height: 100dvh; max-height: 100dvh; }
}
.lightbox::backdrop { background: rgba(11, 11, 12, 0.94); }
.lightbox:not([open]) { display: none; }

.lb-stage {
  position: relative;              /* the close and arrow buttons position against this */
  display: grid;
  /* minmax(0, 1fr), NOT 1fr. A bare `1fr` is `minmax(auto, 1fr)`, and that auto floor
     lets the row grow to the image's natural height — which pushed the caption off
     the bottom of the screen and overflowed a 1600px-wide photo out of the viewport. */
  grid-template-rows: minmax(0, 1fr) auto;
  width: 100%; height: 100%;
  padding: clamp(52px, 8vw, 72px) clamp(12px, 3vw, 32px) clamp(16px, 3vw, 28px);
  gap: 16px;
}

/* The image fills the figure's box exactly and letterboxes inside it with
   object-fit: contain, rather than sizing itself and being capped by max-height.
   `max-height: 100%` on a replaced element does NOT hold here: the percentage is
   resolved against a grid area whose height comes from an `fr` track, and the image
   rendered at its full 1033px inside an 863px row — overflowing the viewport and
   covering the caption. Filling a definite box removes the percentage entirely. */
.lb-figure {
  position: relative;
  margin: 0;
  min-height: 0;
}
.lb-figure img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
}

.lb-bar {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(12px, 3vw, 24px);
  flex-wrap: wrap;
}
.lb-caption {
  margin: 0;
  font-size: 13px; font-weight: 700;
  letter-spacing: var(--track-caps-tight); text-transform: uppercase;
  color: var(--near-white);
  text-align: center;
}
.lb-count {
  margin: 0;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 12px; letter-spacing: 0.08em;
  color: var(--gold);
  flex: none;
}

/* Controls. 48px minimum target on every one of them. */
.lb-btn {
  appearance: none;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 48px; min-height: 48px;
  padding: 0 14px;
  background: var(--gold);
  color: var(--ink);
  border: 0; border-radius: var(--r-none);
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 18px; line-height: 1;
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) { .lb-btn:hover { background: var(--gold-hi); } }
.lb-btn:active { transform: scale(0.97); }

.lb-close { position: absolute; top: clamp(10px, 2vw, 18px); right: clamp(10px, 2vw, 18px); }

/* The arrows are markup children of .lb-bar, so their DEFAULT state is in-flow inside
   the bar — which is what a narrow screen needs. Only from 641px up are they lifted
   out and centred over the image.
   They were previously children of .lb-stage, absolutely positioned, and returned to
   `position: static` on mobile. That made them grid ITEMS of .lb-stage, which had two
   defined rows and now four in-flow children — so they stretched into full-width gold
   blocks covering the photo. */
@media (min-width: 641px) {
  .lb-prev, .lb-next { position: absolute; top: 50%; transform: translateY(-50%); }
  .lb-prev { left: clamp(6px, 1.5vw, 18px); }
  .lb-next { right: clamp(6px, 1.5vw, 18px); }
}
@media (max-width: 640px) {
  /* prev — count — next on the first line, caption wrapping onto its own below. */
  .lb-bar { justify-content: space-between; }
  .lb-caption { order: 3; flex-basis: 100%; }
}

/* ---------- Coach ----------
   One `.coach` card per instructor. auto-fit means a second card drops in beside the
   first with no markup or CSS change — which is the point: the club has a second coach
   whose biography has not been supplied yet. */
.coach-grid { display: grid; gap: clamp(32px, 5vw, 56px); }
@media (min-width: 1025px) {
  .coach-grid { grid-template-columns: repeat(auto-fit, minmax(460px, 1fr)); align-items: start; }
}
.coach { display: grid; gap: 32px; align-content: start; }
/* Side-by-side only while it is the ONLY card. With two cards each column is ~570px, and
   a 320px photo would leave the biography about 210px wide. Two cards stack instead. */
@media (min-width: 1025px) {
  .coach:only-child { grid-template-columns: 340px 1fr; gap: 56px; align-items: start; }
}
.coach-body { display: grid; gap: 18px; align-content: start; }
.coach-lede {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: clamp(22px, 3vw, 34px); line-height: var(--lh-tight);
  letter-spacing: var(--track-display-sm); text-transform: uppercase;
  color: var(--white);
  margin: 0;
}
.coach-lede strong { color: var(--gold); font-weight: var(--weight-display); }
.coach-note { color: var(--muted); font-size: 15px; margin: 0; }

/* ---------- Steps — numeral forward ---------- */
.steps {
  display: grid; gap: var(--rule-gap);
  background: var(--hairline-2);
  border: var(--rule-edge) solid var(--hairline-2);
}
@media (min-width: 700px) { .steps { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1025px) { .steps { grid-template-columns: repeat(4, 1fr); } }
.step { background: var(--ink); padding: 32px 26px; }
.step-n {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--size-numeral); line-height: 0.8;
  letter-spacing: var(--track-display);
  color: var(--gold);
  margin: 0 0 18px;
}
.step h3 { margin-bottom: 12px; }
.step p { color: var(--muted); font-size: 15px; margin: 0; }

/* ---------- Standards ---------- */
.standards-grid { display: grid; gap: clamp(30px, 5vw, 48px); margin-top: clamp(22px, 4vw, 36px); }
.std-group { display: grid; gap: 20px; }
.std-title {
  color: var(--gold);
  margin: 0;
  padding-bottom: 12px;
  border-bottom: var(--rule-edge) solid var(--gold);
  font-size: clamp(20px, 2.6vw, 26px);
}
.std-group strong { color: var(--white); font-weight: 700; }

/* Numbered standards as panel cells */
.std-list {
  list-style: none; counter-reset: std;
  display: grid; gap: var(--rule-gap);
  margin: 0;
  background: var(--hairline-2);
  border: var(--rule-edge) solid var(--hairline-2);
}
@media (min-width: 860px) { .std-list { grid-template-columns: 1fr 1fr; } }
/* The numeral is absolutely positioned, NOT a grid item. Making the <li> a grid container
   turns every text run and every <strong> into its own grid item, which shreds the copy
   into one fragment per cell. */
.std-list li {
  counter-increment: std;
  position: relative;
  background: var(--ink);
  padding: 24px 26px 24px 68px;
  font-size: 15px; line-height: 1.6; color: var(--muted);
}
.std-list li::before {
  content: counter(std, decimal-leading-zero);
  position: absolute; left: 26px; top: 21px;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 22px; line-height: 1;
  letter-spacing: var(--track-display);
  color: var(--gold);
}

/* Do / don't */
.dodont { display: grid; gap: 28px; }
@media (min-width: 860px) { .dodont { grid-template-columns: 1fr 1fr; gap: 24px; align-items: start; } }
.dd-col { display: grid; gap: var(--rule-gap); align-content: start;
  background: var(--hairline-2); border: var(--rule-edge) solid var(--hairline-2); }
.dd-head {
  display: flex; align-items: center; gap: 10px;
  margin: 0;
  padding: 14px 20px;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 15px; letter-spacing: var(--track-caps); text-transform: uppercase;
}
.dd-do { background: var(--gold); color: var(--ink); }
.dd-dont { background: var(--red); color: var(--white); }
.dd-mark { font-size: 17px; line-height: 1; }

.rule { background: var(--ink); padding: 20px; }
.rule h3 {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 16px; letter-spacing: var(--track-display-sm);
  line-height: var(--lh-tight); text-transform: uppercase;
  color: var(--white);
  margin: 0 0 8px;
}
.rule p { margin: 0; font-size: 15px; line-height: 1.6; color: var(--muted); }

/* Hygiene */
.hyg-grid {
  display: grid; gap: var(--rule-gap);
  background: var(--hairline-2);
  border: var(--rule-edge) solid var(--hairline-2);
}
@media (min-width: 860px) { .hyg-grid { grid-template-columns: 1fr 1fr; } }
.hyg { background: var(--ink); padding: 28px 26px; }
.hyg h3 {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 13px; letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 16px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--hairline-2);
}
.hyg-warn h3 { color: var(--red-hi); border-bottom-color: rgba(232, 29, 46, 0.4); }
.hyg ul { list-style: none; display: grid; gap: 12px; margin: 0; }
.hyg li {
  position: relative; padding-left: 20px;
  font-size: 15px; line-height: 1.55; color: var(--muted);
}
.hyg li::before {
  content: ""; position: absolute; left: 0; top: 10px;
  width: 10px; height: 2px; background: var(--gold);
}
.hyg-warn li::before { background: var(--red); }

/* ---------- FAQ ---------- */
.faq {
  display: grid; gap: var(--rule-gap);
  background: var(--hairline-2);
  border: var(--rule-edge) solid var(--hairline-2);
}
.faq details { background: var(--ink); }
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 60px; padding: 16px 20px;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 14px; letter-spacing: 0; text-transform: uppercase;
  line-height: var(--lh-tight);
  cursor: pointer; list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; flex: none;
  width: 9px; height: 9px;
  border-right: 2px solid var(--gold);
  border-bottom: 2px solid var(--gold);
  transform: translateY(-2px) rotate(45deg);
  transition: transform 150ms var(--ease-out);
}
.faq details[open] summary::after { transform: translateY(-2px) rotate(-135deg); }
.faq .faq-a { padding: 0 20px 20px; color: var(--muted); font-size: 15px; }
@media (hover: hover) and (pointer: fine) { .faq summary:hover { background: var(--white-wash); } }

/* ---------- Placeholders ----------
   Deliberately ugly. A placeholder must never read as finished design. */
.placeholder {
  background: var(--charcoal);
  border: var(--rule-edge) dashed var(--red);
  padding: 22px;
  margin-top: 24px;
}
.placeholder-inline { margin-top: 0; margin-bottom: 20px; }
.placeholder-major { margin-top: 0; }

/* --red on charcoal measures 3.46:1. At 16px bold that is BELOW WCAG's bold-large
   threshold (18.66px), so 4.5:1 is required and --red fails. --red-hi is 4.81:1. */
.placeholder-label {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 15px; letter-spacing: var(--track-caps-tight); text-transform: uppercase;
  color: var(--red-hi);
  margin: 0 0 12px;
}
.placeholder p { font-size: 15px; }
.placeholder > p:not(.placeholder-label) { color: var(--white); }
.placeholder-why { color: var(--muted) !important; font-size: 14px !important; }

/* ---------- Final CTA ---------- */
.final-cta {
  border-top: var(--rule-gold) solid var(--gold);
  padding-block: clamp(48px, 7.5vw, 96px);
  background: var(--ink);
}
.final-cta h2 {
  font-size: clamp(40px, 7vw, 88px);
  letter-spacing: -0.035em;
  margin-bottom: 20px;
}
.final-cta .section-lede { margin-inline: auto; margin-bottom: 34px; }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--ink);
  border-top: var(--rule-edge) solid var(--hairline-2);
  padding-block: 44px;
  padding-bottom: calc(44px + 84px + env(safe-area-inset-bottom, 0px));
}
@media (min-width: 1025px) { .site-footer { padding-bottom: 44px; } }

.footer-inner { display: grid; gap: 28px; }
.footer-brand { display: flex; align-items: center; gap: 20px; }
.footer-name {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 16px; text-transform: uppercase; letter-spacing: 0;
  margin: 0 0 4px;
}
.footer-addr { color: var(--muted); font-size: 14px; line-height: 1.5; }

.footer-links, .footer-social { display: flex; flex-wrap: wrap; gap: 4px 24px; }
.footer-links a, .footer-social a {
  display: inline-flex; align-items: center;
  min-height: 44px;
  font-size: 12px; font-weight: 700;
  letter-spacing: var(--track-caps-tight); text-transform: uppercase;
  text-decoration: none;
}
.footer-links a { color: var(--muted); }
.footer-social a { color: var(--gold); }
@media (hover: hover) and (pointer: fine) { .footer-links a:hover { color: var(--white); } }

.footer-legal {
  color: var(--muted); font-size: 12px;
  letter-spacing: 0.04em;
  padding-top: 20px; border-top: 1px solid var(--hairline-2);
  margin: 0;
}

@media (min-width: 768px) {
  .footer-inner { grid-template-columns: 1fr auto; align-items: center; }
  .footer-legal { grid-column: 1 / -1; }
}

/* ---------- Sticky mobile CTA ---------- */
.sticky-cta {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: var(--ink);
  border-top: var(--rule-gold) solid var(--gold);
  padding: 12px var(--gutter);
  padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.6);
  transform: translateY(110%);
  transition: transform 180ms var(--ease-in);
}
.sticky-cta.is-visible {
  transform: translateY(0);
  transition: transform 260ms var(--ease-out);
}
.sticky-cta.no-anim { transition: none; }
.sticky-cta[hidden] { display: none; }
@media (min-width: 1025px) { .sticky-cta { display: none !important; } }

/* ---------- Scroll reveal ----------
   Self-healing: content is visible by default. Opacity only, 220ms — a visitor
   thumb-flicking for a class time outruns anything longer. */
.js-reveal .reveal { opacity: 0; }
.js-reveal .reveal.is-in { opacity: 1; transition: opacity 220ms var(--ease-out); }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .js-reveal .reveal { opacity: 1 !important; }
  .sticky-cta { transform: translateY(0); }
  .sticky-cta:not(.is-visible) { display: none; }
  .btn:active { transform: none; }
}

/* ==========================================================================
   Multi-page additions — page heads, reach cards, nav cards
   The long-tail sections (standards, first class, FAQ, full directions) moved to
   their own pages so the home page stays short on a phone.
   ========================================================================== */

/* Current page marked in both navs — orientation, not decoration. */
.site-nav a[aria-current="page"],
.menu-panel a[aria-current="page"] { color: var(--gold); }

/* ---------- Page head ----------
   Subpages get a compact header instead of the photo hero: same 6px gold rule,
   no 720px minimum, no LCP image to download. */
.pagehead {
  padding-block: clamp(34px, 6.5vw, 80px);
  border-bottom: var(--rule-gold) solid var(--gold);
  background: var(--ink);
}
.pagehead h1 { margin: 0 0 16px; }
.pagehead-lede {
  color: var(--muted);
  font-size: var(--size-lede);
  max-width: 62ch;
  margin: 0;
}

/* ---------- Reach cards (contact page) ---------- */
.reach {
  list-style: none; margin: 0 0 36px;
  display: grid; gap: var(--rule-gap);
  background: var(--hairline-2);
  border: var(--rule-edge) solid var(--hairline-2);
}
@media (min-width: 700px) { .reach { grid-template-columns: 1fr 1fr; } }
.reach li { background: var(--ink); }
.reach a {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "label arrow" "value arrow";
  align-items: center;
  gap: 6px 16px;
  min-height: 104px;
  padding: 24px 26px;
  text-decoration: none;
  transition: background-color 180ms var(--ease-out);
}
.reach-label {
  grid-area: label;
  font-size: 11px; font-weight: 700;
  letter-spacing: var(--track-eyebrow); text-transform: uppercase;
  color: var(--muted);
}
.reach-value {
  grid-area: value;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: clamp(17px, 2.4vw, 24px);
  letter-spacing: var(--track-display-sm); text-transform: uppercase;
  color: var(--gold);
  overflow-wrap: anywhere;
}
/* An address is data, not a label — never uppercased. Specificity raised above
   `.reach-value` deliberately rather than relying on source order. */
.reach .reach-value-email {
  text-transform: none;
  font-family: var(--font-body); font-weight: 700;
  font-size: clamp(14px, 1.8vw, 18px);
  letter-spacing: 0;
}
.reach-arrow {
  grid-area: arrow;
  color: var(--gold); font-size: 24px; line-height: 1;
  transition: transform 200ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .reach a:hover { background: var(--surface-alt); }
  .reach a:hover .reach-arrow { transform: translateX(4px); }
}

/* ---------- Nav cards (home → subpages) ---------- */
.navcards {
  list-style: none; margin: 0;
  display: grid; gap: var(--rule-gap);
  background: var(--hairline-2);
  border: var(--rule-edge) solid var(--hairline-2);
}
@media (min-width: 900px) { .navcards { grid-template-columns: repeat(3, 1fr); } }
/* Four-card variant (the About page). Must follow the rule above so it wins at 900px,
   where `repeat(3, 1fr)` would leave a single orphaned card on its own row. */
@media (min-width: 900px)  { .navcards-4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .navcards-4 { grid-template-columns: repeat(4, 1fr); } }
.navcards li { background: var(--ink); display: flex; }
.navcards a {
  display: grid; gap: 10px; align-content: start;
  width: 100%;
  padding: 28px 26px;
  text-decoration: none;
  transition: background-color 180ms var(--ease-out);
}
.navcard-n {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: 13px; letter-spacing: 0.08em;
  color: var(--gold);
}
.navcard-title {
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: clamp(18px, 2.4vw, 22px);
  letter-spacing: var(--track-display-sm); text-transform: uppercase;
  line-height: var(--lh-tight);
  color: var(--white);
  transition: color 180ms var(--ease-out);
}
.navcard-sub { color: var(--muted); font-size: 14px; line-height: 1.55; }
.navcard-arrow {
  color: var(--gold); font-size: 22px; line-height: 1;
  margin-top: 4px;
  transition: transform 200ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .navcards a:hover { background: var(--surface-alt); }
  .navcards a:hover .navcard-title { color: var(--gold); }
  .navcards a:hover .navcard-arrow { transform: translateX(4px); }
}

/* ---------- Belt rank ----------
   Ported from the design system's BeltRank component. The belt tokens are IDENTITY
   colours and the system's own note says they need a contrast check before use — it was
   right: --belt-purple measures 2.61:1 against --ink, and the black rank bar is 2.61:1
   against the purple body. Neither clears 3:1.

   So the swatch is decorative reinforcement only: it is aria-hidden and the adjacent TEXT
   label carries the rank. That keeps the belt's real colours honest (a purple belt is
   purple; lightening it to pass a ratio would misrepresent the rank) without ever making
   colour the sole carrier of information. A hairline border and a light separator give the
   shape definition against a dark surface. */
.belt {
  display: inline-flex; align-items: center; gap: 10px;
  margin: 0;
}
.belt-swatch {
  position: relative;
  flex: none;
  width: 68px; height: 16px;
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline-2);
}
/* the black rank bar, inset from the tip like a real belt */
.belt-swatch::after {
  content: "";
  position: absolute; top: 0; bottom: 0; right: 6px;
  width: 26px;
  background: var(--belt-bar);
  box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.32),
              inset -1px 0 0 rgba(255, 255, 255, 0.32);
}
.belt-white  { background: var(--belt-white); }
.belt-blue   { background: var(--belt-blue); }
.belt-purple { background: var(--belt-purple); }
.belt-brown  { background: var(--belt-brown); }
.belt-black  { background: var(--belt-black); }
.belt-black::after { background: var(--belt-bar-red); }

.belt-label {
  font-size: 13px; font-weight: 700;
  letter-spacing: var(--track-caps-tight); text-transform: uppercase;
  color: var(--muted);
}

/* ---------- Contact form ----------
   Visible labels (never placeholder-as-label), 16px inputs so iOS does not zoom on focus,
   real autocomplete/inputmode hints, and native validation left to do its job.
   `:user-invalid` rather than `:invalid` — the latter flags empty required fields before
   the visitor has typed anything, which is a scolding, not a hint. */
.form { display: grid; gap: 22px; max-width: 640px; }

.field { display: grid; gap: 8px; }
.field label {
  font-size: 11px; font-weight: 700;
  letter-spacing: var(--track-eyebrow); text-transform: uppercase;
  color: var(--muted);
}
.req { color: var(--gold); }
.opt {
  color: var(--quiet); font-weight: 400;
  letter-spacing: var(--track-caps-tight);
}

.field input,
.field textarea {
  width: 100%;
  min-height: 54px;
  padding: 14px 16px;
  font-family: var(--font-body);
  font-size: 16px;              /* 16px floor: anything smaller makes iOS zoom on focus */
  line-height: 1.5;
  color: var(--white);
  background: var(--ink);
  border: var(--rule-edge) solid var(--field-border);
  border-radius: var(--r-none);
}
.field textarea { min-height: 150px; resize: vertical; }
.field input::placeholder,
.field textarea::placeholder { color: var(--quiet-2); }

.field input:focus-visible,
.field textarea:focus-visible {
  outline: 3px solid var(--white);
  outline-offset: 2px;
  border-color: var(--gold);
}
@media (hover: hover) and (pointer: fine) {
  .field input:hover, .field textarea:hover { border-color: var(--muted); }
}
/* Only after the visitor has actually interacted. */
.field input:user-invalid,
.field textarea:user-invalid { border-color: var(--red-hi); }

.form-note { color: var(--muted); font-size: 14px; margin: 0; }
.form button[type="submit"] { justify-self: start; }
@media (max-width: 479px) { .form button[type="submit"] { justify-self: stretch; width: 100%; } }
