/* =========================================================================
   THE WILD HERB — pitch mockup
   Bali-spa-at-sunrise meets editorial restraint. LAJ House.
   ========================================================================= */

:root{
  --ink:#0E1410;
  --forest:#1A2A1F;
  --forest-2:#243A2C;
  --moss:#4A6849;
  --bone:#F2E9D2;
  --cream:#E8DCB8;
  --gold:#C89A5A;
  --gold-light:#DEB878;
  --whisper:rgba(242,233,210,0.65);
  --hair:rgba(200,154,90,0.32);

  --ease:cubic-bezier(.16,1,.3,1);
  --slow:1.2s;
  --pad:clamp(1.4rem,5vw,6rem);
}

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

html{
  -webkit-text-size-adjust:100%;
  background:var(--ink);
}

body{
  font-family:"Chakra Petch",system-ui,sans-serif;
  font-weight:300;
  letter-spacing:.01em;
  color:var(--bone);
  background:var(--ink);
  line-height:1.65;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
em{font-style:italic}

::selection{background:rgba(200,154,90,.28);color:var(--bone)}

/* ---------- shared type primitives ---------- */
.eyebrow,.card-cat,.find-label,.tm-modalities,.tm-dur-time,.tm-dur-each,
.tm-extra-price,.tm-policy-label,.tm-studio-loc,.wordmark-sm,.nav a,
.scroll-cue-word,.apo-hint{
  font-family:"Bebas Neue",sans-serif;
  font-weight:400;
  text-transform:uppercase;
}
.eyebrow{
  font-size:clamp(.72rem,1vw,.86rem);
  letter-spacing:.42em;
  color:var(--gold);
  margin-bottom:1.6rem;
}
h1,h2,h3,.tm-name,.tm-extra-name,.serif{
  font-family:"Cormorant Garamond",Georgia,serif;
  font-weight:300;
  line-height:1.04;
  letter-spacing:.005em;
}

/* =========================================================================
   GRAIN + CURSOR
   ========================================================================= */
/* =========================================================================
   TOP CHROME
   ========================================================================= */
.chrome{
  position:fixed;top:0;left:0;right:0;
  z-index:70;
  display:flex;align-items:center;justify-content:space-between;
  padding:clamp(1rem,2.4vw,1.9rem) var(--pad);
  pointer-events:none;
}
.chrome::before{
  content:"";position:absolute;left:0;right:0;top:0;
  height:calc(100% + 56px);
  background:linear-gradient(180deg,
    rgba(14,20,16,.92) 0%,rgba(14,20,16,.72) 42%,rgba(14,20,16,0) 100%);
  pointer-events:none;z-index:-1;
}
.chrome a{pointer-events:auto;position:relative}
.wordmark-sm{
  font-size:.7rem;letter-spacing:.32em;color:var(--bone);
  opacity:.82;transition:opacity .5s var(--ease);
}
.wordmark-sm:hover{opacity:1}
.nav{display:flex;align-items:center;gap:clamp(1.1rem,2.4vw,2.6rem)}
.nav a{
  font-size:.86rem;letter-spacing:.22em;color:var(--whisper);
  position:relative;transition:color .5s var(--ease);
}
.nav a:not(.pill)::after{
  content:"";position:absolute;left:0;right:100%;bottom:-7px;height:1px;
  background:var(--gold);transition:right .55s var(--ease);
}
.nav a:not(.pill):hover{color:var(--bone)}
.nav a:not(.pill):hover::after{right:0}
.nav .pill{
  border:1px solid var(--gold);
  color:var(--gold-light);
  padding:.62em 1.5em .56em;
  border-radius:999px;
  letter-spacing:.26em;
  font-size:.78rem;
  transition:background-color .55s var(--ease),color .55s var(--ease);
}
.nav .pill:hover{background:var(--gold);color:var(--ink)}

/* =========================================================================
   SCENE SHELL
   ========================================================================= */
.scene{position:relative;width:100%}
/* GRAIN — 2026-09. Was a position:fixed full-viewport SVG-filter layer,
   recomposited on every frame of every scroll. Now a 6KB tiled PNG painted
   once per section as an absolute pseudo-element: it scrolls with its
   section like any other content and costs nothing between frames.
   No blend mode — at 4.5% on a dark ground, overlay vs normal is invisible,
   and normal needs no isolation layer. */
.scene::after{
  content:"";position:absolute;inset:0;z-index:5;pointer-events:none;
  background:url("assets/grain.png") repeat 0 0 / 256px 256px;
  opacity:.045;
}
.threshold,.story,.sanctuary{min-height:100vh;min-height:100svh}

/* reveal system — visible by default (no-JS safe); hidden only when enhanced */
.enh .reveal[data-rise]{opacity:0;transform:translateY(34px)}
.enh .reveal[data-rise].is-in{
  opacity:1;transform:none;
  transition:opacity 1.5s var(--ease),transform 1.5s var(--ease);
}

/* THE HERO ENTRANCE IS CSS, NOT JS — 2026-09.
   Two problems were tangled together here.

   1. The headline is this page's LCP element, and it was held at opacity:0
      until a setTimeout chain in script.js fired (300ms base + 2x240ms), so
      it could not be painted until ~780ms AFTER the script ran — and crept
      later every time the document grew.

   2. Worse, `.enh` is added BY that script. Before it landed, the no-JS
      baseline left the headline fully visible; then .enh blanked it and the
      stagger faded it back. Measured on a throttled phone profile: visible at
      1931ms, blank at 2288ms, fading back at 3084ms. An 800ms flash, and
      Chrome was quietly crediting LCP to the doomed first paint.

   So: the entrance runs off animation-delay (starts with the render-blocking
   stylesheet, needs no script), and the headline RISES WITHOUT FADING. It is
   contentful from the very first paint and never disappears. The eyebrow and
   the sub-line still fade, because neither is the LCP element.
   Do not give the headline an opacity keyframe, and do not re-add any of
   these four elements to the JS stagger. */
@keyframes heroRise{
  from{opacity:0;transform:translateY(34px)}
  to{opacity:1;transform:none}
}
@keyframes heroRiseSolid{      /* transform only — opacity stays 1 throughout */
  from{transform:translateY(34px)}
  to{transform:none}
}
.threshold .eyebrow.reveal[data-rise],
.threshold .hero-sub.reveal[data-rise]{
  animation:heroRise 1.4s var(--ease) both;
}
.threshold .eyebrow.reveal[data-rise] {animation-delay:.10s}
.threshold .hero-sub.reveal[data-rise]{animation-delay:.64s}

/* Specificity note: this must outrank `.enh .reveal[data-rise]{opacity:0}`
   (0,3,0), hence the span+class+attr chain (0,4,1). A transform-only
   animation cannot override that opacity on its own. */
.threshold .hero-title span.reveal[data-rise]{
  opacity:1;
  animation:heroRiseSolid 1.4s var(--ease) both;
}
.threshold .hero-title span.reveal[data-rise]:nth-child(1){animation-delay:0s}
.threshold .hero-title span.reveal[data-rise]:nth-child(2){animation-delay:.14s}

/* =========================================================================
   SCENE 1 — THE THRESHOLD
   ========================================================================= */
.threshold{
  display:flex;flex-direction:column;justify-content:center;align-items:center;
  text-align:center;
  padding:8rem var(--pad) 6rem;
  background:var(--ink);
  overflow:hidden;            /* contain the Ken-Burns scaled bg */
}
/* live frame — placeholder for the eventual looping bamboo film */
.hero-bg{
  position:absolute;inset:0;z-index:0;
  background:url("assets/hero-bamboo.jpg") center center / cover no-repeat;
  transform-origin:50% 52%;
  animation:kenBurns 40s ease-in-out infinite;
  will-change:transform;
  contain:paint;              /* its repaints never escape its own box */
}
/* Once the crossfade completes the still sits behind an opaque video layer.
   Stop animating what nobody can see, and release the compositor hints. */
.threshold.is-settled .hero-bg{animation-play-state:paused;will-change:auto}
.threshold.is-settled .hero-real,
.threshold.is-settled .hero-scrim-deep{will-change:auto}
.hero-scrim{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,
    rgba(14,20,16,.40) 0%,
    rgba(14,20,16,.65) 60%,
    rgba(14,20,16,.85) 100%);
}
/* keep content above bamboo bg + scrim — z-index only; preserve each element's own positioning */
.threshold-inner{position:relative;z-index:2;max-width:1100px}
.threshold .scroll-cue{z-index:2}
@keyframes kenBurns{
  0%   {transform:scale(1)    translate(0,0)}
  50%  {transform:scale(1.08) translate(-1.5%,-1%)}
  100% {transform:scale(1)    translate(0,0)}
}
.threshold .eyebrow{margin-bottom:2.4rem;color:var(--whisper);letter-spacing:.32em}
.hero-title{
  font-family:"Cormorant Garamond",serif;
  font-weight:300;
  font-size:clamp(3.4rem,13.5vw,12rem);
  line-height:.96;
  color:var(--bone);
}
.hero-title span{display:block}
.hero-title em{color:var(--gold-light)}
.hero-sub{
  margin-top:2.6rem;
  font-size:clamp(.95rem,1.5vw,1.2rem);
  letter-spacing:.16em;
  color:var(--whisper);
  font-weight:300;
}
.scroll-cue{
  position:absolute;left:50%;bottom:clamp(1.6rem,4vh,3rem);
  transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:1rem;
  pointer-events:auto;
}
.scroll-cue-word{font-size:.7rem;letter-spacing:.4em;color:var(--whisper)}
.scroll-cue-line{
  width:1px;height:74px;background:linear-gradient(var(--gold),rgba(200,154,90,0));
  transform-origin:top;
  animation:cuepulse 2.6s var(--ease) infinite;
}
@keyframes cuepulse{
  0%,100%{transform:scaleY(.35);opacity:.35}
  45%{transform:scaleY(1);opacity:1}
}

/* =========================================================================
   SCENE 2 — THE STORY
   ========================================================================= */
.story{
  display:flex;align-items:center;
  padding:clamp(6rem,12vh,11rem) var(--pad);
  background:linear-gradient(180deg,var(--ink) 0%,var(--forest) 55%,var(--ink) 100%);
}
.story-grid{
  width:100%;max-width:1500px;margin:0 auto;
  display:grid;
  /* NOT 40% 60% — percentage tracks resolve against the content box and the
     gap is then added on top, so the row overhung by the whole gap (86px at
     1440, which pushed the document 14px wider than the viewport). fr sizes
     what is left after the gap; minmax(0,…) keeps a long word from forcing a
     track past its share. Same 2:3 proportion, no overflow. */
  grid-template-columns:minmax(0,2fr) minmax(0,3fr);
  gap:clamp(2.5rem,6vw,7rem);align-items:center;
}
.story-figure{margin:0}
/* THE FRAME AND THE PHOTOGRAPH ARE ONE RECTANGLE — 2026-09.
   The tilt used to live on the <img> while the gold rules were drawn on the
   .frame box around it, so the border was axis-aligned and the photograph was
   not: they could never line up. The corners gaped and the frame's own dark
   backing showed through, most obviously top-right and down the left edge.
   `scale(1.02)` was there to paper over exactly that.

   Now .frame carries the border AND the rotation and clips to itself, so the
   photograph is the same rectangle as the frame at whatever angle it sits.
   The <img> must keep NO transform of its own — putting one back reopens the
   gap. `transform` does not affect layout, so the caption below is unmoved. */
.frame{
  position:relative;
  aspect-ratio:3/3.6;          /* was carried by the <img>; the box owns it now */
  overflow:hidden;             /* the photograph can never escape the border */
  transform:rotate(-2.4deg);   /* the tilt, on the same element as the border */
}
.frame img{
  width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(.74) brightness(.82) sepia(.16) contrast(1.04);
}
.frame-vignette{
  position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(78% 70% at 50% 46%,rgba(14,20,16,0) 38%,rgba(14,20,16,.5) 100%),
    linear-gradient(180deg,rgba(14,20,16,.28),rgba(14,20,16,.34)),
    linear-gradient(0deg,rgba(200,154,90,.05),rgba(200,154,90,.05));
  box-shadow:inset 0 0 110px 30px rgba(14,20,16,.6);
}
/* The vignette used to be inset past these rules; now that the frame hugs
   the photograph both sit at inset:0, and the vignette comes later in the
   DOM — so without this the gold would be painted over by the darkest part
   of its own inset shadow. */
.frame-edge{position:absolute;background:var(--gold);transform-origin:center;z-index:2}
.frame-top,.frame-bottom{left:0;right:0;height:1px;transform:scaleX(0)}
.frame-left,.frame-right{top:0;bottom:0;width:1px;transform:scaleY(0)}
.frame-top{top:0}.frame-bottom{bottom:0}
.frame-left{left:0}.frame-right{right:0}
.story-figure.is-in .frame-top,.story-figure.is-in .frame-bottom{
  transform:scaleX(1);transition:transform 1.4s var(--ease) .15s}
.story-figure.is-in .frame-left,.story-figure.is-in .frame-right{
  transform:scaleY(1);transition:transform 1.4s var(--ease) .55s}
.no-enh .frame-edge{transform:none}
figcaption{
  margin-top:1.4rem;text-align:center;
  font-family:"Cormorant Garamond",serif;font-size:1.05rem;
  color:var(--whisper);letter-spacing:.04em;
}
figcaption em{color:var(--gold)}

.story-copy h2{
  font-size:clamp(2.4rem,5.4vw,5rem);
  color:var(--bone);margin-bottom:2.6rem;
}
.story-copy h2 em{color:var(--gold-light)}
.story-body{max-width:46ch}
.story-body p{
  margin-bottom:1.45rem;
  font-size:clamp(1rem,1.18vw,1.16rem);
  color:var(--whisper);font-weight:300;
}
.pull{
  margin-top:3rem;padding-left:1.6rem;
  border-left:1px solid var(--hair);
  font-family:"Cormorant Garamond",serif;
  font-size:clamp(1.4rem,2.6vw,2.1rem);
  line-height:1.32;color:var(--gold);
}

/* =========================================================================
   SCENE 3 — THE APOTHECARY
   ========================================================================= */
.apothecary{background:var(--ink)}
/* Nothing is pinned any more. The section is simply viewport-tall and
   scrolls past like every other; the track inside it scrolls sideways. */
.apo-pin{
  min-height:100vh;min-height:100svh;
  display:flex;flex-direction:column;
  padding:clamp(4.6rem,11vh,7rem) 0 clamp(1.2rem,3vh,2rem);
}
.apo-head{flex:0 0 auto;padding:0 var(--pad);margin-bottom:clamp(1.1rem,3vh,2.2rem)}
.apo-head h2{font-size:clamp(2.4rem,6vw,5.4rem);color:var(--bone)}
.apo-head h2 em{color:var(--gold-light)}
.apo-hint{
  margin-top:1.2rem;font-size:.78rem;letter-spacing:.34em;
  color:var(--whisper);
}

/* A native horizontal scroller. Trackpad swipe, touch drag, shift+wheel,
   the arrow buttons or the arrow keys walk it — the gestures people already
   know. No transform, so the card shadows inside it are cheap again.
   The top/bottom padding is breathing room for the hover lift and the
   plate shadow, which overflow-y:hidden would otherwise clip. */
.apo-track{
  flex:1 1 auto;min-height:0;
  display:flex;align-items:stretch;
  gap:clamp(1.4rem,2.4vw,2.4rem);
  padding:12px var(--pad) 2.4rem;
  overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior-x:contain;
  scroll-padding-inline:var(--pad);  /* snap respects the gutter; rest is scrollLeft 0 */
  scrollbar-width:none;              /* hidden, still scrollable */
}
.apo-track::-webkit-scrollbar{display:none}
.apo-track:focus-visible{outline:1px solid var(--gold);outline-offset:-1px}
.apo-track .card{scroll-snap-align:start}

.card{
  flex:0 0 clamp(300px,30vw,420px);
  display:flex;flex-direction:column;
  background:var(--forest);
  border:1px solid var(--hair);
  position:relative;
  height:100%;            /* fills the pinned track area — full card always in view */
  transition:transform .9s var(--ease),
             border-color .9s var(--ease),
             box-shadow .9s var(--ease);
}
.card:hover{
  transform:translateY(-10px);
  border-color:var(--gold);
}
.card-media{flex:1;overflow:hidden;position:relative}
.card-media img{
  width:100%;height:100%;object-fit:cover;
  object-position:center 42%;
  filter:saturate(.94) brightness(.97);
  transition:transform 1.4s var(--ease);
}
.card-media--shiftL img{object-position:38% 60%}   /* keeps IG corner badge out of frame */
.card:hover .card-media img{transform:scale(1.05)}

.card-body{
  padding:clamp(1.15rem,1.8vw,1.7rem);
  display:flex;flex-direction:column;gap:.5rem;
  background:var(--forest);
  position:relative;z-index:1;
}
.card-cat{
  font-size:.74rem;letter-spacing:.36em;color:var(--gold);
}
.card-name{
  font-size:clamp(1.7rem,2.4vw,2.4rem);
  color:var(--bone);line-height:1;
}
.card-name em{color:var(--gold-light)}
.card-ing{
  font-size:.86rem;color:var(--whisper);letter-spacing:.02em;
}
.card-ing-more{
  display:block;max-height:0;opacity:0;overflow:hidden;
  margin-top:0;color:var(--whisper);
  transition:max-height .9s var(--ease),opacity .7s var(--ease),margin-top .9s var(--ease);
}
.card:hover .card-ing-more{max-height:150px;opacity:1;margin-top:.5rem}
.card-foot{
  display:flex;align-items:center;justify-content:space-between;
  gap:1rem;margin-top:.7rem;
}
.card-price{
  font-family:"Cormorant Garamond",serif;
  font-size:1.35rem;color:var(--cream);letter-spacing:.04em;
}

/* hairline button */
.hairline-btn{
  font-family:"Bebas Neue",sans-serif;
  font-size:.76rem;letter-spacing:.24em;text-transform:uppercase;
  color:var(--gold-light);
  padding:.7em 1.15em;
  border:1px solid var(--hair);
  white-space:nowrap;
  transition:background-color .55s var(--ease),
             color .55s var(--ease),border-color .55s var(--ease);
}
.hairline-btn:hover{background:var(--gold);color:var(--ink);border-color:var(--gold)}

/* typographic-only cards */
.card--type{
  background:
    radial-gradient(120% 80% at 50% 0%,rgba(74,104,73,.28) 0%,rgba(14,20,16,0) 60%),
    linear-gradient(165deg,var(--forest-2) 0%,var(--ink) 78%);
  justify-content:flex-end;
}
.card--type .card-glyph{
  position:absolute;top:0;left:0;right:0;
  height:55%;
  display:flex;align-items:center;justify-content:center;
}
.card--type .card-glyph::before{
  content:"";width:120px;height:120px;border-radius:50%;
  border:1px solid var(--hair);
  box-shadow:0 0 0 18px rgba(200,154,90,.05);
}
.card--type .card-glyph::after{
  content:"❧";position:absolute;
  font-size:2.4rem;color:var(--gold);opacity:.55;
  font-family:"Cormorant Garamond",serif;
}
.card--type .card-body{background:transparent}
.card--type .card-name{font-size:clamp(2rem,3vw,2.9rem)}

/* heritage card — crop onto the jar, then an archival scrim over the rest */
.card--heritage .card-media img{
  object-position:21% 60%;
  transform:scale(1.42);
  transform-origin:22% 60%;
  filter:saturate(.62) brightness(.74) sepia(.18) contrast(1.03);
}
.card--heritage .card-media::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(180deg,rgba(14,20,16,.45) 0%,rgba(14,20,16,.18) 30%,rgba(14,20,16,.4) 62%,rgba(26,42,31,.96) 100%),
    radial-gradient(70% 60% at 38% 52%,rgba(14,20,16,0) 0%,rgba(14,20,16,.5) 100%),
    linear-gradient(0deg,rgba(200,154,90,.06),rgba(200,154,90,.06));
}
.card--heritage:hover .card-media img{transform:scale(1.48)}

/* closing rail */
.card--end{
  background:linear-gradient(160deg,var(--forest-2),var(--ink));
  border-color:var(--gold);
  align-items:center;justify-content:center;text-align:center;
}
.card--end .card-end-inner{display:flex;flex-direction:column;gap:1.6rem;align-items:center;padding:2rem}
.card--end h3{font-size:clamp(2rem,3vw,2.8rem);color:var(--bone)}
.card--end h3 em{color:var(--gold-light)}

/* =========================================================================
   SCENE 4 — THE SANCTUARY
   ========================================================================= */
.sanctuary{
  display:flex;align-items:center;
  padding:clamp(6rem,12vh,11rem) var(--pad);
  background:var(--ink);overflow:hidden;
}
.sanctuary-glow{
  position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(60% 55% at 50% 52%,rgba(200,154,90,.22) 0%,rgba(200,154,90,.06) 35%,rgba(14,20,16,0) 70%),
    radial-gradient(120% 120% at 50% 50%,rgba(36,58,44,.5) 0%,var(--ink) 75%);
  animation:candle 7s ease-in-out infinite alternate;
}
@keyframes candle{0%{opacity:.78;transform:scale(1)}100%{opacity:1;transform:scale(1.04)}}
.sanctuary-inner{position:relative;width:100%;max-width:1280px;margin:0 auto}
.sanctuary > *:not(.sanctuary-media){position:relative;z-index:1}
.sanctuary-head{text-align:center;margin-bottom:clamp(3rem,7vh,5rem)}
.sanctuary-head h2{font-size:clamp(2.6rem,6.4vw,5.6rem);color:var(--bone)}
.sanctuary-head h2 em{color:var(--gold-light)}
.sanctuary-sub{
  margin-top:1.6rem;color:var(--whisper);
  font-size:clamp(.98rem,1.3vw,1.15rem);max-width:46ch;
  margin-inline:auto;letter-spacing:.04em;
}
/* The held footage now sits behind the whole scene rather than inside a
   card, the way the footer's does. Same numbers as the card it replaced:
   0.35 opacity under a two-stop scrim, which held every text band clear of
   WCAG AA against the brightest frame. */
.sanctuary-media{position:absolute;inset:0;z-index:0;pointer-events:none}
.sanctuary-media video{
  width:100%;height:100%;object-fit:cover;
  opacity:.35;
  filter:saturate(.6) brightness(.72);
}
.sanctuary-media-scrim{
  position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(14,20,16,.58),rgba(14,20,16,.76));
}

.solid-btn{
  display:inline-block;
  font-family:"Bebas Neue",sans-serif;
  font-size:1rem;letter-spacing:.34em;text-transform:uppercase;
  color:var(--ink);background:var(--gold);
  padding:1.05em 3.4em;border-radius:999px;
  transition:background-color .55s var(--ease),transform .55s var(--ease);
}
.solid-btn:hover{background:var(--gold-light);transform:translateY(-3px)}

/* =========================================================================
   SCENE 4a — THE MENU
   A printed spa menu, not a product grid: one column at a reading measure,
   hairline rules between treatments, durations set to the right like prices
   on a card. Nothing here is scroll-linked — it is type.
   ========================================================================= */
.treatments{
  padding:clamp(6rem,12vh,10rem) var(--pad) clamp(5rem,10vh,8rem);
  background:linear-gradient(180deg,var(--ink) 0%,var(--forest) 60%,var(--ink) 100%);
}
.tm-inner{width:100%;max-width:820px;margin:0 auto}   /* the reading measure */

.tm-head{text-align:center;margin-bottom:clamp(3rem,7vh,5rem)}
.tm-head h2{font-size:clamp(2.2rem,5.2vw,4.2rem);color:var(--bone)}
.tm-head h2 em{color:var(--gold-light)}
.tm-sub{
  margin-top:1.4rem;color:var(--whisper);
  font-size:clamp(.95rem,1.2vw,1.08rem);max-width:48ch;
  margin-inline:auto;letter-spacing:.04em;
}

/* ---------- a group ---------- */
.tm-group{margin-bottom:clamp(3.4rem,8vh,6rem)}
.tm-group-head{margin-bottom:1.6rem}
.tm-group-name{
  font-size:clamp(1.9rem,3.4vw,2.8rem);
  color:var(--bone);line-height:1.05;
}
.tm-group-name em{color:var(--gold-light)}
.tm-group-blurb{
  margin-top:.6rem;color:var(--whisper);
  font-size:.98rem;letter-spacing:.03em;max-width:52ch;
}

/* ---------- a treatment ---------- */
.tm-list{list-style:none}
.tm-item{
  display:grid;grid-template-columns:1fr auto;
  gap:clamp(1.4rem,3vw,3rem);align-items:start;
  padding:clamp(1.6rem,3vh,2.2rem) 0;
  border-bottom:1px solid var(--hair);
}
.tm-item:first-child{border-top:1px solid var(--hair)}
.tm-modalities{
  font-size:.72rem;letter-spacing:.3em;color:var(--gold);
  margin-bottom:.7rem;line-height:1.5;
}
.tm-name{
  font-size:clamp(1.7rem,2.4vw,2.4rem);   /* the scale of a product name */
  color:var(--bone);line-height:1.05;
}
.tm-name em{color:var(--gold-light)}
.tm-desc{
  margin-top:.75rem;color:var(--whisper);
  font-size:.95rem;line-height:1.7;max-width:54ch;
}
.tm-uses{
  margin-top:.7rem;font-size:.86rem;color:var(--whisper);
  font-style:italic;letter-spacing:.02em;
}
.tm-product{
  color:var(--gold-light);font-style:normal;
  text-decoration:underline;text-underline-offset:.22em;
  text-decoration-color:var(--hair);
  transition:color .55s var(--ease),text-decoration-color .55s var(--ease);
}
.tm-product:hover{color:var(--gold);text-decoration-color:var(--gold)}

/* ---------- the durations, set to the right ---------- */
.tm-durations{
  display:flex;flex-direction:column;gap:1.1rem;
  align-items:flex-end;text-align:right;
}
.tm-dur-line{
  display:flex;align-items:baseline;gap:.5rem;
  flex-wrap:wrap;justify-content:flex-end;
}
.tm-dur-time{font-size:.92rem;letter-spacing:.16em;color:var(--gold);white-space:nowrap}
.tm-dur-dash{color:var(--hair)}
.tm-dur-price{
  font-family:"Cormorant Garamond",serif;
  font-size:1.35rem;color:var(--cream);white-space:nowrap;
}
.tm-dur-each{
  font-size:.66rem;letter-spacing:.24em;color:var(--whisper);
  width:100%;text-align:right;
}
.tm-dur-note{
  margin-top:.25rem;font-size:.8rem;color:var(--whisper);
  font-style:italic;
}
.tm-book{margin-top:.6rem;display:inline-block;white-space:nowrap}

/* ---------- the epigraph that closes each group ---------- */
.tm-epigraph{
  margin:clamp(2.2rem,5vh,3.4rem) auto 0;
  max-width:44ch;text-align:center;
}
.tm-epigraph p{
  font-family:"Cormorant Garamond",serif;font-style:italic;
  font-size:clamp(1rem,1.5vw,1.2rem);
  color:var(--gold);line-height:1.6;
}
.tm-epigraph cite{
  display:block;margin-top:.9rem;font-style:normal;
  font-family:"Bebas Neue",sans-serif;
  font-size:.7rem;letter-spacing:.34em;text-transform:uppercase;
  color:var(--whisper);
}

/* ---------- extras: three columns, in the Find Us idiom ---------- */
.tm-sub-head{
  font-size:clamp(1.5rem,2.6vw,2.1rem);color:var(--bone);
  text-align:center;margin-bottom:clamp(1.6rem,4vh,2.4rem);
}
.tm-sub-head em{color:var(--gold-light)}
.tm-extras{margin-top:clamp(1rem,3vh,2rem)}
.tm-extras-grid{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(1.2rem,2.4vw,2rem);
}
.tm-extra{
  border:1px solid var(--hair);
  background:rgba(36,58,44,.16);
  padding:clamp(1.4rem,2.4vw,2rem);
  display:flex;flex-direction:column;
  transition:background-color .9s var(--ease),border-color .9s var(--ease);
}
.tm-extra:hover{background:rgba(36,58,44,.34);border-color:var(--gold)}
/* "A Complementary Ritual" runs to two lines while the others run to one;
   reserving both keeps the three price labels on a line. */
.tm-extra-name{font-size:1.3rem;color:var(--bone);line-height:1.15;min-height:2.3em}
.tm-extra-name em{color:var(--gold-light)}
.tm-extra-price{
  margin:.6rem 0 .8rem;
  font-size:.72rem;letter-spacing:.28em;color:var(--gold);
}
/* Two of the three are a benefit, not a charge. Gold is the price colour on
   this site, so the included ones step out of it into plain bone — a
   statement of fact rather than a number. */
.tm-extra-price.is-included{color:var(--bone);opacity:.9}
.tm-extra-desc{color:var(--whisper);font-size:.9rem;line-height:1.65}

/* ---------- studio details ---------- */
.tm-studio{
  margin-top:clamp(3rem,7vh,5rem);
  padding-top:clamp(2rem,5vh,3rem);
  border-top:1px solid var(--hair);
  text-align:center;
}
.tm-studio-name{
  font-family:"Cormorant Garamond",serif;font-style:italic;
  font-size:clamp(1.2rem,2vw,1.6rem);color:var(--bone);
}
.tm-studio-loc{
  margin-top:.5rem;font-size:.72rem;letter-spacing:.3em;color:var(--gold);
}
.tm-studio-cta{margin-top:1.5rem;display:inline-block}
/* The switchboard, once, as an alternative. She would rather be texted. */
.tm-studio-alt{
  margin-top:1.1rem;font-size:.82rem;color:var(--whisper);opacity:.72;
}

/* ---------- the fine print, and it should look like it ---------- */
.tm-policy{
  margin-top:clamp(2.4rem,6vh,3.6rem);
  display:flex;flex-direction:column;gap:.5rem;
}
.tm-policy-row{
  display:grid;grid-template-columns:8.5rem 1fr;gap:1rem;
  align-items:baseline;
}
.tm-policy-label{
  font-family:"Bebas Neue",sans-serif;text-transform:uppercase;
  font-size:.68rem;letter-spacing:.26em;color:var(--gold);
}
.tm-policy-text{font-size:.82rem;color:var(--whisper);line-height:1.6;opacity:.8}

@media (max-width:767.98px){
  /* durations move beneath the description rather than beside it */
  .tm-item{grid-template-columns:1fr;gap:1.1rem}
  .tm-durations{
    align-items:flex-start;text-align:left;
    flex-direction:row;flex-wrap:wrap;gap:1.6rem;
  }
  .tm-dur-line{justify-content:flex-start}
  .tm-dur-each{width:auto;text-align:left}
  .tm-extras-grid{grid-template-columns:1fr}
  .tm-policy-row{grid-template-columns:1fr;gap:.15rem}
}
@media (max-width:380px){
  .tm-durations{flex-direction:column;gap:1.1rem}
}

/* =========================================================================
   SCENE 5 — FIND US
   Inherits the exact palette, type scale and spacing of the "What Comes
   Next" block it replaced — only the class names and the CTA are new.
   ========================================================================= */
.find{
  padding:clamp(7rem,14vh,12rem) var(--pad);
  background:linear-gradient(180deg,var(--ink),var(--forest) 130%);
}
.find-head{margin-bottom:clamp(3rem,7vh,5rem)}
.find-head h2{font-size:clamp(2.4rem,6vw,5rem);color:var(--bone)}
.find-head h2 em{color:var(--gold-light)}
.find-grid{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(1.4rem,3vw,2.6rem);max-width:1400px;
}
.find-card{
  border:1px solid var(--hair);
  padding:clamp(2rem,3.4vw,3rem);
  min-height:340px;
  display:flex;flex-direction:column;
  background:rgba(36,58,44,.16);
  transition:background-color .9s var(--ease),border-color .9s var(--ease),transform .9s var(--ease);
}
.find-card:hover{background:rgba(36,58,44,.4);border-color:var(--gold);transform:translateY(-8px)}
.find-label{
  font-size:.76rem;letter-spacing:.4em;color:var(--gold);
  margin-bottom:auto;
}
.find-card h3{
  font-size:clamp(1.7rem,2.6vw,2.4rem);color:var(--bone);
  margin:2.6rem 0 1.2rem;
}
.find-card h3 em{color:var(--gold-light)}
.find-card p{color:var(--whisper);font-size:.98rem}
.find-note{margin-top:.7rem;font-size:.88rem;opacity:.82;font-style:italic}

/* The handle is the only inline link in the block — underlined so it reads
   as tappable without borrowing the button treatment beside it. */
.find-link{
  color:var(--gold-light);
  text-decoration:underline;text-underline-offset:.22em;
  text-decoration-color:var(--hair);
  transition:text-decoration-color .55s var(--ease),color .55s var(--ease);
}
.find-link:hover{color:var(--gold);text-decoration-color:var(--gold)}

/* align-self keeps the button its own width — a flex column would otherwise
   stretch it edge to edge. margin-top holds it to the foot of the card. */
.find-cta{
  align-self:flex-start;
  margin-top:1.6rem;
  display:inline-block;
}

/* =========================================================================
   SCENE 6 — THE VISIT
   ========================================================================= */
.visit{
  padding:clamp(6rem,12vh,10rem) var(--pad) clamp(2rem,4vh,3rem);
  background:var(--ink);
}
.visit-mark{
  font-family:"Cormorant Garamond",serif;font-weight:300;font-style:italic;
  font-size:clamp(3rem,11vw,9rem);color:var(--bone);
  text-align:center;line-height:1;margin-bottom:clamp(3rem,7vh,5rem);
}
.visit-grid{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(2rem,5vw,4rem);
  max-width:1100px;margin:0 auto clamp(4rem,8vh,6rem);
  border-top:1px solid var(--hair);padding-top:clamp(2.5rem,5vh,3.5rem);
}
.visit-col p{color:var(--whisper);line-height:2;font-size:.98rem}
.visit-col a{position:relative;transition:color .5s var(--ease)}
.visit-col a:hover{color:var(--gold-light)}
.signup{display:flex;border-bottom:1px solid var(--hair);max-width:280px}
.signup input{
  flex:1;background:none;border:0;color:var(--bone);
  font-family:"Chakra Petch",sans-serif;font-size:.95rem;
  padding:.6rem 0;letter-spacing:.04em;
}
.signup input::placeholder{color:rgba(242,233,210,.4)}
.signup input:focus{outline:none}
.signup button{
  background:none;border:0;color:var(--gold);cursor:pointer;
  font-size:1.1rem;padding:0 .4rem;transition:transform .5s var(--ease)}
.signup button:hover{transform:translateX(4px)}
.signup-note{margin-top:.9rem;font-size:.82rem;color:var(--whisper);font-style:italic;font-family:"Cormorant Garamond",serif}
.visit-base{
  max-width:1100px;margin:0 auto;
  display:flex;justify-content:space-between;flex-wrap:wrap;gap:1rem;
  font-family:"Bebas Neue",sans-serif;text-transform:uppercase;
  letter-spacing:.26em;font-size:.74rem;color:var(--whisper);
}
.visit-base .laj{color:var(--gold)}

/* closing slate — the credits frame of a film treatment */
.production-slate{
  max-width:1100px;margin:0 auto clamp(2.4rem,5vh,3.4rem);
}
.slate-row{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:32px;
}
.slate-cell{
  padding-top:16px;
  border-top:1px solid var(--gold);
}
.slate-label{
  font-family:"Bebas Neue",sans-serif;
  font-size:10px;letter-spacing:.3em;
  color:var(--gold);text-transform:uppercase;
  margin-bottom:6px;
}
.slate-name{
  font-family:"Bebas Neue",sans-serif;
  font-size:14px;letter-spacing:.2em;
  color:var(--bone);text-transform:uppercase;
}
.slate-detail{
  font-family:"Chakra Petch",sans-serif;font-weight:300;
  font-size:11px;color:var(--whisper);
  margin-top:4px;letter-spacing:.04em;
}

/* =========================================================================
   RESPONSIVE
   ========================================================================= */
@media (max-width:1024px){
  /* five links + the pill is the most this nav carries; below 1024 tighten the
     gap so it never closes on the wordmark. Type size is untouched. */
  .nav{gap:clamp(.85rem,1.7vw,1.6rem)}
  .story-grid{grid-template-columns:1fr;gap:3rem}
  .story-figure{max-width:460px;margin:0 auto}
  .sanctuary-grid{grid-template-columns:1fr;gap:2.6rem}
  .find-grid{grid-template-columns:1fr}
}
@media (max-width:760px){
  :root{--pad:1.4rem}
  .wordmark-sm{font-size:.6rem;letter-spacing:.2em;max-width:42vw}
  .nav{gap:.9rem}
  .nav a:not(.pill){display:none}            /* keep it calm on phones */
  .nav .pill{font-size:.72rem;padding:.6em 1.2em}
  .hero-sub{letter-spacing:.1em}

  /* Always shown on touch (no hover), so it must clear AA on its own:
     at opacity .8 this text measured 4.43:1 against --forest, just under the
     4.5 needed at 13.3px. Full --whisper gives 6.09:1. */
  .card-ing-more{max-height:none;opacity:1;margin-top:.5rem}
  .visit-grid{grid-template-columns:1fr;text-align:left}
  .slate-row{grid-template-columns:1fr;gap:20px}    /* slate stacks vertically on mobile */
  .visit-base{flex-direction:column;text-align:center;align-items:center}
}
@media (max-width:760px) and (hover:none){
  .card-name{font-size:1.9rem}
}

/* =========================================================================
   REDUCED MOTION
   ========================================================================= */
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
  .enh .reveal[data-rise]{opacity:1!important;transform:none!important}
  .scroll-cue-line{animation:none;transform:scaleY(1);opacity:.6}
}

/* =========================================================================
   VIDEO LAYER — real footage, added 2026
   Bamboo still (feeling) dissolves into the real sanctuary (place).
   Every clip is silent, looping, and paused while off-screen.
   ========================================================================= */

/* --- Scene 1 · the hero reveal ----------------------------------------- */
.hero-real{
  position:absolute;inset:0;z-index:0;
  opacity:0;                      /* GSAP scrubs this 0 -> 1 over the pin */
  will-change:opacity;
}
.hero-real video{
  display:block;width:100%;height:100%;
  object-fit:cover;object-position:center 50%;
}
/* The footage reads ~79% brighter than the bamboo still (YAVG 148 vs 82),
   so a second scrim fades in with it to hold the headline legible. */
.hero-scrim-deep{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  opacity:0;will-change:opacity;
  background:linear-gradient(180deg,
    rgba(14,20,16,.20) 0%,
    rgba(14,20,16,.34) 55%,
    rgba(14,20,16,.54) 100%);
}

/* --- The Apothecary · 2026 studio shoot --------------------------------
   The approved crop (center 42%) was framed for the older phone photos,
   where the jar sat high. In the studio shots the jar sits lower, so that
   bias clipped the label. Scoped to assets/products/ only — the cards still
   on the original imagery keep the approved crop untouched. */
.card-media img[src^="assets/products/"]{object-position:center 62%}

/* --- Scene 2 · the practice, small inset (never full-bleed) ------------- */
.story-inset{
  position:relative;margin-top:1.6rem;
  overflow:hidden;background:rgba(14,20,16,.4);
}
.story-inset video{
  display:block;width:100%;aspect-ratio:16/9;object-fit:cover;
  filter:saturate(.78) brightness(.84) sepia(.12) contrast(1.03);
}
.story-inset-edge{
  position:absolute;inset:0;pointer-events:none;
  border:1px solid var(--hair);
  box-shadow:inset 0 0 60px 18px rgba(14,20,16,.55);
}

/* --- Scene 6 · the visit, ambient texture behind the closing block ------ */
.visit{position:relative;overflow:hidden}
.visit-media{position:absolute;inset:0;z-index:0;pointer-events:none}
.visit-media video{
  width:100%;height:100%;object-fit:cover;
  opacity:.16;filter:saturate(.55) brightness(.5);
}
.visit-media-scrim{
  position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(14,20,16,.80),rgba(14,20,16,.94));
}
.visit > *:not(.visit-media){position:relative;z-index:1}

@media (max-width:760px){
  .story-inset{margin-top:1.2rem}
}

/* Reduced motion: JS strips the <source> tags so each <video> renders only
   its poster, and the hero simply stays on the approved bamboo still. */
@media (prefers-reduced-motion:reduce){
  .hero-real,.hero-scrim-deep{opacity:0!important}
}

/* =========================================================================
   THE SHOP — 2026
   The roundel finally on the page, the shelf made shoppable, and the
   detail / cart / checkout overlays. Motion reuses --ease and the site's
   hairline-and-gold vocabulary so nothing here reads as bolted on.
   ========================================================================= */

/* ---------- the mark ---------- */
.wordmark-sm{display:inline-flex;align-items:center;gap:10px}
.wordmark-mark{width:28px;height:28px;flex:0 0 auto;opacity:.9}
.apo-head h2 .head-mark{
  width:40px;height:40px;display:inline-block;
  vertical-align:-.12em;margin-right:.5rem;
}
.visit-roundel{
  width:64px;height:64px;margin:0 auto clamp(1.4rem,3vh,2.2rem);
  opacity:.85;display:block;
}

.footer-byline{color:var(--whisper)}
.footer-byline a{color:var(--whisper);transition:color .5s var(--ease)}
.footer-byline a:hover{color:var(--gold)}

/* ---------- nav cart indicator ---------- */
.cart-btn{
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;padding:0;border:0;background:none;cursor:pointer;
  pointer-events:auto;
}
.cart-btn[hidden]{display:none}
.cart-btn img{width:28px;height:28px;opacity:.9;transition:opacity .5s var(--ease)}
.cart-btn:hover img{opacity:1}
.cart-badge{
  position:absolute;top:-2px;right:-4px;min-width:16px;height:16px;
  padding:0 4px;border-radius:999px;
  background:var(--gold);color:var(--ink);
  font-family:"Bebas Neue",sans-serif;font-size:.62rem;letter-spacing:.06em;
  display:flex;align-items:center;justify-content:center;
}

/* ---------- shelf card additions ---------- */
.card-sub{
  font-family:"Cormorant Garamond",serif;font-style:italic;
  font-size:1rem;color:var(--gold-light);letter-spacing:.03em;margin-top:-.2rem;
}
.card-price.is-onrequest{font-size:1.05rem;font-style:italic;color:var(--whisper)}
.card.is-tappable{cursor:pointer}
.card.is-tappable:focus-visible{outline:1px solid var(--gold);outline-offset:3px}
.card-add{cursor:pointer;background:none;font-family:"Bebas Neue",sans-serif}
.card-add.is-added{background:var(--gold);color:var(--ink);border-color:var(--gold)}

/* =========================================================================
   OVERLAYS — shared shell
   ========================================================================= */
.overlay{
  position:fixed;inset:0;z-index:100;
  background:rgba(9,13,10,.86);
  -webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);
  opacity:0;transition:opacity .55s var(--ease);
  display:flex;
}
.overlay.is-open{opacity:1}
.pd-close{
  position:absolute;top:14px;right:14px;z-index:3;
  width:40px;height:40px;border:1px solid var(--hair);background:rgba(14,20,16,.6);
  color:var(--bone);font-size:1rem;line-height:1;cursor:pointer;
  transition:background-color .5s var(--ease),border-color .5s var(--ease);
}
.pd-close:hover{background:var(--gold);color:var(--ink);border-color:var(--gold)}

/* quantity stepper (detail + cart) */
.qty{display:inline-flex;align-items:center;border:1px solid var(--hair)}
.qty-btn{
  width:38px;height:38px;border:0;background:none;color:var(--gold-light);
  font-size:1.1rem;cursor:pointer;transition:background-color .4s var(--ease);
}
.qty-btn:hover{background:rgba(200,154,90,.14)}
.qty-val{
  min-width:34px;text-align:center;color:var(--bone);
  font-family:"Cormorant Garamond",serif;font-size:1.15rem;
}

/* =========================================================================
   PRODUCT DETAIL
   ========================================================================= */
.pd{align-items:center;justify-content:center;padding:clamp(0px,2vw,2rem)}
.pd-panel{
  position:relative;
  display:grid;grid-template-columns:1.15fr 1fr;
  width:min(1240px,100%);max-height:100%;
  background:var(--forest);border:1px solid var(--hair);
  overflow:hidden;
  transform:translateY(26px) scale(.985);
  transition:transform .7s var(--ease);
}
.overlay.is-open .pd-panel{transform:none}

.pd-gallery{display:flex;flex-direction:column;min-width:0;background:var(--ink)}
.pd-stage{position:relative;flex:1;min-height:0;display:flex;align-items:center;justify-content:center}
.pd-primary{
  width:100%;height:100%;object-fit:contain;
  max-height:min(70vh,660px);
}
.pd-arrow{
  position:absolute;top:50%;transform:translateY(-50%);
  width:44px;height:60px;border:0;background:rgba(14,20,16,.5);
  color:var(--bone);font-size:1.6rem;line-height:1;cursor:pointer;
  transition:background-color .45s var(--ease),color .45s var(--ease);
}
.pd-arrow:hover{background:var(--gold);color:var(--ink)}
.pd-prev{left:0}.pd-next{right:0}
.pd-counter{
  position:absolute;bottom:10px;left:50%;transform:translateX(-50%);
  font-family:"Bebas Neue",sans-serif;font-size:.7rem;letter-spacing:.28em;
  color:var(--whisper);background:rgba(14,20,16,.55);padding:.25em .7em;
}
.pd-thumbs{
  flex:0 0 auto;display:flex;gap:8px;padding:10px;
  overflow-x:auto;scrollbar-width:thin;scrollbar-color:var(--hair) transparent;
}
.pd-thumbs::-webkit-scrollbar{height:5px}
.pd-thumbs::-webkit-scrollbar-thumb{background:var(--hair);border-radius:999px}
.pd-thumb{
  flex:0 0 auto;width:62px;height:62px;padding:0;cursor:pointer;
  border:1px solid transparent;background:none;
  opacity:.55;transition:opacity .45s var(--ease),border-color .45s var(--ease);
}
.pd-thumb img{width:100%;height:100%;object-fit:cover}
.pd-thumb:hover{opacity:.85}
.pd-thumb.is-on{opacity:1;border-color:var(--gold)}

.pd-info{
  padding:clamp(1.6rem,3vw,2.8rem);
  display:flex;flex-direction:column;gap:.85rem;
  overflow-y:auto;
}
.pd-info .eyebrow{margin-bottom:0}
.pd-name{font-size:clamp(2.2rem,3.6vw,3.2rem);color:var(--bone);line-height:1}
.pd-name em{color:var(--gold-light)}
.pd-subtitle{
  font-family:"Cormorant Garamond",serif;font-style:italic;
  font-size:1.15rem;color:var(--gold-light);margin-top:-.4rem;
}
.pd-price{
  font-family:"Cormorant Garamond",serif;font-size:1.7rem;color:var(--cream);
  letter-spacing:.04em;
}
.pd-price.is-onrequest{font-size:1.25rem;font-style:italic;color:var(--whisper)}
.pd-desc{color:var(--whisper);font-size:.98rem;line-height:1.8}
.pd-ing{
  color:var(--gold);font-size:.82rem;letter-spacing:.18em;text-transform:uppercase;
  font-family:"Bebas Neue",sans-serif;
  border-top:1px solid var(--hair);padding-top:.9rem;
}
.pd-actions{display:flex;align-items:center;gap:1rem;flex-wrap:wrap;margin-top:.5rem}
.pd-add{padding:1.05em 2.4em;border:0;cursor:pointer;font-size:.92rem}
.pd-ask{text-align:center;cursor:pointer}

/* =========================================================================
   CART DRAWER
   ========================================================================= */
.cart-overlay{justify-content:flex-end}
.cart-panel{
  position:relative;
  width:min(440px,100%);height:100%;
  background:var(--forest);border-left:1px solid var(--hair);
  display:flex;flex-direction:column;
  padding:clamp(1.4rem,3vw,2.2rem);
  transform:translateX(100%);
  transition:transform .65s var(--ease);
}
.overlay.is-open .cart-panel{transform:none}
.cart-title{font-size:2.2rem;color:var(--bone);margin-bottom:1.4rem}
.cart-title em{color:var(--gold-light)}
.cart-scroll{flex:1;display:flex;flex-direction:column;min-height:0}
.cart-list{list-style:none;flex:1;overflow-y:auto;margin:0 -.2rem}
.cart-line{display:flex;gap:1rem;padding:1.1rem 0;border-bottom:1px solid var(--hair)}
.cart-thumb{width:74px;height:74px;object-fit:cover;flex:0 0 auto;border:1px solid var(--hair)}
.cart-meta{flex:1;min-width:0;display:flex;flex-direction:column;gap:.25rem}
.cart-name{font-family:"Cormorant Garamond",serif;font-size:1.3rem;color:var(--bone);line-height:1.1}
.cart-sub{font-size:.78rem;color:var(--whisper);font-style:italic;font-family:"Cormorant Garamond",serif}
.cart-price{font-family:"Cormorant Garamond",serif;color:var(--cream);font-size:1.05rem}
.cart-price.is-onrequest{font-style:italic;color:var(--whisper);font-size:.92rem}
.cart-line-foot{display:flex;align-items:center;justify-content:space-between;gap:.6rem;margin-top:.35rem}
.cart-line-foot .qty-btn{width:30px;height:30px;font-size:.95rem}
.cart-line-foot .qty-val{min-width:26px;font-size:1rem}
.cart-remove{
  background:none;border:0;cursor:pointer;color:var(--whisper);
  font-family:"Bebas Neue",sans-serif;font-size:.7rem;letter-spacing:.2em;
  text-transform:uppercase;transition:color .45s var(--ease);
}
.cart-remove:hover{color:var(--gold)}
.cart-foot{flex:0 0 auto;padding-top:1.2rem;border-top:1px solid var(--gold)}
.cart-sum{
  display:flex;justify-content:space-between;align-items:baseline;
  font-family:"Bebas Neue",sans-serif;letter-spacing:.24em;
  text-transform:uppercase;font-size:.78rem;color:var(--whisper);
}
.cart-sum-val{font-family:"Cormorant Garamond",serif;font-size:1.6rem;color:var(--cream);letter-spacing:.03em}
.cart-note{margin-top:.5rem;font-size:.8rem;color:var(--whisper);font-style:italic;font-family:"Cormorant Garamond",serif}
.cart-foot .solid-btn{display:block;width:100%;text-align:center;margin-top:1.1rem;border:0;cursor:pointer}
.cart-empty{
  flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:1.2rem;text-align:center;
}
.cart-empty-mark{width:120px;height:120px;opacity:.3}
.cart-empty p{color:var(--whisper);font-family:"Cormorant Garamond",serif;font-style:italic;font-size:1.15rem}

/* =========================================================================
   CHECKOUT
   ========================================================================= */
.co{align-items:center;justify-content:center;padding:clamp(0px,3vw,2rem)}
.co-panel{
  position:relative;width:min(600px,100%);max-height:100%;overflow-y:auto;
  background:var(--forest);border:1px solid var(--hair);
  padding:clamp(1.6rem,3.4vw,2.8rem);
  transform:translateY(26px);transition:transform .7s var(--ease);
}
.overlay.is-open .co-panel{transform:none}
.co-title{font-size:2.2rem;color:var(--bone);margin-bottom:1.2rem}
.co-title em{color:var(--gold-light)}
.co-steps{
  list-style:none;display:flex;gap:1.4rem;margin-bottom:1.8rem;
  border-bottom:1px solid var(--hair);padding-bottom:.9rem;
}
.co-step{
  font-family:"Bebas Neue",sans-serif;font-size:.76rem;letter-spacing:.24em;
  text-transform:uppercase;color:var(--whisper);opacity:.5;
  transition:opacity .45s var(--ease),color .45s var(--ease);
}
.co-step.is-on{opacity:1;color:var(--gold)}
.co-lines{list-style:none;display:flex;flex-direction:column;gap:.7rem}
.co-lines li{display:flex;justify-content:space-between;gap:1rem;color:var(--whisper);font-size:.95rem}
.co-lines .is-onrequest{font-style:italic}
.co-total{
  display:flex;justify-content:space-between;align-items:baseline;
  margin-top:1.2rem;padding-top:1rem;border-top:1px solid var(--hair);
  font-family:"Bebas Neue",sans-serif;letter-spacing:.22em;text-transform:uppercase;
  font-size:.78rem;color:var(--whisper);
}
.co-total span:last-child{font-family:"Cormorant Garamond",serif;font-size:1.5rem;color:var(--cream);letter-spacing:.03em}
.co-note{margin-top:1rem;font-size:.86rem;color:var(--whisper);font-style:italic;font-family:"Cormorant Garamond",serif}
.co-form{display:flex;flex-direction:column;gap:1.1rem}
.co-field{display:flex;flex-direction:column;gap:.4rem}
.co-field > span{
  font-family:"Bebas Neue",sans-serif;font-size:.72rem;letter-spacing:.24em;
  text-transform:uppercase;color:var(--gold);
}
.co-field input,.co-field select,.co-field textarea{
  background:rgba(14,20,16,.5);border:1px solid var(--hair);
  color:var(--bone);font-family:"Chakra Petch",sans-serif;font-weight:300;
  font-size:.98rem;padding:.7rem .8rem;letter-spacing:.02em;width:100%;
  transition:border-color .45s var(--ease);
}
.co-field textarea{resize:vertical}
.co-field input:focus,.co-field select:focus,.co-field textarea:focus{outline:none;border-color:var(--gold)}
.co-field select{appearance:none;cursor:pointer}
.co-field option{background:var(--forest);color:var(--bone)}
.co-ref{
  font-family:"Bebas Neue",sans-serif;letter-spacing:.28em;color:var(--gold);
  font-size:.86rem;margin-bottom:1rem;
}
.co-detail{display:grid;grid-template-columns:auto 1fr;gap:.4rem 1.2rem;margin-top:1.3rem;font-size:.92rem}
.co-detail dt{font-family:"Bebas Neue",sans-serif;font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;color:var(--gold)}
.co-detail dd{color:var(--whisper)}
.co-err{margin-top:.9rem;color:#D98A72;font-size:.88rem;min-height:1.2em}
.co-nav{display:flex;gap:1rem;align-items:center;margin-top:1.6rem}
.co-nav .co-back{cursor:pointer;background:none}
.co-nav .co-fwd{flex:1;border:0;cursor:pointer;padding:1.05em 1.6em;text-align:center;font-size:.88rem}

/* =========================================================================
   SHOP — RESPONSIVE
   ========================================================================= */
@media (max-width:900px){
  .pd-panel{grid-template-columns:1fr;max-height:100%;overflow-y:auto}
  .pd-primary{max-height:46vh}
  .pd-info{overflow:visible}
}
@media (max-width:760px){
  .wordmark-sm{gap:7px}
  .wordmark-mark{width:24px;height:24px}
  .apo-head h2 .head-mark{width:32px;height:32px}
  .pd{padding:0}
  .pd-panel{width:100%;height:100%;max-height:100%;border:0}
  .pd-close{top:8px;right:8px;width:36px;height:36px}
  .pd-arrow{width:38px;height:52px}
  .co{padding:0}
  .co-panel{width:100%;height:100%;max-height:100%;border:0}
  .cart-panel{width:100%;border-left:0}
  .pd-actions{gap:.7rem}
  .pd-add{flex:1;min-width:0}
}
@media (max-width:380px){
  .pd-info{padding:1.1rem}
  .pd-name{font-size:1.9rem}
  .pd-thumb{width:52px;height:52px}
  .co-panel{padding:1.1rem}
  .co-steps{gap:.9rem}
  .co-step{font-size:.68rem;letter-spacing:.16em}
  .cart-thumb{width:60px;height:60px}
  .cart-line{gap:.7rem}
}

@media (prefers-reduced-motion:reduce){
  .overlay,.pd-panel,.cart-panel,.co-panel{transition:none!important}
  .pd-panel,.co-panel{transform:none!important}
  .cart-panel{transform:none!important}
}

/* The overlays autofocus their close button, so the default blue ring was the
   first thing on screen. Gold, to match everything else. */
.overlay :focus-visible,
.card.is-tappable:focus-visible,
.cart-btn:focus-visible{
  outline:1px solid var(--gold);
  outline-offset:2px;
}
.overlay .co-field input:focus-visible,
.overlay .co-field select:focus-visible,
.overlay .co-field textarea:focus-visible{outline-offset:0}

/* ---------- the five group flat-lays, off the shop header ---------- */
.apo-head-foot{
  display:flex;align-items:center;gap:1.4rem;flex-wrap:wrap;
  margin-top:1.2rem;
}
.apo-head-foot .apo-hint{margin-top:0}
.apo-range{cursor:pointer;background:none;font-family:"Bebas Neue",sans-serif}
.apo-range[hidden]{display:none}
/* shelf arrows — the affordance a native scroller needs */
.apo-arrows{display:flex;gap:.5rem;margin-left:auto}
.apo-arrow{
  width:2.6rem;height:2.6rem;padding:0;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:1rem;line-height:1;cursor:pointer;background:none;
}
.apo-arrow[hidden]{display:none}
@media (max-width:767.98px){ .apo-arrows{display:none} }
/* the range view is gallery-led — caption under, not beside. The panel
   stacks, so it needs room to scroll rather than clipping the caption. */
.pd-panel--wide{grid-template-columns:1fr;overflow-y:auto}
.pd-panel--wide .pd-primary{max-height:min(58vh,540px)}
.pd-rangecap{
  padding:clamp(1.2rem,2.4vw,2rem) clamp(1.6rem,3vw,2.8rem) clamp(1.6rem,3vw,2.4rem);
  display:flex;flex-direction:column;gap:.6rem;
}
.pd-rangecap .eyebrow{margin-bottom:0}
.pd-rangecap .pd-name{font-size:clamp(1.8rem,3vw,2.6rem)}
@media (max-width:760px){
  .apo-head-foot{gap:.9rem}
}
/* the product name is the control that opens the detail view */
.card-open{
  background:none;border:0;padding:0;margin:0;cursor:pointer;
  font:inherit;color:inherit;letter-spacing:inherit;text-align:left;
}
.card-open:hover em{color:var(--gold)}

/* =========================================================================
   THE SHELF ON A PHONE — 2026-09
   Horizontal-scroll-on-pin is a desktop idiom; below 768px the shelf is a
   plain grid that rides the native scroll.

   This block also fixes the defect that hid the shop on mobile: the base
   .apo-pin rule carries `height:100svh` and `overflow:hidden` for the pinned
   desktop shelf, and the old mobile override reset min-height/display/padding
   but NOT those two. The stacked column ran to ~8,460px inside a 740px box
   with hidden overflow, so ten of eleven cards were clipped away entirely.
   Both properties must be reset here — do not remove either line.
   ========================================================================= */
@media (max-width:767.98px){
  .apothecary{height:auto}
  .apo-hint{display:none}                    /* the shelf no longer scrolls sideways */
  .apo-pin{
    height:auto;                             /* was 100svh — the clip */
    min-height:0;
    overflow:visible;                        /* was hidden — the clip */
    display:block;
    padding:clamp(3.4rem,9vh,5rem) 0;
  }
  .apo-track{
    display:grid;
    grid-template-columns:repeat(auto-fill,minmax(248px,1fr));
    gap:1.4rem;
    padding:0 var(--pad);
    overflow:visible;
    transform:none!important;                /* in case a stale GSAP x survives */
    scroll-snap-type:none;
    will-change:auto;
  }
  .apo-track .card{
    flex:none;width:100%;height:auto;min-height:0;
  }
  .apo-track .card-media{aspect-ratio:4/5;min-height:0}   /* jar leads on a phone too */
  .apo-track .card--end{grid-column:1/-1;min-height:260px}
}

/* =========================================================================
   VARIANTS + M-PESA CHECKOUT — 2026-09
   ========================================================================= */

/* ---------- size selector (segmented pills, not a native select) ---------- */
.pd-sizes{display:flex;flex-direction:column;gap:.55rem;margin-top:.2rem}
.pd-sizes-label{
  font-family:"Bebas Neue",sans-serif;font-size:.72rem;letter-spacing:.28em;
  text-transform:uppercase;color:var(--gold);
}
.size-pills{display:flex;flex-wrap:wrap;gap:.5rem}
.size-pill{
  font-family:"Bebas Neue",sans-serif;
  font-size:.82rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--whisper);background:none;cursor:pointer;
  padding:.62em 1.15em;border:1px solid var(--hair);
  transition:background-color .5s var(--ease),color .5s var(--ease),
             border-color .5s var(--ease);
}
.size-pill:hover{color:var(--bone);border-color:var(--gold)}
.size-pill.is-on{background:var(--gold);color:var(--ink);border-color:var(--gold)}

/* the size is the identity of a cart line, so it reads louder than a subtitle */
.cart-size{
  font-family:"Bebas Neue",sans-serif;font-size:.7rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--gold);
}

/* ---------- the Till ---------- */
.till{
  border:1px solid var(--gold);
  background:linear-gradient(165deg,rgba(36,58,44,.55),rgba(14,20,16,.5));
  padding:clamp(1.3rem,3vw,1.9rem);
  text-align:center;
}
.till-label{
  font-family:"Bebas Neue",sans-serif;font-size:.74rem;letter-spacing:.34em;
  text-transform:uppercase;color:var(--gold);
}
.till-number{
  font-family:"Cormorant Garamond",serif;font-weight:300;
  font-size:clamp(2.8rem,9vw,4rem);line-height:1;color:var(--cream);
  letter-spacing:.06em;margin:.35rem 0 .2rem;
}
.till-name{
  font-family:"Cormorant Garamond",serif;font-style:italic;
  font-size:1.05rem;color:var(--bone);
}
.till-amount{
  display:flex;align-items:baseline;justify-content:center;gap:.8rem;
  margin-top:1rem;padding-top:.9rem;border-top:1px solid var(--hair);
}
.till-amount span{
  font-family:"Bebas Neue",sans-serif;font-size:.74rem;letter-spacing:.3em;
  text-transform:uppercase;color:var(--whisper);
}
.till-amount strong{
  font-family:"Cormorant Garamond",serif;font-weight:300;
  font-size:1.9rem;color:var(--gold-light);letter-spacing:.03em;
}
.till-copy{
  margin-top:1.1rem;cursor:pointer;background:none;
  font-family:"Bebas Neue",sans-serif;font-size:.76rem;letter-spacing:.24em;
  text-transform:uppercase;color:var(--gold-light);
  padding:.7em 1.3em;border:1px solid var(--hair);
  transition:background-color .5s var(--ease),color .5s var(--ease),border-color .5s var(--ease);
}
.till-copy:hover{border-color:var(--gold)}
.till-copy.is-copied{background:var(--gold);color:var(--ink);border-color:var(--gold)}

.till-how{
  margin:1.4rem 0 1.2rem;padding-left:1.15rem;
  color:var(--whisper);font-size:.92rem;line-height:1.95;
}
.till-how li::marker{color:var(--gold);font-family:"Bebas Neue",sans-serif}
.till-how strong{color:var(--cream);font-weight:400}

.co-hint{
  margin-top:.4rem;font-size:.8rem;color:var(--gold-light);
  font-family:"Cormorant Garamond",serif;font-style:italic;
}
.co-step.is-done{opacity:.85;color:var(--whisper)}

@media (max-width:380px){
  .co-steps{gap:.55rem}
  .co-step{font-size:.62rem;letter-spacing:.1em}
  .till-number{font-size:2.6rem}
}

/* =========================================================================
   PRODUCTS OFF THE PAGE — 2026-09
   The jar should dominate the card and sit ABOVE the background rather than
   in it. The shadow belongs to the image plate; the elevation belongs to the
   card. Deliberately no filter:drop-shadow on the card itself — that would
   smear the hairline border and the type along with the photograph.
   ========================================================================= */

/* give the photograph more of the card */
.card-body{
  padding:clamp(.95rem,1.5vw,1.4rem);
  gap:.4rem;
}
.card-body .card-ing{font-size:.83rem;line-height:1.6}
.card-foot{margin-top:.55rem}

.card-media{
  /* overflow:hidden clips the child image, not the element's own box-shadow,
     so the plate can cast beneath itself without an extra wrapper */
  z-index:1;
  box-shadow:
    0 22px 38px -20px rgba(0,0,0,.88),          /* diffuse dark, beneath */
    0 0 54px -14px rgba(200,154,90,.20);        /* warm glow, behind */
  transition:box-shadow 1.1s var(--ease), transform 1.1s var(--ease);
}
.card:hover .card-media{
  transform:translateY(-6px);
  box-shadow:
    0 36px 56px -20px rgba(0,0,0,.94),
    0 0 76px -12px rgba(200,154,90,.30);
}

/* the closing rail has no photograph, so it gets neither */
.card--end .card-media{box-shadow:none}

@media (hover:none){
  /* no hover on touch — ship the lifted state as the resting state */
  .card-media{
    box-shadow:
      0 20px 34px -20px rgba(0,0,0,.85),
      0 0 48px -14px rgba(200,154,90,.18);
  }
}
@media (prefers-reduced-motion:reduce){
  .card-media{transition:none}
  .card:hover .card-media{transform:none}
}

/* =========================================================================
   THE GALLERY — 2026-09
   Every frame from the shoot that is not already a product's primary image,
   plus the five flat-lays. Masonry via CSS columns: it handles the shoot's
   mixed portrait/landscape frames without JS measuring anything. Every image
   carries its intrinsic width/height so the column heights are reserved
   before the lazy images land and nothing reflows under the reader.
   ========================================================================= */
.gallery{
  padding:clamp(5rem,11vh,9rem) var(--pad);
  background:linear-gradient(180deg,var(--ink),rgba(26,42,31,.35) 60%,var(--ink));
}
.gal-head{margin-bottom:clamp(2.4rem,5vh,3.6rem)}
.gal-head h2{font-size:clamp(2.2rem,5.4vw,4.4rem);color:var(--bone)}
.gal-head h2 em{color:var(--gold-light)}

.gal-wall{
  column-count:4;
  column-gap:clamp(.7rem,1.2vw,1.1rem);
  max-width:1600px;margin:0 auto;
}
.gal-item{
  display:block;width:100%;padding:0;margin:0 0 clamp(.7rem,1.2vw,1.1rem);
  border:0;background:none;cursor:pointer;
  break-inside:avoid;-webkit-column-break-inside:avoid;
  position:relative;overflow:hidden;
  line-height:0;
}
.gal-item img{
  width:100%;height:auto;display:block;
  filter:saturate(.92) brightness(.9);
  transition:transform 1.2s var(--ease),filter 1.2s var(--ease);
}
.gal-item::after{
  content:"";position:absolute;inset:0;
  border:1px solid rgba(200,154,90,0);
  transition:border-color .9s var(--ease);
  pointer-events:none;
}
.gal-item:hover img{transform:scale(1.045);filter:saturate(1) brightness(1)}
.gal-item:hover::after{border-color:var(--hair)}
.gal-item:focus-visible{outline:1px solid var(--gold);outline-offset:2px}

@media (max-width:1200px){ .gal-wall{column-count:3} }
@media (max-width:767.98px){ .gal-wall{column-count:2} }
@media (max-width:380px){ .gal-wall{column-count:2;column-gap:.55rem} .gal-item{margin-bottom:.55rem} }

@media (prefers-reduced-motion:reduce){
  .gal-item img{transition:none}
  .gal-item:hover img{transform:none}
}

/* =========================================================================
   THE ARRIVAL — 2026-09
   Arrival, then treatment. A single non-looping clip is only ever readable
   as deliberate in a transition like this one.
   ========================================================================= */
.arrival{
  position:relative;overflow:hidden;
  height:min(62vh,560px);
  background:var(--ink);
  padding:0;
  display:flex;align-items:flex-end;
}
.arrival-media{position:absolute;inset:0;z-index:0}
.arrival-video{
  width:100%;height:100%;object-fit:cover;object-position:center 42%;
  display:block;
  filter:saturate(.86) brightness(.86) contrast(1.02);
}
.arrival-scrim{
  position:absolute;inset:0;
  background:
    linear-gradient(180deg,rgba(14,20,16,.72) 0%,rgba(14,20,16,.18) 32%,
                    rgba(14,20,16,.42) 72%,var(--ink) 100%);
}
.arrival-label{
  position:relative;z-index:1;
  margin:0 0 clamp(1.6rem,4vh,2.6rem) var(--pad);
  color:var(--gold-light);
}
@media (max-width:767.98px){
  .arrival{height:min(52vh,420px)}
}
