/* ============================================================
   Aerial Somatic Therapy — aerialsomatictherapy.com
   Design system: sanctuary-luxe, gravity-soft, alive.
   Palette (verified brand): navy #1F3253 · gold #BDA169 ·
   ivory #E0DEAD · white #FFFFFF · sky #2EA3F2 (sparing accent)
   60-30-10 = ivory/white 60 · navy 30 · gold 10
   Type: Fraunces (display) + Inter (body). Max 2 families.
   Motion: soft, exhale-paced, never gimmicky. Reduced-motion safe.
   ============================================================ */

:root {
  --navy: #1F3253;
  --navy-deep: #182842;          /* derived shade of brand navy */
  --gold: #BDA169;
  --gold-bright: #C9B07A;        /* derived tint of brand gold */
  --sky: #2EA3F2;                /* sparing 10% accent only */
  --ivory: #E0DEAD;
  --ivory-tint: #F5F3E6;         /* derived tint of brand ivory */
  --white: #FFFFFF;

  --text: rgba(31, 50, 83, 0.94);
  --text-soft: rgba(31, 50, 83, 0.8);
  --text-inverse: rgba(245, 243, 230, 0.96);
  --text-inverse-soft: rgba(245, 243, 230, 0.72);
  --hairline: rgba(31, 50, 83, 0.16);
  --hairline-gold: rgba(189, 161, 105, 0.55);

  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-body: "Inter", -apple-system, "Helvetica Neue", Arial, sans-serif;

  --fs-hero: clamp(2.8rem, 6.4vw, 4.9rem);
  --fs-h2: clamp(2rem, 4.1vw, 3.05rem);
  --fs-h3: clamp(1.35rem, 2.2vw, 1.7rem);
  --fs-lead: clamp(1.22rem, 1.8vw, 1.45rem);
  --fs-body: 1.0625rem;

  --ease-soft: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur-reveal: 0.7s;

  --space-section: clamp(4.5rem, 9vw, 8.5rem);
  --container: 1180px;
  --container-narrow: 780px;
  --container-wide: 1340px;
  --radius: 2px;

  --header-h: 96px;
  --header-h-scrolled: 72px;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
/* offset gold frames intentionally overhang section edges; clip, don't scroll */
html, body { overflow-x: clip; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.75;
  color: var(--text);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { max-width: 100%; height: auto; display: block; }
figure { margin: 0; }
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 380; line-height: 1.12; margin: 0 0 1.1rem; color: var(--navy); letter-spacing: -0.012em; }
h1 { font-size: var(--fs-hero); line-height: 1.04; }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
p { margin: 0 0 1.35rem; }
a { color: var(--navy); text-decoration-color: var(--hairline-gold); text-underline-offset: 3px; transition: color 0.45s var(--ease-soft), text-decoration-color 0.45s var(--ease-soft); }
a:hover { color: var(--gold); text-decoration-color: var(--gold); }
::selection { background: var(--gold); color: var(--navy-deep); }
:focus-visible { outline: 2px solid var(--sky); outline-offset: 3px; border-radius: 1px; }

/* ---------- Layout primitives ---------- */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: clamp(1.35rem, 4.5vw, 2.75rem); }
.container--narrow { max-width: var(--container-narrow); }
.container--wide { max-width: var(--container-wide); }

.section { padding-block: var(--space-section); }
.section--tight { padding-block: clamp(3rem, 6vw, 5.5rem); }
.section--white { background: var(--white); }
.section--tint { background: var(--ivory-tint); }
.section--ivory { background: var(--ivory); }
.section--navy { background: var(--navy); color: var(--text-inverse); }
.section--navy h2, .section--navy h3 { color: var(--ivory-tint); }
.section--navy p { color: var(--text-inverse-soft); }

.eyebrow {
  display: block;
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  /* Navy on light grounds, gold only on navy. Gold #BDA169 measures 2.49:1 on
     white and 1.81:1 on ivory; the floor is 4.5:1 at this size, so gold-on-light
     was failing everywhere it appeared. Gold on navy passes comfortably and is
     kept. Restraint never overrides legibility. Fixed 2026-07-29. */
  color: var(--navy);
  opacity: 0.85; /* 0.72 measured 4.54:1 on ivory, a 0.04 margin over the floor. 0.85 gives real headroom. */
  margin: 0 0 1.35rem;
}
.section--navy .eyebrow,
.hero .eyebrow,
.band .eyebrow { color: var(--gold-bright); opacity: 1; }

/* A section's quiet label is often the section's actual title. When it is, it must be a real
   <h2>, not a <span> -- otherwise the section reads as untitled to anything parsing the page,
   which is what happened to the founder block and the training band on 2026-08-30. Tagging it
   <h2 class="eyebrow"> must therefore look identical to <span class="eyebrow">. It already does
   by cascade (every property below is class-level and beats the bare h1-h4 element rule), but
   it is restated here so a later edit to the h1-h4 rule cannot silently change how these read. */
/* A status stamp sitting UNDER its title rather than above it. Same words, but it is no
   longer the label-above-a-heading pattern that website-builder Section 3 tell (a) counts,
   and the page drops from two of those to the one allowed. Added 2026-08-30. */
.eyebrow--under { margin: -0.5rem 0 0; }

h2.eyebrow,
h3.eyebrow {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.24em;
  margin: 0 0 1.35rem;
}

.lead {
  font-family: var(--font-display);
  font-size: var(--fs-lead);
  font-weight: 340;
  line-height: 1.62;
  color: var(--navy);
}
.section--navy .lead { color: var(--ivory-tint); }

.prose { max-width: 66ch; }
.prose p { margin-bottom: 1.45rem; }
.prose p:last-child { margin-bottom: 0; }

/* A long run of copy set flush on BOTH edges, not ragged on the right. Jose, 2026-09-03,
   looking at the five paragraphs on the About page: "the five paragraphs need to be right and
   left aligned. Right now it's only left aligned. It looks terrible."
   Hyphenation is switched on with it. Justified text without hyphenation opens white rivers
   down the middle of a narrow column, which looks worse than the ragged edge it replaced.
   The two belong together and neither should be used alone. */
.prose--justified p { text-align: justify; hyphens: auto; -webkit-hyphens: auto; }

/* RUNNING BODY COPY IS FLUSH ON BOTH EDGES, SITEWIDE.
   Jose asked for this three times on 2026-09-03, on three different pages, each time about
   a different block of copy: the Offerings paragraph, the five paragraphs on About, and the
   opening of "What Aerial Somatic Therapy Actually Does". Doing it one block at a time was
   the mistake. It is a reading style, not a per-section decision, so it is set once here.

   Hyphenation is switched on with it and the two must never be separated. Justified text
   without hyphenation opens white rivers down the middle of a narrow column, which looks
   worse than the ragged edge it replaced.

   WHERE IT APPLIES: the reading columns. Long-form copy a person actually reads.
   WHERE IT DOES NOT, and each of these is deliberate:
     .hero anything          a headline set flush both ways looks stretched
     .offer-card, .gold-list card captions and short list items are too narrow to justify
     footer, forms, notes    short fragments, not prose
     .center, .pullquote     already centred on purpose
   The last line of any paragraph stays ragged. That is how justification works, so a
   one-line paragraph is untouched and nothing needs to be excluded on length alone. */
.prose p,
.split-body p,
.measure-center p,
.container--narrow > p,
.container--narrow .prose p,
/* Added 2026-09-04, Jose. The three principle blocks on the home page were the ONLY paragraph
   run on the whole site still ragged-right after the sitewide justification pass. Their wrapper
   is .prin-flow inside a plain .container, so it matched none of the selectors above and was
   missed. This is the same correction as "left and right align all sections, not just one
   section", found again in the one place the first sweep could not see. Verified by walking every
   div that directly wraps paragraphs across all 13 pages: .principle-body was the only miss. */
.principle-body p {
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
}

/* Put back the ragged edge where justification would be wrong. */
.hero p, .hero-inner p,
.pullquote p,
.center p, p.center,
.offer-card p, .offer-line,
.site-footer p, .form-note, .form-sent-note,
.band-detail { text-align: inherit; hyphens: manual; }

/* Every paragraph in this run reads at the same weight and size as its opening line, in the
   display face rather than dropping to body text after the first paragraph. Jose, 2026-09-03,
   on the About page: "make the first paragraph font and size follow through into the rest of
   the paragraphs in that section." Five paragraphs of one continuous first-person account
   should not change voice halfway down. */
.prose--lead p {
  font-family: var(--font-display);
  font-size: var(--fs-lead);
  font-weight: 340;
  line-height: 1.62;
  color: var(--navy);
}

/* A heading needs more air beneath it when it introduces a long run of copy rather than a
   single paragraph. The default 1.1rem left "A Lifetime of Study" sitting on top of its own
   first line. Jose: "a lifetime of study is way too close to the copy underneath it." */
.prose-head { margin-bottom: clamp(1.75rem, 3vw, 2.5rem); }

.measure-center { max-width: 66ch; margin-inline: auto; }

/* Gold rule dividers (she asked for these by name) */
.gold-rule { width: 72px; height: 1px; background: var(--gold); border: 0; margin: 0 auto 2.4rem; }
.gold-rule--left { margin-inline: 0; }
.gold-rule--wide { width: 120px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 1rem 2.1rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.5s var(--ease-soft), color 0.5s var(--ease-soft), border-color 0.5s var(--ease-soft), transform 0.5s var(--ease-soft);
}
.btn:hover { transform: translateY(-2px); }
.btn-gold { background: var(--gold); color: var(--navy-deep); }
.btn-gold:hover { background: var(--gold-bright); color: var(--navy-deep); }
.btn-navy { background: var(--navy); color: var(--ivory-tint); }
.btn-navy:hover { background: var(--navy-deep); color: var(--ivory-tint); }
.btn-ghost { background: transparent; border-color: var(--gold); color: var(--ivory-tint); }
.btn-ghost:hover { background: rgba(189, 161, 105, 0.16); color: var(--white); }
.btn-ghost--dark { border-color: var(--navy); color: var(--navy); }
.btn-ghost--dark:hover { background: rgba(31, 50, 83, 0.07); color: var(--navy); }

.text-link {
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--navy);
  border-bottom: 1px solid var(--gold);
  padding-bottom: 0.3rem;
  transition: color 0.45s var(--ease-soft), border-color 0.45s var(--ease-soft);
}
.text-link:hover { color: var(--gold); }
.section--navy .text-link { color: var(--ivory-tint); }

/* ============================================================
   HEADER — navy, sticky, animated Stacked Gold logo (the sting)
   ============================================================ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 90;
  background: var(--navy);
  transition: box-shadow 0.6s var(--ease-soft);
}
.site-header.is-scrolled { box-shadow: 0 10px 34px rgba(24, 40, 66, 0.35); }
.header-inner {
  max-width: var(--container-wide);
  margin-inline: auto;
  padding-inline: clamp(1.35rem, 4vw, 2.5rem);
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  transition: height 0.6s var(--ease-soft);
}
.site-header.is-scrolled .header-inner { height: var(--header-h-scrolled); }

.brand { display: inline-flex; align-items: center; text-decoration: none; }

/* --- The logo sting (approved animated-logo asset, scoped) --- */
.ast-sting {
  --ast-logo-width: 128px;
  --ast-float: 5px;
  --ast-glow: rgba(189, 161, 105, 0.45);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  line-height: 0;
}
/* Light/ivory context variant (brand rule: gold-on-navy, blue-on-ivory).
   Same reveal + idle float; swap the <img> to logo-stacked-blue.png and
   the glow goes soft navy so the mark reads on a light background. */
.ast-sting--blue { --ast-glow: rgba(31, 50, 83, 0.4); }
.ast-sting__logo {
  display: block;
  width: var(--ast-logo-width);
  height: auto;
  opacity: 0;
  transform: translateY(4px) scale(0.94);
  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 var(--ast-reveal, 0%), rgba(0,0,0,0) calc(var(--ast-reveal, 0%) + 14%), rgba(0,0,0,0) 100%);
          mask-image: linear-gradient(to top, #000 0%, #000 var(--ast-reveal, 0%), rgba(0,0,0,0) calc(var(--ast-reveal, 0%) + 14%), rgba(0,0,0,0) 100%);
  will-change: opacity, transform, -webkit-mask-image, filter;
  transition: width 0.6s var(--ease-soft);
}
.site-header.is-scrolled .ast-sting__logo { width: 96px; }
.ast-sting.ast-animate .ast-sting__logo {
  animation:
    ast-reveal 1500ms cubic-bezier(0.22, 0.61, 0.36, 1) forwards,
    ast-rise 900ms cubic-bezier(0.22, 0.61, 0.36, 1) forwards,
    ast-fade 900ms ease-in-out forwards,
    ast-float 4000ms ease-in-out 2600ms infinite,
    ast-glow 4600ms ease-in-out 2600ms infinite;
}
@keyframes ast-reveal { 0% { --ast-reveal: 0%; } 100% { --ast-reveal: 130%; } }
@property --ast-reveal { syntax: "<percentage>"; inherits: false; initial-value: 0%; }
@keyframes ast-rise { 0% { transform: translateY(10px) scale(0.94); } 100% { transform: translateY(0) scale(1); } }
@keyframes ast-fade { 0% { opacity: 0; } 100% { opacity: 1; } }
@keyframes ast-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(calc(var(--ast-float) * -1)); } }
@keyframes ast-glow { 0%, 100% { filter: drop-shadow(0 0 0 var(--ast-glow)); } 50% { filter: drop-shadow(0 6px 22px var(--ast-glow)); } }

/* --- Navigation --- */
.nav { display: flex; align-items: center; gap: clamp(1.1rem, 2vw, 1.9rem); }
.nav a {
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-decoration: none;
  color: var(--text-inverse-soft);
  padding: 0.4rem 0;
  border-bottom: 1px solid transparent;
  transition: color 0.45s var(--ease-soft), border-color 0.45s var(--ease-soft);
  white-space: nowrap;
}
.nav a:hover { color: var(--white); border-bottom-color: var(--gold); }
.nav .nav-cta {
  border: 1px solid var(--gold);
  border-radius: var(--radius);
  padding: 0.55rem 1.25rem;
  color: var(--gold-bright);
}
.nav .nav-cta:hover { background: rgba(189, 161, 105, 0.14); color: var(--white); border-bottom-color: var(--gold); }

/* Active page marker (body[data-page] set per page; header stays identical) */
body[data-page="home"] .nav a[data-nav="home"],
body[data-page="what-is-ast"] .nav a[data-nav="what-is-ast"],
body[data-page="about"] .nav a[data-nav="about"],
body[data-page="offerings"] .nav a[data-nav="offerings"],
body[data-page="the-somatic-ceremony"] .nav a[data-nav="offerings"],
body[data-page="metamorphosis"] .nav a[data-nav="offerings"],
body[data-page="group-experiences"] .nav a[data-nav="offerings"],
body[data-page="practitioner-training"] .nav a[data-nav="practitioner-training"],
body[data-page="inside-the-dome"] .nav a[data-nav="inside-the-dome"],
body[data-page="testimonials"] .nav a[data-nav="testimonials"],
body[data-page="order-your-swing"] .nav a[data-nav="order-your-swing"],
body[data-page="contact"] .nav a[data-nav="contact"] {
  color: var(--white);
  border-bottom-color: var(--gold);
}

/* Offerings dropdown */
.nav-drop { position: relative; }
.nav-drop > a { display: inline-flex; align-items: center; gap: 0.45rem; }
.nav-drop > a::after {
  content: "";
  width: 6px; height: 6px;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform 0.4s var(--ease-soft);
}
.nav-drop.open > a::after, .nav-drop:hover > a::after { transform: rotate(225deg) translateY(-1px); }
.nav-drop-menu {
  position: absolute;
  top: calc(100% + 0.9rem);
  left: 50%;
  transform: translate(-50%, 8px);
  min-width: 240px;
  background: var(--navy-deep);
  border-top: 1px solid var(--gold);
  border-radius: var(--radius);
  box-shadow: 0 22px 48px rgba(24, 40, 66, 0.45);
  list-style: none;
  margin: 0;
  padding: 0.7rem 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s var(--ease-soft), transform 0.5s var(--ease-soft), visibility 0s linear 0.5s;
}
.nav-drop:hover .nav-drop-menu,
.nav-drop:focus-within .nav-drop-menu,
.nav-drop.open .nav-drop-menu {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition: opacity 0.5s var(--ease-soft), transform 0.5s var(--ease-soft), visibility 0s;
}
.nav-drop-menu li a {
  display: block;
  padding: 0.65rem 1.4rem;
  border-bottom: 0;
  color: var(--text-inverse-soft);
}
.nav-drop-menu li a:hover { color: var(--gold-bright); background: rgba(189, 161, 105, 0.07); }

/* Mobile nav */
.nav-toggle {
  display: none;
  background: transparent;
  border: 0;
  width: 44px; height: 44px;
  position: relative;
  cursor: pointer;
  z-index: 110;
}
.nav-toggle span {
  position: absolute;
  left: 10px; right: 10px;
  height: 1.5px;
  background: var(--ivory-tint);
  transition: transform 0.55s var(--ease-soft), opacity 0.4s var(--ease-soft), top 0.55s var(--ease-soft);
}
.nav-toggle span:nth-child(1) { top: 16px; }
.nav-toggle span:nth-child(2) { top: 22px; }
.nav-toggle span:nth-child(3) { top: 28px; }
body.nav-open .nav-toggle span:nth-child(1) { top: 22px; transform: rotate(45deg); }
body.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
body.nav-open .nav-toggle span:nth-child(3) { top: 22px; transform: rotate(-45deg); }

@media (max-width: 1199px) {
  .nav-toggle { display: block; }
  .nav {
    position: fixed;
    inset: 0;
    background: var(--navy-deep);
    flex-direction: column;
    /* flex-start, NOT center. Center-justification splits an expanding submenu's
       growth evenly above and below, so opening one yanked the just-tapped trigger
       ~91px UP out from under the finger; the second tap (what a finger does when
       the first appears to fail) landed on a submenu link and navigated away. That
       is the reported "the menu disappears" bug, and it was CSS, not JS.
       Top-anchoring means an expansion only pushes what is below it. 2026-07-29. */
    justify-content: flex-start;
    padding: 6rem 1.5rem 3rem;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    align-items: center;
    gap: 1.4rem;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.6s var(--ease-soft), visibility 0s linear 0.6s;
    z-index: 100;
  }
  body.nav-open .nav { opacity: 1; visibility: visible; transition: opacity 0.6s var(--ease-soft), visibility 0s; }
  .nav a { font-family: var(--font-display); font-size: 1.45rem; font-weight: 380; letter-spacing: 0.01em; text-transform: none; }
  .nav .nav-cta { padding: 0.75rem 2rem; }
  /* MOBILE DROPDOWN FIX, 2026-09-01, found by Jose on his phone and measured at 390px in a
     headless browser rather than guessed. Two separate causes.

     ONE, the jump to the left. The desktop menu is absolutely positioned and centred with
     left:50% and transform:translate(-50%,0). The rule below cancels that transform on the
     CLOSED menu, but the open-state rule at line ~329 is more specific (0,3,0 against 0,1,0),
     so the instant a menu opened the desktop transform won again and threw it half its own
     width to the left, off the screen edge with the words cut. Measured: the More menu
     rendered at x=10 inside a container at x=130, a 120px shift, exactly half of 240px. This
     is also why Offerings appeared to move only when touched: it is already display:block on
     mobile by default (see the :first-of-type rule below), so it sat centred until the tap
     added .open and the transform fired. The open and hover states must cancel it here too.

     TWO, the off-centre trigger. .nav-drop is a block sized to its widest child. Closed that
     is the short trigger word; open it is the widest menu item, so the inline-flex trigger
     dropped to the left edge of a box that had just grown around it. Measured: "Offerings" at
     x=130 width 103 inside a container 240 wide. Centring the container fixes it, and
     min-width has to be released so a 240px desktop floor stops forcing the width on a
     narrow phone. */
  .nav-drop { text-align: center; width: 100%; }
  .nav-drop > a { justify-content: center; }
  .nav-drop-menu {
    position: static;
    transform: none;
    opacity: 1;
    min-width: 0;
    width: 100%;
    background: transparent;
    border-top: 0;
    box-shadow: none;
    padding: 0;
    display: none;
    text-align: center;
  }
  body.nav-open .nav-drop-menu { visibility: visible; }
  .nav-drop.open .nav-drop-menu { display: block; transform: none; }
  .nav-drop:hover .nav-drop-menu,
  .nav-drop:focus-within .nav-drop-menu { transform: none; }
  /* Nothing inside the mobile nav may push it wider than the screen. */
  .nav { max-width: 100vw; overflow-x: hidden; }
  .nav-drop-menu li a { font-size: 1.05rem; padding: 0.5rem 0; color: var(--gold-bright); }
  body.nav-open { overflow: hidden; }
  /* Mobile discoverability: reveal her signature experiences by name the moment
     the menu opens, no tap needed (Maura's 7/28 phone feedback). Offerings is the
     first .nav-drop; "More" (second) stays collapsed for secondary items. */
  .nav-drop:first-of-type .nav-drop-menu { display: block; }
  .nav-drop:first-of-type > a::after { display: none; }
}

/* ============================================================
   HERO — full-bleed, editorial left-aligned, Ken Burns drift
   ============================================================ */
.hero {
  position: relative;
  min-height: 92vh;
  /* Cap it to the viewport. Previously min-height alone let content push the hero
     PAST the fold (measured 924px tall in a 900px window), which is how the Myers
     credential ended up 33px below the fold on a 390x664 phone. */
  max-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--navy);
}
/* Interior photo heroes fill the entire above-fold area (Pattern A, matches
   Practitioner Training): photo fills the fold, overlaid title sits at its base,
   body copy begins cleanly below the fold. No mid-fold gap. */
.hero--short { min-height: 92vh; }
.hero-media { position: absolute; inset: 0; }
.hero-media img, .hero-media video {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
}
/* What Is AST hero (photo 13): subject sits high in frame; bias the crop
   toward the top so Maura's head is not clipped by the fill-the-fold hero. */
body[data-page="what-is-ast"] .hero-media img { object-position: center 22%; }
.hero-scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(102deg, rgba(24, 40, 66, 0.88) 0%, rgba(24, 40, 66, 0.6) 34%, rgba(24, 40, 66, 0.18) 62%, rgba(24, 40, 66, 0.04) 80%),
    linear-gradient(to top, rgba(24, 40, 66, 0.55) 0%, rgba(24, 40, 66, 0) 34%);
}
.hero--short .hero-scrim {
  background:
    linear-gradient(to top, rgba(24, 40, 66, 0.72) 0%, rgba(24, 40, 66, 0.28) 55%, rgba(24, 40, 66, 0.34) 100%);
}
.hero-inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--container-wide);
  margin-inline: auto;
  /* Third value is the SETBACK from the fold: the copy never sits on the fold line.
     Raised from 11vh to 14vh so the last line clears it with visible air. */
  padding: clamp(3rem, 7vh, 6rem) clamp(1.35rem, 4.5vw, 2.75rem) clamp(5rem, 14vh, 9rem);
}
.hero-eyebrow {
  display: block;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--gold-bright);
  margin-bottom: 1.6rem;
}
.hero-title {
  color: var(--ivory-tint);
  max-width: 12.5ch;
  margin-bottom: 2.2rem;
}
.hero-title em { font-style: italic; font-weight: 340; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 1.1rem; align-items: center; }

/* Ken Burns — a still that quietly breathes */
.kenburns { animation: kenburns 38s ease-in-out infinite alternate; transform-origin: 62% 42%; will-change: transform; }
@keyframes kenburns {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to { transform: scale(1.07) translate3d(-1.4%, -1.2%, 0); }
}

/* ============================================================
   FULL-BLEED PHOTO BAND — slow parallax
   ============================================================ */
.band { position: relative; overflow: hidden; background: var(--navy); }
.band-media { position: absolute; inset: -14% 0; }
.band-media img { width: 100%; height: 100%; object-fit: cover; will-change: transform; }
.band-scrim { position: absolute; inset: 0; background: linear-gradient(to top, rgba(24, 40, 66, 0.78) 0%, rgba(24, 40, 66, 0.3) 55%, rgba(24, 40, 66, 0.42) 100%); }
.band-inner {
  position: relative;
  z-index: 2;
  min-height: 60vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(5rem, 12vh, 8rem) clamp(1.35rem, 4.5vw, 2.75rem);
}
.band-inner h2 { color: var(--ivory-tint); }
.band-inner p { color: var(--text-inverse-soft); max-width: 52ch; }
.band-inner--center { align-items: center; text-align: center; }

/* ============================================================
   SPLIT — image + text editorial rows
   ============================================================ */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(2.75rem, 7vw, 5.5rem);
  align-items: center;
}
.split--flip .split-media { order: 2; }
.split--flip .split-body { order: 1; }
.split-media img { border-radius: var(--radius); width: 100%; box-shadow: 0 30px 70px rgba(24, 40, 66, 0.18); }
.split-media--frame { position: relative; }
.split-media--frame::after {
  content: "";
  position: absolute;
  inset: 1.4rem -1.4rem -1.4rem 1.4rem;
  border: 1px solid var(--hairline-gold);
  border-radius: var(--radius);
  z-index: -1;
}
.split--flip .split-media--frame::after { inset: 1.4rem 1.4rem -1.4rem -1.4rem; }
@media (max-width: 860px) {
  .split, .split--flip { grid-template-columns: 1fr; gap: 2.4rem; }
  .split--flip .split-media { order: 0; }
  .split--flip .split-body { order: 1; }
  .split-media--frame::after, .split--flip .split-media--frame::after { inset: 1rem -0.7rem -0.7rem 1rem; }
}

/* ============================================================
   THREE PRINCIPLES — quiet numerals, no icons
   ============================================================ */
.principles { display: grid; gap: clamp(3rem, 6vw, 4.5rem); }
.principle {
  display: grid;
  grid-template-columns: minmax(150px, 240px) minmax(0, 1fr);
  gap: clamp(1.75rem, 5vw, 4.5rem);
  align-items: start;
}
.principle:nth-child(even) { padding-left: clamp(0rem, 6vw, 5.5rem); }
/* .principle-num removed 2026-08-19. The 01/02/03 gold numerals were deleted from the
   markup (homepage principles + Metamorphosis arc stages) as decorative filler, leaving
   these rules matching nothing. Verified zero occurrences of "principle-num" across all
   .html and .js before removal. */
.principle h3 { margin-bottom: 0; }
.principle-body { max-width: 62ch; }
@media (max-width: 760px) {
  .principle { grid-template-columns: 1fr; gap: 1rem; }
  .principle:nth-child(even) { padding-left: 0; }
}

/* ---------- The principles thread (added 2026-08-30) ----------
   The three principles used to sit as three detached blocks of long text with nothing
   running alongside them. This grafts the "signature moment" rail from
   redesign/round1/arm-2-the-work: one continuous hairline down the left of the whole
   group, a mark beside each heading, each heading sticky so it rides its own body copy,
   and a single ring that lights on whichever principle you are reading.

   Deliberately decorative only. Every <h3> stays visible, stays an <h3>, and is not
   duplicated anywhere, so the heading outline the AEO/GEO layout ruling depends on is
   exactly what it was before. With JS off or reduced-motion on, the thread and marks
   still render static and the headings still hold the text. */
.prin-flow {
  position: relative;
  margin-top: clamp(3.5rem, 7vw, 6rem);
  display: grid;
  gap: clamp(3rem, 6vw, 4.5rem);
}
.prin-flow::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.75rem;
  bottom: 0.75rem;
  width: 1px;
  background: linear-gradient(
    to bottom,
    transparent 0,
    var(--hairline-gold) 6%,
    var(--hairline-gold) 94%,
    transparent 100%
  );
}
/* the stagger would pull the headings off the thread */
.prin-flow .principle { padding-left: 0; }
.prin-flow .principle:nth-child(even) { padding-left: 0; }

.principle-head { position: relative; padding-left: clamp(1.25rem, 2.4vw, 2rem); }
.principle-head h3 { margin-bottom: 0; }

.prin-mark {
  position: absolute;
  left: -3px;
  top: 0.62em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gold);
  transition: background var(--dur-reveal) var(--ease-soft);
}
.principle-head::after {
  content: "";
  position: absolute;
  left: -10px;
  top: calc(0.62em - 7px);
  width: 19px;
  height: 19px;
  border: 1px solid var(--gold);
  border-radius: 50%;
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 0.55s var(--ease-soft), transform 0.55s var(--ease-soft);
  pointer-events: none;
}
.prin-flow.thread-live .principle.is-active .principle-head::after {
  opacity: 1;
  transform: none;
}

/* the pull-quote keeps its place between Alignment and Embodiment, now inside the flow
   so the thread stays unbroken through it */
.prin-aside { padding-block: clamp(0.5rem, 2vw, 1.5rem); }

@media (min-width: 761px) {
  .principle-head {
    position: sticky;
    top: calc(var(--header-h-scrolled) + clamp(1.5rem, 5vh, 3.25rem));
  }
  .principle-head h3 {
    transition: opacity 0.55s var(--ease-soft);
  }
  .prin-flow.thread-live .principle:not(.is-active) .principle-head h3 { opacity: 0.4; }
  .prin-flow.thread-live .principle:not(.is-active) .prin-mark { background: var(--hairline); }
}

@media (max-width: 760px) {
  .prin-flow::before { top: 0.5rem; bottom: 0.5rem; }
  /* The thread lives in a gutter of its own on a phone. The heading box still starts
     at x=0 so its dot stays on the line, and the TEXT inside it is pushed clear by the
     padding. The body copy gets the identical padding so it lines up under the heading
     instead of sitting on top of the line, which is what it did before: .principle
     collapses to one column here, and only the heading had any indent at all.
     Fixed 2026-08-30 after Jose checked it on a phone. */
  .principle-head,
  .principle-body { padding-left: 2.25rem; }
  .prin-mark { top: 0.55em; }
  .principle-head::after { top: calc(0.55em - 7px); }
  /* the pull-quote between Alignment and Embodiment clears the thread too */
  .prin-aside { padding-left: 2.25rem; }
}

@media (prefers-reduced-motion: reduce) {
  .prin-mark,
  .principle-head h3,
  .principle-head::after { transition: none; }
  .principle-head { position: static; }
}

/* Arc stages (Metamorphosis): the three stages as a centered left-to-right
   progression, spacious enough that short labels read as a deliberate arc rather
   than floating apart. (Carried gold numerals until 2026-08-19; see .principle-num.) */
.arc-stages {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(2rem, 6vw, 5rem);
  align-items: start;
  text-align: center;
}
.arc-stage h3 { margin-bottom: 0; }
@media (max-width: 640px) {
  .arc-stages { grid-template-columns: 1fr; gap: clamp(2.5rem, 9vw, 3.5rem); }
}

/* ============================================================
   QUOTES
   ============================================================ */
/* Maura's own pull-quote: centered, Fraunces italic, gold rules */
.pullquote {
  margin: 0;
  padding: 0;
  text-align: center;
}
.pullquote p {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 340;
  font-size: clamp(1.4rem, 2.6vw, 1.9rem);
  line-height: 1.5;
  color: var(--navy);
  max-width: 30ch;
  margin: 0 auto;
}
.section--navy .pullquote p { color: var(--ivory-tint); }
/* Two pull-quotes in a row need air between them.
   Reuses the .stack-lg rhythm value so the spacing system stays one system. */
.pullquote + .pullquote { margin-top: clamp(2.5rem, 5vw, 4rem); }

/* External attributed voice: DISTINCT from Maura's (her explicit note).
   Inter light italic, gold left border, small-caps attribution. */
.external-quote {
  margin: 0;
  padding: 0.4rem 0 0.4rem 1.75rem;
  border-left: 2px solid var(--gold);
}
.external-quote p {
  font-family: var(--font-body);
  font-weight: 300;
  font-style: italic;
  font-size: 1.16rem;
  line-height: 1.72;
  color: var(--text-soft);
  margin-bottom: 0.9rem;
}
.quote-attr {
  display: block;
  font-family: var(--font-body);
  font-style: normal;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--navy);
}
.quote-attr span { display: block; font-weight: 400; letter-spacing: 0.1em; color: var(--text-soft); margin-top: 0.3rem; }
.section--ivory .external-quote p, .section--tint .external-quote p { color: rgba(31, 50, 83, 0.72); }
.section--navy .external-quote p { color: var(--text-inverse-soft); }
.section--navy .quote-attr { color: var(--ivory-tint); }
.section--navy .quote-attr span { color: var(--text-inverse-soft); }

/* Testimonial strip (homepage) + testimonial cards */
.quote-strip { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2.5rem, 6vw, 5rem); }
@media (max-width: 860px) { .quote-strip { grid-template-columns: 1fr; } }

.t-feature { margin: 0; }
.t-feature p {
  font-family: var(--font-display);
  font-weight: 340;
  font-style: italic;
  font-size: clamp(1.25rem, 2vw, 1.5rem);
  line-height: 1.6;
  color: var(--navy);
  margin-bottom: 1.2rem;
}

.t-card {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  gap: 1.5rem;
  align-items: start;
  padding: 2rem 0;
  border-top: 1px solid var(--hairline);
  margin: 0;
}
.t-card:last-child { border-bottom: 1px solid var(--hairline); }
.t-card img { width: 72px; height: 72px; border-radius: 50%; object-fit: cover; border: 1px solid var(--hairline-gold); }
.t-card p { font-weight: 300; font-style: italic; font-size: 1.08rem; color: rgba(31, 50, 83, 0.8); margin-bottom: 0.9rem; }
.t-card--noavatar { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 560px) { .t-card { grid-template-columns: 56px 1fr; } .t-card img { width: 56px; height: 56px; } }

/* ============================================================
   OFFERINGS — asymmetric three, staggered baseline
   ============================================================ */
.offer-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.75rem, 4vw, 3.25rem);
  align-items: start;
}
/* Item 3b Option A: the homepage intro paragraph had no heading and read as orphaned.
   Deliberately not titled "What Is Aerial Somatic Therapy" (that is the /what-is-ast/
   page title; two pages competing for one title is the redundancy she flagged). */
.intro-heading { margin-bottom: clamp(1.4rem, 2.5vw, 2rem); }

/* Item 8: the fourth path, named in text weight rather than card weight, so the
   section stops reading as a complete three-item menu without becoming a four-card
   grid. See build-docs/2026-08-19-JUDGMENT-items-8-3b-4-12.md. */
/* D, 2026-09-01. Maura asked for this line to stand out from the three offering cards above
   it, "a tad bigger or a different font". Given SEPARATION rather than size: more air above,
   a short gold hairline, and a slightly larger, darker line. Raw size was deliberately not
   used, because this sits directly beneath three offering cards and a fourth loud thing there
   reads as a fourth offering and splits the section's one job. The training is her
   highest-value conversion, so it earns its own moment rather than a bigger shout. */
.offer-aside {
  margin-top: clamp(3.25rem, 6vw, 4.75rem);
  padding-top: clamp(1.6rem, 3vw, 2.2rem);
  position: relative;
  color: var(--navy);
  font-size: 1.06rem;
}
.offer-aside::before {
  content: "";
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: 2.75rem; height: 1px;
  background: var(--gold);
}
.offer-card { text-decoration: none; display: block; color: inherit; }
/* All three offering cards sit on ONE baseline, everywhere. The middle card used to
   be pushed down 52px as an editorial stagger. Jose ruled against it on the home page
   on 2026-08-30, and the fix was scoped to home only, which left the same misalignment
   on the Offerings page. He ruled against it there too on 2026-09-03: "metamorphosis,
   you gotta align it from top to bottom to match somatic ceremony and group
   experiences. The picture and the copy underneath it needs to all be moved up
   together." Scoping the first ruling to one page is what made him say it twice, so
   this is now unscoped. Do not reintroduce a per-page exception. */
.offer-card:nth-child(2) { margin-top: 0; }
.offer-card figure { overflow: hidden; border-radius: var(--radius); }
.offer-card img {
  aspect-ratio: 4 / 5;
  object-fit: cover;
  width: 100%;
  transition: transform 1.4s var(--ease-soft);
}
.offer-card:hover img { transform: scale(1.045); }
.offer-card h3 { margin: 1.6rem 0 0.5rem; transition: color 0.45s var(--ease-soft); }
.offer-card:hover h3 { color: var(--gold); }
.offer-card .offer-line { color: var(--text-soft); font-size: 0.98rem; margin-bottom: 1.1rem; }
@media (max-width: 860px) {
  .offer-grid { grid-template-columns: 1fr; }
  .offer-card:nth-child(2) { margin-top: 0; }
  .offer-card img { aspect-ratio: 16 / 10; }
}

/* ============================================================
   GALLERY — editorial masonry (Inside the Dome)
   ============================================================ */
.gallery { columns: 3 300px; column-gap: 1.5rem; }
.gallery figure { break-inside: avoid; margin: 0 0 1.5rem; overflow: hidden; border-radius: var(--radius); }
.gallery img { width: 100%; transition: transform 1.4s var(--ease-soft); }
.gallery figure:hover img { transform: scale(1.035); }

/* Deterministic 3-column gallery (Inside the Dome / The Space): explicit columns
   so the arrangement is controlled, not left to masonry balancing. Preserves
   each photo's natural aspect ratio (no cropping). Stacks on mobile. */
.gallery-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; align-items: start; }
.gcol { display: flex; flex-direction: column; gap: 1.5rem; }
.gcol figure { margin: 0; overflow: hidden; border-radius: var(--radius); }
.gcol img { width: 100%; display: block; transition: transform 1.4s var(--ease-soft); }
.gcol figure:hover img { transform: scale(1.035); }
@media (max-width: 760px) { .gallery-cols { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .gcol img { transition: none; } }

/* Swing color swatches (Order Your Swing): her supplied fabric colors as an
   editorial grid, photo + color name. Sourced from her live site's color set. */
.swatch-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: clamp(1rem, 2.4vw, 1.75rem);
}
.swatch { margin: 0; text-align: center; }
.swatch figure, .swatch { break-inside: avoid; }
.swatch img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius);
  display: block;
  box-shadow: 0 12px 30px rgba(24, 40, 66, 0.12);
  transition: transform 1.2s var(--ease-soft);
}
.swatch:hover img { transform: scale(1.03); }
.swatch figcaption {
  margin-top: 0.7rem;
  font-family: var(--font-body);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-soft);
}
@media (prefers-reduced-motion: reduce) { .swatch img { transition: none; } }

/* ============================================================
   VIDEO HOLDING SPOT — poster now, film drops in later
   ============================================================ */
.video-slot { position: relative; overflow: hidden; border-radius: var(--radius); background: var(--navy); }
.video-slot img, .video-slot video { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; }
.video-slot--tall img, .video-slot--tall video { aspect-ratio: 16 / 10; }

/* Film theater (Inside the Dome): the full film in a contained gold-hairline
   16:9 frame, deliberately framed and centered, never cut by the fold. */
.theater {
  max-width: 940px;
  margin-inline: auto;
  padding: clamp(0.55rem, 1.3vw, 0.95rem);
  border: 1px solid var(--hairline-gold);
  border-radius: var(--radius);
  background: var(--navy-deep);
  box-shadow: 0 30px 70px rgba(24, 40, 66, 0.22);
}
.theater video {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
  border-radius: var(--radius);
  background: var(--navy);
}

/* ============================================================
   FACULTY / DEFINITION ROWS
   ============================================================ */
.faculty { display: grid; gap: 2.75rem; }
.faculty-item {
  display: grid;
  grid-template-columns: minmax(190px, 280px) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  padding-top: 2.75rem;
  border-top: 1px solid var(--hairline);
}
.faculty-item h3 { margin-bottom: 0.35rem; }
.faculty-role { font-size: 0.74rem; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold); }
@media (max-width: 760px) { .faculty-item { grid-template-columns: 1fr; gap: 0.9rem; } }

/* Checklist without icons: gold hairline list */
.gold-list { list-style: none; margin: 0 0 1.35rem; padding: 0; }
.gold-list li { padding: 0.85rem 0 0.85rem 1.65rem; position: relative; border-bottom: 1px solid var(--hairline); }
.gold-list li:first-child { border-top: 1px solid var(--hairline); }
.gold-list li::before { content: ""; position: absolute; left: 0; top: 1.7rem; width: 0.75rem; height: 1px; background: var(--gold); }
.section--navy .gold-list li { border-color: rgba(224, 222, 173, 0.18); }

/* Quiet supporting lines inside a navy CTA band. Added 2026-09-01 for the home-page training
   band, which Maura found "super crowded". The fix is hierarchy rather than deletion: the
   dates, the location and the 8-student limit all stay, and they simply stop shouting at the
   same volume as the headline above them. */
.band-detail { font-size: 0.94rem; color: var(--text-inverse-soft); margin-bottom: 0.55rem; }
.band-detail:last-of-type { margin-bottom: 0; }

/* Numbered care steps (order-your-swing). Her washing instructions arrived 2026-08-31 as
   four sequenced lists, and the site had no ordered-list style at all. Built to sit beside
   .gold-list rather than replace it: same hairline rhythm, but the marker is the step
   number in gold instead of a gold rule, because in care instructions the ORDER is the
   content. .care-list--plain drops the numbering for the drying options, which are a
   choice between two methods, not a sequence. */
.care-steps { display: grid; gap: clamp(2rem, 4vw, 3rem); }
.care-steps h3 { margin-bottom: 0.9rem; }
.care-list { list-style: none; counter-reset: care; margin: 0; padding: 0; }
.care-list li { padding: 0.7rem 0 0.7rem 2.1rem; position: relative; border-bottom: 1px solid var(--hairline); }
.care-list li:first-child { border-top: 1px solid var(--hairline); }
ol.care-list li::before {
  counter-increment: care; content: counter(care);
  position: absolute; left: 0; top: 0.7rem;
  font-family: var(--font-display); font-size: 0.95rem; color: var(--gold);
}
.care-list--plain li::before { content: ""; position: absolute; left: 0; top: 1.45rem; width: 0.75rem; height: 1px; background: var(--gold); }
@media (min-width: 761px) { .care-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(2rem, 4vw, 3.5rem) clamp(2.5rem, 5vw, 4rem); } }

/* Investment block (training) */
.invest { display: flex; flex-wrap: wrap; gap: clamp(2rem, 5vw, 4rem); align-items: baseline; }
.invest-item .invest-num { font-family: var(--font-display); font-weight: 380; font-size: clamp(2.1rem, 3.6vw, 3rem); color: var(--ivory-tint); line-height: 1.1; display: block; }
.invest-item .invest-label { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--text-inverse-soft); display: block; margin-top: 0.5rem; }
/* removed 2026-07-29: colored a price with --sky, which is reserved for focus rings only */

/* ============================================================
   FORMS — editorial, quiet
   ============================================================ */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem 2rem; }
.form-grid .form-field--full { grid-column: 1 / -1; }
@media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } }
.form-field label {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--navy);
  margin-bottom: 0.55rem;
}
.form-field input, .form-field select, .form-field textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--text);
  background: var(--white);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
  transition: border-color 0.45s var(--ease-soft), box-shadow 0.45s var(--ease-soft);
}
.form-field input:focus, .form-field select:focus, .form-field textarea:focus {
  outline: none;
  border-color: var(--sky);
  box-shadow: 0 0 0 3px rgba(46, 163, 242, 0.14);
}
.form-field textarea { min-height: 160px; resize: vertical; }
.form-note { font-size: 0.9rem; color: var(--text-soft); }

/* ============================================================
   FOOTER — navy, newsletter, corrected brand name
   ============================================================ */
.site-footer { background: var(--navy-deep); color: var(--text-inverse-soft); }
.footer-main {
  max-width: var(--container-wide);
  margin-inline: auto;
  padding: clamp(3.5rem, 7vw, 5.5rem) clamp(1.35rem, 4.5vw, 2.75rem) clamp(2.5rem, 5vw, 4rem);
  display: grid;
  grid-template-columns: 1.3fr 0.7fr 0.7fr 1.1fr;
  gap: clamp(2.25rem, 5vw, 4rem);
}
@media (max-width: 980px) { .footer-main { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-main { grid-template-columns: 1fr; } }
.footer-brand img { width: 200px; margin-bottom: 1.4rem; }
.footer-brand p { font-size: 0.94rem; margin-bottom: 0.4rem; }
.footer-heading {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 1.2rem;
}
.footer-links { list-style: none; margin: 0; padding: 0; }
.footer-links li { margin-bottom: 0.65rem; }
.footer-links a { color: var(--text-inverse-soft); text-decoration: none; font-size: 0.95rem; transition: color 0.45s var(--ease-soft); }
.footer-links a:hover { color: var(--gold-bright); }
.footer-news p { font-size: 0.95rem; margin-bottom: 1.1rem; }
.footer-news-form { display: flex; gap: 0.6rem; }
.footer-news-form input {
  flex: 1;
  min-width: 0;
  font-family: var(--font-body);
  font-size: 0.95rem;
  color: var(--ivory-tint);
  background: rgba(245, 243, 230, 0.07);
  border: 1px solid rgba(245, 243, 230, 0.22);
  border-radius: var(--radius);
  padding: 0.75rem 1rem;
  transition: border-color 0.45s var(--ease-soft), box-shadow 0.45s var(--ease-soft);
}
.footer-news-form input::placeholder { color: rgba(245, 243, 230, 0.45); }
.footer-news-form input:focus { outline: none; border-color: var(--sky); box-shadow: 0 0 0 3px rgba(46, 163, 242, 0.16); }
.footer-news-form .btn { padding: 0.75rem 1.4rem; }
.footer-bottom { border-top: 1px solid rgba(245, 243, 230, 0.14); }
.footer-bottom-inner {
  max-width: var(--container-wide);
  margin-inline: auto;
  padding: 1.6rem clamp(1.35rem, 4.5vw, 2.75rem);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.8rem 2rem;
  font-size: 0.85rem;
  color: rgba(245, 243, 230, 0.55);
}
.footer-bottom-inner a { color: rgba(245, 243, 230, 0.7); text-decoration: none; }
.footer-bottom-inner a:hover { color: var(--gold-bright); }

/* ============================================================
   SUB-PAGE HERO (interior pages)
   ============================================================ */
.page-hero { background: var(--navy); position: relative; overflow: hidden; }
.page-hero-inner {
  position: relative;
  z-index: 2;
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(4.5rem, 10vh, 7.5rem) clamp(1.35rem, 4.5vw, 2.75rem) clamp(3.5rem, 8vh, 6rem);
}
.page-hero h1 { color: var(--ivory-tint); max-width: 18ch; font-size: clamp(2.4rem, 5vw, 3.9rem); }
.page-hero .hero-eyebrow { margin-bottom: 1.3rem; }
.page-hero p { color: var(--text-inverse-soft); max-width: 56ch; font-size: 1.05rem; }

/* About (Pattern B): the navy title band + full section padding stacked into a
   mid-fold gap that cut the opening paragraph. Tighten the band's base and the
   first section's top so all of the opening copy sits above the fold. */
body[data-page="about"] .page-hero-inner { padding-bottom: clamp(2rem, 4vh, 3rem); }
/* The navy band + opening copy together fill the above-fold area; the copy is
   vertically centered in the white space beneath the band (self-adjusts to any
   viewport height, so the copy never bottoms out on the fold). */
body[data-page="about"] .about-fold { min-height: calc(100vh - var(--header-h)); display: flex; flex-direction: column; }
body[data-page="about"] .about-fold > .section--white {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: clamp(1rem, 3vh, 2.5rem);
}

/* Contact: same mid-fold gap pushed the photo + intake form partly under the
   fold. Tighten the band base and the form section top so the (now-landscape)
   photo sits fully visible and the form begins cleanly above the fold. */
body[data-page="contact"] .page-hero-inner { padding-bottom: clamp(2rem, 4vh, 3rem); }
body[data-page="contact"] main > section:nth-of-type(2) { padding-top: clamp(2rem, 4vw, 3rem); }

/* Testimonials: shift the whole featured group up so the first testimonial
   (Myers) sits cleanly above the fold on its own and the second falls below.
   Only the band base + group top are trimmed; the stack-lg spacing BETWEEN
   testimonials is left exactly as-is. */
body[data-page="testimonials"] .page-hero-inner { padding-bottom: clamp(2rem, 4vh, 3rem); }
body[data-page="testimonials"] main > section:nth-of-type(2) { padding-top: clamp(2rem, 4vw, 3rem); }

/* Inside the Dome: compact the excess white below The Space gallery so the
   cream "The Work" section follows without a large empty gap. */
body[data-page="inside-the-dome"] main > section:nth-of-type(3) { padding-bottom: clamp(2.5rem, 5vw, 4rem); }

/* ============================================================
   MOTION — scroll reveals (exhale-paced) + reduced motion
   ============================================================ */
/* The reveal is opt-IN, and the .reveal-ready gate is the whole reason why. Nothing
   below hides a block until main.js has added that class to <html>, which it does in
   the same breath as arming the observer that takes it off again. Written the other
   way round, with opacity 0 as the stylesheet's plain default, the fade stopped being
   decoration and became the thing that decided whether the page had content on it: a
   blocked script, a throw anywhere earlier in main.js, an engine with no
   IntersectionObserver, or an observer that simply never fired all left the blocks
   holding their full height and painting nothing. That is what Maura saw on her own
   phone, a long blank white band where the 21 fabric swatches for a $175 swing should
   have been. Put this back the old way and the page can go blank again on any device
   whose browser does not do exactly what we expected. Inverted 2026-09-02, pre-launch. */
html.reveal-ready [data-reveal] {
  opacity: 0;
  transform: translateY(12px); /* premium floor: 8-12px travel (was 30px, 2.5x over spec) */
  transition: opacity var(--dur-reveal) var(--ease-soft), transform calc(var(--dur-reveal) + 0.15s) var(--ease-soft);
  will-change: opacity, transform;
}
html.reveal-ready [data-reveal].in-view { opacity: 1; transform: translateY(0); }
html.reveal-ready [data-reveal="2"] { transition-delay: 0.14s; }
html.reveal-ready [data-reveal="3"] { transition-delay: 0.28s; }
html.reveal-ready [data-reveal="4"] { transition-delay: 0.42s; }

/* No-JS and reduced-motion: everything visible, everything still.
   The no-js line is now belt and braces rather than the only guard, since .reveal-ready
   is never added when scripting is off. It stays because it costs nothing and states
   the intent where a reader looks for it. */
html.no-js [data-reveal] { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* Both selectors, because .reveal-ready outranks a bare [data-reveal] and a visitor
     can turn reduced motion on after the page has already armed itself. */
  [data-reveal],
  html.reveal-ready [data-reveal] { opacity: 1; transform: none; transition: none; }
  .kenburns { animation: none; }
  .ast-sting.ast-animate .ast-sting__logo {
    animation: none;
    opacity: 1;
    transform: none;
    -webkit-mask-image: none;
            mask-image: none;
  }
  .band-media img { transform: none !important; }
  .offer-card img, .gallery img { transition: none; }
  .btn:hover { transform: none; }
}

/* ---------- Utilities ---------- */
.center { text-align: center; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.stack-lg > * + * { margin-top: clamp(2.5rem, 5vw, 4rem); }
.visually-hidden:focus,
.visually-hidden:focus-visible {
  position: fixed;
  top: 1rem;
  left: 1rem;
  width: auto;
  height: auto;
  padding: 0.75rem 1.25rem;
  margin: 0;
  clip: auto;
  clip-path: none;
  overflow: visible;
  white-space: normal;
  background: var(--navy);
  color: var(--ivory-tint);
  border: 2px solid var(--gold);
  border-radius: 2px;
  z-index: 9999;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}


/* Hero subline + first-screen proof (added 2026-07-29: Law 4 five-question gate
   was scoring 2/5, and the strongest credential on the site sat five screens down) */
/* Hero supporting copy. Everything here is LEFT-aligned to match .hero-title.
   A previous version used `margin: ... auto`, which centred the subline and the
   proof line while the headline and buttons stayed left, so the hero alternated
   left / centre / left / centre down the screen. That is what read as disjointed.
   Rhythm below is deliberate: the gaps grow as you descend, so the eye moves
   headline -> promise -> action -> quiet credential without anything crowding. */
.hero-sub {
  max-width: 46ch;
  margin: 0 0 2.6rem;
  font-size: clamp(1.08rem, 1.5vw, 1.28rem);
  line-height: 1.62;
  font-weight: 340;
  color: var(--ivory-tint, #f5f3e6);
  opacity: 0.92;
}
.hero-actions { margin: 0; gap: 1.6rem; }
.hero-alt {
  font-size: 0.9rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ivory-tint, #f5f3e6);
  opacity: 0.86;
  border-bottom: 1px solid rgba(245, 243, 230, 0.4);
  padding-bottom: 2px;
  transition: opacity 0.3s var(--ease-soft), border-color 0.3s var(--ease-soft);
}
/* The link measured 28px tall, under the 44px thumb minimum. It could not simply be
   padded, because the border-bottom IS the underline and vertical padding would drag
   the rule away from the words. So the underline moves to ::after, pinned back up to
   the text, and the padding raises the real tap height to 46px. An invisible overlay
   was tried first and rejected: it fools a thumb but leaves the element itself 28px,
   so every future check keeps reporting it and nobody can tell the fixed case from the
   broken one. Make the target real. Found by the 390px mobile check, 2026-09-02. */
.hero-alt { display: inline-block; position: relative; padding: 11px 0; border-bottom: 0; }
.hero-alt::after { content: ""; position: absolute; left: 0; right: 0; bottom: 9px;
  border-bottom: 1px solid rgba(245, 243, 230, 0.4); transition: border-color 0.3s var(--ease-soft); }
.hero-alt:hover { opacity: 1; }
.hero-alt:hover::after { border-bottom-color: var(--gold-bright); }
.hero-proof {
  margin: 3.4rem 0 0;
  padding-top: 1.7rem;
  max-width: 44ch;
  border-top: 1px solid rgba(245, 243, 230, 0.22);
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--ivory-tint, #f5f3e6);
  opacity: 0.74;
}
.hero-proof span { display: block; font-style: italic; margin-bottom: 0.3rem; opacity: 0.95; }
.hero-proof em { font-style: italic; }
@media (max-width: 640px) {
  .hero-sub { font-size: 1.04rem; margin-bottom: 2.1rem; max-width: 30ch; }
  .hero-actions { gap: 1.2rem; }
  .hero-proof { font-size: 0.85rem; margin-top: 2.6rem; padding-top: 1.3rem; }
}


/* SHORT-VIEWPORT HERO RHYTHM (added 2026-07-29)
   Measured failure: at 390x664, an iPhone with Safari's URL bar visible, the
   credential line sat 33px BELOW the fold and was cut off; at 1440x760 it had
   only 48px clearance and read as sitting on the fold. The block is now
   compressed on short screens so every line clears with a real setback. */
@media (max-height: 800px) {
  .hero-inner { padding-top: clamp(1.5rem, 3vh, 2.5rem); padding-bottom: clamp(4.5rem, 11vh, 6.5rem); }
  .hero-title { margin-bottom: 1.2rem; }
  .hero-sub { margin-bottom: 1.6rem; font-size: 1.02rem; }
  .hero-proof { margin-top: 1.8rem; padding-top: 1.1rem; font-size: 0.84rem; }
  .hero-eyebrow { margin-bottom: 0.9rem; }
}
@media (max-height: 700px) {
  .hero-inner { padding-top: 1rem; padding-bottom: clamp(4.5rem, 11vh, 5.5rem); }
  .hero-title { margin-bottom: 0.85rem; font-size: clamp(2.4rem, 8vw, 3.2rem); }
  .hero-sub { margin-bottom: 1.15rem; font-size: 0.98rem; }
  .hero-actions { gap: 1rem; }
  .hero-proof { margin-top: 1.3rem; padding-top: 0.85rem; font-size: 0.8rem; }
  .hero-eyebrow { margin-bottom: 0.7rem; font-size: 0.68rem; }
}

/* Very short screens (small phones, or any phone with the URL bar showing): drop
   the quotation and keep the credential. "Thomas Myers, author of Anatomy Trains"
   is the part that carries the weight; the quote is the part that costs a line. */
/* Very short screens (small phones, or any phone with the URL bar showing).
   PREVIOUSLY this hid .hero-proof span to buy ~30px of fold clearance. That span
   IS the Myers quotation, so on every phone the page showed his name with no
   quote attached, which is a credential with nothing behind it. Maura reported it
   herself on 2026-08-04 as edit item 1, "Near top with his name, currently missing
   quote." She was reading on a phone. The clearance was bought with the single most
   valuable piece of proof on the page.
   Now: keep BOTH the quote and the credential, and buy the space back from type
   size and rhythm instead. Never hide proof to win layout. 2026-08-19. */
@media (max-height: 680px) {
  .hero-proof { margin-top: 1.15rem; padding-top: 0.8rem; font-size: 0.78rem; line-height: 1.4; }
  .hero-proof span { display: block; margin-bottom: 0.15rem; }
  .hero-sub { margin-bottom: 1.5rem; }
  .hero-title { margin-bottom: 1.15rem; }
  .hero-eyebrow { margin-bottom: 0.8rem; }
}

/* NOTE: pinning .hero to 100svh on short screens was tried 2026-07-29 and REVERTED.
   With overflow:hidden it clipped the block and pushed the credential 35px BELOW
   the fold, worse than the problem. The clamped padding approach above is correct. */

/* .as-h2 — renders identically to an h2 but is a <p>. Added 2026-08-29.
   Used where a QUOTE or an ANNOUNCEMENT was wrapped in <h2>, which made a
   machine read it as a section title and garbled the page's outline.
   Mirrors the h1,h2,h3,h4 rule (line ~67) plus h2's size and the navy override. */
.as-h2 { font-family: var(--font-display); font-weight: 380; line-height: 1.12;
         margin: 0 0 1.1rem; color: var(--navy); letter-spacing: -0.012em;
         font-size: var(--fs-h2); }
.section--navy .as-h2 { color: var(--ivory-tint); }

/* Added 2026-08-29. balance-lines: evens the line lengths of a short paragraph so a
   single word cannot be left orphaned on the last line. text-wrap: pretty is the wider
   fallback; balance is the stronger effect and is right for blocks under ~4 lines.
   answer-first: the one-line answer that sits directly under a question heading. */
.balance-lines { text-wrap: pretty; text-wrap: balance; }
.answer-first { text-wrap: pretty; }

/* ==========================================================================
   ADDED 2026-08-30. The four narrow changes recommended instead of
   stripping gold from the other 37 places it appears. These rules are appended
   so it is trivially reversible: delete from here to the end of the file and
   the stylesheet is byte-identical to the deployed one.
   ========================================================================== */

/* 1. The logo stops pulsing. It keeps its entrance (reveal, rise, fade) and
      then settles. Previously it floated and glowed on an infinite loop, which
      made it the only moving thing on the page and the one element genuinely
      out-competing the Book a Session button for a visitor's first look. */
.ast-sting.ast-animate .ast-sting__logo {
  animation:
    ast-reveal 1500ms cubic-bezier(0.22, 0.61, 0.36, 1) forwards,
    ast-rise 900ms cubic-bezier(0.22, 0.61, 0.36, 1) forwards,
    ast-fade 900ms ease-in-out forwards;
}

/* 2. The top-right button now asks for the SAME thing the hero button asks for.
      Our own rule: you can have ten buttons as long as every one pushes the same
      single decision. The defect was never a button in that corner, it was a
      button asking for something different. It keeps its gold OUTLINE, which
      stays visually subordinate to the filled gold of the hero button, so filled
      gold still means exactly one thing on the page. No CSS change is needed for
      it, only the label and the link, which are in the markup.

      RELABELLED AND REPOINTED 2026-09-08. Both buttons used to read "Book a
      Session" and point at the offerings. Nothing on this site books anything:
      every offering is sold by inquiry, in her own words on the contact page,
      and the only inquiry form for sessions is at /contact/. So the pair now
      reads "Begin an Inquiry" and points at /contact/, which is one click to the
      form from any page instead of three, and which promises only what the site
      can actually deliver. The rule above is unchanged and still holds: the two
      buttons still ask for one identical thing. The three doors are still one
      click away in the same bar, under the Offerings menu, and still sit
      immediately below the hero on the home page. */

/* 3. The newsletter Sign Up stops wearing the same filled gold as the booking
      button, so filled gold means exactly one thing on the page. It sits on
      navy, and ivory on navy measures 13.26:1, so this is more readable, not
      less. (The class is swapped in the three pages' markup.) */
.btn-quiet {
  background: transparent;
  border-color: rgba(245, 243, 230, 0.45);
  color: var(--ivory-tint);
}
.btn-quiet:hover {
  background: rgba(245, 243, 230, 0.12);
  border-color: var(--ivory-tint);
  color: var(--white);
}

/* 4. Four places where gold lettering sat on a light background at roughly
      2.5 to 1, where the readable minimum is 4.5 to 1. Each is replaced with a
      navy already in her palette, and gold is kept wherever it sits on navy and
      passes comfortably. */
/* CORRECTED 2026-08-30, second pass. The first attempt swapped gold for navy-deep,
   which is almost the same colour the text already was, so every hover silently
   became invisible. Jose caught it on the live preview: "I'm hovering over the
   offering names and nothing happens." An UNDERLINE is the right affordance here:
   it is a decoration rather than text, so the 4.5:1 contrast floor does not apply
   to it, and it can therefore be strongly visible without being unreadable. The
   text itself darkens slightly; the underline does the actual signalling. */
a:hover { color: var(--navy-deep); text-decoration-color: var(--navy-deep); }
.section--navy a:hover,
.band a:hover { color: var(--gold-bright); text-decoration-color: var(--gold-bright); }

.text-link:hover { color: var(--navy-deep); border-bottom-color: var(--navy-deep); }
.section--navy .text-link:hover { color: var(--gold-bright); border-bottom-color: var(--gold-bright); }

.offer-card h3 { display: inline-block; border-bottom: 1px solid transparent; padding-bottom: 2px;
                 transition: color 0.45s var(--ease-soft), border-bottom-color 0.45s var(--ease-soft); }
.offer-card:hover h3 { color: var(--navy-deep); border-bottom-color: var(--gold); }

.faculty-role { color: var(--navy); }
.section--navy .faculty-role { color: var(--gold-bright); }


/* ==========================================================================
   ADDED 2026-08-30, second pass.
   ========================================================================== */

/* The menu bar now uses the same face and treatment as the round-two arm 3
   page: Hanken Grotesk, uppercase, wide tracking. Self-hosted rather than
   pulled from Google, so it costs no third-party request. Size is the old
   0.8rem raised 15 percent. Uppercase needs more air between letters than
   sentence case does, so the tracking matches arm 3's 0.14em rather than the
   0.08em the lowercase version used. */
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/assets/fonts/hanken-grotesk-var.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}
/* SCOPED TO THE DESKTOP BAR ONLY. Below 1200px the menu is a full-screen overlay
   whose links are large display type, set by a rule in @media (max-width: 1199px).
   An unscoped rule here sits later in the file and silently overrode that, shrinking
   the phone menu to tiny uppercase. Caught 2026-08-30 by listing every .nav a rule
   in file order instead of trusting a single grep for the last one. */
@media (min-width: 1200px) {
  .nav a {
    font-family: "Hanken Grotesk", var(--font-body);
    font-size: 0.874rem; /* 0.92rem less 5%, per Amanda 2026-08-30 */
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
  }
  /* the Book a Session button keeps its own scale so it does not swell with the links */
  .nav .nav-cta { font-size: 0.82rem; }
}

/* The footer brand block now sizes itself to the line beneath it, so the left
   edge of the logo and the right edge of "Therapy" line up with the two ends of
   "The Aum Dome, Encinitas, California". Doing it this way rather than guessing a
   pixel width means the two stay aligned if the line or the type size ever
   changes. The block shrinks to its widest child, the line is held on one line,
   and the logo fills whatever width that turns out to be. */
.footer-brand { display: inline-block; max-width: 100%; }
.footer-brand p { white-space: nowrap; }
.footer-brand img { width: 100%; margin-bottom: 1.4rem; }

/* on a very narrow phone, let the line wrap again rather than overflow */
@media (max-width: 400px) {
  .footer-brand p { white-space: normal; }
  .footer-brand { display: block; }
  .footer-brand img { width: 200px; }
}


/* The "Come Inside" band: keep the transparency, make the words readable.
   Measured, not guessed: the photograph behind that text averages rgb(154,141,127)
   but contains patches of pure white, and the scrim sat at only 30 percent right
   where the sentence is. White type on a white highlight is 1:1, invisible. A flat
   scrim strong enough to fix the worst patch would need about 65 percent, which
   would destroy the openness that makes the band work.

   So the shade is pooled behind the words instead of spread over everything. A soft
   ellipse centred on the text stacks with the existing gradient to about 66 percent
   at dead centre and falls away to the current 30 percent at the edges, so the photo
   keeps breathing everywhere the type is not. The sentence also stops being set at
   72 percent opacity, which was fading it before the photograph even mattered. */
.band-scrim {
  background:
    radial-gradient(ellipse 62% 58% at 50% 50%,
      rgba(24, 40, 66, 0.52) 0%,
      rgba(24, 40, 66, 0.30) 52%,
      rgba(24, 40, 66, 0) 100%),
    linear-gradient(to top,
      rgba(24, 40, 66, 0.78) 0%,
      rgba(24, 40, 66, 0.30) 55%,
      rgba(24, 40, 66, 0.42) 100%);
}
.band-inner h2,
.band-inner p { color: var(--ivory-tint); text-shadow: 0 1px 14px rgba(24, 40, 66, 0.55); }
.band-inner .btn-ghost { text-shadow: none; }


/* Chosen line breaks, used where a sentence reads better broken at meaning rather
   than wherever the box happens to run out of room. They switch off below 700px,
   because a forced break on a narrow phone creates worse ragging than it fixes. */
.br-wide { display: none; }
@media (min-width: 700px) { .br-wide { display: inline; } }


/* The Metamorphosis arc: one line weaving through the three stages so they read as a
   sequence rather than three separate labels. The shape is a sideways S, dipping under
   between the first two and rising over between the last two, with a dot at each stage.
   The viewBox scales uniformly, so the three dots always land on the three column
   centres whatever the screen width. */
/* The Metamorphosis weave. The drawing sits OVER the three titles rather than under
   them, so the plane of the curve is the line of the words themselves: arc one passes
   below that line, arc two passes above it.

   The geometry, because the obvious version is wrong. The stages sit in a 3-column grid
   WITH a gap, so each column is (100% - 2*gap)/3 wide and the outer column centres are
   half a column in from each edge, not at 1/6 and 5/6. A drawing that assumes no gap
   lands its outer dots about 26px inside their titles. Insetting by exactly half a
   column puts the two ends on the outer centres at any width. The gap is repeated here
   on purpose so the two rules cannot drift apart unnoticed. */
.arc-wrap {
  --arc-gap: clamp(2rem, 6vw, 5rem);   /* must match .arc-stages gap */
  --arc-h: clamp(34px, 4.2vw, 58px);   /* how deep each arc bows */
  --arc-v: clamp(8px, 1vw, 14px);      /* the gap from the words, same above and below */
  position: relative;
  margin-block: calc(var(--arc-h) + var(--arc-v));
}
.arc-stages { --arc-gap: clamp(2rem, 6vw, 5rem); position: relative; z-index: 2; }

/* Each arc spans exactly one gap, from one title centre to the next. The columns have
   a gap between them, so the outer title centres sit half a column in from each edge,
   not at 1/6 and 5/6. Insetting by half a column is what makes the ends land on the
   titles at any screen width. */
.arc-weave {
  position: absolute;
  height: var(--arc-h);
  z-index: 1;
  pointer-events: none;
}
.arc-weave--below {
  top: calc(100% + var(--arc-v));
  left: calc((100% - 2 * var(--arc-gap)) / 6);
  right: 50%;
}
.arc-weave--above {
  bottom: calc(100% + var(--arc-v));
  left: 50%;
  right: calc((100% - 2 * var(--arc-gap)) / 6);
}
.arc-path { display: block; width: 100%; height: 100%; overflow: visible; }
.arc-curve {
  fill: none;
  stroke: var(--gold);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 400;
  stroke-dashoffset: 400;
  transition: stroke-dashoffset 1.4s var(--ease-soft);
}
.arc-dot {
  position: absolute;
  z-index: 2;
  width: 9px;
  height: 9px;
  margin-left: -4.5px;
  border-radius: 50%;
  background: var(--gold);
  opacity: 0;
  transition: opacity 0.55s var(--ease-soft) 0.5s;
}
/* each arc's dots sit on the edge nearest the words */
.arc-weave--below .arc-dot { top: -4.5px; }
.arc-weave--above .arc-dot { bottom: -4.5px; }

.arc-weave.in-view .arc-curve { stroke-dashoffset: 0; }
.arc-weave.in-view .arc-dot { opacity: 1; }

/* the three stack into one column here, so a horizontal weave makes no sense */
@media (max-width: 640px) { .arc-weave { display: none; } }

@media (prefers-reduced-motion: reduce) {
  .arc-curve { stroke-dashoffset: 0; transition: none; }
  .arc-dot { opacity: 1; transition: none; }
}


/* A title for the drawing, pointing at it rather than sitting off to one side. Her own
   sentence calls Metamorphosis "a ceremonial arc", so the words are hers. Centred and
   given real air above and below, because the paragraph before it and the sliding-scale
   line after it were both crowding the visual. */
.arc-title {
  /* A title for the drawing below it, pointing at the visual rather than sitting off to
     one side. The words are hers: her own copy calls Metamorphosis "a ceremonial arc".

     Deliberately NO font overrides. It inherits the page's standard h2 treatment,
     Fraunces at weight 380 and the normal heading size, so it matches every other
     heading on the site. An earlier version set weight 600, which pushes Fraunces into
     a heavy register that reads as generic bold rather than as the display face. Bigger
     and lighter is what makes it look like a heading here, not bolder. A later version
     tried Inter, which was reverted.

     Generous space below it, because the paragraph above and the sliding-scale line
     below were both crowding the drawing. */
  text-align: center;
  margin: clamp(3rem, 6vw, 4.75rem) 0 clamp(4.75rem, 9.5vw, 7.5rem);
}
.arc-wrap { margin-bottom: calc(var(--arc-h) + var(--arc-v) + clamp(2rem, 4vw, 3.25rem)); }

/* Amanda asked for the new section labels to read heavier. Same small-caps treatment,
   more weight and a touch more size, so they register as headings rather than as
   captions floating above the copy. */
h2.eyebrow, h3.eyebrow {
  font-weight: 700;
  font-size: 0.82rem;
  color: var(--navy);
  opacity: 1;
}
.section--navy h2.eyebrow, .section--navy h3.eyebrow,
.band h2.eyebrow, .band h3.eyebrow { color: var(--gold-bright); }

/* Form status line. Replaces the old mailto behaviour's silent failure: the visitor
   now gets told, in words, whether their inquiry actually reached Maura. */
.form-status {
  margin: 1.1rem 0 0;
  font-family: var(--font-body);
  font-size: 0.92rem;
  line-height: 1.55;
  padding: 0.85rem 1.1rem;
  border-left: 2px solid var(--gold);
  background: rgba(24, 40, 66, 0.035);
}
.form-status[data-state="error"] {
  border-left-color: #b4472f;
  background: rgba(180, 71, 47, 0.06);
}

/* Newsletter opt-in on the contact and order forms. Deliberately quiet: it is an
   invitation beside the real action, never competing with the submit button. */
/* min-height 44px so the whole consent row is a legitimate thumb target, not just a
   20px box with text beside it. */
.form-optin {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  min-height: 44px;
  padding: 0.35rem 0;
  margin: 0.4rem 0 1.4rem;
  font-family: var(--font-body);
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--text-soft);
  cursor: pointer;
}
/* 20px, not the 13px browser default. The whole row is a <label>, so the tap target is
   already the full width of the text, but a thumb aimed at the box itself should find
   the box. Measured at 390px on 2026-09-02. */
.form-optin input { margin-top: 0.1rem; flex: 0 0 auto; accent-color: var(--gold); width: 20px; height: 20px; }

/* About fold, 2026-09-02: her portrait and her opening statement now share the first
   screen, so the image is capped against VIEWPORT HEIGHT rather than column width and
   keeps its aspect ratio. The cap is applied to .split-media, not to the <img>, because
   .split-media--frame draws its gold hairline off the container: shrinking the image
   alone would leave the frame floating away from the photograph it is framing.
   The photo is 1066x1600 (0.666), so a 34vh width yields roughly a 51vh height. */
body[data-page="about"] .about-hero-split { align-items: center; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); }
/* The statement is two sentences. At the default split width it wrapped to three lines
   and orphaned the single word "remembering." on the last one. The column is widened so
   the first sentence completes on line one and the break falls between the sentences,
   where the meaning breaks; text-wrap: pretty is the belt-and-braces against an orphan
   at any width in between. */
body[data-page="about"] .about-hero-split .lead { text-wrap: pretty; }
body[data-page="about"] .about-hero-split .split-media { max-width: min(34vh, 360px); margin-inline: auto; }
@media (max-width: 860px) {
  body[data-page="about"] .about-hero-split .split-media { max-width: min(46vh, 320px); }
}
