/* ---------------------------------------------------------------------------
   The centre landing page
   ---------------------------------------------------------------------------
   Ported from the design file rather than rewritten as Tailwind utilities:
   Phase 2 rebuilds this template on the design system, so utilities written now
   would be thrown away twice.

   EVERYTHING is nested inside .landing — the CONTENT wrapper, not the body.
   Scoping to the body is not enough: the shared nav and footer live in that
   subtree, and the design's reset (*, img, button, a) stripped the nav's
   spacing and link colours. Only the palette and page background sit on
   body.landing-page.

   That is not tidiness. Authored CSS
   is emitted AFTER `@import "tailwindcss"`, so a bare class here has the same
   specificity as a utility and wins on source order. Unscoped, the design's
   reset alone — `*`, `img`, `button`, `a` — would reach every page in the app.
   test/infrastructure/brand_css_test.rb enforces this: it walks the brace depth
   of THIS file and fails the build on any rule outside `.landing` other than
   the documented `body.landing-page` and `html:has(...)` exceptions.

   The palette points at tokens that already exist rather than restating them,
   so a brand change is made once.
   --------------------------------------------------------------------------- */

body.landing-page {
  /* The design's palette. --amber, --ink and --white ARE our tokens. */
  --amber: var(--color-interactive-primary-default);
  --amber-dark: #d9a82f;
  --ink: var(--color-text-primary);
  --white: var(--color-background-primary);
  --bg-dark: #000000;
  --bg-dark-2: #1c1c1c;
  --panel: #1c1c1c;
  --line: rgba(255,255,255,.13);
  --green-accent: #48a356;
  /* Points at the shared token rather than restating the family, for the same
     reason the palette above does. `body.landing-page` (0,1,1) outranks the
     `.font-sans` utility (0,1,0) on the same element, so hardcoding a family
     here silently beat both the platform font and any tenant's font-sans
     override — on every landing and booking page. */
  --font: var(--font-sans);
  --page-max: 1248px;
  --pad: 64px;
  /* Minor third scale (1.2), 22px base */
  --fs--1: 18px;
  --fs-0: 22px;
  --fs-1: 26px;
  --fs-2: 32px;
  --fs-3: 38px;
  --fs-4: 46px;
  --fs-5: 55px;
  --fs-6: 66px;
  --fs-7: 79px;

  /* The design's own body rule. */
  font-family: var(--font); font-size: var(--fs-0); line-height: 1.55;
  color: var(--white); background: var(--bg-dark); -webkit-font-smoothing: antialiased;
}

/* Smooth scrolling is a property of the scrolling element, which is never
   .landing — so it is attached to the document only while this page is shown. */
html:has(body.landing-page) { scroll-behavior: smooth; }

/* The responsive gutter, and the dock clearance that keeps the fixed CTA off
   the end of the footer.

   Both live out here, on body.landing-page, because both target the element
   the palette is declared on. The design set them on :root; that cannot work
   once the palette moves onto the body, for two compounding reasons. Nested
   inside .landing the selector becomes `.landing :root`, which matches nothing
   — :root is <html>, an ancestor. And even unnested, body.landing-page's own
   --pad: 64px wins for the body and everything under it, so an inherited value
   from :root never reaches .container.

   The symptom was a page that overflowed its viewport horizontally on a phone:
   64px gutters on a 414px screen, with the right-hand one pushed off-screen. */
@media (max-width: 1023px) {
  body.landing-page { --pad: 32px; }
}
@media (max-width: 767px) {
  body.landing-page { --pad: 16px; padding-bottom: 70px; }
}

.landing {
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
  img { display: block; max-width: 100%; }
  button { cursor: pointer; border: none; background: none; font-family: inherit; color: inherit; }
  a { color: inherit; }

/* ============================================================
   DIRECTION 3: "INSIDE YOUR CENTER"
   Experience-led local tour. Dark, immersive, video-forward.
   Rev 3.0: brand logo assets, location-switcher
   modal, minor-third type scale (18px base), no light sections,
   member photo placeholders, About-the-Center gallery,
   full-width map band, mobile-first stacking.
   ============================================================ */

.container { max-width: var(--page-max); margin: 0 auto; padding-left: var(--pad); padding-right: var(--pad); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--amber); color: var(--ink);
  font-size: var(--fs-0); font-weight: 800; line-height: 1.2; text-transform: uppercase;
  padding: 16px 24px; border-radius: 0; text-decoration: none;
  transition: background .15s; white-space: nowrap;
}
.btn:hover { background: var(--amber-dark); }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--bg-dark), 0 0 0 4px var(--amber); }
.btn--ghost { background: transparent; border: 1px solid var(--amber); color: var(--amber); padding: 12px 24px; }
.btn--ghost:hover { background: rgba(255,200,68,.1); }

.eyebrow { font-size: var(--fs--1); font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: var(--amber); }
.section-heading { font-size: var(--fs-5); font-weight: 800; line-height: 1.15; text-transform: uppercase; }
.lede { font-size: var(--fs-1); line-height: 1.55; color: rgba(255,255,255,.78); }
.fineprint { font-size: var(--fs--1); color: rgba(255,255,255,.55); }

.section { padding: 96px 0; }
.section__head { max-width: 800px; display: flex; flex-direction: column; gap: 16px; margin-bottom: 48px; }
.section__head--center { margin-left: auto; margin-right: auto; text-align: center; align-items: center; }

/* Image placeholder (awaiting brand photography per design.md §1.2) */
.img-ph {
  background: repeating-linear-gradient(45deg, #191a1f, #191a1f 14px, #15161a 14px, #15161a 28px);
  border: 1px dashed rgba(255,255,255,.22);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  color: rgba(255,255,255,.5); text-align: center; padding: 16px;
}
.img-ph svg { width: 34px; height: 34px; opacity: .6; }
.img-ph span { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; line-height: 1.4; }

/* ============================================================
   HEADER (sticky) + SWITCHER
   ============================================================ */
.header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(15,16,20,.94); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.header__inner { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding-top: 14px; padding-bottom: 14px; }
.header__logo img { width: 220px; height: auto; }
.header__right { display: flex; align-items: center; gap: 24px; }
.header__switch {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: var(--fs--1); font-weight: 700; color: var(--amber);
  text-decoration: underline; text-underline-offset: 3px; white-space: nowrap;
}
.header__switch:hover { color: var(--amber-dark); }
.header__switch svg { width: 16px; height: 16px; }
.header .btn { padding: 12px 24px; font-size: 15px; }

/* ============================================================
   HERO
   ============================================================ */
.hero { position: relative; overflow: hidden; }
.hero__bg { position: absolute; inset: 0; }
/* Pulled UP so the subject sits level with the eyebrow and headline.

   The photograph has roughly a third of empty headroom above her, and
   `object-fit: cover` shows all of it: at most widths the image's ratio (1.65)
   is wider than the band's, so cover scales it to the band's HEIGHT and crops
   only horizontally — there is no vertical crop for an `object-position: top`
   to bite on. She therefore sat ~340px down the band however the keyword was
   set.

   A LENGTH offset moves the image regardless, which a percentage cannot: a
   percentage of object-position resolves against the overflow, and the overflow
   here is zero. -240px lifts her head to the headline.

   The mask is what the offset costs. Shifting the image up leaves its bottom
   edge inside the band, and without a fade that edge reads as a photograph cut
   off mid-torso rather than one dissolving into the dark. */
.hero__bg img {
  width: 100%; height: 100%; object-fit: cover;
  object-position: right -240px; opacity: .38;
  mask-image: linear-gradient(to bottom, #000 65%, transparent 95%);
  -webkit-mask-image: linear-gradient(to bottom, #000 65%, transparent 95%);
}

.hero__bg::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top, var(--bg-dark) 8%, rgba(15,16,20,.55) 55%, rgba(15,16,20,.75) 100%); }
/* hero__inner spans the same .container as the header + every section below,
   so their left edges line up. The text column is capped separately and
   left-aligned, keeping it off the background image and readable. */
.hero__inner { position: relative; z-index: 2; padding-top: 96px; padding-bottom: 96px; }
.hero__content { display: flex; flex-direction: column; gap: 24px; align-items: flex-start; max-width: 660px; }
/* Sized for a SENTENCE, not a two-word centre name.

   At --fs-7 the old headline was "OSTEOSTRONG / ANCHORAGE" on two lines. The
   client's replacement is ~65 characters, which at that size ran to eight
   uppercase lines and pushed the address, the lede and the call to action off
   the fold — the hero's whole job is to reach that button. Dropped two steps
   and given a measure so it breaks where the copy does.

   Still uppercase, which is the design's heading language throughout. The
   measure is MEASURED: at 20ch the headline settles to four lines and the call
   to action sits at 889px, just inside a 900px viewport. Narrower runs to seven
   lines and pushes the button to 1067px; wider changes nothing, because the
   explicit <br> between the two sentences is what sets the break. */
.hero__title {
  font-size: var(--fs-5); font-weight: 900; line-height: 1.08;
  text-transform: uppercase; max-width: 20ch;
}
.hero__title span { color: var(--amber); }
/* The design's row assumed hardcoded stars and a count. It now wraps the
   Elfsight aggregate badge, which brings its own markup and needs room to
   mount, plus the caption saying whose rating it is. */
/* No special margin. The badge sits on .hero__content's uniform 24px rhythm
   like every other child.

   Three passes added 16px, then 40px, then 20px here before the approved comp
   was measured properly against our own render at its width: normalised by
   headline line-pitch, it wants 33px from the headline ink to the pill and
   104px from the pill to the centre name. The base rhythm gives 36 and 100.
   Every margin added here made it worse. */
.hero__rating {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  font-size: var(--fs-0); font-weight: 700;
}
.hero__rating-note { font-size: var(--fs--1); font-weight: 600; color: rgba(255,255,255,.6); }
.hero__stars { color: var(--amber); letter-spacing: 2px; }
/* The centre's own name, displaced from the H1 when the headline became the
   offer rather than the centre. Deliberately quieter than the headline and
   louder than the address — it identifies the page without competing with the
   thing the page is selling. Keeps the design's brand-white / locality-amber
   split. */
.hero__name {
  font-size: var(--fs-2); font-weight: 800; text-transform: uppercase;
  letter-spacing: .5px; line-height: 1.2; color: var(--white);
}
.hero__name span { color: var(--amber); }

/* Pulled up against the name: the two are one block identifying the centre,
   and .hero__content's 24px gap plus this line-height's leading put 45px of ink
   between them where the comp has 24px. Measured both at the comp's own width.

   A negative margin rather than a smaller gap, because the gap is the column's
   rhythm and every other pair in the hero wants it. */
.hero__address {
  font-size: var(--fs-1); color: rgba(255,255,255,.85); line-height: 1.5;
  margin-top: -20px;
}
.hero__address strong { color: var(--white); }
.hero__lede { font-size: var(--fs-0); line-height: 1.6; color: rgba(255,255,255,.8); max-width: 620px; }
.hero__meta { display: flex; align-items: center; gap: 16px; font-size: var(--fs--1); color: rgba(255,255,255,.7); flex-wrap: wrap; }
.hero__meta .dot { color: var(--amber); }
.hero__actions { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 8px; }

/* ============================================================
   FIRST SESSION TOUR
   ============================================================ */
.tour { background: var(--bg-dark-2); }
.firstvisit {
  display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-bottom: 48px;
}
.firstvisit__col {
  background: var(--panel); border: 1px solid var(--line); border-left: 4px solid var(--amber);
  padding: 32px; display: flex; flex-direction: column; gap: 10px;
}
.firstvisit__tag { font-size: 15px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: var(--amber); }
.firstvisit__title { font-size: var(--fs-1); font-weight: 800; line-height: 1.25; }
.firstvisit__body { font-size: var(--fs--1); line-height: 1.65; color: rgba(255,255,255,.78); }
.firstvisit__body strong { color: var(--white); }
.step { display: flex; gap: 48px; align-items: center; padding: 48px 0; border-top: 1px solid var(--line); }
.step:last-child { border-bottom: 1px solid var(--line); }
.step__num {
  flex: 0 0 76px; width: 76px; height: 76px; border-radius: 50%;
  background: var(--amber); color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-2); font-weight: 900;
}
.step__num--ghost { background: transparent; border: 2px solid var(--amber); color: var(--amber); }
.step__copy { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.step__title { font-size: var(--fs-2); font-weight: 800; line-height: 1.2; }
.step__title small { font-size: 14px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--amber); display: block; margin-bottom: 4px; }
.step__desc { font-size: var(--fs-0); line-height: 1.6; color: rgba(255,255,255,.75); max-width: 640px; }
.step__media { flex: 0 0 320px; height: 190px; background: #000; overflow: hidden; }
.step__media video { width: 100%; height: 100%; object-fit: cover; }
.tour__foot { display: flex; align-items: center; gap: 24px; margin-top: 48px; flex-wrap: wrap; }

/* ============================================================
   ABOUT THE CENTER — gallery
   ============================================================ */
.space { background: var(--bg-dark); }
.space__grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 48px; align-items: center; }
.space__copy { display: flex; flex-direction: column; gap: 16px; align-items: flex-start; }
.space__copy p { font-size: var(--fs-0); line-height: 1.65; color: rgba(255,255,255,.78); }
.space__facts { list-style: none; display: flex; flex-direction: column; gap: 12px; margin-top: 6px; }
.space__facts li { padding-left: 32px; position: relative; font-size: var(--fs-0); color: rgba(255,255,255,.82); }
.space__facts li::before { content: '✓'; position: absolute; left: 0; color: var(--amber); font-weight: 800; }
.space__gallery { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.space__photo { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 1/1; display: block; }
/* Two photos, side by side. The design's first-child full-bleed assumed three;
   with two it left a hole in the second column. */
.space__gallery { grid-template-columns: 1fr 1fr; }

/* ============================================================
   PROOF — stats + chart
   ============================================================ */
.proof { background: var(--bg-dark-2); }
.stats-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-bottom: 64px; }
.stat { background: var(--panel); border: 1px solid var(--line); padding: 32px; display: flex; flex-direction: column; gap: 10px; }
.stat__num { font-size: var(--fs-6); font-weight: 900; line-height: 1; color: var(--amber); }
.stat__label { font-size: var(--fs--1); line-height: 1.55; color: rgba(255,255,255,.75); }
.stat__source { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: rgba(255,255,255,.45); }

.chart-flex { display: flex; gap: 48px; align-items: flex-start; background: var(--panel); border: 1px solid var(--line); padding: 48px; }
.chart-flex__left { flex: 0 0 40%; }
.chart-flex__left h3 { font-size: var(--fs-3); font-weight: 800; line-height: 1.2; margin-bottom: 16px; }
.chart-flex__left h3 span { color: var(--amber); }
.chart-flex__left p { font-size: var(--fs--1); line-height: 1.65; color: rgba(255,255,255,.75); margin-bottom: 14px; }
.chart-flex__right { flex: 1 1 0; min-width: 0; }
.fc-wrap { position: relative; display: flex; align-items: flex-end; height: 300px; margin-left: 48px; margin-bottom: 48px; border-left: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.fc-y { position: absolute; left: -48px; top: 0; bottom: 0; display: flex; flex-direction: column; justify-content: space-between; align-items: flex-end; padding-right: 8px; }
.fc-y span { font-size: 13px; color: rgba(255,255,255,.4); line-height: 1; }
.fc-bars { display: flex; align-items: flex-end; gap: 12px; height: 100%; width: 100%; padding: 0 10px; position: relative; }
.fc-group { display: flex; flex-direction: column; align-items: center; flex: 1; height: 100%; justify-content: flex-end; position: relative; z-index: 1; }
/* The design's script set these two backgrounds inline while building the bars
   from JavaScript. The chart is server-rendered now, so they belong here — the
   only thing left inline is each bar's height, which is data. */
.fc-bar { width: 100%; border-radius: 2px 2px 0 0; position: relative; min-height: 4px; background: #404040; }
.fc-bar--os { background: var(--amber); box-shadow: 0 0 24px rgba(255,200,68,.35); }
.fc-bar__top { position: absolute; top: -26px; left: 50%; transform: translateX(-50%); font-size: 14px; font-weight: 700; white-space: nowrap; color: var(--white); }
.fc-bar--os .fc-bar__top { color: var(--amber); font-size: var(--fs--1); top: -28px; }
.fc-label { position: absolute; bottom: -40px; left: 50%; transform: translateX(-50%); font-size: 12px; font-weight: 700; color: rgba(255,255,255,.5); text-align: center; text-transform: uppercase; letter-spacing: .4px; white-space: nowrap; line-height: 1.3; }
.fc-threshold { position: absolute; left: 0; right: 0; border-top: 2px dashed rgba(255,200,68,.6); pointer-events: none; z-index: 10; }
.fc-threshold__pill { position: absolute; right: 0; top: 50%; transform: translateY(-50%); background: var(--amber); border-radius: 4px; padding: 4px 10px; font-size: 12px; font-weight: 700; color: var(--ink); white-space: nowrap; box-shadow: 0 4px 12px rgba(0,0,0,.5); }
.fc-legend { display: flex; gap: 24px; flex-wrap: wrap; margin-top: 8px; }
.fc-legend span { display: flex; align-items: center; gap: 8px; font-size: 14px; color: rgba(255,255,255,.6); }
.fc-swatch { width: 14px; height: 14px; border-radius: 2px; flex-shrink: 0; display: inline-block; }
.chart-footnote { margin-top: 24px; font-size: 14px; font-style: italic; color: rgba(255,255,255,.45); }

/* ============================================================
   MEMBERS OF THIS CENTER (dark)
   ============================================================ */
.members { background: var(--bg-dark); }
.members__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: stretch; margin-bottom: 32px; }
.member-quote { background: var(--panel); border: 1px solid var(--line); padding: 40px; display: flex; flex-direction: column; gap: 24px; }
.member-quote__head { display: flex; align-items: center; gap: 16px; }
.member-quote__photo { width: 84px; height: 84px; flex-shrink: 0; border-radius: 50%; overflow: hidden; }
.member-quote__photo .img-ph { width: 100%; height: 100%; padding: 6px; gap: 4px; }
.member-quote__photo .img-ph svg { width: 22px; height: 22px; }
.member-quote__photo .img-ph span { font-size: 8px; letter-spacing: .3px; }
.member-quote__stars { color: var(--amber); letter-spacing: 2px; font-size: var(--fs--1); }
.member-quote__who { font-size: var(--fs--1); font-weight: 700; }
.member-quote__who small { display: block; font-weight: 400; color: rgba(255,255,255,.55); }
.member-quote__text { font-size: var(--fs-0); line-height: 1.65; color: rgba(255,255,255,.82); flex: 1; }
.members__video { display: flex; flex-direction: column; gap: 12px; }
.video-shell { position: relative; width: 100%; aspect-ratio: 16/9; background: #1a1a1a; overflow: hidden; cursor: pointer; }
.video-shell video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.video-shell__poster { position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; background: rgba(0,0,0,.35); transition: opacity .2s; }
.video-shell.is-playing .video-shell__poster { opacity: 0; pointer-events: none; }
.play-btn { width: 68px; height: 68px; border-radius: 50%; background: rgba(255,200,68,.95); display: flex; align-items: center; justify-content: center; transition: transform .2s; }
.video-shell:hover .play-btn { transform: scale(1.08); }
.play-btn svg { width: 26px; height: 26px; fill: var(--ink); margin-left: 3px; }
.video-shell__label { color: rgba(255,255,255,.85); font-size: var(--fs--1); font-weight: 600; }
.disclaimer { font-size: var(--fs--1); font-style: italic; color: rgba(255,255,255,.5); text-align: center; margin-top: 32px; }

/* ============================================================
   DOORS / MODALITIES
   ============================================================ */
.doors { background: var(--bg-dark-2); }
.doors__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; align-items: start; }
.door {
  background: var(--panel); border: 1px solid var(--line); border-top: 4px solid var(--amber);
  padding: 32px; display: flex; flex-direction: column; gap: 14px;
  cursor: pointer; transition: border-color .15s;
}
.door:hover { border-color: var(--amber); }
.door:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.door__kicker { font-size: 15px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: var(--amber); }
.door__title { font-size: var(--fs-1); font-weight: 800; line-height: 1.25; }
.door__body { font-size: var(--fs--1); line-height: 1.6; color: rgba(255,255,255,.75); flex: 1; }
.door__note { font-size: 15px; color: rgba(255,255,255,.55); border-top: 1px solid var(--line); padding-top: 14px; }
.door__toggle {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: var(--fs--1); font-weight: 700; text-transform: uppercase; color: var(--amber);
}
.door__toggle svg { width: 18px; height: 18px; transition: transform .25s; }
.door.is-open .door__toggle svg { transform: rotate(180deg); }
.door__more { overflow: hidden; max-height: 0; transition: max-height .3s ease; }
.door.is-open .door__more { max-height: 560px; }
.door__more-inner { display: flex; flex-direction: column; gap: 16px; padding-top: 16px; border-top: 1px solid var(--line); }
.door__more-inner p { font-size: var(--fs--1); line-height: 1.6; color: rgba(255,255,255,.78); }

.modalities { background: var(--bg-dark); }
/* Flex, not a fixed 5-column grid.
   The design had exactly five modalities, so `repeat(5, 1fr)` was safe. They
   are per-centre now and range 1 to 6 across the live data — 25 centres have
   three, which left two empty columns and the row hanging off to the left.
   Wrapping and centring handles every count, and the max-width stops a single
   modality stretching the full container. */
.modalities__grid { display: flex; flex-wrap: wrap; justify-content: center; gap: 16px; }
/* Exactly six modalities wrap 3 + 3 rather than 5 + 1.
   At full container width six cards do not fit on one row, so the sixth was
   left alone on the second — legible, but it read as an accident. Capping the
   grid's width makes a fourth card unable to fit beside three, which forces the
   even split. Five centres are in this case.

   The :not() matters: :has(:nth-child(6)) alone would also catch seven or more,
   and the catalogue can hold nine. */
.modalities__grid:has(.modality:nth-child(6)):not(:has(.modality:nth-child(7))) {
  max-width: 700px;
  margin-inline: auto;
}

/* Exactly four modalities wrap 2 + 2 below 1024px rather than 3 + 1.
   Four is the second most common count — 46 centres — and at tablet width four
   cards at their flex-basis overflow the row by a dozen pixels, so the fourth
   dropped alone onto the second row.

   Same quantity-query shape as the six rule, and it has to be a rule rather
   than a smaller flex-basis: lowering the basis enough to fit four in one row
   at this width makes FIVE wrap 4 + 1 instead of its current 3 + 2, moving the
   orphan onto the most common count of all rather than removing it.

   Scoped to the breakpoint because four cards already sit in one clean row on
   desktop. */
@media (max-width: 1023px) {
  .modalities__grid:has(.modality:nth-child(4)):not(:has(.modality:nth-child(5))) {
    max-width: 600px;
    margin-inline: auto;
  }
}

/* Exactly five wrap 3 + 2 once all five stop fitting on one row.
   Five is the MOST common count — 49 centres — and five cards need 1064px of
   content, which a viewport narrower than ~1192px does not have. Between there
   and the tablet breakpoint the fifth card dropped alone onto a second row.

   1191px rather than the existing 1023px breakpoint because that is where the
   single row actually stops fitting, measured rather than assumed: at 1024px
   four still fit and the fifth orphans, which the tablet breakpoint alone would
   not have caught. */
@media (max-width: 1191px) {
  .modalities__grid:has(.modality:nth-child(5)):not(:has(.modality:nth-child(6))) {
    max-width: 800px;
    margin-inline: auto;
  }
}

.modality { flex: 1 1 200px; max-width: 280px; background: var(--panel); border: 1px solid var(--line); padding: 24px; display: flex; flex-direction: column; gap: 8px; text-align: center; }
.modality__name { font-size: var(--fs-0); font-weight: 800; }
.modality__desc { font-size: 14px; line-height: 1.5; color: rgba(255,255,255,.65); }
.modalities__note { margin-top: 24px; font-size: var(--fs--1); color: rgba(255,255,255,.6); text-align: center; }

/* ============================================================
   PRICING
   ============================================================ */
.pricing { background: var(--bg-dark-2); }
.tiers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.tier { background: var(--panel); border: 1px solid var(--line); padding: 32px; display: flex; flex-direction: column; gap: 16px; }
.tier--featured { border-color: var(--amber); }
.tier__badge { font-size: var(--fs--1); font-weight: 900; font-style: italic; color: var(--green-accent); min-height: 23px; }
/* Sized so every tier name stays on ONE line. "PLATINUM MEMBERSHIP" is the
   longest and wrapped at --fs-1, leaving its card a line taller than the other
   two above the rule.

   Measured in situ at 1024px, the narrowest width where the grid is still
   three columns and the card therefore narrowest (277px of content): 24px and
   above wraps, 23px fits with no clearance at all, 22px fits with 12px. Taking
   the scale step rather than the exact boundary leaves room for a font
   fallback or a rounding difference to not re-break it.

   Uppercase is why the obvious measurement misleads: a clone that copies `font`
   but not `text-transform` measures the mixed-case string and reports a fit
   that does not exist. */
.tier__name { font-size: var(--fs-0); font-weight: 700; text-transform: uppercase; }
.tier__desc { font-size: var(--fs--1); color: rgba(255,255,255,.7); }
.tier__rule { height: 1px; background: var(--line); }
.tier__starting { font-size: var(--fs--1); color: rgba(255,255,255,.7); }
.tier__price { display: flex; align-items: baseline; gap: 4px; }
.tier__price strong { font-size: var(--fs-6); font-weight: 700; line-height: 1.05; }
.tier__price span { font-size: var(--fs-3); font-weight: 700; }
.tier__monthly { font-size: var(--fs--1); color: rgba(255,255,255,.6); }
.tier ul { list-style: none; display: flex; flex-direction: column; gap: 12px; flex: 1; }
.tier li { display: flex; gap: 10px; font-size: var(--fs--1); align-items: flex-start; }
.tier li::before {
  content: ''; width: 19px; height: 19px; flex-shrink: 0; margin-top: 2px;
  border: 1.5px solid var(--amber); border-radius: 50%;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M6 10l3 3 5-5' stroke='%23ffc844' stroke-width='2' fill='none' stroke-linecap='round'/%3E%3C/svg%3E") center/14px no-repeat;
}
/* The call to action sits on the FLOOR of the card, so the three line up
   however much the copy above them differs — "Platinum Membership" wraps to two
   lines where the others do not, which pushed its button a line lower than the
   rest.

   margin-top: auto on the flex child is what does it. .tier has been a flex
   column all along, and `.tier ul { flex: 1 }` used to do this job, but the
   tiers render no list any more — nothing grows, so nothing pushed the button
   down. The cards are grid items and stretch to equal height already, so
   pinning the button to each card's bottom aligns all three. */
.tier .hero__actions { margin-top: auto; }
.tier .btn { width: 100%; }
.pricing__terms { text-align: center; font-size: var(--fs--1); font-style: italic; color: rgba(255,255,255,.65); margin-top: 40px; }

/* Wellness tooltip (matches marketing landing page) */
.wellness-info { display: inline-flex; align-items: center; gap: 4px; position: relative; }
.wellness-trigger {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 50%;
  border: 1.5px solid rgba(255,255,255,.5); color: rgba(255,255,255,.7);
  font-size: 12px; font-weight: 700; cursor: pointer; flex-shrink: 0;
  transition: border-color .15s, color .15s; background: transparent;
  line-height: 1; vertical-align: middle; margin-left: 4px;
}
.wellness-trigger:hover, .wellness-trigger:focus-visible { border-color: var(--amber); color: var(--amber); outline: none; }
.wellness-tooltip {
  display: none; position: absolute; bottom: calc(100% + 10px); left: 50%;
  transform: translateX(-50%); background: #2a2a2a;
  border: 1px solid rgba(255,200,68,.3); border-radius: 8px;
  padding: 16px; width: 280px; z-index: 100; box-shadow: 0 8px 24px rgba(0,0,0,.5);
}
.wellness-info:hover .wellness-tooltip,
.wellness-trigger:focus-visible + .wellness-tooltip,
.wellness-info:focus-within .wellness-tooltip,
.wellness-info.is-open .wellness-tooltip { display: block; }
.wellness-tooltip__title { display: block; font-size: 13px; font-weight: 700; color: var(--amber); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 10px; }
.wellness-tooltip ul { list-style: none; display: flex; flex-direction: column; gap: 6px; }
.wellness-tooltip li { font-size: 14px; color: var(--white); line-height: 1.4; display: flex; align-items: baseline; gap: 8px; }
.wellness-tooltip li::before { content: '·'; color: var(--amber); flex-shrink: 0; border: none; width: auto; height: auto; background: none; margin: 0; }
.wellness-tooltip::after {
  content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: #2a2a2a;
}

/* ============================================================
   FAQ / VISIT / MAP
   ============================================================ */
.faq { background: var(--bg-dark); }
.faq__list { max-width: 800px; margin: 0 auto; border-bottom: 1px solid var(--line); }
.faq-item { border-top: 1px solid var(--line); }
.faq-item__q { display: flex; align-items: center; gap: 24px; width: 100%; padding: 24px 0; text-align: left; font-size: var(--fs-0); font-weight: 700; line-height: 1.35; color: var(--amber); }
.faq-item__q:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.faq-item__q .chev { width: 28px; height: 28px; flex-shrink: 0; transition: transform .25s; color: var(--white); }
.faq-item.is-open .chev { transform: rotate(180deg); }
.faq-item__a { overflow: hidden; max-height: 0; transition: max-height .3s ease; }
.faq-item__a p { padding: 0 48px 24px 0; font-size: var(--fs--1); line-height: 1.65; color: rgba(255,255,255,.8); }
.faq-item.is-open .faq-item__a { max-height: 460px; }

.visit { background: var(--bg-dark-2); padding-bottom: 0; }
.visit__grid { display: flex; gap: 32px; align-items: stretch; margin-bottom: 80px; }
.visit__card { flex: 1 1 0; background: var(--panel); border: 1px solid var(--line); padding: 40px; display: flex; flex-direction: column; gap: 24px; }
.visit__card h3 { font-size: var(--fs--1); font-weight: 800; text-transform: uppercase; letter-spacing: .5px; color: var(--amber); }
.visit__address { font-size: var(--fs-0); line-height: 1.6; color: rgba(255,255,255,.85); }
/* Contact details, not a call to action — which is the whole point of their
   having moved here. Styled like the address they sit under rather than like
   the button they used to be. */
.visit__contact { margin-top: 12px; font-size: var(--fs-0); line-height: 1.8; }
.visit__contact a { color: var(--amber); text-decoration: underline; }
.visit__contact a:hover { color: var(--amber-dark); }
.visit__contact .visit__email { display: block; }
.visit__hint { font-size: var(--fs--1); color: rgba(255,255,255,.6); }
.visit__actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: auto; }
.hours-table { width: 100%; border-collapse: collapse; font-size: var(--fs--1); }
.hours-table td { padding: 8px 0; color: rgba(255,255,255,.75); border-bottom: 1px solid rgba(255,255,255,.06); }
.hours-table td:last-child { text-align: right; font-weight: 600; color: var(--white); }
.hours-table tr.today td { color: var(--amber); font-weight: 800; }
.hours-table tr.today td:first-child::after { content: ' · today'; font-size: 12px; text-transform: uppercase; }

.mapband { position: relative; }
/* Replaces the design's .img-ph placeholder with the real static map. The
   background shows while the image loads, so the band never flashes white on
   a black page. */
.mapband__map {
  display: block; width: 100%; height: 380px;
  object-fit: cover; background: var(--bg-dark-2);
}
.mapband__card {
  position: absolute; left: var(--pad); top: 50%; transform: translateY(-50%);
  background: var(--bg-dark); border: 1px solid var(--line);
  padding: 32px; max-width: 360px; display: flex; flex-direction: column; gap: 10px;
  box-shadow: 0 20px 50px rgba(0,0,0,.5);
}
.mapband__card strong { font-size: var(--fs-1); line-height: 1.25; }
.mapband__card p { font-size: var(--fs--1); color: rgba(255,255,255,.75); line-height: 1.55; }
.mapband__card a { color: var(--amber); font-weight: 700; font-size: var(--fs--1); text-decoration: underline; text-underline-offset: 3px; }

/* ============================================================
   FOOTER + MOBILE CTA DOCK + MODALS
   ============================================================ */
.footer { background: #000; padding: 64px 0; }
.footer__inner { display: flex; flex-direction: column; gap: 32px; }
.footer__logo img { width: 220px; height: auto; }
.footer__legal { font-size: 14px; line-height: 1.7; color: rgba(255,255,255,.5); max-width: 900px; }
.footer__bottom { display: flex; justify-content: space-between; gap: 24px; border-top: 1px solid var(--line); padding-top: 24px; font-size: 14px; color: rgba(255,255,255,.65); flex-wrap: wrap; }
.footer__links { display: flex; gap: 24px; flex-wrap: wrap; }
.footer__links a { text-decoration: underline; text-underline-offset: 2px; }

.cta-dock {
  display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  background: rgba(15,16,20,.95); backdrop-filter: blur(8px);
  border-top: 1px solid var(--line); padding: 12px 16px;
}
.cta-dock .btn { width: 100%; }

/* The design's free-session modal, unused: the booking widget is embedded
   inline instead. Kept because it is the design's, and a later change may want
   it — see docs for why the modal was not the shape this needed. */
.fs-modal { display: none; position: fixed; inset: 0; z-index: 9999; align-items: center; justify-content: center; }
.fs-modal.is-open { display: flex; }
.fs-modal__overlay { position: absolute; inset: 0; background: rgba(0,0,0,.7); }
.fs-modal__box { position: relative; z-index: 1; width: 90%; max-width: 700px; height: 85vh; max-height: 720px; overflow: hidden; border-radius: 12px; box-shadow: 0 20px 60px rgba(0,0,0,.4); }
.fs-modal__close { position: absolute; top: 12px; right: 16px; z-index: 2; font-size: 28px; line-height: 1; color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.5); }
.fs-modal__box iframe { width: 100%; height: 100%; border: none; }

/* The booking flow's own page: bar, rail, headings, hand-off.

   Scoped under .landing like everything else in this file, because the flow
   layout wraps its body in that class to inherit the palette and --pad. */
.bookflow__bar {
  display: flex; justify-content: center; align-items: center;
  padding: 18px var(--pad); background: var(--bg-dark-2);
}
.bookflow__bar img { height: 22px; width: auto; }

.bookflow { padding: 48px 0 96px; }
/* Wide enough for the calendar's three-column layout. Below about 1040px the
   widget falls back to a cramped two-column mode — calendar left, times right,
   its month header centred over the calendar rather than the card — which
   reads as a calendar that is not centred, and puts the time list behind its
   own scrollbar. Measured against the widget, not guessed. */
.bookflow__inner { max-width: 1140px; text-align: center; }
.bookflow__title, .bookflow__lede, .bookflow__where { max-width: 860px; margin-inline: auto; }

/* The rail reads as progress on its own, so its label is visually hidden
   rather than drawn: a bar with no accessible name tells a screen reader
   nothing, and a percentage tells it less than "step 1 of 2". */
.bookflow__rail {
  height: 3px; margin: 0 auto 20px; max-width: 460px;
  background: rgba(255,255,255,.18); border-radius: 2px; overflow: hidden;
}
.bookflow__rail span { display: block; height: 100%; background: var(--amber); }

.bookflow__where {
  font-size: var(--fs--1); font-weight: 700; letter-spacing: .5px;
  color: var(--white);
}
.bookflow__title {
  margin-top: 6px; font-weight: 800; text-transform: uppercase;
  line-height: 1.05; font-size: clamp(28px, 4.2vw, 44px); color: var(--white);
}
.bookflow__lede { margin-top: 8px; font-size: var(--fs--1); color: rgba(255,255,255,.72); }
/* No ground of its own. The widget paints its own background, and which one
   varies by centre — Classic City's form and calendar are both dark, Anchorage's
   calendar is light — so any colour we put behind it is wrong for half of them.
   White showed as a sliver above the frame and a margin down each side. */
.bookflow .booking__frame {
  margin-top: 28px; background: transparent; border-radius: 0; max-width: 1100px;
}
/* Lead capture cannot be auto-sized — see the comment in the view. A survey's
   own card measured about 490px and a form's about 570px, so this clears both
   with room for their longer steps. */
.bookflow .booking__frame--lead,
.bookflow .booking__frame--lead iframe { height: 880px; min-height: 880px; }

/* The booking widget.

   White, because GoHighLevel renders both the survey and the calendar on a
   light ground and a dark surround would frame them as a pasted-in rectangle.

   min-height reserves the frame's space so the section does not collapse and
   then jump when the widget reports its real height. The frame starts at the
   same value, so with no JavaScript it is still usable — just fixed. */
.booking__frame {
  max-width: 760px;
  margin: 0 auto;
  background: var(--white);
  border-radius: 8px;
  overflow: hidden;
  min-height: 720px;
}
.booking__frame iframe { width: 100%; height: 720px; border: 0; display: block; }

/* Location switcher modal */
/* Unified light switcher (Figma 12466:17751) — tokens per design.md:
   Text/primary #1c1c1c, Text/secondary #767676, Border/low #dcdcdc,
   Surface/medium #f4f4f4, Interactive/primary var(--amber). */
.loc-modal { display: none; position: fixed; inset: 0; z-index: 9998; align-items: flex-start; justify-content: center; padding: 6vh 16px; }
.loc-modal.is-open { display: flex; }
.loc-modal__overlay { position: absolute; inset: 0; background: rgba(0,0,0,.6); }
.loc-modal__box {
  position: relative; z-index: 1; width: 100%; max-width: 528px; max-height: 84vh;
  background: #fff; color: #1c1c1c; border: 1px solid #e5e7eb; border-radius: 16px;
  box-shadow: 0 12px 32px -4px rgba(0,0,0,.12);
  display: flex; flex-direction: column; gap: 16px; padding: 24px;
}
.loc-modal__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.loc-modal__hcol { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.loc-modal__title { font-size: 40px; line-height: 44px; font-weight: 700; color: #1c1c1c; }
.loc-modal__subtitle { font-size: 18px; line-height: 28px; color: #767676; }
.loc-modal__close {
  flex-shrink: 0; width: 44px; height: 44px; border-radius: 9999px;
  border: 1px solid #dcdcdc; background: #fff; color: #1c1c1c;
  display: flex; align-items: center; justify-content: center;
}
.loc-modal__close:hover { background: #f8f8f8; }
.loc-modal__close svg { width: 16px; height: 16px; }
.loc-modal__search-row { display: flex; align-items: center; gap: 8px; }
.loc-modal__search {
  flex: 1; min-width: 0; background: #fff; border: 1px solid #dcdcdc;
  color: #1c1c1c; font-family: var(--font); font-size: 16px; line-height: 24px;
  padding: 10px; border-radius: 0;
}
.loc-modal__search:focus { outline: none; border-color: var(--amber); box-shadow: 0 0 0 1px var(--amber); }
.loc-modal__search::placeholder { color: #767676; }
.loc-modal__go {
  flex-shrink: 0; background: var(--amber); color: #1c1c1c; font-family: var(--font);
  font-weight: 800; font-size: 16px; line-height: 18px; text-transform: uppercase;
  padding: 14px 24px; transition: background .15s ease;
}
.loc-modal__go:hover { background: var(--amber-dark); }
.loc-modal__count { font-size: 16px; line-height: 24px; color: #1c1c1c; }
.loc-modal__list { overflow-y: auto; flex: 1; display: flex; flex-direction: column; gap: 16px; }
.loc-card {
  display: flex; flex-direction: column; gap: 8px; width: 100%; flex-shrink: 0;
  text-align: left; background: #fff; border: 1px solid #dcdcdc; border-radius: 8px;
  padding: 16px; color: #1c1c1c; font-family: var(--font); cursor: pointer;
  transition: border-color .15s ease;
}
.loc-card:hover { border-color: #404040; }
.loc-card.is-current { border: 2px solid var(--amber); padding: 15px; }
/* Hover: title underlines like the design-system Link (design.md §11). */
.loc-card:hover .loc-card__name { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
/* Body row per Figma 12504:11525 — address/distance column + a square amber
   44px icon-only chevron button (decorative: the card is the single click target). */
.loc-card__body { display: flex; align-items: center; gap: 16px; width: 100%; }
.loc-card__content { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.loc-card__btn {
  flex-shrink: 0; width: 44px; height: 44px; background: var(--amber); color: #1c1c1c;
  display: flex; align-items: center; justify-content: center; transition: background .15s ease;
}
.loc-card__btn svg { width: 16px; height: 16px; display: block; }
.loc-card:hover .loc-card__btn { background: var(--amber-dark); }
.loc-card__flag {
  display: flex; align-items: center; gap: 6px;
  font-size: 14px; line-height: 16px; font-weight: 600; text-transform: uppercase; color: #404040;
}
.loc-card__flag::before { content: ''; width: 10px; height: 10px; border-radius: 50%; background: var(--amber); }
.loc-card__name { font-size: 32px; line-height: 36px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.loc-card__chip {
  align-self: flex-start; background: #f4f4f4; border: 1px solid #dcdcdc; border-radius: 6px;
  padding: 4px 8px; font-size: 12px; line-height: 16px; font-weight: 600; text-transform: uppercase;
}
.loc-card__addr { font-size: 18px; line-height: 28px; }
.loc-card__dist { display: flex; align-items: center; gap: 6px; font-size: 14px; line-height: 20px; }
.loc-card__dist svg { width: 14px; height: 14px; flex-shrink: 0; }
.loc-modal__empty { padding: 24px 0; text-align: center; color: #767676; font-size: 16px; }
.loc-modal__all {
  display: flex; align-items: center; justify-content: center; width: 100%;
  background: var(--amber); color: #1c1c1c; font-family: var(--font);
  font-weight: 800; font-size: 16px; line-height: 18px; text-transform: uppercase;
  padding: 14px 24px; text-decoration: none; transition: background .15s ease;
}
.loc-modal__all:hover { background: var(--amber-dark); }
@media (max-width: 767px) {
  .loc-modal__box { padding: 16px; }
  .loc-modal__title { font-size: 32px; line-height: 36px; }
  .loc-card__name { font-size: 24px; line-height: 28px; }
}

/* ============================================================
   RESPONSIVE — mobile-first stacking
   ============================================================ */
@media (max-width: 1023px) {

  .hero__title { font-size: var(--fs-4); max-width: 18ch; }
  .step { flex-wrap: wrap; gap: 24px; }
  .step__media { flex: 1 1 100%; height: 220px; order: 3; }
  .stats-row, .doors__grid, .tiers, .members__grid, .firstvisit { grid-template-columns: 1fr; }
  .chart-flex { flex-direction: column; gap: 36px; }
  .chart-flex__left { flex: none; }
  .space__grid { grid-template-columns: 1fr; gap: 36px; }
  .visit__grid { flex-direction: column; }
}
@media (max-width: 767px) {
  .fc-label { font-size: 8.5px; letter-spacing: .2px; }

  .section { padding: 64px 0; }
  .header__right .btn { display: none; }
  .header__logo img { width: 170px; }
  .crumbbar__inner { flex-wrap: wrap; }
  .breadcrumb ol li.crumb-mid { display: none; } /* parent + current only on mobile per design.md */
  .hero__title { font-size: var(--fs-2); max-width: none; }
  .hero__inner { padding-top: 56px; padding-bottom: 64px; }
  .hero__address { font-size: var(--fs-0); }
  .hero__actions { flex-direction: column; align-items: stretch; width: 100%; }
  .section-heading { font-size: var(--fs-3); }
  .lede { font-size: var(--fs-0); }
  .step__num { flex: 0 0 56px; width: 56px; height: 56px; font-size: var(--fs-1); }
  .fc-wrap { height: 210px; }
  .fc-threshold__pill { right: auto; left: 0; transform: translateY(-120%); font-size: 10px; padding: 3px 6px; }
  .chart-flex { padding: 24px 16px; }
  .faq-item__a p { padding-right: 0; }
  .tier__price strong { font-size: var(--fs-5); }
  .mapband__card { position: static; transform: none; max-width: none; margin: 0 var(--pad); top: auto; }
  .mapband__map { height: 240px; }
  .mapband { display: flex; flex-direction: column-reverse; gap: 16px; padding-bottom: 24px; }
  .cta-dock { display: block; }
}

  /* --- consent banner ---------------------------------------------------- */

  /* Nested inside `.landing`, not left at the top level: landing.css is loaded
     on EVERY page by stylesheet_link_tag :app, so an unscoped rule here
     reaches the whole application. test/infrastructure/brand_css_test.rb
     enforces that and caught this. Both gated layouts wrap their content in
     <div class="landing">, so the banner is rendered inside it. */

  /* Fixed to the bottom rather than a full-screen overlay: this is a choice,
     not a wall, and a modal would stop a visitor reading the page it asks
     about. */
  .consent-banner {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    /* ABOVE the mobile CTA dock, which is also bottom-fixed at z-index 90.
       At 60 the dock covered the consent actions below 768px — including the
       Accept button on a narrow screen, leaving a visitor unable to consent at
       all. Found in review. */
    z-index: 95;
    display: flex;
    justify-content: center;
    padding: 16px;
    background: var(--panel);
    border-top: 1px solid var(--line);
    color: var(--white);
    /* With the category panel open on a short screen, or with enlarged text,
       the banner used to grow past the top of the viewport — and because it is
       bottom-fixed, scrolling the PAGE could not bring its heading or controls
       back. It scrolls itself instead. dvh so a mobile browser's collapsing
       toolbar does not hide the Save button. Found in review. */
    max-height: 100dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* THE rule that makes the `hidden` attribute work.

     `hidden` hides an element only because the User-Agent stylesheet says
     `[hidden] { display: none }` — a low-priority rule that ANY author
     `display` declaration outranks, regardless of specificity. Without this
     the banner renders VISIBLE on every page load until JavaScript hides it,
     and for a visitor who already consented it is never hidden at all. */
  .consent-banner[hidden] { display: none; }

  .consent-banner__inner {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: 100%;
    max-width: var(--page-max);
  }

  .consent-banner__heading {
    font-size: var(--fs--1);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }

  .consent-banner__body {
    font-size: var(--fs--1);
    line-height: 1.45;
    max-width: 68ch;
  }

  .consent-banner__panel {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px 0;
    border-top: 1px solid var(--line);
  }

  /* Same shape as the banner, so the same trap. */
  .consent-banner__panel[hidden] { display: none; }

  .consent-banner__option {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--fs--1);
  }

  .consent-banner__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }

  /* At 320px three buttons will not share a line; let them stack rather than
     push the viewport sideways. */
  @media (max-width: 420px) {
    .consent-banner__actions .btn { flex: 1 1 100%; }
  }

  /* The booking funnel's withdraw affordance. Quiet by design: the funnel's
     job is the booking, and this is a legal affordance, not a CTA. */
  .bookflow__consent {
    padding: 24px 16px 32px;
    text-align: center;
    font-size: var(--fs--1);
    color: var(--white);
    opacity: 0.7;
  }

  /* The reopen trigger, styled to sit in the footer's legal row. */
  .footer__consent-link {
    font: inherit;
    color: inherit;
    text-decoration: underline;
  }
}

/* ---------------------------------------------------------------------------
   Collapsible content defaults to OPEN
   ---------------------------------------------------------------------------
   The design collapses FAQ answers and the persona-card detail with
   `max-height: 0`, revealing them only when JavaScript adds `.is-open`. That
   makes the content unreadable without JavaScript — and invisible to crawlers,
   on a page whose whole purpose is local SEO.

   So the closed state is applied by the CONTROLLER on connect
   (`.js-collapsible`), not by the stylesheet. No JavaScript means everything is
   readable; with JavaScript the accordions behave as designed. The progressive
   enhancement direction the design had backwards.
   --------------------------------------------------------------------------- */
.landing {
  .faq-item__a,
  .door__more { max-height: none; }

  /* The controller adds this to the scope root on connect. */
  &.js-collapsible {
    /* visibility, not max-height alone.
       max-height: 0 hides a panel visually but leaves it in the accessibility
       tree, and the CTA links inside .door__more stayed keyboard-focusable
       while invisible — tab into the page and focus disappears into a
       collapsed panel. `visibility: hidden` removes it from both, and unlike
       `display: none` it still animates.
       The delay matches the transition so the panel stays visible while it
       closes, and becomes visible immediately when it opens. */
    .faq-item__a,
    .door__more {
      max-height: 0;
      visibility: hidden;
      transition: max-height .3s, visibility 0s linear .3s;
    }

    .faq-item.is-open .faq-item__a,
    .door.is-open .door__more {
      max-height: 560px;
      visibility: visible;
      transition: max-height .3s, visibility 0s;
    }
  }
}

/* ---------------------------------------------------------------------------
   Reviews (shared Elfsight widget)
   ---------------------------------------------------------------------------
   The design had no reviews section — its two testimonials were hand-written
   markup. The widget mounts client-side and late, so its space is reserved in
   the partial with an inline min-height to keep it from shoving the video down
   the page when it arrives.
   --------------------------------------------------------------------------- */
.landing {
  /* min-height reserves the widget's space so its late mount does not shove the
     video and the disclaimer down the page.

     MEASURED against the live widget rather than guessed: it settles at 312px
     from 768px up and 243-266px below that, and stays there. The previous 480px
     was sized for an earlier grid-style widget and left 168px of dead space
     under the carousel that replaced it. Re-measure if the widget is swapped
     again — this number is a property of the widget, not of the page. */
  .reviews { margin-bottom: 48px; min-height: 320px; }

  /* The carousel renders shorter on a phone, so it reserves less. */
  @media (max-width: 767px) {
    .reviews { min-height: 280px; }
  }
}
