/* ── Chelsea Parkhurst, CMT ───────────────────────────── */
:root{
  /* The SURFACES are warm, the STRUCTURE is sage, and one hot accent runs
     through both. That split came from sampling her own studio photographs:
     every chromatic colour in the room lands at hue 15-40 degrees — honey
     floorboards, walnut mantel, brass fireplace, the rust scroll — and the
     oat below is the single most common colour in the mantel shot at 12%.
     The greens stayed for the footer, the hours card and the small accents,
     because the page needs something cool to sit against all that warmth;
     they are simply no longer the ground. */
  --ivory:#FAF7F0;
  --cream:#F2EBDD;
  --blush:#EADFCB;
  --sand:#DCCDB2;
  /* The inks warm with the grounds. A green-grey muted tone on oat reads
     dirty the same way a brown one did on green. */
  --ink:#231C14;
  --ink-soft:#5E4E3E;
  --line:rgba(35,28,20,.15);
  --line-soft:rgba(35,28,20,.10);
  --line-light:rgba(255,255,255,.26);
  /* The two dark panels are SAGE, not brown: the footer, the hours card, the
     booking summary and the footer CTA. Picked at the same lightness the
     browns were, so every white-on-panel pairing keeps its old headroom —
     --sage carries white at 5.7:1 and --sage-deep at 9.1:1.
     The terracotta accent stays: sage and terracotta is the pairing, and
     dropping it too would leave the page with no warmth at all. */
  --mocha:#5A6B52;
  --deep:#3F4C39;
  --accent:#9C5A3C;
  /* A brighter, greener sage than the panels use, so it reads as an ACCENT
     rather than a patch of the footer that escaped. 5.56:1 on the ivory and
     5.96:1 carrying white, so it is safe for small text and filled chips.
     It ALTERNATES with the terracotta rather than replacing it — the sun
     mark, the "Most Booked" badge and every button hover stay warm, so the
     page reads two-colour instead of drifting all-green. */
  --sage:#4E6B4A;
  --serif:"Instrument Serif",Georgia,"Times New Roman",serif;
  --sans:"Instrument Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  --pad:clamp(18px,4.4vw,72px);
  --band:clamp(12px,1.6vw,22px);   /* gap between floating colour bands */
  --ease:cubic-bezier(.22,.61,.36,1);
  --r:22px;
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:92px}
body{
  margin:0;background:var(--ivory);color:var(--ink);
  font-family:var(--sans);font-size:16px;line-height:1.62;font-weight:400;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img{max-width:100%;display:block}
svg{width:1em;height:1em}
h1,h2,h3{font-family:var(--serif);font-weight:400;line-height:1.08;letter-spacing:-.02em;margin:0;text-wrap:balance}
h1 em,h2 em,h3 em{font-style:italic}
p{margin:0 0 1em}
a{color:inherit}
.sprite{position:absolute;width:0;height:0;overflow:hidden}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--ink);color:#fff;padding:14px 20px;font-size:13px;letter-spacing:.08em;text-transform:uppercase}
.skip:focus{left:0}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}
.eyebrow{font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--sage);margin:0 0 18px}
.muted{color:var(--ink-soft);font-size:14px;margin:0}

/* reveal */
.r{opacity:0;transform:translateY(22px);transition:opacity .85s var(--ease),transform .85s var(--ease)}
.r.in{opacity:1;transform:none}

/* buttons */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  font-family:var(--sans);font-size:13px;font-weight:500;letter-spacing:.01em;
  padding:13px 26px;border-radius:999px;border:1px solid var(--ink);
  background:var(--ink);color:var(--ivory);text-decoration:none;cursor:pointer;
  transition:background .3s var(--ease),color .3s var(--ease),border-color .3s var(--ease),transform .3s var(--ease);
}
.btn svg{width:17px;height:17px;flex:none}
.btn:hover{background:var(--accent);border-color:var(--accent);color:#fff;transform:translateY(-1px)}
.btn--ghost{background:transparent;color:var(--ink);border-color:var(--line)}
.btn--ghost:hover{background:var(--ink);border-color:var(--ink);color:var(--ivory)}
.btn--light{background:var(--ivory);border-color:var(--ivory);color:var(--ink)}
.btn--light:hover{background:var(--accent);border-color:var(--accent);color:#fff}
.btn--outline-light{background:transparent;border-color:var(--line-light);color:#fff}
.btn--outline-light:hover{background:#fff;border-color:#fff;color:var(--ink)}
.btn--pill{font-size:12.5px;padding:12px 22px}
.btn--block{width:100%;margin-top:28px}
.more{
  display:inline-flex;align-items:center;gap:8px;font-size:13.5px;text-decoration:none;
  border-bottom:1px solid var(--line);padding-bottom:4px;transition:gap .3s var(--ease),border-color .3s var(--ease);
}
.more svg{width:15px;height:15px}
.more:hover{gap:13px;border-color:var(--ink)}

/* wordmark */
.mark{display:inline-flex;align-items:center;gap:9px;text-decoration:none;white-space:nowrap}
.mark__sun{width:17px;height:17px;fill:currentColor;color:var(--accent);flex:none}
.mark span{font-family:var(--serif);font-size:20px;letter-spacing:.005em}
.mark em{font-family:var(--sans);font-style:normal;font-size:10px;letter-spacing:.2em;text-transform:uppercase;opacity:.55;padding-top:3px}
.mark--light{color:#fff}
.mark--light .mark__sun{color:#fff}

/* ── sticky topbar ── */
.topbar{
  position:fixed;top:0;left:0;right:0;z-index:60;background:rgba(250,247,240,.93);
  backdrop-filter:blur(14px);border-bottom:1px solid var(--line-soft);
  transform:translateY(-101%);transition:transform .45s var(--ease);
}
.topbar.show{transform:none}
.topbar__in{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:12px var(--pad);max-width:1600px;margin:0 auto}
.topbar__nav{display:flex;gap:30px}
.topbar__nav a{text-decoration:none;font-size:13.5px;color:var(--ink-soft);transition:color .3s var(--ease)}
.topbar__nav a:hover{color:var(--ink)}
.topbar__end{display:flex;align-items:center;gap:10px}
.burger{display:none;background:none;border:0;cursor:pointer;padding:8px}
.burger__box{display:block;width:24px}
.burger__box i{display:block;height:1.5px;background:currentColor;margin:5px 0;border-radius:2px;transition:transform .35s var(--ease)}
.burger[aria-expanded="true"] .burger__box i:first-child{transform:translateY(3.25px) rotate(45deg)}
.burger[aria-expanded="true"] .burger__box i:last-child{transform:translateY(-3.25px) rotate(-45deg)}

.drawer{position:fixed;inset:0;z-index:55;background:var(--ivory);padding:96px var(--pad) 36px;display:flex;flex-direction:column;justify-content:space-between}
.drawer[hidden]{display:none}
.drawer nav{display:flex;flex-direction:column;gap:2px}
.drawer nav a{font-family:var(--serif);font-size:clamp(28px,8vw,42px);text-decoration:none;padding:5px 0}
.drawer__cta{font-family:var(--sans)!important;font-size:13px!important;letter-spacing:.02em;margin-top:16px;border-top:1px solid var(--line);padding-top:20px!important}
.drawer__meta{font-size:14px;color:var(--ink-soft);line-height:1.9}
.drawer__meta a{text-decoration:none}

/* ── hero ── */
.hero{padding:clamp(12px,1.6vw,22px)}
.hero__card{
  position:relative;border-radius:var(--r);overflow:hidden;
  min-height:min(90svh,860px);display:flex;flex-direction:column;justify-content:space-between;
}
.hero__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 42%;
  filter:saturate(.95) contrast(1.02) brightness(.96);transform:scale(1.06);will-change:transform}
.hero__scrim{position:absolute;inset:0;background:
  linear-gradient(180deg,rgba(28,18,13,.5) 0%,rgba(28,18,13,.14) 26%,rgba(26,17,12,.42) 62%,rgba(20,13,9,.84) 100%),
  linear-gradient(90deg,rgba(24,15,11,.62) 0%,rgba(24,15,11,.2) 44%,transparent 70%)}
.hero__bar{position:relative;z-index:2;display:flex;align-items:center;justify-content:space-between;gap:24px;padding:clamp(18px,2.2vw,30px) clamp(20px,2.6vw,40px)}
.hero__nav{display:flex;gap:clamp(18px,2.4vw,38px)}
.hero__nav a{text-decoration:none;color:rgba(255,255,255,.86);font-size:13.5px;transition:color .3s var(--ease)}
.hero__nav a:hover{color:#fff}
.hero__copy{position:relative;z-index:2;padding:0 clamp(20px,2.6vw,44px) clamp(28px,4vw,54px);max-width:1100px}
.hero__intro{color:rgba(255,255,255,.88);font-size:15px;max-width:46ch;margin:0 0 22px}
.hero h1{color:#fff;font-size:clamp(42px,8vw,104px);letter-spacing:-.025em}
.hero h1 em{color:var(--blush)}

/* The scroll cue. A hairline rail with a lit segment travelling down it —
   quiet enough for a massage practice, clear enough to say "there is more".
   Desktop parks it in the hero's bottom-right corner; on a phone the copy
   already owns the bottom of the card, so it sits centred underneath. */
.hero__scroll{
  position:absolute;right:clamp(20px,2.6vw,44px);bottom:clamp(28px,4vw,54px);z-index:3;
  display:flex;flex-direction:column;align-items:center;gap:11px;
  background:none;border:0;padding:6px;cursor:pointer;font:inherit;
  font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;
  color:rgba(255,255,255,.7);
  transition:color .3s var(--ease),opacity .5s var(--ease),visibility .5s var(--ease);
}
.hero__scroll:hover{color:#fff}
.hero__scroll.gone{opacity:0;visibility:hidden}
.hero__rail{position:relative;display:block;width:1px;height:46px;background:rgba(255,255,255,.26);overflow:hidden}
.hero__rail i{position:absolute;left:0;top:0;width:1px;height:15px;background:#fff;
  animation:hero-rail 2.4s var(--ease) infinite}
@keyframes hero-rail{
  0%  {transform:translateY(-15px);opacity:0}
  28% {opacity:1}
  100%{transform:translateY(46px);opacity:0}
}

/* ── approach ── */
.approach{padding:clamp(60px,8vw,120px) var(--pad) clamp(50px,6vw,90px);position:relative;max-width:1180px;margin:0 auto;text-align:center}
.approach__head h2{font-size:clamp(30px,5.2vw,68px);display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:clamp(10px,1.6vw,24px)}
.approach__chip{width:clamp(110px,15vw,208px);height:clamp(50px,6.4vw,88px);object-fit:cover;border-radius:999px;flex:none}
.approach__body{max-width:52ch;margin:clamp(24px,3vw,40px) auto 0;display:flex;flex-direction:column;align-items:center;gap:16px}
.approach__body p{color:var(--ink-soft);margin:0}
.approach__motif{position:absolute;right:clamp(10px,8vw,140px);bottom:clamp(20px,4vw,64px);width:clamp(64px,8vw,116px);height:clamp(64px,8vw,116px);fill:var(--sand);z-index:-1}

/* ── section heads ── */
.sec-head{max-width:660px;margin:0 auto clamp(34px,4vw,58px);text-align:center}
.sec-head--left{margin-left:0;margin-right:0;text-align:left;max-width:720px}
.sec-head h2{font-size:clamp(28px,4.2vw,52px);margin-bottom:16px}
.sec-head h2 em{color:var(--mocha)}
.sec-head p{color:var(--ink-soft);font-size:15px;margin:0}

/* ── treatment cards ── */
.treatments{padding:clamp(50px,6vw,90px) var(--pad) clamp(60px,7vw,110px);max-width:1400px;margin:0 auto}
.tcards{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:clamp(16px,2vw,26px)}
.tcard{
  background:var(--cream);border:1px solid var(--line-soft);border-radius:16px;
  padding:clamp(24px,2.6vw,34px);position:relative;display:flex;flex-direction:column;
  transition:transform .5s var(--ease),box-shadow .5s var(--ease);
}
.tcard:hover{transform:translateY(-4px);box-shadow:0 18px 44px rgba(60,42,32,.09)}
.tcard__sun{position:absolute;top:clamp(20px,2.4vw,30px);right:clamp(20px,2.4vw,30px);width:30px;height:30px;fill:var(--sand)}
.tcard h3{font-size:clamp(21px,2.3vw,28px);margin:0 0 16px;padding-right:44px;padding-bottom:16px;border-bottom:1px solid var(--line)}
.tcard p{color:var(--ink-soft);font-size:14.5px;margin:0 0 22px}
.tcard .more{margin-top:auto;align-self:flex-start}

/* ── services & rates ── */
.services{padding:clamp(56px,7vw,110px) var(--pad);background:var(--cream)}
.menu{border-top:1px solid var(--line);max-width:1400px;margin:0 auto}
.svc{border-bottom:1px solid var(--line)}
.svc__head{width:100%;background:none;border:0;cursor:pointer;text-align:left;font:inherit;color:inherit;
  display:grid;grid-template-columns:auto 1fr auto auto;align-items:baseline;gap:clamp(12px,2vw,28px);
  padding:clamp(18px,2.1vw,26px) 2px;transition:opacity .3s var(--ease)}
.svc__head:hover{opacity:.6}
.svc__idx{font-size:11px;letter-spacing:.14em;color:var(--ink-soft);width:2.2em}
.svc__name{font-family:var(--serif);font-size:clamp(20px,2.7vw,34px);line-height:1.12}
.svc__from{font-size:12px;color:var(--ink-soft);white-space:nowrap}
.svc__plus{width:26px;height:26px;border:1px solid var(--line);border-radius:50%;position:relative;flex:none;transition:transform .45s var(--ease),background .45s var(--ease)}
.svc__plus::before,.svc__plus::after{content:"";position:absolute;inset:50% 7px;height:1px;background:var(--ink)}
.svc__plus::after{transform:rotate(90deg)}
.svc[data-open="true"] .svc__plus{transform:rotate(135deg);background:var(--sand)}
.svc__panel{overflow:hidden;height:0;transition:height .5s var(--ease)}
.svc__inner{padding:0 2px clamp(24px,2.8vw,36px) calc(2.2em + clamp(12px,2vw,28px));display:grid;grid-template-columns:minmax(240px,1.1fr) minmax(260px,1fr);gap:clamp(20px,4vw,56px);align-items:start}
.svc__desc{color:var(--ink-soft);font-size:14.5px;margin:0;max-width:46ch}
.rates{list-style:none;margin:0;padding:0}
.rates li{display:flex;align-items:baseline;gap:12px;padding:9px 0;border-bottom:1px dotted var(--line)}
.rates li:last-child{border-bottom:0}
.rates b{font-weight:400;font-size:14px;white-space:nowrap}
.rates i{flex:1;height:1px;background:var(--line);font-style:normal}
.rates span{font-family:var(--serif);font-size:19px}
.addons{max-width:1400px;margin:clamp(40px,5vw,68px) auto 0;background:var(--ivory);border-radius:16px;padding:clamp(24px,3vw,44px);display:grid;grid-template-columns:minmax(200px,.75fr) 1.45fr;gap:clamp(22px,4vw,52px)}
.addons__head h3{font-size:clamp(22px,2.6vw,32px);margin-bottom:10px}
.addons__head p{color:var(--ink-soft);font-size:14.5px;margin:0}
.addons__list{list-style:none;margin:0;padding:0}
.addons__list li{display:flex;align-items:baseline;gap:14px;padding:12px 0;border-bottom:1px solid var(--line-soft)}
.addons__list li:last-child{border-bottom:0}
.addons__list b{font-weight:400;font-size:14.5px}
.addons__list i{flex:1;height:1px;background:var(--line-soft);font-style:normal}
.addons__list span{font-family:var(--serif);font-size:18px;white-space:nowrap}
.addons__list small{display:block;font-size:12.5px;color:var(--ink-soft)}

/* ── session plans ── */
.sessions{padding:clamp(56px,7vw,110px) var(--pad);max-width:1400px;margin:0 auto}
.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:clamp(16px,2vw,24px);align-items:stretch}
.plan{background:var(--ivory);border:1px solid var(--line);border-radius:16px;padding:clamp(24px,2.6vw,34px);position:relative;display:flex;flex-direction:column}
.plan--feature{background:var(--cream);border-color:transparent;box-shadow:0 20px 50px rgba(60,42,32,.10)}
.plan__badge{position:absolute;top:-13px;left:clamp(24px,2.6vw,34px);background:var(--accent);color:#fff;font-size:11.5px;font-weight:500;padding:5px 13px;border-radius:999px}
.plan h3{font-size:clamp(22px,2.4vw,29px);margin-bottom:10px}
.plan__note{color:var(--ink-soft);font-size:14px;margin:0 0 20px;min-height:2.8em}
.plan__price{display:flex;align-items:baseline;gap:7px;margin:0 0 20px;padding-bottom:20px;border-bottom:1px solid var(--line)}
.plan__price strong{font-family:var(--serif);font-weight:400;font-size:clamp(32px,3.6vw,44px);letter-spacing:-.02em}
.plan__price span{color:var(--ink-soft);font-size:13.5px}
/* flex:1 so the list absorbs the card's spare height and the button is
   pushed to the bottom. Without it the button sat immediately under the last
   item, so three cards with different amounts of wrapped text put their
   buttons at three different heights — and the middle card, having the most
   text, ended up with almost no gap above its own. */
/* flex:1 0 auto, NOT flex:1. `flex:1` is `1 1 0%` — a zero basis that lets
   the list shrink below its own content, so in the tallest card the items
   overflowed and the button sat right on top of the last one. Growing
   without shrinking keeps every card's button clear of its list. */
/* padding-bottom, not a margin on the button: the list is a grown flex item,
   and in the TALLEST card its content reaches the list's own bottom edge, so
   the button — which starts exactly there — ended up touching the last line.
   Padding lives inside the list's box, so the gap survives however the flex
   line is sized. (An earlier attempt put this in a separate rule ABOVE this
   one, where `padding:0` here promptly reset it.) */
.plan ul{list-style:none;margin:0;padding:0 0 28px;display:grid;gap:13px;flex:1 0 auto;align-content:start}
.plan li{display:flex;gap:11px;align-items:flex-start;font-size:14.5px;color:var(--ink-soft)}
.plan li svg{width:19px;height:19px;flex:none;margin-top:2px;color:var(--sage)}
.plan .btn{margin-top:auto}

.packs{margin-top:clamp(34px,4vw,54px);background:var(--blush);border-radius:16px;padding:clamp(24px,3vw,38px);text-align:center}
.packs__lead{font-family:var(--serif);font-size:clamp(20px,2.4vw,28px);margin:0 0 22px}
.packs ul{list-style:none;margin:0 0 18px;padding:0;display:flex;flex-wrap:wrap;justify-content:center;gap:clamp(12px,2vw,24px)}
.packs li{display:flex;align-items:baseline;gap:8px;background:var(--ivory);border-radius:999px;padding:11px 22px;font-size:14px;color:var(--ink-soft)}
.packs b{font-family:var(--serif);font-weight:400;font-size:24px;color:var(--ink)}
.packs span{color:var(--sage)}
.packs__note{font-size:13.5px;color:var(--ink-soft);margin:0}

/* ── about ── */
.about{display:grid;grid-template-columns:minmax(260px,.8fr) 1.2fr;gap:clamp(28px,5vw,72px);align-items:center;
  padding:clamp(56px,7vw,110px) var(--pad);max-width:1400px;margin:0 auto}
/* height:auto is doing real work here. The <img> carries width/height
   ATTRIBUTES (so the browser can reserve the box before the file lands), and
   with only `width:100%` in CSS the attribute height stays in force — the
   portrait rendered 481x1124 against a natural 900x1124 and the face was
   squeezed to 60% of its true width. Any img given a CSS width needs the
   matching height:auto or the attributes fight it. */
.about__media img,.meet__media img{width:100%;height:auto;border-radius:16px;filter:saturate(.94)}
.about__body h2,.meet__body h2{font-size:clamp(27px,3.6vw,46px);margin-bottom:22px}
.about__body h2 em,.meet__body h2 em{color:var(--mocha)}
.about__text,.meet__text{color:var(--ink-soft);max-width:56ch;font-size:15.5px}
.timeline{list-style:none;margin:30px 0 0;padding:0;border-top:1px solid var(--line)}
.timeline li{display:grid;grid-template-columns:5em 1fr;gap:16px;padding:12px 0;border-bottom:1px solid var(--line-soft);font-size:14.5px;color:var(--ink-soft)}
.timeline span{font-family:var(--serif);font-size:15px;color:var(--ink)}

/* ── meet Chelsea (home only) ──
   She is the whole product — one practitioner, no staff — and after the tabs
   split the site her face only survived on /about, so the home page sold a
   practice with nobody in it. This is the short version: portrait, two lines
   of provenance, and a link through to the full story.
   Portrait sits RIGHT here and LEFT on /about, so the two pages do not read
   as the same band twice. Full-bleed cream separates it from the plain
   treatments block above and the blush testimonials below. */
.meet{background:var(--cream)}
.meet__in{display:grid;grid-template-columns:1.2fr minmax(240px,.75fr);
  gap:clamp(28px,5vw,72px);align-items:center;
  padding:clamp(52px,6.5vw,100px) var(--pad);max-width:1400px;margin:0 auto}
.meet__body h2{margin-bottom:18px}
.meet__text p:last-child{margin-bottom:0}
.meet .more{margin-top:26px}
/* Same trap as the /about portrait: the img carries width/height ATTRIBUTES,
   so a CSS width without height:auto lets the attribute ratio win. */
.meet__media img{border-radius:16px}

/* ── coloured bands float ─────────────────────────────────
   Every section that carries its own colour is an inset rounded card with
   the same gap and the same radius as the hero at the top of the page and
   the footer at the bottom. Nothing on the site butts one colour straight
   against another any more.

   Adjacent bands collapse their vertical margins, so two cards in a row are
   separated by ONE gap, not two — which is why this is a margin and not a
   wrapper with padding. Sections with no background of their own are left
   full-bleed: there is no edge to show. */
.meet,.words,.services,.studio{
  margin:var(--band) clamp(12px,1.6vw,22px);
  border-radius:var(--r);
  overflow:hidden;
}

/* ── testimonials ── */
.words{background:var(--blush);padding:clamp(56px,7vw,104px) var(--pad);text-align:center}
.words h2{font-size:clamp(28px,4.2vw,52px);margin-bottom:clamp(28px,3.4vw,48px)}
.quotes{max-width:70ch;margin:0 auto;position:relative;min-height:12em}
.quote{position:absolute;inset:0;opacity:0;transition:opacity .6s var(--ease);pointer-events:none}
.quote.on{opacity:1;position:relative;pointer-events:auto}
.quote p{font-size:clamp(16px,1.7vw,19px);color:var(--ink-soft);line-height:1.72}
.quote cite{font-style:normal;font-weight:500;font-size:14px;color:var(--ink)}
.quotes__dots{display:flex;justify-content:center;gap:9px;margin-top:26px}
.quotes__dots button{width:8px;height:8px;padding:0;border-radius:50%;border:1px solid var(--ink-soft);background:transparent;cursor:pointer;transition:background .3s var(--ease)}
.quotes__dots button[aria-selected="true"]{background:var(--ink);border-color:var(--ink)}

/* ── booking form ── */
.book{padding:clamp(56px,7vw,110px) var(--pad);background:var(--cream)}
.book__grid{display:grid;grid-template-columns:1.55fr .85fr;gap:clamp(20px,2.4vw,40px);align-items:start;max-width:1400px;margin:0 auto}
.form{background:var(--ivory);border:1px solid var(--line-soft);border-radius:16px;padding:clamp(22px,3vw,44px)}
.steps{display:flex;gap:8px;list-style:none;margin:0 0 clamp(24px,3vw,36px);padding:0 0 20px;border-bottom:1px solid var(--line);flex-wrap:wrap}
.steps li{display:flex;align-items:center;gap:9px;font-size:13px;color:var(--ink-soft);opacity:.5;padding-right:14px}
.steps li span{width:24px;height:24px;border:1px solid currentColor;border-radius:50%;display:grid;place-items:center;font-size:11.5px}
.steps li[aria-current="step"]{opacity:1;color:var(--ink)}
.steps li[aria-current="step"] span{background:var(--ink);color:#fff;border-color:var(--ink)}
.steps li.done{opacity:1;color:var(--sage)}
.step{border:0;padding:0;margin:0;min-width:0}
.step[hidden]{display:none}
.step__legend{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.step__nav{display:flex;gap:12px;flex-wrap:wrap;margin-top:30px;padding-top:24px;border-top:1px solid var(--line)}
.field{margin-bottom:24px;min-width:0}
.row{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.label{display:block;font-size:12.5px;color:var(--ink-soft);margin-bottom:11px}
.label b{color:var(--accent)}
.label small{font-size:12px;opacity:.75;margin-left:6px}
input[type=text],input[type=email],input[type=tel],input[type=date],input:not([type]),textarea{
  width:100%;font:inherit;font-size:16px;color:var(--ink);background:var(--cream);
  border:1px solid var(--line);border-radius:10px;padding:12px 14px;transition:border-color .3s var(--ease),background .3s var(--ease)}
input:focus,textarea:focus{background:#fff;border-color:var(--mocha)}
textarea{resize:vertical;line-height:1.6}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{position:relative}
.chip input{position:absolute;opacity:0;width:100%;height:100%;left:0;top:0;margin:0;cursor:pointer}
.chip span{display:block;padding:10px 17px;border:1px solid var(--line);border-radius:999px;font-size:13.5px;cursor:pointer;transition:all .3s var(--ease);background:var(--cream)}
.chip span small{display:block;font-size:11.5px;opacity:.62;margin-top:1px}
.chip:hover span{border-color:var(--mocha)}
.chip input:checked+span{background:var(--sage);color:var(--ivory);border-color:var(--sage)}
.chip input:focus-visible+span{outline:2px solid var(--accent);outline-offset:2px}
.field--check{display:flex;gap:12px;align-items:flex-start}
.field--check input{margin-top:4px;width:17px;height:17px;accent-color:var(--accent);flex:none}
.field--check label{font-size:14px;color:var(--ink-soft)}
.hint{font-size:13px;color:var(--ink-soft);margin:8px 0 0}
.err{font-size:13px;color:#8E2F1E;margin:8px 0 0}
.err::before{content:"— "}
.summary{position:sticky;top:96px;background:var(--deep);color:#fff;border-radius:16px;padding:clamp(22px,2.4vw,32px)}
.summary__eyebrow{font-size:11px;letter-spacing:.2em;text-transform:uppercase;opacity:.7;margin:0 0 14px}
.summary__svc{font-family:var(--serif);font-size:clamp(23px,2.3vw,30px);line-height:1.15;margin:0 0 5px}
.summary__dur{font-size:13px;opacity:.75;margin:0 0 18px}
.summary__addons{list-style:none;margin:0 0 18px;padding:0;display:grid;gap:7px}
.summary__addons li{display:flex;justify-content:space-between;gap:12px;font-size:13px;opacity:.85;border-bottom:1px dotted var(--line-light);padding-bottom:7px}
.summary__total{display:flex;justify-content:space-between;align-items:baseline;gap:12px;border-top:1px solid var(--line-light);padding-top:16px}
.summary__total span{font-size:12.5px;opacity:.78}
.summary__total strong{font-family:var(--serif);font-weight:400;font-size:clamp(28px,3vw,38px)}
.summary__fine{font-size:12.5px;opacity:.7;margin:13px 0 0;line-height:1.6}
.summary__contact{margin-top:20px;padding-top:16px;border-top:1px solid var(--line-light);display:grid;gap:7px;font-size:13px;opacity:.85}
.summary__contact a{font-family:var(--serif);font-size:20px;text-decoration:none}
.done{text-align:center;padding:clamp(18px,4vw,48px) 0}
.done__sun{width:36px;height:36px;fill:var(--accent);margin:0 auto 16px}
.done h3{font-size:clamp(24px,3vw,36px);margin-bottom:14px}
.done p{color:var(--ink-soft);max-width:46ch;margin-left:auto;margin-right:auto}
.done__sub{font-size:14px}
.done .btn{margin-top:16px}

/* ── faq ── */
.faq{padding:clamp(56px,7vw,110px) var(--pad);max-width:1000px;margin:0 auto}
.faq__list{border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{list-style:none;cursor:pointer;padding:20px 44px 20px 0;position:relative;font-size:16px;font-weight:500;transition:color .3s var(--ease)}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--sage)}
.faq summary::after,.faq summary::before{content:"";position:absolute;right:6px;top:50%;width:12px;height:1.5px;background:var(--ink);border-radius:2px;transition:transform .35s var(--ease),opacity .35s var(--ease)}
.faq summary::before{transform:rotate(90deg)}
.faq details[open] summary::before{opacity:0;transform:rotate(0)}
.faq details p{color:var(--ink-soft);font-size:14.5px;max-width:76ch;padding:0 44px 24px 0;margin:0}

/* ── studio ── */
.studio{padding:clamp(56px,7vw,110px) var(--pad);background:var(--cream)}
.studio__head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:18px;max-width:1400px;margin:0 auto clamp(28px,3vw,44px)}
.studio__head h2{font-size:clamp(28px,4.2vw,52px)}
.gallery{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:clamp(16px,2vw,26px);max-width:1400px;margin:0 auto}
.gallery figure{margin:0}
.gallery img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;border-radius:16px;filter:saturate(.92) contrast(1.03);transition:transform .8s var(--ease)}
.gallery figure:hover img{transform:scale(1.02)}
.gallery figcaption{margin-top:16px;font-size:14px;color:var(--ink-soft)}
.gallery figcaption strong{display:block;font-family:var(--serif);font-weight:400;font-size:19px;color:var(--ink);margin-bottom:5px}

/* ── visit ── */
.visit{display:grid;grid-template-columns:.85fr 1.15fr;gap:clamp(20px,2.4vw,32px);padding:clamp(56px,7vw,110px) var(--pad);max-width:1400px;margin:0 auto}
.visit__hours{background:var(--mocha);color:#fff;border-radius:16px;padding:clamp(26px,3vw,42px)}
.visit__hours h2{font-size:clamp(26px,3vw,38px);margin-bottom:24px}
.visit__hours dl{margin:0 0 22px}
.visit__hours dl div{display:flex;justify-content:space-between;gap:16px;padding:13px 0;border-bottom:1px solid var(--line-light)}
.visit__hours dt{font-size:14px}
.visit__hours dd{margin:0;font-family:var(--serif);font-size:18px}
.visit__note{font-size:14px;opacity:.82;margin:0}
.visit__policy{background:var(--sand);border-radius:16px;padding:clamp(26px,3vw,42px)}
.visit__policy h3{font-size:clamp(22px,2.6vw,32px);margin-bottom:16px}
.visit__policy p{color:var(--ink-soft);font-size:14.5px;max-width:58ch}
.visit__policy ul{list-style:none;margin:20px 0;padding:0;display:grid;gap:14px;max-width:62ch}
.visit__policy li{font-size:14.5px;color:var(--ink-soft);padding-left:20px;position:relative}
.visit__policy li::before{content:"";position:absolute;left:0;top:.62em;width:6px;height:6px;border-radius:50%;background:var(--sage)}
.visit__policy strong{color:var(--ink);font-weight:500}
.visit__thanks{font-family:var(--serif);font-size:19px;color:var(--ink);margin:0}

/* ── footer ── */
/* Inset on all FOUR sides, like the hero card at the top of the page — the
   two bookend each other. It used to be `margin:0 <gap>` with the bottom
   corners squared off, so the panel sat inset at the sides and then ran
   straight off the bottom of the document: it read as cut off rather than
   as a card. The TOP gap matters just as much: without it the green panel
   butted straight onto the blush testimonials on the home page and onto
   the CTA band on every tab, so its rounded top corners sat on a coloured
   ground and the card had no edge. Same gap all round, same radius all
   round, on every page. */
.foot{background:var(--mocha);color:var(--ivory);border-radius:var(--r);margin:clamp(12px,1.6vw,22px);padding:clamp(34px,4vw,54px) clamp(22px,3vw,48px) 22px}
.foot__top{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:20px;padding-bottom:clamp(30px,4vw,50px);border-bottom:1px solid var(--line-light)}
.foot__nav{display:flex;flex-wrap:wrap;gap:clamp(16px,2.4vw,34px)}
.foot__nav a{text-decoration:none;font-size:13.5px;opacity:.82;transition:opacity .3s var(--ease)}
.foot__nav a:hover{opacity:1}
.foot__grid{display:grid;grid-template-columns:1fr minmax(300px,.85fr);gap:clamp(26px,4vw,60px);padding:clamp(32px,4vw,52px) 0}
.foot__contact h2{font-size:clamp(24px,3vw,36px);margin-bottom:16px}
.foot__contact address{font-style:normal;font-size:14.5px;opacity:.82;margin-bottom:22px;line-height:1.7}
.foot__links{list-style:none;margin:0;padding:0;display:grid;gap:11px}
.foot__links a{font-size:14px;opacity:.85;text-decoration:none;display:inline-flex;align-items:center;gap:9px;transition:opacity .3s var(--ease)}
.foot__links svg{width:28px;height:28px;padding:6px;border-radius:50%;border:1px solid var(--line-light);flex:none;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;transition:background .3s var(--ease)}
.foot__links a:hover svg{background:rgba(255,255,255,.12)}
.foot__links a:hover{opacity:1}
.foot__cta{background:var(--deep);border-radius:16px;padding:clamp(24px,2.6vw,34px);align-self:start}
.foot__cta h3{font-size:clamp(22px,2.4vw,30px);margin-bottom:14px}
.foot__cta p{font-size:14.5px;opacity:.82;margin-bottom:22px}
.foot__bar{display:flex;justify-content:space-between;gap:18px;flex-wrap:wrap;padding-top:20px;border-top:1px solid var(--line-light);font-size:12.5px;opacity:.66}
.foot__bar p{margin:0}

/* ── responsive ── */
@media (max-width:1080px){
  .book__grid{grid-template-columns:1fr}
  .summary{position:static;order:-1}
  .about{grid-template-columns:1fr}
  .about__media{max-width:420px}
  /* Stacked, the portrait leads — a face above the text, not marooned under it. */
  .meet__in{grid-template-columns:1fr}
  .meet__media{max-width:420px;order:-1}
  .visit{grid-template-columns:1fr}
  .addons{grid-template-columns:1fr}
  .foot__grid{grid-template-columns:1fr}
}
@media (max-width:900px){
  .hero__nav,.topbar__nav{display:none}
  .burger{display:block}
  .hero__bar{display:none}
  .topbar{transform:none;background:rgba(250,247,240,.94)}
  .hero{padding-top:66px}
  /* Shorter than it was. At 78svh the hero filled the phone completely and
     the page looked like it ended there; this leaves a band of the next
     section showing, which does half the work of the scroll cue. */
  .hero__card{min-height:min(70svh,620px);justify-content:flex-end}
  .hero__img{object-position:68% 45%}
  /* HEADLINE FIRST. Source order puts the standfirst above the h1, which
     works beside it on a wide screen but means a phone opens with four
     dense lines of body copy before it says what the place is called. */
  .hero__copy{display:flex;flex-direction:column;padding-bottom:14px}
  .hero__copy h1{order:-1;margin-bottom:13px}
  .hero__intro{font-size:14.5px;line-height:1.5;margin:0}
  .hero__scroll{position:static;align-self:center;margin:0 auto clamp(20px,5vw,30px);gap:9px}
  .hero__rail{height:34px}
  .svc__head{grid-template-columns:1fr auto;row-gap:5px}
  .svc__idx{display:none}
  .svc__from{grid-column:1}
  .svc__inner{grid-template-columns:1fr;padding-left:2px}
  .row{grid-template-columns:1fr}
  .approach__head h2{display:block}
  .approach__chip{display:inline-block;vertical-align:middle;margin:0 6px}
}
@media (max-width:560px){
  /* 11px eyebrows and 12.5px buttons are fine on a desktop at arm's length
     and mean squinting on a phone. Nudged up, letter-spacing eased slightly
     so the uppercase labels do not get wider at the same time. */
  .eyebrow{font-size:12px;letter-spacing:.18em}
  .btn--pill{font-size:13.5px;padding:13px 22px}
  .sec-head p,.about__text,.meet__text{font-size:16px}
  .foot__bar{font-size:13px}
  .plan__badge{font-size:12px}
  .hero__scroll{font-size:11px}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important}
  .r{opacity:1;transform:none}
  .hero__img{transform:scale(1.02)!important}
  .hero__rail i{animation:none;top:auto;bottom:0;height:46px;opacity:.55}
}

/* ── mobile ───────────────────────────────────────────── */
@media (max-width:1080px){
  /* the estimate becomes a compact bar pinned to the bottom of the viewport */
  .summary{
    order:1;position:sticky;bottom:10px;margin-top:18px;
    display:grid;grid-template-columns:1fr auto;align-items:center;column-gap:14px;
    padding:14px 18px;border-radius:14px;box-shadow:0 12px 34px rgba(31,25,22,.28);
  }
  .summary:not(.has){display:none}
  .summary__eyebrow,.summary__addons,.summary__fine,.summary__contact{display:none}
  .summary__svc{grid-column:1;grid-row:1;font-size:18px;margin:0;line-height:1.2}
  .summary__dur{grid-column:1;grid-row:2;margin:0;font-size:12.5px}
  .summary__total{grid-column:2;grid-row:1/3;flex-direction:column;align-items:flex-end;
    border:0;padding:0;gap:0;text-align:right}
  .summary__total span{font-size:10.5px;letter-spacing:.14em;text-transform:uppercase}
  .summary__total strong{font-size:28px;line-height:1}
}
@media (max-width:900px){
  /* her studio photos are 320px wide — don't stretch them past that */
  .gallery{max-width:380px;margin-inline:auto}
  .plan__note{min-height:0}
  .chip span{padding:12px 18px}
  .quotes__dots button{width:24px;height:24px;border:0;background:none;display:grid;place-items:center}
  .quotes__dots button::before{content:"";width:8px;height:8px;border-radius:50%;border:1px solid var(--ink-soft)}
  .quotes__dots button[aria-selected="true"]{background:none}
  .quotes__dots button[aria-selected="true"]::before{background:var(--ink);border-color:var(--ink)}
  .studio__head{align-items:flex-start;flex-direction:column}
  .foot__cta{margin-top:4px}
}
@media (max-width:520px){
  :root{--r:16px}
  .tcard h3,.plan h3{padding-right:38px}
  .approach__chip{width:132px;height:56px}
  .packs li{padding:10px 16px}
  .foot__bar{gap:8px}
  .svc__head{padding:16px 2px}
}
html{-webkit-tap-highlight-color:rgba(156,90,60,.15)}

/* ── Booking handoff ──────────────────────────────────────
   Shown after the form is completed. The request goes out as a text from the
   client's own phone, so this panel exists for desktop, where an sms: link
   usually does nothing — the message is on screen with somewhere to send it
   rather than a dead button. */
.handoff{
  margin:22px auto 26px;
  max-width:34rem;
  text-align:left;
}
.handoff__text{
  width:100%;
  padding:14px 16px;
  border:1px solid rgba(58,42,32,.22);
  border-radius:14px;
  background:rgba(255,255,255,.62);
  font:inherit;
  font-size:.92rem;
  line-height:1.55;
  color:inherit;
  resize:vertical;
}
.handoff__acts{
  display:flex;
  flex-wrap:wrap;
  gap:10px;
  margin-top:14px;
}
.handoff__note{
  margin-top:12px;
  font-size:.82rem;
  opacity:.72;
}

/* `hidden` is a UA rule of `display:none`, which ANY class that sets display
   beats — .btn is inline-flex, so the hidden "Email instead" button rendered
   anyway. This is the guard for every hidden element on the page, not just
   that one. */
[hidden]{ display:none !important; }

/* ── Tab pages ────────────────────────────────────────────
   Interior tabs open on a compact header rather than the home page's
   full-bleed hero: the site's name as an eyebrow, the page's own H1, and one
   line of orientation. Sized so the section underneath still lands above the
   fold on a laptop. */
.pagehead{
  padding:clamp(118px,13vw,168px) var(--pad) clamp(30px,4vw,54px);
  background:var(--ivory);
}
.pagehead__in{max-width:1400px;margin:0 auto}
.pagehead h1{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(36px,6vw,68px);line-height:1.04;
  letter-spacing:-.01em;margin:0;
}
.pagehead__sub{
  margin:16px 0 0;max-width:52ch;
  font-size:clamp(15px,1.5vw,18px);color:var(--ink-soft);
}

/* An interior tab has no booking form on it, so it ends with the invitation
   instead of dropping straight into the footer. */
.tabcta{padding:0 var(--pad) clamp(46px,6vw,86px);background:var(--ivory)}
.tabcta__in{
  max-width:1400px;margin:0 auto;
  background:var(--cream);border-radius:var(--r);
  padding:clamp(30px,4vw,56px);
  display:flex;flex-wrap:wrap;align-items:center;gap:18px 32px;
}
.tabcta__in h2{
  font-family:var(--serif);font-weight:400;margin:0;
  font-size:clamp(24px,3vw,38px);line-height:1.1;flex:1 1 16ch;
}
.tabcta__in p{margin:0;color:var(--ink-soft);flex:1 1 26ch;font-size:15px}
.tabcta__in .btn{flex:none}

/* The current tab, marked in both the sticky bar and the drawer. */
.topbar__nav a[aria-current="page"],
.drawer__nav a[aria-current="page"]{color:var(--sage)}

/* On the Studio tab the section's own <h2> is dropped (the page H1 already
   says it), which leaves the Book button alone in a space-between row and
   pinned left. Push a lone child back to the right. */
.studio__head > :only-child{margin-left:auto}

/* Studio and FAQ drop their section <h2> because the tab's own <h1> already
   says the same thing — which leaves the section's full 101px of top padding
   sitting above a lone Book button. Full-bleed that merely looked generous;
   inside a floating card it reads as an empty shelf at the top of the card.
   Only the top padding comes down; the bottom keeps its room. */
.studio:not(:has(h2)),
.faq:not(:has(h2)){padding-top:clamp(34px,4vw,60px)}

/* The section before the closing CTA carries a full 100px of bottom padding,
   and the ground changes tone right at that boundary — so the colour change
   landed in the middle of a large empty gap and the CTA read as stranded
   rather than as the end of the page. Halving that padding puts the tone
   change and the card together. Degrades to the old spacing where :has()
   is unsupported, which is no worse than before. */
main > section:has(+ .tabcta){
  padding-bottom:clamp(30px,4vw,54px);
}
/* ...unless that section has a BACKGROUND of its own. /services is beige, and
   halving its bottom padding ended the beige band about 70px under the
   add-ons card — close enough that the card read as sitting on a shelf that
   had been sliced off, rather than inside a section that finishes. A coloured
   band needs room beneath its content before the ground changes tone. */
main > section.services:has(+ .tabcta){
  padding-bottom:clamp(56px,7vw,104px);
}

/* ── Session helper ───────────────────────────────────────
   Follows the convention settled on the Snow Lotus widget, because a visitor
   who has met one chat launcher expects the next one to behave the same way:

     · the launcher is ALWAYS visible and always bottom-right; it does not
       vanish when the panel opens, it collapses to a circle with a chevron
     · the panel opens ABOVE the launcher and never overlaps it
     · on a phone the launcher is icon-only — a labelled pill covers real
       content — and hides while the panel is full-screen

   FAB is 56px tall so the panel can sit at bottom:(gap + 56 + 12) without
   measuring anything at runtime. */
.helper{--fab:56px;--gap:clamp(12px,2vw,22px);position:fixed;right:var(--gap);bottom:var(--gap);z-index:70}

.helper__fab{
  position:relative;
  display:inline-flex;align-items:center;gap:10px;
  height:var(--fab);
  /* White ground with green type: against the cream and oat sections the
     page is built from, a white pill is the lightest thing on screen and
     reads as an invitation rather than another dark button competing with
     "Book an Appointment". The outline is a solid green ring rather than a
     hairline tint, so the pill holds its own shape against the cream and oat
     grounds instead of dissolving into them. */
  background:#fff;color:var(--deep);
  border:1.5px solid var(--sage);border-radius:999px;
  padding:0 20px 0 17px;
  font:inherit;font-size:14px;letter-spacing:.01em;
  cursor:pointer;
  box-shadow:0 14px 34px rgba(60,42,32,.16),0 2px 6px rgba(60,42,32,.08);
  transition:transform .35s var(--ease),background .35s var(--ease),
             padding .35s var(--ease),box-shadow .35s var(--ease);
}
.helper__fab:hover{
  transform:translateY(-2px);
  border-color:var(--deep);
  box-shadow:0 18px 42px rgba(60,42,32,.22),0 2px 6px rgba(60,42,32,.10);
}
.helper__fab:active{transform:translateY(0)}

/* The sun is the site's mark, and it is the one warm thing on the button. */
.helper__mark{fill:var(--accent);flex:none;transform-origin:50% 50%;width:21px;height:21px}
.helper__chev{display:none;flex:none}

/* Open: the label goes, the pill becomes a circle, and the sun gives way to
   a chevron so the button reads as "close" rather than "open again".
   (These rules were lost in a rewrite of the panel block below — the launcher
   kept showing the sun while the panel was open.) */
.helper.is-open .helper__fab{background:var(--deep);color:var(--ivory);border-color:var(--deep);padding:0;width:var(--fab);justify-content:center}
.helper.is-open .helper__fab span,
.helper.is-open .helper__mark{display:none}
.helper.is-open .helper__chev{display:block}

/* ── Drawing the eye ──────────────────────────────────────
   One layer only, and deliberately slow — this is a massage practice, and a
   bouncing badge would be the wrong register entirely. The sun BREATHES,
   continuously and almost imperceptibly. An expanding ring was tried here
   too and read as a rendering artefact, so it is gone for good.
   Off under prefers-reduced-motion, where the button is simply a button. */
@keyframes helper-breathe{
  0%,100%{transform:scale(1);opacity:.92}
  50%    {transform:scale(1.13);opacity:1}
}
.helper__mark{animation:helper-breathe 4.2s var(--ease) infinite}

.helper__panel{
  position:absolute;right:0;bottom:calc(var(--fab) + 12px);
  width:min(370px,calc(100vw - 2*var(--gap)));
  background:var(--ivory);border:1px solid var(--line);
  border-radius:18px;box-shadow:0 22px 60px rgba(35,28,20,.20);
  overflow:hidden;display:flex;flex-direction:column;
}

/* A coloured header bar, the way a chat panel announces itself — title plus
   one line saying where the answers come from. */
.helper__head{
  display:flex;align-items:flex-start;gap:12px;
  padding:15px 16px;flex:none;
  background:var(--mocha);color:var(--ivory);
}
.helper__title{margin:0;font-family:var(--serif);font-size:19px;line-height:1.2}
.helper__sub{margin:3px 0 0;font-size:12.5px;line-height:1.35;opacity:.82}
.helper__x{
  background:none;border:0;font-size:22px;line-height:1;
  color:var(--ivory);opacity:.75;cursor:pointer;padding:0 2px;margin-left:auto;
}
.helper__x:hover{opacity:1}

.helper__body{padding:16px;max-height:min(50vh,400px);overflow-y:auto;flex:1}

/* The greeting is a message in the thread, not page copy. */
.helper__bubble{
  margin:0;padding:12px 14px;
  background:var(--cream);border:1px solid var(--line-soft);border-radius:14px;
  font-size:13.5px;line-height:1.55;color:var(--ink);
}
.helper__chips{display:flex;flex-direction:column;align-items:flex-start;gap:7px;margin-top:12px}
.helper__chip{
  background:transparent;border:1px solid var(--line);border-radius:999px;
  padding:8px 15px;font:inherit;font-size:12.5px;color:var(--ink);cursor:pointer;
  text-align:left;
  transition:background .25s var(--ease),border-color .25s var(--ease);
}
.helper__chip:hover{background:var(--cream);border-color:var(--mocha)}

.helper__you{margin:0 0 14px;font-size:13px;color:var(--ink-soft);font-style:italic}
.helper__rec h4{margin:0;font-family:var(--serif);font-weight:400;font-size:21px;line-height:1.2}
.helper__meta{margin:3px 0 7px;font-size:12.5px;color:var(--sage);letter-spacing:.02em}
.helper__why{margin:0;font-size:13.5px;line-height:1.55;color:var(--ink-soft)}
.helper__or{margin:16px 0 8px;font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-soft)}
.helper__flag{
  margin:13px 0 0;padding:10px 12px;border-radius:10px;
  background:var(--sand);font-size:12.5px;line-height:1.5;color:var(--ink);
}
.helper__acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}
.helper__acts .btn{font-size:12.5px;padding:10px 18px}

.helper__form{display:flex;gap:8px;padding:12px 16px 8px;flex:none;border-top:1px solid var(--line-soft)}
.helper__form input{
  flex:1;min-width:0;font:inherit;
  /* 16px exactly: anything smaller and iOS Safari zooms the page on focus. */
  font-size:16px;color:var(--ink);
  background:var(--cream);border:1px solid var(--line);border-radius:999px;padding:11px 16px;
}
.helper__form input:focus{outline:none;background:#fff;border-color:var(--mocha)}
.helper__form button{
  flex:none;width:42px;height:42px;border:0;border-radius:999px;cursor:pointer;
  background:var(--mocha);color:var(--ivory);display:grid;place-items:center;
}
.helper__form button svg{fill:none;stroke:currentColor;stroke-width:1.6}
.helper__fine{margin:0;padding:0 16px 14px;font-size:11px;line-height:1.5;color:var(--ink-soft);flex:none}
.helper__fine a{color:var(--sage)}

@media (max-width:560px){
  /* The label stays on a phone too. It was icon-only on the grounds that a
     labelled pill covers content, but a bare sun gives no clue what the
     button does — "Ask me a question" is the whole point of it. At 13.5px
     the pill is under half the width of a 390px screen. */
  .helper__fab{padding:0 17px 0 15px;font-size:13.5px}
  .helper__mark{width:20px;height:20px}
  /* Scrolled: sun-only circle, same footprint as the open state. The label is
     clipped rather than display:none'd so screen readers still hear
     "Ask me a question". */
  .helper.is-compact:not(.is-open) .helper__fab{width:var(--fab);padding:0;justify-content:center;gap:0}
  .helper.is-compact:not(.is-open) .helper__fab span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

  /* NOT full-screen. The panel floats over the page with the launcher still
     on screen beneath it — the page stays visible around the edges, which is
     what the reference does. The previous full-screen version locked body
     scroll and pinned its own height to visualViewport on every keyboard
     event, and that combination jumped on iOS every time the panel opened. */
  .helper__panel{
    position:fixed;
    left:var(--gap);right:var(--gap);
    bottom:calc(var(--gap) + var(--fab) + 12px);
    top:auto;width:auto;max-height:70vh;
  }
  .helper__body{max-height:none}
}
@media (prefers-reduced-motion:reduce){
  .helper__fab{transition:none}
  .helper__mark{animation:none;transform:none;opacity:1}
}

/* The model's own sentence, above the service cards. */
.helper__reply{margin:0 0 15px;font-size:14px;line-height:1.55}
.helper__thinking{margin:0;font-size:13.5px;color:var(--ink-soft);font-style:italic}

/* The sticky bar's CTA read "Book an Appointment" at every width. Beside the
   wordmark and the hamburger on a 390px screen that is 126px of pill wrapping
   onto THREE lines, which pushed the whole bar to 92px tall. The long label
   is for the desktop bar; the phone gets the verb. */
.bar-cta__short{display:none}
@media (max-width:760px){
  .topbar .btn--pill{white-space:nowrap}
  .bar-cta__long{display:none}
  .bar-cta__short{display:inline}
}

/* ── /services: grouped cards + jump bar ──────────────────
   Replaces the one-at-a-time accordion. The band is overflow:CLIP rather than
   hidden: hidden makes the section a scroll container, and a sticky child
   then sticks to the section instead of the viewport. */
.services{overflow:clip}
.jump{position:sticky;top:var(--tb,70px);z-index:20;max-width:1400px;margin:clamp(20px,3vw,36px) auto clamp(28px,4vw,52px);
  display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;padding:6px;background:rgba(250,247,240,.92);
  backdrop-filter:blur(12px);border:1px solid var(--line-soft);border-radius:999px;box-shadow:0 8px 24px rgba(60,42,32,.06)}
.jump::-webkit-scrollbar{display:none}
.jump a{flex:none;text-decoration:none;font-size:13.5px;color:var(--ink-soft);padding:9px 18px;border-radius:999px;transition:background .3s var(--ease),color .3s var(--ease)}
.jump a:hover{color:var(--ink);background:var(--cream)}
.jump a[aria-current]{background:var(--ink);color:var(--ivory)}
.menu{border-top:0}
.sgroup{max-width:1400px;margin:0 auto clamp(40px,5vw,72px);scroll-margin-top:84px}
.sgroup__head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap;
  padding-bottom:14px;margin-bottom:clamp(16px,2vw,24px);border-bottom:1px solid var(--line)}
.sgroup__head h3{font-size:clamp(26px,3.2vw,40px)}
.sgroup__head p{margin:0;color:var(--ink-soft);font-size:14px}
.scards{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr));gap:clamp(14px,1.8vw,22px)}
.scard{background:var(--ivory);border-radius:16px;padding:clamp(22px,2.4vw,32px);display:flex;flex-direction:column;gap:16px;
  scroll-margin-top:84px}
.scard__top{display:flex;flex-direction:column;gap:10px}
.scard h4{font-family:var(--serif);font-weight:400;font-size:clamp(24px,2.4vw,30px);line-height:1.1;margin:0}
.scard__tags{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.scard__tags li{font-size:11.5px;color:var(--sage);border:1px solid rgba(78,107,74,.35);border-radius:999px;padding:3px 10px}
.scard__desc{margin:0;color:var(--ink-soft);font-size:14.5px;line-height:1.6;flex:1 0 auto}
.scard__rates{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(78px,1fr));gap:8px}
.scard__rates li{display:flex;flex-direction:column;align-items:center;gap:2px;padding:10px 6px;background:var(--cream);border-radius:12px}
.scard__rates span{font-size:12px;color:var(--ink-soft)}
.scard__rates b{font-family:var(--serif);font-weight:400;font-size:24px;line-height:1.1;color:var(--ink)}
.scard__book{align-self:flex-start;display:inline-flex;align-items:center;gap:8px;font-size:14px;color:var(--ink);text-decoration:none;
  border-bottom:1px solid var(--line);padding-bottom:3px;transition:gap .3s var(--ease),border-color .3s var(--ease)}
.scard__book svg{width:15px;height:15px}
.scard__book:hover{gap:13px;border-color:var(--ink)}
#addons,#packs{scroll-margin-top:84px}
@media (max-width:600px){
  .jump{margin-left:calc(-1 * var(--pad) + 8px);margin-right:calc(-1 * var(--pad) + 8px);border-radius:14px}
  .jump a{padding:8px 14px;font-size:13px}
  /* Two of the five links start off-screen; the fade says the bar scrolls. */
  .jump{-webkit-mask-image:linear-gradient(90deg,#000 80%,transparent);mask-image:linear-gradient(90deg,#000 80%,transparent)}
  .jump.at-end{-webkit-mask-image:none;mask-image:none}
  .scard__rates b{font-size:22px}
}

/* Contrast pass (Chelsea: "a ton of text"). One short line leads each card,
   the full description folds into <details>, cards go white on the oat band,
   and the prices become the darkest thing on the card so they are read first. */
.scard{background:#fff;box-shadow:0 1px 2px rgba(60,42,32,.05),0 10px 30px rgba(60,42,32,.06);gap:14px}
.scard h4{font-size:clamp(26px,2.6vw,32px)}
.scard__tags li{background:var(--cream);border-color:transparent;color:var(--ink-soft)}
.scard__best{margin:0;font-size:15.5px;line-height:1.45;color:var(--ink);flex:1 0 auto}
.scard__rates li{background:var(--deep);border-radius:12px}
.scard__rates span{color:rgba(255,255,255,.78)}
.scard__rates b{color:#fff}
.scard__more{border-top:1px solid var(--line-soft);padding-top:12px}
.scard__more summary{cursor:pointer;list-style:none;font-size:13.5px;color:var(--ink-soft);display:flex;align-items:center;gap:8px}
.scard__more summary::-webkit-details-marker{display:none}
.scard__more summary::after{content:"+";font-size:17px;line-height:1;margin-left:auto;transition:transform .3s var(--ease)}
.scard__more[open] summary::after{transform:rotate(45deg)}
.scard__more summary:hover{color:var(--ink)}
.scard__more p{margin:10px 0 0;font-size:14px;line-height:1.6;color:var(--ink-soft)}
.sgroup__head h3{font-size:clamp(30px,3.8vw,48px)}
.sgroup__head{border-bottom-color:rgba(35,28,20,.28)}
/* Prices start right under the one-liner on every card; the spare height goes
   below them, so the Book links still line up across a row. */
.scard__best{flex:none}
.scard__rates{flex:1 0 auto;align-content:start;grid-template-columns:repeat(auto-fill,minmax(66px,1fr));gap:6px}
.scard__rates li{padding:9px 4px}
.scard__rates b{font-size:22px}

/* Price menu (Tessa: the tile grid read crowded). The dark chips wrapped to
   two ragged rows and outweighed the heading; a spa-menu list keeps every
   duration on one line, leaves a dotted leader to the price and lets the
   serif figures carry the colour instead of a filled block. */
.scard__rates{display:flex;flex-direction:column;justify-content:flex-start;gap:0;
  border-top:1px solid var(--line-soft)}
.scard__rates li{flex-direction:row;align-items:baseline;gap:10px;padding:9px 0;background:none;border-radius:0;
  border-bottom:1px solid var(--line-soft)}
.scard__rates li::after{content:"";order:1;flex:1;align-self:center;height:0;border-bottom:1px dotted rgba(35,28,20,.28);transform:translateY(3px)}
.scard__rates span{order:0;font-size:13px;letter-spacing:.02em;color:var(--ink-soft);white-space:nowrap}
.scard__rates b{order:2;font-family:var(--serif);font-weight:400;font-size:24px;line-height:1;color:var(--deep);font-variant-numeric:lining-nums}
.scard__rates{border-top:0}
.scard__rates li{border-bottom:0;padding:7px 0}

/* Row alignment (Tessa: "see how they are uneven"). One-liners and titles wrap
   to different line counts, so each card's price list started at a different
   height. Subgrid makes title+line / prices / book / more share tracks across
   every card in a row, so the first price lines up everywhere. */
@supports (grid-template-rows:subgrid){
  .scard{display:grid;grid-row:span 4;grid-template-rows:subgrid;row-gap:14px;align-content:start}
  .scard__rates{align-self:start}
  .scard__best{margin-top:4px}
  .scard__book{align-self:end;justify-self:start}
}

/* Jump-bar fade without a mask. mask-image faded the bar's own background as
   well, so card prices scrolling underneath showed through its right end.
   A sticky gradient in the bar's colour fades the LINKS but keeps the ground
   opaque. */
@media (max-width:600px){
  .jump,.jump.at-end{-webkit-mask-image:none;mask-image:none;background:rgb(250,247,240)}
  .jump::after{content:"";position:sticky;right:-6px;flex:none;width:44px;margin:-6px -6px -6px -44px;
    background:linear-gradient(90deg,rgba(250,247,240,0),rgb(250,247,240) 75%);pointer-events:none;transition:opacity .3s}
  .jump.at-end::after{opacity:0}
}
.packs__note a{color:var(--deep);font-weight:600;text-decoration:underline;text-underline-offset:3px;margin-left:4px;white-space:nowrap}
