/* ==========================================================================
   FindUrHealth — shared stylesheet for index / about / services
   Tokens are the locked brand set (same names as find_web/ so the two folders
   stay swappable). No Tailwind here: the utility set this site needs is small
   enough to own, which also sidesteps the CDN's unlayered-base specificity
   trap that bit find_web.
   ========================================================================== */

:root {
  /* Brand core */
  --forest:        #1c3a17;
  --forest-deep:   #0d1f0b;
  --forest-mid:    #24491d;
  --rose:          #a13a52;
  --rose-bright:   #c04a66;
  --rose-soft:     #e8c3ce;
  --lime:          #7fb82d;
  --cream:         #fbfaf4;
  --paper:         #fffdf9;
  --sand:          #f1efe3;
  --muted:         #5c6650;

  /* Semantic */
  --bg:        var(--cream);
  --fg:        var(--forest);
  --line:      rgba(28, 58, 23, 0.14);
  --line-soft: rgba(28, 58, 23, 0.07);
  /* Cream at 78% over forest-deep computes to ~9:1 — safe for body copy on
     the dark bands. Anything lighter than this must be large text only. */
  --on-dark-body: rgba(251, 250, 244, 0.78);

  /* Type */
  --display: "Fraunces", ui-serif, Georgia, serif;
  --sans:    "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Motion */
  --ease-out:    cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);

  /* Layout */
  --gutter: clamp(1.25rem, 5vw, 6rem);
  --maxw:   1340px;
  --nav-h:  84px;
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;       /* fallback when Lenis is absent */
  scroll-padding-top: calc(var(--nav-h) + 16px);
}

body {
  margin: 0;
  /* Warm blush-into-cream page wash. Fixed so it stays put while scrolling. */
  background:
    radial-gradient(88% 55% at 84% 4%,  #f7e6ea 0%, transparent 58%),
    radial-gradient(70% 48% at 4% 16%,  #eef1e1 0%, transparent 60%),
    radial-gradient(80% 50% at 50% 100%, #f6ece6 0%, transparent 62%),
    var(--cream);
  background-attachment: fixed;
  color: var(--fg);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

/* Any author `display` rule beats the UA stylesheet's [hidden]{display:none},
   and .field / .book__grid both set display:grid — so el.hidden alone left
   them on screen. Keep this above the components that set display. */
[hidden] { display: none !important; }

img, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4, p, figure, blockquote, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
button { font: inherit; color: inherit; }

::selection { background: var(--rose); color: #fff; }

:focus-visible {
  outline: 3px solid var(--rose);
  outline-offset: 3px;
  border-radius: 5px;
}
.on-dark :focus-visible, .footer :focus-visible, .drawer :focus-visible {
  outline-color: var(--rose-soft);
}

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

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 500;
  background: var(--forest); color: #fff; padding: 1rem 1.5rem; font-weight: 700;
}
.skip-link:focus { left: 1rem; top: 1rem; }

/* --------------------------------------------------------------------------
   Utilities (the small hand-rolled set this site actually uses)
   -------------------------------------------------------------------------- */

.shell { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.narrow { max-width: 78ch; }

/* Sections clip their botanicals so decoration can hang off the edge without
   creating page-wide horizontal scroll. */
.section { padding-block: clamp(4.5rem, 11vh, 9rem); position: relative; overflow: hidden; }
.section--tight { padding-block: clamp(3rem, 7vh, 5.5rem); }

.bg-cream { background: var(--cream); }
.bg-paper { background: var(--paper); }
.bg-sand  { background: var(--sand); }

/* Any block with light text owns an opaque dark background of its own —
   never inherits one from a shared layer. */
.on-dark {
  background:
    radial-gradient(80% 60% at 82% 0%, #24491d 0%, transparent 58%),
    radial-gradient(60% 55% at 4% 96%, #2b3a1c 0%, transparent 62%),
    var(--forest-deep);
  color: var(--cream);
}
.on-dark .lede, .on-dark .body { color: var(--on-dark-body); }
.on-dark .eyebrow { color: var(--rose-soft); }
.on-dark .rule { background: rgba(251, 250, 244, 0.16); }

.stack   { display: grid; }
.flex    { display: flex; }
.wrap    { flex-wrap: wrap; }
.center  { align-items: center; }
.between { justify-content: space-between; }
.jc      { justify-content: center; }
.tc      { text-align: center; }
.relative { position: relative; }

.g-1 { gap: .5rem; }  .g-2 { gap: .85rem; } .g-3 { gap: 1.25rem; }
.g-4 { gap: 1.75rem; } .g-5 { gap: 2.5rem; } .g-6 { gap: clamp(2rem, 5vw, 4rem); }

.mb-1 { margin-bottom: .5rem; }  .mb-2 { margin-bottom: .85rem; }
.mb-3 { margin-bottom: 1.25rem; } .mb-4 { margin-bottom: 1.75rem; }
.mb-5 { margin-bottom: 2.5rem; }  .mb-6 { margin-bottom: 3.5rem; }
.mt-4 { margin-top: 1.75rem; }    .mt-6 { margin-top: 3.5rem; }

.cols-2, .cols-3, .cols-4 { display: grid; gap: clamp(1.25rem, 2.5vw, 2rem); }
@media (min-width: 680px)  { .cols-2 { grid-template-columns: repeat(2, 1fr); }
                             .cols-4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px)  { .cols-3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1080px) { .cols-4 { grid-template-columns: repeat(4, 1fr); } }

.split { display: grid; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
@media (min-width: 900px) {
  .split            { grid-template-columns: 1fr 1fr; }
  .split--media-sm  { grid-template-columns: 0.85fr 1.15fr; }
  .split--media-lg  { grid-template-columns: 1.15fr 0.85fr; }
}

.rule { height: 1px; background: var(--line); border: 0; }

/* --------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */

.display-xl, .display-lg, .display-md, .display-sm { font-family: var(--display); font-weight: 600; }

.display-xl {
  /* line-height must clear Fraunces' cap-height + descender overshoot at this
     optical size — anything under ~1.08 gets its ascenders/descenders sliced
     by .reveal-line's overflow:hidden mask. */
  font-size: clamp(2.6rem, 6.6vw, 6.2rem); line-height: 1.2; letter-spacing: -.035em;
  font-variation-settings: "SOFT" 30, "WONK" 1, "opsz" 120;
}
.display-lg {
  font-size: clamp(2.1rem, 5vw, 4.2rem); line-height: 1.04; letter-spacing: -.028em;
  font-variation-settings: "SOFT" 24, "WONK" 1, "opsz" 100;
}
.display-md {
  font-size: clamp(1.6rem, 3vw, 2.6rem); line-height: 1.12; letter-spacing: -.02em;
  font-variation-settings: "SOFT" 20, "opsz" 60;
}
.display-sm {
  font-size: clamp(1.2rem, 1.9vw, 1.5rem); line-height: 1.24; letter-spacing: -.012em;
  font-variation-settings: "SOFT" 16, "opsz" 36;
}

.eyebrow {
  font-size: .72rem; font-weight: 800; letter-spacing: .26em;
  text-transform: uppercase; color: var(--rose);
}

.lede { font-size: clamp(1.03rem, 1.35vw, 1.24rem); line-height: 1.65; color: var(--muted); }
.body { color: var(--muted); }
.small { font-size: .94rem; }
.ink { color: var(--forest); }
.accent { color: var(--rose); }

/* --------------------------------------------------------------------------
   Botanicals — shared mask system (extended from find_web)
   -------------------------------------------------------------------------- */

.floral { position: absolute; pointer-events: none; user-select: none; z-index: 0; }

.floral-mask {
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: contain;     mask-size: contain;
  -webkit-mask-position: center;  mask-position: center;
}
.mask-sprig  { -webkit-mask-image: url("../assets/floral/sprig.svg");  mask-image: url("../assets/floral/sprig.svg");  aspect-ratio: 160/320; }
.mask-bloom  { -webkit-mask-image: url("../assets/floral/bloom.svg");  mask-image: url("../assets/floral/bloom.svg");  aspect-ratio: 1/1; }
.mask-branch { -webkit-mask-image: url("../assets/floral/branch.svg"); mask-image: url("../assets/floral/branch.svg"); aspect-ratio: 420/220; }
.mask-wreath { -webkit-mask-image: url("../assets/floral/wreath.svg"); mask-image: url("../assets/floral/wreath.svg"); aspect-ratio: 1/1; }
.mask-petal  { -webkit-mask-image: url("../assets/floral/petal.svg");  mask-image: url("../assets/floral/petal.svg");  aspect-ratio: 60/90; }

.fl-tr { top: -4%;   right: -5%; width: clamp(140px, 19vw, 290px); }
.fl-tl { top: -3%;   left: -6%;  width: clamp(140px, 19vw, 290px); }
.fl-br { bottom: -8%; right: -7%; width: clamp(150px, 21vw, 310px); }
.fl-bl { bottom: -8%; left: -7%;  width: clamp(150px, 21vw, 310px); }

/* The sprig is a 1:2 portrait shape, so the shared corner widths would make it
   620px tall and it climbs into the headline. Cap it separately. */
.fl-tl.mask-sprig, .fl-tr.mask-sprig,
.fl-bl.mask-sprig, .fl-br.mask-sprig { width: clamp(100px, 12vw, 190px); }

.fl-sage { color: var(--lime);      opacity: .26; }
.fl-rose { color: var(--rose);      opacity: .20; }
.fl-pale { color: var(--rose-soft); opacity: .30; }
.fl-flip { transform: scaleX(-1); }

/* Content inside a section that carries botanicals must sit above them. */
.section > .shell { position: relative; z-index: 1; }

/* --------------------------------------------------------------------------
   Navigation
   -------------------------------------------------------------------------- */

.nav {
  position: fixed; inset: 0 0 auto; z-index: 100;
  border-bottom: 1px solid transparent;
  transition: background 420ms var(--ease-out), backdrop-filter 420ms, border-color 420ms;
}
.nav.is-stuck {
  background: rgba(251, 250, 244, .9);
  backdrop-filter: blur(16px) saturate(1.4);
  border-bottom-color: var(--line-soft);
}
.nav__inner { display: flex; align-items: center; justify-content: space-between; gap: 1.25rem; min-height: var(--nav-h); }
/* the anchor, not the image, carries the 44px touch target */
.nav__brand { display: inline-flex; align-items: center; gap: .6rem; min-height: 44px; }
.nav__logo { height: 52px; width: auto; }
/* The badge's own arched lettering is illegible under ~90px, so the brand
   name sits beside it as real text — selectable, translatable, and crisp. */
.nav__wordmark {
  font-family: var(--display); font-weight: 600;
  font-size: 1.35rem; letter-spacing: -.02em; line-height: 1;
  color: var(--forest); white-space: nowrap;
  font-variation-settings: "SOFT" 20, "opsz" 40;
}
@media (max-width: 420px) { .nav__wordmark { font-size: 1.12rem; } }

.nav__links { display: none; gap: 2rem; font-size: .92rem; font-weight: 600; }
.nav__link { position: relative; padding-block: .5rem; color: var(--forest); }
.nav__link::after {
  content: ""; position: absolute; left: 0; bottom: .1rem; height: 1.5px; width: 0;
  background: var(--rose); transition: width 320ms var(--ease-out);
}
.nav__link:hover::after, .nav__link:focus-visible::after { width: 100%; }
.nav__link[aria-current="page"] { color: var(--rose); }
.nav__link[aria-current="page"]::after { width: 100%; }

/* Two-class selectors on purpose: `.btn { display: inline-flex }` is declared
   further down the file, so a bare `.nav__cta { display: none }` loses the
   later-wins tie and the pill never hid on phones. */
.nav .nav__cta { display: none; }
@media (min-width: 620px) { .nav .nav__cta { display: inline-flex; } }
@media (min-width: 1000px) { .nav__links { display: flex; } .drawer { display: none; } }

.nav__burger {
  width: 48px; height: 48px; display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 999px;
  background: rgba(255, 255, 255, .6); color: var(--forest); cursor: pointer;
  list-style: none;                       /* kills the <summary> triangle */
}
.nav__burger::-webkit-details-marker { display: none; }
.nav__burger:hover { background: #fff; }

/* Mobile drawer.
   Built on <details>/<summary> so it opens and closes with zero JavaScript —
   the script only adds the niceties (body scroll lock, Escape, close on
   navigate). Dark surface, so it uses the white logo. */
.drawer { position: relative; }
.drawer .ic-close { display: none; }
.drawer[open] .ic-open  { display: none; }
.drawer[open] .ic-close { display: block; }

/* `top/left/right` + an explicit height rather than `inset: … 0 0`.
   .nav.is-stuck applies backdrop-filter, which makes the nav a containing
   block for its fixed descendants — with `bottom: 0` the open drawer collapsed
   to the height of the nav (a 72px sliver) as soon as the page was scrolled.
   The nav is pinned to the top edge at full width, so top/left/right resolve
   identically either way; only the height needed pinning down. */
.drawer__panel {
  position: fixed; top: var(--nav-h); left: 0; right: 0;
  height: calc(100svh - var(--nav-h)); z-index: 140;
  background: var(--forest-deep); color: var(--cream);
  display: flex; flex-direction: column;
  padding: 1.5rem var(--gutter) 3rem; overflow-y: auto;
  animation: drawerIn 420ms var(--ease-out) both;
}
@keyframes drawerIn { from { opacity: 0; transform: translateY(-16px); } }

.drawer__link {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.9rem, 8vw, 2.8rem);
  color: var(--cream); padding-block: .6rem;
  border-bottom: 1px solid rgba(251, 250, 244, .12);
}
.drawer__link[aria-current="page"] { color: var(--rose-soft); }
.drawer__meta { margin-top: auto; padding-top: 2.5rem; color: var(--on-dark-body); font-size: .9rem; }
/* The phone number is a primary mobile CTA, not incidental prose — as a bare inline
   link it measured 140x17, well under the 44px tap-target floor. */
.drawer__meta a[href^="tel:"] {
  display: inline-flex; align-items: center; min-height: 44px; padding-inline: 2px;
  color: var(--cream); font-weight: 700;
}

/* Legal links in the drawer: secondary, but still real tap targets — a 44px
   row each rather than two small links crowded on one line. */
.drawer__legal {
  display: flex; flex-direction: column;
  margin-top: 1.25rem; padding-top: 1.25rem;
  border-top: 1px solid rgba(251, 250, 244, .14);
}
.drawer__legal a {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: .86rem; color: rgba(251, 250, 244, .72);
}
.drawer__legal a:hover { color: var(--cream); }

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
  min-height: 52px; padding: 0 1.75rem;
  border-radius: 999px; border: 1px solid transparent;
  font-family: var(--sans); font-size: .94rem; font-weight: 700;
  cursor: pointer; text-align: center;
  transition: transform 240ms var(--ease-out), background 240ms, color 240ms, border-color 240ms;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn--full { width: 100%; }
.btn--sm { min-height: 46px; padding: 0 1.25rem; font-size: .86rem; }

.btn--primary { background: var(--rose); color: #fff; box-shadow: 0 10px 28px -12px rgba(161, 58, 82, .7); }
.btn--primary:hover { background: var(--rose-bright); }

.btn--ghost { border-color: var(--line); color: var(--forest); background: rgba(255, 255, 255, .55); }
.btn--ghost:hover { background: #fff; border-color: var(--forest); }

.btn--light { border-color: rgba(251, 250, 244, .38); color: var(--cream); }
.btn--light:hover { background: rgba(251, 250, 244, .12); border-color: rgba(251, 250, 244, .7); }

.btn__icon { transition: transform 300ms var(--ease-out); flex: none; }
.btn:hover .btn__icon { transform: translateX(4px); }

/* Text link with an underline that grows — 44px target kept via ::before */
.tlink {
  position: relative; display: inline-block;
  font-size: .78rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  color: var(--rose); border-bottom: 1.5px solid currentColor; padding-bottom: 3px;
  transition: color 200ms;
}
.tlink::before { content: ""; position: absolute; inset: -14px -10px; }
.tlink:hover { color: var(--forest); }
.on-dark .tlink, .plan .tlink { color: var(--rose-soft); }
.on-dark .tlink:hover, .plan .tlink:hover { color: var(--cream); }

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero {
  position: relative; overflow: hidden;
  padding-block: calc(var(--nav-h) + clamp(2.5rem, 7vh, 5rem)) clamp(3rem, 8vh, 6rem);
}
.hero--tall { min-height: 100svh; display: flex; align-items: center; }
.hero__inner { position: relative; z-index: 2; width: 100%; }

.hero__grid { display: grid; gap: clamp(2.5rem, 5vw, 4rem); align-items: center; }
/* Figure column takes the larger share: the hero collage is a wide canvas
   (woman + cards + floaters around her), not just a portrait. */
@media (min-width: 960px) { .hero__grid { grid-template-columns: .92fr 1.08fr; gap: clamp(1.5rem, 3vw, 2.5rem); } }

.hero__figure { position: relative; justify-self: center; width: min(100%, 440px); }
.hero__photo {
  position: relative; overflow: hidden;
  border-radius: 999px 999px 42px 42px;
  aspect-ratio: 4 / 5;
  box-shadow: 0 42px 90px -48px rgba(28, 58, 23, .55);
  background: var(--sand);
}
.hero__photo img { width: 100%; height: 100%; object-fit: cover; }

.hero__badge {
  position: absolute; left: -1rem; bottom: 2rem; z-index: 2;
  display: flex; align-items: center; gap: .75rem;
  background: rgba(255, 253, 249, .95); backdrop-filter: blur(10px);
  border: 1px solid var(--line-soft); border-radius: 18px; padding: .8rem 1rem;
  box-shadow: 0 20px 40px -26px rgba(28, 58, 23, .5);
}
@media (max-width: 560px) { .hero__badge { left: 0; bottom: 1rem; } }

/* Home's hero moved the badge off the photo (it collided with the floating
   cards) and into the text column as a normal flow element. */
.hero__badge--inline { position: static; margin-top: 1.75rem; width: fit-content; }

.hero__floral-a { top: -6%;  right: -8%;  width: clamp(140px, 20vw, 280px); color: var(--lime); opacity: .42; transform: rotate(9deg); }
.hero__floral-b { bottom: -10%; left: -10%; width: clamp(130px, 17vw, 230px); color: var(--rose); opacity: .3; transform: rotate(-166deg); }
.hero__floral-c { top: 6%;  left: -13%;  width: clamp(180px, 25vw, 360px); color: var(--lime); opacity: .24; transform: scaleX(-1); }

/* --------------------------------------------------------------------------
   Hero collage — cutout portrait, floating info cards, floating nutrition
   elements. Sits inside .hero__figure (which owns the column width); .hero
   already has overflow:hidden, so anything that pokes past the collage
   edge clips cleanly instead of causing page-level horizontal scroll.
   -------------------------------------------------------------------------- */

/* woman.png is a full-body cutout with an unusually tall/narrow frame
   (379×998, ratio .38). object-fit:contain fits her ENTIRE height — feet
   included — inside the box, which shrinks her to a ~240px-wide sliver
   letterboxed in dead space. The reference crops her around knee level,
   and that lower crop is exactly what lets her fill the width.
   So: cover + top anchor. She scales to the box's full width and the
   empty leg/floor area falls off the bottom. Box width now drives how
   big she reads; height only decides where the crop lands. */
/* The collage is a WIDE canvas, not a portrait frame. In the reference the
   canvas is ~2.7x the woman's own width — that surplus is what lets the
   cards sit fully clear to her right and the floaters scatter around her.
   So the box fills its (now larger) column and the woman is absolutely
   placed against its left edge at ~54% of it. */
/* Bleeds right into the shell's own gutter — .hero clips it — to buy back
   the width the card cluster needs without starving the text column. */
.hero__collage { width: calc(100% + 2.5rem); height: clamp(540px, 72vh, 720px); }

.hero__woman {
  position: absolute; z-index: 2; left: 2%; top: 0;
  width: 56%; height: 100%;
  object-fit: cover; object-position: 50% 0;
  filter: drop-shadow(0 30px 55px rgba(28, 58, 23, .3));
}


@media (max-width: 720px) {
  /* No room for a side-by-side canvas on a phone: she goes back to a plain
     in-flow image at full width and the cards stack beneath her.

     height:auto is load-bearing. The collage is a fixed height on desktop so
     the cards can be absolutely positioned over the photo. Once they stack in
     flow underneath, that fixed box no longer contains them — they spilled
     past the bottom of .hero, which clips (overflow:hidden), so the first card
     was cut through the middle and the other three vanished entirely. The
     photo carries the height now and the collage grows to fit its content. */
  .hero__collage { width: min(100%, 420px); height: auto; }
  .hero__woman {
    position: relative; left: 0;
    width: 100%; height: clamp(320px, 55vh, 480px);
    object-fit: cover; object-position: top;
  }
}


/* A flex column, not four absolutely-positioned cards. With fixed `top:%`
   values the gaps came out at 27 / 46 / 60px because the cards are different
   heights (two-line titles wrap). Letting flex own the spacing makes the
   gaps identical no matter how the copy wraps. translateY lifts the whole
   cluster off the bottom edge. */
.hero__cards {
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  display: flex; flex-direction: column; align-items: flex-start;
  justify-content: center;
  gap: clamp(1.25rem, 3vh, 2.25rem);
  transform: translateY(-5%);
}
.hero__card {
  position: static; pointer-events: auto; flex: none;
  display: flex; align-items: flex-start; gap: .7rem;
  width: clamp(195px, 44vw, 232px);
  background: rgba(255, 253, 249, .97); backdrop-filter: blur(10px);
  border: 1px solid var(--line-soft); border-radius: 18px;
  padding: 1.05rem 1.15rem;
  box-shadow: 0 24px 46px -28px rgba(28, 58, 23, .5);
}
/* Chevron ">" — cards 1 and 4 tuck in, 2 and 3 push right to form the point.
   Horizontal offset only; flex handles the vertical rhythm. */
.hero__card--1 { margin-left: 50%; }
.hero__card--2 { margin-left: 63%; }
.hero__card--3 { margin-left: 63%; }
.hero__card--4 { margin-left: 50%; }

/* Between the two-column breakpoint and ~1200px the figure column is too
   narrow for full-size cards at these offsets — card 2 (the chevron's point)
   ran 8-37px past the viewport edge and got clipped. Pull the trio in and
   shrink the cards slightly across that band only; the wide-screen
   composition above 1200px is untouched. */
@media (min-width: 960px) and (max-width: 1200px) {
  .hero__card { width: clamp(168px, 19vw, 200px); padding: .85rem .95rem; }
  .hero__card-title { font-size: .88rem; }
  .hero__card-text  { font-size: .76rem; }
  .hero__card-icon  { width: 34px; height: 34px; }
  .hero__cards { gap: clamp(.7rem, 1.6vh, 1.1rem); }
  .hero__card--1 { margin-left: 42%; }
  .hero__card--2 { margin-left: 54%; }
  .hero__card--3 { margin-left: 54%; }
  .hero__card--4 { margin-left: 42%; }
}

.hero__card-icon {
  flex: none; width: 40px; height: 40px; border-radius: 999px;
  display: grid; place-items: center;
}
.hero__card-icon--sage { background: #dfe8d3; color: var(--forest-mid); }
.hero__card-icon--rose { background: var(--rose-soft); color: var(--rose); }

.hero__card-title { display: block; font-weight: 800; font-size: .95rem; line-height: 1.25; color: var(--fg); }
.hero__card-text  { display: block; font-size: .82rem; line-height: 1.45; color: var(--muted); margin-top: .28rem; }

@media (max-width: 720px) {
  .hero__cards { position: static; display: grid; gap: .6rem; margin-top: 1rem; }
  .hero__cards { transform: none; }
  .hero__card, .hero__card--1, .hero__card--2, .hero__card--3, .hero__card--4 { position: static; width: 100%; margin-left: 0; }
}

/* --------------------------------------------------------------------------
   Service strip — six programs, directly under the hero.
   -------------------------------------------------------------------------- */

.service-strip { padding-block: clamp(1.5rem, 4vw, 2.5rem); position: relative; z-index: 2; }
.service-strip__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.25rem, 3vw, 2rem);
}
@media (min-width: 720px) { .service-strip__list { grid-template-columns: repeat(6, 1fr); } }
.service-strip__item {
  display: flex; flex-direction: column; align-items: center; gap: .6rem;
  text-align: center; font-size: .85rem; font-weight: 700; color: var(--fg);
}
.service-strip__icon {
  width: clamp(58px, 8vw, 74px); aspect-ratio: 1; border-radius: 999px; overflow: hidden;
  box-shadow: 0 16px 30px -20px rgba(28, 58, 23, .4);
}
.service-strip__icon img { width: 100%; height: 100%; object-fit: cover; }

/* Masked line-by-line headline reveal */
.reveal-line { display: block; overflow: hidden; }
.reveal-line > span { display: block; transform: translateY(105%); }

.hero__scroll {
  position: absolute; bottom: 1.25rem; left: 50%; transform: translateX(-50%);
  z-index: 2; display: flex; flex-direction: column; align-items: center; gap: .65rem;
  font-size: .6rem; letter-spacing: .3em; text-transform: uppercase;
  color: rgba(28, 58, 23, .78); font-weight: 800;  /* 5.7:1 on cream */
}
.hero__scroll-track { width: 1px; height: 50px; background: rgba(28, 58, 23, .2); position: relative; overflow: hidden; }
.hero__scroll-track::after {
  content: ""; position: absolute; inset-inline: 0; height: 42%;
  background: var(--rose); animation: scrollCue 2s var(--ease-in-out) infinite;
}
@keyframes scrollCue { from { transform: translateY(-100%); } to { transform: translateY(250%); } }

/* The cue is absolutely positioned to the bottom of .hero. Once the hero
   stacks on a phone, "bottom" lands over the pillar cards and the 1px track
   draws a line straight through the first one. Scrolling needs no hint on a
   touch screen. Must come after the rules above: same specificity, so this
   only wins on source order. */
@media (max-width: 720px) {
  .hero__scroll { display: none; }
}

/* Sparse drifting petals — decorative only, kept well under 100 on screen.
   Lives inside .hero (which clips), so there is no page-wide fixed layer to
   fight the stacking order of later sections. */
/* Starts below the nav so a drifting petal can never sit behind a nav link
   and eat its contrast (the nav is transparent until it sticks). */
.petals { position: absolute; inset: var(--nav-h) 0 0; z-index: 1; pointer-events: none; overflow: hidden; }
.petal {
  position: absolute; top: -12%; width: 22px;
  color: var(--rose-soft); opacity: 0;
  animation: petalFall linear infinite;
}
.petal:nth-child(even) { color: var(--lime); width: 15px; }
@keyframes petalFall {
  0%   { opacity: 0;   transform: translate3d(0, -10vh, 0) rotate(0deg); }
  12%  { opacity: .75; }
  88%  { opacity: .55; }
  100% { opacity: 0;   transform: translate3d(6vw, 108vh, 0) rotate(420deg); }
}

/* Breadcrumb — only the six service sub-pages use it. They are not primary-nav
   items and deliberately carry no aria-current in the nav, so this is the page's
   only "you are here" signal. min-height keeps each crumb a 44px target. */
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; color: var(--muted); }
.crumbs a { display: inline-flex; align-items: center; min-height: 44px; color: var(--rose); font-weight: 700; border-bottom: 1.5px solid transparent; }
.crumbs a:hover { border-bottom-color: currentColor; }
.crumbs [aria-current] { color: var(--forest); font-weight: 700; }

/* Sub-page hero figure: the squared 3:4 .media frame, given .hero__photo's lift
   so the two hero treatments read as the same family. */
.hero__frame { box-shadow: 0 42px 90px -48px rgba(28, 58, 23, .55); }

/* --------------------------------------------------------------------------
   Marquee
   -------------------------------------------------------------------------- */

.marquee {
  overflow: hidden; border-block: 1px solid var(--line-soft);
  background: var(--sand); padding-block: 1.1rem; position: relative;
}
.marquee__track { display: flex; gap: 3rem; width: max-content; }
.marquee__item {
  display: inline-flex; align-items: center; gap: 3rem;
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.05rem, 1.9vw, 1.6rem); color: var(--forest); white-space: nowrap;
}
.marquee__dot { width: 7px; height: 7px; border-radius: 999px; background: var(--rose); flex: none; }

/* --------------------------------------------------------------------------
   Word-by-word manifesto reveal
   -------------------------------------------------------------------------- */

.wordwrap .word { display: inline-block; opacity: .18; transition: opacity 200ms linear; }
.wordwrap .word.is-lit { opacity: 1; }

/* --------------------------------------------------------------------------
   Media cards
   -------------------------------------------------------------------------- */

.media {
  border-radius: 22px; overflow: hidden; background: var(--sand);
  aspect-ratio: 4 / 3; position: relative;
}
.media--tall   { aspect-ratio: 3 / 4; }
.media--wide   { aspect-ratio: 16 / 9; }
.media--square { aspect-ratio: 1 / 1; }
.media img { width: 100%; height: 100%; object-fit: cover; transition: transform 900ms var(--ease-out); }
.media-hover:hover .media img, a:hover > .media img { transform: scale(1.05); }

.card {
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 24px;
  padding: clamp(1.4rem, 2.4vw, 2.1rem);
  transition: transform 380ms var(--ease-out), box-shadow 380ms var(--ease-out);
}
.card--flat { background: transparent; border: 0; padding: 0; }
a.card:hover, .card--lift:hover { transform: translateY(-6px); box-shadow: 0 26px 58px -32px rgba(28, 58, 23, .45); }
.on-dark .card { background: rgba(251, 250, 244, .055); border-color: rgba(251, 250, 244, .14); }

.quote { font-family: var(--display); font-size: 1.05rem; line-height: 1.62; font-weight: 400; }

.pill {
  display: inline-flex; align-items: center; gap: .45rem;
  border: 1px solid var(--line); border-radius: 999px;
  padding: .45rem .9rem; font-size: .8rem; font-weight: 700;
  background: rgba(255, 255, 255, .6); color: var(--forest);
}
.on-dark .pill { border-color: rgba(251, 250, 244, .22); background: rgba(251, 250, 244, .06); color: var(--cream); }

/* Reveal-on-scroll primitive */
.rise { opacity: 0; transform: translateY(34px); }
.rise.is-in { opacity: 1; transform: none; transition: opacity 850ms var(--ease-out), transform 850ms var(--ease-out); }

/* --------------------------------------------------------------------------
   The journey — six stacked stages with a sticky index rail.
   Deliberately NOT a pinned horizontal track: it reads the same on a phone as
   on a desktop, and there is no locked-height panel to overflow.
   -------------------------------------------------------------------------- */

.journey__layout { display: grid; gap: clamp(2rem, 4vw, 3.5rem); }
@media (min-width: 1000px) { .journey__layout { grid-template-columns: 230px 1fr; align-items: start; } }

.rail { display: none; }
@media (min-width: 1000px) {
  .rail { display: block; position: sticky; top: calc(var(--nav-h) + 2.5rem); }
}
.rail__item {
  display: flex; align-items: center; gap: .8rem;
  padding: .55rem 0; font-size: .88rem; font-weight: 600;
  color: var(--muted); transition: color 260ms;
}
.rail__num {
  width: 26px; height: 26px; flex: none; border-radius: 999px;
  display: grid; place-items: center; font-size: .68rem; font-weight: 800;
  border: 1px solid var(--line); transition: background 260ms, color 260ms, border-color 260ms;
}
.rail__item.is-active { color: var(--rose); }
.rail__item.is-active .rail__num { background: var(--rose); border-color: var(--rose); color: #fff; }

.stage { position: relative; padding-block: clamp(2.5rem, 6vh, 4.5rem); scroll-margin-top: calc(var(--nav-h) + 24px); }
.stage + .stage { border-top: 1px solid var(--line); }
.stage__grid { display: grid; gap: clamp(1.5rem, 3.5vw, 3rem); align-items: center; }
@media (min-width: 780px) { .stage__grid { grid-template-columns: .9fr 1.1fr; } }

.stage__index {
  font-family: var(--display); font-size: clamp(2.6rem, 6vw, 4.4rem);
  line-height: .85; color: transparent;
  -webkit-text-stroke: 1.4px rgba(161, 58, 82, .38);
  margin-bottom: .5rem;
}

/* Price panel — an opaque deep-green card so its cream text is always safe. */
.plans {
  background: var(--forest-deep); color: var(--cream);
  border-radius: 24px; padding: clamp(1.25rem, 2.4vw, 1.9rem);
}
.plan {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding-block: .85rem;
  border-bottom: 1px solid rgba(251, 250, 244, .12);
}
.plan:last-child { border-bottom: 0; padding-bottom: 0; }
.plan__name  { font-size: .92rem; font-weight: 600; }
.plan__right { display: flex; align-items: center; gap: 1rem; flex: none; }

/* --------------------------------------------------------------------------
   Portrait + promo
   -------------------------------------------------------------------------- */

.portrait { position: relative; border-radius: 30px; overflow: hidden; aspect-ratio: 4 / 5; background: var(--sand); }
.portrait img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%; }
.portrait__wash { position: absolute; inset: 0; background: linear-gradient(190deg, transparent 48%, rgba(13, 31, 11, .66) 100%); }
.portrait__tag {
  position: absolute; left: 1.1rem; right: 1.1rem; bottom: 1.1rem;
  display: flex; align-items: center; gap: .85rem;
  background: rgba(251, 250, 244, .95); backdrop-filter: blur(10px);
  border-radius: 18px; padding: .85rem 1rem; color: var(--forest);
}

.promo {
  background: linear-gradient(135deg, var(--forest) 0%, var(--forest-mid) 100%);
  border-radius: 32px; color: var(--cream); overflow: hidden; position: relative;
  padding: clamp(1.75rem, 4.5vw, 3.5rem);
}
.promo__glow {
  position: absolute; width: 440px; height: 440px; border-radius: 999px;
  background: radial-gradient(circle, rgba(161, 58, 82, .5), transparent 68%);
  top: -170px; right: -130px; pointer-events: none;
}
.promo > .promo__body { position: relative; z-index: 1; }

.event {
  display: flex; align-items: center; gap: 1rem;
  background: rgba(251, 250, 244, .08); border: 1px solid rgba(251, 250, 244, .16);
  border-radius: 20px; padding: .8rem 1rem;
}
.event__date {
  width: 56px; height: 56px; border-radius: 16px; flex: none;
  display: grid; place-content: center; text-align: center; line-height: 1.1;
  background: var(--rose); color: #fff;
}
.event__img { width: 50px; height: 50px; border-radius: 13px; object-fit: cover; flex: none; }

/* --------------------------------------------------------------------------
   Pricing comparison table (Services)
   -------------------------------------------------------------------------- */

/* Wide content scrolls inside its own box; the page body never does. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 22px; border: 1px solid var(--line); background: var(--paper); }
.ptable { width: 100%; border-collapse: collapse; min-width: 620px; font-size: .93rem; }
.ptable caption { text-align: left; padding: 1.1rem 1.25rem; color: var(--muted); font-size: .88rem; }
.ptable th, .ptable td { padding: .9rem 1.25rem; text-align: left; border-top: 1px solid var(--line-soft); vertical-align: middle; }
.ptable thead th { border-top: 0; background: var(--sand); font-size: .72rem; letter-spacing: .16em; text-transform: uppercase; font-weight: 800; color: var(--forest); }
.ptable tbody th { font-weight: 600; color: var(--forest); }
.ptable tbody tr:hover { background: rgba(241, 239, 227, .5); }
.table-hint { display: none; }

/* Below 720px the comparison table stops being a table and becomes a stack of
   cards. At 375px the 620px table sat in a 333px window with 287px hidden off
   the right edge — the Term and the Enroll link, which is the entire point of
   the row, were both behind a sideways swipe most people never try. The
   <table> markup and its semantics are untouched; only the presentation
   changes, so the header row is kept for assistive tech rather than removed. */
@media (max-width: 719px) {
  .table-scroll { overflow: visible; border: 0; background: none; border-radius: 0; }
  .ptable { min-width: 0; display: block; font-size: 1rem; }
  /* display:block on the table leaves the caption sized to the old table box,
     which wrapped it into a ~90px ribbon. */
  .ptable caption { display: block; width: 100%; padding: 0 0 1rem; }
  .ptable thead {
    position: absolute; width: 1px; height: 1px;
    padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  .ptable tbody { display: block; }

  .ptable tbody tr.group { display: block; }
  .ptable tbody tr.group th {
    display: block; background: none; border: 0;
    padding: 1.5rem 0 .6rem; font-size: 1.05rem;
  }
  .ptable tbody tr.group:first-child th { padding-top: 0; }

  .ptable tbody tr:not(.group) {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas: "name name" "term cta";
    align-items: center; gap: .35rem .9rem;
    padding: .95rem 1.1rem; margin-bottom: .6rem;
    border: 1px solid var(--line-soft); border-radius: 16px;
    background: var(--paper);
  }
  .ptable tbody tr:not(.group):hover { background: var(--paper); }
  .ptable tbody tr:not(.group) th,
  .ptable tbody tr:not(.group) td { display: block; border: 0; padding: 0; }
  .ptable tbody tr:not(.group) th[scope="row"] { grid-area: name; font-size: 1rem; font-weight: 700; }
  .ptable tbody tr:not(.group) td:first-of-type { grid-area: term; color: var(--muted); font-size: .88rem; }
  .ptable tbody tr:not(.group) td:last-of-type  { grid-area: cta; justify-self: end; }
}

.ptable .group th {
  background: var(--cream); font-family: var(--display); font-weight: 600;
  font-size: 1rem; color: var(--forest); letter-spacing: normal; text-transform: none;
}

/* --------------------------------------------------------------------------
   Accordion (FAQ + "what's included")
   -------------------------------------------------------------------------- */

.acc__item { border-bottom: 1px solid var(--line); }
.acc__trigger {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 1.25rem;
  background: none; border: 0; cursor: pointer; text-align: left;
  padding: 1.35rem 0; min-height: 56px;
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.02rem, 1.6vw, 1.32rem); color: var(--forest);
}
.acc__sign {
  flex: none; width: 34px; height: 34px; border-radius: 999px; border: 1px solid var(--line);
  display: grid; place-items: center;
  transition: transform 380ms var(--ease-out), background 280ms, color 280ms, border-color 280ms;
}
.acc__trigger[aria-expanded="true"] .acc__sign { transform: rotate(45deg); background: var(--rose); color: #fff; border-color: var(--rose); }
.acc__panel { overflow: hidden; height: 0; }
.acc__panel-inner { padding-bottom: 1.5rem; max-width: 68ch; color: var(--muted); }
.acc__panel-inner a { color: var(--rose); font-weight: 700; }

/* No JavaScript: nothing can ever set the panel height, so the answers would be
   permanently unreachable behind a button that will never respond. Show them
   all and drop the +/- affordance that implies interactivity. */
@media (scripting: none) {
  .acc__panel { height: auto; }
  .acc__sign  { display: none; }
  /* .rise starts at opacity 0 and only JS can clear it. The service pages now
     carry their nutrition guide inside .rise cards, so without this the whole
     body of the page is permanently invisible to a no-JS visitor. */
  .rise { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   Lists
   -------------------------------------------------------------------------- */

.ticks { display: grid; gap: .7rem; }
/* 1rem, not .95: the service pages now carry their main body copy in these
   lists, so they have to clear the 16px reading floor. */
.ticks li { display: flex; gap: .7rem; align-items: flex-start; font-size: 1rem; color: var(--muted); }
.ticks strong { color: var(--forest); font-weight: 700; }
.ticks svg { flex: none; margin-top: .32rem; color: var(--rose); }
.on-dark .ticks li { color: var(--on-dark-body); }
.on-dark .ticks svg { color: var(--rose-soft); }
/* .ticks strong is forest green — invisible on the dark bands without this. */
.on-dark .ticks strong { color: var(--cream); }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.footer { background: var(--forest-deep); color: var(--on-dark-body); position: relative; }
.footer a:hover { color: var(--cream); }
/* 44px touch targets in the footer link lists; the row pitch replaces the gap */
.footer ul.stack { gap: 0; }
.footer ul.stack li { display: flex; align-items: center; min-height: 44px; }
.footer ul.stack a { display: flex; align-items: center; min-height: 44px; width: 100%; }
.footer__logo { height: 92px; width: auto; margin-bottom: 1.25rem; }

.footer__head { font-size: .68rem; letter-spacing: .22em; text-transform: uppercase; color: var(--rose-soft); font-weight: 800; margin-bottom: 1rem; }
.footer__grid { display: grid; gap: 2.75rem; }
/* Stacked one per row, the four footer columns ran to 1572px on a 375px
   phone — nearly two full screens of footer under every page. The two link
   lists sit side by side instead (they are the tall ones), the gaps tighten
   and the map loses a little height. */
@media (max-width: 779px) {
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 1.6rem 1.25rem; }
  .footer__grid > :nth-child(1) { grid-column: 1 / -1; }            /* brand   */
  .footer__grid > :nth-child(2) { grid-column: 1; grid-row: 2; }    /* site    */
  .footer__grid > :nth-child(4) { grid-column: 2; grid-row: 2; }    /* contact */
  .footer__grid > :nth-child(3) { grid-column: 1 / -1; grid-row: 3; } /* clinic */
  .footer__grid .small { font-size: .82rem; }
  .footer ul.stack a { word-break: break-word; }
  .footer__head { margin-bottom: .5rem; }
  .footer__logo { height: 62px; margin-bottom: .8rem; }
  .footer__bottom { margin-top: 1.75rem; padding-top: 1.1rem; gap: .6rem; }
}

@media (min-width: 780px)  { .footer__grid { grid-template-columns: 1.4fr 1fr 1fr; } }
@media (min-width: 1080px) { .footer__grid { grid-template-columns: 1.6fr 1fr 1fr 1fr; } }
.footer__bottom {
  margin-top: 3rem; padding-top: 1.6rem; border-top: 1px solid rgba(251, 250, 244, .14);
  display: flex; flex-wrap: wrap; gap: 1.25rem; justify-content: space-between;
  font-size: .78rem; color: rgba(251, 250, 244, .62);
}

/* --------------------------------------------------------------------------
   Booking form — lives inside the dark #cta band on every page, and inside
   the home-page <dialog>. Both copies share these rules.
   -------------------------------------------------------------------------- */

.book {
  background: var(--paper);
  border-radius: 26px;
  padding: clamp(1.5rem, 3.5vw, 2.5rem);
  text-align: left;
  color: var(--forest);
  box-shadow: 0 40px 80px -46px rgba(13, 31, 11, .8);
  scroll-margin-top: calc(var(--nav-h) + 24px);
}
.book__grid { display: grid; gap: 1.1rem; }
@media (min-width: 760px) { .book__grid { grid-template-columns: 1fr 1fr; } .book__grid .field--wide { grid-column: 1 / -1; } }

.field { display: grid; gap: .4rem; }
.field > label { font-size: .78rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 800; color: var(--forest); }
.input {
  font: inherit;
  font-size: 1rem;              /* 16px floor — also stops iOS zoom-on-focus */
  color: var(--forest);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: .8rem 1rem;
  min-height: 52px;
  width: 100%;
  transition: border-color 200ms var(--ease-out), box-shadow 200ms var(--ease-out);
}
.input:hover { border-color: rgba(28, 58, 23, .3); }
.input:focus-visible { outline: none; border-color: var(--rose); box-shadow: 0 0 0 3px rgba(161, 58, 82, .22); }
/* Native select keeps its own arrow; only the box is restyled. */
select.input { appearance: none; -webkit-appearance: none; padding-right: 2.75rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%231c3a17' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 1.1rem center; }

.field__err { font-size: .86rem; font-weight: 700; color: #8c1f36; }
.book__note { font-size: .86rem; color: var(--muted); }
.book__note a { color: var(--rose); font-weight: 700; }

/* Swapped in where the form was once an enquiry is sent (see main.js). */
.book__done {
  padding: clamp(1.5rem, 4vw, 2.25rem);
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--sand);
}
.book__done p { font-size: .94rem; color: var(--muted); }
.book__done-title {
  font-family: var(--display);
  font-size: clamp(1.25rem, 2.6vw, 1.6rem);
  font-weight: 600;
  color: var(--fg);
  margin-bottom: .5rem;
}
.book__done strong { color: var(--fg); }
.input[aria-invalid="true"] { border-color: var(--rose); }

/* --------------------------------------------------------------------------
   Home-page consultation modal — a native <dialog>. The platform gives us the
   top layer, Escape-to-close, the backdrop and focus containment for free, and
   with JS off it simply never opens instead of covering the page.
   -------------------------------------------------------------------------- */

.modal {
  border: 0; padding: 0; max-width: min(560px, calc(100vw - 2rem)); width: 100%;
  background: transparent; color: var(--forest); overflow: visible; position: relative;
}
.modal::backdrop { background: rgba(13, 31, 11, .62); backdrop-filter: blur(3px); }
.modal[open] { animation: modal-in 320ms var(--ease-out); }
@keyframes modal-in { from { opacity: 0; transform: translateY(18px); } }
/* Its own scrollbar on short screens, so the whole form stays reachable. The
   card carries data-lenis-prevent in the markup, without which Lenis eats the
   wheel and this never scrolls. */
.modal__card { position: relative; max-height: 88vh; overflow-y: auto; }
/* Forest-on-cream, not cream-on-cream: at .55rem inside a paper card the
   low-contrast version was effectively invisible. */
.modal__close {
  position: absolute; top: .6rem; right: .6rem; z-index: 1;
  width: 44px; height: 44px; display: grid; place-items: center;
  border: 1px solid var(--forest); border-radius: 999px;
  background: var(--forest); color: var(--cream); cursor: pointer;
}
.modal__close:hover { background: var(--rose); border-color: var(--rose); }

/* --------------------------------------------------------------------------
   Blog — index cards + article body
   -------------------------------------------------------------------------- */

/* Grid children stretch, so the card is a column and the "Read" line is pushed
   to the bottom — otherwise it floats mid-card whenever the dek is short. */
.card--post { display: flex; flex-direction: column; }
.card--post .media { margin-bottom: 1.25rem; }
/* Several real WordPress featured images are portrait; a centred cover crop in
   a 16:9 thumb beheads the subject. Bias the crop toward the top third. */
.card--post .media img { object-position: 50% 28%; }
.card--post .post-more { margin-top: auto; padding-top: 1.25rem; }

.post-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .75rem;
  font-size: .8rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
}
.post-meta .dot { width: 4px; height: 4px; border-radius: 999px; background: var(--rose); flex: none; }
.on-dark .post-meta { color: var(--on-dark-body); }

/* Article body. One wrapper, because the imported WordPress markup is plain
   p/h2-h4/ul/ol/hr/strong with its block classes stripped. */
.prose { max-width: 68ch; }
.prose > * + * { margin-top: 1.15rem; }
.prose p, .prose li { font-size: 1.05rem; line-height: 1.72; color: var(--muted); }
.prose strong { color: var(--forest); font-weight: 700; }
.prose em { font-style: italic; }
.prose h2, .prose h3, .prose h4 {
  font-family: var(--display); font-weight: 600; color: var(--forest);
  letter-spacing: -.015em; line-height: 1.2;
}
.prose h2 { font-size: clamp(1.5rem, 2.6vw, 2rem); margin-top: 2.9rem; }
.prose h3 { font-size: clamp(1.28rem, 2vw, 1.6rem); margin-top: 2.4rem; }
.prose h4 { font-size: clamp(1.1rem, 1.6vw, 1.28rem); margin-top: 1.9rem; }
.prose h2 + *, .prose h3 + *, .prose h4 + * { margin-top: .8rem; }
.prose ul, .prose ol { display: grid; gap: .7rem; margin-top: 1rem; }
.prose li { padding-left: 1.5rem; position: relative; }
.prose ul > li::before {
  content: ""; position: absolute; left: 2px; top: .68em;
  width: 7px; height: 7px; border-radius: 999px; background: var(--rose); opacity: .6;
}
.prose ol { counter-reset: prose-n; }
.prose ol > li { padding-left: 1.9rem; counter-increment: prose-n; }
.prose ol > li::before {
  content: counter(prose-n) "."; position: absolute; left: 0; top: 0;
  color: var(--rose); font-weight: 800; font-variant-numeric: tabular-nums;
}
.prose hr { height: 1px; border: 0; background: var(--line); margin-block: 2.4rem; }
.prose a { color: var(--rose); font-weight: 700; border-bottom: 1.5px solid rgba(161, 58, 82, .38); }
.prose a:hover { border-bottom-color: currentColor; }

/* 3:2, not 16:9 — five of the real WordPress featured images are portrait or
   small, and the wider crop guillotines them. Bias the crop upward for the
   same reason: the subject is almost always in the top half. */
.post-hero { max-width: 760px; aspect-ratio: 3 / 2; }
.post-hero img { object-position: 50% 32%; }

/* Sits under the article body: the medical caveat plus provenance. */
.post-note {
  border-left: 3px solid var(--rose); background: var(--sand);
  border-radius: 0 16px 16px 0; padding: 1.1rem 1.35rem;
  font-size: .92rem; color: var(--muted); max-width: 68ch;
}
.post-note a { color: var(--rose); font-weight: 700; }

/* --- Journal masthead -----------------------------------------------------
   The blog's cover image runs the full width of the shell under the headline
   rather than sitting in the 440px .hero__figure column: these are landscape
   frames, and shrinking one into that column reads as a thumbnail, not a
   cover. Same shadow as .hero__frame so it stays in the family. */
.masthead__band {
  border-radius: clamp(18px, 2.4vw, 30px);
  aspect-ratio: 21 / 9;
  box-shadow: 0 42px 90px -48px rgba(28, 58, 23, .55);
}
/* Both women's faces sit in the upper half of the frame; a centred cover crop
   at 21:9 cuts them. */
.masthead__band img { object-position: 50% 36%; }
@media (max-width: 760px) { .masthead__band { aspect-ratio: 4 / 3; } }

/* Cover line. An opaque paper card, deliberately not text set over the photo —
   there is no scrim to get wrong and the contrast is the page's own. */
.masthead__note {
  position: absolute; left: clamp(.75rem, 2.5vw, 2rem); bottom: clamp(.75rem, 2.5vw, 2rem);
  z-index: 2; max-width: min(90%, 30ch);
  background: rgba(255, 253, 249, .96); backdrop-filter: blur(8px);
  border: 1px solid var(--line-soft); border-radius: 18px;
  padding: .9rem 1.15rem;
  box-shadow: 0 24px 48px -30px rgba(28, 58, 23, .55);
}
/* On a phone the card would cover most of the frame, so it drops below the
   image instead of disappearing — the copy stays readable either way. */
@media (max-width: 640px) {
  .masthead__note { position: static; max-width: none; margin-top: 1rem; backdrop-filter: none; }
}

/* --- Category filter ------------------------------------------------------
   Plain links carrying ?category=, not a JS toggle: the filter survives a
   dead script, is linkable, and the back button does the right thing. */
.filters { display: flex; flex-wrap: wrap; gap: .6rem; }
.filters .pill { min-height: 44px; transition: background 200ms var(--ease-out), color 200ms var(--ease-out); }
.filters .pill:hover { background: #fff; border-color: var(--rose); color: var(--rose); }
.pill--on, .filters .pill--on:hover {
  background: var(--forest); border-color: var(--forest); color: var(--cream);
}

/* --- Featured article -----------------------------------------------------
   Bigger frame, bigger type and its own rule above it, so the lead story is
   visibly a different rank from the grid rather than a wider card. */
.feature .media { border-radius: clamp(18px, 2.4vw, 28px); box-shadow: 0 34px 74px -44px rgba(28, 58, 23, .5); }
.feature .media img { object-position: 50% 30%; }

/* --- Byline ---------------------------------------------------------------
   The circular brand badge, per the logo rules — the byline is the practice,
   not a named individual, so no portrait is implied. */
.byline { display: flex; align-items: center; gap: .9rem; }
.byline__mark {
  width: 48px; height: 48px; border-radius: 999px; object-fit: cover; flex: none;
  border: 1px solid var(--line);   /* the badge's own ground is near-cream, so it needs an edge */
}

/* --- Reading progress -----------------------------------------------------
   Scroll-driven CSS animation: no JS, no ScrollTrigger, and browsers without
   animation-timeline simply never paint the bar. Sits one above the nav's
   z-index 100 so the stuck nav's blurred backdrop cannot cover it. */
@supports (animation-timeline: scroll()) {
  .readbar {
    position: fixed; inset: 0 0 auto; height: 3px; z-index: 101;
    transform-origin: 0 50%; transform: scaleX(0);
    background: linear-gradient(90deg, var(--rose), var(--lime));
    animation: readProgress linear both;
    animation-timeline: scroll(root block);
  }
  @keyframes readProgress { to { transform: scaleX(1); } }
}
@media (prefers-reduced-motion: reduce) { .readbar { display: none; } }

/* --- Article body extras --------------------------------------------------
   Drop cap on the opening paragraph — the one editorial signal the imported
   WordPress markup cannot supply itself. */
.prose--article > p:first-of-type::first-letter {
  float: left; font-family: var(--display); font-weight: 600;
  font-size: 3.6em; line-height: .84; padding: .06em .12em 0 0;
  color: var(--rose);
}
/* The imported copy uses <hr> liberally — several articles put one between
   every numbered item — so this stays a short centred tick rather than a
   full-width rule or a glyph: eighteen "* * *" marks down one page reads as
   confetti, not chapters. */
.prose--article hr {
  width: 56px; margin-inline: auto; margin-block: 2.6rem;
  background: var(--rose); opacity: .35;
}

/* --- Previous / next ------------------------------------------------------ */
.postnav { display: grid; gap: 1rem; }
@media (min-width: 700px) { .postnav { grid-template-columns: 1fr 1fr; } }
.postnav__item {
  display: block; padding: 1.25rem 1.4rem; min-height: 44px;
  border: 1px solid var(--line); border-radius: 20px; background: var(--paper);
  transition: border-color 260ms var(--ease-out), transform 260ms var(--ease-out);
}
.postnav__item:hover { border-color: var(--rose); transform: translateY(-3px); }
.postnav__item--next { text-align: right; grid-column: 2; }
@media (max-width: 699px) { .postnav__item--next { text-align: left; grid-column: auto; } }
.postnav__dir {
  font-size: .72rem; font-weight: 800; letter-spacing: .2em;
  text-transform: uppercase; color: var(--rose); display: block; margin-bottom: .4rem;
}

/* --------------------------------------------------------------------------
   Clinic location — one composed panel, not a map parked beside two boxes.
   The map is the panel's media half, the addresses are a divided list in the
   same surface, and a dark base bar carries the hours and the booking CTA so
   the whole thing reads as a single object (same family as .plans / .promo).
   -------------------------------------------------------------------------- */

.clinic {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 30px;
  overflow: hidden;                 /* clips the map's square corners to the radius */
  box-shadow: 0 40px 90px -58px rgba(28, 58, 23, .5);
}
.clinic__grid { display: grid; }
@media (min-width: 900px) { .clinic__grid { grid-template-columns: 1.06fr .94fr; } }

/* Absolute iframe rather than height:100% — the wrapper is aspect-ratio sized
   on phones and stretch-sized in the desktop grid row, and inset:0 covers both. */
.clinic__map { position: relative; background: var(--sand); aspect-ratio: 16 / 11; min-height: 240px; }
@media (min-width: 900px) { .clinic__map { aspect-ratio: auto; } }
.clinic__map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }
/* Google's default embed is louder than this palette; pull the saturation back
   so it sits with the cream/sage page rather than shouting over it. */
.clinic__map iframe { filter: saturate(.82) contrast(1.03); }

/* Map band at the top of the footer, so it sits right beneath the booking
   form. Slightly dimmed: Google's embed is a bright white slab against the
   forest footer otherwise. */
.footer__map {
  position: relative;
  height: clamp(150px, 24vw, 280px);
  margin-bottom: clamp(2rem, 4vw, 3rem);
  border-radius: 18px;
  overflow: hidden;
  border: 1px solid rgba(251, 250, 244, .16);
  background: var(--forest-mid);
}
.footer__map iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; display: block;
  filter: saturate(.78) contrast(1.02) brightness(.94);
}

.clinic__body { padding: clamp(1.5rem, 3vw, 2.4rem); }
.clinic__item { display: flex; gap: 1rem; padding-block: clamp(1.1rem, 2vw, 1.5rem); }
.clinic__item:first-child { padding-top: 0; }
.clinic__item:last-child  { padding-bottom: 0; }
.clinic__item + .clinic__item { border-top: 1px solid var(--line-soft); }

.clinic__pin {
  flex: none; width: 40px; height: 40px; border-radius: 999px;
  display: grid; place-items: center;
  background: rgba(161, 58, 82, .1); color: var(--rose);
}

/* Light text, so this bar owns an opaque dark background of its own. */
.clinic__foot {
  background: var(--forest-deep); color: var(--cream);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 1rem clamp(1rem, 3vw, 2rem);
  padding: 1.1rem clamp(1.5rem, 3vw, 2.4rem);
}
.clinic__hours { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.25rem; font-size: .92rem; }
.clinic__hours span { display: inline-flex; align-items: center; gap: .55rem; color: var(--on-dark-body); }
.clinic__hours svg { flex: none; color: var(--rose-soft); }
.clinic__hours a { color: var(--cream); font-weight: 700; min-height: 44px; display: inline-flex; align-items: center; }
@media (max-width: 560px) { .clinic__foot .btn { width: 100%; } }

/* --------------------------------------------------------------------------
   Reduced motion — kill movement, keep every scrap of content reachable.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .modal[open] { animation: none; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .rise { opacity: 1; transform: none; }
  .reveal-line > span { transform: none; }
  .wordwrap .word { opacity: 1; }
  .petals, .hero__scroll-track::after { display: none; }
  .rail { position: static; }
}

/* --------------------------------------------------------------------------
   Pager — blog index pagination. Hand-rolled to match the site's own pill
   language (the packaged Laravel views are Tailwind-only).
   -------------------------------------------------------------------------- */

.pager {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: .5rem; padding-top: clamp(1.5rem, 4vw, 2.5rem);
  border-top: 1px solid var(--line-soft);
}
.pager__pages { display: flex; flex-wrap: wrap; gap: .35rem; margin: 0 .35rem; }

.pager__link, .pager__page {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; min-width: 44px; padding-inline: .9rem;
  border: 1px solid var(--line); border-radius: 999px;
  font-size: .9rem; font-weight: 700; color: var(--fg); background: var(--paper);
  transition: background 240ms var(--ease-out), border-color 240ms var(--ease-out);
}
.pager__link:hover, .pager__page:hover { background: var(--sand); border-color: var(--line); }

.pager__page.is-on { background: var(--rose); border-color: var(--rose); color: #fff; }

.pager__link.is-disabled { opacity: .38; pointer-events: none; }

@media (max-width: 480px) {
  .pager__link, .pager__page { padding-inline: .7rem; font-size: .84rem; }
}

/* --------------------------------------------------------------------------
   Pillars — the four-step method on the home page.
   -------------------------------------------------------------------------- */

.pillar {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: 22px;
  padding: clamp(1.4rem, 2.4vw, 1.9rem);
}
.pillar__icon {
  display: grid; place-items: center;
  width: 56px; height: 56px; margin-bottom: 1rem;
  border-radius: 999px; background: #dfe8d3; color: var(--forest-mid);
}
.pillar__icon svg { width: 28px; height: 28px; }
.pillar:nth-child(even) .pillar__icon { background: var(--rose-soft); color: var(--rose); }

/* --------------------------------------------------------------------------
   Preloader — two curtains part left/right, badge spins in the centre.
   Runs on every page load (client's call). Kept to ~1.4s total so the wait
   stays tolerable on repeat navigation.
   -------------------------------------------------------------------------- */

.preloader {
  position: fixed; inset: 0; z-index: 999;
  display: grid; place-items: center;
  pointer-events: none;                 /* never blocks a click, even mid-animation */
}

/* The two halves. They cover the viewport, then slide apart. */
.preloader__panel {
  position: absolute; top: 0; bottom: 0; width: 50.5%;   /* .5% overlap kills the seam */
  background: var(--cream);
  will-change: transform;
  animation: curtain-l 900ms 520ms var(--ease-in-out) forwards;
}
.preloader__panel--l { left: 0; }
.preloader__panel--r { right: 0; animation-name: curtain-r; }

.preloader__mark {
  position: relative;
  width: clamp(140px, 26vw, 260px); height: auto;
  animation: mark-spin 1400ms var(--ease-in-out) forwards;
  will-change: transform, opacity;
}

@keyframes curtain-l { to { transform: translateX(-100%); } }
@keyframes curtain-r { to { transform: translateX(100%); } }

@keyframes mark-spin {
  0%   { transform: rotate(0deg)   scale(.72); opacity: 0; }
  22%  { transform: rotate(140deg) scale(1);   opacity: 1; }
  60%  { transform: rotate(330deg) scale(1);   opacity: 1; }
  100% { transform: rotate(360deg) scale(1.5); opacity: 0; }
}

/* Once finished the element is removed from the DOM by main.js; this is the
   belt-and-braces state in case the script never runs. */
.preloader.is-done { display: none; }

/* Respect reduced motion: no spin, no slide — a brief fade and out of the way.
   The global reduced-motion block below also clamps every animation to ~0s,
   which would otherwise leave the curtains stuck closed over the page. */
@media (prefers-reduced-motion: reduce) {
  .preloader { display: none; }
}

/* --------------------------------------------------------------------------
   Hero CTAs on small screens — keep both buttons on one line.
   At default size the pair wraps below ~430px; trimming the horizontal
   padding and letting them share the row keeps them side by side without
   dropping either to its own line. nowrap stops the labels breaking mid-word.
   -------------------------------------------------------------------------- */

@media (max-width: 560px) {
  .hero .flex.wrap.g-3 { flex-wrap: nowrap; gap: .6rem; }
  .hero .flex.wrap.g-3 .btn {
    flex: 1 1 0; min-width: 0;
    padding-inline: .85rem;
    font-size: .84rem;
    white-space: nowrap;
  }
  /* The arrow is decoration; drop it before the label has to shrink further. */
  .hero .flex.wrap.g-3 .btn__icon { display: none; }
}

@media (max-width: 380px) {
  .hero .flex.wrap.g-3 .btn { font-size: .78rem; padding-inline: .6rem; }
}

/* Optional-field hint in the booking form */
.field__opt { font-weight: 500; color: var(--muted); text-transform: none; letter-spacing: 0; }

/* --------------------------------------------------------------------------
   Auth screens — brand shell for sign-in. Plain CSS on the public token set
   so these pages never depend on the Vite build.
   -------------------------------------------------------------------------- */

.auth {
  min-height: 100svh; margin: 0;
  display: grid; place-items: center;
  padding: clamp(1.5rem, 5vw, 3rem);
  background:
    radial-gradient(80% 50% at 85% 0%,  #f7e6ea 0%, transparent 60%),
    radial-gradient(70% 45% at 5% 100%, #eef1e1 0%, transparent 62%),
    var(--cream);
  font-family: var(--sans); color: var(--fg);
}

.auth__shell { width: 100%; max-width: 420px; }

.auth__brand {
  display: flex; align-items: center; justify-content: center; gap: .65rem;
  margin-bottom: 1.75rem;
}
.auth__brand img { width: 52px; height: 52px; }
.auth__brand span {
  font-family: var(--display); font-weight: 600; font-size: 1.4rem;
  letter-spacing: -.02em; color: var(--forest);
}

.auth__card {
  background: var(--paper);
  border: 1px solid var(--line-soft); border-radius: 24px;
  padding: clamp(1.6rem, 4vw, 2.25rem);
  box-shadow: 0 30px 60px -40px rgba(28, 58, 23, .5);
}

.auth__title { font-family: var(--display); font-weight: 600; font-size: 1.6rem; letter-spacing: -.02em; }
.auth__sub   { color: var(--muted); font-size: .92rem; margin-top: .35rem; margin-bottom: 1.5rem; }

.auth__form { display: grid; gap: 1.1rem; }
.auth__form .btn { margin-top: .35rem; }

.auth__row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; font-size: .88rem; flex-wrap: wrap;
}
.auth__check { display: inline-flex; align-items: center; gap: .5rem; color: var(--muted); cursor: pointer; }
.auth__check input { width: 16px; height: 16px; accent-color: var(--rose); }

.auth__status,
.auth__err {
  border-radius: 12px; padding: .7rem .9rem; font-size: .88rem; margin-bottom: 1.1rem;
}
.auth__status { background: #dfe8d3; color: var(--forest-mid); }
.auth__err    { background: var(--rose-soft); color: var(--rose); }

.auth__foot { text-align: center; margin-top: 1.5rem; font-size: .88rem; }
.auth__foot a { color: var(--muted); }
.auth__foot a:hover { color: var(--rose); }

/* --------------------------------------------------------------------------
   Legal pages — privacy policy and terms. Long-form prose, so it opts out of
   the marketing rhythm and just reads well.
   -------------------------------------------------------------------------- */

.legal { max-width: 68ch; }
.legal h2 {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(1.15rem, 1.8vw, 1.4rem); letter-spacing: -.015em;
  color: var(--forest); margin-top: 2.25rem; margin-bottom: .6rem;
}
.legal h2:first-child { margin-top: 0; }
.legal p { color: var(--muted); line-height: 1.72; margin-bottom: .9rem; }
.legal ul { margin: 0 0 1.1rem; padding-left: 1.1rem; list-style: disc; }
.legal li { color: var(--muted); line-height: 1.7; margin-bottom: .35rem; }

.footer__legal { display: inline-flex; gap: 1.25rem; flex-wrap: wrap; }
.footer__legal a { text-decoration: underline; text-underline-offset: 3px; }
