@import url("/static/fonts.css");
/* The Healing Collective — public marketing site.
 *
 * CONSUMES static/tokens.css and adds no colour of its own. There is not a
 * single hex literal, rgba() or named colour in this file: every value comes
 * from a semantic token (DECISIONS D22). If a shade is missing, add a token
 * — do not inline one here.
 *
 * Contrast, verified against the ratios recorded in tokens.css:
 *   --color-text        on --color-bg          13.9:1  AA ✓
 *   --color-text-muted  on --color-bg           7.2:1  AA ✓
 *   --color-text-on-dark on --color-surface-dark 6.4:1  AA ✓
 *   --color-primary     on --color-surface      7.05:1 AA ✓
 * --color-accent is 3.74:1 and is used for RULES AND BORDERS ONLY, never for
 * text (same rule templates/events.html follows).
 *
 * Mobile-first: the base rules are the phone layout, and the two breakpoints
 * (40rem, 60rem) only add. No JavaScript — the nav wraps instead of toggling,
 * so the site cannot break with scripts blocked.
 */

:root { color-scheme: light; }

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

body, h1, h2, h3, h4, p, ul, ol, li, figure, table, blockquote {
  margin: 0;
  padding: 0;
}

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
}

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

a { color: var(--color-primary); }

:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
}

/* On the olive surfaces the gold focus ring all but disappears, so those
   regions switch to the bone outline they already contrast against. */
.hero__panel :focus-visible,
.footer :focus-visible {
  outline-color: var(--color-text-on-dark);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--color-surface);
  border-radius: var(--radius);
  z-index: 10;
}
.skip-link:focus { left: var(--space-4); }

/* Text for screen readers only. Used to give repeated links ("Book this
   room") a distinct accessible name without shouting the room name twice on
   screen. Clipped rather than display:none, which would hide it from
   assistive tech as well. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------- masthead */

/* Sticky slim bar: logo left, links right on desktop; a hamburger drawer on
   phones. It occupies flow (sticky, not fixed) so nothing needs padding to
   sit clear of it. site.js adds .is-scrolled once you leave the very top. */
/* TRANSPARENT, AND IT SCROLLS AWAY. Both measured on their live site, at the
   top of the page and again after scrolling 600px:

                          theirs                    ours before
     background           rgba(0,0,0,0) at both     cream 92% + 8px blur
     after scrolling 600  top -131, gone            top 0, still pinned

   Ours painted a cream bar across the top of every page and then followed you
   down it. On the home page that bar sat over the hero — the photograph
   starts at y78 and reaches UP behind the header on both sites, so theirs
   shows through it and ours covered it, cutting the top off "The Healing
   Collective". That is what Steve photographed.

   Their #SITE_HEADER computes position:sticky but carries no top offset, so
   sticky never engages and it behaves as a normal block that leaves with the
   page. position:static is the same behaviour said plainly.

   The trade-off is real and deliberate: the nav is no longer reachable once
   you scroll, on desktop AND on phones, where it takes the menu button with
   it. That is how their site behaves and matching it was the instruction. If
   we would rather keep a pinned nav, this rule is the one to change back —
   but then it needs a background again, because black links over a
   photograph are not legible.

   .is-scrolled went with it: site.js still adds the class, but a border and
   shadow on a bar that is gone by the time you have scrolled is nothing. */
.masthead {
  /* Sticky and TRANSPARENT. Two separate facts, both measured on theirs.
     Transparent is why the home hero photograph — which starts at y78 on both
     sites, above the header — shows through instead of being covered by a
     cream bar that also clipped the top of the heading.
     Sticky because their header does come back: it hides on the way down and
     returns on the way up (see the scroll walk in site.js). A version of this
     rule that simply scrolled away lost the nav for the rest of the page. */
  position: sticky;
  top: 0;
  z-index: 50;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: top .28s ease, border-color .25s ease;
}

/* NO transform, filter or backdrop-filter on .masthead or .masthead__inner,
   ever. On phones the nav drawer lives INSIDE this header and is
   position:fixed, parked off the right edge with translateX(100%). Any of
   those properties on an ancestor makes that ancestor the drawer's containing
   block instead of the viewport, and a fixed box that is no longer
   viewport-fixed counts toward the page's width. Measured at 375 on every
   public page: scrollWidth 375 at the top, 667 as soon as you scrolled —
   .is-scrolled (backdrop-filter) and .is-tucked (translateY) each did it on
   their own, and the page scrolled sideways onto an invisible menu.

   So the frosted background lives on a pseudo-element BEHIND the content
   (not an ancestor of the drawer), and the tuck moves the sticky offset
   instead of transforming the box. tests/test_no_sideways_scroll.py holds
   this line. */
.masthead::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  transition: background .25s ease;
}

/* Off the top of the page: give the links something to sit on. See site.js
   for why this is a deliberate difference from theirs. */
.masthead.is-scrolled {
  border-bottom-color: var(--color-border);
  box-shadow: 0 2px 14px rgba(45, 45, 35, .06);
}
.masthead.is-scrolled::before {
  background: color-mix(in srgb, var(--color-bg) 92%, transparent);
  backdrop-filter: saturate(1.1) blur(8px);
}

/* Tucked away while you scroll down: a sticky box whose top offset is minus
   its own height sits exactly above the viewport, which is where
   translateY(-100%) used to put it. site.js keeps --masthead-h equal to the
   header's rendered height (77px on a phone, 131px on desktop, taller if the
   desktop links wrap); the fallback only matters if that script never ran,
   and then nothing adds .is-tucked anyway. */
.masthead.is-tucked { top: calc(-1 * var(--masthead-h, 8.5rem)); }

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

.masthead__inner {
  max-width: 76rem;
  margin: 0 auto;
  padding: var(--space-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.wordmark { display: block; color: var(--color-text); text-decoration: none; flex: 0 0 auto; }

.wordmark__logo {
  height: 2.4rem;
  width: auto;
  max-width: 100%;
  font-family: var(--font-display);
  font-size: 1.4rem;
  letter-spacing: .04em;
  line-height: var(--leading-tight);
  color: var(--color-text);
  /* no height transition: nothing animates the logo any more, and a stray
     one is how the bounce got in. */
}

@media (min-width: 48rem) {
  /* Theirs renders 248x64 at 1280px; ours was ~175 wide. The wordmark is
     415x121, so 64px tall gives 219 wide — 4rem lands it on their size. */
  .wordmark__logo { height: 4rem; }
  /* NO shrink-on-scroll. Mariah: "the logo is still kind of bouncing."
     .wordmark__logo carries `transition: height .25s ease`, and is-scrolled
     toggles at 8px of scroll, so the logo animated between 4rem and 3.2rem
     every time you crossed that line — and with a trackpad you cross it
     constantly. Theirs is one fixed size at every scroll position. */

  /* Their bar is 131px tall; ours was 97px. Both carry the same 64px logo, so
     every one of those 34px is padding: they breathe 33px above and below the
     wordmark, we were breathing 16px. This is not a cosmetic detail — the
     masthead pushes every band down the page, so a short bar puts every
     heading on every page 34px above where theirs sits. Measured: theirs
     logo y=33 in a 131px bar, ours y=16 in a 97px bar. */
  .masthead__inner { padding-block: 33px; }

  /* Full-bleed, like theirs. Their logo sits 50px from the left edge and the
     nav's last link ends 47px from the right edge at EVERY width — measured
     at 1280, 1512, 1728 and 2100. Ours was a 76rem box centred in the window,
     which lands in nearly the same place at 1280 and nowhere near it after
     that: at 1728 our logo was at x272 against their x50, and our nav ended
     272px from the right edge against their 47. That is the menu sitting
     centred on ours and hard right on theirs. */
  .masthead__inner { max-width: none; padding-inline: 50px 47px; }
}

/* ---- the hamburger (mobile only) ---- */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--color-text);
}

.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  display: block;
  width: 22px;
  height: 2px;
  background: currentColor;
  transition: transform .25s ease, opacity .25s ease;
}
.nav-toggle__bars { position: relative; }
.nav-toggle__bars::before { position: absolute; top: -7px; left: 0; }
.nav-toggle__bars::after  { position: absolute; top:  7px; left: 0; }

.nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after  { transform: translateY(-7px) rotate(-45deg); }

/* ---- the nav ---- */
/* Measured off the live site at 1280px on 2026-09-04. The nav's POSITION
   already matched almost exactly (theirs spans 352->1233, ours 352->1232);
   what made it read as a different menu entirely was its texture:

     theirs  18px, Title Case, 0.9px tracking, near-black
     ours    14px, UPPERCASE,  1.68px tracking, muted grey

   Small wide-tracked caps read as one compact block; their larger title-case
   words read as separate items spread across the bar. Same coordinates, very
   different shape. */
.nav__link {
  font-size: 1.125rem;              /* 18px */
  letter-spacing: .05em;            /* ~0.9px at 18px */
  /* Theirs is Lato LIGHT (Wix ships it as a family called "lato-light" at
     weight 400). Ours is one Lato family, so their Light is our 300. At 400
     every label rendered 2-5px wider and read heavier than theirs — the
     nav looked darker without any colour being wrong. */
  font-weight: 300;
  text-transform: none;
  /* Pure black, not our ink. Measured rgb(0,0,0) on every inactive link. */
  color: #000;
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 0;
}
.nav__link:hover,
.nav__link:focus-visible { color: rgba(45, 45, 35, .72); }

/* The CURRENT page fades rather than underlines. Measured on the live site:
   the active link is rgba(45,45,35,0.51) — ink at about half strength — with
   text-decoration none and a 0px bottom border. We were drawing an accent
   underline instead, which reads as a different navigation entirely: theirs
   recedes to show you where you are, ours points at it. */
.nav__link[aria-current="page"] {
  color: rgba(45, 45, 35, .51);
  border-bottom: 0;
  text-decoration: none;
}

/* Mobile (< 48rem): nav is an off-canvas drawer sliding in from the right. */
@media (max-width: 47.99rem) {
  .nav {
    position: fixed;
    top: 0;
    right: 0;
    height: 100dvh;
    width: min(78vw, 20rem);
    background: var(--color-surface-dark);
    color: var(--color-text-on-dark);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: calc(var(--space-16) + env(safe-area-inset-top, 0)) var(--space-6) var(--space-8);
    transform: translateX(100%);
    transition: transform .3s cubic-bezier(.4, 0, .2, 1);
    z-index: 60;
    overflow-y: auto;
    /* A drawer moved out of sight by a transform alone is still FOCUSABLE,
       so a keyboard user tabbing a phone page walked into an invisible menu.
       That is fixed with the `inert` attribute in site.js rather than here:
       a CSS visibility transition looked tidier but did not reliably flip
       back to hidden after the drawer had been opened once, which left the
       links focusable again — verified in a browser before choosing. */
  }
  .nav.is-open { transform: translateX(0); }
  .nav__link {
    color: var(--color-text-on-dark);
    font-size: 1rem;
    padding: var(--space-3) 0;
    border-bottom: 1px solid color-mix(in srgb, var(--color-text-on-dark) 18%, transparent);
  }
  .nav__link[aria-current="page"] { color: rgba(224, 222, 210, .55); }

  .nav-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(45, 45, 35, .5);
    z-index: 55;
  }
  /* The drawer's z-index 60 only ranks it INSIDE the header, which is its own
     stacking context at 50 — below this backdrop at 55. So the backdrop lay
     over the open drawer: it dimmed the links, and every tap on one landed on
     the backdrop, which closes the menu. Tapping "Reiki-The Initiation" closed
     the drawer and stayed on the page (clicked in a browser at 375, top of the
     page and scrolled). While the drawer is open the whole header goes above
     the backdrop; site.js sets the class in open() and clears it in close(). */
  .masthead.is-nav-open { z-index: 56; }
}

/* Desktop (>= 48rem): a plain horizontal row; hide the hamburger + drawer. */
@media (min-width: 48rem) {
  .nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3) 36px;   /* measured: 36px between every link */
    align-items: center;
    justify-content: flex-end;
  }
  .nav-toggle { display: none; }
  .nav-backdrop { display: none !important; }
}

/* "Log in" is the seventh link in the row (Mariah, 14 Oct). The six Wix links
   plus it need ~1400px at the measured 36px gap; below that they would wrap
   onto a second line, so the gap tightens to 22px from 48rem up to 87.5rem.
   At 87.5rem and wider nothing here applies and the gap is the measured 36px.
   Measured 14 Oct in headless Chrome: one row at 1280 and wider; at 1180 and
   narrower the row wraps onto a second line. */
@media (min-width: 48rem) and (max-width: 87.49rem) {
  .nav { column-gap: 22px; }
}

/* ----------------------------------------------------------------- hero */

/* ============================================================ HOME + HEROES
 *
 * Rebuilt 2026-08-30 to match how the live Wix site actually MOVES, not just
 * its colours: real side-by-side splits (they were stacking a full-width 4:5
 * image under the text, which is the "huge image" everyone saw), one pinned
 * parallax band you scroll OVER, and sections that overlap instead of sitting
 * cleanly before/after each other.
 *
 * The reveal-on-scroll this comment used to describe was removed on
 * 2026-09-06: their site has no such effect, and ours was shifting and
 * fading content mid-measurement. See the note above @keyframes.
 */

.hero {
  background: var(--color-surface-dark);
  color: var(--color-text-on-dark);
}

.hero__panel {
  max-width: 72rem;
  margin: 0 auto;
  padding: var(--space-12) var(--space-4);
}

.hero__eyebrow {
  font-size: var(--text-small);
  letter-spacing: .14em;
  text-transform: uppercase;
  margin-bottom: var(--space-4);
}

.hero__eyebrow a { color: inherit; }

.hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(var(--text-h1), 6vw, var(--text-hero));
  line-height: var(--leading-tight);
  letter-spacing: .01em;
  max-width: 22ch;
}

.hero__subtitle {
  margin-top: var(--space-6);
  max-width: 46ch;
  font-size: 1.0625rem;
}

.hero__byline {
  font-size: var(--text-small);
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* A hero with no photograph is a deliberate type panel, not a gap. */
.hero--type .hero__panel { padding-top: var(--space-16); }

.hero--type .hero__title::before {
  content: "";
  display: block;
  width: 3.5rem;
  border-top: 2px solid var(--color-accent);
  margin-bottom: var(--space-8);
}

/* ---- the split hero: text panel + photo, SIDE BY SIDE on desktop ----
 * The whole hero is one capped-height row. The photo fills its half via
 * object-fit, so it never dictates the height — that was the stacked-4:5 bug.
 */
.hero--split { display: block; }

.hero--split .hero__media {
  aspect-ratio: 3 / 2;      /* mobile: a calm banner, not a 4:5 monolith */
}

@media (min-width: 60rem) {
  .hero--split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: stretch;
    min-height: min(86vh, 760px);
  }
  .hero--split .hero__panel {
    display: flex;
    flex-direction: column;
    justify-content: center;
    max-width: none;
    padding: var(--space-16) clamp(var(--space-8), 6vw, var(--space-16));
  }
  .hero--split .hero__media {
    aspect-ratio: auto;     /* fill the row, don't impose a ratio */
    height: 100%;
  }
}

/* Home centres its panel and adds the emblem + button; the split rules above
   still give it the side-by-side photo. */
.hero--home .hero__panel { align-items: center; text-align: center; }
.hero--home .hero__title { max-width: none; }

.hero__emblem { display: block; margin-top: var(--space-6); color: var(--color-text-on-dark); }
.hero__emblem svg { display: block; width: auto; height: 84px; }

.hero__btn {
  margin-top: var(--space-6);
  display: inline-block;
  background: var(--color-cta);
  color: var(--hc-cream);
  font-size: .875rem;
  font-weight: 300;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  padding: .8rem 2rem;
}

.hero__btn:hover { background: color-mix(in srgb, var(--color-cta) 60%, transparent); }

.hero__ornament { margin-top: var(--space-8); color: var(--color-text-on-dark); opacity: .75; }

/* The hero photograph. Mobile stacks it under the panel; the split rules
   above turn the pair side-by-side and let it fill the row. */
.hero__media { display: block; background: var(--color-surface-alt); aspect-ratio: 4 / 5; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ------------------------------------------------- home page sections */

.mission { max-width: 72rem; margin: 0 auto; padding: var(--space-16) var(--space-4) var(--space-12); }

.mission__heading {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 4.5vw, 3.25rem);
  letter-spacing: -.03em;
  margin-bottom: var(--space-8);
}

.mission__split { display: grid; gap: var(--space-8); align-items: center; }

.mission__photo { aspect-ratio: 4 / 5; }
.mission__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

.mission__lead {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 3vw, 2.125rem);
  margin-bottom: var(--space-4);
}

.mission__text p:not(.mission__lead) {
  font-weight: 300;
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  line-height: 1.6;
}

@media (min-width: 60rem) {
  .mission__split { grid-template-columns: 4fr 6fr; }
  .mission__photo { aspect-ratio: 3 / 4; max-height: 30rem; }
}

/* ---- the parallax band: image PINNED, content scrolls over it ----
 * background-attachment: fixed is what makes the photo "hover" while the page
 * moves. iOS treats it as scroll (a plain band) — an acceptable fallback. The
 * About section below pulls UP over this band so a block flows over the image
 * instead of sitting after it. */
.photo-band {
  min-height: min(70vh, 560px);
  background-image: url("/static/brand/band.jpg");
  background-size: cover;
  background-position: center;
  background-attachment: fixed;
  background-color: var(--color-surface-dark);
}

.photo-band img { display: none; }   /* the <img> is now the CSS background */

/* About Us: photo, with the translucent olive card overlapping from the lower
   right — and the whole section lifted UP over the parallax band. */
.about {
  position: relative;
  max-width: 80rem;
  margin: 0 auto;
  padding: 0 var(--space-4) var(--space-16);
  margin-top: calc(-1 * var(--space-16));   /* flow up over the pinned band */
}

.about__stage { position: relative; }

.about__photo { max-width: 100%; box-shadow: var(--shadow); }
.about__photo img { width: 100%; height: auto; display: block; }

.about__card {
  background: color-mix(in srgb, var(--hc-olive) 94%, transparent);
  color: var(--color-text-on-dark);
  padding: var(--space-8);
  margin-top: calc(-1 * var(--space-12));    /* overlap the photo on mobile */
  position: relative;
  box-shadow: var(--shadow);
}

.about__heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2rem, 5vw, 3.5rem);
  margin-bottom: var(--space-4);
}

.about__card p { font-weight: 300; font-size: clamp(1rem, 1.6vw, 1.3rem); line-height: 1.6; }

@media (min-width: 60rem) {
  .about__photo { max-width: 64%; }
  .about__card {
    position: absolute;
    right: 0;
    bottom: -3rem;
    width: 52%;
    margin-top: 0;
    padding: var(--space-12);
  }
}

/* ---- NO reveal on scroll ----
 * There was a scroll-driven "rise and fade" here on .band__inner and on the
 * home-page sections. It is gone, and deliberately so.
 *
 * Their site does not have it. Measured: scrolled their page so a fresh
 * section was entering from the bottom and walked every element in the lower
 * half of the viewport looking for opacity < 1 or a non-identity transform.
 * Zero matches. Their content is simply present at full strength.
 *
 * It was also actively producing the mismatches in the screenshots: an
 * entering band sat at translateY(9px) and opacity 0.67, so a band caught
 * mid-entry photographed BOTH a few pixels low AND visibly washed out
 * against the same band on their page. Every "the colour is off" and "this
 * is offset" report is explained by a element measured or photographed
 * before its animation finished — including my own measurements, which is
 * how a 9.2px phantom gap ended up on my defect list.
 *
 * If motion is ever wanted back, it cannot be this: it has to leave the
 * resting geometry and the resting colour untouched. */

/* ---- one-shot reveal, driven by site.js ----------------------------------
 * Their home page runs a timed rise on two blocks. Ours reproduces it with an
 * IntersectionObserver that adds .is-revealed ONCE and unobserves, so it
 * cannot play backwards on the way up and cannot leave a block faded when it
 * was already on screen at load. Both of those are why the previous
 * scroll-timeline version was removed.
 *
 * The hidden state is behind .js-reveal, which site.js puts on <html>. No JS,
 * no hidden state — the copy is simply there. A settled element computes to
 * opacity 1 / transform none, which matters on this project: an earlier
 * reveal left elements mid-animation and produced false "the colour is wrong"
 * and "this is offset" reports for days. */
.js-reveal [data-hc-reveal] {
  opacity: 0;
  transform: translateY(24px);
}
.js-reveal [data-hc-reveal].is-revealed {
  opacity: 1;
  transform: none;
  transition: opacity .7s ease, transform .7s cubic-bezier(.645, .045, .355, 1);
}
@media (prefers-reduced-motion: reduce) {
  .js-reveal [data-hc-reveal],
  .js-reveal [data-hc-reveal].is-revealed {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* --------------------------------------------------------------- layout
 *
 * The prose column is a grid so a section can opt OUT of the reading measure
 * without leaving the flow: paragraphs stay at a comfortable 38rem, while
 * shortcode blocks and wide markdown tables widen to 54rem. This is why body
 * copy and a practitioner grid can sit in the same <article>.
 */

/* Mobile: page padding and nothing else — "wide" and "text" are the SAME
 * column. The breakout gutters only appear once there is width to spare
 * (see the 40rem/72rem blocks below). Declaring the 8rem gutters here instead
 * shrank the reading column to ~115px on a phone, because grid hands free
 * space to fixed-max tracks before flexible ones: the gutters filled up and
 * the body copy wrapped every three words. */
.prose {
  display: grid;
  grid-template-columns:
    [full-start] var(--space-4)
    [wide-start text-start] minmax(0, 1fr) [text-end wide-end]
    var(--space-4) [full-end];
  padding: var(--space-12) 0 var(--space-16);
}

/* From 40rem the reading measure applies: body copy stops at 38rem, and the
 * wide column (shortcodes, tables) takes the rest. Both start at the page
 * gutter, which is where the hero's title starts at these widths (the hero
 * panel is narrower than its 72rem cap, so its 1rem padding is the edge).
 * The 38rem track is a FIXED-max track, so it fills before the 1fr one: on a
 * narrow tablet the text gets the room and the breakout gets what is left,
 * never the reverse (the phone bug described above). */
@media (min-width: 40rem) {
  .prose {
    grid-template-columns:
      [full-start] var(--space-4)
      [wide-start text-start] minmax(0, 38rem) [text-end] minmax(0, 1fr) [wide-end]
      var(--space-4) [full-end];
  }
}

/* From 72rem the hero panel is at its cap and centred, so its title starts
 * at (viewport - 72rem) / 2 + 1rem: 80px at 1280. The prose column starts
 * there too, and its wide column ends where the hero panel's content does
 * (38rem + 32rem = the panel's 70rem). Before this, body copy ran the whole
 * 1250px of a 1280 window, 64px left of the heading above it. */
@media (min-width: 72rem) {
  .prose {
    grid-template-columns:
      [full-start] minmax(var(--space-4), 1fr)
      [wide-start text-start] minmax(0, 38rem) [text-end] minmax(0, 32rem) [wide-end]
      minmax(var(--space-4), 1fr) [full-end];
  }
}

.prose > * { grid-column: text; }
.prose > .sc { grid-column: wide; }

.prose > * + * { margin-top: var(--space-6); }

/* MARKDOWN headings only — the "> " is load-bearing, exactly as it is on the
   list rules below. A shortcode's card headings are <h3>/<h4> too, and as a
   descendant selector these rules reached inside them: .prose h4 (0,1,1) beat
   .room__name (0,1,0), so every room title rendered at body size in bold
   sans-ish weight instead of the display face, every card heading picked up a
   48px top margin that opened a hole under the monogram, and .floor__name
   came out semibold when it is meant to be regular. Markdown headings are
   always direct children of .prose, so scoping costs nothing. */
.prose > h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-h1);
  line-height: var(--leading-tight);
  letter-spacing: .01em;
  margin-top: var(--space-16);
}

/* Section rhythm. These pages are a long stack of "## " sections with nothing
   marking where one ends, which is most of why the site read as a document.
   Each h2 after the first opens on a short brand rule — the one break that
   works for ANY markdown Mariah writes, without her having to do anything. */
.prose > h2:not(:first-child)::before {
  content: "";
  display: block;
  width: 2.5rem;
  border-top: 2px solid var(--color-accent);
  margin-bottom: var(--space-6);
}

.prose > h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-h2);
  line-height: var(--leading-tight);
  margin-top: var(--space-12);
}

.prose > h4 {
  font-size: var(--text-body);
  font-weight: 700;
  letter-spacing: .04em;
  margin-top: var(--space-8);
}

.prose > h2:first-child,
.prose > h3:first-child { margin-top: 0; }

/* Markdown lists only. The :not([class]) is load-bearing: every list this
   repo authors carries a class (.card-grid, .event-list, .post-list) and
   markdown's never do, so bullet indents and the li+li rhythm cannot leak
   into a shortcode's card grid — which silently pushed every card after the
   first 8px down out of its row before this was scoped. */
.prose > ul:not([class]),
.prose > ol:not([class]) { padding-left: 1.25rem; }

.prose > ul:not([class]) li + li,
.prose > ol:not([class]) li + li { margin-top: var(--space-2); }

/* Pull quote. A markdown "> " block is the one lever Mariah has in the editor
   for breaking up a long stretch of copy, so it is styled as a real display
   quote — larger than body, in the display face, stepped out of the measure —
   rather than as an indented aside. */
.prose blockquote {
  grid-column: wide;
  border-left: 3px solid var(--color-accent);
  padding: var(--space-2) 0 var(--space-2) var(--space-6);
  margin-top: var(--space-12);
  font-family: var(--font-display);
  font-size: 1.5rem;
  line-height: 1.35;
  color: var(--color-primary);
}

.prose blockquote p + p { margin-top: var(--space-4); }

.prose hr {
  border: 0;
  border-top: 1px solid var(--color-border);
  margin-top: var(--space-12);
}

.prose code {
  background: var(--color-surface-alt);
  border-radius: var(--radius-sm);
  padding: 0 .3em;
  font-size: .9em;
}

.prose pre {
  background: var(--color-surface-alt);
  border-radius: var(--radius);
  padding: var(--space-4);
  overflow-x: auto;
}

.prose pre code { background: none; padding: 0; }

/* A markdown table can be any width the operator likes, so it gets its own
   scroll container rather than pushing the page sideways. */
.prose > table {
  grid-column: wide;
  display: block;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
  font-size: var(--text-small);
}

.prose > table th,
.prose > table td {
  border-bottom: 1px solid var(--color-border);
  padding: var(--space-3) var(--space-4);
  text-align: left;
  vertical-align: top;
}

.prose > table thead th {
  background: var(--color-surface-alt);
  font-weight: 700;
  letter-spacing: .04em;
  white-space: nowrap;
}

/* ---------------------------------------------------------- shortcodes */

.sc__empty {
  color: var(--color-text-muted);
  font-family: var(--font-display);
  font-size: 1.125rem;
}

/* ---------------------------------------------------- practitioner cards
 *
 * There are no portraits, so the card leads on a typographic monogram. It has
 * to look like a decision rather than a hole where a face should be: display
 * face, sand medallion, and the brand star from the logo alongside.
 */

.person-grid {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
}

.person {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-6);
  display: grid;
  gap: var(--space-4);
  align-content: start;
}

.person__monogram {
  position: relative;
  width: 4rem;
  height: 4rem;
  border-radius: var(--radius-pill);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 1.375rem;
  letter-spacing: .06em;
  color: var(--color-primary);
}

/* Decorative only (the <p> is aria-hidden), so --color-accent is fine here:
   the "borders and rules only" limit exists to keep accent off TEXT. */
.person__star {
  position: absolute;
  top: -2px;
  right: -2px;
  color: var(--color-accent);
}

.person__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-h2);
  line-height: var(--leading-tight);
}

.person__modalities {
  margin-top: var(--space-2);
  font-size: var(--text-small);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-primary);
}

.person__bio {
  margin-top: var(--space-4);
  color: var(--color-text-muted);
}

.person__action { margin-top: var(--space-6); }

.btn--quiet {
  display: inline-block;
  font-size: var(--text-small);
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-primary-text);
  background: var(--color-primary);
  border-radius: var(--radius-pill);
  padding: var(--space-2) var(--space-6);
}

.btn--quiet:hover,
.btn--quiet:focus-visible { background: var(--color-text); }

.event-list { list-style: none; padding: 0; }

.event {
  background: var(--color-surface);
  border-left: 4px solid var(--color-accent);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4) var(--space-6);
}

.event + .event { margin-top: var(--space-4); }

.event__when {
  font-size: var(--text-small);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-primary);
}

.event__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-h2);
  line-height: var(--leading-tight);
  margin-top: var(--space-1);
}

.event__meta {
  margin-top: var(--space-1);
  font-size: var(--text-small);
  color: var(--color-text-muted);
}

.rates {
  width: 100%;
  border-collapse: collapse;
}

.rates + .rates { margin-top: var(--space-8); }

.rates caption {
  font-family: var(--font-display);
  font-size: var(--text-h2);
  text-align: left;
  padding-bottom: var(--space-3);
}

.rates th,
.rates td {
  border-bottom: 1px solid var(--color-border);
  padding: var(--space-3) var(--space-2);
  text-align: left;
  font-weight: 400;
}

.rates thead th {
  font-size: var(--text-small);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.rates td { text-align: right; }

/* --------------------------------------------------------- rooms
 *
 * The selling point. This is the one shortcode that goes full-bleed: the
 * prose column above it stays at its reading measure, the rooms break out
 * edge to edge on a sand band, and the column resumes underneath. That
 * alternation is most of what stops the page reading as one long document.
 */

.prose > .sc-rooms { grid-column: full; }

.rooms__band {
  background: var(--color-surface-alt);
  padding: var(--space-12) var(--space-4);
}

.rooms__band > .floor {
  max-width: 72rem;
  margin: 0 auto;
}

.floor + .floor { margin-top: var(--space-12); }

.floor__name {
  font-family: var(--font-display);
  font-size: var(--text-h2);
  font-weight: 400;
  letter-spacing: .08em;
  text-transform: uppercase;
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-accent);
}

.room-grid {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
}

.room {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* The ratio is set HERE, not on the img, so the box is the same size whether
   it holds one of her photographs or the monogram fallback — a room without a
   picture yet cannot leave a ragged step in the grid, and nothing reflows when
   a lazy image lands. */
.room__media {
  /* flex item: without these the <img> intrinsic height wins and
     aspect-ratio below is ignored, giving ragged card rows (489 vs 475px)
     and a 14px jump as each lazy image decodes. */
  flex: none;
  min-height: 0;
  aspect-ratio: 4 / 5;
  background: var(--color-surface-alt);
  border-bottom: 1px solid var(--color-border);
}

.room__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.room__monogram {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 3rem;
  letter-spacing: .1em;
  color: var(--color-primary);
  opacity: .55;
}

.room__text {
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  flex: 1;
}

.room__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-h2);
  line-height: var(--leading-tight);
}

.room__tagline {
  margin-top: var(--space-2);
  font-family: var(--font-display);
  font-size: 1.0625rem;
  color: var(--color-primary);
}

.room__type {
  margin-top: var(--space-4);
  font-size: var(--text-small);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.room__lede {
  margin-top: var(--space-4);
  color: var(--color-text-muted);
  font-size: var(--text-small);
}

.room__facts {
  margin-top: var(--space-6);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-4);
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-4);
  font-size: var(--text-small);
}

.room__fact-label {
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.room__fact { color: var(--color-text); }

/* margin-top:auto pins the CTA to the bottom of the card, so the buttons line
   up across a row whatever length each description runs to. */
.room__action {
  margin-top: auto;
  padding-top: var(--space-6);
}

.sc-chat__prompt { color: var(--color-text-muted); }

/* -------------------------------------------------------------- journal */

.post-list { list-style: none; padding: 0; }

.post-card + .post-card {
  margin-top: var(--space-8);
  padding-top: var(--space-8);
  border-top: 1px solid var(--color-border);
}

.post-card__media img { border-radius: var(--radius-lg); }

.post-card__text { margin-top: var(--space-4); }

.post-card__date {
  font-size: var(--text-small);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.post-card__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-h1);
  line-height: var(--leading-tight);
  margin-top: var(--space-2);
}

.post-card__title a {
  color: var(--color-text);
  text-decoration: none;
}

.post-card__title a:hover,
.post-card__title a:focus-visible { text-decoration: underline; }

.post-card__excerpt { margin-top: var(--space-3); color: var(--color-text-muted); }

.post-card__byline {
  margin-top: var(--space-3);
  font-size: var(--text-small);
  color: var(--color-text-muted);
}

.back-link { font-size: var(--text-small); letter-spacing: .06em; }

/* --------------------------------------------------------------- footer */

.footer {
  /* the live footer is INK, not olive (measured #2D2D23, 2026-08-18) */
  background: var(--hc-ink);
  color: var(--hc-cream);
}

.footer__inner {
  max-width: 72rem;
  margin: 0 auto;
  padding: var(--space-12) var(--space-4);
  display: grid;
  gap: var(--space-8);
}

@media (min-width: 48rem) {
  .footer__inner {
    grid-template-columns: 1fr auto;
    align-items: end;
  }
}

.footer__logo { display: block; width: 239px; max-width: 100%; height: auto; }

.footer__legal {
  margin-top: var(--space-6);
  font-size: var(--text-small);
  font-weight: 300;
  opacity: .85;
}

/* A dot and the link after it wrap as one (templates/site/base.html). */
.footer__legal-item { white-space: nowrap; }

.footer__contacts { font-weight: 300; line-height: var(--leading-body); }

.footer__contact { margin-bottom: var(--space-2); }

.footer__contact-link {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: .2em;
}

/* A phone number never breaks after "801-" (the FAQ's contact answer at
   375px did). Every tel: link, in page copy and in the footer. */
a[href^="tel:"] { white-space: nowrap; }

.footer__contact-link:hover,
.footer__contact-link:focus-visible { opacity: .8; }

/* <address> is italic by default in every browser; this is a postal address,
   not an aside. */
.footer__address {
  font-style: normal;
  margin-top: var(--space-2);
}

/* ---- the footer, pinned to theirs at 1280 -------------------------------
   Measured on healingcollectiveutah.org, offsets from the footer's own top:

                    theirs              ours before
     footer height  191                 214.4
     logo           x181, y38, 239x62   x80,  y58
     copyright      x181, y129, 16px    x80,  y146.5, 14px
     phone          x855, y38           x990, y51
     email          x855, y61           x990, y84.6
     address        x855, y105 + 124.5  x990, y118.2

   Their background is rgb(45,45,35) and so is ours, which is why the footer
   looked "nearly right" while every element inside it sat in the wrong place.
   The left column starts 101px inside our content box and the contact column
   674px after that; their line spacing is a tight 19.5px with a deliberate
   24.5px break before the postal address, where ours ran an even 33.6px.

   MARIAH ASKED FOR THE CORNERS, and that is a deliberate departure from the
   original. Her words: "The footer is still formatted different, it's kind of
   squished into the middle of the page, but they should be out to either
   corner." Ours was NOT actually different — measured at 1728 theirs sits at
   logo x405 / contact x1079 and ours landed on the same two numbers, because
   both were a fixed block centred in the window. She simply does not want
   their version. So the two halves now go to the page's own 80px gutter:
   the wordmark under the left edge of the body content, the contact block
   flush to the right. Do not "fix" this back to match the old site.

   The vertical geometry below is unchanged and still matches theirs exactly
   (logo y38, copyright y129, contact rows y38/61/105, 191px tall). */
@media (min-width: 80rem) {
  .footer__inner {
    grid-template-columns: auto auto;
    justify-content: space-between;   /* logo hard left, contact hard right */
    align-items: start;
    gap: 0;
    padding: 38px 80px 43px;
  }
  /* their copyright line computes to line-height:normal, ours inherited the
     body's 1.6 — 6.4px of extra leading, which was the whole remaining
     difference in footer height (197.6 vs their 191). */
  .footer__legal { margin-top: 29px; font-size: 16px; line-height: normal; }
  .footer__contacts { line-height: 19.5px; }
  .footer__contact { margin: 0 0 3.5px; }
  .footer__address { margin-top: 24.5px; line-height: 19.5px; }
}


/* ==========================================================================
   BAND SYSTEM — how this site MOVES
   ==========================================================================
   Reading the live site page by page, every screen is the same mechanic: a
   vertical stack of FULL-WIDTH BANDS in an alternating palette rhythm —
   cream -> olive -> photo -> beige -> dark -> photo — each band holding one
   composition (centred text, a split, a 3-up grid, a table, a roadmap).
   The "feel" people describe is that rhythm plus the parallax photo breaks
   between content, not any single page's layout.

   So this is a SYSTEM, not per-page CSS: .band sets the surface, .band__inner
   sets the measure, and the composition classes below drop into any band.
   Every page then moves identically, and a new page is a composition of
   bands rather than a new stylesheet.

   MEASURE, corrected 2026-09-04. This comment used to say "their content
   column is 980px; we use 1000px". That was wrong, and it made every page on
   this site 120px narrower than the original — the single biggest reason the
   two never quite matched at a glance. Measured properly off the live site
   at a 1280px viewport: the content container is x=80, width 1120, i.e. 80px
   side margins. A max-width of 1120px reproduces exactly that, and centres
   the same way on wider screens.
   ====================================================================== */

.band {
  position: relative;
  background: var(--color-bg);
  color: var(--color-text);
}

.band__inner {
  /* NO max-width. Their content column is `viewport - 160px` at every width —
     80px of padding either side and no cap. It is not a fixed 1120 column.
     1120 is simply what vw-160 equals at 1280, which is the only width the
     original of this comment was checked at, and that single wrong assumption
     is what made every page match at 1280 and drift everywhere else.
     Measured on their site: the Neurova hero image is 69% of (vw-160) at
     1280 (772.6), 1512 (932.6), 1728 (1081.6) and 2100 (1338) — four widths,
     no cap anywhere. At 1728 their column is 1568 and ours was still 1120,
     so every image was 448px of column narrower than theirs. */
  max-width: none;
  margin: 0 auto;
  padding: clamp(var(--space-12), 8vw, var(--space-16)) var(--space-4);
}
@media (min-width: 48rem) { .band__inner { padding-inline: 80px; } }

/* ---- surfaces (the alternating rhythm) ---- */
.band--cream { background: var(--hc-cream); }
.band--beige { background: var(--hc-bone); }
.band--olive { background: var(--hc-olive); color: var(--hc-ink); }
.band--dark  { background: var(--hc-ink);  color: var(--hc-bone); }
.band--deep  { background: var(--hc-olive-deep); color: var(--hc-bone); }

.band--dark .band__title,
.band--deep .band__title,
.band--dark a:not(.btn),
.band--deep a:not(.btn) { color: var(--hc-bone); }

/* ---- full-bleed parallax photo break ----
   The pinned image the content scrolls over. iOS ignores fixed attachment
   and renders a plain band, which is an acceptable fallback rather than a
   broken layout. */
.band--photo {
  min-height: min(100vh, 900px);  /* theirs renders 1280x900 at 1280 wide */
  background-size: cover;
  background-position: center;
  background-attachment: fixed;
  background-color: var(--color-surface-dark);
}

/* A dark scrim so text stays legible when a band carries copy over a photo. */
.band--photo.band--scrim::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
              rgba(45, 45, 35, .55), rgba(45, 45, 35, .35));
}
.band--photo .band__inner { position: relative; z-index: 1; }

/* ---- band furniture ---- */
/* The live site does NOT use one heading size. Measured at 1280px:
     page title            64px, line-height ~1.0
     major section         52-56px, tight (-0.03em)
     ordinary section      38px,  line-height 1.2, -0.02em
   Ours was a single clamp topping out at 56px, so every heading on the page
   came out the size of a page title and the hierarchy the original has was
   flattened away. .band__title now tops out at their section size, and
   .band__title--hero carries the page-title size. */
.band__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.75rem, 3.2vw, 2.375rem);     /* 28 -> 38px */
  line-height: 1.2;
  letter-spacing: -.02em;
  margin-bottom: var(--space-8);
}
.band__title--major { font-size: clamp(2rem, 4.2vw, 3.25rem); line-height: 1.05; letter-spacing: -.03em; }
.band__title--hero  { font-size: clamp(2.25rem, 5vw, 4rem);  line-height: 1.05; letter-spacing: -.01em; }
/* Their headings are not a tidy scale: 64 page title, 56 "Built for Every
   Brain", 52 "Built on a Belief", 38 ordinary sections. This is the 56. */
.band__title--major-lg { font-size: clamp(2.125rem, 4.4vw, 3.5rem); line-height: 1.4; letter-spacing: normal; }
.band__title--center { text-align: center; }

/* Measured against the live Wix site at 1280px on 2026-09-04: every body
   paragraph there is 18px with a 27px line box — a flat 1.5, not a scaling
   clamp. Ours was reaching 20.8px at 1.65, which is why the new pages read
   noticeably larger and looser than the originals even with the right
   typefaces loaded. Matching the number rather than approximating it. */
.band__lede {
  font-weight: 300;
  font-size: clamp(1.0625rem, 1.55vw, 1.125rem);  /* 17 -> 18px, hits 18 by ~1160px */
  line-height: 1.5;
  max-width: 60ch;
}
.band__inner--center { text-align: center; }
.band__inner--center .band__lede { margin-inline: auto; }
/* Consecutive paragraphs need air. Measured on the live site: 27px between
   body paragraphs. Ours had none, so multi-paragraph copy ran together into
   one grey slab — visible on The Initiation, where the original reads as
   four separate thoughts and ours as a wall. Sibling selector so the last
   paragraph does not push the button away from its block. */
.band__lede + .band__lede { margin-top: 27px; }

/* ---- the CTA button, in both polarities ---- */
.btn {
  display: inline-block;
  margin-top: var(--space-6);
  padding: .72rem 2.2rem;   /* theirs measure 40px tall */
  /* Their buttons are Title Case with no tracking — measured "Book Here",
     not "BOOK HERE". Wide-tracked caps read as a different, louder control. */
  font-size: .875rem;       /* 14px on every button on the live site */
  /* Their buttons are 40px tall. Our padding (11.52px) and font-size (14px)
     already matched, but .btn inherited the body's 1.6 leading, giving a
     22px line box and a 47px button — 7px too tall on every CTA sitewide. */
  line-height: 1.1;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background .2s ease, color .2s ease, border-color .2s ease;
}
.btn--dark  { background: var(--hc-ink);   color: var(--hc-cream); }
.btn--dark:hover  { background: color-mix(in srgb, var(--hc-ink) 72%, transparent); }
.btn--light { background: var(--hc-cream); color: var(--hc-ink); }
.btn--light:hover { background: color-mix(in srgb, var(--hc-cream) 62%, transparent); }
.btn--ghost { background: transparent; color: inherit; border-color: currentColor; }
.btn--ghost:hover { background: color-mix(in srgb, currentColor 12%, transparent); }

/* ---- SPLIT: two columns, ratio set per instance ---- */
.split { display: grid; gap: clamp(var(--space-6), 4vw, var(--space-12)); align-items: center; }
.split__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.split__media { aspect-ratio: 4 / 5; }
/* The Neurova hero photograph is LANDSCAPE on the live site — 773x587, a
   1.32 ratio — where our default media box is 4/5 portrait (0.80). Same
   image, rotated framing, which is why it read as a different picture. */
.split__media--land { aspect-ratio: 773 / 587; }

@media (min-width: 60rem) {
  .split { grid-template-columns: 1fr 1fr; }
  .split--30-70 { grid-template-columns: 3fr 7fr; }
  .split--40-60 { grid-template-columns: 2fr 3fr; }
  .split--45-55 { grid-template-columns: 45fr 55fr; }
  .split--60-40 { grid-template-columns: 3fr 2fr; }
  /* Measured off the live Neurova page: the hero photograph takes 773 of the
     1120 content column, and the footage 379. With our 48px gap those are
     roughly 72/28 and 35/65 — not the even-ish splits we had. */
  .split--72-28 { grid-template-columns: 72fr 28fr; }
  .split--65-35 { grid-template-columns: 65fr 35fr; }
  /* photo on the right without reordering the DOM (keeps reading order) */
  .split--flip .split__media { order: 2; }
  /* Compound, not descendant. Every call site writes
     class="split__media split--tall" — both classes on ONE element — so the
     descendant form matched nothing and these four images silently kept the
     default ratio instead of the portrait crop they were written for. */
  .split__media.split--tall { aspect-ratio: 3 / 4; max-height: 30rem; }
}

/* ---- PILLARS: the 3-up photo + heading + copy grid ---- */
.pillars { display: grid; gap: var(--space-8); }
.pillar__media { aspect-ratio: 4 / 3; margin-bottom: var(--space-4); }
/* Square, and SMALL. Measured on the live site: 121x121 at a 1280 viewport,
   about 9% of the width. Ours were rendering 301x301 — two and a half times
   over — which is why that row read as three big panels rather than the
   three modest supporting thumbnails the original shows. */
.pillars--thumbs .pillar__media {
  aspect-ratio: 1 / 1;
  width: min(121px, 40vw);
  margin-inline: auto;
}
.pillar__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pillar h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.3rem;
  margin-bottom: var(--space-3);
}
.pillar p { font-weight: 300; line-height: 1.65; }

/* The three-up "Built for Every Brain" row, measured on the live site:
     thumbnail   121x121, CIRCULAR (Wix masks it with an SVG; border-radius
                 does the same job)
     heading     32px, centred
     body        18px / 27px, centred, ~280px wide
   Ours had square thumbnails, 20.8px left-aligned headings and left-aligned
   body — the same three cards reading as a completely different block. */
.pillars--thumbs { text-align: center; }
.pillars--thumbs .pillar__media { border-radius: 50%; overflow: hidden; }
.pillars--thumbs .pillar__media img { border-radius: 50%; }
.pillars--thumbs .pillar h3 { font-size: 2rem; margin-top: var(--space-6); }
.pillars--thumbs .pillar p {
  font-size: 1.125rem;              /* 18px, as the rest of their body copy */
  line-height: 1.5;
  max-width: 280px;
  margin-inline: auto;
}

@media (min-width: 48rem) {
  .pillars { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
}

/* ---- MATRIX: the comparison table ---- */
.matrix-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.matrix {
  width: 100%;
  min-width: 34rem;
  border-collapse: collapse;
  font-size: .95rem;
}
.matrix th {
  background: var(--hc-olive-deep);
  color: var(--hc-cream);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.1rem;
  text-align: left;
  padding: var(--space-4);
}
.matrix td { padding: var(--space-3) var(--space-4); font-weight: 300; vertical-align: top; }
.matrix tbody tr:nth-child(odd) { background: var(--hc-bone); }
.matrix tbody tr:nth-child(even) { background: color-mix(in srgb, var(--hc-bone) 45%, transparent); }
.matrix td:first-child { font-weight: 400; }

/* ---- RATES: two side-by-side price tables ---- */
.rate-cols { display: grid; gap: var(--space-12); }
.rate-cols h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.45rem;
  margin-bottom: var(--space-3);
  min-height: 2.6em;         /* keeps the two headings baseline-aligned */
}
.rate-cols p { font-weight: 300; margin-bottom: var(--space-4); }
.rate-table { width: 100%; border-collapse: collapse; }
.rate-table th {
  background: var(--hc-olive);
  color: var(--hc-cream);
  font-weight: 400;
  font-size: .8rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-align: left;
  padding: var(--space-3) var(--space-4);
}
.rate-table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid color-mix(in srgb, var(--hc-ink) 12%, transparent);
  font-weight: 300;
}
.rate-table td:last-child { text-align: right; font-weight: 400; }

@media (min-width: 48rem) { .rate-cols { grid-template-columns: 1fr 1fr; } }

/* ---- FAQ: the 2-up question grid ---- */
.faq-grid { display: grid; gap: var(--space-8) var(--space-12); }
.faq h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.35rem;
  margin-bottom: var(--space-3);
}
.faq p { font-weight: 300; line-height: 1.65; margin-bottom: var(--space-3); }
@media (min-width: 48rem) { .faq-grid { grid-template-columns: 1fr 1fr; } }

/* ---- STEPS: the numbered roadmap (01 / 02 / 03) ---- */
.steps { display: grid; gap: var(--space-8); counter-reset: step; }
.step__num {
  font-family: var(--font-display);
  font-size: 2.6rem;
  line-height: 1;
  opacity: .55;
  margin-bottom: var(--space-3);
}
.step h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.25rem;
  margin-bottom: var(--space-3);
}
.step ul { list-style: none; font-weight: 300; line-height: 1.8; }
@media (min-width: 48rem) { .steps { grid-template-columns: repeat(3, 1fr); } }

/* ---- STATS: the metrics bar ---- */
.stats { display: grid; gap: var(--space-8); text-align: center; }
/* Line boxes are theirs, not ours: numbers 60px on an 84px line (1.4),
   labels 16px on a 24px line (1.5). Ours were 60/60 and 16/25.6, which is
   most of why the band read cramped with the SAME font sizes. Unitless so
   the phone sizes keep the same proportions. */
.stat__num {
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 5vw, 3.75rem);   /* 60px, measured */
  line-height: 1.4;
  margin-bottom: var(--space-3);
}
/* :not(.stat__num) is load-bearing. `.stat p` is specificity (0,1,1) and
   .stat__num is (0,1,0), so the plain descendant selector was winning and
   every headline figure — 60%, 500+, 185M, $500B — rendered at 15.2px
   instead of the 60px the rule above intends. Measured on their page: the
   numbers are 60px and the labels 16px. */
.stat p:not(.stat__num) { font-weight: 300; font-size: 16px; line-height: 1.5; }

/* Their stats row WRAPS — it is not a fixed column count. Read off their
   page's own CSS (a Wix fluid-columns repeater: 40px margins on every item
   inside a -40px frame) and confirmed at 1280, 1370, 1380, 1512, 1728, 2200:
     cell      284 x 279, 80px apart across AND down (the 364px pitch)
     number    line box 45px below the cell top
     label     line box 140px below the cell top, a 226px measure — which
               is why "Annual cost to U.S. healthcare system" takes two lines
     row       laid out across the FULL viewport, not the 80px-inset column:
               4x284 + 3x80 = 1376, so one row from a 1376px viewport up
               (1380 is one row, 1370 is 3+1), centred on the viewport
   The old rule here (260px cells, 104px gaps, capped at the column) had the
   same pitch but only fitted one row from 1512 up, and its 60px row gap put
   the wrapped fourth figure 183px under the first at 1280, against 359.
   TRAP: in a background or hidden tab that repeater never upgrades — no
   frames are painted — so their row reads as 284px cells with NO gaps, one
   row even at 1280, in a 393.6px band. Force a paint (a screenshot does it)
   before trusting a read. Their wrapped fourth cell hangs left under the
   first; ours stays centred. */
@media (min-width: 48rem) {
  .stats {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 80px;
    /* Cancels .band__inner's 80px side padding so the row gets the whole
       band width, as theirs does. Only from 48rem, where that padding is. */
    margin-inline: -80px;
  }
  .stat { flex: 0 0 284px; min-height: 279px; padding-top: 45px; }
  .stat__num { margin-bottom: 11px; }     /* 45 + 84 + 11 = label at 140 */
  .stat p:not(.stat__num) { max-width: 226px; margin-inline: auto; }
}

/* The TidyCal booking calendar on the Neurova page. Their embed measures
   1636px tall at 1280; it does not resize itself, so the height is fixed
   rather than aspect-ratio'd. */
/* WIDTH IS A DELIBERATE DEPARTURE. Wix embeds a fixed 1582px box centred
   on the viewport, which runs off both sides of the screen below 1582 (x=-149
   at 1280). Ours fills the content column at every width instead. */
.booking-embed { display: block; width: 100%; height: 1636px; border: 0; }

/* ---- CARDS: the practitioner directory ---- */
.cards { display: grid; gap: var(--space-8); }
.card-p {
  background: var(--hc-bone);
  display: grid;
  gap: var(--space-4);
  padding: var(--space-6);
}
.card-p__media { aspect-ratio: 1 / 1; }
.card-p__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card-p__role {
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}
.card-p h3 { font-family: var(--font-display); font-weight: 400; font-size: 1.4rem; margin-bottom: var(--space-3); }
.card-p ul { list-style: none; font-weight: 300; line-height: 1.7; margin-bottom: var(--space-3); }
.card-p ul li::before { content: "· "; }
.card-p a { color: inherit; }

@media (min-width: 40rem) { .card-p { grid-template-columns: 12rem 1fr; align-items: start; } }
@media (min-width: 64rem) { .cards { grid-template-columns: 1fr 1fr; } }


/* ---------------------------------------------------------- signup modal
   The live site's on-load lightbox: a cream card centred over a blurred,
   dimmed page. Native <dialog>, so the platform handles focus trapping and
   the backdrop; ::backdrop is where the blur lives. */
.signup {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: min(92vw, 34rem);
  width: 100%;
}
.signup::backdrop {
  background: rgba(45, 45, 35, .45);
  backdrop-filter: blur(4px);
}

.signup__form {
  position: relative;
  background: var(--hc-cream);
  color: var(--hc-ink);
  padding: clamp(var(--space-8), 5vw, var(--space-12));
  display: grid;
  gap: var(--space-4);
  max-height: 88dvh;
  overflow-y: auto;
}

.signup__close {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  width: 40px;
  height: 40px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: transparent;
  font-size: 1.3rem;
  line-height: 1;
  color: var(--hc-ink);
  cursor: pointer;
}
.signup__close:hover { background: var(--hc-bone); }

.signup__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.7rem, 4.5vw, 2.4rem);
  letter-spacing: .06em;
  text-transform: uppercase;
  text-align: center;
  margin-bottom: var(--space-2);
}

.signup__form label { display: block; font-size: .9rem; font-weight: 300; }
.signup__form input[type="text"],
.signup__form input[type="email"] {
  width: 100%;
  margin-top: var(--space-2);
  padding: .7rem .8rem;
  border: 1px solid transparent;
  background: var(--hc-bone);
  font: inherit;
  color: inherit;
}
.signup__form input:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 1px; }

.signup__row { display: grid; gap: var(--space-4); }
@media (min-width: 32rem) { .signup__row { grid-template-columns: 1fr 1fr; } }

.signup__interests { border: 0; padding: 0; display: grid; gap: var(--space-2); }
.signup__interests legend { font-size: .9rem; margin-bottom: var(--space-2); }
.signup__interests label {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  line-height: 1.45;
}
.signup__interests input { width: 20px; height: 20px; accent-color: var(--hc-olive-deep); flex: 0 0 auto; }

.signup__submit { width: 100%; margin-top: var(--space-2); text-align: center; border: 0; cursor: pointer; }
.signup__error { color: var(--color-danger); font-size: .85rem; }
.signup__thanks { text-align: center; font-weight: 300; }

/* ------------------------------------------------- donate + contact forms */

.donate__group { border: 0; padding: 0; margin-bottom: var(--space-6); display: block; }
.donate__group legend,
.donate__group { font-size: .9rem; font-weight: 300; }
.donate__group legend { margin-bottom: var(--space-3); }

.donate__freq, .donate__amounts { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.donate__amounts { display: grid; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 30rem) { .donate__amounts { grid-template-columns: repeat(3, 1fr); } }

/* The selector pills. min-height 48px is the touch target the mobile spec
   asks for, and the on-state is a real fill rather than a border tweak so it
   survives being glanced at on a phone in sunlight. */
.chip {
  min-height: 48px;
  padding: .6rem 1.1rem;
  border: 1px solid var(--hc-ink);
  background: transparent;
  color: var(--hc-ink);
  font: inherit;
  font-size: .95rem;
  cursor: pointer;
  transition: background .18s ease, color .18s ease;
}
.chip:hover { background: color-mix(in srgb, var(--hc-ink) 10%, transparent); }
.chip.is-on { background: var(--hc-ink); color: var(--hc-cream); }

.donate__other { display: block; margin-top: var(--space-4); }
.donate__other input,
.donate__group > input[type="text"] {
  width: 100%;
  margin-top: var(--space-2);
  padding: .7rem .8rem;
  border: 1px solid var(--color-border);
  background: var(--hc-cream);
  font: inherit;
}
.donate__count { display: block; margin-top: var(--space-2); font-size: .78rem; color: var(--color-text-muted); }
.donate__submit { width: 100%; border: 0; cursor: pointer; text-align: center; }
.donate__error { color: var(--color-danger); font-size: .9rem; margin-bottom: var(--space-3); }
.donate__thanks {
  background: var(--hc-olive-deep);
  color: var(--hc-bone);
  padding: var(--space-4);
  margin-bottom: var(--space-6);
}

/* ---- contact form (sits over a photo, so fields are solid) ---- */
.contact-form { display: grid; gap: var(--space-4); color: var(--hc-cream); }
.contact-form label { display: block; font-size: .9rem; font-weight: 300; }
.contact-form input,
.contact-form textarea {
  width: 100%;
  margin-top: var(--space-2);
  padding: .7rem .8rem;
  border: 1px solid transparent;
  background: color-mix(in srgb, var(--hc-cream) 92%, transparent);
  color: var(--hc-ink);
  font: inherit;
}
.contact-form__row { display: grid; gap: var(--space-4); }
@media (min-width: 34rem) { .contact-form__row { grid-template-columns: 1fr 1fr; } }
.contact-form__choices { border: 0; padding: 0; display: grid; gap: var(--space-2); }
.contact-form__choices legend { font-size: .9rem; margin-bottom: var(--space-2); }
.contact-form__choices label { display: flex; gap: var(--space-3); align-items: flex-start; line-height: 1.45; }
.contact-form__choices input { width: 20px; height: 20px; margin-top: .15rem; accent-color: var(--hc-olive); flex: 0 0 auto; }
.contact-form button { border: 0; cursor: pointer; justify-self: start; }
.contact-form__error { color: #ffd7cf; font-size: .9rem; }
.contact-form__thanks { font-weight: 300; }

/* practitioner card monogram (we have no headshots; the brand mark stands in) */
.card-p__monogram {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  background: var(--hc-olive);
  color: var(--hc-cream);
  font-family: var(--font-display);
  font-size: 2.4rem;
  letter-spacing: .06em;
}

/* ---------------------------------------------------------------- events
   A list, not a calendar. Mariah, 2026-09-01: "I don't think it needs to be
   in calendar format ... that feels less crazy than seeing a big old empty
   calendar." A short list reads as a short list; an empty grid advertises
   that nothing is happening. */

.events {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.event-card {
  display: grid;
  grid-template-columns: minmax(7.5rem, 9rem) 1fr auto;
  gap: var(--space-6);
  align-items: center;
  padding: var(--space-6);
  background: var(--cream, #fbfaf6);
  border: 1px solid rgba(0, 0, 0, .08);
  border-left: 3px solid var(--olive, #6b7355);
}

/* A full event keeps its place on the page rather than vanishing — you can
   only tell something is in demand if you can still see it. */
.event-card.is-full { opacity: .72; border-left-color: rgba(0, 0, 0, .2); }

.event-card__when {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  border-right: 1px solid rgba(0, 0, 0, .1);
  padding-right: var(--space-4);
}
.event-card__day {
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.1;
}
.event-card__time { font-size: .85rem; opacity: .72; }

.event-card__body { display: flex; flex-direction: column; gap: .4rem; }
.event-card__title {
  font-family: var(--font-display);
  font-size: 1.5rem;
  line-height: 1.15;
  margin: 0;
}
.event-card__host {
  display: flex;
  align-items: center;
  gap: .55rem;
  margin: 0;
  font-size: .92rem;
}
.event-card__face {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
}
.event-card__blurb { margin: 0; max-width: 58ch; }
.event-card__where { margin: 0; font-size: .85rem; opacity: .7; }

.event-card__act { display: flex; align-items: center; }
.event-card__full {
  font-size: .78rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: .45em .9em;
  border: 1px solid rgba(0, 0, 0, .25);
  white-space: nowrap;
}

@media (max-width: 46rem) {
  .event-card {
    grid-template-columns: 1fr;
    gap: var(--space-3);
  }
  .event-card__when {
    border-right: 0;
    padding-right: 0;
    flex-direction: row;
    align-items: baseline;
    gap: .6rem;
  }
  .event-card__act { justify-content: flex-start; }
}

/* ------------------------------------------------- practitioner application
   The agreement is the substance of this form, not fine print. Mariah's whole
   reason for showing it is that somebody reads the awkward parts BEFORE they
   arrive — the street noise, the insurance floor, the background check — so
   it is set at reading size in its own scrolling panel rather than as agate
   behind a link. The panel is focusable so it scrolls from the keyboard. */

/* tokens.css defines no --space-5; a var() naming it voided the gap. */
.apply { display: flex; flex-direction: column; gap: var(--space-6); }
.apply__h {
  font-family: var(--font-display);
  font-size: 1.6rem;
  margin: var(--space-4) 0 0;
}
.apply__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--space-4);
}
.apply label { display: flex; flex-direction: column; gap: .35rem; font-size: .95rem; }
.apply label.check { flex-direction: row; align-items: flex-start; gap: .6rem; }
.apply input[type="text"], .apply input[type="email"],
.apply input[type="tel"], .apply textarea {
  font: inherit;
  padding: .65rem .75rem;
  border: 1px solid rgba(0, 0, 0, .25);
  background: #fff;
  border-radius: 2px;
  width: 100%;
}
.apply small { opacity: .7; font-size: .82rem; }
.apply__note { max-width: 60ch; opacity: .8; }

.agreement {
  background: #fff;
  border: 1px solid rgba(0, 0, 0, .12);
  border-left: 3px solid var(--olive, #6b7355);
  padding: var(--space-4) var(--space-6);
  max-height: 70vh;
  overflow-y: auto;
  overflow-wrap: anywhere;
  line-height: 1.55;
}
.agreement:focus-visible { outline: 2px solid var(--olive, #6b7355); outline-offset: 2px; }
.agreement > * { max-width: 68ch; }
.agreement p { margin: 0 0 .6rem; }
.agreement .agreement__blank { margin: 0; height: .5rem; }
.agreement__h1 { font-size: 1.35rem; margin: 1.2rem 0 .6rem; }
.agreement__h2 { font-size: 1.1rem; margin: 1.1rem 0 .4rem; }
.agreement__h3 { font-size: 1rem; margin: .9rem 0 .3rem; }
.agreement > :first-child { margin-top: 0; }
.agreement__list { margin: 0 0 .6rem; padding-left: 1.4rem; }
.agreement__list li { margin-bottom: .25rem; }
.agreement__version { margin: calc(-1 * var(--space-3)) 0 0; font-size: .78rem; opacity: .6; }

.initials { display: flex; flex-direction: column; gap: .35rem; }
.initials input[type="text"] { max-width: 10rem; }
.initials__quote { margin: 0; font-size: .85rem; opacity: .75; max-width: 62ch; }

.apply__error {
  background: #f6e5e5;
  border-left: 3px solid #9a4b4b;
  padding: var(--space-3) var(--space-4);
  margin: 0;
}
.apply__done { max-width: 55ch; display: flex; flex-direction: column; gap: var(--space-3); }
/* The form and the thank-you swap by the HTML `hidden` attribute (apply.js).
   An author `display` beats the browser's own [hidden] rule, so without
   this the thank-you showed under an untouched form, and a sent form never
   went away. */
.apply[hidden], .apply__done[hidden] { display: none; }
.apply__ref { font-size: .9rem; opacity: .8; }

/* Video inside a split column.
   I first made this 16:9 on the reasoning that a portrait crop would cut the
   man out of his own shot. Then I measured the live site: it renders that
   same footage at 379x549 — PORTRAIT, cover-cropped from the 16:9 source,
   exactly what I had talked myself out of. Matching the original beats my
   opinion about the original. */
.split__media--wide { aspect-ratio: 379 / 549; max-height: none; }
.split__video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---------------------------------------------------------- overlapping hero
   The thing that makes the original's heroes read as LAYERED rather than as
   two columns side by side, and the effect Steve described early on as the
   blocks "flowing over" the images.

   Measured off the live Neurova page at a 1280px viewport:
     image  773 x 587 at x=80
     panel  559 x 587 at x=641, background #e0ded2
   So the panel sits OVER the image by 212px and starts 73px lower than it,
   ending 73px below the image's bottom edge.

   As proportions of the 1120px content column: the image is 69% wide, the
   panel spans from 50% to the right edge, offset down by 73px. Stated that
   way it holds at any width instead of only at 1280.

   Stacks below 60rem — an overlap at phone width is just an unreadable
   collision. */
.hero-lap { position: relative; }
.hero-lap__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero-lap__panel { background: var(--hc-bone); padding: var(--space-8) var(--space-6); }
.hero-lap__panel > :first-child { margin-top: 0; }
/* The panel is a flex column, so a block-level button stretches to its full
   width — ours came out 448px against their 142px. Shrink to content. */
.hero-lap__panel .btn { align-self: flex-start; }

@media (min-width: 60rem) {
  .hero-lap { padding-bottom: 73px; }
  /* Their media is 69% of the column WIDE and a fixed 587px TALL at every
     width — 772.6x587 at 1280, 932.6x587 at 1512, 1081.6x587 at 1728. An
     aspect-ratio grows the height with the width, which made ours 821px tall
     at 1728 and pushed the whole page down 160px. */
  .hero-lap__media { width: 69%; height: 587px; }
  .hero-lap__panel {
    position: absolute;
    top: 73px; left: 50%; right: 0; bottom: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: clamp(var(--space-8), 4vw, 3rem);
  }
}

/* ------------------------------------------------------------------ contact
   Measured on the live page at 1280px. The markup for this exists in
   contact.html but had no styles, because the agent that wrote it was not
   allowed to touch this file — so the page rendered with raw browser
   controls and cream labels on a bone ground, effectively invisible.

     section  1280 x 987, bone
     photo    1280 x 446, flush to the section's top edge
     panel     980 x 579 at x=150, cream, 30px padding, square, no shadow,
              starting 199px below the section top so it laps 247px UP over
              the photograph and leaves 209px of bone beneath it
     fields   436 x 38, transparent, underlined — not boxes
     submit   920 x 43, full panel width, #707054 with bone text            */

.contact-band { position: relative; padding: 0; overflow: hidden; }
.contact-band__media {
  display: block;
  width: 100%;
  height: 446px;
  object-fit: cover;
}
.contact-panel {
  position: relative;
  width: min(980px, calc(100% - 2 * var(--space-4)));
  margin: -247px auto 209px;
  padding: 30px;
  background: var(--hc-cream);
  color: var(--hc-ink);
}
.contact-panel__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2rem, 4.2vw, 3.25rem);   /* 52px */
  line-height: 1.5;                          /* 78px */
  letter-spacing: normal;
  margin: 0 0 var(--space-6);
}

/* 24px left row two at 554.4 against their 555.8. */
.contact-form { display: flex; flex-direction: column; gap: 25.4px; }
.contact-form__row { display: grid; gap: 48px; }
/* Their two fields are 436px with a 36px gutter, left-aligned in the 920px
   panel — which leaves 12px unused on the right rather than filling it. Ours
   was 1fr 1fr with a 48px gap, so the second column started at 664 against
   their 652. minmax keeps it from overflowing once the panel is narrower. */
@media (min-width: 48rem) {
  .contact-form__row {
    grid-template-columns: repeat(2, minmax(0, 436px));
    gap: 36px;
    justify-content: start;
  }
}

/* Labels are INK on cream. They were inheriting a light colour from the bone
   band and rendering at roughly 1.2:1 — unreadable.

   display:block, NOT flex-column. As a column flex container the label's bare
   text node and its <span>*</span> became two separate flex items, so every
   required field rendered as three stacked lines:

       First name
       *
       [input]

   with the asterisk on its own full-width line. That is what pushed each
   input 40px below theirs and cascaded down the whole form — the submit
   button ended up 87px low. As a block, the text and the asterisk are inline
   again and sit on one line, which is what their form does. */
.contact-form label,
.contact-form legend {
  display: block;
  font-size: 1rem;
  color: var(--hc-ink);
}
/* Their label baseline is 462 and the field top 492.4 — a 30.4px step from
   the top of a 25.6px line, so 4.8px of air under the text. */
.contact-form__row input { display: block; margin-top: 4.8px; }
.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form input[type="tel"] {
  font: inherit;
  height: 38px;
  padding: 0 0 .35rem;
  background: transparent;          /* underlined, not boxed */
  border: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--hc-ink) 45%, transparent);
  color: var(--hc-ink);
  border-radius: 0;
}
.contact-form input:focus-visible {
  outline: none;
  border-bottom-color: var(--hc-ink);
}

/* Their four choices sit at 682/718/754/790 — a 36px pitch, 31.4px under the
   legend. Ours ran 684.8/721.4/758/794.5 on a 36.6px pitch. */
.contact-form__choices { border: 0; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 9px; }
.contact-form__choices legend { margin-bottom: 6.8px; }
/* The four choices land exactly on theirs (682/718/754/790), but our checkbox
   row box is 27px tall against their ~24, so the Submit button finished 6.4px
   low (842.4 against their 836). Closed here rather than by re-cutting the
   label line-height, because that line-height is what makes the 36px row
   pitch come out exact. */
.contact-form__choices { margin-bottom: -6.4px; }
/* The checkbox rows still want flex; the base rule no longer supplies it. */
.contact-form__choices label {
  display: flex; flex-direction: row; align-items: flex-start; gap: .6rem;
}
.contact-form__choices input { margin-top: .25rem; flex: none; }

.contact-form__submit {
  font: inherit;
  font-size: .875rem;
  width: 100%;                       /* 920px inside the 980 panel */
  height: 43px;
  border: 0;
  border-radius: 0;
  background: #707054;
  color: var(--hc-bone);
  cursor: pointer;
}
.contact-form__submit:hover { background: color-mix(in srgb, #707054 88%, black); }
.contact-form__error { margin: 0; color: #8a3b3b; }
.contact-form__thanks { margin: 0; }

@media (max-width: 47.99rem) {
  .contact-panel { margin-top: -80px; margin-bottom: var(--space-12); }
  .contact-band__media { height: 260px; }
}

/* The six marks on The Initiation's "This is for you if..." list. They are on
   the original and were simply missing from ours — abstract geometric glyphs,
   61x39, filled bone, sitting above each line. Paths lifted from the live
   page; Wix serves them as inline SVG with a colour token, so they are inline
   here too rather than six extra requests. */
.pillar__icon {
  display: block;
  width: 61px;
  height: 39px;
  margin-bottom: var(--space-4);
  fill: var(--hc-bone);
}
.band--dark .pillar__icon,
.band--deep .pillar__icon { fill: var(--hc-bone); }
.band--cream .pillar__icon,
.band--beige .pillar__icon { fill: var(--hc-olive); }

/* The Initiation's Apply Now. Measured on the live page: ink ground with an
   OLIVE label, rgb(134,134,100) — not the cream every other dark button on
   the site uses. Steve spotted it; it is the one button that breaks the
   house pattern, so it gets its own rule rather than changing .btn--dark. */
.init-page .btn--dark,
.init-apply { color: var(--hc-olive); }

/* ------------------------------------------------------- working sections
   page_blocks: ask, tour, signup, contact, visit. A visitor can DO something
   in each; the behaviour is static/widget.js and static/site.js. Controls
   that need a script start `hidden` and are un-hidden once it has mounted, so
   nobody meets a control that does nothing. An author `display` beats the
   browser's own [hidden] rule, so it is restated for the one class. */
.blk-needs-js[hidden] { display: none; }
/* A <button class="btn"> does not inherit the page's font the way the <a>
   buttons do. */
button.btn.blk-needs-js, .blk-ask button.btn { font-family: inherit; cursor: pointer; }

.blk-ask {
  display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: center;
  max-width: 40rem; margin: var(--space-6) auto 0;
}
.blk-ask__input {
  flex: 1 1 16rem; min-width: 0;
  font: inherit; padding: .7rem 1rem; border-radius: 0;
  border: 1px solid color-mix(in srgb, var(--hc-ink) 45%, transparent);
  background: var(--hc-cream); color: var(--hc-ink);
}
.blk-ask__input:focus-visible { outline: 2px solid var(--hc-ink); outline-offset: 2px; }
.blk-ask .btn { margin-top: 0; cursor: pointer; }

/* The contact form keeps its own look (the /contact page's) on a cream card,
   so its ink labels read on every band colour. */
.blk-contact {
  max-width: 44rem; margin: var(--space-6) auto 0; padding: 30px;
  background: var(--hc-cream); color: var(--hc-ink); text-align: left;
}
.blk-contact .contact-form textarea {
  font: inherit; width: 100%; padding: .5rem 0; border-radius: 0; resize: vertical;
  background: transparent; color: var(--hc-ink);
  border: 0; border-bottom: 1px solid color-mix(in srgb, var(--hc-ink) 45%, transparent);
}
.blk-contact .contact-form textarea:focus-visible { outline: none; border-bottom-color: var(--hc-ink); }

.blk-visit { max-width: 40rem; margin: var(--space-6) auto 0; text-align: center; }
.blk-visit__list {
  list-style: none; margin: 0 0 var(--space-4); padding: 0;
  display: grid; gap: var(--space-3);
}
.blk-visit .band__lede { margin-top: var(--space-6); }
.blk-visit__map { display: block; width: min(100%, 26rem); height: auto; margin: var(--space-6) auto 0; }
