/* ============================================================
   neoSKiN — subpage system, REFINED
   Treatment + concern detail pages and their two hub pages.
   ------------------------------------------------------------
   Replaces the earlier "panel on every paragraph" rule. Body copy
   is now set as TYPE ON THE FIELD; elevation is reserved for the
   things that genuinely are objects — the price sheet, the
   treatment/concern cards, the regimen grid. Rhythm comes from
   grounds (pine ↔ putty ↔ bone), hairlines, scale and space.
   Tokens, nav, footer, buttons and the reveal grammar come from
   base.css + chrome.css. shop / packages / team keep treatment.css.
   ============================================================ */

/* nav logo reads dark on the light subpage ground */
.logo-svg{height:22px}
.logo{--lg-badge:var(--ivory);--lg-neo:var(--bone);--lg-word:var(--ivory)}

/* ---------- section rhythm ----------
   Tighter default beat; the pine chapter alone gets extra air, so
   spacing varies with meaning instead of being uniformly huge. */
section{padding:clamp(52px,7.5vh,88px) 0}
.t-hero{padding:0}
.sec-bone{
  background:var(--bg-2);
  border-block:1px solid var(--hairline-2);
  padding-block:clamp(64px,9vh,110px);
}

/* ============================================================
   HERO (pine) — shared by detail pages and both hubs
   ============================================================ */
.t-hero{
  background:
    radial-gradient(ellipse at 78% 18%, rgba(124,131,112,.16), rgba(124,131,112,.05) 30%, transparent 55%),
    linear-gradient(118deg, rgba(239,233,222,.03), transparent 42%, rgba(0,0,0,.18)),
    var(--pine);
  color:var(--bone);
  position:relative;
}
/* film grain on the hero, so the pine reads as stock rather than fill */
.t-hero::after{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.35;
  mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.4'/%3E%3C/svg%3E");
}
.t-hero > *{position:relative;z-index:1}
.t-hero > .container{
  padding:clamp(128px,18vh,190px) 0 clamp(72px,10vh,112px);
}
.t-hero-grid{
  display:grid;grid-template-columns:1.06fr .94fr;
  gap:clamp(32px,5vw,88px);align-items:center;
}
.crumb{
  font-family:'JetBrains Mono',monospace;font-size:.75rem;
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--sage-on-dark);margin-bottom:var(--s5);display:block;
}
.crumb a{color:var(--bone-dim)}
.crumb a:hover{color:var(--bone)}
.t-hero h1{
  font-size:clamp(2.6rem,5.6vw,4.7rem);margin-bottom:var(--s5);
  /* no per-word shadow: the split words clip it into visible boxes */
  /* A measure, which this heading never had. Without one the hub headlines
     ran the full 1240px container as a single unbroken line at 75px — the
     eye has to track the whole width and it reads badly even though the
     contrast is fine. Every other heading is already held to one (14ch on
     .band-split, 20ch on .band-sec h2); the hero h1 was the one missed. At
     20ch the 18-27 character page titles stay on one line and only the two
     long hub sentences wrap. */
  max-width:20ch;
}
.t-hero .lede{color:var(--bone-dim);max-width:34em}
/* The default .btn is a sage fill carrying ink-dark label text. On this
   hero's pine ground that measured 4.44 against the 4.5 a label needs — a
   hair under, but it is the primary call to action on 26 pages. Bone with a
   pine label is what the homepage hero and the book band already use, so
   this makes the primary CTA one thing site-wide instead of three. */
.t-hero .btn{background:var(--glass-fill);color:var(--bone);border-color:var(--glass-edge-strong)}
.t-hero .btn .btn-orb{color:var(--pine)}
.hero-meta{display:flex;gap:var(--s3);flex-wrap:wrap;margin:var(--s6) 0 var(--s7)}
.chip{
  font-family:'JetBrains Mono',monospace;font-size:.75rem;
  letter-spacing:.08em;text-transform:uppercase;
  border:1px solid rgba(247,244,238,.28);border-radius:999px;
  padding:9px 16px;color:var(--bone-dim);
}
.t-hero-img{
  border-radius:var(--radius-card);overflow:hidden;margin:0;
  border:1px solid rgba(247,244,238,.14);aspect-ratio:4/4.5;
  box-shadow:0 44px 90px -34px rgba(0,0,0,.62), inset 0 1px 0 rgba(247,244,238,.18);
}
.t-hero-img img{width:100%;height:100%;object-fit:cover}
@media (max-width:860px){
  .t-hero-grid{grid-template-columns:1fr}
  /* Was 4/3. Eight of the eleven concern heroes are portrait faces
     (0.67–0.91), and a landscape frame cropped them to a band across
     the eyes — 50% of the source was being thrown away at 375px, with
     the nose and mouth cut off. Matching the desktop 4/4.5 keeps the
     same part of the photograph visible at every width, which is also
     why the crop no longer changes as you rotate a phone. */
  .t-hero-img{aspect-ratio:4/4.5;max-width:520px}
}

/* ============================================================
   SECTION HEAD + EDITORIAL SPLIT
   ============================================================ */
.section-head{max-width:38em;margin-bottom:var(--head-gap)}
.section-head .eyebrow{color:var(--sage-label)}
.section-head h2{font-size:var(--t-4);margin:0}
.section-head p{color:var(--ivory-dim);margin-top:var(--s3)}

.two-col{
  display:grid;grid-template-columns:minmax(0,.36fr) minmax(0,.64fr);
  gap:clamp(32px,6vw,100px);align-items:start;
}
.two-col .section-head{margin-bottom:0}
@media (max-width:860px){.two-col{grid-template-columns:1fr;gap:var(--s6)}}

/* ============================================================
   PROSE — type on the field, no panel
   ============================================================ */
.prose{max-width:38em;color:var(--ivory-dim);font-size:1.05rem;line-height:1.72;
  background:none;border:0;box-shadow:none;padding:0;border-radius:0}
.prose p+p{margin-top:1.1em}
.two-col .prose>p:first-child,
.prose.lead>p:first-child{
  font-family:'Expose',sans-serif;font-weight:500;
  font-size:clamp(1.25rem,1.9vw,1.6rem);line-height:1.42;
  letter-spacing:-.014em;color:var(--ivory);margin-bottom:1.05em;
}
.prose a{color:var(--ivory);border-bottom:1px solid var(--sage-label);padding-bottom:1px}
.prose a:hover{border-bottom-color:var(--ivory)}
.prose strong{color:var(--ivory);font-weight:500}

/* "what it treats" — a ruled index, not filled cells */
.benefits ul{
  list-style:none;display:grid;grid-template-columns:repeat(2,1fr);
  column-gap:clamp(32px,5vw,80px);max-width:62em;
  border-top:1px solid var(--hairline);
}
.benefits li{
  color:var(--ivory);font-size:1.05rem;background:none;
  padding:15px 0 15px 26px;position:relative;
  border-bottom:1px solid var(--hairline-2);
}
.benefits li::before{
  content:"";position:absolute;left:0;top:1.5em;
  width:12px;height:1px;background:var(--champagne);
  transition:width var(--dur-state) var(--ease-out);
}
/* the index answers the pointer: tick grows, entry steps forward */
.benefits li{transition:padding-left var(--dur-state) var(--ease-soft)}
.benefits li:hover{padding-left:34px}
.benefits li:hover::before{width:20px}
@media (max-width:640px){.benefits ul{grid-template-columns:1fr}}

/* ============================================================
   PRICING — the one spec panel
   ============================================================ */
/* A price list is a spec sheet, not a hero: compact rows, quiet
   frame, dotted leader carrying the eye from item to figure. */
.price-table{
  max-width:560px;border-radius:var(--radius-panel);
  border:1px solid var(--hairline);background:var(--bg-2);
  box-shadow:var(--e1);padding:6px clamp(18px,2vw,26px);
}
.price-row{
  display:flex;justify-content:space-between;gap:var(--s4);
  align-items:baseline;padding:11px 0;border-bottom:1px solid var(--hairline-2);
}
.price-table .price-row:last-child{border-bottom:0}
.price-row b{font-weight:400;color:var(--ivory);font-size:.95rem}
.price-row::after{
  content:"";order:2;flex:1;min-width:16px;
  border-bottom:1px dotted rgba(33,29,24,.25);
  transform:translateY(-4px);
}
.price-row b{order:1}
.price-row span{
  order:3;
  font-family:'JetBrains Mono',monospace;font-size:.8rem;letter-spacing:.02em;
  color:var(--ivory);white-space:nowrap;font-variant-numeric:tabular-nums;
}
.price-note{
  margin-top:var(--s5);max-width:52em;font-size:.9rem;color:var(--ivory-dim);
  padding-left:26px;position:relative;
  background:none;border:0;box-shadow:none;border-radius:0;
}
.price-note::before{
  content:"";position:absolute;left:0;top:.72em;width:14px;height:1px;background:var(--champagne);
}

/* ============================================================
   VIEWPORT COMPOSITIONS
   Each .vpc is one composed idea: bounded surfaces in a grid,
   never a run of stacked bands.

   NO LONGER a forced 100svh. That worked only for sections whose
   content actually filled a screen; the rest centred a 500px block
   inside a 1150px box and split the 650px remainder above and
   below it. Consecutive sections then stacked their leftovers, so
   the page carried 400–540px of continuous nothing between every
   content block — 2,769px of dead space on one treatment page,
   38% of its height — and it grew with the window, because the
   box tracked the viewport while the content did not.

   Height now comes from content plus the house section rhythm, so
   a short section is short. The hero still takes the full screen
   below, where filling it is the point.
   ============================================================ */
.vpc{
  display:flex;align-items:center;
  padding-block:var(--sec-md);
}
/* the first section still has to clear the fixed nav */
.vpc:first-of-type{padding-block:calc(var(--nav-h) + var(--s6)) var(--sec-md)}
.vpc>.container{width:min(1240px,calc(100% - 48px))}
/* the hero is the one section that should still own the screen —
   it is the only one whose content is built to fill it */
.t-hero.vpc{min-height:100svh;padding-block:0}
.t-hero.vpc>.container{padding-block:calc(var(--nav-h) + 24px) 40px}

/* ---- VP2: understand — about card + story carousel ---- */
.vp2-grid{display:grid;grid-template-columns:minmax(0,.44fr) minmax(0,.56fr);gap:clamp(20px,2.6vw,36px);align-items:start}
.vp2-grid--single{grid-template-columns:1fr}
.vp2-grid--single .about-card{max-width:900px;margin-inline:auto}
.about-card{
  background:var(--bg-2);border:1px solid var(--hairline-2);
  border-radius:var(--radius-card);box-shadow:var(--e1);
  padding:clamp(24px,2.6vw,40px);
  display:flex;flex-direction:column;gap:var(--s5);
}
.about-card .eyebrow{margin-bottom:0}
.about-card .ac-lede{
  font-family:'Expose',sans-serif;font-weight:500;
  font-size:clamp(1.15rem,1.6vw,1.5rem);line-height:1.36;
  letter-spacing:-.014em;color:var(--ivory);
}
.about-card .ac-body{color:var(--ivory-dim);font-size:.98rem;line-height:1.62;max-width:46ch}
.ac-chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:auto}
.ac-chips i{font-style:normal;display:block;width:100%;
  font-family:'JetBrains Mono',monospace;font-size:.75rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--sage-label);margin-bottom:2px}
.ac-chips span{
  font-size:.78rem;color:var(--ivory-dim);
  border:1px solid var(--hairline-2);border-radius:999px;padding:5px 11px;
  background:var(--bg-3);
}

/* story carousel: horizontal snap, dot nav, user-driven

   HEIGHT. Every child of a slide is absolutely positioned — the
   <img> and the .sr-cap both — so a slide contributes NO in-flow
   height. .sr-track is height:100% of a parent that had no definite
   height, which resolves to auto, so the whole rail collapsed to its
   two 1px borders: a 2px hairline where a carousel should be, on all
   21 pages that carry one.

   align-self:stretch takes the height from the card beside it, which
   is the intended composition. The aspect-ratio is the floor for the
   case where that card is ever shorter than the rail needs, and for
   the single-column layout below 900px where there is no card to
   match. */
.story-rail{position:relative;border-radius:var(--radius-card);overflow:hidden;
  border:1px solid var(--hairline-2);box-shadow:var(--e2);background:var(--pine);
  align-self:stretch;
  min-height:clamp(300px,32vw,520px);}
.sr-track{display:flex;height:100%;overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.sr-track::-webkit-scrollbar{display:none}
.sr-slide{position:relative;flex:0 0 100%;scroll-snap-align:start;min-height:100%}
.sr-slide img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.sr-slide::after{content:"";position:absolute;inset:0;
  background:linear-gradient(185deg,transparent 42%,rgba(34,38,30,.88) 92%)}
.sr-cap{position:absolute;left:clamp(18px,2.4vw,30px);right:18px;bottom:clamp(16px,2.2vw,26px);z-index:2;color:var(--bone)}
.sr-cap i{font-style:normal;display:block;font-family:'JetBrains Mono',monospace;
  font-size:.75rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--sage-on-dark);margin-bottom:4px}
.sr-cap b{font-family:'Expose',sans-serif;font-weight:500;font-size:clamp(1.2rem,1.9vw,1.7rem);
  letter-spacing:-.016em;line-height:1.15}
.story-rail--caption-card .sr-slide::after{
  inset:auto 0 0;height:32%;
  background:linear-gradient(180deg,transparent,rgba(31,35,27,.12));
  pointer-events:none;
}
.story-rail--caption-card .sr-cap{
  left:clamp(14px,2vw,22px);right:auto;bottom:clamp(14px,2vw,22px);
  width:min(360px,calc(100% - clamp(28px,4vw,44px)));
  padding:14px 16px 15px;border:1px solid rgba(247,244,238,.16);
  border-radius:12px;background:rgba(31,35,27,.88);
  box-shadow:0 12px 32px rgba(20,24,18,.18);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
}
.story-rail--caption-card .sr-slide{scroll-snap-stop:always}
.sr-dots{position:absolute;right:clamp(16px,2vw,24px);top:clamp(14px,1.8vw,20px);z-index:2;display:flex;gap:6px}
.sr-dots button{width:8px;height:8px;border-radius:50%;padding:0;
  background:rgba(247,244,238,.38);transition:background var(--dur-tap),transform var(--dur-tap)}
.sr-dots button.is-on{background:var(--bone);transform:scale(1.2)}
@media (max-width:900px){
  .vp2-grid{grid-template-columns:1fr}
  .story-rail{min-height:52vw}
  .vpc{min-height:0;padding-block:56px 24px}
  .t-hero.vpc{min-height:100svh}
}

/* ---- exploded-view scroll scrub ---- */
/* ---- tabs card: vertical nav left, content right ----
   Pills in a wrapping row truncated long labels and left the
   panel half-empty. A side rail carries full-length labels and
   the content column fills the card. ---- */
.tabs-card{
  background:var(--bg-2);border:1px solid var(--hairline-2);
  border-radius:var(--radius-card);box-shadow:var(--e1);
  padding:clamp(22px,2.6vw,36px);
  display:grid;grid-template-columns:minmax(220px,.3fr) minmax(0,.7fr);
  gap:clamp(24px,3vw,48px);align-items:start;
}
.tc-rail{display:flex;flex-direction:column;gap:4px;
  border-right:1px solid var(--hairline-2);padding-right:clamp(16px,2vw,28px)}
.tc-rail button{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  text-align:left;font-family:'Bespoke Sans','Helvetica Neue',sans-serif;
  font-size:.93rem;font-weight:400;letter-spacing:0;text-transform:none;
  padding:12px 14px;border-radius:12px;cursor:pointer;
  border:1px solid var(--hairline-2);background:var(--bg);
  color:var(--ivory);position:relative;
  box-shadow:0 1px 0 rgba(33,29,24,.04);
  transition:background var(--dur-tap) var(--ease-soft),color var(--dur-tap),
             border-color var(--dur-tap),transform var(--dur-tap) var(--ease-soft),
             box-shadow var(--dur-tap);
}
/* the chevron says "this opens something" */
.tc-rail button::after{
  content:"";flex:none;width:7px;height:7px;
  border-right:1.5px solid var(--sage-label);border-top:1.5px solid var(--sage-label);
  transform:rotate(45deg);
  transition:transform var(--dur-tap) var(--ease-soft),border-color var(--dur-tap);
}
.tc-rail button:hover{
  border-color:var(--hairline);background:var(--bg-2);
  transform:translateX(2px);box-shadow:var(--e1);
}
.tc-rail button:hover::after{transform:rotate(45deg) translate(1px,-1px)}
.tc-rail button.is-on{background:var(--pine);border-color:var(--pine);color:var(--bone);box-shadow:var(--e2)}
.tc-rail button.is-on::after{border-color:var(--sage-on-dark);transform:rotate(45deg)}
.tc-rail button:focus-visible{outline:2px solid var(--sage-label);outline-offset:2px}
.tc-panel{display:none;max-height:min(52vh,520px);overflow-y:auto;
  padding-right:12px;scrollbar-width:thin;
}
/* the bottom fade is a "more below" signal, not decoration — it was
   burnt on permanently, so a panel scrolled to its end (or one that
   never overflowed at all) had its last line half-erased. JS now sets
   .fade-b only while content actually remains below the fold. */
.tc-panel.is-on{display:block;animation:tc-in .32s cubic-bezier(.16,1,.3,1)}
@keyframes tc-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.tc-panel .prose{max-width:none}
.tc-panel .prose>p:first-child{
  font-family:'Expose',sans-serif;font-weight:500;
  font-size:clamp(1.05rem,1.4vw,1.3rem);line-height:1.4;
  letter-spacing:-.012em;color:var(--ivory);max-width:34em;
}
.tc-panel .prose ul{list-style:none;border-top:1px solid var(--hairline);margin-top:var(--s4);
  columns:2;column-gap:clamp(32px,4vw,64px)}
.tc-panel .prose li{
  padding:12px 0 12px 22px;position:relative;
  border-bottom:1px solid var(--hairline-2);
  color:var(--ivory-dim);font-size:1rem;line-height:1.55;
  break-inside:avoid;
}
.tc-panel .prose li::before{content:"";position:absolute;left:0;top:1.3em;width:12px;height:1px;background:var(--champagne)}
.tc-panel .prose li strong{display:block;color:var(--ivory);font-weight:500;font-size:.98rem;margin-bottom:2px}
.tc-panel .prose p{max-width:64ch}
.tc-panel .prose p+p{margin-top:.9em}
.tc-qa{padding:12px 0;border-bottom:1px solid var(--hairline-2)}
.tc-qa:last-child{border-bottom:0}
.tc-qa b{display:block;font-weight:500;color:var(--ivory);margin-bottom:4px;font-size:1.05rem}
.tc-qa p{color:var(--ivory-dim);font-size:.98rem;line-height:1.65;max-width:70ch}
@media (max-width:860px){
  .tabs-card{grid-template-columns:1fr;gap:var(--s4)}
  .tc-rail{flex-direction:row;overflow-x:auto;border-right:0;padding-right:0;
    border-bottom:1px solid var(--hairline-2);padding-bottom:10px;scrollbar-width:none}
  .tc-rail::-webkit-scrollbar{display:none}
  .tc-rail button{white-space:nowrap;font-size:.85rem;padding:9px 13px}
  .tc-panel .prose ul{columns:1}
}
@media (prefers-reduced-motion:reduce){.tc-panel.is-on{animation:none}}

/* concern VP2: the about card must not stretch into a void, and the
   portrait slider is capped so the pairing balances */
.vp2-grid .ba-figure{max-width:440px;margin-inline:auto}

/* ---- VP5: proof + act ---- */
.vp5-grid{display:grid;grid-template-columns:minmax(0,.56fr) minmax(0,.44fr);gap:clamp(20px,2.6vw,36px);align-items:stretch}
.vp5-products{
  background:var(--bg-2);border:1px solid var(--hairline-2);
  border-radius:var(--radius-card);box-shadow:var(--e1);
  padding:clamp(22px,2.4vw,34px);min-width:0;
}
.vp5-products h3{font-size:var(--t-3);margin:6px 0 var(--s4)}
.vp5-products .c-home{margin-top:0}
.vp5-products .c-home h3{font-size:var(--t-3)}
.vp5-products .c-home-lede{font-size:1rem;margin-bottom:var(--s4)}
/* the shelf becomes a rail inside the card at every width */
.vp5-products .rg-grid{display:flex;overflow-x:auto;gap:10px;
  scroll-snap-type:x proximity;padding-bottom:8px;scrollbar-width:thin}
.vp5-products .rg-grid>.rg-item{flex:0 0 204px;scroll-snap-align:start}
/* rail cards read brand · name · price — the role tag is noise at
   this size and forced "BARE ROOTS" to wrap mid-brand */
.vp5-products .rg-role{display:none}
.vp5-products .rg-brand{
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  letter-spacing:.06em;font-size:.75rem;color:var(--sage-label);
}
.vp5-products .rg-name{
  font-size:.86rem;line-height:1.38;min-height:calc(1.38em * 3);
  overflow:visible;
}
.vp5-products .rg-item{display:flex;flex-direction:column}
.vp5-products .rg-price{margin-top:auto;padding-top:8px}
.book-card{
  background:var(--pine);color:var(--bone);border-radius:var(--radius-card);
  box-shadow:var(--e2);padding:clamp(24px,2.6vw,40px);
  display:flex;flex-direction:column;gap:var(--s4);
  position:relative;isolation:isolate;overflow:hidden;
}
.book-card::before{content:"";position:absolute;inset:0;z-index:-1;
  background:radial-gradient(120% 100% at 80% 0%,rgba(163,173,146,.14),transparent 60%)}
.book-card h2{font-size:clamp(1.5rem,2.4vw,2.1rem);max-width:14ch}
.book-card p{color:var(--bone-dim);font-size:.95rem;max-width:36ch}
.book-card .btn{background:var(--glass-fill);color:var(--bone);
  border-color:var(--glass-edge-strong);align-self:flex-start}
.book-card .btn:hover{background:var(--glass-hover)}
.bc-links{margin-top:var(--s5);border-top:1px solid rgba(247,244,238,.16);padding-top:var(--s4)}
.bc-sub{margin-bottom:2px}
.bc-links a{display:flex;justify-content:space-between;gap:12px;padding:8px 0;
  color:var(--bone);font-size:.9rem;border-bottom:1px solid rgba(247,244,238,.1)}
.bc-links a:last-child{border-bottom:0}
.bc-links a:hover{color:var(--sage-on-dark)}
.bc-links a::after{content:"\2197";font-size:.75rem;color:var(--bone-dim);margin-left:2px;
  transition:transform var(--dur-tap) var(--ease-soft)}
.bc-links a:hover::after{transform:translate(2px,-2px);color:var(--sage-on-dark)}
.bc-links span{font-family:'JetBrains Mono',monospace;font-size:.75rem;
  color:var(--bone-dim);letter-spacing:.05em;white-space:nowrap}
.bc-sub{font-size:.8rem;color:var(--bone-dim)}
.bc-sub a{color:var(--bone);border-bottom:1px solid rgba(247,244,238,.3)}
/* The phone number is the highest-intent tap on a phone, and it was
   measuring 43px — one pixel under the 44px floor. Padded rather than
   line-height'd so the underline stays tight to the digits, and
   inline-block so the padding actually creates a hit area. */
.bc-sub a[href^="tel:"]{
  display:inline-block;
  padding-block:11px;
  /* the padding must not push the following text off its line */
  margin-block:-11px;
}
@media (max-width:900px){.vp5-grid{grid-template-columns:1fr}}

/* ============================================================
   PRICING BENTO — filterable, bounded, navigable
   Pills re-filter the grid with a FLIP animation (bento.js).
   Cards: name + price at rest; hover/tap lifts the card and
   reveals duration, indication and a book link in place.
   The whole thing lives in one bounded container — prices
   never render as a stacked column again.
   ============================================================ */
.bento-wrap{max-width:1240px}
.bento-pills{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:var(--s5)}
.bento-pill{
  font-family:'JetBrains Mono',monospace;font-size:.75rem;font-weight:500;
  letter-spacing:.08em;text-transform:uppercase;
  padding:9px 16px;border-radius:999px;cursor:pointer;
  border:1px solid var(--hairline);color:var(--ivory);background:var(--bg-2);
  box-shadow:0 1px 0 rgba(33,29,24,.05);
  transition:background var(--dur-tap) var(--ease-soft),
             color var(--dur-tap),border-color var(--dur-tap),
             transform var(--dur-tap) var(--ease-soft),box-shadow var(--dur-tap);
}
.bento-pill:hover{border-color:rgba(33,29,24,.4);transform:translateY(-1px);box-shadow:var(--e1)}
.bento-pill:active{transform:translateY(0) scale(.97)}
.bento-pill:focus-visible{outline:2px solid var(--sage-label);outline-offset:2px}
.bento-pill.is-on{background:var(--pine);border-color:var(--pine);color:var(--bone)}
.bento{
  position:relative;
  display:grid;gap:10px;
  grid-template-columns:repeat(4,1fr);
  grid-auto-rows:104px;
  max-height:min(62vh,560px);overflow-y:auto;
  overscroll-behavior:contain;
  padding:2px;
  scrollbar-width:thin;
}
.bento-card{
  position:relative;display:flex;flex-direction:column;justify-content:space-between;
  padding:16px 18px;border-radius:var(--radius-panel);
  background:var(--bg-2);border:1px solid var(--hairline-2);
  cursor:default;will-change:transform;
  transition:transform var(--dur-state) var(--ease-out),
             box-shadow var(--dur-state) var(--ease-out),
             border-color var(--dur-state);
}
.bento-card.is-hero{grid-column:span 2;background:linear-gradient(150deg,var(--bg-2),#F3EDDF 130%)}
.bento-card.is-hidden{display:none}
.bento-card::after{
  content:"+";position:absolute;top:10px;right:12px;
  width:20px;height:20px;border-radius:50%;
  border:1px solid var(--hairline-2);
  color:var(--sage-label);font-size:.85rem;line-height:18px;text-align:center;
  font-family:'JetBrains Mono',monospace;
  transition:transform var(--dur-tap) var(--ease-soft),border-color var(--dur-tap),
             color var(--dur-tap);
}
.bento-card:hover::after,.bento-card.is-open::after{
  transform:rotate(45deg);border-color:rgba(124,131,112,.6);color:var(--ivory);
}
.bento-card b{font-weight:400;color:var(--ivory);font-size:.98rem;line-height:1.3;letter-spacing:-.01em;padding-right:26px}
.bento-card .bp{
  font-family:'JetBrains Mono',monospace;font-size:.95rem;color:var(--ivory);
  font-variant-numeric:tabular-nums;letter-spacing:.02em;
}
.bento-card .bp small{font-size:.75rem;color:var(--ivory-mute);letter-spacing:.08em;margin-right:6px}
.bento-card .bmeta{
  position:absolute;left:8px;right:8px;top:calc(100% - 6px);z-index:5;
  background:var(--pine);color:var(--bone);border-radius:12px;
  padding:12px 14px;font-size:.8rem;line-height:1.5;
  opacity:0;transform:translateY(-4px);pointer-events:none;
  transition:opacity var(--dur-state) var(--ease-out),
             transform var(--dur-state) var(--ease-out);
  box-shadow:var(--e3);
}
.bento-card .bmeta i{font-style:normal;display:block;color:var(--sage-on-dark);
  font-family:'JetBrains Mono',monospace;font-size:.75rem;letter-spacing:.1em;
  text-transform:uppercase;margin-bottom:3px}
.bento-card .bmeta a{
  display:inline-block;margin-top:8px;color:var(--pine);background:var(--bone);
  border-radius:999px;padding:6px 14px;
  font-family:'JetBrains Mono',monospace;font-size:.75rem;font-weight:500;
  letter-spacing:.08em;text-transform:uppercase;
}
/* when the card sits low in the container, the panel opens upward
   instead of clipping against the container edge */
.bento-card.flip-up .bmeta{
  top:auto;bottom:calc(100% - 6px);
  transform:translateY(4px);
}
.bento-card.flip-up:hover .bmeta,.bento-card.flip-up.is-open .bmeta{transform:none}

.bento-card:hover,.bento-card.is-open{
  transform:translateY(-3px);border-color:rgba(124,131,112,.55);
  box-shadow:var(--e3);z-index:6;
}
.bento-card:hover .bmeta,.bento-card.is-open .bmeta{
  opacity:1;transform:none;pointer-events:auto;
}
.bento-note{margin-top:var(--s4);font-size:.82rem;color:var(--ivory-mute)}
@media (max-width:900px){
  .bento{grid-template-columns:repeat(2,1fr);grid-auto-rows:112px;max-height:58vh}
}
@media (max-width:480px){
  .bento{grid-template-columns:1fr 1fr;grid-auto-rows:118px}
  .bento-card b{font-size:.9rem}
}
@media (prefers-reduced-motion:reduce){
  .bento-card,.bento-card .bmeta,.bento-pill{transition:none}
  .bento-card:hover{transform:none}
}

/* ============================================================
   PROCESS — numbered editorial list
   ============================================================ */
.steps{counter-reset:step;max-width:660px;border-top:1px solid var(--hairline)}
.step{
  display:grid;grid-template-columns:auto 1fr;gap:clamp(20px,3vw,40px);
  padding:var(--s5) 0;border-bottom:1px solid var(--hairline-2);align-items:baseline;
}
.step::before{
  counter-increment:step;content:counter(step,decimal-leading-zero);
  font-family:'JetBrains Mono',monospace;font-size:.82rem;letter-spacing:.06em;
  color:var(--sage-label);padding-top:.15em;
}
.step>div{background:none;border:0;box-shadow:none;padding:0;border-radius:0}
.step b{display:block;font-weight:400;font-size:1.12rem;color:var(--ivory);margin-bottom:6px}
.step p{color:var(--ivory-dim);font-size:1rem;line-height:1.62}

/* ============================================================
   FAQ (treatment detail) — disclosure rows on hairlines
   ============================================================ */
.faq{max-width:680px;border-top:1px solid var(--hairline)}
.faq details{border-bottom:1px solid var(--hairline-2);background:none;border-radius:0;padding:0;margin:0}
.faq summary{
  cursor:pointer;list-style:none;padding:var(--s5) 0;font-size:1.1rem;color:var(--ivory);
  display:flex;justify-content:space-between;gap:20px;align-items:center;
  transition:color var(--dur-state) var(--ease-soft);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--sage-label)}
.faq summary::after{
  content:"";flex:none;width:11px;height:11px;
  border-right:1.5px solid var(--sage-label);border-bottom:1.5px solid var(--sage-label);
  transform:rotate(45deg);margin-top:-4px;
  transition:transform var(--dur-state) var(--ease-out);
}
.faq details[open] summary::after{transform:rotate(-135deg);margin-top:2px}
.faq details p{color:var(--ivory-dim);padding:0 0 var(--s5);max-width:54em;font-size:1rem;line-height:1.66}

/* ============================================================
   CARDS — treatment "pairs well with", and concern/hub grids
   ============================================================ */
.related-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s4)}
.related-card{
  border:1px solid var(--hairline);border-radius:var(--radius-card);
  padding:26px;background:var(--bg-2);display:flex;flex-direction:column;gap:var(--s2);
  box-shadow:var(--e1);
  transition:transform var(--dur-state) var(--ease-out),border-color var(--dur-state),box-shadow var(--dur-state) var(--ease-out);
}
.related-card:hover{transform:translateY(-4px);border-color:rgba(124,131,112,.5);box-shadow:var(--e3)}
.related-card b{font-weight:400;font-size:1.18rem;letter-spacing:-.02em;color:var(--ivory)}
.related-card span{font-family:'JetBrains Mono',monospace;font-size:.75rem;letter-spacing:.07em;text-transform:uppercase;color:var(--ivory-dim)}
@media (max-width:760px){.related-grid{grid-template-columns:1fr}}

/* ---------- concern / treatment hub grids ---------- */
.c-treats{padding:clamp(64px,9.5vh,116px) 0}
.c-treats > .container > .eyebrow{color:var(--sage-label)}
.c-treats > .container > h2{font-size:var(--t-4);max-width:22ch;margin-bottom:var(--head-gap)}

.hub-group{
  font-size:var(--t-2);margin:var(--sec-sm) 0 var(--s5);
  padding-bottom:var(--s4);border-bottom:1px solid var(--hairline-2);
}
.hub-group:first-of-type{margin-top:var(--s6)}

/* auto-fit, not a fixed 3: four cards fill one row instead of
   stranding an orphan on line two */
.c-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:var(--s4)}
.c-card{
  position:relative;display:flex;flex-direction:column;gap:var(--s3);
  border:1px solid var(--hairline);border-radius:var(--radius-card);
  padding:30px 28px 26px;background:var(--bg-2);box-shadow:var(--e1);
  transition:transform var(--dur-state) var(--ease-out),border-color var(--dur-state),box-shadow var(--dur-state) var(--ease-out);
}
.c-card:hover{transform:translateY(-5px);border-color:rgba(124,131,112,.5);box-shadow:var(--e3)}
.c-card h3{font-size:1.3rem;letter-spacing:-.02em;color:var(--ivory)}
.c-card p{color:var(--ivory-dim);font-size:.97rem;line-height:1.58;flex:1}
.c-foot{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  border-top:1px solid var(--hairline-2);margin-top:var(--s4);padding-top:var(--s4);
}
.c-chip{
  font-family:'JetBrains Mono',monospace;font-size:.75rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ivory);border:1px solid var(--hairline);border-radius:999px;padding:7px 13px;
  font-variant-numeric:tabular-nums;
}
.c-go{
  display:inline-flex;align-items:center;gap:10px;white-space:nowrap;
  font-family:'JetBrains Mono',monospace;font-size:.75rem;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;color:var(--sage-label);
  transition:color var(--dur-state) var(--ease-soft);
}
.c-go::after{
  content:"";width:30px;height:30px;flex:none;border-radius:999px;
  border:1px solid var(--hairline);background:var(--arrow-ne-ink) center/12px no-repeat;
  transition:transform var(--dur-state) var(--ease-soft),border-color var(--dur-state);
}
.c-card:hover .c-go{color:var(--ivory)}
.c-card:hover .c-go::after{transform:translate(3px,-3px);border-color:rgba(124,131,112,.7)}
.c-card.is-soon{opacity:.55;pointer-events:none}
.c-card.is-soon .c-go{color:var(--ivory-mute)}
@media (max-width:1000px){.c-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:680px){.c-grid{grid-template-columns:1fr}}

/* ============================================================
   CONCERN NARRATIVE — intro + editorial heading|prose splits
   ============================================================ */
.band-sec{padding:clamp(64px,9.5vh,116px) 0}
.c-narrative{padding-block:clamp(64px,9.5vh,116px) 0}

/* the opening statement — a large lead, not a bordered card.
   Champagne rule in, display scale up: reads as a pull-quote. */
.c-intro{max-width:62ch;margin-bottom:var(--sec-sm);
  background:none;border:0;box-shadow:none;padding:0;border-radius:0}
.c-intro::before{
  content:"";display:block;width:64px;height:2px;
  background:var(--champagne);margin-bottom:var(--s5);
}
.c-intro p{
  font-family:'Expose',sans-serif;font-weight:500;
  font-size:clamp(1.5rem,2.7vw,2.2rem);line-height:1.28;
  letter-spacing:-.018em;color:var(--ivory);
}
.c-intro p + p{
  font-family:'Bespoke Sans','Helvetica Neue',sans-serif;font-weight:300;
  font-size:1.05rem;line-height:1.7;color:var(--ivory-dim);letter-spacing:0;margin-top:var(--s5);
}

/* heading left, explanation right — hairline between movements */
.c-sec{
  display:grid;grid-template-columns:minmax(0,.34fr) minmax(0,.66fr);
  gap:clamp(32px,5vw,90px);align-items:start;
  padding-block:clamp(48px,7vh,80px);border-top:1px solid var(--hairline-2);
  /* the treatment detail pages drop .c-sec straight into the page with no
     .container, so the heading column sat at left:0 — 100px outside every
     other block on the page at 1440. This inset reproduces .container's
     measure (1240 max, 24px minimum gutter) while leaving the border-top
     full-bleed, which is the point of the hairline. */
  padding-inline:max(24px,calc((100% - 1240px) / 2));
}
/* where .c-sec is already inside a .container the measure is set, and this
   would inset it a second time */
.container .c-sec{padding-inline:0}
.c-sec h2{font-size:var(--t-3);max-width:16ch;margin:0;color:var(--ivory)}
.c-sec .prose{max-width:64ch;background:none;border:0;box-shadow:none;padding:0;border-radius:0}
.c-sec .prose > p:first-child{
  font-family:'Expose',sans-serif;font-weight:500;
  font-size:clamp(1.08rem,1.5vw,1.28rem);line-height:1.42;letter-spacing:-.012em;color:var(--ivory);
}
.c-sec .prose p + p,.c-sec .prose ul + p,.c-sec .prose p + ul{margin-top:var(--s5)}
.c-sec .prose ul{list-style:none;display:flex;flex-direction:column;gap:var(--s4)}
.c-sec .prose li{position:relative;padding-left:24px;color:var(--ivory-dim);font-size:1.02rem;line-height:1.55}
.c-sec .prose li::before{content:"";position:absolute;left:0;top:.62em;width:12px;height:1px;background:var(--champagne)}
@media (max-width:900px){
  .c-sec{grid-template-columns:1fr;gap:var(--s5)}
  .c-sec h2{max-width:22ch}
}

/* ============================================================
   CONCERN FAQ — hairline disclosure rows
   ============================================================ */
.c-faq{padding-block:clamp(56px,8vh,96px);border-top:1px solid var(--hairline)}
.c-faq > h2{font-size:var(--t-3);margin-bottom:var(--s5);color:var(--ivory)}
.faq-row{
  border-bottom:1px solid var(--hairline-2);background:none;border-radius:0;
  margin:0;padding:0;transition:none;
}
.faq-row summary{
  list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;
  gap:var(--s5);padding:var(--s5) 0;min-height:0;
}
.faq-row summary::-webkit-details-marker{display:none}
.faq-row summary h3{font-size:var(--t-2);font-weight:400;margin:0;color:var(--ivory);transition:color .3s}
.faq-row summary::after{
  content:"";flex:none;width:11px;height:11px;
  border-right:1.5px solid var(--sage-label);border-bottom:1.5px solid var(--sage-label);
  transform:rotate(45deg);margin-top:-4px;transition:transform var(--dur-state) var(--ease-out);
}
.faq-row[open] summary::after{transform:rotate(-135deg);margin-top:2px}
.faq-row summary:hover h3{color:var(--sage-label)}
.faq-row > p{color:var(--ivory-dim);max-width:70ch;padding:0 0 var(--s5);margin:0;line-height:1.66}

/* ============================================================
   "AT HOME" — routine lead + regimen grid
   ============================================================ */
.c-home{margin-top:var(--sec-sm)}
.c-home .eyebrow{color:var(--sage-label)}
.c-home h3{font-size:var(--t-3);margin:var(--s3) 0 var(--s4);color:var(--ivory)}
.c-home-lede{
  max-width:60ch;margin-bottom:var(--s6);
  background:none;border:0;box-shadow:none;padding:0;border-radius:0;
  font-family:'Expose',sans-serif;font-weight:500;
  font-size:clamp(1.1rem,1.6vw,1.35rem);line-height:1.4;letter-spacing:-.012em;color:var(--ivory);
}
.c-products{
  margin-top:var(--s7);max-width:60ch;color:var(--ivory-dim);
  background:none;border:0;box-shadow:none;padding:0;border-radius:0;
}
.c-products .c-go{margin-top:var(--s4)}

/* regimen grid — individual product cards.
   The old construction (1px gaps over a grey backdrop) painted the
   backdrop across every empty cell, so a short row rendered as grey
   slabs. Cards carry their own border; empty space is just the page. */
.rg-grid{
  display:grid;gap:12px;
  grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
  background:none;border:0;border-radius:0;overflow:visible;
}
.rg-grid--flat{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}
.rg-item{display:flex;flex-direction:column;gap:5px;background:var(--bg-2);
  border:1px solid var(--hairline-2);border-radius:var(--radius-panel);
  padding:var(--s5) var(--s4);transition:background .3s var(--ease-out)}
.rg-item:hover{filter:brightness(1.02)}
.rg-shot{display:block;background:var(--putty,#EFE9DE);border-radius:12px;overflow:hidden;margin-bottom:var(--s4)}
.rg-shot img{width:100%;height:auto;aspect-ratio:1/1;object-fit:contain;display:block;mix-blend-mode:multiply}
.rg-shot.is-empty{aspect-ratio:1/1}
.rg-role{color:var(--sage-label);font-size:.75rem;letter-spacing:.14em;text-transform:uppercase}
.rg-brand{color:var(--ivory-mute);font-size:.75rem}
.rg-name{font-size:var(--t-s);color:var(--ivory);line-height:1.3;flex:1}
.rg-price{color:var(--ivory-dim);font-size:.78rem;margin-top:var(--s3)}
.rg-more{display:inline-block;margin-top:var(--s5);color:var(--sage-label);border-bottom:1px solid var(--hairline-2);padding-bottom:3px}
.rg-more:hover{color:var(--ivory);border-bottom-color:var(--ivory)}
.rg-group{display:block;margin:var(--s6) 0 var(--s4);font-size:.75rem;letter-spacing:.16em;text-transform:uppercase;color:var(--sage-label)}
.rg-group:first-child{margin-top:0}
.rg-grid + .rg-group{margin-top:var(--s7)}
@media (max-width:1080px){.rg-grid{grid-template-columns:repeat(3,1fr)}}
@media (max-width:760px){
  .rg-grid{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;gap:12px;
    scrollbar-width:none;background:none;border:0;border-radius:0;
    margin-inline:calc(var(--gutter,24px) * -1);padding-inline:var(--gutter,24px);padding-bottom:12px}
  .rg-grid::-webkit-scrollbar{display:none}
  .rg-grid > .rg-item{flex:0 0 62%;scroll-snap-align:start;border:1px solid var(--hairline-2);border-radius:var(--radius-panel)}
}

/* ============================================================
   PINE FEATURE BAND — .sec-pine
   A dark anchor dropped into the light run at an important
   moment. Everything inside flips to the on-dark palette (bone
   text, sage-on-dark labels, translucent-bone surfaces and
   hairlines) so contrast holds. The sticky nav auto-detects the
   dark ground and tints itself. Reusable on any section.
   ============================================================ */
.sec-pine{
  background:var(--pine);color:var(--bone);
  border-block:1px solid rgba(247,244,238,.12);
  padding-block:clamp(64px,10vh,120px);
}
.sec-pine .section-head .eyebrow,
.sec-pine .eyebrow{color:var(--sage-on-dark)}
.sec-pine h2,.sec-pine h3,.sec-pine .c-sec h2{color:var(--bone)}
.sec-pine .section-head p{color:var(--bone-dim)}

/* prose + lists on pine */
.sec-pine .prose{color:var(--bone-dim)}
.sec-pine .two-col .prose>p:first-child,
.sec-pine .c-sec .prose>p:first-child,
.sec-pine .prose.lead>p:first-child{color:var(--bone)}
.sec-pine .prose a{color:var(--bone);border-bottom-color:var(--sage-on-dark)}
.sec-pine .prose a:hover{border-bottom-color:var(--bone)}
.sec-pine .prose strong{color:var(--bone)}
.sec-pine .c-sec{border-top-color:rgba(247,244,238,.14)}
.sec-pine .c-sec .prose li{color:var(--bone-dim)}
.sec-pine .c-sec .prose li::before{background:var(--sage-on-dark)}

/* benefits index on pine */
.sec-pine .benefits ul{border-top-color:rgba(247,244,238,.22)}
.sec-pine .benefits li{color:var(--bone);border-bottom-color:rgba(247,244,238,.12)}
.sec-pine .benefits li::before{background:var(--sage-on-dark)}

/* price sheet on pine — a translucent lift, not a bright card */
.sec-pine .price-table{
  background:rgba(247,244,238,.06);border-color:rgba(247,244,238,.16);box-shadow:none;
}
.sec-pine .price-row{border-bottom-color:rgba(247,244,238,.12)}
.sec-pine .price-row b,.sec-pine .price-row span{color:var(--bone)}
.sec-pine .price-note{color:var(--bone-dim)}
.sec-pine .price-note::before{background:var(--sage-on-dark)}

/* process steps on pine */
.sec-pine .steps{border-top-color:rgba(247,244,238,.22)}
.sec-pine .step{border-bottom-color:rgba(247,244,238,.12)}
.sec-pine .step::before{color:var(--sage-on-dark)}
.sec-pine .step b{color:var(--bone)}
.sec-pine .step p{color:var(--bone-dim)}

/* faq on pine */
.sec-pine .faq{border-top-color:rgba(247,244,238,.22)}
.sec-pine .faq details{border-bottom-color:rgba(247,244,238,.12)}
.sec-pine .faq summary{color:var(--bone)}
.sec-pine .faq summary:hover{color:var(--sage-on-dark)}
.sec-pine .faq summary::after{border-color:var(--sage-on-dark)}
.sec-pine .faq details p{color:var(--bone-dim)}

/* a CTA sitting on pine takes the inverted button */
.sec-pine .btn{background:var(--bone);color:var(--pine)}
.sec-pine .btn:hover{background:var(--glass-hover)}

/* ============================================================
   SCANNABLE LISTS — turn dense prose bullets into termed entries
   The concern narrative lists ("types of…", "treatment options")
   read as paragraphs. Promoting the lead term to its own line,
   with the description beneath and a hairline between entries,
   makes them scannable and breaks the wall of text.
   ============================================================ */
.c-sec .prose li{padding:var(--s4) 0 var(--s4) 24px;border-bottom:1px solid var(--hairline-2)}
.c-sec .prose ul{gap:0;border-top:1px solid var(--hairline)}
.c-sec .prose li:last-child{border-bottom:0}
.c-sec .prose li strong{
  display:block;color:var(--ivory);font-weight:500;
  font-size:1.06rem;letter-spacing:-.01em;margin-bottom:3px;
}
.c-sec .prose li strong a{border-bottom:1px solid var(--sage-label)}
.sec-pine .c-sec .prose li strong{color:var(--bone)}
.sec-pine .c-sec .prose li strong a{border-bottom-color:var(--sage-on-dark)}

/* ============================================================
   BOOK BAND (pine) — treatment detail pages
   ============================================================ */
.book-band{background:var(--pine);color:var(--bone);text-align:center}
.book-band h2{font-size:clamp(2rem,4.2vw,3.1rem);max-width:15em;margin:0 auto var(--s5)}
.book-band p{color:var(--bone-dim);max-width:34em;margin:0 auto var(--s6)}
.book-band .btn{background:var(--bone);color:var(--pine)}
.book-band .btn:hover{background:var(--glass-hover)}
.book-band .sub{font-size:.85rem;margin-top:22px;color:var(--bone-dim)}
.book-band .sub a{color:var(--bone);border-bottom:1px solid rgba(247,244,238,.35)}
.book-band .sub a:hover{color:var(--sage-on-dark)}

/* ============================================================
   MICRO-INTERACTIONS + focus parity
   ============================================================ */
.rg-item{transition:transform var(--dur-state) var(--ease-soft),box-shadow var(--dur-state) var(--ease-soft),background-color var(--dur-state) var(--ease-soft)}
.rg-item:hover{transform:translateY(-2px);box-shadow:var(--e2)}
.rg-item .rg-shot img{transition:transform var(--dur-amb) var(--ease-out)}
.rg-item:hover .rg-shot img{transform:scale(1.05)}
.c-card:focus-visible,.related-card:focus-visible,.rg-item:focus-visible{
  outline:2px solid var(--sage-label);outline-offset:3px;border-radius:var(--radius-card);
}
@media (prefers-reduced-motion:reduce){
  .rg-item,.rg-item .rg-shot img{transition:none}
  .rg-item:hover{transform:none}
  .rg-item:hover .rg-shot img{transform:none}
}

/* ============================================================
   MOTION LAYER
   Hero parallax (driven by subpage-motion.js) and the FAQ open
   reveal. Transform/opacity only; the whole block is gated on
   prefers-reduced-motion so a reader who opts out gets an instant,
   static page with no drift and no open animation.
   ============================================================ */
@media (prefers-reduced-motion:no-preference){
  /* the hero frame is the only element JS transforms on scroll */
  .t-hero-img{will-change:transform}

  /* the answer settles in rather than snapping when a row opens */
  .faq details[open] > p,
  .faq-row[open] > p{
    animation:faq-reveal var(--dur-state) var(--ease-out) both;
  }
  @keyframes faq-reveal{
    from{opacity:0;transform:translate3d(0,-6px,0)}
    to  {opacity:1;transform:none}
  }
}

/* ============================================================
   MOBILE REFINEMENTS
   The grids already collapse (two-col/c-sec 860, c-grid 680,
   related 760, benefits/price 640, regimen → rail 760). These
   are the edge cases those breakpoints don't cover: stacked-hero
   image sizing, long single-word titles at 320px, and price rows
   whose label + figure would collide on a narrow phone.
   body{overflow-x:clip} in base.css is the backstop against any
   sideways scroll.
   ============================================================ */
@media (max-width:860px){
  .t-hero-grid{gap:var(--s6)}
  .t-hero > .container{padding-top:clamp(104px,16vh,150px)}
  .t-hero-img{max-width:520px;margin-inline:auto}   /* centre, don't stretch */
}
@media (max-width:560px){
  /* a long title ("Pigmentation", "Microblading") must not overrun the gutter */
  .t-hero h1{font-size:clamp(2.1rem,8.5vw,2.75rem)}
  .t-hero h1,.book-band h2,.c-sec h2,.section-head h2{overflow-wrap:break-word}
  .section-head{max-width:100%}
  /* long price labels wrap above the figure instead of colliding with it */
  .price-row{flex-wrap:wrap;gap:2px var(--s4)}
  .price-row b{min-width:0}
  /* full-width tap surfaces for the disclosure rows */
  .faq summary,.faq-row summary{gap:var(--s4)}
}

/* ============================================================
   AESTHETIC DETAIL — depth, texture, editorial marks
   The pages read flat: text on plain grounds. These add the
   detail that lifts them without adding a single image —
   a fine film grain over every ground, a soft light in the
   dark bands, editorial section numbering, and a touch of
   sage in the hero meta. Decorative only; nothing shifts
   layout, everything is pointer-events:none or ::before text.
   ============================================================ */

/* ---- film grain: one fixed layer over the whole page ---- */
body::after{
  content:"";position:fixed;inset:0;z-index:4;pointer-events:none;
  opacity:.055;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:160px 160px;
}

/* ---- soft light in the dark bands, so pine has depth ---- */
.t-hero,.sec-pine,.book-band{position:relative;isolation:isolate}
.t-hero::after,.sec-pine::before,.book-band::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(120% 90% at 12% 0%,
    rgba(163,173,146,.16), transparent 58%);
}
.sec-pine::before{background:radial-gradient(110% 120% at 85% 0%,
    rgba(163,173,146,.12), transparent 55%)}
.book-band::before{background:radial-gradient(80% 120% at 50% 0%,
    rgba(163,173,146,.12), transparent 60%)}

/* Numbered eyebrows and ghost numerals were tried here and removed:
   numbering every section is scaffolding, not voice. The heading
   scale and one champagne rule carry the hierarchy instead. */
.c-sec h2{position:relative;font-size:var(--t-4);max-width:14ch}
.c-sec h2::after{
  content:"";display:block;width:44px;height:2px;
  background:var(--champagne);margin-top:var(--s4);
}
.sec-pine .c-sec h2::after{background:var(--sage-on-dark)}

/* ---- hero meta: a sage bead on each chip ---- */
.chip{display:inline-flex;align-items:center;gap:9px}
.chip::before{
  content:"";width:5px;height:5px;border-radius:50%;
  background:var(--sage-on-dark);flex:none;
}
.chip a{color:inherit}

/* ---- lead paragraphs: a raised sage initial ---- */
.two-col .prose>p:first-child::first-letter,
.c-intro>p:first-child::first-letter{
  color:var(--champagne);font-weight:500;
}

/* ============================================================
   BEFORE / AFTER — draggable wipe slider
   Two portrait frames stacked; the top (before) is clipped to a
   handle position the reader drags. A range input drives it, so
   it is keyboard-accessible and touch-friendly for free. Result
   photography is proof — the strongest way to break the text.
   ============================================================ */
.ba-band{padding-block:clamp(64px,9.5vh,116px)}
.ba-figure{max-width:560px;margin-inline:auto}
.ba{
  position:relative;aspect-ratio:1000/1493;--pos:50%;
  border-radius:var(--radius-card);overflow:hidden;isolation:isolate;
  border:1px solid var(--hairline);box-shadow:var(--e2);
  touch-action:pan-y;user-select:none;
}
.ba-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.ba-before{clip-path:inset(0 calc(100% - var(--pos)) 0 0)}
.ba-divider{
  position:absolute;top:0;bottom:0;left:var(--pos);width:2px;
  background:var(--bone);transform:translateX(-1px);pointer-events:none;
  box-shadow:0 0 0 1px rgba(33,29,24,.18);
}
.ba-divider::after{
  content:"";position:absolute;top:50%;left:50%;width:46px;height:46px;
  transform:translate(-50%,-50%);border-radius:999px;background:var(--bone);
  box-shadow:var(--e2);background-repeat:no-repeat;background-position:center;
  background-size:22px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23211D18' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 7l-4 5 4 5M15 7l4 5-4 5'/%3E%3C/svg%3E");
}
.ba-range{
  position:absolute;inset:0;width:100%;height:100%;margin:0;
  opacity:0;cursor:ew-resize;
}
.ba:focus-within .ba-divider::after{outline:2px solid var(--sage-label);outline-offset:3px}
.ba-cap{
  margin-top:var(--s4);text-align:center;
  font-size:.82rem;color:var(--ivory-dim);
}

/* ============================================================
   SPLIT PANEL — full-bleed diagonal image/text feature band
   One wedge is a full-bleed photo cut on a diagonal; the other
   is a colour ground carrying one heading + one line. Alternate
   side (.sp-left) and ground (.sp-light) down the page so a run
   of identical cards becomes a sequence of distinct panels.
   Swap real imagery into .sp-media later.
   ============================================================ */
.split-panel{
  position:relative;isolation:isolate;overflow:hidden;
  display:grid;grid-template-columns:1fr 1fr;align-items:center;
  min-height:min(86vh,720px);
  background:var(--pine);color:var(--bone);
}
.split-panel .sp-media{
  position:absolute;inset:0;margin:0;z-index:-1;
  clip-path:polygon(40% 0, 100% 0, 100% 100%, 54% 100%);
}
.split-panel .sp-media img{width:100%;height:100%;object-fit:cover;display:block}
.split-panel .sp-copy{grid-column:1;padding:clamp(40px,6vw,100px);max-width:34em}
.split-panel .sp-copy .eyebrow{color:var(--sage-on-dark);margin-bottom:var(--s4)}
.split-panel .sp-copy h2{font-size:var(--t-4);margin-bottom:var(--s4)}
.split-panel .sp-copy p{color:var(--bone-dim);max-width:30em;font-size:1.05rem;line-height:1.7}

/* image on the LEFT, copy on the right */
.split-panel.sp-left .sp-media{clip-path:polygon(0 0, 60% 0, 46% 100%, 0 100%)}
.split-panel.sp-left .sp-copy{grid-column:2}

/* light text-ground variant */
.split-panel.sp-light{background:var(--bg);color:var(--ivory)}
.split-panel.sp-light .sp-copy .eyebrow{color:var(--sage-label)}
.split-panel.sp-light .sp-copy p{color:var(--ivory-dim)}

@media (max-width:760px){
  /* stack: photo on top, copy beneath — no diagonal on a phone */
  .split-panel{grid-template-columns:1fr;min-height:0}
  .split-panel .sp-media,
  .split-panel.sp-left .sp-media{
    position:relative;clip-path:none;height:62vw;max-height:440px;z-index:0;
  }
  .split-panel .sp-copy,
  .split-panel.sp-left .sp-copy{grid-column:1;padding:clamp(28px,7vw,48px)}
}

/* ============================================================
   SCROLL STACK — pinned story panels (the Sciton idiom)
   Each panel pins at the top of the viewport; the next scrolls
   up and covers it, so the section reads as a sequence of
   full-screen chapters. Pure position:sticky — no scroll-jack,
   nothing to run at 60fps because the compositor does the work.
   Panel = full-bleed image + directional scrim + one statement.
   ============================================================ */
.stack{position:relative}
/* Was position:sticky at 100svh — three full-screen pinned covers
   read as too much page. Normal flow at 72vh keeps the full-bleed
   drama without holding the reader hostage. */
.stack-panel{
  position:relative;min-height:min(72vh,640px);
  display:flex;align-items:center;overflow:hidden;
  background:var(--pine);color:var(--bone);isolation:isolate;
}
.stack-panel .st-media{position:absolute;inset:0;margin:0;z-index:-2}
.stack-panel .st-media img{width:100%;height:100%;object-fit:cover;display:block}
.stack-panel::after{           /* directional scrim keeps copy readable */
  content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(92deg,
    rgba(34,38,30,.88) 0%, rgba(34,38,30,.72) 40%, rgba(34,38,30,.12) 78%);
}
.stack-panel.st-right::after{
  background:linear-gradient(268deg,
    rgba(34,38,30,.92) 0%, rgba(34,38,30,.8) 42%, rgba(34,38,30,.14) 80%);
}
.stack-panel .st-copy{
  position:relative;width:min(1240px,calc(100% - 48px));margin-inline:auto;
  padding-block:clamp(48px,8vh,88px);
}
.stack-panel .st-inner{max-width:30em}
.stack-panel.st-right .st-inner{margin-left:auto}
.stack-panel .eyebrow{color:var(--sage-on-dark);margin-bottom:var(--s4)}
.stack-panel h3{
  font-size:clamp(2rem,4.6vw,3.6rem);line-height:1.06;
  letter-spacing:-.022em;margin-bottom:var(--s4);color:var(--bone);
}
.stack-panel p{color:var(--bone-dim);font-size:1.08rem;line-height:1.65;max-width:26em}
.stack-panel .st-index{
  font-family:'JetBrains Mono',monospace;font-size:.75rem;
  letter-spacing:.18em;color:var(--sage-on-dark);
  display:block;margin-top:var(--s6);
}
/* seam: each incoming panel carries a hairline lip so the cover
   reads as a surface arriving, not a jump cut */
.stack-panel + .stack-panel,
.stack .stack-panel:not(:first-child){box-shadow:0 -1px 0 rgba(247,244,238,.18)}
@media (max-width:760px){
  .stack-panel{min-height:70svh}
  .stack-panel::after,.stack-panel.st-right::after{
    background:linear-gradient(180deg,
      rgba(34,38,30,.2) 0%, rgba(34,38,30,.82) 62%, rgba(34,38,30,.92) 100%);
  }
  .stack-panel .st-copy{display:flex;align-items:flex-end;min-height:70svh}
  .stack-panel .st-inner,.stack-panel.st-right .st-inner{margin:0}
}

/* ============================================================
   INTERACTION LAYER — cursor halo, marquee ribbon
   ============================================================ */
#cur-dot{
  position:fixed;left:0;top:0;z-index:9990;pointer-events:none;
  width:8px;height:8px;border-radius:50%;background:var(--pine);
  transition:transform-origin 0s, scale .25s, background-color .25s, opacity .25s;
  transition:scale .25s cubic-bezier(.16,1,.3,1), background-color .25s, opacity .25s;
}
#cur-dot.is-act{scale:2.2;background:var(--sage-label)}
#cur-dot.is-out{opacity:0}
@media (hover:none),(prefers-reduced-motion:reduce){#cur-dot{display:none}}

/* the closing ribbon: kinetic editorial type above the footer */
.mq{
  background:var(--pine);color:var(--bone);overflow:hidden;
  padding:clamp(20px,3vh,34px) 0;border-block:1px solid rgba(247,244,238,.1);
}
.mq-track{
  display:flex;gap:0;white-space:nowrap;width:max-content;
  animation:mq-roll 46s linear infinite;
}
.mq i{
  font-style:normal;font-family:'Expose',sans-serif;font-weight:500;
  font-size:clamp(1.7rem,3.4vw,2.9rem);letter-spacing:-.02em;
  padding-right:1.2em;
}
.mq i:nth-child(even){
  color:transparent;-webkit-text-stroke:1px rgba(247,244,238,.5);
}
@keyframes mq-roll{from{transform:translate3d(0,0,0)}to{transform:translate3d(-50%,0,0)}}
.mq:hover .mq-track{animation-play-state:paused}
@media (prefers-reduced-motion:reduce){.mq-track{animation:none}}


/* ============================================================
   PRODUCT RAIL ON MOBILE — two rows, not one long one

   At 375px a single row of 204px cards meant ~20 cards of
   sideways travel to see a shelf, which is a lot of scrolling
   for one section. Two rows halve that distance and let each
   card be smaller, so more of the shelf is legible at once.

   Column flow is what makes it work: items fill DOWN then
   ACROSS, so the pair in each column stays together and the
   reading order still matches the DOM. It also keeps
   rail-auto.js honest — with 2 rows, the first clone still
   begins exactly one set-width along, so the seamless loop
   measures the same as it does on desktop.
   ============================================================ */
@media (max-width:760px){
  .vp5-products .rg-grid{
    display:grid;
    grid-auto-flow:column;
    grid-template-rows:repeat(2,auto);
    grid-auto-columns:46%;      /* ~2.2 columns in view: the cut edge
                                   is the affordance that says "more" */
    align-items:start;
    gap:10px 10px;
  }
  /* flex sizing has no meaning in a grid track */
  .vp5-products .rg-grid > .rg-item{flex:none;width:auto}

  /* the card gets smaller, so the shot has to give up the most */
  .vp5-products .rg-shot{margin-bottom:var(--s3)}
  .vp5-products .rg-name{
    font-size:.82rem;line-height:1.35;
    /* two lines, not three — at this width three reserved lines
       left a visible gap under every short product name */
    min-height:calc(1.35em * 2);
  }
  .vp5-products .rg-brand{font-size:.75rem}
  .vp5-products .rg-price{font-size:.75rem;padding-top:6px}
}

/* A hero awaiting its photograph. Holds the exact box the image will
   occupy so the layout does not shift when it lands, and reads as a
   deliberate empty plate rather than a broken image. */
.t-hero-img.is-awaiting{
  /* with no <img> inside there is nothing to give the figure width, so
     it collapsed to 2px in the single-column mobile grid */
  width:100%;
  background:
    linear-gradient(135deg, rgba(247,244,238,.07), rgba(247,244,238,.02));
  box-shadow:inset 0 1px 0 rgba(247,244,238,.14);
}

/* ============================================================
   ICON SYSTEM — base class + draw-on entrance
   ============================================================ */
.ic{width:20px;height:20px;flex:none;display:inline-block;vertical-align:-4px}
.ic *{vector-effect:non-scaling-stroke}
@media (prefers-reduced-motion:no-preference){
  .ic-draw path,.ic-draw circle,.ic-draw rect{
    stroke-dasharray:60;stroke-dashoffset:60;
    animation:ic-draw .9s cubic-bezier(.16,1,.3,1) forwards;
  }
  @keyframes ic-draw{to{stroke-dashoffset:0}}
}

/* footer + card icon rows */
.ic-row{display:flex;align-items:center;gap:10px}
.ic-row .ic{width:17px;height:17px;opacity:.75}

/* MOBILE BOOKING DOCK — moved to chrome.css.
   The .dock markup ships on 42 pages, but this stylesheet is linked by only
   some of them: index, shop, packages and team never load it, so the dock
   arrived unstyled there and fell into normal flow as raw "Book Call" text
   under the footer. chrome.css is loaded by every page carrying the markup,
   so the rules live there now. */

/* ============================================================
   PRICING STEPPER — one chaptered pine card. Built by pricer.js
   from the bento markup; bento grid + pills hide when it exists.
   ============================================================ */
.has-pricer .bento,
.has-pricer .bento-pills,
.has-pricer .bento-note,
.has-pricer .section-head h2,
.has-pricer .section-head p{display:none}
.has-pricer .section-head{margin-bottom:18px}

.pricer{
  position:relative;max-width:720px;margin:0 auto;
  background:var(--pine);color:var(--bone);border-radius:var(--radius-card);
  padding:clamp(24px,3.4vw,36px) clamp(22px,4.5vw,48px) clamp(20px,2.6vw,28px);
  box-shadow:0 30px 70px -30px rgba(33,29,24,.45);
}
.pr-kicker{
  display:flex;justify-content:space-between;align-items:baseline;
  font-family:'JetBrains Mono',monospace;font-size:.75rem;
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--sage-on-dark,#A3AD92);margin-bottom:14px;
}
.pr-stage{position:relative;overflow:hidden;
  transition:height .5s cubic-bezier(.16,1,.3,1)}
.pr-slide{display:none}
section.pr-slide{padding:0;margin:0;min-height:0}
.pr-slide.is-on{display:block;
  transition:opacity .42s cubic-bezier(.16,1,.3,1),transform .42s cubic-bezier(.16,1,.3,1)}
.pr-slide.is-measuring{display:block;position:absolute;inset:0 0 auto;visibility:hidden}
.pr-slide.is-enter-r{opacity:0;transform:translateX(36px)}
.pr-slide.is-enter-l{opacity:0;transform:translateX(-36px)}
.pr-slide.is-exit-l,.pr-slide.is-exit-r{
  display:block;position:absolute;inset:0 0 auto;opacity:0;pointer-events:none;
  transition:opacity .3s,transform .42s cubic-bezier(.16,1,.3,1)}
.pr-slide.is-exit-l{transform:translateX(-36px)}
.pr-slide.is-exit-r{transform:translateX(36px)}

.pr-title{
  font-family:'Expose','Georgia',serif;font-weight:500;
  font-size:clamp(1.6rem,3vw,2.2rem);letter-spacing:-.015em;
  line-height:1.08;margin:0 0 4px;
}
.pr-list{list-style:none;margin:10px 0 0;padding:0}
.pr-list li{border-top:1px solid rgba(247,244,238,.14)}
.pr-list li:last-child{border-bottom:1px solid rgba(247,244,238,.14)}
.pr-list a{
  display:flex;align-items:baseline;justify-content:space-between;gap:18px;
  padding:10px 2px;text-decoration:none;color:inherit;
  transition:background-color .25s,padding .25s;
}
.pr-list a:hover{background:rgba(247,244,238,.05);padding-left:10px;padding-right:10px}
.pr-name{font-size:.96rem;line-height:1.4}
.pr-desc{font-size:.76rem;color:rgba(247,244,238,.72);margin-left:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:34ch;display:inline-block;vertical-align:baseline}
@media (max-width:760px){.pr-desc{display:block;margin:2px 0 0;white-space:normal;max-width:none}}
.pr-tag{
  display:inline-block;vertical-align:2px;font-style:normal;
  font-family:'JetBrains Mono',monospace;font-size:.75rem;
  letter-spacing:.12em;text-transform:uppercase;
  color:var(--pine);background:var(--sage-on-dark,#A3AD92);
  border-radius:999px;padding:2px 8px;margin-left:8px;
}
.pr-price{
  font-family:'JetBrains Mono',monospace;font-size:.9rem;
  color:#F7F4EE;white-space:nowrap;
}

.pr-nav{display:flex;align-items:center;justify-content:space-between;
  gap:14px;margin-top:16px}
.pr-arr{
  width:46px;height:46px;border-radius:50%;flex:0 0 auto;cursor:pointer;
  background:none;border:1px solid rgba(247,244,238,.28);color:#F7F4EE;
  display:flex;align-items:center;justify-content:center;
  transition:background-color .25s,border-color .25s,transform .25s;
}
.pr-arr:hover{background:rgba(247,244,238,.1);border-color:rgba(247,244,238,.5)}
.pr-arr:active{transform:scale(.94)}
.pr-arr svg{width:18px;height:18px}
.pr-dots{display:flex;gap:10px;align-items:center}
.pr-dot{
  width:7px;height:7px;border-radius:50%;border:0;padding:0;cursor:pointer;
  background:rgba(247,244,238,.28);
  transition:background-color .25s,transform .25s;
}
.pr-dot:hover{transform:scale(1.5)}
.pr-dot.is-on{background:#F7F4EE;transform:scale(1.3)}

.pr-ctas{display:flex;gap:12px;margin-top:14px}
.pr-cta{
  flex:1;text-align:center;text-decoration:none;border-radius:999px;
  padding:15px 18px;font-family:'JetBrains Mono',monospace;
  font-size:.75rem;letter-spacing:.1em;text-transform:uppercase;
  transition:transform .25s,background-color .25s,color .25s;
}
.pr-cta--ghost{color:#F7F4EE;border:1px solid rgba(247,244,238,.3)}
.pr-cta--ghost:hover{border-color:rgba(247,244,238,.6)}
.pr-cta--solid{background:var(--bone,#FDFBF6);color:var(--pine)}
.pr-cta--solid:hover{transform:translateY(-1px)}
.pr-note{max-width:70ch;
  margin:14px 2px 0;font-size:.75rem;line-height:1.5;
  color:rgba(247,244,238,.66);   /* .45 measured 3.12:1 on pine at 12px */
}

@media (max-width:760px){
  .pricer{border-radius:20px;margin-inline:-6px}
  .pr-list a{display:grid;grid-template-columns:1fr auto;align-items:baseline;gap:0 14px}
  .pr-desc{grid-column:1 / -1}
  .pr-price{font-size:.85rem}
  .pr-arr{width:42px;height:42px}
  .pr-ctas{flex-direction:column-reverse}
}
@media (prefers-reduced-motion:reduce){
  .pr-stage{transition:none}
  .pr-slide.is-on{transition:none}
}

/* ---- glass scene: photo ground + frosted card ---- */
.pr-scene{position:relative;overflow:hidden}
.pr-scene::before{
  content:"";position:absolute;inset:0;z-index:0;
  background-image:var(--pr-img);background-size:cover;background-position:center;
  transform:scale(1.04);
}
.pr-scene::after{
  content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(33,29,24,.48),rgba(33,29,24,.68));
}
.pr-scene .container{position:relative;z-index:2}
.pr-scene .section-head .eyebrow{color:var(--sage-on-dark,#A3AD92)}
.pr-scene .pricer{
  background:rgba(33,29,24,.36);
  -webkit-backdrop-filter:blur(26px) saturate(1.35);
  backdrop-filter:blur(26px) saturate(1.35);
  border:1px solid rgba(255,255,255,.14);
  box-shadow:0 34px 80px -30px rgba(0,0,0,.55);
}
.pr-scene .pr-list li{border-top-color:rgba(247,244,238,.16)}
.pr-scene .pr-list li:last-child{border-bottom-color:rgba(247,244,238,.16)}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .pr-scene .pricer{background:rgba(33,29,24,.92)}
}

/* ---- pricer texture + variants (lab) ---- */
.pricer.has-grain::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  opacity:.06;mix-blend-mode:overlay;
}
.pricer.v-light{
  background:var(--bone,#FDFBF6);color:var(--ink,#211D18);
  border:1px solid rgba(33,29,24,.1);
  box-shadow:0 26px 60px -28px rgba(33,29,24,.28);
}
.pricer.v-light.has-grain::after{opacity:.05;mix-blend-mode:multiply}
.pricer.v-light .pr-kicker{color:var(--sage-label,#4E5442)}
.pricer.v-light .pr-list li{border-top-color:rgba(33,29,24,.12)}
.pricer.v-light .pr-list li:last-child{border-bottom-color:rgba(33,29,24,.12)}
.pricer.v-light .pr-list a:hover{background:rgba(33,29,24,.04)}
.pricer.v-light .pr-desc{color:rgba(33,29,24,.55)}
.pricer.v-light .pr-price{color:var(--ink,#211D18)}
.pricer.v-light .pr-tag{background:var(--sage-label,#4E5442);color:#F7F4EE}
.pricer.v-light .pr-arr{border-color:rgba(33,29,24,.25);color:var(--ink,#211D18)}
.pricer.v-light .pr-arr:hover{background:rgba(33,29,24,.06);border-color:rgba(33,29,24,.45)}
.pricer.v-light .pr-dot{background:rgba(33,29,24,.22)}
.pricer.v-light .pr-dot.is-on{background:var(--ink,#211D18)}
.pricer.v-light .pr-cta--ghost{color:var(--ink,#211D18);border-color:rgba(33,29,24,.3)}
.pricer.v-light .pr-cta--solid{background:var(--pine,#2E3226);color:#F7F4EE}
.pricer.v-light .pr-note{color:rgba(33,29,24,.5)}

.prlab{
  position:fixed;left:50%;bottom:18px;transform:translateX(-50%);z-index:9980;
  display:flex;gap:6px;background:var(--pine,#2E3226);border-radius:999px;
  padding:6px;box-shadow:0 10px 30px -10px rgba(0,0,0,.5);
}
.prlab button{
  font-family:'JetBrains Mono',monospace;font-size:.75rem;letter-spacing:.08em;
  text-transform:uppercase;color:#F7F4EE;background:none;cursor:pointer;
  border:1px solid rgba(247,244,238,.25);border-radius:999px;padding:8px 13px;
}
.prlab button.on{background:#F7F4EE;color:var(--pine,#2E3226);border-color:#F7F4EE}

/* light textural grounds: keep the texture bright, let the card carry contrast */
.pr-scene--light::after{
  background:linear-gradient(180deg,rgba(33,29,24,.1),rgba(33,29,24,.22));
}
.pr-scene--light .section-head .eyebrow{color:var(--sage-label,#4E5442)}

/* on light textural grounds the card itself is light glass:
   milky frost, dark text, texture structure visible through it */
.pr-scene--light .pricer{
  background:rgba(253,251,246,.44);
  -webkit-backdrop-filter:blur(14px) saturate(1.15);
  backdrop-filter:blur(14px) saturate(1.15);
  border:1px solid rgba(255,255,255,.6);
  box-shadow:0 30px 70px -32px rgba(33,29,24,.35);
}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .pr-scene--light .pricer{background:rgba(253,251,246,.94)}
}

/* live opening-hours status (contact) + clinical review line */
.hours-now{margin:18px 0 4px;font-family:'JetBrains Mono',monospace;font-size:15px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--ink)}
.review-line{margin:18px 0 0;font-size:12.5px;letter-spacing:.02em;color:rgba(239,233,222,.62)}
.review-line a{color:rgba(239,233,222,.85);text-underline-offset:3px}

/* ============================================================
   FACELIFT 20260812 — the homepage's editorial voice, carried
   across every subpage. Script italics (PP Editorial New) accent
   the closing word of headline copy; hero type moves up to the
   homepage's chapter scale.
   ============================================================ */
.t-hero h1{font-size:clamp(2.9rem,6.2vw,5.4rem);letter-spacing:-.04em;line-height:.95}


/* contact hero: brand plate fills the once-empty right side */
.hero-brand-grid{display:grid;grid-template-columns:minmax(320px,1.05fr) minmax(300px,.95fr);gap:clamp(32px,5vw,80px);align-items:center}
.brand-plate{margin:0}
.brand-plate{overflow:hidden;border-radius:var(--radius-card);box-shadow:0 40px 84px -30px rgba(0,0,0,.55), inset 0 1px 0 rgba(247,244,238,.2)}
.brand-plate img{display:block;width:100%;height:auto}
@media (max-width:900px){.hero-brand-grid{grid-template-columns:1fr}.brand-plate{max-width:520px}}

/* ============================================================
   VP5 GROUND SWAP — 21 Aug 2026
   The products panel takes the pine; the booking card takes the
   bone. Scoped to .vp5-grid on purpose: about.html, contact.html
   and skin-consultation.html carry a STANDALONE .book-card that
   is not part of this pair, and it stays dark there.

   Only panel-level type flips. The product tiles are .rg-item —
   bone cards with their own ink — and they now read as objects
   sitting on the pine rather than as tints on a white field.
   ============================================================ */
.vp5-products{
  background:var(--pine);color:var(--bone);
  border-color:rgba(247,244,238,.14);
  box-shadow:var(--e2);
}
.vp5-products .c-home .eyebrow{color:var(--sage-on-dark)}
.vp5-products .c-home h3,
.vp5-products .c-home-lede{color:var(--bone)}
.vp5-products .rg-more{
  color:var(--sage-on-dark);
  border-bottom-color:rgba(247,244,238,.3);
}
.vp5-products .rg-more:hover{color:var(--bone);border-bottom-color:var(--bone)}
/* the rail's own scrollbar was a dark thumb on a dark trough */
.vp5-products .rg-grid{scrollbar-color:rgba(247,244,238,.34) transparent}

.vp5-grid .book-card{
  background:var(--bg-2);color:var(--ivory);
  border:1px solid var(--hairline-2);
  box-shadow:var(--e1);
}
/* the sage bloom was tuned to sit on pine; at .14 on bone it reads as
   a dirty corner rather than light */
.vp5-grid .book-card::before{
  background:radial-gradient(120% 100% at 80% 0%,rgba(124,131,112,.11),transparent 62%);
}
.vp5-grid .book-card p{color:var(--ivory-dim)}
.vp5-grid .book-card .eyebrow{color:var(--sage-label)}
/* back to the house button — the bone-on-pine override was for the
   dark card and would now be white on white */
.vp5-grid .book-card .btn{background:var(--glass-fill);color:var(--bone)}
.vp5-grid .book-card .btn:hover{background:var(--glass-hover)}
.vp5-grid .book-card .bc-sub{color:var(--ivory-dim)}
.vp5-grid .book-card .bc-sub a{color:var(--ivory);border-bottom-color:rgba(33,29,24,.32)}
.vp5-grid .book-card .bc-links{border-top-color:var(--hairline-2)}
.vp5-grid .book-card .bc-links a{color:var(--ivory);border-bottom-color:var(--hairline-2)}
.vp5-grid .book-card .bc-links a::after{color:var(--ivory-dim)}
.vp5-grid .book-card .bc-links span{color:var(--ivory-dim)}

/* ---- and the two faults visible in the list itself ----

   1. space-between with three flex items (name, price, the ::after
      arrow) parked the price wherever the name happened to end, so
      the column of prices was ragged. A grid fixes them to a track.
   2. hover DIMMED the row: bone -> sage-on-dark halves the contrast
      on pine, which reads as disabling the thing you are pointing
      at. The name now holds; the arrow carries the state. */
.bc-links a{
  display:grid;grid-template-columns:minmax(0,1fr) max-content 1.1em;
  align-items:baseline;gap:14px;
}
.bc-links span{justify-self:end;text-align:right}
.bc-links a::after{justify-self:end;margin-left:0}
.bc-links a:hover{color:var(--bone)}
.vp5-grid .book-card .bc-links a:hover{color:var(--ivory)}
.bc-links a:hover::after{color:var(--sage-on-dark)}
.vp5-grid .book-card .bc-links a:hover::after{color:var(--sage-label)}

/* The stray rule floating beside "South Melbourne": the tel link is
   inline-block with padding-block:11px to reach the 44px tap target,
   so its border-bottom draws at the bottom of a 47px box — 11px under
   the digits, which lands on the NEXT line of the paragraph and reads
   as a detached dash. text-decoration follows the text, not the box,
   so the tap target and the underline stop fighting. */
.bc-sub a[href^="tel:"]{
  border-bottom:0;
  text-decoration:underline;
  text-decoration-thickness:1px;
  text-underline-offset:3px;
  text-decoration-color:rgba(247,244,238,.34);
}
.vp5-grid .book-card .bc-sub a[href^="tel:"]{text-decoration-color:rgba(33,29,24,.34)}

/* ============================================================
   AUDIT FIXES — 24 Aug 2026 (rendered sweep, 40 pages x 2 widths)
   ============================================================ */
/* eyebrows on pine bands were still on the light-ground sage stop:
   #4E5442 on pine measures 2.03:1. The dark-ground stop is the token
   built for this. */
.sec-pine .eyebrow, .on-pine .eyebrow, .band-sec--pine .eyebrow { color: var(--sage-on-dark); }
/* FAQ and prose answers ran to ~85ch at 1440 — 75ch is the ceiling */
.faq p, details p { max-width: 70ch; }
/* the pricer's step dots and rail arrows were 7-10px hit targets;
   a padded hit area lifts them to 24px+ without changing the mark */
.pr-dot { position: relative; }
.pr-dot::after { content: ""; position: absolute; inset: -9px; }

/* audit: 8px story-rail dots and 15px-tall breadcrumb links were the
   two smallest hit targets on the site. Marks unchanged; hit areas
   padded to 24px+ via inset pseudo / block padding. */
.sr-dots{gap:12px}
.sr-dots button{position:relative}
.sr-dots button::after{content:"";position:absolute;inset:-9px}
.crumb a,.ix-crumb a{display:inline-block;padding-block:6px;margin-block:-6px}

/* ============================================================
   "HOW WE TREAT IT" ON PINE — 25 Aug 2026, all 13 concern pages.
   The bone cards were sitting on a bone field, so the band read as
   one flat surface. Pine behind them makes each card an object.
   Section-level colour, not card-level: the cards keep their own
   ground and now have something to lift off.
   ============================================================ */
.c-treats{background:var(--pine);color:var(--bone)}
/* the child-combinator rules above are (0,3,0) — match them or lose */
.c-treats > .container > .eyebrow{color:var(--sage-on-dark)}
.c-treats > .container > h2{color:var(--bone)}
.c-treats .c-card{background:var(--bg-2);border-color:rgba(247,244,238,.14);box-shadow:var(--e3)}
.c-treats .c-card h3{color:var(--ivory)}
.c-treats .c-card p{color:var(--ivory-dim)}

/* no text may fade: the bottom masks on scrollable panels erased the
   final line whenever content ran past the box. Scroll now simply
   scrolls; the rule below is the only "more below" signal left. */
.tc-panel{border-bottom:1px solid transparent}
.tc-panel.fade-b{border-bottom-color:var(--hairline-2)}

/* The three-column row (name · price · arrow) leaves the name 163px at
   375, so treatment names wrap mid-name — "MOXI® / Laser" strands the
   registered mark at the end of the first line. Below 560 the row
   stacks: name on its own line, price and arrow beneath it. */
@media (max-width:560px){
  .bc-links a{
    grid-template-columns:1fr auto;
    grid-template-areas:"name name" "price arrow";
    row-gap:4px;
  }
  .bc-links .bc-nm{grid-area:name;font-weight:inherit}
  .bc-links span{grid-area:price;justify-self:start;text-align:left}
  .bc-links a::after{grid-area:arrow;justify-self:end}
}

/* ============================================================
   TREATMENT UPGRADES — depth and arrival. 27 Aug 2026.
   A flat white card holding fourteen identical rows reads as a
   printed price list someone photographed. It keeps the spec-sheet
   discipline — dotted leader, figures right — but gains a ground,
   a lift, a live hover, and rows that arrive in sequence rather
   than all at once.
   ============================================================ */
#upgrades .price-table{
  position:relative;isolation:isolate;
  background:linear-gradient(168deg,var(--bg-2) 0%,var(--bg-3) 100%);
  border:1px solid var(--hairline);
  box-shadow:var(--e3),inset 0 1px 0 rgba(255,255,255,.6);
  padding:10px clamp(18px,2vw,28px) 14px;
  overflow:hidden;
}
/* a sage edge down the left, the only colour on the sheet */
#upgrades .price-table::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:linear-gradient(180deg,var(--champagne),rgba(124,131,112,0));
}
#upgrades .price-row{
  position:relative;padding:13px 10px 13px 8px;margin-inline:-8px;
  border-radius:6px;
  transition:background .28s var(--ease-out),transform .28s var(--ease-out);
}
#upgrades .price-row:hover{background:rgba(124,131,112,.09);transform:translateX(3px)}
#upgrades .price-row:hover b{color:var(--ivory)}
#upgrades .price-row span{font-variant-numeric:tabular-nums}

/* rows arrive in sequence — the eye reads a list top to bottom, so the
   reveal should too. Delay is set per row by subpage-motion.js; this is
   the ceiling so a fourteen-row sheet never crawls. */
#upgrades .price-row{opacity:1;transform:none}
html.js #upgrades .price-row{opacity:0;transform:translateY(10px)}
html.js #upgrades .price-row.is-in{
  opacity:1;transform:none;
  transition:opacity .5s var(--ease-out),transform .5s var(--ease-out);
}
@media (prefers-reduced-motion:reduce){
  html.js #upgrades .price-row{opacity:1;transform:none}
  #upgrades .price-row:hover{transform:none}
}


/* ============================================================
   UPGRADES + CHOOSING — full-width rebuild. 29 Aug 2026.

   Both sections inherit .c-sec, a 34/66 grid: heading left, card
   right. That works for three paragraphs. It does not work for a
   fourteen-row price sheet or a six-item criteria list — the right
   column squeezes them into one tall ribbon while the left column
   sits empty for the whole scroll.

   Both are given the full measure instead: heading on top, content
   across the width, in columns. Row markup and the .price-row class
   are untouched, so the staggered reveal in subpage-motion.js still
   drives the sheet.
   ============================================================ */
#upgrades,#choosing{
  grid-template-columns:minmax(0,1fr);
  gap:clamp(22px,2.8vw,36px);
}
#upgrades > h2,#choosing > h2{max-width:20ch}
/* .c-sec .prose caps at 64ch — right for a paragraph column, wrong for a
   sheet that is now meant to span the section. */
#upgrades .prose,#choosing .prose{max-width:none}
/* the intro keeps a reading measure even though the card is now wide */
#upgrades .prose > p:first-child,
#choosing .prose > p:first-child{max-width:60ch}

/* ---- the upgrade sheet: columns, not one long ribbon ---- */
#upgrades .price-table{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(292px,1fr));
  column-gap:clamp(26px,3.2vw,58px);
  max-width:none;              /* .price-table caps at 560px for a single column */
}
/* the leader rule belongs to each row, so every column ends flush */
#upgrades .price-row{border-bottom:1px solid var(--hairline-2)}
#upgrades .price-table .price-row:last-child{border-bottom:1px solid var(--hairline-2)}
/* price reads as a value, not a column of loose figures */
#upgrades .price-row span{
  flex:none;padding:3px 10px;border-radius:999px;
  background:rgba(124,131,112,.10);
  color:var(--ivory);font-size:.86rem;letter-spacing:.01em;
}
#upgrades .price-row:hover span{background:rgba(124,131,112,.2)}
/* The one long name — Clairderm Crystal Microdermabrasion — pushed the
   leader and price onto a second line, leaving a row twice the height of
   its neighbours. The name wraps inside itself instead; the price stays
   on the first baseline, so every row still scans as one line of figures. */
#upgrades .price-row{flex-wrap:nowrap}
#upgrades .price-row b{min-width:0}

/* ---- choosing: six criteria as a numbered set ---- */
#choosing .prose ul{
  /* six items: an explicit 3 gives 3x2. auto-fit made 4+2, which reads
     as a row that ran out rather than a set. */
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(14px,1.6vw,22px);
  counter-reset:crit;
}
#choosing .prose li{
  counter-increment:crit;
  padding:clamp(16px,1.5vw,20px);padding-top:clamp(38px,3.4vw,44px);
  background:var(--bg-3);
  border:1px solid var(--hairline-2);
  border-radius:var(--radius-panel);
}
/* replaces the inherited dash */
#choosing .prose li::before{
  content:counter(crit,decimal-leading-zero);
  position:static;width:auto;height:auto;background:none;
  display:block;margin-bottom:8px;
  font-family:'JetBrains Mono',monospace;font-size:.75rem;
  letter-spacing:.12em;color:var(--sage-label);
}
@media (max-width:1100px){
  #choosing .prose ul{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:900px){
  #upgrades .price-table{grid-template-columns:minmax(0,1fr)}
  #choosing .prose ul{grid-template-columns:minmax(0,1fr)}
}
@media (prefers-reduced-motion:reduce){
  #upgrades .price-row:hover span{background:rgba(124,131,112,.10)}
}
