/* =====================================================
   THE ASTELL — INTERIOR DESIGN SYSTEM
   Quiet Luxury + Editorial.
   Applies to every page except the homepage (/index.html).

   Principles:
   · Whitespace is the primary material — sections breathe.
   · Typography is the hero. Serif display, sans body, few words.
   · No stacked cards. Surfaces earn their existence; hairlines
     do the work that borders and boxes used to.
   · Motion is slow, soft and additive — never attention-seeking.
   ===================================================== */

:root {
  --gut-m: 24px;   /* the single phone gutter — must match index.html */
  /* ── warm palette (locked CI) ── */
  --ivory:     #F8F4ED;
  --pearl:     #FCFAF5;
  --cream:     #EFE7DA;
  --sand:      #E9D9BF;
  --champagne: #D8C2A7;
  --gold:      #C6A977;
  --gold-lt:   #D4B880;
  --gold-deep: #997951;
  --taupe:     #8E7A68;
  --mocha:     #23150F;
  --chocolate: #2A1D16;

  /* ── ink levels (never pure black) ── */
  --ink:      #23150F;
  --ink-80:   rgba(35,21,15,.80);
  --ink-64:   rgba(35,21,15,.64);
  --ink-48:   rgba(35,21,15,.48);
  --ink-32:   rgba(35,21,15,.32);
  --hairline: rgba(35,21,15,.11);

  /* 'Noto Sans SC' trails the Latin face rather than replacing it in 中文: Latin
     glyphs resolve in Cormorant/Jost, only Han glyphs fall through. */
  --serif: 'Cormorant Garamond', 'Noto Sans SC', serif;
  --sans:  'Jost', 'Noto Sans SC', sans-serif;

  /* ── motion ── */
  --ease:      cubic-bezier(.16, 1, .3, 1);
  --ease-soft: cubic-bezier(.4, 0, .2, 1);

  /* ── rhythm ── */
  --gut:     clamp(30px, 6vw, 88px);   /* page gutter — the floor is the phone gutter */
  --sec:     clamp(96px, 14vh, 190px); /* section spacing */
  --radius:  18px;
  --shadow:  0 30px 80px -30px rgba(35,21,15,.22);

  /* ── liquid glass (same recipe as the homepage) ── */
  --g-bg:      rgba(255, 255, 255, 0.18);
  --g-bg-deep: rgba(255, 255, 255, 0.26);
  --g-border:  rgba(255, 255, 255, 0.26);
  --g-top:     rgba(255, 255, 255, 0.55);
  --g-blur:    blur(32px) saturate(180%) brightness(104%);
  --g-shadow:  0 8px 40px rgba(35, 21, 15, 0.09),
               inset 0 1.5px 0 rgba(255, 255, 255, 0.65),
               inset 0 -1px 0 rgba(35, 21, 15, 0.04);
  --g-radius:  20px;
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100% }
main { overflow-x: clip }

body {
  background: linear-gradient(178deg, #FAF7F1 0%, #F5EFE4 42%, #F2E9DA 72%, #F8F3EA 100%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;          /* `clip`, not `hidden` — `hidden` here would make body a scroll
                                container and break any `position: sticky` on the page */
}
img { display: block; width: 100%; height: auto; object-fit: cover }
a { text-decoration: none; color: inherit }
::selection { background: var(--champagne); color: var(--mocha) }
a:focus-visible, button:focus-visible {
  outline: 1px solid var(--gold-deep); outline-offset: 4px; border-radius: 2px;
}

/* ── shared type atoms ────────────────────────────── */
.eyebrow {
  display: block;
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .42em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.display {
  font-family: var(--serif);
  font-weight: 300;
  font-style: italic;
  letter-spacing: -.022em;
  line-height: 1.02;
  color: var(--ink);
}
.display em { font-style: italic; color: var(--gold-deep) }
.lede {
  font-family: var(--serif);
  font-size: clamp(20px, 2.05vw, 27px);
  font-style: italic;
  font-weight: 300;
  line-height: 1.62;
  color: var(--ink-80);
  letter-spacing: -.005em;
}

/* ── layout containers ────────────────────────────── */
.shell   { width: 100%; padding-inline: var(--gut) }
.measure { max-width: 660px }
.wide    { max-width: 1320px; margin-inline: auto }
.mid     { max-width: 1040px; margin-inline: auto }

/* =====================================================
   NAV — floating liquid-glass pill.
   Monogram circle left · one centred pill holding the
   links and the Book Now button · burger right (mobile).
   The bar itself is transparent; the glass lives on the
   pill and the monogram, so imagery runs behind them.
   ===================================================== */
nav {
  position: fixed; inset: 14px 0 auto 0; z-index: 100;
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0 clamp(18px, 3vw, 40px);
  background: transparent;
  transition: transform .7s var(--ease);
}
nav.scrolled { transform: translateY(-2px) }

/* shared liquid-glass recipe (pill + monogram) — a luminous top edge and a
   soft gradient rim, drawn with a masked border so imagery glows through */
.nav-links {
  position: relative;
  background: rgba(255,255,255,.05);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  box-shadow: inset 0 1px 1px rgba(255,255,255,.14), 0 10px 34px -18px rgba(35,21,15,.45);
}
.nav-links::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  padding: 1.2px;
  background: linear-gradient(180deg,
    rgba(255,255,255,.5) 0%, rgba(255,255,255,.16) 24%,
    rgba(255,255,255,0) 45%, rgba(255,255,255,0) 60%,
    rgba(255,255,255,.16) 82%, rgba(255,255,255,.5) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  pointer-events: none;
}

/* logo: frameless — the mark alone, no plate, no rim, no border */
.nav-logo {
  justify-self: start;
  /* declared here, not on the img, so the frosted layer further down inherits the same box */
  --logo-box: 132px;
  display: flex; align-items: center;
  /* No plate. The padding stays — it is the link's tap area, and the link already measures
     only ~37px tall. border-radius is kept so the focus ring follows a rounded box. Without
     the plate the frosted letters sample the photograph itself rather than an already-blurred
     layer, which is what makes the glass read. */
  padding: 7px 14px; border-radius: 18px;
  transition: transform .5s var(--ease);
}
.nav-logo:hover { transform: scale(1.03) }
/* The logo asset is a 6250x6250 square whose actual mark occupies only the
   middle 75% x 23.7% — the rest is transparent padding. Sizing by height
   therefore rendered a tiny mark. Crop the padding away and pull the empty
   space back with negative margins so the box hugs the artwork. */
.nav-logo img {
  width: var(--logo-box); height: var(--logo-box);
  object-fit: contain; display: block;
  clip-path: inset(37.6% 12.2%);
  margin-block: calc(var(--logo-box) * -0.376);
  margin-inline: calc(var(--logo-box) * -0.122);
  filter: brightness(.24) sepia(.44) saturate(2.2) hue-rotate(-10deg);
  transition: filter .5s var(--ease);
}

.nav-links {
  justify-self: center;
  display: flex; align-items: center; gap: 2px;
  padding: 6px;
  border-radius: 100px;
}
.nav-links a {
  position: relative;
  font-size: 10.5px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-64);
  padding: 10px 15px; border-radius: 100px;
  transition: color .5s var(--ease-soft), background .5s var(--ease-soft);
}
.nav-links a:hover { color: var(--ink); background: rgba(255,255,255,.28) }
.nav-links a[aria-current="page"] { color: var(--ink); background: rgba(255,255,255,.34) }

/* ── ACTIVE-PAGE INDICATOR ─────────────────────────────────────────────────────────────────
   The active pill used to be a background painted on the link itself, so moving between
   pages simply cut from one pill to the next. It is now a single element that travels: on
   click it stretches across the gap, then settles onto the target. The stretch is the part
   that reads as motion rather than a jump.
   Palette is untouched — this is the same pill in the same colours, only moving. The two
   backgrounds below mirror a[aria-current] exactly, light nav and over-photo nav.
   Gated on html.js and on the desktop nav row: without script, or in the mobile drawer,
   the static background on the link is still what paints. */
@media (min-width: 1061px) {
  .nav-links { position: relative }
  .nav-links a, .nav-drop { z-index: 1 }
  .nav-ind {
    position: absolute; z-index: 0; top: 0; left: 0; width: 0; height: 0;
    border-radius: 100px; opacity: 0; pointer-events: none;
    background: rgba(255,255,255,.34);
    transition: opacity .35s var(--ease-soft);
  }
  .nav-ind.on { opacity: 1 }
  body.has-visual nav:not(.scrolled) .nav-ind { background: rgba(255,255,255,.18) }
  /* The link keeps its colour change; only the background moves out to the indicator.
     Both over-photo and scrolled variants have to be named — the .has-visual rule further
     down outranks a bare html.js selector, and leaving it in force stacks two pills. */
  html.js .nav-links a[aria-current="page"],
  html.js nav.scrolled .nav-links a[aria-current="page"],
  html.js body.has-visual nav:not(.scrolled) .nav-links a[aria-current="page"] { background: transparent }
}
/* outside the query: the element must not sit in the mobile drawer as a stray flex item */
.nav-ind { display: none }
@media (min-width: 1061px) { .nav-ind { display: block } }


.nav-book {
  margin-left: 6px;
  padding: 10px 20px !important;
  background: var(--mocha);
  color: var(--ivory) !important;
  display: inline-flex; align-items: center; gap: 7px;
  transition: background .6s var(--ease), color .6s var(--ease), transform .6s var(--ease) !important;
}
.nav-book::after {
  content: '\2197';
  font-size: 12px; line-height: 1;
  transition: transform .5s var(--ease);
}
.nav-book:hover { background: var(--gold-deep); color: var(--ivory) !important; transform: none }
.nav-book:hover::after { transform: translate(2px, -2px) }

/* ── EN / 中文 pill ──
   Interior pages are mostly cream, so the resting state here is dark ink on glass — the
   inverse of the homepage, whose nav sits on a dark hero. Photo-hero pages (body.has-visual)
   flip to the light treatment until the nav picks up its scrolled state. */
.nav-right { justify-self: end; display: flex; align-items: center; gap: 10px }
.lang-pill {
  position: relative;
  display: flex; align-items: center; gap: 3px;
  padding: 6px 8px 6px 12px; border-radius: 100px;
  background: rgba(35, 21, 15, .05);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, .35), 0 10px 34px -18px rgba(35, 21, 15, .4);
}
.lang-globe {
  width: 15px; height: 15px; margin-right: 4px; flex: 0 0 auto;
  stroke: rgba(35, 21, 15, .5); fill: none; stroke-width: 1.5;
  transition: stroke .4s;
}
.lang-btn {
  background: none; border: none; cursor: pointer;
  /* was 32x25 / 38x26 — under the 44x44 touch target, on the one control a Chinese-speaking
     visitor has to find first. The pill keeps its painted size; the box grows around it. */
  /* Height comes from .nav-links a — same font-size, same padding, and line-height inherited
     the same way — so the language pill and the menu pill measure identically. The 44px touch
     target is restored by ::after, which adds no layout height. */
  position: relative;
  min-width: 44px; line-height: inherit;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 10px 11px; border-radius: 100px;
  /* the CJK stack matters now that Noto Sans SC is no longer downloaded up front: without it
     the two characters on this button fall back to whatever the OS picks. */
  font-family: var(--sans), 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Noto Sans SC', sans-serif;
  font-size: 10.5px; letter-spacing: .1em; font-weight: 600;
  color: rgba(35, 21, 15, .5); transition: color .35s, background .35s;
}
.lang-btn:hover { color: var(--ink); background: rgba(255, 255, 255, .45) }
.lang-btn.active { color: var(--ivory); background: var(--ink) }
.lang-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px }
.lang-btn::after {
  content: ''; position: absolute; left: 0; right: 0;
  top: 50%; height: 44px; transform: translateY(-50%);
}

body.has-visual nav:not(.scrolled) .lang-pill { background: rgba(255, 255, 255, .06) }
body.has-visual nav:not(.scrolled) .lang-globe { stroke: rgba(252, 250, 245, .75) }
body.has-visual nav:not(.scrolled) .lang-btn { color: rgba(252, 250, 245, .62) }
body.has-visual nav:not(.scrolled) .lang-btn:hover { color: var(--ivory); background: rgba(255, 255, 255, .14) }
body.has-visual nav:not(.scrolled) .lang-btn.active { color: var(--mocha); background: var(--pearl) }

/* 中文 only restyles what is actually translated. Cormorant's italic display sizing does not
   suit Han characters, so tagged nodes drop the slant and the tracking — but a section still
   in English keeps the exact English typography, italics and all. */
html.zh [data-zh], html.zh [data-zh] * { font-style: normal }
html.zh :is(h1, h2, h3, .display, .lede, .statement p, .cta p, .vband-cap p)[data-zh],
html.zh :is(h1, h2, h3, .display, .lede, .statement p, .cta p, .vband-cap p)[data-zh] * {
  letter-spacing: 0; line-height: 1.35;
}
html.zh .eyebrow[data-zh] { letter-spacing: .16em }

@media (max-width: 1060px) {
  .nav-right { gap: 4px }
  .lang-pill { padding: 4px 6px 4px 10px }
  .lang-globe { width: 13px; height: 13px }
  .lang-btn { padding: 5px 8px; font-size: 10px }
}

.burger {
  display: none; flex-direction: column; gap: 6px; align-items: center; justify-content: center;
  background: none; border: 0; cursor: pointer; padding: 8px;
  /* measured 38x31 — the one control the whole mobile nav depends on, under the 44px min */
  min-width: 44px; min-height: 44px;
}
.burger span {
  display: block; width: 22px; height: 1px; background: var(--ink);
  transition: transform .5s var(--ease), opacity .35s;
}
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg) }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0 }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg) }

/* =====================================================
   BUTTONS — minimal, warm, soft hover
   ===================================================== */
.btn {
  display: inline-block;
  font-family: var(--sans); font-size: 10.5px; font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase;
  padding: 17px 42px; border-radius: 100px;
  border: 1px solid var(--ink-32); color: var(--ink);
  cursor: pointer;
  transition: background .7s var(--ease), color .7s var(--ease),
              border-color .7s var(--ease), transform .7s var(--ease);
}
.btn:hover { background: var(--mocha); border-color: var(--mocha); color: var(--ivory); transform: translateY(-2px) }

/* ── ENQUIRY FORM — hairline fields, no boxes ── */
.enq { margin-top: clamp(34px, 4.4vh, 54px); max-width: 780px }
.enq-row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(20px, 3vw, 40px) }
.enq-row + .enq-row { margin-top: clamp(20px, 3vw, 34px) }
.enq-field { display: block }
.enq-label {
  display: block; margin-bottom: 10px;
  font-family: var(--sans); font-size: 9.5px; font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase; color: var(--ink-48);
}
.enq input, .enq select, .enq textarea {
  width: 100%; padding: 12px 2px 13px;
  /* 16px, not 15: below 16px iOS Safari zooms the page on focus */
  font-family: var(--sans); font-size: 16px; color: var(--ink);
  background: transparent; border: 0; border-bottom: 1px solid var(--hairline);
  border-radius: 0; appearance: none; -webkit-appearance: none;
  transition: border-color .5s var(--ease);
}
.enq select {
  /* the caret has to be drawn in — appearance:none removes the native one */
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-48) 50%),
                    linear-gradient(135deg, var(--ink-48) 50%, transparent 50%);
  background-position: right 8px center, right 3px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 22px; cursor: pointer;
}
.enq-field--wide { margin-top: clamp(22px, 3vw, 32px) }
.enq-label em { font-style: normal; text-transform: none; letter-spacing: .04em; opacity: .7 }
/* multi-select as tappable chips — a native multiple-select is unusable on a phone */
.enq-chips { display: flex; flex-wrap: wrap; gap: 8px }
.enq-chip { cursor: pointer }
.enq-chip input { position: absolute; opacity: 0; width: 0; height: 0 }
.enq-chip span {
  display: inline-flex; align-items: center; min-height: 38px; padding: 8px 16px;
  border: 1px solid var(--hairline); border-radius: 100px;
  font-family: var(--sans); font-size: 12px; letter-spacing: .04em; color: var(--ink-64);
  transition: background .4s var(--ease), border-color .4s var(--ease), color .4s var(--ease);
}
.enq-chip:hover span { border-color: var(--ink-32); color: var(--ink) }
.enq-chip input:checked + span {
  background: var(--mocha); border-color: var(--mocha); color: var(--ivory); font-weight: 500;
}
.enq-chip input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: 2px }

.enq input::placeholder, .enq textarea::placeholder { color: var(--ink-32) }
.enq textarea { resize: vertical; min-height: 76px; line-height: 1.6 }
.enq input:focus, .enq select:focus, .enq textarea:focus { outline: none; border-bottom-color: var(--gold-deep) }
/* Treatment interest is health-related data, so PDPA s.26 wants consent given by a deliberate
   act rather than inferred from pressing Send. The box is unticked and the form will not submit
   without it. */
.enq-consent-box { display: flex; gap: 11px; align-items: flex-start; margin-top: 22px;
  font-size: 11.5px; line-height: 1.8; color: var(--ink-64); max-width: 62ch; cursor: pointer }
.enq-consent-box input { width: 17px; height: 17px; flex: 0 0 auto; margin-top: 3px;
  accent-color: var(--gold-deep); appearance: auto; -webkit-appearance: auto; border: 0 }
.enq-consent-box a { color: var(--gold-deep); text-decoration: underline; text-underline-offset: 2px }
.enq-consent {
  margin-top: clamp(24px, 3.2vh, 36px);
  font-size: 12px; line-height: 1.8; color: var(--ink-48); max-width: 58ch;
}
.enq-send { margin-top: 22px; background: transparent }
.enq-status { margin-top: 16px; font-size: 13px; line-height: 1.7; min-height: 1.2em }
.enq-status.is-ok  { color: var(--gold-deep) }
.enq-status.is-err { color: #9C4A32 }
@media (max-width: 680px) {
  .enq-row { grid-template-columns: 1fr; gap: 22px }
  .enq-row + .enq-row { margin-top: 22px }
}
.btn-light { border-color: rgba(248,244,237,.34); color: var(--ivory) }
.btn-light:hover { background: var(--ivory); border-color: var(--ivory); color: var(--mocha) }

/* quiet text link with arrow */
.tlink {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 10.5px; font-weight: 500; letter-spacing: .2em; text-transform: uppercase;
  color: var(--gold-deep);
  transition: gap .6s var(--ease), color .6s var(--ease);
}
.tlink:hover { gap: 18px; color: var(--ink) }

/* =====================================================
   PAGE HERO — typography-led, enormous breathing room
   ===================================================== */
.phero {
  padding-block: clamp(150px, 20vh, 240px) clamp(48px, 8vh, 96px);
}
.phero .eyebrow { margin-bottom: clamp(24px, 3vh, 40px) }
.phero h1 {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(46px, 8.4vw, 128px);
  line-height: .98; letter-spacing: -.028em;
  color: var(--ink);
  max-width: 20ch; text-wrap: balance;
}
.phero h1 em { color: var(--gold-deep) }
.phero .lede { margin-top: clamp(28px, 4vh, 52px); max-width: 46ch }

/* centred variant for article-style pages */
.phero.center { text-align: center }
.phero.center h1 { max-width: 30ch; margin-inline: auto; text-wrap: balance }
.phero.center .lede { margin-inline: auto; text-align: center }

/* =====================================================
   FULL-BLEED IMAGE — slow parallax, soft mask reveal
   ===================================================== */
.bleed {
  position: relative; overflow: hidden;
  height: clamp(340px, 64vh, 720px);
  margin-block: var(--sec);
}
.bleed.tall { height: clamp(420px, 84vh, 880px) }
.bleed-inner { position: absolute; inset: -12% 0; will-change: transform }
.bleed-inner img { width: 100%; height: 100%; object-fit: cover }
/* cross-fade stack: every frame sits on the same spot and only opacity moves, so the parallax
   transform on .bleed-inner still drives the whole band as one layer */
.bleed-inner.is-slides img { position: absolute; inset: 0; opacity: 0; transition: opacity 1.7s var(--ease) }
/* without JS the band is simply the first photograph — never an empty box */
.bleed-inner.is-slides img:first-child { opacity: 1 }
/* .is-live is set by interior.js once it owns the stack. Both rules below outrank the
   :first-child fallback on specificity, so the opening frame can fade out like any other. */
.bleed-inner.is-slides.is-live img:not(.is-on) { opacity: 0 }
.bleed-inner.is-slides.is-live img.is-on { opacity: 1 }
.bleed-cap {
  position: absolute; left: var(--gut); bottom: clamp(24px, 4vh, 48px); z-index: 2;
  font-size: 10px; letter-spacing: .32em; text-transform: uppercase;
  color: rgba(248,244,237,.82);
  text-shadow: 0 1px 20px rgba(20,11,5,.5);
}
.bleed::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(20,11,5,.30), transparent 42%);
}

/* inset (not full-bleed) figure */
.figure { border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow) }
.figure img { transition: transform 1.6s var(--ease) }
.figure:hover img { transform: scale(1.035) }

/* =====================================================
   EDITORIAL SPLIT — asymmetric, alternating
   ===================================================== */
.split {
  display: grid;
  grid-template-columns: 1.15fr .85fr;
  gap: clamp(40px, 7vw, 120px);
  align-items: center;
  margin-block: var(--sec);
}
.split.rev { grid-template-columns: .85fr 1.15fr }
.split.rev .split-media { order: 2 }
.split-media { border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow) }
.split-media img { aspect-ratio: 4/5; transition: transform 1.8s var(--ease) }
.split-media:hover img { transform: scale(1.04) }
.split-body .eyebrow { margin-bottom: 26px }
.split-body h2 {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(30px, 4vw, 60px); line-height: 1.08; letter-spacing: -.022em;
  color: var(--ink); margin-bottom: 28px;
}
.split-body h2 em { color: var(--gold-deep) }
.split-body p { font-size: 16px; line-height: 1.95; color: var(--ink-64); margin-bottom: 18px; max-width: 46ch }
.split-body .tlink { margin-top: 14px }

/* =====================================================
   ENVIRONMENT RAIL — one landscape ratio, sliding on its own
   Every frame is exported at exactly 3:2 and every tile is 3:2, so `cover` crops nothing:
   each photograph is shown whole. The staggered heights are gone — with twenty frames the
   uniform ratio is what makes the row read as one set rather than a scrapbook.
   ===================================================== */
/* Edge to edge: three frames fill the page width exactly, with nothing but the gaps between
   them. The rail is a direct child of <main>, never inside a .shell — that is deliberate.
   Sizing it with 100vw counted the scrollbar and pushed the third tile ~15px off screen;
   at full width, plain percentages measure the real thing. */
.envrail {
  position: relative;
  margin-top: clamp(40px, 5vh, 66px);
  margin-bottom: var(--sec);
  --envgap: 14px;
}
.envtrack {
  display: flex; align-items: flex-start; gap: var(--envgap);
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
  padding-block: 4px;
}
.envtrack::-webkit-scrollbar { display: none }
.envtile {
  flex: 0 0 calc((100% - 2 * var(--envgap)) / 3);
  aspect-ratio: 3 / 2;
  scroll-snap-align: start; margin: 0;
  border-radius: var(--radius); overflow: hidden;
  background: var(--sand); box-shadow: var(--shadow);
}
.envtile img { width: 100%; height: 100%; object-fit: cover; display: block;
               transition: transform 1.8s var(--ease) }
.envtile:hover img { transform: scale(1.045) }
/* the rail touches both edges, so the arrows sit inside it rather than outside */
.envrail .reelrail-prev { left: 16px }
.envrail .reelrail-next { right: 16px }

@media (max-width: 900px) {
  .envrail { --envgap: 10px }
  .envtile { flex-basis: calc((100% - var(--envgap)) / 2) }   /* two across on tablets */
}
@media (max-width: 560px) {
  .envtile { flex-basis: calc(100% - 2 * var(--envgap)) }     /* one across on phones */
}


/* =====================================================
   RECOGNITION PLAQUES
   Ported from the homepage's inline stylesheet: /doctor/ now shows the same three
   award plaques, and it loads this file instead — without these rules the markup
   rendered as an unstyled bullet list.
   ===================================================== */
/* On the homepage the plaques sit inside #numbers, which supplies the vertical rhythm.
   Here they are dropped straight into a .shell, which has none — without this the row
   collided with the section heading underneath it. */
.rec { max-width: 1180px; margin-inline: auto; margin-block: clamp(30px, 4vh, 56px) var(--sec) }
.rec-head { text-align: center; margin-bottom: clamp(44px, 5.6vh, 76px) }
.rec-head .eyebrow { display: block; margin-bottom: 18px }
.rec-head h2 { margin-inline: auto }
.rec-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2.2vw, 32px) }
.rec-award {
  position: relative; isolation: isolate;
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: clamp(46px, 4.6vw, 68px) clamp(20px, 2.2vw, 34px) clamp(32px, 3.2vw, 44px);
  min-height: clamp(430px, 38vw, 540px);          /* a plaque wants to stand tall, not sit square */
  border-radius: 999px 999px var(--g-radius) var(--g-radius);
  background: linear-gradient(172deg, rgba(255,255,255,.60), rgba(255,255,255,.20));
  backdrop-filter: blur(26px) saturate(165%);
  -webkit-backdrop-filter: blur(26px) saturate(165%);
  box-shadow: 0 30px 64px -44px rgba(35,21,15,.5);
  transition: transform .7s var(--ease), box-shadow .7s var(--ease);
}
/* gold rim, drawn as a masked gradient so it fades around the arch instead of ringing it */
.rec-award::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1.2px;
  background: linear-gradient(180deg,
    rgba(198,169,119,1) 0%, rgba(198,169,119,.55) 26%,
    rgba(216,194,167,.18) 56%, rgba(255,255,255,.6) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  pointer-events: none;
}
.rec-award:hover { transform: translateY(-6px); box-shadow: 0 42px 80px -44px rgba(35,21,15,.55) }
/* the four-point star from the wordmark, used as the award seal */
.rec-seal { width: 26px; height: 26px; color: var(--gold); flex: 0 0 auto }
.rec-seal svg { width: 100%; height: 100%; display: block; fill: currentColor }
.rec-rule { width: 1px; height: clamp(20px, 2.6vw, 34px); margin: 14px 0 18px;
            background: linear-gradient(180deg, var(--champagne), transparent) }
.rec-by {
  font-family: var(--sans); font-size: 9.5px; font-weight: 600;
  letter-spacing: .24em; text-transform: uppercase; color: rgba(35,21,15,.48);
}
.rec-by sup { font-size: .66em; letter-spacing: 0 }
.rec-title {
  margin-top: 16px;
  font-family: var(--serif); font-weight: 400; font-style: italic;
  font-size: clamp(24px, 2.3vw, 34px); line-height: 1.18;
  letter-spacing: -.012em; color: var(--mocha); text-wrap: balance;
}
/* the plaques now carry a sentence of their own, so the year is pushed to the foot by the
   body rather than by an empty gap */
.rec-body {
  margin-top: clamp(14px, 1.6vw, 20px);
  font-family: var(--sans); font-weight: 300;
  font-size: 13px; line-height: 1.75; letter-spacing: .005em;
  color: rgba(35,21,15,.62); max-width: 34ch;
}
.rec-body sup { font-size: .62em; letter-spacing: 0 }
.rec-year sup { font-size: .68em; letter-spacing: 0 }
.rec-year {
  margin-top: auto; padding-top: clamp(20px, 2.4vw, 30px);
  font-family: var(--sans); font-weight: 400;
  font-size: 12px; letter-spacing: .2em; color: var(--gold-deep);
}
.rec-foot {
  margin-top: clamp(38px, 4.6vh, 58px); text-align: center;
  font-family: var(--sans); font-size: 10.5px; font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase; color: rgba(35,21,15,.42);
}

@media (max-width: 860px) {
  .rec-grid { grid-template-columns: 1fr; gap: 18px; max-width: 420px; margin-inline: auto }
  .rec-award { border-radius: 999px 999px var(--g-radius) var(--g-radius) }
}

/* =====================================================
   ETHOS — facility + values as one spread
   Two centred text blocks running back to back read as the same section twice, and
   neither carried its own spacing so they collided. They are now one warm band with a
   two-column composition inside, split by a gold rule with the wordmark star as its bead.
   ===================================================== */
.ethos-band {
  margin-block: var(--sec);
  padding-block: clamp(74px, 9vw, 128px);
  background: linear-gradient(180deg, #F4ECDE 0%, #EDE2CE 100%);
  border-block: 1px solid rgba(160, 128, 84, .16);
}
.ethos {
  position: relative;
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(40px, 6vw, 104px);
}
.ethos > * { min-width: 0 }
/* the rule opens up at its midpoint so the star sits in the gap rather than on top of it */
.ethos::before {
  content: ''; position: absolute; inset-block: 0; left: 50%; width: 1px; translate: -.5px 0;
  background: linear-gradient(180deg,
    transparent 0%, rgba(160, 128, 84, .38) 15%, rgba(160, 128, 84, .38) 43%,
    transparent 45%, transparent 55%,
    rgba(160, 128, 84, .38) 57%, rgba(160, 128, 84, .38) 85%, transparent 100%);
}
.ethos-seal {
  position: absolute; top: 50%; left: 50%; translate: -50% -50%;
  width: 17px; height: 17px; color: var(--gold-deep);
}
.ethos-seal svg { width: 100%; height: 100%; display: block; fill: currentColor }
.ethos-col .eyebrow { display: block; margin-bottom: 18px }
.ethos-col h2 { font-size: clamp(30px, 3.4vw, 46px); line-height: 1.05; max-width: 13ch }
.ethos-rule {
  display: block; width: 40px; height: 1px; margin: clamp(24px, 2.6vw, 32px) 0;
  background: linear-gradient(90deg, var(--champagne), transparent);
}
.ethos-col p { font-size: 15.5px; line-height: 1.92; color: var(--ink-64); max-width: 44ch }
.ethos-col p + p { margin-top: 17px }

@media (max-width: 860px) {
  .ethos { grid-template-columns: 1fr; gap: 0 }
  .ethos::before, .ethos-seal { display: none }
  .ethos-col + .ethos-col {
    margin-top: clamp(38px, 8vw, 52px); padding-top: clamp(38px, 8vw, 52px);
    border-top: 1px solid rgba(160, 128, 84, .28);
  }
}

/* =====================================================
   STATEMENT — a single large line, alone on the page
   ===================================================== */
.statement { margin-block: var(--sec); text-align: center }
.statement p {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(23px, 3.05vw, 41px); line-height: 1.28; letter-spacing: -.02em;
  color: var(--ink); max-width: 100%; margin-inline: auto; text-wrap: balance;
}
.statement p em { color: var(--gold-deep) }
.statement cite {
  display: block; margin-top: 36px; font-style: normal;
  font-size: 10px; letter-spacing: .3em; text-transform: uppercase; color: var(--ink-48);
}

/* =====================================================
   TRIO — three images in a row, centred (not left/right)
   ===================================================== */
.trio {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(12px, 1.8vw, 26px);
  margin-block: var(--sec);
}
.trio figure { border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow) }
.trio img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.8s var(--ease) }
.trio figure:hover img { transform: scale(1.045) }
/* staggered heights give the row rhythm without breaking symmetry */
.trio .t-tall  { aspect-ratio: 3/4.4 }
.trio .t-mid   { aspect-ratio: 3/4; align-self: center }
.trio .t-short { aspect-ratio: 3/3.6; align-self: end }

/* DUO — two images, equal, centred */
.duo { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(12px, 1.8vw, 26px); margin-block: var(--sec) }
.duo figure { border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); aspect-ratio: 4/3 }
.duo img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.8s var(--ease) }
.duo figure:hover img { transform: scale(1.045) }

/* =====================================================
   VIDEO BAND — full-bleed, muted, slow
   ===================================================== */
.vband { position: relative; overflow: hidden; height: clamp(360px, 74vh, 780px); margin-block: var(--sec) }
.vband video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover }
.vband::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(20,11,5,.46), rgba(20,11,5,.06) 55%);
}
.vband-cap {
  position: absolute; left: 0; right: 0; bottom: clamp(40px, 7vh, 84px); z-index: 2;
  padding-inline: var(--gut); text-align: center;
}
.vband-cap p {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(24px, 3.4vw, 48px); line-height: 1.2; letter-spacing: -.02em;
  color: var(--ivory); max-width: 26ch; margin-inline: auto; text-wrap: balance;
  text-shadow: 0 2px 30px rgba(20,11,5,.4);
}
.vband-cap p em { color: var(--gold-lt) }

/* =====================================================
   CREDENTIALS — quiet centred band, hairline separated
   ===================================================== */
.creds {
  display: grid; grid-template-columns: repeat(4, 1fr);
  margin-block: var(--sec);
  border-block: 1px solid var(--hairline);
}
.cred { text-align: center; padding: clamp(34px, 4.6vw, 60px) 18px; border-right: 1px solid var(--hairline) }
.cred:last-child { border-right: 0 }
.cred-v {
  display: block; font-family: var(--sans); font-weight: 300;
  font-size: clamp(27px, 3.2vw, 44px); line-height: 1; letter-spacing: .01em; color: var(--gold-deep);
  font-feature-settings: 'lnum' 1;
}
.cred-k {
  display: block; margin-top: 16px;
  font-size: 9.5px; letter-spacing: .28em; text-transform: uppercase; color: var(--ink-48); line-height: 1.7;
}

/* ── DOCTOR PROFILES ── two physicians, side by side, no card chrome */
.docs-head { text-align: center; margin-bottom: clamp(34px, 4.6vh, 58px) }
.docs-head .display { font-size: clamp(30px, 4.4vw, 58px); margin-top: 20px }
.docs {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: clamp(30px, 4vw, 68px);
  margin-bottom: var(--sec);
}
.docp-portrait {
  /* the same arch the treatment chapters use, so the pages read as one system */
  border-radius: 999px 999px var(--radius) var(--radius);
  overflow: hidden; aspect-ratio: 3 / 3.4; background: var(--sand);
  box-shadow: var(--shadow); margin-bottom: 26px;
}
.docp-portrait img { width: 100%; height: 100%; object-fit: cover; display: block }
.docp-portrait--empty {
  box-shadow: none;
  background: repeating-linear-gradient(-45deg,
    rgba(35,21,15,.035) 0 10px, rgba(35,21,15,.06) 10px 20px);
  border: 1px dashed rgba(35,21,15,.16);
}
.docp-name {
  font-family: var(--serif); font-weight: 400; font-size: clamp(23px, 2.5vw, 32px);
  line-height: 1.2; letter-spacing: -.01em; color: var(--ink);
}
.docp-role {
  margin-top: 10px;
  font-family: var(--sans); font-size: 10px; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: var(--ink-48);
}

/* สบส. wants the licence number displayed with the registered name, so it sits directly under
   the role line rather than in the credentials list. Digits go through .num (Jost) per the
   project's numerals rule — Cormorant would render them as old-style figures. */
.docp-licence {
  margin-top: 7px;
  /* same treatment as .docp-role so the two read as one identification block — without the
     explicit family it would have inherited Cormorant and set the digits as old-style figures */
  font-family: var(--sans); font-size: 10px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase; color: var(--ink-48);
}
/* No .num override here any more. The licence number now inherits the label's own weight,
   size and tracking, so "THAI MEDICAL COUNCIL LICENCE NO. 69412" reads as one line rather
   than a label with a differently-set number bolted onto it. */

.docp-body { margin-top: 18px; font-size: 15px; line-height: 1.85; color: var(--ink-80); max-width: 46ch }
.docp-creds { list-style: none; margin: 22px 0 0; padding: 0 }
.docp-creds li {
  position: relative; padding: 11px 0 11px 20px;
  border-top: 1px solid var(--hairline);
  font-size: 13px; line-height: 1.7; color: var(--ink-64);
}
.docp-creds li::before {
  content: ''; position: absolute; left: 2px; top: 19px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--champagne);
}
/* the slot that is still waiting on the client's information reads as unfinished on purpose */
.docp--pending .docp-name,
.docp--pending .docp-body,
.docp--pending .docp-creds li { color: var(--ink-48) }
.docp--pending .docp-creds li::before { background: transparent; box-shadow: inset 0 0 0 1px var(--ink-32) }
@media (max-width: 760px) {
  .docs { grid-template-columns: 1fr; gap: 46px }
}

/* =====================================================
   EDITORIAL INDEX — the treatments list (no cards)
   ===================================================== */
/* ── FEED GRID — Instagram-style: square tiles, three across, flowing down ── */
.feed { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(6px, 1vw, 14px) }
.ftile {
  position: relative; display: block; aspect-ratio: 1 / 1; overflow: hidden;
  border-radius: 6px; background: var(--sand);
}
.ftile img { width: 100%; height: 100%; object-fit: cover; display: block;
             transition: transform 1.4s var(--ease) }
.ftile:hover img { transform: scale(1.05) }
/* the caption sits under a scrim that only deepens on hover, so the grid reads as imagery first */
.ftile-in {
  position: absolute; inset: 0; z-index: 1;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: clamp(14px, 1.6vw, 22px);
  background: linear-gradient(180deg, rgba(20,11,5,0) 42%, rgba(20,11,5,.62) 100%);
  transition: background .6s var(--ease);
}
.ftile:hover .ftile-in { background: linear-gradient(180deg, rgba(20,11,5,.12) 20%, rgba(20,11,5,.76) 100%) }
.ftile-kind {
  font-family: var(--sans); font-size: 8.5px; font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase; color: rgba(255,255,255,.66);
  margin-bottom: 8px;
}
.ftile-t {
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: clamp(16px, 1.5vw, 21px); line-height: 1.22; color: #fff;
  text-shadow: 0 1px 12px rgba(20,11,5,.5);
}
/* corner glyph marks what a tile links to — an article, or Instagram */
.ftile-mark {
  position: absolute; top: 12px; right: 12px; z-index: 2;
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.4);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.ftile-mark svg { width: 13px; height: 13px; fill: none; stroke: #fff; stroke-width: 1.7;
                  stroke-linecap: round; stroke-linejoin: round }

/* the real Instagram grid: tight gutters, no captions, corner glyph only — as the app shows it */
.iggrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px }
.igtile { position: relative; display: block; aspect-ratio: 4 / 5; overflow: hidden; background: var(--sand) }
.igtile img { width: 100%; height: 100%; object-fit: cover; display: block }
.igtile::after {
  content: ''; position: absolute; inset: 0;
  background: rgba(20,11,5,.34); opacity: 0;
  transition: opacity .4s var(--ease);
}
.igtile:hover::after { opacity: 1 }
.igtile-ico {
  position: absolute; top: 10px; right: 10px; z-index: 2;
  width: 17px; height: 17px; color: #fff;
  filter: drop-shadow(0 1px 3px rgba(20,11,5,.55));
}
.igtile-ico svg { width: 100%; height: 100%; display: block; fill: none; stroke: currentColor;
                  stroke-width: 1.8; stroke-linejoin: round }
.igtile-open {
  position: absolute; inset: 0; z-index: 2; display: grid; place-items: center;
  opacity: 0; transition: opacity .4s var(--ease);
  font-family: var(--sans); font-size: 9.5px; font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase; color: #fff;
}
.igtile:hover .igtile-open { opacity: 1 }
/* Instagram shows reels 9:16, not square — mirror that so the two grids read as its two tabs */
.igtile--reel { aspect-ratio: 9 / 16 }
/* reels run as one horizontal rail: three in view, swipe/scroll right for the rest */
.iggrid--reels {
  display: flex; gap: 4px;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scroll-padding-left: 0;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 4px;
}
.iggrid--reels::-webkit-scrollbar { display: none }
/* arrows — a mouse has no swipe, so the rail needs visible controls on desktop */
.reelrail { position: relative }
.reelrail-btn {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 4;
  width: 44px; height: 44px; padding: 0; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: rgba(255,255,255,.5); border: 1px solid rgba(255,255,255,.75);
  backdrop-filter: blur(14px) saturate(160%); -webkit-backdrop-filter: blur(14px) saturate(160%);
  box-shadow: 0 10px 30px -12px rgba(35,21,15,.5);
  color: var(--ink);
  transition: opacity .4s var(--ease), background .4s var(--ease), transform .4s var(--ease);
}
.reelrail-btn svg { width: 19px; height: 19px; fill: none; stroke: currentColor;
                    stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round }
.reelrail-btn:hover { background: rgba(255,255,255,.78) }
.reelrail-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px }
.reelrail-prev { left: -14px }
.reelrail-next { right: -14px }
.reelrail-btn[disabled] { opacity: 0; pointer-events: none }
/* touch already swipes — keep the rail clean there */
@media (hover: none) { .reelrail-btn { display: none } }
.iggrid--reels > .igtile {
  flex: 0 0 calc((100% - 8px) / 3);      /* exactly three across, matching the 4px gaps */
  scroll-snap-align: start;
}
@media (max-width: 640px) {
  .iggrid--reels { gap: 2px }
  .iggrid--reels > .igtile { flex: 0 0 calc((100% - 4px) / 3) }
}
.ig-tab {
  margin: clamp(30px, 4vh, 46px) 0 14px;
  font-family: var(--sans); font-size: 10px; font-weight: 600;
  letter-spacing: .26em; text-transform: uppercase; color: var(--ink-48);
  display: flex; align-items: center; gap: 14px;
}
.ig-tab::after { content: ''; flex: 1; height: 1px; background: var(--hairline) }
.iggrid + .ig-tab { margin-top: clamp(34px, 4.6vh, 56px) }

@media (max-width: 640px) { .iggrid { gap: 2px } .igtile-ico { width: 13px; height: 13px; top: 6px; right: 6px } }

/* the @handle bar that heads the feed */
.ig-head {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 18px;
  padding-bottom: clamp(20px, 2.6vh, 30px); margin-bottom: clamp(18px, 2.4vh, 28px);
  border-bottom: 1px solid var(--hairline);
}
.ig-handle { display: flex; align-items: center; gap: 12px }
.ig-handle svg { width: 20px; height: 20px; fill: none; stroke: var(--ink-64); stroke-width: 1.5 }
.ig-handle b {
  font-family: var(--sans); font-size: 13px; font-weight: 600; letter-spacing: .04em; color: var(--ink);
}
.ig-follow {
  font-family: var(--sans); font-size: 10px; font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase; color: var(--gold-deep);
  display: inline-flex; align-items: center; gap: 9px;
  transition: gap .5s var(--ease);
}
.ig-follow:hover { gap: 15px }

@media (max-width: 640px) {
  .feed { gap: 5px }
  .ftile-t { font-size: 13px }
  .ftile-kind { font-size: 7.5px; margin-bottom: 5px }
  .ftile-in { padding: 10px }
  .ftile-mark { width: 21px; height: 21px; top: 8px; right: 8px }
  .ftile-mark svg { width: 10px; height: 10px }
}

.eindex { margin-block: var(--sec); border-top: 1px solid var(--hairline) }
.erow {
  display: grid;
  grid-template-columns: 82px minmax(0, 1.05fr) minmax(0, 1fr) 38px;
  gap: clamp(16px, 3vw, 48px);
  align-items: baseline;
  padding-block: clamp(28px, 3.4vw, 46px);
  border-bottom: 1px solid var(--hairline);
  transition: background .7s var(--ease), padding-inline .7s var(--ease);
}
/* variant carrying a thumbnail — adds imagery to the list without boxing it */
.eindex.with-thumbs .erow {
  grid-template-columns: 60px 92px minmax(0, 1fr) minmax(0, .95fr) 38px;
  align-items: center;
}
.erow-thumb {
  width: 92px; aspect-ratio: 3/4; border-radius: 10px; overflow: hidden;
  box-shadow: 0 10px 26px -14px rgba(35,21,15,.4);
}
.erow-thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.4s var(--ease) }
.erow:hover .erow-thumb img { transform: scale(1.07) }
.erow:hover { background: rgba(255,255,255,.34); padding-inline: 22px }
.erow-num {
  font-family: var(--sans); font-weight: 400;
  font-size: 12px; letter-spacing: .1em; color: var(--gold-deep);
}
.erow-name {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(28px, 3.4vw, 50px); line-height: 1.06; letter-spacing: -.02em;
  color: var(--ink);
  transition: color .6s var(--ease);
}
.erow:hover .erow-name { color: var(--gold-deep) }
.erow-desc {
  font-size: 14.5px; line-height: 1.85; color: var(--ink-48); max-width: 44ch;
  transition: color .6s var(--ease);
}
.erow:hover .erow-desc { color: var(--ink-64) }

/* =====================================================
   TREATMENT CHAPTERS — editorial menu, not rows.
   Each category is a chapter: arch image on one side,
   a staggered serif menu on the other, ghost numeral
   behind. Descriptions unfold on hover.
   ===================================================== */
.tchap {
  position: relative;
  display: grid; grid-template-columns: .88fr 1.12fr;
  gap: clamp(48px, 7vw, 120px);
  align-items: center;
  padding-block: clamp(56px, 9vh, 120px);
}
.tchap.rev .tchap-media { order: 2 }
.tchap-media figure {
  border-radius: 999px 999px var(--radius) var(--radius);
  overflow: hidden; aspect-ratio: 3 / 3.7;
  box-shadow: var(--shadow);
}
.tchap-media img,
.tchap-media video {
  display: block; width: 100%; height: 100%; object-fit: cover;
  transition: transform 2s var(--ease);
}
.tchap:hover .tchap-media img,
.tchap:hover .tchap-media video { transform: scale(1.045) }
.tchap-ghost {
  position: absolute; z-index: 0; top: 0;
  font-family: var(--serif); font-style: italic; font-weight: 300;
  font-size: clamp(130px, 16vw, 250px); line-height: 1;
  color: rgba(35,21,15,.05);
  pointer-events: none; user-select: none;
}
.tchap:not(.rev) .tchap-ghost { right: 0 }
.tchap.rev .tchap-ghost { left: 0 }
.tchap-body { position: relative; z-index: 1; min-width: 0 }
.tchap-label { display: flex; align-items: center; gap: 18px; margin-bottom: clamp(20px, 3vh, 34px) }
.tchap-label::after { content: ''; height: 1px; width: clamp(40px, 6vw, 90px); background: var(--gold); opacity: .5 }
.tchap-intro {
  font-family: var(--serif); font-style: italic; font-weight: 300;
  font-size: clamp(17px, 1.6vw, 21px); line-height: 1.6; color: var(--ink-64);
  max-width: 40ch;
  margin-bottom: clamp(28px, 4.5vh, 52px);
}
.tmenu { display: flex; flex-direction: column }
.tmenu a {
  position: relative; width: max-content; max-width: 100%;
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(30px, 3.3vw, 52px); line-height: 1.12; letter-spacing: -.022em;
  color: var(--ink); padding-block: clamp(6px, 1vh, 12px);
  transition: color .5s var(--ease);
}
.tmenu a:hover, .tmenu a:focus-visible { color: var(--gold-deep) }
.tmenu .no {
  font-family: var(--sans); font-style: normal; font-weight: 500;
  font-size: 10px; letter-spacing: .22em; color: var(--gold-deep);
  vertical-align: super; margin-right: 14px;
}
.tmenu .aro {
  display: inline-block; font-size: .5em; vertical-align: middle;
  margin-left: 14px; opacity: 0; transform: translateX(-8px);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.tmenu a:hover .aro, .tmenu a:focus-visible .aro { opacity: 1; transform: none }
.tmenu .desc {
  display: block;
  font-family: var(--sans); font-style: normal;
  font-size: 13.5px; line-height: 1.7; letter-spacing: 0; color: var(--ink-48);
  max-width: 44ch;
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height .6s var(--ease), opacity .5s var(--ease), margin-top .6s var(--ease);
}
.tmenu a:hover .desc, .tmenu a:focus-visible .desc { max-height: 100px; opacity: 1; margin-top: 7px }
/* staggered indents — a composed column, not a list */
.tmenu a:nth-child(2) { margin-left: clamp(26px, 4vw, 76px) }
.tmenu a:nth-child(3) { margin-left: clamp(10px, 1.8vw, 30px) }
.tmenu a:nth-child(4) { margin-left: clamp(44px, 6.4vw, 116px) }
@media (max-width: 1024px) {
  .tchap { grid-template-columns: 1fr; gap: clamp(32px, 5vh, 48px); padding-block: clamp(44px, 7vh, 72px) }
  .tchap.rev .tchap-media { order: 0 }
  .tchap-media { width: min(74vw, 400px); margin-inline: auto }
  .tchap-ghost { font-size: clamp(110px, 24vw, 160px) }
}
@media (max-width: 720px) {
  /* long serif names must wrap, never widen the page */
  .tmenu a { font-size: clamp(27px, 7.4vw, 34px); width: auto }
  .tmenu .desc { max-width: 100% }
}

/* =====================================================
   ARTICLE BODY — treatment detail + journal
   ===================================================== */
.prose { max-width: 660px; margin-inline: auto }
.prose > * + * { margin-top: 22px }
.prose h2 {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(26px, 3.1vw, 40px); line-height: 1.16; letter-spacing: -.02em;
  color: var(--ink);
  margin-top: clamp(56px, 7vh, 96px); margin-bottom: 4px;
}
.prose p { font-size: 16.5px; line-height: 1.95; color: var(--ink-64) }
.prose p strong, .prose li strong { color: var(--ink); font-weight: 500 }
.prose ul { list-style: none }

/* the dateline on /privacy/ — metadata, so it sits quieter than the body it follows */
.prv-updated {
  margin-top: 40px; padding-top: 20px; border-top: 1px solid var(--line, rgba(35,21,15,.12));
  font-family: var(--sans); font-size: 12px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-48);
}

.prose li {
  position: relative; padding-left: 26px;
  font-size: 16.5px; line-height: 1.9; color: var(--ink-64);
  margin-top: 14px;
}
.prose li::before {
  content: ''; position: absolute; left: 2px; top: 14px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--champagne);
}

/* key facts — a quiet spec row, hairlines instead of boxes */
.specs {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 3vw, 48px);
  margin-block: clamp(52px, 7vh, 84px);
  padding-block: 40px;
  border-block: 1px solid var(--hairline);
}
.spec-k { display: block; font-size: 9.5px; letter-spacing: .3em; text-transform: uppercase; color: var(--ink-48); margin-bottom: 12px }
.spec-v {
  display: block; font-family: var(--serif); font-style: italic; font-weight: 300;
  font-size: clamp(19px, 2vw, 26px); line-height: 1.25; color: var(--ink);
}

/* dense clinical reference — minimal disclosures, no boxes */
.detail { border-top: 1px solid var(--hairline) }
.detail:last-of-type { border-bottom: 1px solid var(--hairline) }
.detail summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding-block: 26px;
  font-family: var(--serif); font-style: italic; font-weight: 300;
  font-size: clamp(20px, 2.2vw, 27px); color: var(--ink);
  transition: color .5s var(--ease);
}
.detail summary::-webkit-details-marker { display: none }
.detail summary:hover { color: var(--gold-deep) }
.detail summary::after {
  content: ''; flex: 0 0 auto; width: 11px; height: 11px; margin-right: 4px;
  border-right: 1px solid var(--gold-deep); border-bottom: 1px solid var(--gold-deep);
  transform: rotate(45deg) translateY(-3px);
  transition: transform .6s var(--ease);
}
.detail[open] summary::after { transform: rotate(-135deg) translateY(-3px) }
.detail-body { padding-bottom: 34px; animation: soft-in .8s var(--ease) both }
.detail-body > * + * { margin-top: 16px }
.detail-body p, .detail-body li { font-size: 15.5px; line-height: 1.9; color: var(--ink-64) }
.detail-body ul { list-style: none }
.detail-body li { position: relative; padding-left: 24px; margin-top: 12px }
.detail-body li::before {
  content: ''; position: absolute; left: 2px; top: 13px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--champagne);
}
@keyframes soft-in { from { opacity: 0; transform: translateY(-6px) } to { opacity: 1; transform: none } }

/* products — quiet hairline list, not chips */
.plist { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 clamp(24px, 4vw, 56px) }
.plist span {
  padding-block: 15px; border-bottom: 1px solid var(--hairline);
  font-size: 14.5px; letter-spacing: .02em; color: var(--ink-64);
}

/* =====================================================
   NUMBERED STEPS — lit arch cards
   The row-of-hairlines version read as a table, not a design. Each step is now an
   arch — the clinic's own facade shape — lit from the crown the way the building is
   at night, with the numeral as a pale watermark rather than a label.
   ===================================================== */
.steps {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(12px, 1.5vw, 22px);
  margin-top: clamp(46px, 6vh, 78px);
}
.step {
  position: relative; overflow: hidden; text-align: center;
  padding: clamp(32px, 3.2vw, 44px) clamp(16px, 1.7vw, 26px) clamp(30px, 3vw, 40px);
  border: 1px solid rgba(198, 169, 119, .26);
  border-radius: 999px 999px var(--g-radius) var(--g-radius);
  background: linear-gradient(180deg, #FDFBF7 0%, #F5EEE2 100%);
}
/* The lift uses `translate`, not `transform`, because the scroll-reveal owns `transform`
   on this same element — sharing it would make one cancel the other. Both transitions are
   declared here in one shot: a bare `.step` rule would be overridden by [data-reveal]'s. */
.steps .step {
  transition: opacity 1.25s var(--ease), transform 1.25s var(--ease), filter 1.25s var(--ease),
              translate .7s var(--ease), box-shadow .7s var(--ease), border-color .7s var(--ease);
}
/* warm light spilling down from the crown of the arch */
.step::before {
  content: ''; position: absolute; inset: 0 0 auto; height: 62%; pointer-events: none;
  background: radial-gradient(118% 100% at 50% 0%, rgba(216, 194, 167, .38), transparent 72%);
}
.step > * { position: relative }
.steps .step:hover {
  translate: 0 -7px;
  border-color: rgba(198, 169, 119, .5);
  box-shadow: 0 44px 78px -48px rgba(35, 21, 15, .5);
}
.step-n {
  display: block; font-family: var(--sans); font-weight: 300;
  font-size: clamp(42px, 4.4vw, 62px); line-height: 1; letter-spacing: .05em;
  color: rgba(198, 169, 119, .34);
}
.step-rule {
  display: block; width: 1px; height: clamp(18px, 2.2vw, 28px); margin: 15px auto 17px;
  background: linear-gradient(180deg, rgba(198, 169, 119, .75), rgba(198, 169, 119, 0));
}
.step h3 {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(21px, 2vw, 28px); line-height: 1.1; letter-spacing: -.015em; color: var(--ink);
}
.step p { margin-top: 14px; font-size: 14.5px; line-height: 1.85; color: var(--ink-64) }

@media (max-width: 980px) {
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px }
}
@media (max-width: 620px) {
  .steps { grid-template-columns: 1fr; gap: 14px; max-width: 420px; margin-inline: auto }
  .step { padding-block: clamp(28px, 7vw, 36px) 30px }
  .step-n { font-size: 46px }
}

/* =====================================================
   GALLERY — reviews
   ===================================================== */
.gfilters {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(14px, 2.2vw, 34px);
  margin-bottom: clamp(44px, 6vh, 76px);
}
.gfilter {
  background: none; border: 0; cursor: pointer; padding: 6px 0;
  position: relative;
  font-family: var(--sans); font-size: 10px; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase; color: var(--ink-48);
  transition: color .5s var(--ease);
}
.gfilter::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--gold-deep); transform: scaleX(0); transform-origin: right;
  transition: transform .6s var(--ease);
}
.gfilter:hover { color: var(--ink) }
.gfilter.on { color: var(--ink) }
.gfilter.on::after, .gfilter:hover::after { transform: scaleX(1); transform-origin: left }

.ggrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(14px, 2.2vw, 34px) }
.gitem {
  border-radius: var(--radius); overflow: hidden;
  box-shadow: 0 20px 50px -28px rgba(35,21,15,.28);
  transition: opacity .8s var(--ease), transform .9s var(--ease);
}
.gitem img { transition: transform 1.5s var(--ease) }
.gitem:hover img { transform: scale(1.03) }
.gitem[hidden] { display: none }
.gnote {
  max-width: 62ch; margin: clamp(48px, 7vh, 84px) auto 0; text-align: center;
  font-size: 12.5px; line-height: 1.95; color: var(--ink-48);
}
/* the how-to-use + results-vary line, sitting directly above the photographs */
.ba-hint {
  max-width: 58ch; margin: clamp(18px, 2.4vh, 28px) 0 clamp(26px, 3.4vh, 40px);
  font-size: 12.5px; line-height: 1.9; color: var(--ink-48);
}

/* =====================================================
   CONTACT — hairline rows, large serif values
   ===================================================== */
.crows { margin-block: var(--sec) 0; border-top: 1px solid var(--hairline) }
.crow {
  display: grid; grid-template-columns: minmax(0, .5fr) minmax(0, 1.5fr) 38px;
  gap: clamp(16px, 3vw, 48px);
  align-items: baseline;
  padding-block: clamp(26px, 3vw, 40px);
  border-bottom: 1px solid var(--hairline);
  transition: background .7s var(--ease), padding-inline .7s var(--ease);
}
a.crow:hover { background: rgba(255,255,255,.34); padding-inline: 22px }
.crow-k { font-size: 10px; letter-spacing: .3em; text-transform: uppercase; color: var(--ink-48) }
.crow-v {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(22px, 2.5vw, 34px); line-height: 1.24; letter-spacing: -.018em; color: var(--ink);
  transition: color .6s var(--ease);
}
a.crow:hover .crow-v { color: var(--gold-deep) }
.crow-sub { display: block; margin-top: 8px; font-size: 13.5px; line-height: 1.7; color: var(--ink-48); font-family: var(--sans); font-style: normal }
.crow-arrow { justify-self: end; font-size: 16px; color: var(--ink-32); transition: transform .7s var(--ease), color .7s var(--ease) }
a.crow:hover .crow-arrow { transform: translateX(9px); color: var(--gold-deep) }

/* =====================================================
   CTA BAND — full-bleed warm dark, closes every page
   ===================================================== */
.cta {
  margin-top: var(--sec);
  background: var(--chocolate);
  padding: clamp(88px, 15vh, 180px) var(--gut);
  text-align: center;
  position: relative; overflow: hidden;
}
.cta::before {
  content: ''; position: absolute; top: -40%; left: 50%; transform: translateX(-50%);
  width: min(900px, 120vw); aspect-ratio: 1;
  background: radial-gradient(circle, rgba(198,169,119,.13), transparent 62%);
  pointer-events: none;
}
/* NOTE: never put a `ch` max-width on this wrapper — `ch` resolves against the
   wrapper's own 16px font-size, not the large display text inside it, which
   squeezed the headline into a narrow tower. Measure belongs on the text. */
.cta-in { position: relative; max-width: 900px; margin-inline: auto }
.cta .eyebrow { color: var(--gold); margin-bottom: 30px }
.cta p {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(28px, 4vw, 56px); line-height: 1.16; letter-spacing: -.022em;
  color: var(--ivory); margin-bottom: clamp(36px, 5vh, 56px);
}
.cta p em { color: var(--gold) }

/* =====================================================
   FOOTER — quiet, warm, hairline
   ===================================================== */
footer { background: var(--mocha); padding: clamp(64px, 9vh, 110px) var(--gut) 44px; color: rgba(216,194,167,.62) }
.f-grid {
  display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.3fr;
  gap: clamp(32px, 5vw, 72px);
  max-width: 1320px; margin-inline: auto;
  padding-bottom: clamp(44px, 6vh, 72px);
  border-bottom: 1px solid rgba(255,255,255,.07);
}
.f-logo img { height: 78px; width: auto; object-fit: contain; filter: brightness(1.22); margin-bottom: 22px }
.f-tagline { font-size: 13px; line-height: 1.9; color: rgba(216,194,167,.5); max-width: 30ch }
footer h5 { font-size: 9px; letter-spacing: .3em; text-transform: uppercase; color: var(--gold); margin-bottom: 22px; font-weight: 500 }
footer a, footer p { display: block; font-size: 14px; line-height: 2.05; color: rgba(216,194,167,.55) }
footer a { transition: color .5s var(--ease) }
footer a:hover { color: var(--gold-lt) }
.f-bottom {
  max-width: 1320px; margin: 0 auto; padding-top: 28px;
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px;
  font-size: 10.5px; letter-spacing: .05em; color: rgba(216,194,167,.32);
}

/* =====================================================
   NUMERALS — กฎเหล็ก #1: digits NEVER render in Cormorant
   (old-style figures มีหัว/หางย้อย — ห้ามเด็ดขาด, see CLAUDE.md)
   interior.js auto-wraps digit runs inside serif elements
   with <span class="num"> so this holds everywhere.

   .num has ONE job: keep digits out of the serif. It declares no weight, size or tracking, so
   a numeral inside Jost text is typographically identical to the words beside it.
   Measured 2026-09-21: 259 of 402 numerals sat in sans text and every single one rendered
   lighter and smaller than its own sentence — the entire footer on 21 pages, the doctors'
   licence lines, the credential lists. The cause was applying the serif compensation below
   unconditionally. It is now scoped.
   ===================================================== */
.num, .price, .phone, time, [data-num] {
  font-family: var(--sans) !important;
  font-feature-settings: 'lnum' 1, 'tnum' 0;
  /* font-style is INHERITED, not forced upright. Jost standing straight in the middle of an
     italic Cormorant line reads as a different font pasted in; letting it lean with the line
     keeps it part of the sentence. Data numerals below opt back out. */
  font-style: inherit;
}
/* Optical compensation — ONLY inside Cormorant. Jost at the serif's own weight and size reads
   heavier in colour and taller than the letters around it, so in a serif line the digits have
   to step back. In Jost text there is nothing to step back from, and doing it anyway is what
   produced the bug above. This list is interior.js's serifHosts plus the hosts that carry
   hardcoded .num spans (.tmenu a, .tocard-body h3, .rec-title). Add a host here whenever one
   is added there. .nmega-h is absent on purpose — it restyles .num completely on its own.

   Deliberately NOT here, though interior.js wraps them: .prose p, .detail-body p and
   .detail-body li all compute to Jost (measured across 23 pages — 207 elements, zero serif),
   and .prose h3 has no declaration anywhere. That mismatch is why the privacy page and the
   treatment detail lists still read thin after the first pass. The wrap list in interior.js
   stays broader on purpose: wrapping a digit that is already sans costs nothing, while a
   missed wrap on a serif host breaks กฎเหล็ก #1. The two lists answer different questions —
   "could this be Cormorant?" vs "is this measurably Cormorant?" — and must not be merged.
   .crow-v and .split-body h2 render on no current page but are declared var(--serif) italic
   in this file, so they stay. */
:is(.crow-v, .spec-v, .erow-name, .display, .lede, .rec-title, .tmenu a,
    .statement p, .split-body h2, .prose h2, .detail summary, .cta p,
    .step h3, .vband-cap p, .tocard-body h3,
    .phero h1, .phero-visual h1) :is(.num, [data-num]) {
  font-weight: 300;
  font-size: .9em;
  letter-spacing: .03em;
}
/* data, not display — a phone number, a price or a clock time stays upright whatever surrounds it */
.price, .phone, time, .crow-v .num, .spec-v .num, .num--data { font-style: normal }
/* numeric atoms that previously used the serif
   (.step-n is deliberately absent — the booking steps set their own watermark scale) */
.erow-num {
  font-family: var(--sans); font-style: normal; font-weight: 500;
  font-size: 10.5px; letter-spacing: .24em; color: var(--gold-deep);
}
.cred-v {
  font-family: var(--sans); font-style: normal; font-weight: 300;
  letter-spacing: .01em;
}
/* .cred-v .num needed a font-size:1em patch until the shrink was scoped to serif hosts. */

/* =====================================================
   PAGE HERO · VISUAL — full-bleed photo + glass badge
   (หน้าแรกเวอร์ชันย่อ สำหรับหน้า interior)
   ===================================================== */
.phero-visual {
  position: relative; overflow: hidden;
  min-height: clamp(540px, 88vh, 940px);
  display: flex; align-items: flex-end;
  padding-block: clamp(150px, 20vh, 240px) clamp(56px, 9vh, 110px);
  margin-bottom: calc(var(--sec) * .35);
}
.ph-bg { position: absolute; inset: 0; z-index: -1 }
.ph-bg :is(img, video) {
  width: 100%; height: 100%; object-fit: cover; display: block;
  animation: ph-drift 2.8s var(--ease) both;
}
@keyframes ph-drift { from { transform: scale(1.06) } to { transform: scale(1) } }

/* A slow, continuous breath on the Journal banner: in over 26s, out over 26s, forever.
   ph-drift still plays the entrance; ph-breathe is declared after it and delayed by the same
   2.8s, so it takes over the transform exactly when the entrance finishes. */
.ph-bg--breathe :is(img, video) {
  animation:
    ph-drift 2.8s var(--ease) both,
    ph-breathe 26s 2.8s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes ph-breathe { from { transform: scale(1) } to { transform: scale(1.12) } }
@media (prefers-reduced-motion: reduce) {
  .ph-bg--breathe :is(img, video) { animation: ph-drift 2.8s var(--ease) both }
}
.ph-bg::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top,
    rgba(20,11,5,.64), rgba(20,11,5,.16) 48%,
    rgba(20,11,5,.20) 76%, rgba(20,11,5,.46) 100%);
}
/* The standard scrim is tuned for the dark exterior heroes. The reception interior is bright
   exactly where the lede sits, so that page opts into a deeper one rather than changing the
   gradient for every hero on the site. */
.phero-visual.ph-scrim-deep .ph-bg::after {
  background: linear-gradient(to top,
    rgba(20, 11, 5, .74), rgba(20, 11, 5, .40) 44%,
    rgba(20, 11, 5, .28) 72%, rgba(20, 11, 5, .48) 100%);
}
.phero-visual .ph-in { position: relative; width: 100% }
.ph-badge {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 12px 24px; border-radius: 100px;
  background: rgba(252,250,245,.13);
  border: 1px solid rgba(252,250,245,.26);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  backdrop-filter: blur(18px) saturate(150%);
  font-size: 10px; font-weight: 500; letter-spacing: .38em; text-transform: uppercase;
  color: rgba(252,250,245,.92);
  margin-bottom: clamp(24px, 3.4vh, 40px);
}
.ph-badge::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--gold-lt) }
.phero-visual h1 {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(46px, 8vw, 118px); line-height: .98; letter-spacing: -.028em;
  color: var(--pearl); max-width: 23ch; text-wrap: balance;
  text-shadow: 0 2px 44px rgba(20,11,5,.35);
}
.phero-visual h1 em { color: var(--gold-lt) }
/* A heading written as two deliberate lines, with no space around the <em>. */
.phero-visual.ph-stack h1 em { display: block }
/* The subject of this clip sits well right of centre, so a centred cover-crop lands on the
   empty middle of the room on any viewport narrower than the 16:9 source. Only the horizontal
   axis moves; where there is no horizontal overflow this has no effect at all. */
.ph-focus-right .ph-bg :is(img, video) { object-position: 82% 50% }
/* Nudge the framing 10px left. Measured with a striped probe image: calc(50% - Npx) moves the
   picture left and calc(50% + Npx) moves it right, for object-position and background-position
   alike. This rule had the sign inverted and was moving the clip right. */
.ph-nudge-l .ph-bg :is(img, video) { object-position: calc(50% - 10px) 50% }
.phero-visual .lede {
  margin-top: clamp(24px, 3.6vh, 44px); max-width: 46ch;
  color: rgba(252,250,245,.88);
}

/* Over a dark photo hero the pill glows light-on-dark, exactly like the
   reference: pale links, and the Book button flips to white-on-mocha. */
/* The white mark over a photograph. With the plate gone this is the only thing between the
   letters and a lit wall or a bright sky, so it carries its own shadow — index.html does the
   same on the same path. This rule is deliberately OUTSIDE the @supports block below: a
   browser with no mask support never gets the frosted layer and falls back to exactly this. */
body.has-visual nav:not(.scrolled) .nav-logo img {
  filter: brightness(0) invert(1) sepia(.14) brightness(.98) drop-shadow(0 1px 7px rgba(20,11,5,.5));
}

/* ── FROSTED LOGO — photo heroes only ───────────────────────────────────────────────────────
   Ported from index.html so every hero banner reads the same. The ASTELL letters become the
   glass: the mark is a mask over a layer that blurs and lifts whatever is behind it, so the
   photograph shows through the letterforms instead of a flat white fill.

   Why a masked pseudo-element and not the <img>: backdrop-filter samples what is behind the
   element's box, and the image's own pixels paint on top of it, so the blur would never show.

   Scope is body.has-visual nav:not(.scrolled) — a photograph behind the nav. Every other state
   keeps the solid mark, because frosted glass needs something to refract: on the cream split
   heroes of the treatment pages, and on the flat dark sections nav.on-dark covers, it would be
   invisible. The whole thing sits inside @supports, so a browser without mask support keeps the
   solid logo rather than an empty rectangle. */
@supports ((-webkit-mask-image: url("/favicon.ico")) or (mask-image: url("/favicon.ico"))) {
  body.has-visual nav:not(.scrolled) .nav-logo img { display: none }
  body.has-visual nav:not(.scrolled) .nav-logo::after {
    content: '';
    width: var(--logo-box); height: var(--logo-box);
    clip-path: inset(37.6% 12.2%);
    margin-block: calc(var(--logo-box) * -0.376);
    margin-inline: calc(var(--logo-box) * -0.122);
    -webkit-mask: url("/Astell Clinic_Logo with Description-02.png") center / contain no-repeat;
    mask: url("/Astell Clinic_Logo with Description-02.png") center / contain no-repeat;
    /* The milky body of the glass — without it the letters are only a blur and vanish into the
       photograph. 66% is where index.html settled after compositing against both hero plates;
       re-measured here against these heroes. */
    background: rgba(255,255,255,.66);
    -webkit-backdrop-filter: blur(6px) brightness(2.5) saturate(1.2);
    backdrop-filter: blur(6px) brightness(2.5) saturate(1.2);
    /* NO filter here. An element with a filter becomes its own backdrop root, which leaves
       backdrop-filter nothing to sample — the blur silently becomes a no-op and the letters
       render as flat white. Any shadow has to go on a separate layer. */
  }
}
body.has-visual nav:not(.scrolled) .nav-links a { color: rgba(252,250,245,.82) }
body.has-visual nav:not(.scrolled) .nav-links a:hover {
  color: var(--pearl); background: rgba(255,255,255,.14);
}
body.has-visual nav:not(.scrolled) .nav-links a[aria-current="page"] {
  color: var(--pearl); background: rgba(255,255,255,.18);
}
body.has-visual nav:not(.scrolled) .nav-book {
  background: var(--pearl); color: var(--mocha) !important;
}
body.has-visual nav:not(.scrolled) .nav-book:hover {
  background: var(--gold-lt); color: var(--mocha) !important;
}
body.has-visual .burger span { background: var(--pearl) }
body.has-visual nav.scrolled .burger span { background: var(--ink) }

/* ── NAV OVER A DARK SECTION ───────────────────────────────────────────────────────────────
   Same problem as the homepage: the interior pages end on a dark `.cta` band and a dark footer,
   and the nav keeps its ink treatment straight over them (ink on rgb(42,29,22) is 1.08:1).
   `.on-dark` is set from the background actually painted behind the nav — see interior.js —
   and restores the light treatment the photo heroes already use. */
nav.on-dark .nav-logo img { filter: brightness(0) invert(1) sepia(.14) brightness(.98) drop-shadow(0 1px 6px rgba(20,11,5,.45)) }
nav.on-dark .nav-links a { color: rgba(252,250,245,.82) }
nav.on-dark .nav-links a:hover { color: var(--pearl); background: rgba(255,255,255,.14) }
nav.on-dark .nav-links a[aria-current="page"] { color: var(--pearl); background: rgba(255,255,255,.18) }
nav.on-dark .nav-ind { background: rgba(255,255,255,.18) }
nav.on-dark .nav-book { background: var(--pearl); color: var(--mocha) !important }
nav.on-dark .nav-book:hover { background: var(--gold-lt); color: var(--mocha) !important }
nav.on-dark .lang-pill { background: rgba(255,255,255,.06) }
nav.on-dark .lang-globe { stroke: rgba(252,250,245,.75) }
nav.on-dark .lang-btn { color: rgba(252,250,245,.62) }
nav.on-dark .lang-btn:hover { color: var(--ivory); background: rgba(255,255,255,.14) }
nav.on-dark .lang-btn.active { color: var(--mocha); background: var(--pearl) }
/* doubled class so this outranks `body.has-visual nav.scrolled .burger span` */
nav.on-dark.on-dark .burger span { background: var(--pearl) }

@media (max-width: 720px) {
  .phero-visual { min-height: clamp(480px, 76vh, 720px) }
}

/* =====================================================
   PAGE HERO · SPLIT — treatment detail pages.
   Text on cream, image inside the Astell arch (the same
   arch as the building facade). Outline pill badge is the
   cream-surface sibling of the glass .ph-badge.
   ===================================================== */
.phero-split {
  display: grid; grid-template-columns: 1.08fr .92fr;
  gap: clamp(40px, 6vw, 96px);
  align-items: center;
  padding-top: clamp(130px, 16vh, 200px);
  padding-bottom: clamp(36px, 5vh, 64px);
  min-height: calc(88vh - 10px);
}
.phero-split > * { min-width: 0 }
.pill-badge {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 11px 22px; border-radius: 100px;
  border: 1px solid rgba(153,121,81,.32);
  font-size: 10px; font-weight: 500; letter-spacing: .38em; text-transform: uppercase;
  color: var(--gold-deep);
  margin-bottom: clamp(22px, 3vh, 36px);
}
.pill-badge::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--gold) }
.phero-split h1 {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(44px, 6.4vw, 100px); line-height: .98; letter-spacing: -.028em;
  color: var(--ink); max-width: 17ch; text-wrap: balance;
}
.phero-split h1 em { color: var(--gold-deep) }
.phero-split .lede { margin-top: clamp(22px, 3.4vh, 40px); max-width: 44ch }
.phero-split .tlink { margin-top: clamp(26px, 4vh, 44px) }
.ps-arch {
  position: relative;
  width: min(100%, 460px); justify-self: end;
  aspect-ratio: 3 / 3.85;
  border-radius: 999px 999px var(--radius) var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
}
.ps-arch img { width: 100%; height: 100%; object-fit: cover }
.ps-arch::after {
  content: ''; position: absolute; inset: 12px;
  border: 1px solid rgba(252,250,245,.42);
  border-radius: 999px 999px calc(var(--radius) - 8px) calc(var(--radius) - 8px);
  pointer-events: none;
  opacity: 0; transition: opacity .9s var(--ease) .55s;
}
.ps-arch.in::after { opacity: 1 }
@media (max-width: 1024px) {
  .phero-split { grid-template-columns: 1fr; min-height: 0; gap: clamp(36px, 6vh, 56px) }
  .phero-split h1 { max-width: none }
  .phero-split .lede { max-width: none }
  .ps-arch { justify-self: center; width: min(78vw, 420px) }
}

/* =====================================================
   MOTION — slow, soft, additive
   ===================================================== */
@media (prefers-reduced-motion: no-preference) {
  /* html.js, not bare [data-reveal]: the content must paint by default and JS opts into
     animating it, never the other way round. Without the guard a single failed request for
     interior.js left the whole page blank with no error anyone could see. */
  html.js [data-reveal] {
    opacity: 0;
    transform: translateY(26px);
    filter: blur(7px);
    transition: opacity 1.25s var(--ease), transform 1.25s var(--ease), filter 1.25s var(--ease);
  }
  html.js [data-reveal].in { opacity: 1; transform: none; filter: none }

  /* Mask reveal for media.
     The clip lives on the CHILD, never on the observed element itself:
     an element clipped to zero height reports intersectionRatio 0, so it
     would never receive .in — and would stay invisible permanently. */
  [data-reveal="mask"] { opacity: 1; filter: none; transform: none }
  [data-reveal="mask"] > *:not(.bleed-cap):not(.vband-cap) {
    clip-path: inset(0 0 100% 0);
    transition: clip-path 1.5s var(--ease);
  }
  [data-reveal="mask"].in > *:not(.bleed-cap):not(.vband-cap) { clip-path: inset(0 0 0 0) }
  /* captions fade in just behind the mask */
  [data-reveal="mask"] .bleed-cap, [data-reveal="mask"] .vband-cap {
    opacity: 0; transition: opacity .9s var(--ease) .5s;
  }
  [data-reveal="mask"].in .bleed-cap, [data-reveal="mask"].in .vband-cap { opacity: 1 }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto }
  [data-reveal] { opacity: 1 !important; transform: none !important; filter: none !important; clip-path: none !important }
}

/* =====================================================
   RESPONSIVE
   ===================================================== */
@media (max-width: 1024px) {
  .split, .split.rev { grid-template-columns: 1fr; gap: clamp(28px, 5vw, 48px) }
  .split.rev .split-media { order: 0 }
  .split-media img { aspect-ratio: 3/2 }
  .ggrid { grid-template-columns: repeat(2, 1fr) }
  .f-grid { grid-template-columns: 1fr 1fr }
  .erow { grid-template-columns: 54px minmax(0, 1fr) 30px }
  .eindex.with-thumbs .erow { grid-template-columns: 44px 72px minmax(0, 1fr) 30px }
  .erow-thumb { width: 72px }
  .erow-desc { display: none }
  .creds { grid-template-columns: repeat(2, 1fr) }
  .cred:nth-child(2n) { border-right: 0 }
  .cred:nth-child(-n+2) { border-bottom: 1px solid var(--hairline) }
}
/* 1060px, not 720px: the desktop link row needs ~1000px, so between 721 and ~1000 it
   overflowed and pushed the language pill off-screen — at 768px (iPad portrait) the pill
   sat at x=918 on a 768px screen, so 中文 was unreachable on all 21 interior pages.
   index.html was fixed to 1060px earlier; interior.css has its own copy and was missed. */
@media (max-width: 1060px) {
  /* flex, not grid: the fixed-position overlay must not join track sizing */
  nav { inset: 12px 0 auto 0; display: flex; align-items: center; justify-content: space-between; padding-inline: var(--gut) }
  .nav-logo { padding: 5px 10px; border-radius: 14px; --logo-box: 108px }
  .burger { display: flex; z-index: 101; justify-self: end }
  /* the pill becomes a full-screen frosted panel; size it explicitly — `inset: 0` alone
     leaves it shrink-to-fit, which rendered as a narrow strip mid-screen */
  .nav-links {
    position: fixed; top: 0; left: 0; z-index: 100;
    width: 100vw; height: 100vh; height: 100dvh;
    flex-direction: column; align-items: stretch; justify-content: flex-start;
    gap: 0; border-radius: 0;
    padding: 96px var(--gut-m) calc(28px + env(safe-area-inset-bottom)) var(--gut-m);
    background: rgba(250,247,241,.97);
    -webkit-backdrop-filter: blur(30px) saturate(180%); backdrop-filter: blur(30px) saturate(180%);
    box-shadow: none;
    opacity: 0; pointer-events: none;
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    transition: opacity .5s var(--ease);
  }
  /* the panel starts hidden and nothing ever revealed it — interior.js toggles `.open`,
     but no rule matched it, so the burger did nothing on every page except the homepage */
  .nav-links.open { opacity: 1; pointer-events: auto }
  .nav-links::before { display: none }
  .nav-links a,
  body.has-visual nav:not(.scrolled) .nav-links a {
    display: flex; align-items: center; justify-content: space-between;
    min-height: 56px; padding: 4px 2px;      /* a real tap target */
    border-bottom: 1px solid rgba(35,21,15,.10);
    font-family: var(--serif); font-style: italic; font-weight: 400;
    font-size: 27px; letter-spacing: -.01em; text-transform: none;
    color: var(--ink); background: none;
  }
  .nav-links a[aria-current="page"],
  body.has-visual nav:not(.scrolled) .nav-links a[aria-current="page"] {
    color: var(--gold-deep); background: none;
  }
  .nav-links a:active { background: rgba(198,169,119,.12) }
  /* the desktop pill leaves a 100px radius on every row — strip it so the list reads as rows */
  nav .nav-links a,
  body.has-visual nav:not(.scrolled) .nav-links a { border-radius: 0 }
  nav .nav-links a.nav-book,
  nav.scrolled .nav-links a.nav-book,
  body.has-visual nav:not(.scrolled) .nav-links a.nav-book {
    justify-content: center; margin: 26px 0 0; border-bottom: 0;
    min-height: 54px; border-radius: 100px;
    background: var(--mocha) !important; color: var(--ivory) !important;
    font-family: var(--sans); font-style: normal; font-size: 11px;
    font-weight: 500; letter-spacing: .2em; text-transform: uppercase;
  }

  .specs { grid-template-columns: 1fr; gap: 26px; padding-block: 30px }
  .plist { grid-template-columns: 1fr }
  .ggrid { gap: 10px }
  .trio { grid-template-columns: 1fr 1fr; gap: 10px }
  .trio .t-tall, .trio .t-mid, .trio .t-short { aspect-ratio: 3/4; align-self: auto }
  .trio figure:nth-child(3) { grid-column: 1 / -1; aspect-ratio: 16/10 }
  .duo { grid-template-columns: 1fr; gap: 10px }
  .vband { height: clamp(300px, 56vh, 460px) }
  .eindex.with-thumbs .erow { grid-template-columns: 36px 60px minmax(0, 1fr) 24px }
  .erow-thumb { width: 60px }
  .crow { grid-template-columns: 1fr 24px; row-gap: 8px }
  .crow-k { grid-column: 1 / -1 }
  .f-grid { grid-template-columns: 1fr; gap: 36px }
  .bleed { margin-block: clamp(64px, 10vh, 96px) }
  .phero h1 { max-width: none }
}

/* =====================================================
   REVIEWS PAGE — dedicated composition
   Split hero · floating stat bar · filter chips · card
   gallery · testimonial carousel · image CTA · light footer
   ===================================================== */

/* ── split hero, image bleeds to the right edge ── */
/* ── floating stat bar ── */
/* Liquid glass: the bar floats half over the hero photo, half over cream,
   so the panel is translucent and the backdrop is blurred through it. */
.statbar {
  position: relative; z-index: 3;
  margin: clamp(-58px, -6.5vh, -42px) auto 0;
  max-width: 1180px;
  display: grid; grid-template-columns: repeat(4, 1fr);
  background: linear-gradient(180deg, rgba(255,255,255,.58), rgba(255,255,255,.38));
  -webkit-backdrop-filter: blur(30px) saturate(185%) brightness(107%);
  backdrop-filter: blur(30px) saturate(185%) brightness(107%);
  border: 1px solid rgba(255,255,255,.46);
  border-top-color: rgba(255,255,255,.72);
  border-radius: var(--g-radius);
  box-shadow:
    0 22px 60px -30px rgba(35,21,15,.30),
    inset 0 1.5px 0 rgba(255,255,255,.7),
    inset 0 -1px 0 rgba(35,21,15,.04);
  overflow: hidden;
}
/* no @supports fallback needed for colour, but keep it legible if blur is off */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .statbar { background: rgba(252,250,246,.94) }
}
.stat {
  text-align: center;
  padding: clamp(18px, 2.1vw, 26px) 14px;
  border-right: 1px solid rgba(35,21,15,.09);
}
.stat:last-child { border-right: 0 }
.stat svg { width: 21px; height: 21px; margin: 0 auto 9px; display: block; stroke: var(--ink-64); fill: none; stroke-width: 1.2 }
.stat-v {
  display: block; font-family: var(--sans); font-weight: 300; font-size: clamp(20px, 2.1vw, 27px);
  line-height: 1; color: var(--ink); letter-spacing: .01em;
  font-feature-settings: 'lnum' 1;
}
.stat-k { display: block; margin-top: 6px; font-size: 10.5px; color: var(--ink-48); letter-spacing: .03em }

/* ── filter chips ── */
.chips { display: flex; flex-wrap: wrap; gap: 9px; margin-block: clamp(52px, 7vh, 84px) clamp(30px, 4vh, 46px) }
.chip {
  background: none; cursor: pointer; padding: 10px 20px; border-radius: 100px;
  border: 1px solid var(--hairline);
  font-family: var(--sans); font-size: 10px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-64);
  transition: background .5s var(--ease), color .5s var(--ease), border-color .5s var(--ease);
}
.chip:hover { border-color: var(--gold); color: var(--gold-deep) }
.chip.on { background: var(--gold-deep); border-color: var(--gold-deep); color: #FCFAF6 }

/* ── gallery cards ── */
.rgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(14px, 1.8vw, 24px) }
.rcard {
  display: block; background: #FCFAF6; border-radius: var(--radius); overflow: hidden;
  box-shadow: 0 18px 44px -30px rgba(35,21,15,.34);
  transition: transform .6s var(--ease), box-shadow .6s var(--ease);
}
.rcard:hover { transform: translateY(-4px); box-shadow: 0 30px 64px -30px rgba(35,21,15,.42) }
.rcard[hidden] { display: none }
.rcard-img { position: relative; overflow: hidden; background: var(--sand) }
.rcard-img img { width: 100%; height: auto; display: block; transition: transform 1.5s var(--ease) }
.rcard:hover .rcard-img img { transform: scale(1.035) }
.rcard-body { padding: 20px 22px 22px }
.rcard-t {
  font-family: var(--serif); font-weight: 400; font-size: 17.5px; line-height: 1.35;
  color: var(--ink); letter-spacing: -.005em;
}
.rcard-go {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 12px;
  font-size: 11px; color: var(--ink-48); letter-spacing: .04em;
  transition: gap .5s var(--ease), color .5s var(--ease);
}
.rcard:hover .rcard-go { gap: 15px; color: var(--gold-deep) }
.morewrap { display: flex; justify-content: center; margin-top: clamp(38px, 5vh, 60px) }

/* ── before / after: drag to compare ──
   The AFTER shot is the base layer; BEFORE sits on top, clipped from the right edge of the
   divider, so dragging left→right wipes the before away. Everything keys off one custom
   property (--p) that JS writes, which keeps the divider, the clip and the labels in sync. */
.rcard--ba:hover { transform: none }              /* no lift — the card is a drag target */
.rcard--wide { grid-column: span 2 }
.ba {
  --p: 50%;
  position: relative; overflow: hidden; background: var(--sand);
  aspect-ratio: var(--ar, 4/5);
  cursor: ew-resize;
  touch-action: pan-y;                            /* vertical page scroll still works on touch */
}
.ba img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
  user-select: none; -webkit-user-drag: none; pointer-events: none;
}
.ba-before { clip-path: inset(0 calc(100% - var(--p)) 0 0) }
.ba-line {
  position: absolute; top: 0; bottom: 0; left: var(--p); width: 1px; z-index: 2;
  transform: translateX(-.5px); pointer-events: none;
  background: linear-gradient(180deg,
    rgba(255,255,255,.18), rgba(255,255,255,.9) 14%, rgba(255,255,255,.9) 86%, rgba(255,255,255,.18));
  box-shadow: 0 0 18px rgba(20,11,5,.28);
}
.ba:not(.dragging) .ba-before { transition: clip-path .4s var(--ease) }
.ba:not(.dragging) .ba-line   { transition: left .4s var(--ease) }
.ba-grip {
  position: absolute; top: 50%; left: var(--p); z-index: 3;
  transform: translate(-50%, -50%);
  width: 44px; height: 44px; padding: 0; border-radius: 50%;
  display: grid; place-items: center; cursor: ew-resize;
  background: rgba(255,255,255,.22);
  backdrop-filter: blur(10px) saturate(150%); -webkit-backdrop-filter: blur(10px) saturate(150%);
  border: 1px solid rgba(255,255,255,.72);
  /* the outer dark hairline is what keeps the grip visible on pale skin, where a
     white-on-white ring would disappear entirely */
  box-shadow: 0 0 0 1px rgba(20,11,5,.16), 0 12px 30px -14px rgba(20,11,5,.6);
  transition: transform .5s var(--ease), background .5s var(--ease), border-color .5s var(--ease);
}
.ba:not(.dragging) .ba-grip { transition: left .4s var(--ease), transform .5s var(--ease), background .5s var(--ease) }
.ba-grip svg { width: 19px; height: 19px; fill: none; stroke: #fff; stroke-width: 1.7;
               stroke-linecap: round; stroke-linejoin: round;
               filter: drop-shadow(0 1px 2px rgba(20,11,5,.5)) }
.ba:hover .ba-grip { background: rgba(255,255,255,.26); border-color: rgba(255,255,255,.75) }
.ba.dragging .ba-grip { transform: translate(-50%, -50%) scale(.94) }
.ba-grip:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px }
.ba-lbl {
  position: absolute; bottom: 14px; z-index: 2; pointer-events: none;
  font-family: var(--serif); font-style: italic; font-size: 15px; letter-spacing: .015em;
  color: #fff; text-shadow: 0 1px 16px rgba(20,11,5,.6);
  transition: opacity .35s var(--ease);
}
.ba-lbl-pre  { left: 16px }
.ba-lbl-post { right: 16px }

@media (prefers-reduced-motion: reduce) {
  .ba-before, .ba-line, .ba-grip { transition: none !important }
}

/* ── testimonials ── */
.testi {
  position: relative; margin-top: var(--sec);
  background: linear-gradient(180deg, rgba(255,255,255,.5), rgba(255,255,255,.18));
  border-radius: var(--radius); padding: clamp(44px, 6vw, 76px) clamp(24px, 4vw, 60px);
}
.testi-head { display: grid; grid-template-columns: 1.25fr 1fr; gap: clamp(24px, 4vw, 70px); align-items: end; margin-bottom: clamp(34px, 4.6vh, 54px) }
.testi-head .eyebrow { margin-bottom: 18px }
.testi-head h2 {
  font-family: var(--serif); font-weight: 300; font-size: clamp(28px, 3.6vw, 50px);
  line-height: 1.12; letter-spacing: -.025em; color: var(--ink); max-width: 21ch; text-wrap: balance;
}
.testi-head p { font-size: 14.5px; line-height: 1.8; color: var(--ink-64); max-width: 42ch }
.testi-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(14px, 1.8vw, 22px) }
.tstm {
  position: relative; overflow: hidden;
  background: #FCFAF6; border-radius: 14px; padding: 26px 26px 22px;
  box-shadow: 0 14px 36px -28px rgba(35,21,15,.34);
}
.tstm-stars { color: var(--gold); font-size: 12px; letter-spacing: .22em; margin-bottom: 14px }
.tstm-mark { font-family: var(--serif); font-size: 30px; line-height: .6; color: var(--champagne); display: block; margin-bottom: 8px }
.tstm-q { font-size: 14px; line-height: 1.75; color: var(--ink-64); min-height: 5.6em }
.tstm-by { display: flex; align-items: center; gap: 11px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--hairline) }
.tstm-av {
  width: 34px; height: 34px; border-radius: 50%; flex: 0 0 auto;
  background: var(--champagne); color: var(--mocha);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: 15px; font-weight: 500;
}
.tstm-n { font-size: 12.5px; color: var(--ink); font-weight: 500; line-height: 1.35 }
.tstm-tr { font-size: 10.5px; color: var(--ink-48); letter-spacing: .04em }
.tstm-num {
  position: absolute; right: 18px; bottom: 10px;
  font-family: var(--sans); font-weight: 300; font-size: 34px; line-height: 1;
  color: rgba(35,21,15,.08); pointer-events: none; font-feature-settings: 'lnum' 1;
}

/* ── image CTA band ── */
/* Closing CTA — a single warm, dark panel. Deliberately image-free: a photo
   behind this text fought the wordmark inside it and forced a milky overlay
   that read as washed-out rather than quiet. Depth comes from a gold bloom
   and a hairline rule instead. */
.ctaimg {
  position: relative; overflow: hidden;
  margin-top: var(--sec);
  margin-bottom: clamp(64px, 9vh, 120px);
  border-radius: var(--g-radius);
  background:
    radial-gradient(120% 180% at 88% -40%, rgba(198,169,119,.30), transparent 58%),
    linear-gradient(104deg, #1E120C 0%, var(--chocolate) 46%, #33241A 100%);
  box-shadow: 0 34px 80px -44px rgba(20,11,5,.72);
}
/* faint top sheen — the same light logic as the glass components */
.ctaimg::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(180deg, rgba(255,255,255,.09), transparent 34%);
}
.ctaimg-in {
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.42fr) 1px minmax(0, .78fr) auto;
  gap: clamp(26px, 3.4vw, 56px);
  align-items: center;
  padding: clamp(40px, 5.2vw, 68px) clamp(30px, 4.4vw, 64px);
}
.ctaimg-rule {
  align-self: stretch; width: 1px;
  background: linear-gradient(180deg, transparent, rgba(198,169,119,.42) 22%, rgba(198,169,119,.42) 78%, transparent);
}
.ctaimg-in h2 {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(24px, 2.5vw, 36px); line-height: 1.16; letter-spacing: -.022em;
  color: var(--pearl); max-width: 26ch; text-wrap: balance;
}
.ctaimg-in h2 em { color: var(--gold-lt) }
.ctaimg-in p {
  font-size: 14px; line-height: 1.85; color: rgba(252,250,245,.66);
  max-width: 30ch;
}
.btn-gold {
  display: inline-block; white-space: nowrap;
  background: var(--gold); border: 1px solid var(--gold); color: var(--mocha);
  font-family: var(--sans); font-size: 10.5px; font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase;
  padding: 18px 36px; border-radius: 100px;
  box-shadow: 0 14px 34px -18px rgba(198,169,119,.7);
  transition: background .6s var(--ease), border-color .6s var(--ease), transform .6s var(--ease);
}
.btn-gold:hover {
  background: var(--pearl); border-color: var(--pearl); color: var(--mocha);
  transform: translateY(-2px);
}

/* =====================================================
   LIGHT FOOTER — used sitewide on interior pages
   ===================================================== */
footer.light { background: transparent; color: var(--ink-64); border-top: 1px solid var(--hairline); padding-top: clamp(64px, 9vh, 104px) }
footer.light .f-grid { grid-template-columns: 1.5fr 1fr 1fr 1.15fr 1.1fr; border-bottom-color: var(--hairline) }
footer.light .f-mark { display: block; margin-bottom: 20px }
footer.light .f-mark img {
  --logo-box: 210px;
  width: var(--logo-box); height: var(--logo-box);
  object-fit: contain; display: block;
  clip-path: inset(37.6% 12.2%);
  margin-block: calc(var(--logo-box) * -0.376);
  margin-inline: calc(var(--logo-box) * -0.122);
  /* asset is a light-on-dark mark — recoloured to warm ink for the cream footer */
  filter: brightness(.24) sepia(.44) saturate(2.2) hue-rotate(-10deg);
}
footer.light .f-tagline { color: var(--ink-48) }
footer.light h5 { color: var(--ink-48); font-weight: 500 }
footer.light a, footer.light p { color: var(--ink-64) }
footer.light a:hover { color: var(--gold-deep) }
footer.light .f-bottom { color: var(--ink-48) }
.f-social { display: flex; gap: 12px; margin-top: 22px }
.f-social a {
  width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--hairline);
  display: flex; align-items: center; justify-content: center;
  transition: border-color .5s var(--ease), background .5s var(--ease);
}
.f-social a:hover { border-color: var(--gold); background: rgba(198,169,119,.12) }
.f-social svg { width: 14px; height: 14px; fill: currentColor }
.f-bottom-links { display: flex; gap: 24px }

/* =====================================================
   REVIEWS RESPONSIVE
   ===================================================== */
@media (max-width: 1024px) {
  .statbar { margin-top: -34px; grid-template-columns: repeat(2, 1fr) }
  .stat:nth-child(2n) { border-right: 0 }
  .stat:nth-child(-n+2) { border-bottom: 1px solid rgba(35,21,15,.09) }
  .rgrid { grid-template-columns: repeat(2, 1fr) }
  .testi-head { grid-template-columns: 1fr; align-items: start }
  .testi-grid { grid-template-columns: 1fr }
  .ctaimg-in { grid-template-columns: 1fr; text-align: center; justify-items: center; gap: 22px }
  .ctaimg-in h2 { max-width: 22ch }
  .ctaimg-in p { max-width: 44ch }
  .ctaimg-rule { width: clamp(60px, 22vw, 120px); height: 1px; align-self: center;
    background: linear-gradient(90deg, transparent, rgba(198,169,119,.42), transparent) }
  footer.light .f-grid { grid-template-columns: 1fr 1fr }
}
@media (max-width: 680px) {
  .rgrid { grid-template-columns: 1fr }
  .rcard--wide { grid-column: span 1 }
  .ba-grip { width: 40px; height: 40px }
  .statbar { margin-inline: 0 }
  .chips { gap: 7px }
  .chip { padding: 9px 15px; font-size: 9.5px }
  footer.light .f-grid { grid-template-columns: 1fr }
  .f-bottom-links { gap: 16px }
}

/* =====================================================
   TREATMENTS · HERO CHIPS + OVERVIEW (section 2)
   Adapted from the approved liquid-glass reference:
   full-bleed imagery, big serif headline top-left, and
   glass cards with an icon, tag-chips and a serif title.
   Chapters I–IV below remain untouched.
   ===================================================== */

/* small glass chips under the hero lede */
.ph-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: clamp(20px, 3vh, 32px) }
.ph-chips span {
  padding: 9px 18px; border-radius: 100px;
  background: rgba(252,250,245,.10);
  border: 1px solid rgba(252,250,245,.22);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
  font-size: 10px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
  color: rgba(252,250,245,.88);
}

/* ── the overview section ── */
.tover {
  position: relative; overflow: hidden;
  padding: clamp(88px, 13vh, 170px) var(--gut) clamp(56px, 8vh, 96px);
  margin-bottom: calc(var(--sec) * .5);
}
.tover-bg { position: absolute; inset: 0; z-index: 0 }
.tover-bg img { width: 100%; height: 100%; object-fit: cover; object-position: center 62% }
.tover-bg::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to bottom,
    rgba(20,11,5,.52), rgba(20,11,5,.34) 34%, rgba(20,11,5,.58) 100%);
}
.tover-in { position: relative; z-index: 1; max-width: 1320px; margin-inline: auto }
.tover-label {
  font-size: 10px; font-weight: 500; letter-spacing: .38em; text-transform: uppercase;
  color: rgba(252,250,245,.75); margin-bottom: clamp(18px, 2.6vh, 28px); display: block;
}
.tover h1,
.tover h2 {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(40px, 6.4vw, 96px); line-height: .96; letter-spacing: -.028em;
  color: var(--pearl); max-width: 16ch; text-wrap: balance;
  text-shadow: 0 2px 40px rgba(20,11,5,.4);
}
.tover h1 em,
.tover h2 em { color: var(--gold-lt) }

/* the same block doubling as the page hero — clears the floating nav
   and fills the first screen */
.tover.is-hero {
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding-top: clamp(140px, 19vh, 220px);
  padding-bottom: clamp(72px, 10vh, 120px);
}
.tover-lede {
  margin-top: clamp(18px, 2.4vh, 26px);
  font-size: clamp(14px, 1.05vw, 16px); font-weight: 300; line-height: 1.75;
  color: rgba(252,250,245,.84); max-width: 46ch; text-wrap: pretty;
}
.tover-cap {
  position: absolute; left: var(--gut); bottom: clamp(18px, 3vh, 30px); z-index: 1;
  font-size: 10px; letter-spacing: .32em; text-transform: uppercase;
  color: rgba(252,250,245,.55);
}

/* card grid */
.tover-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: clamp(12px, 1.4vw, 20px);
  margin-top: clamp(44px, 7vh, 84px);
}

/* liquid-glass card — same masked-rim recipe as the nav pill */
.tocard {
  position: relative; border-radius: 20px;
  padding: 20px 20px 24px;
  min-height: clamp(280px, 36vh, 350px);
  display: flex; flex-direction: column;
  background: rgba(255,255,255,.05);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  backdrop-filter: blur(18px) saturate(150%);
  box-shadow: inset 0 1px 1px rgba(255,255,255,.14), 0 18px 50px -28px rgba(0,0,0,.55);
  transition: background .6s var(--ease), transform .6s var(--ease);
}
.tocard::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  padding: 1.2px;
  background: linear-gradient(180deg,
    rgba(255,255,255,.46) 0%, rgba(255,255,255,.15) 22%,
    rgba(255,255,255,0) 42%, rgba(255,255,255,0) 60%,
    rgba(255,255,255,.15) 82%, rgba(255,255,255,.46) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  pointer-events: none;
}
.tocard:hover { background: rgba(255,255,255,.075) }

.tocard-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px }
.tocard-ico {
  flex: 0 0 auto; width: 42px; height: 42px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.08);
  box-shadow: inset 0 1px 1px rgba(255,255,255,.16);
}
.tocard-ico svg { width: 21px; height: 21px; stroke: var(--gold-lt); fill: none; stroke-width: 1.4 }
.tocard-tags {
  display: flex; flex-wrap: wrap; gap: 5px;
  margin-top: auto; padding-top: 22px;
}
.tocard-tags a {
  padding: 6px 12px; border-radius: 100px;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.22);
  font-size: 10.5px; font-weight: 500; letter-spacing: .07em; text-transform: uppercase;
  color: var(--pearl); white-space: nowrap;
  transition: background .45s var(--ease), border-color .45s var(--ease), color .45s var(--ease);
}
.tocard-tags a:hover { background: var(--pearl); border-color: var(--pearl); color: var(--mocha) }

.tocard-body { padding-top: 22px }
.tocard-body h3 {
  font-family: var(--serif); font-weight: 300; font-style: italic;
  font-size: clamp(24px, 2vw, 30px); line-height: 1.04; letter-spacing: -.018em;
  color: var(--pearl);
}
.tocard-eyebrow {
  display: block; margin-bottom: 10px;
  font-family: var(--sans); font-style: normal; font-weight: 500;
  font-size: 9.5px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--gold-lt);
}
.tocard-body p {
  margin-top: 9px; font-size: 12.5px; font-weight: 300; line-height: 1.7;
  color: rgba(252,250,245,.82); max-width: 30ch;
}

@media (max-width: 1180px) {
  .tover-grid { grid-template-columns: repeat(2, 1fr) }
  .tocard { min-height: 260px }
}
@media (max-width: 620px) {
  .tover { padding-inline: var(--gut) }
  .tover-grid { grid-template-columns: 1fr; gap: 10px }
  .tocard { min-height: 0 }
  .tocard-body { padding-top: 18px }
  .ph-chips span { padding: 8px 14px; font-size: 9.5px }
}

/* =====================================================
   NAV MEGA MENU — hover/focus on Treatments reveals the
   four chapters and every treatment underneath them.
   Placed at the end of the file so it wins the specificity
   ties against the .has-visual nav-link colour rules above.
   Desktop/tablet only; the mobile overlay stays a plain list.
   ===================================================== */
.nav-drop { position: relative }
.nav-mega {
  position: absolute; top: 100%; left: 50%;
  padding-top: 14px;               /* hover bridge across the gap */
  width: min(880px, calc(100vw - 48px));
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translate(-50%, -6px);
  transition: opacity .4s var(--ease), transform .4s var(--ease), visibility .4s;
}
.nav-drop:hover .nav-mega,
.nav-drop:focus-within .nav-mega {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translate(-50%, 0);
}
.nmega-in {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: clamp(16px, 1.8vw, 28px);
  padding: 26px 28px 24px; border-radius: 22px;
  background: rgba(250,247,241,.94);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  backdrop-filter: blur(22px) saturate(160%);
  box-shadow: 0 34px 80px -34px rgba(35,21,15,.55), inset 0 1px 1px rgba(255,255,255,.7);
}
.nmega-h {
  display: block; margin-bottom: 12px; padding-bottom: 11px;
  border-bottom: 1px solid rgba(35,21,15,.12);
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: 17px; letter-spacing: -.01em; color: var(--mocha);
  white-space: nowrap;
}
.nmega-h .num {
  display: block; margin-bottom: 5px;
  font-family: var(--sans); font-style: normal; font-weight: 500;
  font-size: 8.5px; letter-spacing: .26em; text-transform: uppercase;
  color: var(--gold-deep);
}
nav .nav-links .nav-mega a.nmega-l,
body.has-visual nav:not(.scrolled) .nav-links .nav-mega a.nmega-l {
  display: block; padding: 7px 0; border-radius: 0;
  background: none; color: rgba(35,21,15,.7);
  font-size: 11.5px; font-weight: 400; letter-spacing: .01em; text-transform: none;
}
nav .nav-links .nav-mega a.nmega-l:hover,
body.has-visual nav:not(.scrolled) .nav-links .nav-mega a.nmega-l:hover {
  background: none; color: var(--gold-deep);
}

@media (max-width: 900px) { .nav-mega { display: none } }

/* ── TREATMENTS SUB-MENU ON TOUCH ──────────────────────────────────────────────────────────
   .nav-mega is a hover flyout, and below 900px it is display:none — which left all twelve
   treatment links unreachable on a phone. Tapping "Treatments" reached the index page, so the
   content was never lost, but every treatment was one extra navigation away.
   The fix is the standard disclosure pattern: the link still navigates, and a separate button
   beside it opens the list. interior.js injects that button; it is invisible on desktop, where
   hover already works. */
.nav-drop-toggle { display: none }

@media (max-width: 900px) {
  .nav-drop-toggle {
    /* The drawer is a flex column and .nav-drop is display:contents there, so this button
       cannot sit beside the Treatments link — it becomes its own full-width row. Rather than
       fight that, it reads as a disclosure row: chevron on the right, tucked up under the link
       it belongs to, keeping the full 44px height as the tap target. */
    display: flex; align-items: center; justify-content: flex-end;
    width: 100%; min-height: 44px; padding: 0 2px 0 0; margin: -10px 0 0;
    background: none; border: 0; cursor: pointer; color: inherit;
  }
  .nav-drop-toggle svg {
    width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
    transition: transform .35s var(--ease);
  }
  .nav-drop.open .nav-drop-toggle svg { transform: rotate(180deg) }

  /* opened, the flyout stops being a flyout and becomes part of the drawer's flow */
  .nav-drop.open .nav-mega {
    display: block; position: static; width: auto; padding-top: 6px;
    opacity: 1; visibility: visible; pointer-events: auto; transform: none;
  }
  .nav-drop.open .nmega-in {
    grid-template-columns: 1fr; gap: 14px; padding: 14px 16px 12px;
    border-radius: 16px; box-shadow: none;
  }
  .nav-drop.open .nmega-h { margin-bottom: 4px; padding-bottom: 8px }
  /* every treatment link gets a real touch target */
  nav .nav-links .nav-drop.open .nav-mega a.nmega-l {
    min-height: 44px; display: flex; align-items: center; padding: 0; font-size: 13.5px;
  }
}

/* Footer links measured 25–32px tall. Low risk because they sit at the end of the page, but
   they are still the clinic's phone number and address on a phone. */
@media (max-width: 900px) {
  footer a { min-height: 44px; display: flex; align-items: center }
  .f-bottom a { min-height: 44px; display: inline-flex; align-items: center }
}

@media (max-width: 1060px) { .nav-drop { display: contents } }
