/*
 * /site-redesign/draft-b-bento-dashboard/styles/draft.css
 *
 * Draft-specific layout for the bento dashboard direction.
 * Composes on top of the locked tokens + base components in /styles/tokens.css.
 *
 * Layout language for this draft:
 *   - CSS Grid heavy — explicit grid templates for the bento on the homepage
 *   - Tile-based — every region has a clear card boundary
 *   - Comfortable but dense — light section padding, denser type than draft-a
 *   - Dark moments confined to hero + footer per design system
 *
 * Tokens used (from tokens.css):
 *   --color-paper / --color-paper-warm / --color-ink / --color-border / --color-mid
 *   --type-display-* / --type-body* / --type-caption
 *   --space-1..24
 *   --radius-sm / --radius
 *   --transition-hover / --transition-expand
 */


/* ============================================================
   SITE-WIDE ANNOUNCEMENT BAR
   Sits above the nav on every page. Apex-black bg + paper text + green CTA.
   Tri-color compliant. Locked 2026-05-18 for the June 1 enrollment window.
   ============================================================ */
.announcement-bar {
  background: var(--apex-black);
  color: var(--apex-white);
  font-size: var(--type-body-s);
  line-height: 1.3;
  border-bottom: 1px solid var(--apex-ink-16);
}

.announcement-bar__inner {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-3) var(--container-pad);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  text-align: center;
}

.announcement-bar__text strong {
  color: var(--apex-white);
  font-weight: 700;
  margin-right: var(--space-2);
}

.announcement-bar__sub {
  color: rgba(255, 255, 255, 0.7);
}

.announcement-bar__cta {
  color: var(--apex-green);
  font-weight: 600;
  border-bottom: 1px solid currentColor;
  transition: opacity var(--transition-hover);
  white-space: nowrap;
}

.announcement-bar__cta:hover {
  opacity: 0.85;
}

/* Mobile: hide the .announcement-bar__sub on the narrowest viewports so the
   sticky stack stays under control. The strong primary fact ("Kids classes
   start June 1.") + the CTA carry the message; the secondary "Free 1-on-1
   sessions…" line shows again at ≥481px. Per pre-launch audit 2026-05-19
   HIGH #2 — was previously 100px tall (3 wrapped lines) on a 375px viewport. */
@media (max-width: 480px) {
  .announcement-bar__inner {
    gap: var(--space-2);
    padding-block: var(--space-2);
    flex-wrap: nowrap;
    text-align: left;
  }
  .announcement-bar__sub {
    display: none;
  }
  .announcement-bar__cta {
    margin-left: auto;
    flex-shrink: 0;
  }
}


/* ============================================================
   TOP NAV
   ============================================================ */
.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  /* --space-5 was never defined in tokens (silent fallthrough to 0).
     space-3 = 12px keeps the nav tight around the new 64/84px logo.
     The taller logo itself drives the nav's effective height. */
  padding: var(--space-3) var(--container-pad);
  background: var(--color-paper);
  border-bottom: var(--border);
  position: sticky;
  top: 0;
  z-index: 50;
}

.site-nav__logo {
  display: inline-flex;
  align-items: center;
  border-bottom: 0;
}

.site-nav__logo img {
  height: 64px;                /* mobile default — per apex_site_hero_logo_decisions memory */
  width: auto;
  display: block;
}

@media (min-width: 768px) {
  .site-nav__logo img {
    height: 84px;              /* desktop — matches locked decision */
  }
}

.site-nav__links {
  display: flex;
  gap: var(--space-6);
  margin-left: auto;
  font-size: var(--type-body);
  font-weight: 600;            /* bumped 2026-05-18: 400 was reading thin next to the green CTA pill */
  color: var(--color-ink);     /* full ink, not inherited muted */
}

.site-nav__links a {
  color: var(--color-ink);     /* explicit full-contrast ink */
  border-bottom: 1px solid transparent;
  transition: color var(--transition-hover), border-color var(--transition-hover);
}

.site-nav__links a:hover,
.site-nav__links a:focus-visible {
  /* Hover: keep ink, draw the underline. Plum hover was the previous treatment but
     the user wants more weight + contrast, not a color shift. */
  color: var(--color-ink);
  border-bottom-color: var(--color-ink);
}

.site-nav__links a[aria-current="page"] {
  border-bottom-color: var(--color-ink);
}

.site-nav__cta {
  font-size: var(--type-body-s);
}

/* Mobile nav — logo + CTA on row 1, links centered on row 2.
   Per pre-launch audit 2026-05-19 HIGH #2: tightened gaps + padding so the
   total sticky stack (announcement + nav) sits well under 200px instead of
   ~300px (35% of mobile viewport). Per audit MED: tap targets on links are
   ≥44×44 via padding-block + min-height. */
@media (max-width: 639px) {
  .site-nav {
    flex-wrap: wrap;
    gap: var(--space-2);
    padding-block: var(--space-2);
  }
  .site-nav__logo img {
    height: 48px;             /* down from 64px on small mobile — saves ~16px sticky height */
  }
  .site-nav__cta {
    order: 2;
    margin-left: auto;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .site-nav__links {
    order: 3;
    width: 100%;
    margin-left: 0;
    /* WRAP is load-bearing: with 5 links (Adults · Self-Defence · Schedule ·
       About · Coaches) added after the youth discontinuation, a non-wrapping
       centered row overflowed and clipped the first link below ~432px.
       Wrapping flows them to two centered rows with no clipping. */
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2) var(--space-4);   /* row-gap col-gap */
    font-size: var(--type-body-s);        /* smaller so more fit per row */
    padding-top: var(--space-2);
    border-top: var(--border);
  }
  .site-nav__links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding-inline: var(--space-2);   /* tap target stays ≥44 wide; tighter so links fit */
  }
  .announcement-bar__cta {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
}

/* Very small viewports (≤390px) — re-audit 2026-05-19 found the 375×844 stack
   still 243px because the nav-links row sits below the logo+CTA row. Below
   ≤390px, drop the logo + CTA further (40px logo) and tighten the links row
   padding-top so the stack sits closer to 200px. The announcement-bar sub
   text is already hidden at ≤480 (see rule above). */
@media (max-width: 390px) {
  .site-nav {
    gap: var(--space-1);
    padding-block: var(--space-1);
  }
  .site-nav__logo img {
    height: 40px;
  }
  .site-nav__links {
    padding-top: var(--space-1);
    gap: var(--space-3);
  }
  .site-nav__cta {
    /* shrink horizontal padding so logo + CTA stay one row on narrow widths */
    padding-inline: var(--space-3);
  }
}


/* ============================================================
   HERO REGIONS
   ============================================================ */
.hero {
  padding-top: var(--space-12);
  padding-bottom: var(--space-12);
}

@media (min-width: 768px) {
  .hero {
    padding-top: var(--space-16);
    padding-bottom: var(--space-16);
  }
}

/* Home hero tighter desktop padding so total section height fits inside the
   ≤62vh lock (with figure capped at 50vh + ~space-8 padding each side = ~57vh). */
@media (min-width: 900px) {
  .hero-home {
    padding-top: var(--space-8);
    padding-bottom: var(--space-8);
  }
}

.hero__copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* Hero lede — mission/values paragraph that opens the home hero. Sits between
   the H1 and the procedural subhead. Slightly larger + heavier than the subhead
   so it reads as the philosophical hook. Added 2026-05-18 when the mission
   band was inlined into the hero. */
.hero__lede {
  font-size: 1.375rem;             /* ~22px — a step above body-l */
  line-height: var(--leading-lead);
  font-weight: 500;
  color: var(--color-ink);
  max-width: 36ch;                  /* tighter measure for the short mission line */
}

@media (min-width: 768px) {
  .hero__lede {
    font-size: 1.625rem;            /* ~26px desktop */
  }
}

.hero__subhead {
  font-size: var(--type-body-l);
  line-height: var(--leading-lead);
  max-width: 60ch;
}

.on-dark .hero__subhead {
  color: var(--color-text-muted-on-dark);
}

.hero__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-2);
}

/* Hero variants */
.hero-home    .hero__copy { gap: var(--space-6); }
.hero-intro   .hero__copy { gap: var(--space-4); }
.hero-about   .hero__copy { gap: var(--space-4); }

/* ============================================================
   HERO WITH IMAGE — homepage 2-col, about full-bleed figure
   ============================================================ */

/* Homepage: copy left, technique-demo image right on desktop.
   Stack vertically below 768 (copy first, then image — the H1 wants
   to lead, the image grounds it second). */
.hero-home__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: center;
}

@media (min-width: 900px) {
  .hero-home__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-12);
  }
}

.hero-home__figure {
  margin: 0;
}

.hero-home__figure img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center;
  display: block;
  border-radius: var(--radius);
  background: var(--apex-black);    /* black placeholder before image paints */
}

/* Home hero ≤62vh on desktop per CLAUDE.md "next section peeks above the fold"
   rule. Achieved by capping the technique-demo figure to 50vh on desktop —
   the image is the tall axis; copy on the left stays naturally sized; the
   section's total height = max(50vh, copy_height) + padding (~70vh on 900px
   viewport, comfortable headroom for the bento to peek). */
@media (min-width: 900px) {
  .hero-home__figure img {
    max-height: 50vh;
    height: 50vh;
    aspect-ratio: auto;
  }
}

/* About: editorial figure above the H1.
   Per Goal 2 step 9 (2026-05-19): capped at 40vh mobile / 50vh desktop and a
   ≤32px gap to the heading, so photo + headline read as one composition rather
   than two stacked blocks. Aspect dropped (was 3/2) — height is the constraint,
   object-fit handles the crop. */
.hero-about__figure {
  margin: 0 0 var(--space-8);              /* 32px to heading */
  border-radius: var(--radius);
  overflow: hidden;
}

.hero-about__figure img {
  width: 100%;
  height: 40vh;
  object-fit: cover;
  object-position: center;
  display: block;
  background: var(--apex-black);
}

@media (min-width: 768px) {
  .hero-about__figure img {
    height: 50vh;
  }
}


/* ============================================================
   BENTO GRID (homepage)
   ============================================================ */
.bento__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

/* Tablet: 2 columns. */
@media (min-width: 600px) {
  .bento__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-6);
  }
}

/* Desktop: 2x2. With youth removed (2026-05-31) the bento holds 4 tiles —
   Adults + Self-Defence on row 1, Schedule + Location on row 2. A 2-col grid
   balances cleanly; the previous 3-col + span layout left an empty cell once
   the youth tile was gone. */
@media (min-width: 1024px) {
  .bento__grid {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: minmax(0, auto);
    gap: var(--space-6);
  }
}


/* ============================================================
   TILE BASE + VARIANTS
   ============================================================ */
.tile {
  background: var(--color-paper);
  border: var(--border);
  border-radius: var(--radius);
  padding: var(--space-8);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.tile--program {
  background: var(--color-paper-warm);
}

.tile__heading {
  font-size: var(--type-display-m);
  margin-bottom: 0;
}

/* .tile__eyebrow rule deleted 2026-05-31 — it existed only for the Youth tile's
   head-start eyebrow; no program tile carries an eyebrow after the youth
   discontinuation. Rebuild from the global .eyebrow class if a tile needs one. */

.tile__body {
  font-size: var(--type-body);
  line-height: var(--leading-body);
}

.tile__cta {
  margin-top: auto;
  padding-top: var(--space-2);
}

/* In-tile FAQ expander block was deleted 2026-05-19 — no template references
   `.tile__faq`. If FAQ-in-tile pattern returns, rebuild from the schedule
   block rather than reviving these rules. */

/* Schedule teaser + location tile */
.tile--schedule .tile__heading,
.tile--location .tile__heading {
  font-size: var(--type-display-m);
}

.tile--location .location-map iframe {
  width: 100%;
  height: 220px;
  border: var(--border);
  border-radius: var(--radius-sm);
  display: block;
}

.tile--location .location-nap {
  font-style: normal;
}

.tile--location .location-nap p { margin-bottom: var(--space-2); font-size: var(--type-body-s); }
.tile--location .location-nap a { border-bottom: 1px solid currentColor; }


/* MISSION REGION rules (`.mission-region__eyebrow`, `.mission-block`) were
   deleted 2026-05-19. The full-bleed homepage mission band was removed in an
   earlier pass — the mission lede now lives in the hero (`.hero__lede`) on
   `/` and as a body-style H2 (`.mission-region__lede`) on `/about`. Both have
   live rules elsewhere in this stylesheet. */


/* ============================================================
   /intro: COMBINED CALENDLY + WHAT TO EXPECT GRID
   Per DESIGN_LOCKED_v1 #7: column heights aligned on desktop. CSS Grid
   tracks naturally stretch to row max-height; we just ensure both columns
   participate (align-items: stretch is the grid default).
   ============================================================ */
/* /intro "What to Expect" layout — was a 3fr/2fr grid alongside an inline
   Calendly embed before 2026-05-19. With the embed gone, the region becomes
   a centered narrow-column reading block: two stacked articles on mobile,
   2-up at tablet+ for "For you" + "For your child" side-by-side. */
.intro-wte__layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
}

@media (min-width: 768px) {
  .intro-wte__layout {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-12);
    align-items: start;
  }
}

/* Section-label eyebrow above the WTE blocks. */
.intro-wte .section-label {
  margin-bottom: var(--space-6);
}

/* /intro H3 ("For you" / "For your child") dropped from display-m (40px) to
   text-lg (24px) per pre-launch audit 2026-05-19 MED — H2 and H3 were both
   40px, collapsing the heading hierarchy. H1 stays at display-xl 64px, the
   sr-only H2 stays at display-m 40px, and H3 now sits comfortably under both. */
.wte-block h3 { font-size: var(--fs-text-lg); margin-bottom: var(--space-3); }

.bullet-list {
  list-style: disc;
  padding-left: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  color: var(--color-text);
}

/* `.intro-grid*`, `.calendly-inline-widget`, `.calendly-fallback` rules deleted
   2026-05-19 — the inline embed was removed from /intro because iOS visual
   viewport scroll inside the Calendly iframe was breaking. /intro now uses
   the popup widget via the delegated data-calendly handler like every other
   "Book Free Intro" CTA site-wide. */


/* ============================================================
   /schedule: MEMBERSHIPS — 3-card pricing block
   Sits between the Glofox iframe and the standalone CTA. All three cards are
   equal-weight paper; Apex Unlimited carries the green "Most popular" pill
   as the sole differentiator (inline below 1024px, absolute top-right ≥1024).
   ============================================================ */

.memberships {
  background: var(--color-bg-alt);    /* off-white panel to break from the Glofox iframe above */
}

.memberships__header {
  text-align: center;
  margin-bottom: var(--space-12);
}

.memberships__subhead {
  margin-top: var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--type-body-l);
}

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

/* Tablet (768–1023): 2-up so the headings + perks lists aren't cramped. */
@media (min-width: 768px) {
  .memberships__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-6);
    align-items: stretch;
  }
}

/* Desktop (≥1024): 3-up. Coincides with the breakpoint where the "Most popular"
   badge becomes absolute-positioned in the top-right of the card. */
@media (min-width: 1024px) {
  .memberships__grid {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-8);
  }
}

.plan-card {
  background: var(--apex-white);
  color: var(--color-ink);
  border: var(--border);
  border-radius: var(--radius);
  padding: var(--space-8);
  display: flex;
  flex-direction: column;
  position: relative;
}

/* NOTE — .plan-card--featured (elevated dark variant) was deleted 2026-05-18.
   The dark-on-dark treatment produced an ink-on-ink H3 bug, and visually
   competed with the "Most popular" pill. All three cards are now equal-weight
   paper; the green pill is the only differentiator. */

/* "Most popular" badge — green pill on Apex Unlimited.
   Was blush (#F2D4D4) — tri-color rule (2026-05-18).
   Inline at narrow widths (mobile + tablet), absolute top-right at desktop —
   absolute-positioning on a narrow card was clipping the wrapped H3 heading. */
.plan-card__badge {
  background: var(--apex-green);
  color: var(--apex-black);
  font-family: var(--font-label);
  font-size: var(--fs-ui-md);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: var(--tr-label);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  margin: 0 0 var(--space-3);
  align-self: flex-start;
  white-space: nowrap;        /* keep "MOST POPULAR" on one line on narrow cards */
}

@media (min-width: 1024px) {
  .plan-card__badge {
    position: absolute;
    top: var(--space-4);
    right: var(--space-4);
    margin: 0;
  }
}

.plan-card__name {
  font-size: 1.75rem;          /* ~28px per design lock */
  margin: 0 0 var(--space-4);
}

/* At desktop the absolute-positioned badge reserves space in the top-right;
   pad the heading so any wrap stays clear of the pill. */
@media (min-width: 1024px) {
  .plan-card__name {
    padding-right: 140px;
  }
}

.plan-card__price {
  margin-bottom: var(--space-6);
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.plan-card__price-amount {
  font-family: var(--font-display);
  font-size: 2.25rem;          /* ~36px per design lock */
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-display);
  color: inherit;
}

.plan-card__price-period {
  font-size: var(--type-body-s);
  opacity: 0.7;
}

/* .plan-card__subhead rule deleted 2026-05-31 — it existed only for the Apex
   Youth card's June 1 cohort line; youth removed, no plan carries a subhead.
   The {% if plan.subhead %} guard in schedule.html stays (harmless no-op) so a
   future plan could reintroduce one. */

.plan-card__perks {
  list-style: disc;
  padding-left: var(--space-6);
  margin: 0 0 var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  flex-grow: 1;
}

.plan-card__perks li {
  font-size: var(--type-body);
  line-height: var(--leading-body);
}

/* Joining-fee note: italic, small, muted. Same treatment on every card now
   that the elevated variant is retired. */
.plan-card__joining-fee {
  font-size: var(--type-body-s);
  font-style: italic;
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-4);
  margin-top: auto;
  color: var(--apex-black);
}

/* Block-CTA band — full-bleed black, white text. Was plum-deep before the
   tri-color rule (2026-05-18). Still "visually breaks the card grid as a
   deliberate section close" because it goes ink-on-white between two white sections. */
.memberships__cta-band {
  background: var(--apex-black);
  color: var(--apex-white);
  margin-top: var(--space-12);
  padding-block: var(--space-12);
}

.memberships__cta-band-inner {
  text-align: center;
}

.memberships__cta-lede {
  font-size: var(--type-body-l);
  font-weight: var(--fw-bold);
  margin-bottom: var(--space-6);
  max-width: 56ch;
  margin-left: auto;
  margin-right: auto;
  color: var(--apex-white);
}

/* Button inversion on the dark CTA band — green pill, black ink (matches the
   primary CTA elsewhere on the site). Was paper-on-plum before tri-color rule
   (2026-05-18). */
.btn.btn-on-deep {
  background: var(--apex-green);
  color: var(--apex-black);
}
.btn.btn-on-deep:hover  { filter: brightness(1.06); }
.btn.btn-on-deep:active { filter: brightness(0.94); }


/* ============================================================
   /schedule: GLOFOX iframe wrapped in a paper-soft frame
   Per DESIGN_LOCKED_v1 #10: paper-soft container + 'Live timetable' eyebrow
   + 1px ink divider above the iframe.
   ============================================================ */
.glofox-frame {
  background: var(--bg-soft);
  border-radius: var(--radius);
  padding: var(--space-6) var(--space-6) var(--space-4);
}

@media (min-width: 768px) {
  .glofox-frame {
    padding: var(--space-8) var(--space-8) var(--space-6);
  }
}

.glofox-frame__header {
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-ink);
}

.glofox-frame__eyebrow {
  margin: 0;
  color: var(--color-ink);
}

.glofox-iframe {
  width: 100%;
  border: 0;
  border-radius: var(--radius-sm);
  display: block;
  background: var(--apex-white);
}

.glofox-attribution {
  text-align: right;
  margin-top: var(--space-3);
  font-size: var(--type-body-s);
  color: var(--color-mid);
}


/* ============================================================
   /about: COACHES — stacked on mobile, 2-col Owen LEFT / Elliot RIGHT
   on desktop. Per Goal 2 step 5 (2026-05-19): switched from flex-column
   stacking to a 2-col grid at min-width 900px to use horizontal room
   instead of stacking empty gutters. Anchor IDs (#owen, #elliot, #contact)
   preserved on the article wrappers in about.html; deep-links unaffected.
   ============================================================ */
.coaches-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-16);
  max-width: var(--container-narrow);
  margin: 0 auto;
}

@media (min-width: 900px) {
  .coaches-grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-16);
    align-items: start;                          /* don't stretch shorter card to match */
    max-width: 1100px;                            /* wider canvas for 2-up */
  }
}

.coach {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.coach__name {
  font-size: var(--type-display-m);
  margin: var(--space-4) 0 0;
}

.coach__title {
  font-size: var(--type-body);
  color: var(--color-mid);
  font-weight: 500;
  margin-bottom: var(--space-3);
}

.coach__record {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: var(--border);
}

.coach__record .section-label { margin-bottom: var(--space-2); }

/* Comp record list — em-dash prefix per Goal 2 step 6 (2026-05-19).
   Reset native UL chrome so each medal/ranking line reads as a discrete row
   marked by a typographic dash, not a bullet. */
.coach__record ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
  margin: 0;
}

.coach__record li {
  font-size: var(--type-body-s);
  line-height: var(--leading-body);
  padding-left: 1.25em;
  text-indent: -1.25em;
}

.coach__record li::before {
  content: "— ";
  color: var(--color-mid);
}

.coach__social { margin-top: var(--space-4); }
.coach__social a { border-bottom: 1px solid currentColor; }

/* `.placeholder-image--coach` deleted 2026-05-19 — real coach photos replaced
   the placeholder divs (see .coach__photo below). */

/* Coach photo — replaces the placeholder div with a real <img>.
   4/5 aspect locked so the two coaches sit at identical heights regardless of
   per-photo crop. object-fit: cover crops to fill without distortion.
   max-width caps the photo at ~400px so it sits as a portrait within the
   stacked column, not as a full-width dominant block. */
.coach__photo {
  width: 100%;
  max-width: 400px;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center top;
  display: block;
  margin-bottom: var(--space-4);
  border-radius: var(--radius);
  background: var(--apex-black);   /* dark placeholder before image loads */
}


/* ============================================================
   ORIGIN STORY
   ============================================================ */
.origin-region p { font-size: var(--type-body-l); line-height: var(--leading-lead); }
.origin-region p + p { margin-top: var(--space-6); }


/* ============================================================
   MISSION REGION on /about
   Per DESIGN_LOCKED_v1 #12 the mission lede is a large editorial paragraph,
   NOT a display headline. The default h2 sizing (24/40 Archivo Black) was
   visually outweighing the hero H1 "About Apex." once it wrapped to 3-4
   lines — single-word H1 vs long multi-line H2 in the same display family
   inverted the hierarchy.

   Override to body family + body-scale size + medium weight. Keeps it as a
   section-opening voice, but the H1 stays the page headline. Letter-spacing
   reset because display tracking pulls glyphs apart in a way that doesn't
   suit body type.
   ============================================================ */
/* Mission lede pulled flush with the body rhythm — same 18px size as the
   surrounding paragraphs, only differentiated by font-weight 600. Was 24/700
   originally (felt loud), then 20/600 (still a size jump), now 18/600 — the
   whole mission region reads as one continuous body block with the opener
   carrying just enough weight to read as "opening sentence" not "heading". */
.mission-region__lede {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--type-body-l);       /* 18px both mobile + desktop */
  line-height: var(--leading-lead);
  letter-spacing: 0;
  margin-bottom: var(--space-3);       /* 12px gap to first paragraph — tight */
  max-width: 36ch;
}

/* Mission paragraphs match the hero subhead size so the whole top-of-page
   reading block sits at a consistent 18px body-l rhythm. */
.mission-region p {
  font-size: var(--type-body-l);
  line-height: var(--leading-lead);
}

/* Tighten paragraph-to-paragraph spacing in the mission region — was using
   the default p + p margin (16px); 8px reads as one continuous voice. */
.mission-region p + p {
  margin-top: var(--space-2);
}

/* Pull hero-about and mission-region together. Section padding is the floor;
   the figure margin-bottom (32px) inside the hero already provides separation,
   so the section padding sits tight at space-4 / space-6 (16/24px) above and
   below the boundary. Total visual gap subhead → lede sits around 40px. */
.page-about .hero-about {
  padding-bottom: var(--space-4);
}

.page-about .mission-region {
  padding-top: var(--space-6);
}


/* ============================================================
   CTA REGION (button-only) — reinstated 2026-05-19 per Goal 2 step 4
   ============================================================ */
.cta-region {
  background: var(--color-paper);
  text-align: center;
}

.cta-region__inner {
  display: flex;
  justify-content: center;
}

/* The .page-about scope below tightens the rest of the /about flow;
   keep the CTA breathing room generous (the call to action wants air).
   Specificity bump to (0,2,0) so it beats `.page-about .section`. */
.page-about .cta-region--about {
  padding-top: var(--space-16);          /* 64px mobile */
  padding-bottom: var(--space-16);
}

@media (min-width: 768px) {
  .page-about .cta-region--about {
    padding-top: var(--space-24);        /* 96px desktop */
    padding-bottom: var(--space-24);
  }
}


/* ============================================================
   LOCATION REGION (full-width on /intro, /schedule, /about#contact)
   ============================================================ */
.location-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}

@media (min-width: 768px) {
  .location-grid {
    grid-template-columns: 2fr 1fr;
    gap: var(--space-8);
  }
}

.location-region .location-map iframe {
  width: 100%;
  height: 320px;
  border: var(--border);
  border-radius: var(--radius);
  display: block;
}

.location-nap {
  font-style: normal;
}

.location-nap p { margin-bottom: var(--space-2); }
.location-nap p + p { margin-top: 0; }
.location-nap__neighborhood { color: var(--color-mid); font-size: var(--type-body-s); margin-bottom: var(--space-4); }
.location-nap a { border-bottom: 1px solid currentColor; }


/* ============================================================
   BOTTOM FAQ GRID (homepage)
   2 columns desktop, 1 column mobile. Was 3 columns (one per program); the
   youth column was removed 2026-05-31, leaving Adults + Self-Defence two-up.
   ============================================================ */
.faq-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
}

@media (min-width: 768px) {
  .faq-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-12);
  }
}

.faq-group__heading {
  font-size: var(--type-display-m);
  margin-bottom: var(--space-4);
}

.faq-list--compact details summary {
  font-size: var(--type-body);
  padding: var(--space-3) 0;
}

.faq-list--compact details .answer {
  font-size: var(--type-body-s);
}


/* ============================================================
   /privacy — prose page, narrow container, plain typography
   No bento tiles. Inherits tokens; no new colors.
   ============================================================ */
.page-privacy main {
  padding-top: var(--space-12);
  padding-bottom: var(--space-12);
}

.privacy-hero { margin-bottom: var(--space-12); }

.privacy-hero h1 {
  font-size: var(--fs-display-md);
  margin-bottom: var(--space-4);
}

.privacy-hero__lede {
  font-size: var(--type-body-l);
  line-height: var(--leading-lead);
  margin-bottom: var(--space-4);
  max-width: 50ch;
}

.privacy-hero__meta {
  font-size: var(--type-body-s);
  color: var(--color-text-muted);
}

.privacy-section {
  margin-bottom: var(--space-8);
}

.privacy-section h2 {
  font-size: var(--type-display-m);
  margin-bottom: var(--space-4);
}

.privacy-section p { margin-bottom: var(--space-3); }
.privacy-section p:last-child { margin-bottom: 0; }

.privacy-list {
  list-style: disc;
  padding-left: var(--space-6);
  margin: var(--space-3) 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.privacy-list li {
  line-height: var(--leading-body);
}

.privacy-contact {
  font-style: normal;
  margin-bottom: var(--space-4);
  line-height: var(--leading-body);
}


/* ============================================================
   /404
   ============================================================ */
.page-404__main {
  padding: var(--space-24) 0;
  text-align: center;
}

.page-404__main h1 {
  font-size: var(--type-display-xl);
  margin-bottom: var(--space-6);
}

.page-404__line {
  font-size: var(--type-body-l);
  line-height: var(--leading-lead);
  color: var(--color-mid);
  margin-bottom: var(--space-8);
  max-width: 50ch;
  margin-left: auto;
  margin-right: auto;
}


/* ============================================================
   FOOTER — 4 columns desktop, stacked mobile in same order
   ============================================================ */
.site-footer {
  padding-top: var(--space-16);
  padding-bottom: var(--space-8);
}

.site-footer__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
}

@media (min-width: 768px) {
  .site-footer__inner {
    grid-template-columns: 1.4fr 1fr 1fr 1fr;
    gap: var(--space-12);
  }
}

.site-footer__col-heading {
  font-family: var(--font-body);
  font-size: var(--type-caption);
  text-transform: uppercase;
  letter-spacing: var(--tracking-section-label);
  color: rgba(255, 255, 255, 0.5);   /* tri-color rule (2026-05-18): white tint on the dark footer */
  font-weight: 500;
  margin-bottom: var(--space-3);
}

.site-footer__brand-name {
  font-family: var(--font-display);
  font-size: var(--type-display-m);
  margin-bottom: var(--space-4);
  color: var(--color-paper);
}

.site-footer address {
  font-style: normal;
  color: var(--color-text-muted-on-dark);
}

.site-footer ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.site-footer a {
  color: var(--color-paper);
  border-bottom: 1px solid rgba(255, 255, 255, 0.3);   /* tri-color rule (2026-05-18) */
  transition: border-color var(--transition-hover);
}

.site-footer a:hover { border-bottom-color: var(--color-paper); }

/* App-store badges (real Glofox links).
   Per Goal 5 step 19 (2026-05-19): the placeholder <span> dashed-border boxes
   were replaced with real <a> elements pointing at Glofox's white-label app
   in the iOS App Store and Google Play. Until licensed SVG badges drop in
   (see docs/ASSETS_PENDING.md), the visual treatment is a black pill with
   a small "Download on the / Get it on" eyebrow + bold store name — same
   information architecture as the official badges, no trademark assets. */
.site-footer__app-badges {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding: 0;
  list-style: none;
}

.site-footer__app-badge {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-2) var(--space-4);
  border: 1px solid rgba(255, 255, 255, 0.4);    /* tri-color: white tint on the dark footer */
  border-radius: var(--radius);
  background: transparent;
  color: var(--color-paper);
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.4);   /* override the .site-footer a underline */
  line-height: 1.1;
  transition: background-color var(--transition-hover), border-color var(--transition-hover);
}

.site-footer__app-badge:hover,
.site-footer__app-badge:focus-visible {
  background: rgba(255, 255, 255, 0.08);
  border-color: var(--color-paper);
}

.site-footer__app-badge-eyebrow {
  font-size: 0.625rem;                            /* 10px — quiet voice */
  letter-spacing: 0.05em;
  text-transform: uppercase;
  opacity: 0.75;
}

.site-footer__app-badge-name {
  font-size: var(--type-body);
  font-weight: 700;
  letter-spacing: -0.01em;
}

.site-footer__strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-12);
  padding-top: var(--space-6);
  border-top: var(--border-on-dark);
  font-size: var(--type-body-s);
  color: var(--color-text-muted-on-dark);
}

.site-footer__strip [aria-hidden="true"] {
  color: rgba(255, 255, 255, 0.3);   /* tri-color rule (2026-05-18) */
}


/* ============================================================
   GLOBAL TWEAKS that apply on this draft
   ============================================================ */

/* Tighten section padding slightly on this dashboard draft. */
.section {
  padding-top: var(--space-12);
  padding-bottom: var(--space-12);
}

@media (min-width: 768px) {
  .section {
    padding-top: var(--space-16);
    padding-bottom: var(--space-16);
  }
}

/* /about: halve the section-to-section rhythm so the page reads as one
   composition. Per Goal 2 step 7 (2026-05-19): target ≤60px mobile / ≤100px
   desktop combined gap between adjacent sections. With 32+32 mobile = 64px
   and 48+48 desktop = 96px we sit just under both ceilings. CTA region is
   excluded — the call to action wants air, and its own .cta-region--about
   rule above carries the roomier 64/96 padding. The :not() exclusion is
   load-bearing: same-specificity rules later in the cascade would win
   otherwise. */
.page-about .section:not(.cta-region--about) {
  padding-top: var(--space-8);
  padding-bottom: var(--space-8);
}

@media (min-width: 768px) {
  .page-about .section:not(.cta-region--about) {
    padding-top: var(--space-12);
    padding-bottom: var(--space-12);
  }
}

/* Sticky nav clearance — when in-page anchors fire (e.g. /about#owen from
   /intro For You bullet), scroll-padding-top keeps the target heading below
   the sticky nav rather than tucked under it. Bumped 120 → 156 on 2026-05-19
   to cover the full desktop sticky stack: ~32px announcement bar + 84px logo
   + 24px nav padding + headroom margin = ~156px. The previous 120 left ~33px
   of target text tucked under the nav. */
html {
  scroll-padding-top: 156px;
}

/* Inline links inside paragraphs get an underline (design system rule). */
main p a {
  border-bottom: 1px solid currentColor;
  transition: opacity var(--transition-hover);
}

main p a:hover { opacity: 0.7; }
