/* ============================================================
   supplemental.css — fallback rules for page-local classes
   used by individual pages but not yet codified in main.css.
   Loaded AFTER main.css. Token vars from main.css §2 are used.

   FULL REWRITE 2026-06-02 by MASTER PATCH AGENT.
   Driven by 30-file QA review under /qa_reviews/.

   Goals:
     - Kill the 800px .subpage .container clamp that broke every subpage.
     - Replace off-palette hex with locked design tokens.
     - Replace undefined --brand-cream / --brand-ink vars with
       --surface-cream / --surface-ink.
     - Add missing component rules (legal-page__*, pillar-card color
       modifiers, day-accordion sub-elements, race-toggle sub-elements,
       compare grid, calculator aliases, faq-accordion__content, etc).
     - Restore list bullets on legal/content pages (global reset killed them).
   ============================================================ */


/* ============================================================
   1. .subpage IS A HINT, NOT A CLAMP
   ------------------------------------------------------------
   Previously: `.subpage .container { max-width: 800px; padding: 64px 0; }`
   broke every interior page (homepage container is 1200px, subpages
   were forced down to 800px and lost their horizontal gutter).
   Now: .subpage is purely a nav scroll-state hint. Container clamp
   is opt-in via .container--narrow on the inner element.
   ============================================================ */
body.subpage {
  /* .subpage is now a pure semantic marker — DOES NOT force cream-fill
     on the nav. Per fix 2026-06-01: nav is transparent on EVERY page
     at scroll-top, and only flips to cream via .nav--scrolled (added
     by main.js when window.scrollY > 50). The previous override —
     `body.subpage .nav { background: cream }` — pushed every subpage
     hero below the nav and is REMOVED. */
}
/* Patched 2026-06-02 (X-AXIS UNIFICATION): legal `.container--narrow`
   wrapper now keeps the canonical 1200px max-width so the left edge
   aligns with every other page. The 720px reading-line clamp applies
   to its children via `.container--narrow > *` (main.css §4). */
body.subpage--legal .container--narrow {
  max-width: var(--page-max);
}
body.subpage--legal .container--narrow > * {
  max-width: var(--container-narrow);
}
/* Legal pages should sit on cream like every other section — remove
   the prior `.subpage--legal { background: #fff }` conflict. */
body.subpage--legal {
  background: var(--surface-cream);
}


/* ============================================================
   2. HERO VARIANTS
   ------------------------------------------------------------
   ALL hero min-heights live in main.css §9 now (single source of
   truth: home = 100svh, every other hero = 30svh mobile / 35svh
   desktop). Legacy override removed 2026-06-02.
   ============================================================ */


/* ============================================================
   3. LEGAL PAGES
   ------------------------------------------------------------
   Pages use a mix of .legal__* (privacy.html) and .legal-page__*
   (terms.html, photo-release.html). Both naming forms must work.
   ============================================================ */
.legal,
.legal-page {
  padding: 48px 0 96px;
}
.legal__body,
.legal-page__body {
  max-width: 760px;
  /* Patched 2026-06-02 (X-AXIS UNIFICATION): anchor to wrapper's
     left edge so the body copy on legal pages aligns with the
     hero H1, section H2s, and footer columns on every other page.
     The 760px clamp still gives a readable measure. */
  margin-inline-start: 0;
  margin-inline-end: auto;
  font-size: 1rem;
  line-height: 1.7;
  color: var(--surface-ink);
}
.legal__body h2,
.legal-page__body h2 {
  margin-top: 2.5em;
  margin-bottom: 0.6em;
  font-size: 1.5rem;
  color: var(--brand-aubergine);
}
.legal__body h3,
.legal-page__body h3 {
  margin-top: 1.8em;
  margin-bottom: 0.4em;
  font-size: 1.2rem;
}
.legal__body p,
.legal__body li,
.legal-page__body p,
.legal-page__body li {
  margin-bottom: 1em;
}
.legal__body ul,
.legal__body ol,
.legal-page__body ul,
.legal-page__body ol {
  padding-left: 1.5em;
}

/* Legal-page meta line ("Last updated: ...") */
.legal-meta,
.legal__updated,
.legal-page__updated {
  font-size: 0.875rem;
  color: var(--ink-muted);
  margin-bottom: 2em;
  padding-bottom: 1em;
  border-bottom: 1px solid var(--ink-muted);
}

/* Pull-quotes on legal pages */
.legal__quote,
.legal-page__quote {
  border-left: 4px solid var(--brand-aubergine);
  padding: 1.5rem 1.5rem 1.5rem 2rem;
  margin: 2rem 0;
  background: var(--surface-cream);
  font-style: italic;
  color: var(--surface-ink);
}

/* Section dividers on legal pages */
.legal__divider,
.legal-page__divider {
  border: 0;
  border-top: 1px solid var(--ink-muted);
  margin: 3rem 0;
}

/* Strap/intro lines */
.legal__strap,
.legal-page__strap,
.legal-page__intro {
  font-size: 1.0625rem;
  color: var(--ink-muted);
  margin-bottom: 1.5em;
}

/* Legal-section + legal-body inherit from the container; supply a baseline. */
.legal-section,
.legal-body {
  margin-bottom: 2em;
}

/* TOC card */
.legal-toc {
  background: var(--surface-cream);
  border-left: 4px solid var(--brand-aubergine);
  padding: 20px 24px;
  margin: 24px 0 32px;
  border-radius: 4px;
}
.legal-toc__title {
  font-size: 1rem;
  font-weight: 700;
  margin-bottom: 8px;
  color: var(--brand-aubergine);
}
.legal-toc ol,
.legal-toc ul {
  margin: 0;
  padding-left: 1.2em;
  list-style: decimal;
}
.legal-toc a {
  color: var(--brand-aubergine);
  text-decoration: none;
}
.legal-toc a:hover,
.legal-toc a:focus-visible {
  text-decoration: underline;
}

/* Tables on legal pages */
.legal-table-wrap {
  overflow-x: auto;
  margin: 1.5em 0;
}
.legal-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}
.legal-table th,
.legal-table td {
  border: 1px solid var(--ink-muted);
  padding: 10px 12px;
  text-align: left;
  vertical-align: top;
}
.legal-table th {
  background: var(--surface-cream);
  font-weight: 700;
  color: var(--brand-aubergine);
}


/* ============================================================
   4. RESTORE LIST BULLETS ON CONTENT PAGES
   ------------------------------------------------------------
   The global reset in main.css §1 kills list-style: none on ul/ol.
   That's fine for nav/footer, but legal + body content needs
   real bullets to be readable.
   ============================================================ */
.legal-page ul,
.legal-page__body ul,
.legal__body ul,
.body ul:not(.no-bullets),
ul.body:not(.no-bullets),
.legal-section ul,
.legal-body ul,
.pillar-card__list {
  list-style: disc;
  padding-left: 1.5em;
}
.legal-page ol,
.legal-page__body ol,
.legal__body ol,
.body ol:not(.no-bullets),
ol.body:not(.no-bullets),
.legal-section ol,
.legal-body ol {
  list-style: decimal;
  padding-left: 1.5em;
}
.legal-page li,
.legal-page__body li,
.legal__body li,
.body li,
.pillar-card__list li {
  margin-bottom: 0.5em;
  line-height: 1.6;
}


/* ============================================================
   5. PILLAR CARD COLOR MODIFIERS + EXTENSIONS
   ------------------------------------------------------------
   main.css §11 covers nth-child rotation. Some pages set explicit
   modifiers; both must work.
   ============================================================ */
.pillar-card--lilac    { background: var(--brand-lilac);    color: var(--surface-ink); }
.pillar-card--salmon   { background: var(--accent-salmon);  color: var(--surface-ink); }
.pillar-card--lavender { background: var(--accent-lavender); color: var(--surface-ink); }

.pillar-card__cost-number {
  font-family: var(--font-display);
  font-size: 3rem;
  line-height: 1;
  color: var(--surface-ink);
}
.pillar-card__cost-label {
  font-size: 0.875rem;
  color: var(--surface-ink);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.pillar-card__list {
  margin: 12px 0;
}
.pillar-card__back-link {
  display: inline-block;
  margin-top: 1rem;
}
.pillar-card__body {
  flex: 1;
}
.pillar-card__body-text {
  font-size: 1rem;
  line-height: 1.6;
  margin: 0 0 12px;
  color: var(--surface-ink);
}


/* ============================================================
   6. STAT BAND EXTENSIONS
   ============================================================ */
.stat-band--cumulative {
  background: var(--brand-aubergine);
  color: var(--surface-white);
}
.stat-band--cumulative .stat-band__number,
.stat-band--cumulative .stat-band__label {
  color: var(--surface-white);
}

/* Patched 2026-06-02: when ANY stat-band modifier (--cumulative,
   --pilot, etc.) is nested inside a `.section--cream` (post-alternation
   flip), reset bg + text color so the band reads as part of the cream
   section. Specificity (0,3,0) beats the modifier rules above (0,2,0)
   so this wins regardless of source order. */
.section--cream .stat-band--cumulative,
.section--cream .stat-band--cumulative .stat-band__number,
.section--cream .stat-band--cumulative .stat-band__label,
.section--cream .stat-band--pilot,
.section--cream .stat-band--pilot .stat-band__number,
.section--cream .stat-band--pilot .stat-band__label {
  background: transparent;
  color: var(--surface-ink);
}


/* ============================================================
   7. STEP / PROCESS GRIDS
   ------------------------------------------------------------
   B17: pick ONE step-number convention — 56px Cosmic Buns aubergine
   on cream, NO background circle. Apply to .step__number,
   .how-step__num, .steps-grid__num.
   ============================================================ */
.step-grid,
.steps-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 24px;
  margin: 32px 0;
}
.step,
.how-step,
.steps-grid__item {
  padding: 24px;
  background: var(--surface-white);
  border-radius: var(--radius-card);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.step__number,
.how-step__num,
.steps-grid__num {
  display: inline-block;
  width: auto;
  height: auto;
  line-height: 1;
  background: transparent;
  color: var(--brand-aubergine);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 56px;
  margin-bottom: 12px;
  border-radius: 0;
  text-align: left;
}


/* ============================================================
   8. COMPARE / ELIGIBILITY GRIDS
   ============================================================ */
.compare-grid,
.eligibility-grid,
.compare {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px;
  margin: 24px 0;
}
.compare__col,
.compare-grid > *,
.eligibility-grid > * {
  background: var(--surface-white);
  padding: 20px;
  border-radius: var(--radius-card);
  border: 1px solid var(--surface-cream);
}
.compare__title {
  font-family: var(--font-heading);
  font-weight: 900;
  font-size: 1.125rem;
  margin-bottom: 12px;
  color: var(--brand-aubergine);
}
.compare__list {
  list-style: disc;
  padding-left: 1.5em;
}
.compare__list li {
  margin-bottom: 0.5em;
  line-height: 1.6;
}


/* ============================================================
   9. RESCUE / CALLOUT BOXES
   ============================================================ */
.rescue-callout {
  background: var(--accent-salmon);
  border-radius: var(--radius-card);
  padding: 20px 24px;
  margin: 24px 0;
  color: var(--surface-ink);
}
.rescue-callout strong {
  color: var(--brand-aubergine);
}


/* ============================================================
   10. JOTFORM / FORM PLACEHOLDERS
   ============================================================ */
.jotform-placeholder {
  background: var(--surface-cream);
  border: 2px dashed var(--brand-aubergine);
  border-radius: var(--radius-card);
  padding: 48px 24px;
  text-align: left;
  margin: 32px 0;
  color: var(--ink-muted);
}


/* ============================================================
   11. ERROR PAGE / 404
   ============================================================ */
.error-links {
  list-style: none;
  padding: 0;
  margin: 24px 0;
}
.error-links li {
  margin: 12px 0;
}

/* Countdown on cream sections — main.css §15 was designed for aubergine.
   B18: variant for cream-backed countdowns (404, faq, thanks). */
.countdown--on-cream .countdown__label {
  color: var(--surface-ink);
}
.countdown--on-cream .countdown__number,
.countdown--on-cream .countdown__sep {
  color: var(--brand-aubergine);
}


/* ============================================================
   12. TRUST / CLOSING CTA SECTIONS
   ------------------------------------------------------------
   B21: never center body text. Per BUILD_CONTRACT line 192.
   ============================================================ */
.section--trust {
  background: var(--surface-cream);
  padding-block: var(--section-pad-mobile);
  padding-inline: 0;
}
@media (min-width: 768px) {
  .section--trust {
    padding-block: var(--section-pad-desktop);
  }
}
.trust-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 32px;
  font-size: 0.95rem;
  color: var(--ink-muted);
  /* NOT centered — left-align per hard rule */
}
/* Patched 2026-06-01: handle BOTH .section--closing-cta (about-hy) and
   .section--closing (index). The Home closing block previously rendered
   as a cream image-band with a huge gap before the footer because the
   image-overlay rules didn't constrain padding. Force aubergine fill,
   white text, no center alignment, and a sensible bottom padding. */
.section--closing,
.section--closing-cta {
  background: var(--brand-aubergine);
  color: var(--surface-white);
  padding-block: var(--section-pad-mobile);
  padding-inline: 0;
  /* B21: NOT centered. */
  text-align: left !important;
  position: relative;
  overflow: hidden;
}
@media (min-width: 768px) {
  .section--closing,
  .section--closing-cta {
    padding-block: var(--section-pad-desktop);
  }
}
.section--closing .h1,
.section--closing .h2,
.section--closing h1,
.section--closing h2,
.section--closing-cta .h1,
.section--closing-cta .h2,
.section--closing-cta h1,
.section--closing-cta h2 {
  color: var(--surface-white);
}
.section--closing .body,
.section--closing p,
.section--closing-cta .body,
.section--closing-cta p {
  color: var(--brand-lilac);
}
/* Patched 2026-06-02 (Sam): closing-CTA Register button uses the site-wide
   orange-pill spec — was white-on-aubergine. Override removed so the base
   .btn--primary (terracotta) wins. Hover: aubergine (inverse). */
.section--closing .btn--primary,
.section--closing-cta .btn--primary {
  background: var(--brand-terracotta) !important;
  color: var(--surface-white) !important;
}
.section--closing .btn--primary:hover,
.section--closing .btn--primary:focus-visible,
.section--closing-cta .btn--primary:hover,
.section--closing-cta .btn--primary:focus-visible {
  background: var(--brand-aubergine) !important;
  color: var(--surface-white) !important;
}
/* When the closing section contains a background image + overlay
   (Home pattern), suppress the image and keep the aubergine fill —
   the image was producing the cream-band-before-footer gap. */
.section--closing .section__image,
.section--closing-cta .section__image {
  display: none;
}
.section--closing .section__overlay,
.section--closing-cta .section__overlay {
  display: none;
}
.section--closing .container,
.section--closing-cta .container {
  position: relative;
  z-index: 1;
}
.section--closing .section__closing-content,
.section--closing-cta .section__closing-content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-4);
}
.section--closing .section__closing-micro {
  color: var(--brand-lilac);
  font-size: var(--fs-small);
  opacity: 0.85;
}
.closing-cta__row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 24px;
  /* NOT centered */
  justify-content: flex-start;
}


/* ============================================================
   13. (REMOVED) .btn--orange — invalid off-palette token.
   ------------------------------------------------------------
   B7: removed entirely. About-HY closing "Visit Health Yetu"
   CTA should use .btn--primary (aubergine pill). For hierarchy,
   make the secondary use .btn--secondary (cream/ink/border).
   We leave a no-op alias so that any HTML still wearing
   .btn--orange degrades to .btn--primary styling, not white-
   on-white invisibility.
   ============================================================ */
.btn--orange {
  /* alias: behave as .btn--primary so we don't break the page if
     the HTML hasn't been rewritten yet. */
  background: var(--brand-aubergine) !important;
  color: var(--surface-white) !important;
  border: 0;
}
.btn--orange:hover,
.btn--orange:focus-visible {
  background: var(--brand-terracotta) !important;
}


/* ============================================================
   13b. AFTERMOVIE PLACEHOLDER
   ------------------------------------------------------------
   Patched 2026-06-01: hide the placeholder iframe block when no
   real YouTube ID is set (data-youtube-id="TBD" or missing).
   Otherwise the Home page renders a broken empty iframe slot
   between the pillar grid and cumulative stat band.
   ============================================================ */
.aftermovie__frame[data-youtube-id="TBD"],
.aftermovie__frame:not([data-youtube-id]),
.aftermovie-placeholder[data-youtube-id="TBD"],
.aftermovie-placeholder:not([data-youtube-id]):not([data-has-content]) {
  display: none !important;
}
/* When the frame is hidden, hide its caption too. */
.aftermovie:has(.aftermovie__frame[data-youtube-id="TBD"]) .aftermovie__caption,
.aftermovie:has(.aftermovie__frame:not([data-youtube-id])) .aftermovie__caption {
  display: none !important;
}
/* And the entire aftermovie wrapper if every child is suppressed. */
.aftermovie:has(.aftermovie__frame[data-youtube-id="TBD"]):not(:has(.aftermovie__frame:not([data-youtube-id="TBD"]))) {
  display: none !important;
}


/* ============================================================
   14. MAP PLACEHOLDERS
   ============================================================ */
.map-placeholder,
.map-static-kenya {
  width: 100%;
  min-height: 320px;
  background: var(--surface-cream);
  border: 1px solid var(--ink-muted);
  border-radius: var(--radius-card);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--brand-aubergine);
  font-weight: 600;
  margin: 24px 0;
}
.map-placeholder::after,
.map-static-kenya::after {
  content: "Map preview";
  opacity: 0.6;
}


/* ============================================================
   15. DAY ACCORDION SUB-ELEMENTS
   ------------------------------------------------------------
   B13: hierarchy collapsed because the-race.html emits
   .day-accordion__date / __activity / __altitude / __distance /
   __preview / __meta / __body without rules.
   ============================================================ */
.day-accordion__date {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--brand-lilac);
}
.day-accordion__activity {
  display: block;
  font-family: var(--font-heading);
  font-weight: 900;
  font-size: 1.125rem;
  line-height: 1.3;
  color: inherit;
}
.day-accordion__altitude,
.day-accordion__distance {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  color: inherit;
  opacity: 0.85;
}
.day-accordion__preview {
  display: block;
  font-family: var(--font-body);
  font-size: 0.875rem;
  color: inherit;
  opacity: 0.85;
  margin-top: 4px;
}
.day-accordion__meta {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 16px;
  margin: 16px 0;
  font-size: 0.9375rem;
}
.day-accordion__meta dt {
  font-family: var(--font-heading);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.75rem;
  color: var(--brand-lilac);
  align-self: center;
}
.day-accordion__meta dd {
  margin: 0;
  color: inherit;
}
.day-accordion__body {
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  color: inherit;
}
.day-accordion__body p + p {
  margin-top: 12px;
}


/* ============================================================
   16. RACE-TOGGLE SUB-ELEMENTS
   ------------------------------------------------------------
   B14: legs / leg-label / leg-value / leg-note / total / total-value.
   Patched 2026-06-01 (LEFT-ALIGN FLEX REWRITE per Sam): legs flow
   left-to-right with a fixed gap. First leg aligns to the card's
   left edge (matching the card title). Each leg sizes to its natural
   width — long notes wrap inside the leg's max-width without breaking
   the row. // Left-align flex pattern per Sam's instruction. */
.race-toggle__legs {
  display: flex !important;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: flex-start;
  gap: var(--space-4);
  margin: var(--space-5) 0 var(--space-4);
  list-style: none;
  padding: 0;
}
.race-toggle__legs > li {
  flex: 0 0 auto;                              /* natural width per content */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;                                /* allow shrink only if absolutely needed */
  /* no max-width — block sizes to content. Patched 2026-06-01d (Sam): removed
     the 220px cap so the label + value can size to their natural widths and
     labels stay on one line (see .race-toggle__leg-label nowrap). */
}
@media (max-width: 480px) {
  .race-toggle__legs {
    flex-direction: column !important;
  }
  .race-toggle__legs > li {
    max-width: 100%;
  }
}
.race-toggle__leg-label {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--brand-terracotta);
  display: block;
  margin-bottom: 4px;
  white-space: nowrap;                         /* labels stay on one line — block width = max(value, label) */
}
.race-toggle__leg-value {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.5rem, 3vw, 2.5rem);
  line-height: 1.1;
  color: var(--surface-ink);
  display: block;
}
.race-toggle__leg-note {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 0.875rem;
  color: var(--ink-muted);
  margin-top: 4px;
  display: block;
}
.race-toggle__total {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(23, 20, 17, 0.12);
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
}
.race-toggle__total-label,
.race-toggle__total .eyebrow {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 0.75rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--brand-terracotta);
}
.race-toggle__total-value {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2.5rem);
  color: var(--brand-aubergine);
}


/* ============================================================
   17. CALCULATOR CLASS ALIASES
   ------------------------------------------------------------
   B16: support both naming conventions emitted by calculator.js
   (now emits both, but the CSS aliases let either name win).
   ============================================================ */
.calculator__count {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 3rem;
  line-height: 1;
  color: inherit;
}
.calculator__label {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: inherit;
  margin-left: 8px;
}


/* ============================================================
   18. FAQ ACCORDION — content wrapper
   ------------------------------------------------------------
   HTML uses .faq-accordion__content for the answer wrapper.
   main.css §16 only styled .faq-accordion__answer. Add the alias.
   ============================================================ */
.faq-accordion__content {
  margin-top: var(--space-3);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink-muted);
  padding-bottom: var(--space-2);
}
.faq-accordion__content p + p {
  margin-top: 12px;
}
.faq-accordion__bucket-title {
  font-family: var(--font-heading);
  font-weight: 900;
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  margin-top: var(--space-6);
  margin-bottom: var(--space-3);
  color: var(--surface-ink);
}


/* ============================================================
   19. FOOTER CLASS CONSOLIDATION
   ------------------------------------------------------------
   B11: pages mix .footer__top vs .footer__cols and
   .footer__legal-links vs .footer__bottom-links. Aliases.
   ============================================================ */
.footer__cols,
.footer__top {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
}
@media (min-width: 768px) {
  .footer__cols,
  .footer__top {
    grid-template-columns: repeat(3, 1fr);
  }
}
.footer__bottom-links,
.footer__legal-links {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}


/* ============================================================
   20. RESPONSIVE COLLAPSES
   ============================================================ */
@media (max-width: 640px) {
  /* Stale grid-template-columns rule replaced by flex-direction:
     these grids are now LEFT-ALIGN FLEX (see §23 C4–C11). The
     base rules already set flex-direction: column on mobile. */
  .step-grid,
  .compare-grid,
  .eligibility-grid,
  .compare {
    flex-direction: column !important;
  }
  .trust-line {
    gap: 16px;
  }
  .legal__body,
  .legal-page__body {
    font-size: 1rem;
  }
}


/* ============================================================
   21. NAV LOGO — DUAL-IMAGE WHITE/BLACK SWAP
   ------------------------------------------------------------
   Added 2026-06-01 with the Yetu Triathlon brand mark.
   Each nav contains TWO <img> tags:
     .nav__logo-img--white (for dark hero / transparent nav)
     .nav__logo-img--black (for cream-on-ink nav)
   CSS picks which one is visible based on nav state.

   Patched 2026-06-01c (double-logo fix):
     Earlier rules in main.css used `.nav__logo img` (specificity 0,1,1)
     which OUTRANKED `.nav__logo-img--black { display: none }` (0,1,0)
     — both images rendered side by side. main.css was tightened to use
     only `.nav__logo-img` (0,1,0), so the simple class swap below now
     wins on equal specificity by source order (supplemental loads last).
     The previous `body.subpage .nav__logo-img--*` overrides were removed
     — every page now starts in the un-scrolled state (white logo) and
     swaps to black on `.nav--scrolled`. The parallel hero-overlay-nav
     fix agent owns the matching `body.subpage` nav-background cleanup.

   Logo is also larger now — Sam reported the old yt_logo at
   140x40 was too small. New default is up to 64px tall.
   ============================================================ */
.nav__logo {
  display: inline-flex;
  align-items: center;
  /* The two stacked <img>s share the same slot; only one is shown. */
}

/* Default state: white logo visible (over hero photo). */
.nav__logo-img { max-height: 64px; height: auto; width: auto; }
.nav__logo-img--black { display: none; }
.nav__logo-img--white { display: block; }

/* Scrolled state: nav becomes cream → swap to black logo. */
.nav.nav--scrolled .nav__logo-img--white,
.nav--scrolled .nav__logo-img--white { display: none; }
.nav.nav--scrolled .nav__logo-img--black,
.nav--scrolled .nav__logo-img--black { display: block; }

/* Mobile size. */
@media (max-width: 768px) {
  .nav__logo-img { max-height: 48px; }
}


/* ============================================================
   22. FOOTER LOGO — ALWAYS WHITE, BIGGER
   ------------------------------------------------------------
   Footer is always aubergine — the white logo always wins.
   Bump the displayed size to match the new Yetu Triathlon mark.
   ============================================================ */
.footer__logo {
  display: block;
  max-height: 80px;
  height: auto;
  width: auto;
  margin-bottom: 16px;
}
@media (max-width: 768px) {
  .footer__logo {
    max-height: 64px;
  }
}


/* ============================================================
   23. VISUAL-AUDIT FIXES (2026-06-01)
   ------------------------------------------------------------
   Driven by /Users/samvanooijen/yetutriathlon_site/VISUAL_AUDIT.md
   Sam: "horizontals often still not well aligned and too large
   text size to fit on the pages. SAME SETTINGS everywhere."
   HARD RULES enforced site-wide:
     - Horizontal grids = `repeat(N, 1fr); gap: 2rem` desktop,
       single-column mobile at 768px (or 480px for stat-bands).
     - No per-cell clamp() font sizes in display text.
     - Step-numbers: 3rem Cosmic Buns aubergine, no circle bg.
     - Partner / pillar / sponsor tier cards equal-height.
     - Closing CTAs: aubergine, left-aligned, padding 96px 0.
   ============================================================ */

/* --- C1, C2, C3: section-header rhythm (eyebrow + h2 + lede) --- */
.eyebrow + .h2,
.eyebrow + h2,
.eyebrow + h3,
.eyebrow + .h3 {
  margin-top: var(--space-2);
}
.section__header {
  max-width: 720px;
  margin-bottom: var(--space-5);
}
.section__header .h2 + .body,
.section__header h2 + p,
.section__header .h2 + p {
  margin-top: var(--space-3);
}
.section__lede {
  max-width: 720px;
  margin-top: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}

/* Patched 2026-06-02 (SECTION INTERNAL RHYTHM FALLBACK):
   Many sections don't wrap content in `.section__header`. Those sections
   render as bare children of `.container` and feel cramped because nothing
   sets vertical gaps between eyebrow / h2 / body / CTA. This adds default
   spacing to direct `.container` children inside any `.section`, without
   touching sections that DO use `.section__header` (its children are
   wrapped one level deeper so this selector doesn't reach them). */
.section > .container > * + *,
.section > .container--narrow > * + * {
  margin-top: var(--space-4);                 /* 24px default sibling gap */
}
.section > .container > .eyebrow + .h2,
.section > .container > .eyebrow + h2,
.section > .container--narrow > .eyebrow + .h2,
.section > .container--narrow > .eyebrow + h2 {
  margin-top: var(--space-2);                 /* 8px tight eyebrow→h2 */
}
.section > .container > .h2 + .body,
.section > .container > .h2 + p,
.section > .container > h2 + p,
.section > .container--narrow > .h2 + .body,
.section > .container--narrow > .h2 + p,
.section > .container--narrow > h2 + p {
  margin-top: var(--space-3);                 /* 16px h2→body */
}
.section > .container > p + .btn,
.section > .container > .body + .btn,
.section > .container > p + .btn--text,
.section > .container > .body + .btn--text,
.section > .container--narrow > p + .btn,
.section > .container--narrow > .body + .btn,
.section > .container--narrow > p + .btn--text,
.section > .container--narrow > .body + .btn--text {
  margin-top: var(--space-5);                 /* 32px body→CTA (pill OR text link) */
}

/* Patched 2026-06-02 (CLOSING-CTA → FOOTER COMPRESSION, Sam):
   The closing CTA's bottom padding + the footer's top padding stack to a
   192px+ gap on desktop, which feels disconnected. Pull them together so
   the "Register" pill sits closer to the footer's "About" block — visual
   continuity between the call-to-action and the legal/contact info that
   follows. Override scoped to (a) closing-CTA bottom and (b) footer top
   only — section→section gaps elsewhere remain at the canonical token. */
.section.closing-cta,
.section--closing,
.section--closing-cta,
section.closing-cta {
  padding-bottom: var(--space-6) !important;  /* 48px mobile + desktop */
}

/* Patched 2026-06-02 (RACE-TOGGLE ON AUBERGINE BG):
   The race-toggle tabs + leg labels/values/notes were styled for cream.
   When the section is .section--aubergine (purple), the dark ink text +
   greyed-muted inactive-tab color disappear against the bg. Light-on-dark
   variant scoped to the aubergine section only. */
.section--aubergine .race-toggle__tablist {
  border-bottom-color: rgba(255, 255, 255, 0.25);
}
.section--aubergine .race-toggle__tab {
  color: rgba(255, 255, 255, 0.65);             /* inactive tab — soft white */
}
.section--aubergine .race-toggle__tab[aria-selected="true"] {
  color: var(--surface-white);                  /* selected — full white */
  border-bottom-color: var(--brand-lilac);      /* lilac underline pops on aubergine */
}
.section--aubergine .race-toggle__tab:hover {
  color: var(--surface-white);
}
.section--aubergine .race-toggle__leg-label {
  color: var(--brand-lilac);                    /* lilac label on aubergine */
}
.section--aubergine .race-toggle__leg-value {
  color: var(--surface-white);
}
.section--aubergine .race-toggle__leg-note {
  color: rgba(255, 255, 255, 0.75);             /* slightly subdued note */
}
.section--aubergine .race-toggle__total {
  border-top-color: rgba(255, 255, 255, 0.25);  /* divider visible on aubergine */
}
.section--aubergine .race-toggle__total-label,
.section--aubergine .race-toggle__total .eyebrow {
  color: var(--brand-lilac);                    /* matches leg-label treatment */
}
.section--aubergine .race-toggle__total-value {
  color: var(--surface-white);                  /* was aubergine-on-aubergine — invisible */
}

/* Patched 2026-06-02: connector word ("or") inside a .stat-band__number
   should sit smaller + lighter than the surrounding numerals so the
   numbers carry the visual weight. Used on the-race AT A GLANCE for
   "25 or 75 km". */
.stat-band__connector {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.45em;                            /* relative to the big numeric size */
  text-transform: lowercase;
  letter-spacing: 0.02em;
  vertical-align: middle;
  opacity: 0.75;
  margin: 0 0.15em;
}
.footer {
  padding-top: var(--space-6) !important;     /* 48px mobile + desktop */
}
@media (min-width: 1024px) {
  .section.closing-cta,
  .section--closing,
  .section--closing-cta,
  section.closing-cta {
    padding-bottom: var(--space-6) !important;
  }
  .footer {
    padding-top: var(--space-6) !important;
  }
}

/* --- C4: .how-grid (fundraise) — LEFT-ALIGN FLEX per Sam's instruction
   (was grid 1fr → 3fr). First card aligns to section left edge; cards
   flow right with fixed gap and grow to fill the row.
   // Left-align flex pattern per Sam's instruction. */
.how-grid {
  display: flex !important;
  flex-direction: column !important;
  flex-wrap: wrap !important;
  justify-content: flex-start !important;
  align-items: stretch !important;
  gap: 2rem !important;
  margin-top: var(--space-6);
  list-style: none;
  padding: 0;
}
.how-grid > * {
  flex: 1 1 240px;
  min-width: 0;
}
@media (min-width: 768px) {
  .how-grid {
    flex-direction: row !important;
  }
}
.how-step {
  background: var(--surface-white);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 220px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
}

/* --- C5, C6, C7: step-grid + step-number — LEFT-ALIGN FLEX per Sam's
   instruction (was grid 1fr → 2fr → 4fr). First step aligns to section
   left edge; cards flow right with a fixed gap and grow to fill space.
   // Left-align flex pattern per Sam's instruction. */
.step-grid,
.steps-grid {
  display: flex !important;
  flex-direction: column !important;
  flex-wrap: wrap !important;
  justify-content: flex-start !important;
  align-items: stretch !important;
  gap: 2rem !important;
  margin: var(--space-6) 0 0 !important;
  list-style: none;
  padding: 0;
}
.step-grid > *,
.steps-grid > * {
  flex: 1 1 220px;
  min-width: 0;
}
@media (min-width: 768px) {
  .step-grid,
  .steps-grid {
    flex-direction: row !important;
  }
}
.step-grid__item,
.steps-grid__item,
.step,
.how-step {
  background: var(--surface-white);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
  min-height: 0;
}
.step-grid__number,
.steps-grid__number,
.step__number,
.how-step__num {
  display: block;
  font-family: var(--font-display) !important;
  font-weight: 400 !important;
  font-size: 3rem !important;
  line-height: 1 !important;
  color: var(--brand-aubergine) !important;
  background: transparent !important;
  border-radius: 0 !important;
  width: auto !important;
  height: auto !important;
  margin-bottom: 0.75rem !important;
  text-align: left !important;
  padding: 0 !important;
}
@media (max-width: 768px) {
  .step-grid__number,
  .steps-grid__number,
  .step__number,
  .how-step__num {
    font-size: 2.25rem !important;
  }
}

/* --- C8, C9, C10, C11: compare/eligibility cards — LEFT-ALIGN FLEX
   per Sam's instruction (was grid 1fr/repeat(2, 1fr)). First card aligns
   to section left edge; cards grow to fill the row with a fixed gap.
   // Left-align flex pattern per Sam's instruction. */
.compare-grid,
.compare,
.eligibility-grid {
  display: flex !important;
  flex-direction: column !important;
  flex-wrap: wrap !important;
  justify-content: flex-start !important;
  align-items: stretch !important;
  gap: 2rem !important;
  margin: var(--space-6) 0 0 !important;
  list-style: none;
  padding: 0;
}
.compare-grid > *,
.compare > *,
.eligibility-grid > * {
  flex: 1 1 280px;
  min-width: 0;
}
@media (min-width: 768px) {
  .compare-grid,
  .compare,
  .eligibility-grid {
    flex-direction: row !important;
  }
}
.compare-col,
.compare__col {
  background: var(--surface-white);
  padding: var(--space-5);
  border-radius: var(--radius-card);
  border: 1px solid rgba(23, 20, 17, 0.06);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  /* Patched 2026-06-02: lock dark text + dark bullet markers inside the
     white compare cards, regardless of the parent section's color. When
     the parent section is .section--aubergine, the section's white-text
     cascade made bullets + body white-on-white (invisible). */
  color: var(--surface-ink);
}
.compare-col *,
.compare__col * {
  color: var(--surface-ink);
}
/* Restore aubergine + underline for inline links inside the white compare
   cards (e.g. rescue.co in the Included list). Was inheriting ink color
   from the * rule above. */
.compare-col a,
.compare__col a {
  color: var(--brand-aubergine);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.compare-col a:hover,
.compare-col a:focus-visible,
.compare__col a:hover,
.compare__col a:focus-visible {
  color: var(--brand-terracotta);
}
/* Patched 2026-06-02 (Sam): both columns get a terracotta orange accent
   line on top (was: aubergine on --in, ink-muted on --out). Consistent
   visual treatment + matches the site-wide orange CTA palette. */
.compare-col--included,
.compare__col--in,
.compare-col--excluded,
.compare__col--out {
  border-top: 4px solid var(--brand-terracotta);
}
.compare-list,
.compare__list {
  list-style: disc;
  padding-left: 1.5em;
  margin: 0;
}
.compare-list li,
.compare__list li {
  margin-bottom: 0.5em;
  line-height: 1.6;
}

/* --- C13: .stat-band__grid baseline (covers fundraise + impact where the
   flex container sits at section root, not inside .container).
   Patched 2026-06-01: container constraints only — display/flex behaviour
   is now owned by main.css §10 (left-align flex pattern per Sam).
   Patched 2026-06-01c (STAT-BAND ALIGNMENT FIX — Sam's Image #28):
   The previous version applied `padding-inline: var(--container-pad)` to
   EVERY `.stat-band__grid`, including the ones that already sit inside a
   `<div class="container">`. That produced a DOUBLE gutter: the `.container`
   contributed `--container-pad` on the left, then this rule added another
   `--container-pad` on top — so the first stat item ("€37,000") landed
   ~40-80 px to the right of the section H2 ("Twelve climbed. Twelve
   summited."), which was rendered by the outer `.container` only.
   Fix: keep the rule's auto-margin + max-width, but ONLY add padding-inline
   when the grid is NOT a descendant of `.container` (i.e. impact.html +
   fundraise.html where the grid sits directly under the section). For grids
   inside `.container`, the container already supplies the gutter, so we
   neutralise this rule via the overrides below. --- */
.stat-band__grid {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  /* Patched 2026-06-02 (X-AXIS UNIFICATION): canonical page-gutter so
     stat-bands that sit at section-root (impact.html, fundraise.html)
     share the same left edge as `.container`-wrapped stat-bands. */
  padding-inline: var(--page-gutter);
}
/* Neutralise the C13 padding when the grid is INSIDE a .container — the
   container already provides the horizontal gutter. Also catches Pattern A
   (`.stat-band` as direct flex parent) when wrapped in `.container`. */
.container .stat-band__grid,
.container .stat-band:has(> .stat-band__item) {
  padding-inline: 0 !important;
  padding-left: 0 !important;
  margin-left: 0 !important;
  max-width: none;          /* the parent .container already caps width */
}
.container .stat-band__item:first-child {
  margin-left: 0 !important;
  padding-left: 0 !important;
}

/* --- C13b: vertical divider between consecutive stat items on aubergine.
   Each item gets a right-side rule + small right padding. The last item
   has no border and no padding-right. Combined with the flex `gap`, the
   visual rhythm is: [content][2rem pad-right][1px divider][gap][next].
   Subtle on the aubergine background. --- */
.stat-band__item {
  padding-right: 2rem;
  border-right: 1px solid rgba(255, 255, 255, 0.15);
}
.stat-band__item:last-child {
  border-right: 0;
  padding-right: 0;
}
/* On narrow mobile the flex container stacks vertically — switch the
   divider from right-edge to bottom-edge so it still visually separates
   stacked items. */
@media (max-width: 480px) {
  .stat-band__item {
    padding-right: 0;
    padding-bottom: 1.5rem;
    border-right: 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
    width: 100%;
  }
  .stat-band__item:last-child {
    border-bottom: 0;
    padding-bottom: 0;
  }
}

/* On cream sections (fundraise.html "the goal"), the white-on-aubergine
   divider would be invisible. Swap to an ink-on-cream alpha. */
.section--cream .stat-band__item {
  border-right-color: rgba(23, 20, 17, 0.10);
}
@media (max-width: 480px) {
  .section--cream .stat-band__item {
    border-bottom-color: rgba(23, 20, 17, 0.10);
  }
}

/* --- C14, C15: day-accordion trigger — explicit grid so the 5 children
   don't get squeezed by `justify-content: space-between`. Columns size
   to content per row (won't perfectly align across rows, but no overflow). --- */
.day-accordion__trigger {
  display: grid !important;
  grid-template-columns: auto auto 1fr auto auto;
  align-items: center;
  column-gap: var(--space-3);
  text-align: left;
}
.day-accordion__trigger > * {
  min-width: 0;
  overflow-wrap: break-word;
}
.day-accordion__num {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 2.25rem;
  line-height: 1;
  color: inherit;
  flex: 0 0 auto;
}
.day-accordion__activity {
  font-family: var(--font-heading);
  font-weight: 900;
  font-size: 1.125rem;
  line-height: 1.25;
  color: inherit;
  white-space: normal;
}
@media (max-width: 768px) {
  .day-accordion__trigger {
    grid-template-columns: auto 1fr auto !important;
    grid-template-areas:
      "num activity icon"
      "date date date"
      "preview preview preview";
    row-gap: 4px;
  }
  .day-accordion__num     { grid-area: num; font-size: 1.75rem; }
  .day-accordion__date    { grid-area: date; }
  .day-accordion__activity{ grid-area: activity; font-size: 1rem; }
  .day-accordion__preview { grid-area: preview; }
  .day-accordion__icon    { grid-area: icon; }
}

/* --- C16, C17: race-toggle leg values + total = FIXED size, no clamp --- */
.race-toggle__leg-value {
  font-size: 2rem !important;
  line-height: 1.1;
}
.race-toggle__total-value {
  font-size: 2rem !important;
  line-height: 1.1;
}
@media (max-width: 768px) {
  .race-toggle__leg-value,
  .race-toggle__total-value {
    font-size: 1.625rem !important;
  }
}

/* --- C18, C19: .closing-cta (no `section--` prefix) gets the same
   aubergine left-aligned treatment as .section--closing-cta. Travel
   page emits .closing-cta with a centered overlay block; override. --- */
.closing-cta {
  background: var(--brand-aubergine) !important;
  color: var(--surface-white) !important;
  padding-block: var(--section-pad-mobile) !important;
  padding-inline: 0 !important;
  min-height: 0 !important;
  text-align: left !important;
  position: relative;
  overflow: hidden;
  display: block !important;
  align-items: flex-start !important;
  justify-content: flex-start !important;
}
@media (min-width: 768px) {
  .closing-cta {
    padding-block: var(--section-pad-desktop) !important;
  }
}
.closing-cta__image,
.closing-cta__overlay {
  display: none !important;
}
.closing-cta__content {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  /* Patched 2026-06-02 (X-AXIS UNIFICATION): closing CTA content shares
     the canonical page x-axis with every other section wrapper. */
  padding: 0 var(--page-gutter);
  display: flex !important;
  flex-direction: column;
  align-items: flex-start !important;
  text-align: left !important;
  gap: var(--space-4);
}
.closing-cta__h2,
.closing-cta h2,
.closing-cta .h2 {
  color: var(--surface-white) !important;
  font-family: var(--font-heading);
  font-weight: 900;
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  text-align: left !important;
}
.closing-cta__micro,
.closing-cta p {
  color: var(--brand-lilac);
  text-align: left !important;
}
.closing-cta .eyebrow {
  color: var(--brand-lilac);
}
/* Same orange treatment for .closing-cta (no --section prefix, used on
   travel-and-logistics and the-race closing CTAs). Patched 2026-06-02. */
.closing-cta .btn--primary {
  background: var(--brand-terracotta) !important;
  color: var(--surface-white) !important;
}
.closing-cta .btn--primary:hover,
.closing-cta .btn--primary:focus-visible {
  background: var(--brand-aubergine) !important;
  color: var(--surface-white) !important;
}

/* --- C20, C21, C22: partner card equal-height + uniform placeholder --- */
.partner-card {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  text-align: center;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-4);
  background: var(--surface-white);
  border-radius: var(--radius-card);
  min-height: 240px;
}
.partner-card__logo {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 72px;
  max-width: 100%;
}
.partner-card__placeholder {
  min-height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  color: var(--ink-muted);
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 14px;
  text-align: center;
  background: var(--surface-cream);
  border-radius: var(--radius-card);
  padding: var(--space-2) var(--space-3);
}
.partner-card__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: center;
  text-align: center;
  justify-content: flex-start;
}
.partner-card__name {
  font-family: var(--font-heading);
  font-weight: 900;
  font-size: 1.0625rem;
  line-height: 1.25;
  color: var(--surface-ink);
  margin: 0;
}
.partner-card__role {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ink-muted);
  text-transform: none;
  letter-spacing: 0;
}
.partner-card__location {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brand-aubergine);
  margin-top: auto;
}

/* --- C23: extension tiles 2-col (travel) --- */
.extension-tiles {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  margin-top: var(--space-6);
}
@media (min-width: 768px) {
  .extension-tiles {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* --- C24: tips-list (fundraise) — kill the disc list-style so the inline
   ol with custom number spans doesn't double-number. --- */
.tips-list {
  list-style: none !important;
  padding: 0 !important;
}

/* --- Pillar card equal-height + cost-number alignment uniform --- */
.pillar-card {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.pillar-card__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.pillar-card__cost {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.pillar-card__cost-number {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 2.5rem;
  line-height: 1;
  color: var(--surface-ink);
}
@media (max-width: 768px) {
  .pillar-card__cost-number { font-size: 2rem; }
}
.pillar-card__cost-label {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 0.8125rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--surface-ink);
  opacity: 0.85;
}

/* --- Pillar grid HARD ENFORCE: 3-col desktop, single-col mobile.
   Some pages place .pillar-grid both as direct child of .section and
   wrapped in .container — main.css §11 covers both; this re-asserts
   the gap and tightens the mobile breakpoint. --- */
.pillar-grid {
  display: grid !important;
  grid-template-columns: 1fr !important;
  gap: 2rem !important;
}
@media (min-width: 768px) {
  .pillar-grid {
    grid-template-columns: repeat(3, 1fr) !important;
  }
}

/* --- Partner grid HARD ENFORCE: 4 desktop, 2 tablet, 1 mobile --- */
.partner-grid {
  display: grid !important;
  grid-template-columns: 1fr !important;
  gap: 2rem !important;
}
@media (min-width: 640px) {
  .partner-grid {
    grid-template-columns: repeat(2, 1fr) !important;
  }
}
@media (min-width: 1024px) {
  .partner-grid {
    grid-template-columns: repeat(4, 1fr) !important;
  }
}

/* --- Footer cols HARD ENFORCE: 3-col desktop, single mobile --- */
.footer__cols,
.footer__top {
  display: grid !important;
  grid-template-columns: 1fr !important;
  gap: var(--space-6) !important;
}
@media (min-width: 768px) {
  .footer__cols,
  .footer__top {
    grid-template-columns: repeat(3, 1fr) !important;
    gap: 2.5rem !important;
  }
}

/* --- FAQ accordion item — uniform spacing, prevent the +/- glyph from
   shifting when long questions wrap --- */
.faq-accordion__item summary {
  align-items: flex-start;
}
.faq-accordion__item summary > * {
  min-width: 0;
}

/* --- H2 uniform inside .section--aubergine + .section--ink (ensure white
   text everywhere, including pages that wrote `style="color:white"` inline) --- */
.section--aubergine .h2,
.section--aubergine h2,
.section--ink .h2,
.section--ink h2,
.stat-band .h2,
.stat-band h2 {
  color: var(--surface-white);
}
.section--aubergine .body,
.section--aubergine p:not(.eyebrow),
.section--ink .body,
.section--ink p:not(.eyebrow) {
  color: rgba(255, 255, 255, 0.92);
}

/* --- H2 fixed sizes site-wide (override clamp() if any subagent
   introduced one). main.css §3 ships fixed values; supplemental reasserts. --- */
.h2,
h2 {
  font-size: 1.75rem;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
@media (min-width: 768px) {
  .h2,
  h2 { font-size: 2rem; }
}
@media (min-width: 1024px) {
  .h2,
  h2 { font-size: 2.25rem; }
}

/* --- Container padding sane mobile baseline (override per-page drift).
   Patched 2026-06-02 (X-AXIS UNIFICATION): both `.container` and
   `.container--narrow` now use the canonical `--page-gutter` and
   `--page-max` tokens, so their left-edges align exactly. The 720px
   constraint moved onto the children via `.container--narrow > *`
   (see main.css §4). DO NOT reintroduce `.container--narrow {
   max-width: 720px }` here — it would re-center the narrow body and
   shift its left edge ~240px to the right of `.container`. --- */
.container,
.container--narrow {
  padding-inline: var(--page-gutter);
  max-width: var(--page-max);
}
.container--narrow > * {
  max-width: var(--container-narrow);
  margin-inline-start: 0;
}

/* --- Section uniform padding rhythm (covers `.section`, `.section--cream`,
   etc.). main.css §4 sets 64/96; this is a belt-and-suspenders for any
   page that wrote inline `padding-top:32px`. The override is intentional
   only on fundraise tax-note section; we leave that one alone via
   inline specificity — but ALL other sections get uniform padding. --- */
@media (min-width: 1024px) {
  .section {
    padding-top: var(--section-pad-desktop);
    padding-bottom: var(--section-pad-desktop);
  }
}

/* --- Hero short variants — uniform 60svh for short pages (faq, thanks,
   privacy, terms, photo-release, partners). --- */
/* Hero height duplicates removed 2026-06-02 — canonical 70svh for every
   non-home hero is now defined ONCE in main.css §9. Earlier duplicates
   here (.hero--short at 50svh desktop, .hero--faq at 35svh) were
   overriding main.css due to load order and producing inconsistent
   per-page hero heights. Single source of truth in main.css. */

/* --- Closing CTA on travel page specifically: defeat the inline `<style>`
   block that centered the content and applied a 60svh image bleed. --- */
section.closing-cta {
  min-height: auto !important;
  display: block !important;
}
section.closing-cta .closing-cta__content {
  padding-block: var(--space-8) !important;
}

/* --- legal TOC card — same width as legal body for visual harmony --- */
.legal-toc {
  margin-inline: 0;
}

/* End of section 23. */


/* ============================================================
   §24 CAROUSEL
   ------------------------------------------------------------
   Reusable rotating slide component. Markup contract:
     <section class="carousel" data-carousel data-autoplay="6000">
       <div class="carousel__track">
         <div class="carousel__slide is-active"> ... </div>
         ...
       </div>
       <button class="carousel__prev">‹</button>
       <button class="carousel__next">›</button>
       <div class="carousel__dots"></div>
     </section>
   Behaviour wired in /assets/js/carousel.js (IIFE, defensive nulls).
   ============================================================ */
.carousel {
  position: relative;
  width: 100%;
  overflow: hidden;
  outline: none;
}
.carousel:focus-visible {
  outline: 2px solid var(--brand-terracotta);
  outline-offset: 2px;
}

/* Slide stack: all slides occupy the same grid cell; fade controls which
   one is visible. opacity transition is the only animation. */
.carousel__track {
  position: relative;
  display: grid;
  grid-template-areas: "slide";
  width: 100%;
  aspect-ratio: 4 / 3;
}
@media (min-width: 768px) {
  .carousel__track {
    aspect-ratio: 16 / 9;
  }
}

.carousel__slide {
  grid-area: slide;
  position: relative;
  width: 100%;
  height: 100%;
  opacity: 0;
  visibility: hidden;
  transition: opacity 200ms ease, visibility 0s linear 200ms;
}
.carousel__slide.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity 200ms ease, visibility 0s linear 0s;
}
.carousel__slide picture,
.carousel__slide > img {
  display: block;
  width: 100%;
  height: 100%;
}
.carousel__slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Caption: bottom-pinned gradient backdrop for legibility, white text. */
.carousel__caption {
  position: absolute;
  inset: auto 0 0 0;
  padding: 1.5rem;
  color: var(--surface-white);
  background: linear-gradient(180deg, rgba(23, 20, 17, 0) 0%, rgba(23, 20, 17, 0.7) 100%);
}
.carousel__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.5rem;
  line-height: 1.15;
  margin: 0 0 var(--space-2);
  color: var(--surface-white);
}
.carousel__sub {
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.4;
  margin: 0;
  color: var(--surface-white);
}

/* Prev / Next buttons: circular aubergine, white glyph, hover lilac. */
.carousel__prev,
.carousel__next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--brand-aubergine);
  color: var(--surface-white);
  font-size: 1.5rem;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 2;
  transition: background-color 150ms ease;
}
.carousel__prev { left: 1rem; }
.carousel__next { right: 1rem; }
.carousel__prev:hover,
.carousel__next:hover {
  background: var(--brand-lilac);
  color: var(--brand-aubergine);
}
.carousel__prev:focus-visible,
.carousel__next:focus-visible {
  outline: 2px solid var(--brand-terracotta);
  outline-offset: 2px;
}

/* Dots: row of circles under the slide, aubergine outline, filled when active. */
.carousel__dots {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) 0 0;
}
.carousel__dots button {
  width: 12px;
  height: 12px;
  padding: 0;
  border: 2px solid var(--brand-aubergine);
  border-radius: var(--radius-pill);
  background: transparent;
  cursor: pointer;
  transition: background-color 150ms ease;
}
.carousel__dots button.is-active,
.carousel__dots button[aria-current="true"] {
  background: var(--brand-aubergine);
}
.carousel__dots button:focus-visible {
  outline: 2px solid var(--brand-terracotta);
  outline-offset: 2px;
}

/* Mobile: shrink the arrows so they don't crowd the slide. */
@media (max-width: 768px) {
  .carousel__prev,
  .carousel__next {
    width: 40px;
    height: 40px;
    font-size: 1.25rem;
  }
  .carousel__prev { left: 0.5rem; }
  .carousel__next { right: 0.5rem; }
  .carousel__caption {
    padding: 1rem;
  }
  .carousel__title {
    font-size: 1.25rem;
  }
  .carousel__sub {
    font-size: 0.9375rem;
  }
}

/* Reduced motion: cut the fade entirely. */
@media (prefers-reduced-motion: reduce) {
  .carousel__slide,
  .carousel__slide.is-active {
    transition: none;
  }
}

/* ----------------------------------------------------------------
   .carousel--small — narrower + shorter modifier.
   Used by the pilot 2025 carousel on the-race page so the slide
   fits on a 1080p laptop viewport (default 16/9 at 1200px = 675px
   tall, which combined with fixed nav (~80px) eats ~75% of the
   viewport). 800px / 3:2 = 533px tall, 800px / 4:3 mobile = 600px.
   Wildlife carousel keeps default sizing — Sam wants that one big.
   ---------------------------------------------------------------- */
.carousel--small {
  max-width: 800px;
  margin-inline: auto;
}
.carousel--small .carousel__track {
  aspect-ratio: 4 / 3;
}
@media (min-width: 768px) {
  .carousel--small .carousel__track {
    aspect-ratio: 3 / 2;
  }
}

/* End of section 24. */


/* ============================================================
   §25 HERO H1 TWO-LINE LAYOUT + ORANGE CTA VARIANT (2026-06-02)
   ------------------------------------------------------------
   Sam's ask: keep "on Mount Kenya" on a single line slightly
   smaller than "Yetu Triathlon", and add a terracotta-filled
   "Or donate" pill matching the Register pill shape.
   ============================================================ */

.hero__h1 {
  display: flex;
  flex-direction: column;
  gap: 0.15em;
}

.hero__h1-main {
  display: block;
  /* inherits .h1 font-size — this is the dominant line */
}

.hero__h1-sub {
  display: block;
  font-size: 0.62em;       /* ~62% of the main H1 size */
  font-weight: 500;        /* lighter than the main 900 */
  line-height: 1.1;
  letter-spacing: -0.01em;
  opacity: 0.95;
  white-space: nowrap;     /* keep "on Mount Kenya" intact */
}

/* Orange (terracotta-filled) primary button — same as the new site-wide
   .btn--primary default, kept for legacy class usage. Hover → aubergine. */
.btn--primary.btn--primary-orange {
  background: var(--brand-terracotta) !important;
  color: var(--surface-white) !important;
}
.btn--primary.btn--primary-orange:hover,
.btn--primary.btn--primary-orange:focus-visible {
  background: var(--brand-aubergine) !important;
}

/* Purple (aubergine-filled) primary button — for secondary CTAs that
   need to contrast against the orange site-wide default. Hover → orange. */
.btn--primary.btn--primary-purple {
  background: var(--brand-aubergine) !important;
  color: var(--surface-white) !important;
}
.btn--primary.btn--primary-purple:hover,
.btn--primary.btn--primary-purple:focus-visible {
  background: var(--brand-terracotta) !important;
}

/* End of section 25. */


/* ============================================================
   §26 INTERACTIVE MAPS (Leaflet, embedded)
   ------------------------------------------------------------
   .interactive-map gets explicit height — Leaflet renders into a
   div via its own internal sizing and CANNOT determine the
   container's height on its own. Without this rule the map ends
   up 0px tall and appears missing.

   .elevation-profile likewise needs a fixed height for the
   leaflet-elevation chart to render.

   Both are MOBILE-FIRST: ~360px on phones (small but usable),
   bumped to 520px on tablet+ and 640px on widescreens.
   ============================================================ */
.interactive-map {
  width: 100%;
  height: 360px;
  margin-top: var(--space-4);
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--surface-cream);  /* placeholder while tiles load */
  border: 1px solid rgba(23, 20, 17, 0.08);
}
@media (min-width: 768px) {
  .interactive-map {
    height: 520px;
  }
}
@media (min-width: 1200px) {
  .interactive-map {
    height: 640px;
  }
}

.elevation-profile {
  width: 100%;
  min-height: 180px;
  margin-top: var(--space-3);
}
@media (min-width: 768px) {
  .elevation-profile {
    min-height: 220px;
  }
}

/* Ensure Leaflet popups and controls inherit reasonable typography. */
.leaflet-popup-content {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.45;
  margin: 12px 14px;
}
.leaflet-popup-content strong {
  font-family: var(--font-heading);
  font-weight: 600;
}
.leaflet-container {
  font-family: var(--font-body);
}

/* End of section 26. */


/* ============================================================
   §27 BULLET-LIST (SITE-WIDE)
   ------------------------------------------------------------
   Square-marker list, originally page-local to travel-and-logistics.
   Lifted here so every page can use the same style: aubergine square
   markers + ink text on cream sections; lilac square markers + white
   text on aubergine sections.

   Sam's preferred bullet style across the whole site.
   ============================================================ */
.bullet-list {
  list-style: none;
  padding: 0;
  margin: var(--space-4) 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.bullet-list li {
  position: relative;
  padding-left: 22px;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--surface-ink);
}
.bullet-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 8px;
  height: 8px;
  background: var(--brand-aubergine);
}
.bullet-list a {
  color: var(--brand-aubergine);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.bullet-list a:hover,
.bullet-list a:focus-visible {
  color: var(--brand-terracotta);
}
.bullet-list strong { font-weight: 700; }

/* On aubergine sections, flip text + markers + links so they read on the
   dark purple background. */
.section--aubergine .bullet-list li { color: var(--surface-white); }
.section--aubergine .bullet-list li::before { background: var(--brand-lilac); }
.section--aubergine .bullet-list a { color: var(--brand-lilac); }
.section--aubergine .bullet-list a:hover,
.section--aubergine .bullet-list a:focus-visible { color: var(--surface-white); }

/* End of section 27. */


/* ============================================================
   §28 FAQ HERO HEIGHT OVERRIDE
   ------------------------------------------------------------
   FAQ page is utilitarian — content starts immediately, no need
   for a 45svh hero. Shrink to ~28svh so "Event basics" appears
   right under the subtitle. !important to beat the site-wide
   .hero--faq, ... { min-height: 45svh !important } rule.
   ============================================================ */
.hero--faq {
  min-height: 18svh !important;
}

/* End of section 28. */


/* ============================================================
   §29 BECOME-A-FRIEND INLINE LINK
   ------------------------------------------------------------
   Plain underline by default, aubergine (purple) on hover.
   Used inline in the "Become a Partner" body on partners.html.
   ============================================================ */
.link-friends {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  font-weight: 500;
}
.link-friends:hover,
.link-friends:focus-visible {
  color: var(--brand-aubergine);
}

/* End of section 29. */


/* ============================================================
   §30 NATIVE REGISTRATION FORM
   ------------------------------------------------------------
   Form lives in register.html §5, posts to /api/register
   (Cloudflare Pages Function backed by D1).
   Sits inside .section--cream so default text colour is ink.
   ============================================================ */

.register-form {
  margin-top: var(--space-6);
  max-width: 720px;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* Honeypot — hide visually + from AT, keep focusable for bots */
.register-form__honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.register-form__group {
  background: var(--surface-white);
  border: 0;
  border-radius: var(--radius-card);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.register-form__legend {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: var(--fs-h3, 22px);
  color: var(--brand-aubergine);
  padding: 0;
  margin-bottom: var(--space-2);
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.form-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}
@media (min-width: 640px) {
  .form-row { grid-template-columns: 1fr 1fr; }
}

.form-field > label,
.form-field > label:not(.form-radio):not(.form-check) {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 15px;
  color: var(--surface-ink);
}

.form-required {
  color: var(--brand-terracotta);
  font-weight: 700;
}

.form-help {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--ink-muted, rgba(23, 20, 17, 0.65));
  line-height: 1.45;
  margin: 0;
}

.register-form input[type="text"],
.register-form input[type="email"],
.register-form input[type="tel"],
.register-form input[type="date"],
.register-form textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: 16px; /* ≥16px stops iOS zoom on focus */
  line-height: 1.4;
  color: var(--surface-ink);
  background: var(--surface-cream);
  border: 1px solid rgba(23, 20, 17, 0.15);
  border-radius: 8px;
  padding: 12px 14px;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.register-form input:focus,
.register-form textarea:focus {
  outline: none;
  border-color: var(--brand-aubergine);
  box-shadow: 0 0 0 3px rgba(88, 14, 65, 0.15);
}

.register-form textarea {
  resize: vertical;
  min-height: 80px;
}

/* Field error state — applied to .form-field wrapper */
.form-field.has-error > label { color: var(--brand-terracotta); }
.form-field.has-error input,
.form-field.has-error textarea {
  border-color: var(--brand-terracotta);
  box-shadow: 0 0 0 3px rgba(195, 73, 34, 0.12);
}

/* ---- Radio group (race choice + altitude yes/no) ---- */
.form-radio-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.form-radio-group--inline {
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.form-radio {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  background: var(--surface-cream);
  border: 1px solid rgba(23, 20, 17, 0.15);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}
.form-radio:hover { border-color: var(--brand-aubergine); }
.form-radio input[type="radio"] {
  margin: 4px 0 0;
  accent-color: var(--brand-aubergine);
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
.form-radio input[type="radio"]:checked + .form-radio__label,
.form-radio:has(input[type="radio"]:checked) {
  border-color: var(--brand-aubergine);
  background: rgba(88, 14, 65, 0.04);
}
.form-radio__label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--surface-ink);
}
.form-radio__label strong { font-weight: 700; }
.form-radio__sub {
  font-size: 13px;
  color: var(--ink-muted, rgba(23, 20, 17, 0.7));
}

.form-radio--inline {
  padding: 8px 14px;
  background: transparent;
  border: 1px solid rgba(23, 20, 17, 0.2);
  align-items: center;
}
.form-radio--inline span { font-size: 15px; }

/* ---- Checkbox group (dietary, gear) + stacked consent ---- */
.form-check-group {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
}
@media (min-width: 640px) {
  .form-check-group { grid-template-columns: 1fr 1fr; }
}

.form-check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--surface-ink);
  cursor: pointer;
  line-height: 1.45;
}
.form-check input[type="checkbox"] {
  margin: 3px 0 0;
  accent-color: var(--brand-aubergine);
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
.form-check a {
  color: var(--brand-aubergine);
  text-decoration: underline;
}
.form-check--stacked {
  padding: var(--space-3) 0;
  border-bottom: 1px solid rgba(23, 20, 17, 0.08);
}
.form-check--stacked:last-child { border-bottom: 0; }

/* ---- Submit row ---- */
.register-form__submit {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: flex-start;
  margin-top: var(--space-3);
}
.register-form__btn {
  min-width: 220px;
}

.form-status {
  font-family: var(--font-body);
  font-size: 14px;
  margin: 0;
  color: var(--surface-ink);
}
.form-status[data-kind="error"] {
  color: var(--brand-terracotta);
  font-weight: 600;
}

/* End of section 30. */


/* ============================================================
   §31 EXPEDITION CHAPTERS (travel-and-logistics §2)
   ------------------------------------------------------------
   Editorial chapter-stack replacing the old trip-arc.
   Two-column grid at ≥960px: chapters left, sticky route-map right.
   Single column below 960px; map hidden on small screens.
   ============================================================ */

.chapters {
  margin-top: var(--space-6);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}

.chapters__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.chapter {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--space-4);
  padding: var(--space-2) 0 var(--space-6) var(--space-4);
  border-left: 1px solid var(--brand-aubergine);
}

.chapter:last-child {
  padding-bottom: var(--space-2);
}

.chapter__numeral {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 44px;
  line-height: 1;
  color: var(--brand-aubergine);
  align-self: start;
  margin: 0;
  min-width: 0;
  font-variant-numeric: lining-nums;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.chapter__numeral--small {
  font-size: 36px;
  line-height: 1;
}

.chapter__node {
  position: absolute;
  left: -6px;
  top: 0.6rem;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid var(--brand-lilac);
  transition: background 200ms ease, border-color 200ms ease;
}

.chapter.is-active .chapter__node {
  background: var(--brand-terracotta);
  border-color: var(--brand-terracotta);
}

.chapter__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-top: var(--space-2);
}

.chapter__day {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--brand-aubergine);
  margin: 0;
}

.chapter__eyebrow {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--brand-terracotta);
  margin: 0;
}

.chapter__headline {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 22px;
  line-height: 1.25;
  color: var(--surface-ink);
  margin: 0;
  max-width: 28ch;
}

.chapter__body {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--surface-ink);
  margin: 0;
  max-width: 52ch;
}

.chapter__meta {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.chapter__meta li {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  background: transparent;
  border: 1px solid var(--brand-aubergine);
  border-radius: 999px;
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand-aubergine);
}

.chapter--optional {
  border-left-style: dashed;
  border-left-color: var(--brand-lilac);
}

.chapter--optional .chapter__numeral,
.chapter--optional .chapter__day,
.chapter--optional .chapter__eyebrow {
  color: var(--brand-lilac);
}

.chapter--optional .chapter__node {
  border-color: var(--brand-lilac);
}

.chapter__map-strip {
  display: none;
}

.chapters__aside {
  display: none;
}

.routemap {
  width: 100%;
  height: auto;
  max-height: 80vh;
  display: block;
}

.routemap__path {
  fill: none;
  stroke: var(--brand-aubergine);
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.routemap__contour {
  fill: none;
  stroke: var(--brand-aubergine);
  stroke-width: 0.6;
  opacity: 0.18;
}

.routemap__ridge {
  fill: none;
  stroke: var(--brand-aubergine);
  stroke-width: 0.8;
  stroke-linecap: round;
  opacity: 0.35;
}

.routemap__route {
  fill: none;
  stroke: var(--brand-terracotta);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.45;
  transition: opacity 400ms ease, stroke-width 400ms ease;
}

.routemap__route.is-active {
  opacity: 1;
  stroke-width: 2.6;
}

/* Roads (off-mountain, dashed, terracotta) */
.routemap__route--road {
  stroke: var(--brand-terracotta);
  stroke-width: 1.2;
  stroke-dasharray: 4 3;
  opacity: 0.35;
}
.routemap__route--road.is-active {
  opacity: 1;
  stroke-width: 2;
}

/* Triathlon segments (lilac, lights up on Day 4 chapter) */
.routemap__route--triathlon {
  stroke: var(--brand-lilac);
}
.routemap__route--triathlon.is-active {
  stroke: var(--brand-lilac);
}

.routemap__node {
  fill: var(--surface-cream);
  stroke: var(--brand-aubergine);
  stroke-width: 1.2;
}

.routemap__node--summit {
  fill: var(--brand-terracotta);
  stroke: var(--brand-terracotta);
}

.routemap__node--town {
  fill: var(--surface-cream);
  stroke: var(--brand-aubergine);
  stroke-width: 1.2;
  stroke-dasharray: 1.5 1.5;
}

.routemap__node--triathlon {
  fill: var(--surface-cream);
  stroke: var(--brand-lilac);
  stroke-width: 1.4;
}

.routemap__label {
  font-family: var(--font-heading);
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  fill: var(--brand-aubergine);
}

.routemap__title {
  font-family: var(--font-display);
  font-size: 14px;
  fill: var(--brand-aubergine);
}

.routemap__compass {
  font-family: var(--font-heading);
  font-size: 8px;
  letter-spacing: 0.1em;
  fill: var(--brand-aubergine);
  opacity: 0.6;
}

@media (prefers-reduced-motion: reduce) {
  .chapter__node,
  .routemap__route {
    transition: none;
  }
}

@media (min-width: 960px) {
  .chapters {
    grid-template-columns: minmax(0, 6fr) minmax(0, 4fr);
    column-gap: var(--space-7);
    align-items: start;
  }
  .chapters__aside {
    display: block;
    position: sticky;
    top: 100px;
    max-height: calc(100vh - 120px);
  }
  .chapter {
    padding-left: var(--space-5);
  }
}

/* End of section 31. */


/* ============================================================
   §32 ATHLETES GRID (athletes.html)
   ------------------------------------------------------------
   Editorial cohort grid. 3-col desktop / 2 tablet / 1 mobile.
   Cut-out portraits over alternating aubergine/terracotta panels.
   Click-to-inline-expand bio. TBD silhouettes link to register.
   ============================================================ */

.athletes-grid {
  list-style: none;
  margin: var(--space-6) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}
@media (min-width: 640px) {
  .athletes-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .athletes-grid { grid-template-columns: repeat(3, 1fr); gap: var(--space-5); }
}

.athlete {
  position: relative;
  display: flex;
  flex-direction: column;
  transition: grid-column 250ms ease;
}

.athlete__trigger {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  padding: 0;
  border: 0;
  border-radius: var(--radius-card, 14px);
  overflow: hidden;
  background: var(--brand-aubergine);
  color: var(--surface-cream);
  text-decoration: none;
  cursor: pointer;
  transition: transform 250ms cubic-bezier(0.2, 0.8, 0.2, 1),
              box-shadow 250ms ease,
              background 200ms ease;
}

.athlete--terracotta .athlete__trigger { background: var(--brand-terracotta); }
.athlete--aubergine  .athlete__trigger { background: var(--brand-aubergine); }

/* Hover lift + slight tilt — desktop only */
@media (hover: hover) {
  .athlete__trigger:hover {
    transform: translateY(-6px) rotate(-0.5deg);
    box-shadow: 0 12px 30px rgba(195, 73, 34, 0.18);
  }
  .athlete:nth-child(even) .athlete__trigger:hover {
    transform: translateY(-6px) rotate(0.5deg);
  }
  .athlete__trigger:hover .athlete__image {
    filter: saturate(1.08);
  }
}

.athlete__trigger:focus-visible {
  outline: 2px solid var(--brand-lilac);
  outline-offset: 3px;
}

.athlete__media {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-top: 12%;
}

.athlete__image {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: bottom center;
  filter: drop-shadow(0 8px 14px rgba(23, 20, 17, 0.28));
  transition: filter 250ms ease, transform 250ms ease;
}

.athlete__silhouette {
  width: 60%;
  height: auto;
  color: var(--brand-lilac);
  opacity: 0.55;
  filter: none;
}

.athlete__caption {
  position: absolute;
  left: var(--space-3);
  bottom: var(--space-3);
  right: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 2;
  pointer-events: none;
  text-align: left;
}

.athlete__name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.1rem, 1.6vw, 1.4rem);
  line-height: 1.05;
  color: var(--surface-cream);
}

.athlete__badge {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brand-lilac);
}

.athlete--terracotta .athlete__badge { color: var(--surface-cream); opacity: 0.85; }

/* Bio panel — hidden by default, revealed when card is .is-open */
.athlete__bio {
  margin-top: var(--space-3);
  padding: var(--space-4);
  background: var(--surface-white, #ffffff);
  border-left: 3px solid var(--brand-terracotta);
  border-radius: 8px;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--surface-ink);
}

.athlete__bio[hidden] { display: none; }

.athlete.is-open .athlete__trigger {
  transform: none;
  box-shadow: 0 6px 18px rgba(88, 14, 65, 0.22);
}

@media (min-width: 1024px) {
  .athlete.is-open { grid-column: span 2; }
  .athlete.is-open .athlete__trigger {
    aspect-ratio: 8 / 5;
  }
}

/* TBD silhouette tiles — link to /register, dimmer treatment */
.athlete--tbd .athlete__trigger {
  background: var(--brand-aubergine);
  opacity: 0.85;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.athlete--tbd.athlete--terracotta .athlete__trigger { background: var(--brand-terracotta); }

.athlete--tbd .athlete__trigger::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(
      45deg,
      transparent 0 12px,
      rgba(255,255,255,0.04) 12px 24px
    );
  pointer-events: none;
}

.athlete--tbd .athlete__media {
  position: relative;
  inset: auto;
  padding-top: 0;
  height: 100%;
  width: 100%;
  align-items: center;
  justify-content: center;
}

.athlete--tbd .athlete__name { color: var(--surface-cream); opacity: 0.85; }
.athlete--tbd .athlete__badge { color: var(--brand-lilac); }

.athlete--tbd .athlete__trigger:hover {
  opacity: 1;
}

/* Note + CTA blocks at the section bottom */
.athletes-grid__note {
  margin-top: var(--space-4);
  font-family: var(--font-body);
  font-size: var(--fs-small);
  color: var(--ink-muted, rgba(23, 20, 17, 0.6));
  text-align: center;
}
.athletes-grid__note a {
  color: var(--brand-aubergine);
  text-decoration: underline;
}
.section--aubergine .athletes-grid__note { color: var(--brand-lilac); }

.athletes-grid__cta {
  margin-top: var(--space-5);
  display: flex;
  justify-content: center;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .athlete,
  .athlete__trigger,
  .athlete__image {
    transition: none;
  }
  .athlete__trigger:hover {
    transform: none;
  }
}

/* Nav: Athletes menu-item in the right-side cluster — just inherits the
   default .nav__menu-item styling. Only spacing adjustment lives here. */
.nav__menu-item--athletes {
  margin-right: var(--space-3);
}

/* End of section 32. */


/* ============================================================
   §33 MOBILE-ONLY OPTIMIZATIONS (sitewide audit pass)
   ------------------------------------------------------------
   All rules scoped to @media queries. Desktop layout untouched.
   Synthesis of per-page mobile audits — addresses tap targets,
   stat-band overflow, h2 nowrap, section padding, hero CTAs,
   compare cards, the-race accordion, calculator, athletes,
   register form, gallery, faq, thank-you pages, 404.
   ============================================================ */

/* ---- (a) Allow long h2s with inline white-space:nowrap to wrap on small screens.
   Targets index/the-race AT-A-GLANCE, fundraise goal, etc. ---- */
@media (max-width: 768px) {
  h2[style*="nowrap"],
  .h2[style*="nowrap"],
  h2[style*="white-space"] {
    white-space: normal !important;
  }
}

/* ---- (b) Stat-band — wrap earlier and tighten gap on small phones ---- */
@media (max-width: 640px) {
  .stat-band__grid {
    flex-wrap: wrap !important;
    gap: var(--space-4) !important;
    justify-content: center !important;
  }
}
@media (max-width: 480px) {
  .stat-band__grid {
    gap: var(--space-3) !important;
  }
  .stat-band__item {
    flex: 1 1 calc(50% - 12px) !important;
    min-width: 0 !important;
    text-align: center;
  }
}

/* ---- (c) Counter numbers — tabular figures for stable digit widths.
   counter.js handles the actual min-width reservation; this just locks
   digit widths so the animation looks tidy and digits align. ---- */
@media (max-width: 768px) {
  [data-counter-target] {
    font-variant-numeric: tabular-nums;
  }
}

/* ---- (d) Primary buttons — bump tap target to 48px on mobile ---- */
@media (max-width: 768px) {
  .btn {
    padding: 14px 26px;
    min-height: 48px;
  }
}

/* ---- (e) Hero CTAs — stack vertical full-width on small phones ---- */
@media (max-width: 480px) {
  .hero__cta {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
  }
  .hero__cta .btn,
  .hero__cta > .btn {
    width: 100%;
  }
}

/* ---- (f) Section padding — tighten on smallest phones (<480px) ---- */
@media (max-width: 480px) {
  :root {
    --section-pad-mobile: 48px;
  }
  .section {
    padding-block: 48px;
  }
}

/* ---- (g) Compare cards (the-race "Included / Not included") ---- */
@media (max-width: 480px) {
  .compare > *,
  .compare__col {
    flex: 1 1 100% !important;
    min-width: 0 !important;
  }
}

/* ---- (h) Pillar cards — drop the 480px desktop min-height on mobile ---- */
@media (max-width: 768px) {
  .pillar-card {
    min-height: auto;
  }
}

/* ---- (i) The Race — race toggle tabs + Leaflet height ---- */
@media (max-width: 768px) {
  .race-toggle__tab {
    padding: 12px 18px;
    min-height: 44px;
  }
  .interactive-map,
  #map,
  .map-leaflet {
    height: clamp(280px, 50vh, 360px);
  }
}

/* ---- (j) Day-by-day accordion — text wrap on narrow phones ---- */
@media (max-width: 480px) {
  .day-accordion__date,
  .day-accordion__preview {
    word-break: break-word;
    font-size: clamp(0.875rem, 3vw, 1rem);
  }
}

/* ---- (k) Fundraise — calculator input + tips list compression ---- */
@media (max-width: 480px) {
  .calculator__input {
    font-size: 22px !important;
  }
  .calculator__input-prefix {
    font-size: 18px !important;
  }
}

/* ---- (l) Athletes — CTA full-width + badge contrast + tighter top margin ---- */
@media (max-width: 640px) {
  .athletes-grid {
    margin-top: var(--space-4);
  }
  .athletes-grid__cta .btn {
    width: 100%;
  }
}
/* Badge contrast on terracotta tiles — both desktop and mobile (visual fix) */
.athlete--terracotta .athlete__badge {
  opacity: 1;
  color: var(--brand-lilac);
}

/* ---- (m) Register — submit button full-width + stat-band wrap override.
   The page has inline style="flex-wrap: nowrap..." on the stat-band; we
   override only on mobile so desktop keeps its single-row layout. ---- */
@media (max-width: 640px) {
  .register-form__btn {
    width: 100%;
  }
  .register-form__submit {
    align-items: stretch !important;
  }
  .stat-band__grid[style*="nowrap"] {
    flex-wrap: wrap !important;
    justify-content: center !important;
  }
}

/* ---- (n) Gallery (admin) — 1-col grid on small phones + stack actions ---- */
@media (max-width: 480px) {
  .photo-grid {
    grid-template-columns: 1fr !important;
    gap: 8px !important;
  }
  .slot-panel-actions {
    flex-direction: column !important;
    gap: 8px !important;
  }
  .slot-panel-actions .btn,
  .slot-panel-actions button {
    width: 100% !important;
  }
  .slot-clear {
    width: 32px !important;
    height: 32px !important;
    font-size: 16px !important;
  }
}

/* ---- (o) FAQ summary — bigger tap target on mobile ---- */
@media (max-width: 768px) {
  .faq-accordion summary,
  details.faq-accordion__item > summary {
    padding-block: 14px;
    min-height: 48px;
  }
}

/* ---- (p) Thank-you pages — step number scaling ---- */
@media (max-width: 480px) {
  .step__number,
  .step-grid__number,
  .step-grid li > span:first-child {
    font-size: 2.5rem;
  }
  .steps-grid,
  .step-grid {
    gap: 20px;
  }
}

/* ---- (q) 404 — h3 link sizing on narrow phones ---- */
@media (max-width: 375px) {
  .error-links .h3,
  .error-links h3 {
    font-size: 18px;
  }
}

/* ---- (r) Travel page — extension link tap target on mobile ---- */
@media (max-width: 768px) {
  .extension-tile__link,
  .extension-tile__cta {
    display: inline-block;
    padding: 8px 0;
    min-height: 44px;
    line-height: 28px;
  }
}

/* ---- (s) Athletes scroll-into-view — make sure expanded card lands at top
   (the inline JS uses block:'nearest'; on small phones we want block:'start').
   This rule alone can't change JS behaviour, so it's a hint via CSS:
   add scroll-margin-top so 'nearest' lands below the sticky nav. ---- */
@media (max-width: 768px) {
  .athlete.is-open {
    scroll-margin-top: 80px;
  }
}

/* End of section 33. */


/* ============================================================
   §34 NAV MOBILE FIX (top-nav overflow on phones)
   ------------------------------------------------------------
   Bug (2026-06-02): On phones the top nav shifted right and the
   "Athletes" link ran off the viewport. Root cause: `.nav__right`
   contains THREE elements that all remain visible below the
   1024px desktop breakpoint — the Athletes link, the Register
   CTA, and the hamburger button. Combined with the §33 bump that
   gave every `.btn` 14px 26px padding + 48px min-height, the
   right cluster exceeded the viewport width at 375px.

   Fix strategy (mobile only, no desktop changes):
     1. Hide the duplicate Athletes link in `.nav__right` below
        1024px (the same breakpoint where the hamburger appears
        in main.css around L2122-2126). The mobile drawer already
        exposes Athletes, so this is purely dedup.
     2. Shrink `.nav__cta` so the §33 .btn padding bump does NOT
        balloon the in-nav Register button. Override the §33
        global .btn bump for `.nav__cta` only.
     3. Guard `.nav__inner` against horizontal overflow
        (defensive: min-width:0 + flex-wrap allowance).
     4. Keep hamburger at its 44x44 hit target — leave alone.

   All rules scoped to @media (max-width: 1023.98px). Above
   1024px nothing in this section applies; desktop is byte-for-byte
   unchanged.
   ============================================================ */

@media (max-width: 1023.98px) {

  /* (1) Hide the duplicate Athletes link in the right cluster.
     The mobile drawer (`.mobile-drawer`) already lists Athletes,
     so showing it twice on phones is redundant AND the primary
     cause of horizontal overflow. */
  .nav__right .nav__menu-item--athletes {
    display: none !important;
  }

  /* (2) Re-tighten the in-nav Register CTA. §33's global .btn
     bump (padding 14px 26px, min-height 48px) is appropriate for
     hero/section CTAs but too large for a nav-bar pill. Restore
     the original .nav__cta dimensions (10px 22px) at the nav
     scope only — body CTAs keep the 48px tap target. */
  .nav__cta,
  .nav .nav__cta,
  .nav__right .nav__cta {
    padding: 10px 18px !important;
    min-height: 0 !important;
    font-size: 14px;
    line-height: 1.2;
  }

  /* (3) Defensive overflow guards. `.nav__inner` is a flex row;
     if any child (e.g. a long logo) tries to push the row wider
     than the viewport, min-width:0 lets flex shrink them first
     instead of producing a horizontal scrollbar. */
  .nav__inner {
    min-width: 0;
    flex-wrap: nowrap;
  }
  .nav__logo,
  .nav__right {
    min-width: 0;
  }
  /* Right cluster: tighten the gap on phones so logo + CTA +
     hamburger fit comfortably at 375px. */
  .nav__right {
    gap: var(--space-2);
  }
}

/* ---- Narrow phones (<=480px): if Register still feels tight,
   nudge font/padding down one more notch. This is opt-in — the
   1024px block above is the load-bearing fix; this is polish. ---- */
@media (max-width: 480px) {
  .nav__cta,
  .nav .nav__cta,
  .nav__right .nav__cta {
    padding: 9px 14px !important;
    font-size: 13px;
  }
}

/* End of section 34. */


/* ============================================================
   §35 HERO MOBILE FIX (2026-06-02)
   ------------------------------------------------------------
   Sam: "The hero's are off" on mobile.
   Root causes addressed:
     1. .hero__h1-sub has `white-space: nowrap` (set in §25 for
        "on Mount Kenya"). On <=375px viewports the 0.62em sub
        renders ~24-25px and 14-char string flirts with overflow.
     2. Display font (Cosmic Buns) at the mobile token --fs-h1:40px
        leaves no slack for the longest single-token H1 lines
        ("Frequently Asked Questions" wraps OK, but the home main
        line "Yetu Triathlon" needs to feel anchored, not pinned
        against the gutter edge).
     3. .hero__content has hard `padding-top: 80px` to clear the
        fixed nav, but no `env(safe-area-inset-*)` allowance for
        iOS notch / home-indicator on full-bleed heroes.
     4. .hero__image uses `object-position: center` — on portrait
        viewports our mountain photos crop the peak out of frame;
        biasing upward keeps the subject visible.
     5. .hero__overlay gradient (main.css §6) is tuned for desktop
        landscape; on portrait the lower-third where text sits is
        less covered, so legibility against bright sky drops.
   Scope: mobile only (<=768px primary, <=480px tighter). Zero
   desktop changes. No HTML touched. No .hero--gallery rules.
   ============================================================ */

/* ---- (a) H1 sizing — clamp the home two-line layout so neither
   the main line nor the "on Mount Kenya" sub overflows on the
   narrowest phones. Also allow the sub to wrap as a last resort
   instead of blowing past the gutter. ---- */
@media (max-width: 768px) {
  .hero__h1 {
    /* tighter inter-line gap on small heroes */
    gap: 0.1em;
    /* belt-and-suspenders: keep H1 inside the content column */
    max-width: 100%;
  }
  .hero__h1-main {
    /* shrink "Yetu Triathlon" gracefully on small phones — fluid
       between 32px (320px viewport) and 40px (768px viewport).
       Below the canonical 40px mobile token only at <375px. */
    font-size: clamp(32px, 9.5vw, 40px);
    line-height: 1.02;
    letter-spacing: -0.02em;
  }
  .hero__h1-sub {
    /* allow wrap on tiny phones; preserve nowrap intent above 480 */
    font-size: clamp(20px, 6vw, 26px);
    line-height: 1.1;
  }
}

/* ---- (b) Narrow phones (<=480px): drop the §25 nowrap so the
   sub line can break onto two lines if the device is unusually
   narrow (older iPhone SE = 320px). Single-line preferred but
   wrap is better than overflow. ---- */
@media (max-width: 480px) {
  .hero__h1-sub {
    white-space: normal;
  }
  /* Non-home hero H1s (single-line headings like "Frequently Asked
     Questions", "The Race", "Travel & Logistics") — clamp the
     site-wide .h1/.hero__h1 size so long titles stay inside the
     327px content column without forcing 3-line wraps. */
  .hero__h1:not(:has(.hero__h1-main)) {
    font-size: clamp(30px, 8.5vw, 38px);
    line-height: 1.06;
  }
}

/* ---- (c) Hero content padding — respect iOS safe areas on
   full-bleed heroes (notch top, home-indicator bottom). The
   80px nav clearance stays; we ADD the env() value on top. ---- */
@media (max-width: 768px) {
  .hero__content {
    padding-top: calc(80px + env(safe-area-inset-top, 0px));
    padding-bottom: calc(var(--space-7) + env(safe-area-inset-bottom, 0px));
    /* Keep left/right gutter aligned with rest of page but ensure
       no child can punch past it (e.g. a long unbroken token). */
    min-width: 0;
  }
  .hero__content > * {
    /* main.css caps children at 720px — on mobile clamp to 100% so
       nothing escapes the gutter regardless. */
    max-width: 100%;
    min-width: 0;
  }
  /* hero__sub readability: bump line-height a touch + add a faint
     text-shadow on photo heroes (skipped on cream/faq below). */
  .hero__sub {
    font-size: 15px;
    line-height: 1.5;
  }
}

/* ---- (d) Hero image cropping — bias upward on portrait so the
   peak / subject stays in frame. Desktop unchanged (default
   `center` from main.css applies above 768px). ---- */
@media (max-width: 768px) {
  .hero__image,
  .hero .hero__image img,
  .hero__image > img {
    object-position: center 35%;
  }
}

/* ---- (e) Hero overlay — darken on photo heroes for mobile
   legibility. Cream / faq / thanks / 404 heroes already hide the
   overlay (main.css §6) so they are untouched. ---- */
@media (max-width: 768px) {
  .hero__overlay {
    background:
      radial-gradient(ellipse at 30% 75%, rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0.25) 65%),
      linear-gradient(180deg, rgba(0, 0, 0, 0.15) 0%, rgba(0, 0, 0, 0.6) 100%);
  }
}

/* ---- (f) Text shadow only on photo heroes (skip cream variants
   so the ink-on-cream pages don't get a blur halo). ---- */
@media (max-width: 768px) {
  .hero:not(.hero--cream):not(.hero--faq):not(.hero--thanks):not(.hero--404):not(.section--cream) .hero__h1,
  .hero:not(.hero--cream):not(.hero--faq):not(.hero--thanks):not(.hero--404):not(.section--cream) .hero__sub {
    text-shadow: 0 1px 12px rgba(0, 0, 0, 0.35);
  }
}

/* ---- (g) Home hero specifically (100svh) — guarantee the CTA
   block sits above the iOS home-indicator gesture area, and
   never gets pinched by the bottom padding on tall phones.
   §33 already stacks the two home CTAs vertical full-width
   below 480px; we just ensure breathing room. ---- */
@media (max-width: 768px) {
  .hero--home .hero__content {
    padding-bottom: calc(var(--space-7) + env(safe-area-inset-bottom, 0px) + 12px);
  }
}

/* ---- (h) FAQ hero (18svh override from §28) — on phones that's
   only ~150px tall which crushes the H1 + sub. Bump to a usable
   floor without going near the 45svh secondary default. ---- */
@media (max-width: 768px) {
  .hero--faq {
    min-height: clamp(180px, 28svh, 240px) !important;
  }
}

/* End of section 35. */


/* ============================================================
   §36 DONATION GRID — variant of §32 athletes-grid (donate.html)
   ------------------------------------------------------------
   Anchor-based tile (not button) — each card links to a per-athlete
   donate page. Adds a raised-amount line + thin progress bar under
   the existing name/badge caption. Also styles the recent-donations
   ticker strip and the overall-total counter context.
   ============================================================ */

/* Anchor variant of .athlete__trigger. Inherits all visual rules from
   §32 — we only need to make sure the anchor element behaves like the
   button (no underline, cursor pointer). */
.athlete__trigger--donate {
  text-decoration: none;
  cursor: pointer;
  color: inherit;
}
.athlete__trigger--donate:hover,
.athlete__trigger--donate:focus-visible {
  text-decoration: none;
}

/* Tiny "raised so far" line, sits just above the progress bar. */
.athlete__raised {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--brand-lilac);
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
.athlete--terracotta .athlete__raised {
  color: var(--surface-cream);
  opacity: 0.9;
}

/* Progress bar — CSS custom property drives the fill width. */
.athlete__progress {
  --progress: 0%;
  height: 6px;
  width: 100%;
  margin-top: 8px;
  background: rgba(234, 170, 255, 0.25);
  border-radius: 3px;
  overflow: hidden;
  position: relative;
}
.athlete__progress::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--brand-terracotta), var(--brand-aubergine));
  border-radius: 3px;
  width: var(--progress);
  transition: width 800ms cubic-bezier(0.16, 1, 0.3, 1);
}
.athlete--terracotta .athlete__progress {
  background: rgba(255, 255, 255, 0.30);
}
.athlete--terracotta .athlete__progress::after {
  background: var(--surface-cream);
}

/* Recent donations ticker — thin editorial strip. */
.donations-ticker {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  border-top: 1px solid var(--surface-ink);
  border-bottom: 1px solid var(--surface-ink);
  padding-block: var(--space-4);
}
.donations-ticker li,
.donations-ticker__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  color: var(--surface-ink);
}
.donations-ticker__name { font-weight: 600; }
.donations-ticker__athlete { color: var(--brand-aubergine); font-weight: 600; }
.donations-ticker__amount {
  color: var(--brand-terracotta);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.donations-ticker__time {
  color: var(--ink-muted, rgba(23,20,17,0.6));
  font-size: 13px;
}
.donations-ticker__empty {
  justify-content: center;
  color: var(--ink-muted);
  font-style: italic;
}

/* Mobile: only 3 rows visible. Desktop: 5 rows. Beyond 5 = always hidden. */
.donations-ticker__row--desktop-hidden { display: none; }
@media (max-width: 720px) {
  .donations-ticker__row--mobile-hidden { display: none; }
}
@media (max-width: 480px) {
  .donations-ticker li,
  .donations-ticker__row { flex-wrap: wrap; }
  .donations-ticker__time { flex-basis: 100%; }
}

/* Overall raised line — sits above/under the §3 strip CTAs. */
.donate-overall {
  margin-top: var(--space-4);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.donate-overall .js-overall-total {
  color: var(--brand-terracotta);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* "Where the money goes" three-up. */
.money-grid {
  margin-top: var(--space-5);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}
@media (min-width: 720px) {
  .money-grid { grid-template-columns: repeat(3, 1fr); gap: var(--space-5); }
}
.money-grid__item {
  background: var(--surface-white, #ffffff);
  border-left: 3px solid var(--brand-terracotta);
  border-radius: 8px;
  padding: var(--space-4);
}
.money-grid__num {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4vw, 2.6rem);
  line-height: 1;
  color: var(--brand-aubergine);
}
.money-grid__label {
  margin-top: var(--space-2);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--surface-ink);
}
.money-grid__body {
  margin-top: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink-muted);
}

@media (prefers-reduced-motion: reduce) {
  .athlete__progress::after { transition: none; }
}
/* End of section 36. */

/* ============================================================
   §37 PERSONAL DONATION PAGE  (/donate/<slug>)
   Server-rendered by functions/donate/[slug].js. Styles cover:
     - Hero two-column layout (cut-out portrait + intro)
     - Large progress bar with milestone tick marks
     - Recent-supporters donor list
   These selectors are scoped tightly enough that they shouldn't
   bleed into other pages. Mobile-first; desktop adjusts at 960px.
   ============================================================ */
.donate-personal-hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  align-items: center;
}
@media (min-width: 960px) {
  .donate-personal-hero { grid-template-columns: 1fr 1fr; }
}
.donate-personal-hero__photo img {
  width: 100%;
  height: auto;
  max-height: 70svh;
  object-fit: contain;
}

.progress-large {
  position: relative;
  height: 12px;
  width: 100%;
  background: rgba(234, 170, 255, 0.20);
  border-radius: 6px;
  overflow: visible;
  margin-block: var(--space-4);
}
.progress-large__fill {
  --progress: 0%;
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--brand-terracotta), var(--brand-aubergine));
  border-radius: 6px;
  width: var(--progress);
  transition: width 800ms cubic-bezier(0.16, 1, 0.3, 1);
}
.progress-large__milestone {
  position: absolute;
  top: -4px;
  height: 20px;
  width: 1px;
  background: rgba(23, 20, 17, 0.4);
}
.progress-large__milestone span {
  position: absolute;
  top: 24px;
  transform: translateX(-50%);
  font-family: var(--font-heading);
  font-size: 11px;
  color: rgba(23, 20, 17, 0.5);
  white-space: nowrap;
}

.donor-list {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.donor-list li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  padding-block: var(--space-3);
  border-bottom: 1px solid rgba(23, 20, 17, 0.08);
  font-family: var(--font-body);
}
.donor-list li:last-child { border-bottom: 0; }
.donor-list__name {
  color: var(--surface-ink);
  font-weight: 500;
}
.donor-list__amount {
  color: var(--brand-terracotta);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.donor-list__empty .donor-list__name {
  opacity: 0.65;
  font-style: italic;
  font-weight: 400;
}
/* End of section 37. */



/* ============================================================
   §38 COMPACT FOOTER (footer--compact)
   ------------------------------------------------------------
   3-col on desktop (brand | navigate | contact), single stack
   on mobile. Single legal ribbon at bottom collapses all entity
   IDs + policy links onto one line.
   ============================================================ */

.footer.footer--compact {
  background: var(--brand-aubergine);
  color: var(--surface-cream);
  padding: var(--space-6) 0 var(--space-4);
}

.footer--compact .footer__top {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  align-items: start;
}
@media (min-width: 768px) {
  .footer--compact .footer__top {
    grid-template-columns: 1.2fr 1fr 1.4fr;
    gap: var(--space-6);
  }
}

.footer--compact .footer__brand {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.footer--compact .footer__logo {
  width: 200px;
  height: auto;
}
.footer--compact .footer__tagline {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.45;
  max-width: 32ch;
  color: var(--surface-cream);
  opacity: 0.9;
  margin: 0;
}

.footer--compact .footer__heading {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand-lilac);
  margin: 0 0 var(--space-3);
}

.footer--compact .footer__nav ul,
.footer--compact .footer__contact-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
}

@media (min-width: 768px) {
  .footer--compact .footer__nav ul {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-4);
    row-gap: 6px;
  }
}

.footer--compact a {
  color: var(--surface-cream);
  text-decoration: none;
  transition: color 150ms ease;
}
.footer--compact a:hover,
.footer--compact a:focus-visible {
  color: var(--brand-lilac);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.footer--compact a:focus-visible {
  outline: 2px solid var(--brand-lilac);
  outline-offset: 2px;
}

.footer--compact .footer__follow {
  margin-top: var(--space-2);
  color: var(--surface-cream);
  opacity: 0.95;
}
.footer--compact .footer__follow a {
  margin-left: 4px;
}

.footer--compact .footer__ribbon {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(234, 170, 255, 0.18);
}
.footer--compact .footer__ribbon p {
  font-family: var(--font-body);
  font-size: 12px;
  line-height: 1.6;
  letter-spacing: 0.02em;
  color: var(--surface-cream);
  opacity: 0.7;
  margin: 0;
  text-align: left;
}
.footer--compact .footer__ribbon a {
  color: var(--surface-cream);
  opacity: 1;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.footer--compact .footer__ribbon a:hover {
  color: var(--brand-lilac);
}
.footer--compact .footer__ribbon span[aria-hidden="true"] {
  opacity: 0.45;
  margin: 0 2px;
}

@media (max-width: 640px) {
  .footer--compact .footer__nav ul,
  .footer--compact .footer__contact-list {
    gap: 10px;
    font-size: 15px;
  }
  .footer--compact .footer__ribbon p {
    text-align: center;
  }
}

/* End of section 38. */
