/* ═══════════════════════════════════════════════════════════════════════
   Chitra's Lifeline Clinic — landing page
   Light throughout. Depth comes from three tinted surfaces (paper / bone /
   blush) rather than from dark sections.
   No frameworks, no runtime CSS. Motion degrades to fades under
   prefers-reduced-motion.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Tokens ──────────────────────────────────────────────────────────── */
:root {
  /* Brand — sampled directly from the clinic logo artwork. */
  --brand-pink: #AD1E87;
  --brand-cyan: #28C2DA;

  /* The three surfaces. Warm pink-whites rather than neutral greys — a cool
     grey next to this pink reads as dirty. */
  --paper:      #FFFFFF;
  --bone:       #FDF8FA;
  --blush:      #F9E9F1;

  /* Accent = the brand magenta family. Actions, links, highlights. */
  --accent:      #AD1E87;
  --accent-hi:   #E24BA6;
  --accent-deep: #7C1361;
  /* Button-only highlight. --accent-hi is too light to carry white label text
     (3.6:1); this is the lightest pink that still clears 4.5:1 against white. */
  --accent-btn:  #C93A9E;

  /* Champagne = the metallic. Numerals, medallions, hairlines — the things
     that make a page feel expensive without shouting. */
  --lux:        #E3C39F;
  --lux-hi:     #F5E3C9;
  /* Deep enough to clear 4.5:1 as text on white — champagne goes muddy and
     illegible if you take it any lighter. Doubles as the gradient's dark stop. */
  --lux-deep:   #77522B;
  --tx:         #1F0E1A;
  --tx-mute:    #574350;
  --line:       #EFE1E9;
  /* Bodoni Moda for display: a high-contrast Didone, the fashion-house serif.
     Its opsz axis redraws the hairlines for the size it's set at, so it holds
     up at 16px as well as at 8rem. Jost for everything else: a Futura-style
     sans that stays quiet next to it. */
  --display: "Bodoni Moda", "Bodoni 72", Didot, Georgia, serif;
  --sans:    "Jost", system-ui, -apple-system, "Segoe UI", sans-serif;

  --r-sm: 8px;
  --r:    16px;
  --r-lg: 28px;
  --r-xl: 40px;

  --gut: clamp(20px, 5vw, 72px);
  --sect-y: clamp(56px, 6.8vw, 100px);

  --ease: cubic-bezier(.22, 1, .36, 1);
  --ease-io: cubic-bezier(.65, 0, .35, 1);

  --nav-h: 76px;
}

/* ── Reset ───────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  font-size: 106.25%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--bone);
  color: var(--tx);
  font-family: var(--sans);
  font-size: clamp(15px, .55vw + 13.6px, 17px);
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg, iframe { display: block; max-width: 100%; }
img { height: auto; object-fit: cover; }
svg { fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
/* Solid-shape glyphs (phone, whatsapp, shield) fill instead of stroke. */
.ico-wa, .nav__cta svg, .dock svg, .book__wa svg, .rx svg { fill: currentColor; stroke: none; }

button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
/* A Didone gets its elegance from contrast, not weight: headings sit at 500,
   which keeps the hairlines visible on the metallic gradients, with only a
   touch of negative tracking. Emphasis is the drawn italic, never bold. */
h1, h2, h3, h4 { font-family: var(--display); font-weight: 500; line-height: 1.1; letter-spacing: -.012em; }
:is(h1, h2, h3, h4) em { font-style: italic; }
ul, ol { list-style: none; padding: 0; }

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

.skip-link {
  position: fixed; top: 8px; left: 8px; z-index: 999;
  background: var(--accent); color: #fff; padding: 12px 18px; border-radius: var(--r-sm);
  transform: translateY(-200%);
}
.skip-link:focus-visible { transform: none; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

/* ── Layout ──────────────────────────────────────────────────────────── */
.wrap { width: min(1280px, 100% - var(--gut) * 2); margin-inline: auto; }
.wrap--narrow { width: min(820px, 100% - var(--gut) * 2); }
.section { padding-block: var(--sect-y); position: relative; }
/* Two sections on the same ground read as one block, so the second one's top
   padding would only double the gap. */
.section--light + .section--light, .section--tint + .section--tint { padding-top: 0; }
/* Three surfaces carry the whole page rhythm: paper (white) → bone (the body
   default) → blush (the pink tint). No dark sections anywhere. */
.section--light { background: var(--paper); }
.section--tint  { background: var(--blush); }

/* ── Ambient background: drifting pink/plum mesh + grain ─────────────── */
.ambient { position: fixed; inset: 0; z-index: -2; pointer-events: none; overflow: hidden; }
.ambient__blob {
  position: absolute; border-radius: 50%; filter: blur(90px); opacity: .5;
  will-change: transform;
}
.ambient__blob--1 { width: 46vw; height: 46vw; left: -10vw;  top: -8vw;
  background: radial-gradient(circle, rgba(173,30,135,.28), transparent 70%); animation: drift1 26s var(--ease-io) infinite alternate; }
.ambient__blob--2 { width: 38vw; height: 38vw; right: -8vw;  top: 22vh;
  background: radial-gradient(circle, rgba(227,195,159,.42), transparent 70%); animation: drift2 32s var(--ease-io) infinite alternate; }
.ambient__blob--3 { width: 30vw; height: 30vw; left: 30vw;  bottom: -10vw;
  background: radial-gradient(circle, rgba(173,30,135,.16), transparent 70%); animation: drift3 38s var(--ease-io) infinite alternate; }

@keyframes drift1 { to { transform: translate3d(8vw, 6vh, 0) scale(1.15); } }
@keyframes drift2 { to { transform: translate3d(-7vw, -5vh, 0) scale(1.2); } }
@keyframes drift3 { to { transform: translate3d(5vw, -8vh, 0) scale(.9); } }

.grain {
  position: fixed; inset: -50%; z-index: 999; pointer-events: none; opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grainShift 7s steps(6) infinite;
}
@keyframes grainShift {
  0%,100% { transform: translate(0,0); }   17% { transform: translate(-4%,-3%); }
  33%     { transform: translate(3%,-5%); } 50% { transform: translate(-2%,4%); }
  67%     { transform: translate(4%,2%); }  83% { transform: translate(-3%,-2%); }
}

/* Soft light that follows the pointer. Desktop only. */
.cursor-glow {
  position: fixed; z-index: -1; width: 460px; height: 460px; border-radius: 50%;
  left: 0; top: 0; pointer-events: none; opacity: 0;
  background: radial-gradient(circle, rgba(173,30,135,.16), transparent 62%);
  transform: translate3d(-50%, -50%, 0);
  transition: opacity .5s ease;
  will-change: transform;
}

/* ── Buttons ─────────────────────────────────────────────────────────── */
.btn {
  --btn-bg: var(--accent); --btn-fg: #FFFFFF;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 14px 26px; border: 0; border-radius: 100px; cursor: pointer;
  font-size: .95rem; font-weight: 500; letter-spacing: -.01em;
  background: var(--btn-bg); color: var(--btn-fg);
  position: relative; overflow: hidden; isolation: isolate;
  transition: transform .5s var(--ease), box-shadow .5s var(--ease), background-color .3s ease, color .3s ease;
}
.btn svg { width: 18px; height: 18px; transition: transform .45s var(--ease); }
.btn:hover { transform: translateY(-2px); box-shadow: 0 14px 34px -12px rgba(173,30,135,.65); }
.btn:hover svg:not(.ico-wa) { transform: translateX(4px); }
.btn:active { transform: translateY(0); }

/* Sheen sweep on hover. */
.btn::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(105deg, transparent 35%, rgba(255,255,255,.5) 50%, transparent 65%);
  transform: translateX(-120%); transition: transform .8s var(--ease);
}
.btn:hover::after { transform: translateX(120%); }

/* Top-lit rather than corner-to-corner: the old 135° run to --accent-deep
   went muddy at the right end of a wide pill. Its lightest stop is still
   --accent-btn, which holds white text at 4.58:1. */
.btn--accent {
  background: linear-gradient(180deg, var(--accent-btn) 0%, var(--accent) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), 0 10px 24px -14px rgba(124, 19, 97, .6);
}
/* Deep plum-pink rather than a flat dark — a secondary weight below the
   bright accent gradient, without introducing a dark surface. */
.btn--dark  { --btn-bg: var(--accent-deep); --btn-fg: #fff; }
.btn--ghost { --btn-bg: transparent; --btn-fg: currentColor; box-shadow: inset 0 0 0 1px currentColor; }
.btn--ghost:hover { box-shadow: inset 0 0 0 1px currentColor, 0 12px 28px -14px rgba(0,0,0,.5); }
.btn--outline { --btn-bg: transparent; --btn-fg: var(--tx); box-shadow: inset 0 0 0 1px rgba(31,14,26,.18); }
.btn--outline:hover { --btn-bg: rgba(173,30,135,.05); box-shadow: inset 0 0 0 1px rgba(173,30,135,.45); }
.btn--dark-outline { --btn-fg: var(--tx); box-shadow: inset 0 0 0 1px rgba(0,0,0,.2); }
.btn--dark-outline:hover { --btn-bg: rgba(0,0,0,.04); box-shadow: inset 0 0 0 1px rgba(0,0,0,.4); }
/* 11px block padding, not 10, so the small button clears the 44px
   tap-target minimum. */
.btn--sm { padding: 11px 18px; font-size: .875rem; }
.btn--lg { padding: 17px 34px; font-size: 1.02rem; }
.btn--block { width: 100%; }

/* ── Nav ─────────────────────────────────────────────────────────────── */
.nav {
  position: fixed; inset: 0 0 auto; z-index: 100; height: var(--nav-h);
  color: var(--tx);
  transition: background-color .45s var(--ease), backdrop-filter .45s var(--ease),
              color .45s var(--ease), box-shadow .45s var(--ease), height .45s var(--ease);
}
.nav__inner { height: 100%; width: min(1280px, 100% - var(--gut) * 2); margin-inline: auto;
  display: flex; align-items: center; gap: 28px; }

.nav.is-stuck {
  height: 64px; background: rgba(255,255,255,.86); color: var(--tx);
  backdrop-filter: saturate(180%) blur(18px); -webkit-backdrop-filter: saturate(180%) blur(18px);
  box-shadow: 0 1px 0 rgba(0,0,0,.07), 0 10px 40px -20px rgba(0,0,0,.3);
}

.nav__brand { display: flex; align-items: center; gap: 12px; margin-right: auto; }
/* The clinic's own logo mark. Its pink and cyan carry on both the dark hero
   and the frosted light nav, so no colour variant is needed. */
.nav__mark {
  width: 42px; height: 42px; flex: none; object-fit: contain;
  transition: transform .5s var(--ease);
}
.nav__brand:hover .nav__mark { transform: rotate(-8deg) scale(1.06); }
.nav__name { display: flex; flex-direction: column; line-height: 1.25; }
.nav__name strong { font-family: var(--display); font-weight: 500; font-size: 1.12rem; letter-spacing: 0; white-space: nowrap; }
.nav__name em { font-style: normal; font-size: .75rem; letter-spacing: .09em; text-transform: uppercase; font-weight: 500; opacity: .62; }

/* A frosted pill, so the links stay legible where the hero's photograph
   runs under them; once the bar itself is frosted the pill steps back. */
.nav__links {
  display: flex; gap: 26px; font-size: .875rem;
  padding: 7px 24px; border-radius: 999px;
  background: rgba(255, 255, 255, .72);
  backdrop-filter: saturate(160%) blur(14px); -webkit-backdrop-filter: saturate(160%) blur(14px);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .7), 0 10px 30px -20px rgba(31, 14, 26, .4);
  transition: background-color .45s var(--ease), box-shadow .45s var(--ease);
}
.nav.is-stuck .nav__links { background: transparent; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
.nav__links a { position: relative; padding-block: 6px; opacity: .82; transition: opacity .3s; }
.nav__links a::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 1px; width: 100%;
  background: var(--accent); transform: scaleX(0); transform-origin: right;
  transition: transform .45s var(--ease);
}
.nav__links a:hover { opacity: 1; }
.nav__links a:hover::after { transform: scaleX(1); transform-origin: left; }

.nav__cta { display: flex; gap: 10px; align-items: center; }
/* A pill that wraps to two lines stops reading as a button, so the label
   never wraps; phones get the short form instead. */
.nav__cta .btn { white-space: nowrap; }
.nav__cta-short { display: none; }

.nav__links a { white-space: nowrap; }
/* Laptops: the tagline goes first so the links never wrap to two lines. */
@media (max-width: 1340px) {
  .nav__name em { display: none; }
  .nav__links { gap: 20px; padding-inline: 20px; }
}
@media (max-width: 1080px) { .nav__links { display: none; } }
@media (max-width: 620px)  {
  .nav__name em { display: none; }
  .nav__name strong { font-size: 1.02rem; }
  .nav__cta .btn--ghost { display: none; }
  .nav__cta-long { display: none; }
  .nav__cta-short { display: inline; }
}

/* ── Eyebrow ─────────────────────────────────────────────────────────── */
.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: .75rem; letter-spacing: .15em; text-transform: uppercase; font-weight: 500;
  color: var(--accent-deep); margin-bottom: 26px;
}
/* Cyan appears only in small doses — the logo's second colour, used as a
   counterpoint so the page doesn't become monochrome pink. */
.eyebrow__dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--brand-cyan);
  box-shadow: 0 0 0 0 rgba(40,194,218,.7); animation: ping 2.6s var(--ease-io) infinite;
}
@keyframes ping {
  0%   { box-shadow: 0 0 0 0 rgba(40,194,218,.7); }
  70%  { box-shadow: 0 0 0 12px rgba(40,194,218,0); }
  100% { box-shadow: 0 0 0 0 rgba(40,194,218,0); }
}

/* ══ JUSTDENT LAYER ════════════════════════════════════════════════════════
   Hero, preloader and metallic type, rebuilt from the Just Dent site's source
   (ClientWorks/JustDent). JustDent drives these with GSAP; here they are CSS
   driven by a handful of custom properties that motion.js sets. MOTION.md
   records how each piece maps back to the original. */

:root {
  /* The hero panel and the preloader share one ground, so as the preloader
     wipes away the panel underneath is already the same colour — only the
     photograph and the headline appear to arrive. A shade deeper than bone so
     the panel still reads as a surface against the rest of the page. */
  --panel: #F5EBF0;
  --ease-expo: cubic-bezier(.16, 1, .3, 1);
  --ease-expo-io: cubic-bezier(.87, 0, .13, 1);
}

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

/* ── Metallic type ───────────────────────────────────────────────────────
   A many-stop gradient clipped to the glyphs, swept slowly sideways so the
   highlight travels across the word. The class must sit on the element that
   directly holds the text: background-clip:text does not reach text inside a
   transformed descendant (the same failure that once blanked the hero's
   accent word here). text-shadow is cleared because it paints over the fill.

   Every variant's lightest stop is checked against its ground — the
   gradient sweeps, so any stop can land under any glyph. */
.text-metal, .text-metal-plum, .text-metal-rose {
  background-size: 240% 100%; background-position: 0% 50%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  text-shadow: none;
  animation: metalSheen 11s ease-in-out infinite alternate;
}
/* Silver — JustDent's own stops. For photographs only. */
.text-metal {
  background-image: linear-gradient(100deg, #8e9197 0%, #f4f4f1 16%, #b4b7bc 30%, #ffffff 44%, #8a8d93 58%, #e9e9e6 74%, #a3a6ac 88%, #f7f7f5 100%);
}
/* Plum chrome — JustDent's graphite, rebased on the page's ink so headings
   stay in the brand family. For section headings on the light grounds. */
.text-metal-plum {
  background-image: linear-gradient(100deg, #1F0E1A 0%, #6B4A60 18%, #24101E 34%, #7A5870 50%, #2A1424 66%, #634458 84%, #1F0E1A 100%);
}
/* Rose chrome — the brand pink polished. Every stop clears 4.5:1 on the light
   grounds, so it is safe on small type as well as display. */
.text-metal-rose {
  background-image: linear-gradient(100deg, #6A1052 0%, #A1307C 18%, #5E0E49 34%, #A43F84 50%, #6F1456 66%, #94297A 84%, #641050 100%);
}
@keyframes metalSheen { to { background-position: 100% 50%; } }

/* ── Blend-mode title ────────────────────────────────────────────────────
   White with a difference blend comes out as (255 − backdrop): near-black on
   the light panel, and an inversion of the photograph wherever the letters
   cross onto it. It only works against what is painted in the same stacking
   context, which is why the hero headline is a direct child of the stage. */
.title-difference { color: #fff; mix-blend-mode: difference; }

/* ── Masked line rise ────────────────────────────────────────────────────
   The clip lives on the wrapper so the line can start fully below its box
   rather than fading in place. Tight display leading puts ascenders outside
   the line box, so the clip is padded out and the padding cancelled with a
   negative margin — the mask hides the incoming line without cropping the
   resting one. */
.rise-mask { display: block; overflow: hidden; padding-block: .12em; margin-block: -.12em; }
.rise-mask > span { display: block; }

/* ── Preloader ───────────────────────────────────────────────────────────
   A head script marks <html> before first paint with whether this visit gets
   the preloader, so a returning visitor never sees it flash. If the script
   bundle never arrives, the failsafe below clears it after 7s; the scroll
   lock is set from JS for the same reason, so a failed bundle cannot leave
   the page stuck. */
.pl {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(28px, 6vh, 48px);
  background: var(--panel);
  animation: plFailsafe .01s linear 7s forwards;
}
html[data-pl="skip"] .pl, html[data-pl="done"] .pl { display: none; }
@keyframes plFailsafe { to { visibility: hidden; opacity: 0; } }

.pl__logo { width: min(62vw, 17rem); height: auto; overflow: visible; }
/* Each part transforms about its own box, not the whole SVG's. */
.pl__logo .pl-part { transform-box: fill-box; }
html[data-pl="active"] .pl__logo .pl-part { opacity: 0; }

/* The meter is the functional half: it tracks the fonts, the hero photograph
   and the document actually arriving, and the preloader will not lift until
   they have — so a slow connection sees progress, never a half-built page. */
.pl__meter { width: min(50vw, 12.5rem); display: flex; flex-direction: column; align-items: center; gap: 12px; }
.pl__track {
  position: relative; width: 100%; height: 2px; border-radius: 2px; overflow: hidden;
  background: rgba(173, 30, 135, .14);
}
.pl__bar {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, var(--accent-deep), var(--accent));
  transform-origin: left center; transform: scaleX(var(--p, 0));
}
.pl__pct {
  font-size: .75rem; font-weight: 600; letter-spacing: .24em; text-transform: uppercase;
  color: var(--tx-mute); font-variant-numeric: tabular-nums;
}

/* ── Hero ────────────────────────────────────────────────────────────────
   JustDent's split hero. The section is two screens tall and its stage
   sticks while the extra screen scrolls past; motion.js writes the scroll
   progress into --hp (0 → 1) and everything below is derived from it:
     · the photo window grows from the right half (desktop) or the lower part
       of the screen (mobile) to the whole stage;
     · the panel copy fades out over the first 15%;
     · the headline slides away left and fades, inverting through the photo;
     · a second, metallic title slides in over the photo;
     · three treatment names rise along its foot near the end.
   The window is two opposed translations — the frame moves in while its
   content moves back out by the same amount — so the photograph holds still
   and only the opening grows. Transforms and opacity only, so it stays on the
   compositor. */
.hx {
  --hp: 0;
  /* Lines up with the page column (.wrap) on every width; the percentage
     resolves against the stage wherever the variable is used. */
  --hx-pad: max(var(--gut), calc((100% - 1280px) / 2));
  --hx-wx: calc(50% * (1 - var(--hp)));
  --hx-wy: 0%;
  position: relative; height: 200svh; background: var(--panel);
}
.hx__stage {
  position: sticky; top: 0; height: 100svh; min-height: 560px;
  overflow: hidden; background: var(--panel);
}

/* Panel copy that leaves as the window opens. Hidden outright once it has
   faded, so an invisible button can never take a click. */
.hx-fade { opacity: clamp(0, 1 - var(--hp) * 6.67, 1); }
.hx.is-open .hx-fade { visibility: hidden; }

.hx__eyebrow {
  position: absolute; z-index: 2; margin: 0;
  left: var(--hx-pad); top: calc(var(--nav-h) + 30px);
}

.hx__intro {
  position: absolute; z-index: 2;
  left: var(--hx-pad); bottom: clamp(28px, 6vh, 56px);
  width: min(42vw, 31rem);
}
.hx__sub { font-size: 1rem; line-height: 1.62; color: var(--tx-mute); margin: 0 0 22px; max-width: 42ch; }
.hx__sub strong { color: var(--tx); font-weight: 600; }
.hx__actions { display: flex; flex-wrap: wrap; gap: 12px; }
.hx__trust {
  display: flex; gap: 30px; margin-top: 26px; padding-top: 20px;
  border-top: 1px solid rgba(31, 14, 26, .1);
}
.hx__trust li { display: flex; align-items: baseline; gap: 10px; }
.hx__trust strong {
  font-family: var(--display); font-weight: 500; font-size: 2rem; line-height: 1;
  letter-spacing: -.02em;
}
.hx__trust span { font-size: .78rem; line-height: 1.4; color: var(--tx-mute); }

/* The photo window. */
.hx__frame {
  position: absolute; inset: 0; z-index: 1; overflow: hidden;
  transform: translate3d(var(--hx-wx), var(--hx-wy), 0); will-change: transform;
}
.hx__counter {
  position: absolute; inset: 0;
  transform: translate3d(calc(var(--hx-wx) * -1), calc(var(--hx-wy) * -1), 0); will-change: transform;
}
/* Oversized vertically so the exit drift never exposes an edge. */
.hx__photo {
  position: absolute; inset-inline: 0; top: -8%; height: 116%;
  transform: translate3d(0, var(--hx-lag, 0%), 0);
}
.hx__media { width: 100%; height: 100%; transform-origin: 50% 50%; }
.hx__img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: var(--hx-pos, 50% 50%);
  background: var(--blush);
}
/* The botox shot has its subject on the left, which is the half hidden at
   rest. Mirroring it puts the face in the open half; there is no text in
   frame for the flip to betray. */
html[data-hero="botox-injection"] .hx__img { transform: scaleX(-1); }

/* A plum wash, lighter than JustDent's navy: dark enough that the inverted
   headline letters come out bright over the photo, light enough that the
   photograph still reads as daylight. */
.hx__tint { position: absolute; inset: 0; background: rgba(31, 14, 26, .26); pointer-events: none; }
@media (min-width: 1024px) {
  .hx__tint::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(90deg, transparent 49%, rgba(31, 14, 26, .5) 50%, rgba(31, 14, 26, .3) 66%, transparent 82%);
    opacity: clamp(0, 1 - var(--hp, 0) * 3, 1);
  }
}
.hx__fadebot {
  position: absolute; inset: auto 0 0; height: 55%; pointer-events: none;
  background: linear-gradient(0deg, rgba(31, 14, 26, .66), rgba(31, 14, 26, 0));
}
/* Deepens behind the incoming title as the window opens. */
.hx__shade {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(31, 14, 26, .6) 0%, rgba(31, 14, 26, .22) 62%, rgba(31, 14, 26, 0) 100%);
  opacity: clamp(0, (var(--hp) - .3) * 1.67, 1);
}

.hx__note {
  position: absolute; left: 50%; right: 0; bottom: 0; z-index: 1;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 32px;
  padding: clamp(28px, 3vw, 48px); color: #fff;
}
.hx__note-lead {
  font-family: var(--display); font-weight: 400; letter-spacing: -.01em;
  font-size: clamp(1.35rem, 1.9vw, 1.8rem); line-height: 1.15; max-width: 17rem; margin: 0;
}
.hx__note-lead em { font-style: italic; }
.hx__note-by { font-size: .86rem; line-height: 1.5; color: rgba(255, 255, 255, .88); text-align: right; margin: 0; }
.hx__note-m { display: none; }

.hx__title2 {
  position: absolute; inset-inline: 0; top: 50%; margin: 0;
  padding-inline: var(--hx-pad);
  font-family: var(--display); font-weight: 400;
  font-size: clamp(2.5rem, 6.4vw, 7.4rem); line-height: .98; letter-spacing: -.03em;
  transform: translate3d(calc(100% * (1 - clamp(0, (var(--hp) - .1) * 1.18, 1))), -50%, 0);
}
.hx__title2 em { font-style: italic; }

.hx__tips {
  position: absolute; inset-inline: 0; bottom: 0; margin: 0; list-style: none;
  display: flex; flex-wrap: wrap; gap: 8px 44px;
  padding: 0 var(--hx-pad) clamp(28px, 5vh, 48px);
}
.hx__tips span {
  font-size: .75rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase;
  color: rgba(255, 255, 255, .88);
  transform: translateY(110%);
  transition: transform .9s var(--ease-expo) calc(var(--i, 0) * .12s);
}
.hx.is-end .hx__tips span { transform: none; }

/* The headline, over the seam: on desktop it spans both halves. */
.hx__headline {
  position: absolute; z-index: 3; pointer-events: none;
  left: var(--hx-pad); right: 0; top: 47%;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(3.1rem, 6.9vw, 8.6rem); line-height: .92; letter-spacing: -.035em;
  transform: translate3d(calc(-50% * var(--hp)), -50%, 0);
  opacity: clamp(0, 1 - (var(--hp) - .25) * 3.33, 1);
}
.hx__headline b { font-weight: 400; font-style: italic; }
/* Every headline stacked in one grid cell and swapped on a timer: the
   outgoing lines leave upward through their masks while the incoming lines
   rise in from below.

   Without JavaScript the first headline simply stands. With it, html.js (set
   in <head>, before paint) lowers the lines out of sight so they can rise in;
   if motion.js then never takes over (.is-live), a failsafe brings the first
   set up after 6s rather than leaving the hero without a headline. */
.hx__stack { display: grid; }
.hx__set { grid-area: 1 / 1; }
.hx__set:not(:first-child) { visibility: hidden; }
/* 140%, not 115%: Bodoni's ascenders and italic descenders reach well past
   the line box, and at 115% they still showed inside the mask. */
html.js .hx__set .rise-mask > span { transform: translateY(140%); }
html.js .hx:not(.is-live) .hx__set:first-child .rise-mask > span { animation: hxFailsafe .01s linear 6s forwards; }
@keyframes hxFailsafe { to { transform: none; } }
.hx.is-live .hx__set { visibility: hidden; }
.hx.is-live .hx__set.is-shown { visibility: visible; }
html.js .hx__set.is-in .rise-mask > span {
  transform: none;
  transition: transform 1.1s var(--ease-expo) calc(var(--d, 0s) + var(--i, 0) * .1s);
}
html.js .hx__set.is-out .rise-mask > span {
  transform: translateY(-140%);
  transition: transform .65s cubic-bezier(.55, .06, .68, .19) calc(var(--i, 0) * .06s);
}

/* The entrance push-in's starting scale, in place from first paint so the
   photograph never shows at rest and then jumps. motion.js eases it back. */
@media (prefers-reduced-motion: no-preference) {
  html.js .hx__media { transform: scale(1.25); }
}
@media (min-width: 1024px) {
  /* One line, so the accent word falls naturally across the seam. */
  .hx__set .rise-mask:last-child > span { white-space: nowrap; }
}

/* Laptops with a short viewport: the trust row is the first thing to go so
   the headline and the buttons never collide. */
@media (min-width: 1024px) and (max-height: 760px) {
  .hx__trust { display: none; }
  .hx__sub { margin-bottom: 18px; }
}

/* Phones and tablets: the photo starts in the lower part of the screen and
   the headline sits on its top edge, as on JustDent. The primary button sits
   between the two — headline, then the action, then everything else. */
@media (max-width: 1023px) {
  .hx {
    --hx-start-y: 60%;
    --hx-wx: 0%;
    --hx-wy: calc(var(--hx-start-y) * (1 - var(--hp)));
  }
  /* Eyebrow, headline and Book button stack from the top in normal flow, and
     motion.js starts the photo window just below them (--hx-start-y, in px).
     So the gap is the same on every phone, instead of the headline hanging
     off a fixed share of the screen and leaving a hole under the eyebrow on
     tall ones. The 60% above is the fallback if the script never runs. */
  .hx__stage {
    display: flex; flex-direction: column;
    padding: calc(var(--nav-h) + 14px) var(--hx-pad) 0;
  }
  .hx__eyebrow, .hx__headline, .hx__intro { position: relative; inset: auto; }
  .hx__eyebrow { order: 1; font-size: .72rem; letter-spacing: .12em; margin-bottom: 20px; }
  .hx__headline {
    order: 2;
    font-size: clamp(2.45rem, 11.2vw, 4.6rem); line-height: .94; letter-spacing: -.045em;
    transform: translate3d(calc(-50% * var(--hp)), 0, 0);
  }
  .hx__intro { order: 3; width: auto; margin-top: 22px; }
  .hx__intro .hx__sub, .hx__intro .hx__trust { display: none; }
  .hx__actions { flex-wrap: nowrap; }
  .hx__actions .btn--lg { padding: 14px 24px; font-size: .95rem; }
  /* WhatsApp collapses to its icon — the sticky dock carries the full label. */
  /* Scoped to .hx__actions so it outranks the .btn--lg padding just above —
     otherwise 24px a side leaves the icon 2px of a 50px circle. */
  .hx__actions .hx__wa { padding: 0; width: 50px; flex: none; }
  .hx__wa svg { flex: none; width: 22px; height: 22px; }
  .hx__wa-t { display: none; }
  .hx__note { display: none; }
  .hx__note-m {
    display: block; position: absolute; inset: auto 0 0; z-index: 1; color: #fff;
    /* Clear of the sticky booking dock that owns the bottom 78px. */
    padding: 0 var(--hx-pad) 104px;
  }
  .hx__note-m p { font-size: .9rem; line-height: 1.55; margin: 0 0 16px; color: rgba(255, 255, 255, .92); max-width: 36ch; }
  .hx__note-m strong { color: #fff; }
  .hx__note-m .hx__trust { border-top-color: rgba(255, 255, 255, .22); margin-top: 0; padding-top: 14px; gap: 22px; }
  .hx__note-m .hx__trust strong { font-size: 1.45rem; color: #fff; }
  .hx__note-m .hx__trust span { color: rgba(255, 255, 255, .8); }
  /* Number over its label: side by side, three of them crush into slivers. */
  .hx__note-m .hx__trust li { flex-direction: column; align-items: flex-start; gap: 6px; }
  .hx__title2 { font-size: clamp(2.4rem, 11vw, 4.4rem); }
  .hx__tips { padding-bottom: 104px; gap: 6px 26px; }
  /* Phones crop a landscape photo to its middle; steer each one to its
     subject. */
  html[data-hero="laser-handpiece"] .hx { --hx-pos: 62% 50%; }
  html[data-hero="botox-injection"] .hx { --hx-pos: 40% 50%; }
}

/* ── Lazy images ─────────────────────────────────────────────────────────
   Below-the-fold photographs load natively lazily (the browser starts them a
   little before they scroll into view) and decode off the main thread. While
   one is on its way it shows a soft blush shimmer rather than a hole; when it
   lands it fades in. Gated on html.js, so without JavaScript every image
   simply renders as normal. */
html.js img[loading="lazy"]:not(.is-loaded):not(.is-cached) {
  background-color: var(--blush);
  background-image: linear-gradient(100deg, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, .6) 50%, rgba(255, 255, 255, 0) 70%);
  background-size: 220% 100%; background-repeat: no-repeat;
  animation: imgShimmer 1.6s linear infinite;
}
@keyframes imgShimmer { from { background-position: 160% 0; } to { background-position: -60% 0; } }
html.js img.is-loaded { animation: imgIn .75s var(--ease-expo) both; }
@keyframes imgIn { from { opacity: 0; } }

/* The map is a heavy third-party embed (roughly a megabyte of Google's
   script). It is only requested once the section is close — until then this
   panel holds its place. */
.location__map { position: relative; background: var(--blush); }
.location__map::before {
  content: "Map loads as you reach it"; position: absolute; inset: 0; z-index: 0;
  display: grid; place-items: center;
  font-size: .75rem; letter-spacing: .16em; text-transform: uppercase; font-weight: 500; color: var(--tx-mute);
}
.location__map iframe { position: relative; z-index: 1; }
/* Without JavaScript the deferred frame would never load; its <noscript>
   twin, which loads the normal way, stands in. */
html:not(.js) .location__map iframe[data-src] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .text-metal, .text-metal-plum, .text-metal-rose { animation: none; }
  .hx { height: 100svh; }
  .hx__title2, .hx__shade, .hx__tips { display: none; }
  .hx__set .rise-mask > span { transform: none !important; transition: none !important; }
  html.js img[loading="lazy"], html.js img.is-loaded { animation: none !important; }
}

/* ── Marquee ─────────────────────────────────────────────────────────── */
.marquee {
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  overflow: hidden; padding-block: 18px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.marquee__track {
  display: flex; align-items: center; gap: 26px; width: max-content;
  animation: marq 34s linear infinite;
}
.marquee span {
  font-family: var(--display); font-weight: 400; font-style: italic; font-size: clamp(1.2rem, 2.1vw, 1.75rem);
  color: var(--tx-mute); white-space: nowrap; letter-spacing: 0;
}
.marquee i { color: var(--accent); font-style: normal; }
@keyframes marq { to { transform: translateX(-50%); } }

/* ── Section headings ────────────────────────────────────────────────── */
.sect-head { max-width: 62ch; margin-bottom: clamp(28px, 3.6vw, 52px); }
.kicker {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: .75rem; letter-spacing: .16em; text-transform: uppercase; font-weight: 500;
  color: var(--accent-deep); margin-bottom: 18px;
}
.kicker::before { content: ""; width: 26px; height: 1px; background: currentColor; }
/* Tinted sections are light too now, so the kicker keeps the same deep pink. */
.sect-head h2, .deep__copy h2, .location__copy h2, .book__copy h2, .doctor__copy h2 {
  font-size: clamp(1.95rem, 3.7vw, 3.15rem); letter-spacing: -.03em; text-wrap: balance;
}
.lede { font-size: clamp(1rem, .5vw + .9rem, 1.14rem); color: var(--tx-mute); margin-top: 18px; text-wrap: pretty; }
.section--tint .lede { color: var(--tx-mute); }

/* ── Compare ─────────────────────────────────────────────────────────── */
.compare__grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(16px, 2.5vw, 28px); }
.compare__card {
  padding: clamp(28px, 3.5vw, 46px); border-radius: var(--r-lg); position: relative;
}
.compare__card h3 { font-size: 1.42rem; margin-bottom: 24px; }
.compare__card ul { display: grid; gap: 15px; }
.compare__card li {
  position: relative; padding-left: 32px; font-size: .96rem; line-height: 1.6;
}
.compare__card li::before {
  content: ""; position: absolute; left: 0; top: .44em;
  width: 17px; height: 17px; border-radius: 50%;
  background-repeat: no-repeat; background-position: center; background-size: 10px;
}

.compare__card--them { background: #F2EFEA; color: var(--tx-mute); }
.compare__card--them li::before {
  background-color: #DCD5CB;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237A7268' stroke-width='3.4' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6L6 18'/%3E%3C/svg%3E");
}

/* Separation now comes from a pink-tinted panel and a brand border rather than
   from inverting to dark. */
.compare__card--us {
  background: linear-gradient(160deg, var(--blush), #FFF6FA 70%);
  box-shadow: inset 0 0 0 1.5px var(--accent), 0 34px 70px -42px rgba(173,30,135,.55);
}
.compare__card--us { color: var(--tx); }
.compare__card--us strong { color: var(--accent-deep); font-weight: 500; }
.compare__card--us li::before {
  background-color: var(--brand-cyan);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23102A2F' stroke-width='3.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E");
}
.compare__flag {
  position: absolute; top: -13px; left: clamp(28px, 3.5vw, 46px);
  background: var(--accent); color: #FFFFFF; font-size: .72rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; font-weight: 500; padding: 6px 14px; border-radius: 100px;
}
@media (max-width: 780px) { .compare__grid { grid-template-columns: 1fr; } }

/* ── Service cards ───────────────────────────────────────────────────── */
.services__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(16px, 2vw, 26px); }
.svc {
  display: flex; flex-direction: column; border-radius: var(--r-lg); overflow: hidden;
  background: var(--bone); box-shadow: inset 0 0 0 1px var(--line);
  transform-style: preserve-3d; will-change: transform;
  transition: transform .6s var(--ease), box-shadow .6s var(--ease);
}
.svc:hover { box-shadow: inset 0 0 0 1px var(--accent), 0 34px 60px -34px rgba(0,0,0,.35); }
.svc__img { overflow: hidden; aspect-ratio: 4 / 3; }
.svc__img img { width: 100%; height: 100%; transition: transform 1.1s var(--ease), filter .8s ease; }
.svc:hover .svc__img img { transform: scale(1.07); }
.svc__body { padding: clamp(22px, 2.5vw, 32px); display: flex; flex-direction: column; flex: 1; }
.svc__n {
  font-family: var(--display); font-weight: 500; font-style: italic; font-size: 1rem; color: var(--lux-deep);
  letter-spacing: .04em; margin-bottom: 8px;
}
.svc h3 { font-size: 1.6rem; margin-bottom: 12px; }
.svc p { font-size: .94rem; color: var(--tx-mute); margin-bottom: 22px; }
.svc__go {
  margin-top: auto; display: inline-flex; align-items: center; gap: 8px;
  font-size: .85rem; font-weight: 500; color: var(--accent-deep);
}
.svc__go svg { width: 16px; height: 16px; transition: transform .45s var(--ease); }
.svc:hover .svc__go svg { transform: translateX(5px); }
@media (max-width: 900px) { .services__grid { grid-template-columns: 1fr; } }
/* Tablets: one column of full-width cards is mostly photograph, so the
   card turns sideways, picture beside the words. */
@media (min-width: 561px) and (max-width: 900px) {
  .svc { flex-direction: row; }
  .svc__img { flex: 0 0 42%; aspect-ratio: auto; min-height: 240px; }
}

/* ── Deep dives ──────────────────────────────────────────────────────── */
.deep__grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(36px, 5.5vw, 84px); align-items: center;
}
/* Positioned so the absolutely-placed children — the face map and the float
   layers — resolve against the image column. Without it they fall back to the
   section box, and the face-map dots land nowhere near the face. */
.deep__media { position: relative; }
.deep--flip .deep__media { order: 2; }
.deep__frame {
  position: relative; border-radius: var(--r-lg); overflow: hidden; aspect-ratio: 4 / 3;
  box-shadow: 0 40px 80px -44px rgba(0,0,0,.55);
}
.deep__frame img { width: 100%; height: 100%; }
.deep__copy > * + * { margin-top: 20px; }
.deep__copy .btn { margin-top: 32px; }

.taglist { display: flex; flex-wrap: wrap; gap: 9px; }
.taglist li {
  font-size: .84rem; padding: 8px 15px; border-radius: 100px;
  background: rgba(173,30,135,.1); color: var(--accent-deep); box-shadow: inset 0 0 0 1px rgba(173,30,135,.24);
}

.facts {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px;
  border-top: 1px solid var(--line); padding-top: 24px; margin-top: 30px !important;
}
.facts div { display: flex; flex-direction: column; gap: 5px; }
.facts dt { font-size: .75rem; letter-spacing: .11em; text-transform: uppercase; font-weight: 500; color: var(--tx-mute); }
.facts dd { font-family: var(--display); font-weight: 500; font-size: 1.3rem; letter-spacing: -.01em; margin: 0; }
/* Wide enough on desktop for every value to sit on one line, so the columns
   size to their content instead of wrapping the longest. */
@media (min-width: 1200px) {
  .facts { grid-template-columns: repeat(4, auto); justify-content: space-between; column-gap: 20px; }
  .facts dd { white-space: nowrap; }
}
/* The hyphen in a range, from the sans: Bodoni draws it as a hairline. */
.rng { font-family: var(--sans); font-weight: 400; margin-inline: .1em; }
/* Retained as a light "emphasis" variant of the facts row on tinted sections. */
.facts--dark dd { color: var(--accent-deep); }
@media (max-width: 560px) { .facts { grid-template-columns: repeat(2, 1fr); gap: 20px 4px; } }

.rx {
  display: flex; gap: 11px; align-items: flex-start;
  font-size: .84rem; color: var(--tx-mute); line-height: 1.55;
  padding: 15px 18px; border-radius: var(--r); background: rgba(0,0,0,.035);
}
.rx svg { width: 17px; height: 17px; flex: none; margin-top: 2px; color: var(--accent-deep); }
.rx--dark { background: rgba(255,255,255,.7); }


/* Laser sweep — light bar crosses the frame when the section is in view. */
.laser-frame { overflow: hidden; }
.laser-sweep { z-index: 2; }
.laser-sweep {
  position: absolute; top: -20%; left: 0; width: 26%; height: 140%;
  background: linear-gradient(90deg, transparent, rgba(232,216,168,.14) 30%, rgba(255,255,255,.85), rgba(232,216,168,.14) 70%, transparent);
  filter: blur(1px); transform: translateX(-140%) skewX(-14deg); opacity: 0;
}
.deep__media.is-in .laser-sweep { animation: sweep 2.8s var(--ease-io) .3s infinite; }
@keyframes sweep {
  0%   { transform: translateX(-140%) skewX(-14deg); opacity: 0; }
  12%  { opacity: 1; }
  70%  { opacity: 1; }
  100% { transform: translateX(500%) skewX(-14deg); opacity: 0; }
}

/* Area chips */
.chips-label { font-size: .75rem; letter-spacing: .11em; text-transform: uppercase; font-weight: 500; color: var(--tx-mute); }
.chips { display: flex; flex-wrap: wrap; gap: 9px; }
.chip {
  /* 11px block padding keeps these at the 44px minimum tap target. */
  padding: 11px 17px; border-radius: 100px; cursor: pointer; font-size: .86rem;
  background: var(--paper); color: var(--tx-mute);
  border: 1px solid var(--line);
  transition: all .35s var(--ease);
}
.chip:hover { color: var(--accent-deep); border-color: var(--accent); transform: translateY(-1px); }
.chip.is-on {
  background: var(--accent); border-color: var(--accent); color: #FFFFFF; font-weight: 500;
  box-shadow: 0 10px 24px -10px rgba(173,30,135,.75);
}

@media (max-width: 860px) {
  .deep__grid { grid-template-columns: 1fr; }
  .deep--flip .deep__media { order: 0; }
}

/* ── Facial types ────────────────────────────────────────────────────── */
.ftypes { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; background: var(--line); border-radius: var(--r); overflow: hidden; }
.ftypes article { background: var(--paper); padding: 20px 22px; transition: background .4s ease; }
.ftypes article:hover { background: var(--blush); }
.ftypes h4 { font-size: 1.03rem; margin-bottom: 5px; }
.ftypes p { font-size: .84rem; color: var(--tx-mute); }
@media (max-width: 560px) { .ftypes { grid-template-columns: 1fr; } }

/* ── Also offered ────────────────────────────────────────────────────── */
.also__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; background: var(--line); border-radius: var(--r-lg); overflow: hidden; }
.also__grid li {
  background: var(--paper); padding: clamp(26px, 3vw, 40px);
  transition: background .45s ease, transform .45s var(--ease);
}
.also__grid li:hover { background: var(--blush); }
.also__grid h3 { font-size: 1.24rem; margin-bottom: 8px; }
.also__grid p { font-size: .88rem; color: var(--tx-mute); }
@media (max-width: 860px) { .also__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .also__grid { grid-template-columns: 1fr; } }

/* ── Instagram reels ─────────────────────────────────────────────────── */
.ig__head {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: 24px; margin-bottom: clamp(28px, 4vw, 48px);
}
.ig__handle {
  display: inline-flex; align-items: center; gap: 11px; padding: 11px 20px 11px 14px;
  border-radius: 100px; font-size: .92rem; font-weight: 500; color: var(--accent-deep);
  background: linear-gradient(120deg, rgba(226,75,166,.14), rgba(40,194,218,.12));
  box-shadow: inset 0 0 0 1px rgba(173,30,135,.28);
  transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}
.ig__handle:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--accent); }
.ig__handle svg { width: 22px; height: 22px; }

/* Reels are 9:16. Scrollable rail on small screens, grid on large. */
.ig__grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(12px, 1.6vw, 20px);
}
.reel {
  position: relative; display: block; border-radius: var(--r-lg); overflow: hidden;
  aspect-ratio: 9 / 16; background: var(--blush);
  box-shadow: 0 26px 52px -30px rgba(31,14,26,.4);
  transition: transform .6s var(--ease), box-shadow .6s var(--ease);
}
.reel:hover { transform: translateY(-6px); box-shadow: 0 40px 70px -30px rgba(173,30,135,.5); }
.reel img { width: 100%; height: 100%; transition: transform 1.1s var(--ease); }
.reel:hover img { transform: scale(1.06); }
.reel::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(21,6,16,.88), transparent 52%);
}
.reel__play {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%) scale(.9);
  width: 58px; height: 58px; border-radius: 50%; z-index: 2;
  display: grid; place-items: center;
  background: rgba(255,255,255,.16); backdrop-filter: blur(10px);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.4);
  opacity: 0; transition: opacity .45s var(--ease), transform .55s var(--ease);
}
.reel:hover .reel__play { opacity: 1; transform: translate(-50%,-50%) scale(1); }
.reel__play svg { width: 20px; height: 20px; fill: #fff; stroke: none; margin-left: 3px; }
.reel__cap {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; padding: 18px;
  display: flex; flex-direction: column; gap: 5px;
}
.reel__cap strong { font-family: var(--display); font-weight: 500; font-size: 1.08rem; color: #fff; letter-spacing: 0; }
/* White over the reel's own dark photo gradient — the one place light text is
   correct, because it sits on imagery rather than on a page surface. */
.reel__cap span { font-size: .78rem; color: rgba(255,255,255,.9); }
.reel__badge {
  position: absolute; top: 14px; left: 14px; z-index: 2;
  font-size: .75rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  padding: 5px 11px; border-radius: 100px; color: #fff;
  background: rgba(21,6,16,.55); backdrop-filter: blur(8px);
}
.ig__note {
  margin-top: 30px; padding: 16px 20px; border-radius: var(--r);
  background: rgba(226,75,166,.09); box-shadow: inset 0 0 0 1px rgba(226,75,166,.3);
  font-size: .86rem; color: var(--tx-mute);
}
.ig__note strong { color: var(--accent-deep); }

@media (max-width: 1000px) { .ig__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px)  { .ig__grid { grid-template-columns: 1fr 1fr; gap: 10px; } .reel__cap { padding: 13px; } }

/* ── Doctor ──────────────────────────────────────────────────────────── */
.doctor__grid { display: grid; grid-template-columns: .85fr 1.15fr; gap: clamp(36px, 6vw, 88px); align-items: center; }
.doctor__media { position: relative; }
.doctor__frame {
  border-radius: var(--r-xl); overflow: hidden; aspect-ratio: 4 / 5;
  box-shadow: 0 50px 90px -46px rgba(0,0,0,.5);
}
.doctor__frame img { width: 100%; height: 100%; }
.doctor__stamp {
  position: absolute; right: -18px; bottom: 40px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 132px; height: 132px; border-radius: 50%; text-align: center;
  /* Rose-champagne medallion — the one overtly "luxury" object on the page. */
  background: linear-gradient(135deg, var(--lux-hi), var(--lux) 52%, var(--lux-deep));
  color: #3A2A14; box-shadow: 0 22px 44px -18px rgba(168,127,78,.85);
  animation: bob 5s var(--ease-io) infinite alternate;
}
@keyframes bob { to { transform: translateY(-12px); } }
.doctor__stamp span { font-family: var(--display); font-weight: 500; font-size: 1.6rem; line-height: 1; }
.doctor__stamp em { font-style: normal; font-size: .66rem; letter-spacing: .07em; margin-top: 6px; padding-inline: 14px; line-height: 1.3; }

.doctor__copy > * + * { margin-top: 18px; }
.doctor__role { font-size: 1.05rem; color: var(--accent-deep); letter-spacing: .01em; }
.creds { display: grid; gap: 2px; background: var(--line); border-radius: var(--r); overflow: hidden; margin-top: 30px !important; }
.creds li {
  background: var(--paper); padding: 15px 20px; font-size: .93rem;
  display: grid; grid-template-columns: 116px 1fr; gap: 14px; align-items: baseline;
}
.creds span { font-size: .75rem; letter-spacing: .11em; text-transform: uppercase; font-weight: 500; color: var(--tx-mute); }
.pull {
  /* Bodoni Moda's drawn italic: the doctor's own words, set like a quote. */
  font-family: var(--display); font-weight: 400; font-size: clamp(1.3rem, 1.8vw, 1.62rem); font-style: italic;
  line-height: 1.4; padding-left: 24px; border-left: 2px solid var(--lux);
  color: var(--tx); margin-top: 32px !important;
}
.doctor__note { font-size: .88rem; color: var(--tx-mute); padding-top: 20px; border-top: 1px solid var(--line); }
@media (max-width: 900px) {
  .doctor__grid { grid-template-columns: 1fr; }
  .doctor__media { max-width: 420px; width: 100%; margin-inline: auto; }
  .creds li { grid-template-columns: 1fr; gap: 3px; }
}

/* ── Clinic rail (horizontal scroll) ─────────────────────────────────── */
.rail { overflow: hidden; padding-block: 8px; }
.rail__track {
  display: flex; gap: clamp(14px, 1.8vw, 24px); width: max-content;
  padding-inline: var(--gut); will-change: transform;
}
.rail figure { width: clamp(230px, 27vw, 400px); flex: none; }
.rail img {
  width: 100%; aspect-ratio: 4 / 5; border-radius: var(--r-lg);
  transition: transform .8s var(--ease); box-shadow: 0 30px 60px -36px rgba(0,0,0,.5);
}
.rail figure:hover img { transform: scale(1.03); }
.rail figcaption {
  margin-top: 13px; font-size: .78rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 500;
  color: var(--tx-mute);
}

/* ── Process ─────────────────────────────────────────────────────────── */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(18px, 2.5vw, 36px); position: relative; }
/* Editorial steps: a hairline that draws in champagne as each step reveals,
   a large drawn-italic numeral, then the words. */
.steps li { position: relative; padding-top: clamp(22px, 2.4vw, 32px); border-top: 1px solid var(--line); }
.steps li::before {
  content: ""; position: absolute; left: 0; right: 0; top: -1px; height: 1px;
  background: linear-gradient(90deg, var(--lux-deep), var(--lux));
  transform: scaleX(0); transform-origin: left;
  transition: transform 1.3s var(--ease) calc(var(--d, 0) * .12s + .1s);
}
.steps li.is-in::before { transform: none; }
.steps__n {
  display: block; margin-bottom: clamp(14px, 1.6vw, 22px);
  font-family: var(--display); font-weight: 400; font-style: italic; line-height: 1;
  font-size: clamp(2.6rem, 4.2vw, 4rem); letter-spacing: -.02em;
  background: linear-gradient(135deg, #B48C5C 0%, var(--lux-deep) 60%, #5E3F1F 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;
}
.steps h3 { font-size: clamp(1.25rem, 1.6vw, 1.45rem); margin-bottom: 10px; }
.steps p { font-size: .94rem; color: var(--tx-mute); max-width: 30ch; }
@media (max-width: 900px) { .steps { grid-template-columns: 1fr 1fr; row-gap: 40px; } }
@media (max-width: 520px) { .steps { grid-template-columns: 1fr; } }

/* ── Reviews marquee ─────────────────────────────────────────────────── */
.revmarq {
  overflow: hidden; margin-top: clamp(28px, 4vw, 48px);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.revmarq__track { display: flex; gap: 20px; width: max-content; animation: marq 46s linear infinite; }
.revmarq:hover .revmarq__track { animation-play-state: paused; }
.revmarq article {
  width: min(400px, 82vw); flex: none; padding: 30px 32px; border-radius: var(--r-lg);
  background: var(--paper); box-shadow: inset 0 0 0 1px var(--line), 0 22px 46px -32px rgba(31,14,26,.28);
}
.stars { color: var(--lux-deep); letter-spacing: .18em; font-size: .9rem; margin-bottom: 15px; }
.revmarq p { font-size: .98rem; line-height: 1.62; color: var(--tx); margin-bottom: 22px; }
.revmarq footer { display: flex; align-items: center; gap: 12px; }
.revmarq footer img { width: 42px; height: 42px; border-radius: 50%; flex: none; }
.revmarq footer span { display: flex; flex-direction: column; font-size: .8rem; color: var(--tx-mute); }
.revmarq footer strong { color: var(--tx); font-weight: 500; font-size: .88rem; }

/* ── FAQ ─────────────────────────────────────────────────────────────── */
.faq__grid {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(32px, 6vw, 104px); align-items: start;
}
.faq__head { position: sticky; top: calc(var(--nav-h) + 40px); margin-bottom: 0; }
.faq__wa { margin-top: 28px; }
.faq__wa svg { width: 18px; height: 18px; color: #25D366; }
@media (max-width: 900px) {
  .faq__grid { grid-template-columns: 1fr; gap: 0; }
  .faq__head { position: static; margin-bottom: 32px; }
}
/* Rules between rows rather than a coloured gap, so a row still waiting to
   reveal shows as paper instead of a grey slab. */
.acc { display: grid; background: var(--paper); border-radius: var(--r-lg); overflow: hidden; box-shadow: inset 0 0 0 1px var(--line), 0 30px 60px -48px rgba(31, 14, 26, .35); }
.acc details { background: transparent; }
.acc details + details { border-top: 1px solid var(--line); }
.acc summary {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 22px clamp(20px, 3vw, 32px); cursor: pointer; list-style: none;
  font-family: var(--display); font-weight: 500; font-size: clamp(1.08rem, 1.45vw, 1.26rem); letter-spacing: 0;
  transition: color .3s ease;
}
.acc summary::-webkit-details-marker { display: none; }
.acc summary:hover { color: var(--accent-deep); }
.acc summary span {
  position: relative; width: 22px; height: 22px; flex: none;
  transition: transform .5s var(--ease);
}
.acc summary span::before, .acc summary span::after {
  content: ""; position: absolute; top: 50%; left: 50%; background: var(--accent-deep);
  transform: translate(-50%,-50%); transition: opacity .35s ease;
}
.acc summary span::before { width: 14px; height: 1.6px; }
.acc summary span::after  { width: 1.6px; height: 14px; }
.acc details[open] summary span { transform: rotate(180deg); }
.acc details[open] summary span::after { opacity: 0; }
.acc__body { padding: 0 clamp(20px, 3vw, 32px) 26px; }
.acc__body p { font-size: .96rem; color: var(--tx-mute); max-width: 68ch; }
.acc__body a { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 3px; }
/* Height is animated in JS via a wrapper; this keeps the closed state clean. */
.acc details:not([open]) .acc__body { display: none; }

/* ── Location ────────────────────────────────────────────────────────── */
.location__grid { display: grid; grid-template-columns: 1fr 1.1fr; gap: clamp(32px, 5vw, 70px); align-items: center; }
.location__copy > * + * { margin-top: 18px; }
.location address {
  font-style: normal; font-size: 1.02rem; line-height: 1.75; color: var(--tx);
  padding-left: 20px; border-left: 2px solid var(--accent); margin-top: 28px !important;
}
.contact { display: grid; gap: 16px; margin-top: 28px !important; }
.contact div { display: grid; grid-template-columns: 92px 1fr; gap: 14px; align-items: baseline; }
.contact dt { font-size: .75rem; letter-spacing: .11em; text-transform: uppercase; font-weight: 500; color: var(--tx-mute); }
.contact dd { margin: 0; font-size: .95rem; }
.contact a { color: var(--accent-deep); font-weight: 500; }
.contact a:hover { text-decoration: underline; text-underline-offset: 3px; }
.location__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px !important; }
.location__map {
  border-radius: var(--r-lg); overflow: hidden; aspect-ratio: 4 / 3;
  box-shadow: 0 40px 80px -44px rgba(0,0,0,.4); background: var(--line);
}
.location__map iframe { width: 100%; height: 100%; border: 0; filter: grayscale(.35) contrast(1.05); }
@media (max-width: 900px) {
  .location__grid { grid-template-columns: 1fr; }
  .contact div { grid-template-columns: 1fr; gap: 3px; }
}

/* ── Booking form ────────────────────────────────────────────────────── */
.book__grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(36px, 5vw, 76px); align-items: start; }
.book__copy > * + * { margin-top: 18px; }
.book__points { display: grid; gap: 12px; margin-top: 30px !important; }
.book__points li { position: relative; padding-left: 28px; font-size: .96rem; color: var(--tx-mute); }
.book__points li::before {
  content: ""; position: absolute; left: 0; top: .48em; width: 15px; height: 15px; border-radius: 50%;
  background: var(--brand-cyan) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23102A2F' stroke-width='3.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E") center/9px no-repeat;
}
.book__wa {
  display: flex; align-items: center; gap: 14px; margin-top: 34px !important;
  padding: 16px 20px; border-radius: var(--r); background: var(--paper);
  box-shadow: inset 0 0 0 1px var(--line), 0 18px 40px -30px rgba(31, 14, 26, .3);
  transition: background .4s ease, transform .5s var(--ease);
}
.book__wa:hover { box-shadow: inset 0 0 0 1px rgba(37,211,102,.45), 0 22px 44px -28px rgba(31, 14, 26, .35); transform: translateY(-2px); }
.book__wa svg { width: 30px; height: 30px; flex: none; color: #25D366; }
.book__wa span { display: flex; flex-direction: column; font-size: .85rem; color: var(--tx-mute); }
.book__wa strong { color: var(--tx); font-weight: 500; font-size: .96rem; }

.form {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
  padding: clamp(26px, 3.4vw, 42px); border-radius: var(--r-lg);
  background: var(--paper); box-shadow: inset 0 0 0 1px var(--line), 0 30px 70px -40px rgba(31,14,26,.3);
}
.field { position: relative; }
.field--full { grid-column: 1 / -1; }
.field input, .field select, .field textarea {
  width: 100%; padding: 22px 16px 10px; border-radius: var(--r-sm);
  background: var(--bone); color: var(--tx);
  border: 1px solid var(--line);
  transition: border-color .3s ease, background-color .3s ease;
  appearance: none; -webkit-appearance: none;
}
.field textarea { resize: vertical; min-height: 92px; padding-top: 26px; }
.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236E5766' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; background-size: 17px;
  padding-right: 42px; cursor: pointer;
}
.field select option { background: var(--paper); color: var(--tx); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--accent); background: var(--paper);
  box-shadow: 0 0 0 3px rgba(173,30,135,.12);
}
.field label {
  position: absolute; left: 16px; top: 15px; pointer-events: none;
  font-size: .95rem; color: var(--tx-mute);
  transition: transform .3s var(--ease), font-size .3s var(--ease), color .3s ease;
  transform-origin: left top;
}
.field input:focus + label, .field textarea:focus + label,
.field input:not(:placeholder-shown) + label, .field textarea:not(:placeholder-shown) + label,
.field select:focus + label, .field select:valid + label {
  transform: translateY(-9px) scale(.74); color: var(--accent-deep);
}
.field.is-bad input, .field.is-bad select, .field.is-bad textarea { border-color: #E0655B; }
.err { display: block; min-height: 15px; font-size: .78rem; color: #B3261E; padding: 3px 4px 0; }

.consent { display: flex; gap: 11px; align-items: flex-start; font-size: .8rem; color: var(--tx-mute); cursor: pointer; }
.consent input {
  appearance: none; -webkit-appearance: none; flex: none;
  width: 19px; height: 19px; margin-top: 1px; border-radius: 5px; cursor: pointer;
  border: 1px solid rgba(31,14,26,.25); background: var(--paper);
  transition: all .3s ease;
}
.consent input:checked {
  background: var(--accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FFFFFF' stroke-width='3.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E") center/12px no-repeat;
  border-color: var(--accent);
}
.consent.is-bad input { border-color: #E0655B; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

.form .btn { grid-column: 1 / -1; margin-top: 6px; }
.btn__spin {
  display: none; width: 17px; height: 17px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.35); border-top-color: #FFFFFF;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.form.is-sending .btn__spin { display: block; }
.form.is-sending .btn { pointer-events: none; opacity: .8; }

.form__foot { grid-column: 1 / -1; font-size: .76rem; color: var(--tx-mute); text-align: center; }
.form__status { grid-column: 1 / -1; font-size: .88rem; text-align: center; }
.form__status:not(:empty) { padding: 13px 16px; border-radius: var(--r-sm); }
.form__status.is-ok  { background: rgba(22,140,70,.1);  color: #11703B; }
.form__status.is-bad { background: rgba(190,50,40,.09);  color: #A32F26; }

@media (max-width: 900px) { .book__grid { grid-template-columns: 1fr; } }
@media (max-width: 520px) { .form { grid-template-columns: 1fr; } }

/* ── Footer ──────────────────────────────────────────────────────────── */
.foot {
  background: var(--bone); color: var(--tx-mute);
  border-top: 1px solid var(--line);
  padding-block: clamp(48px, 6vw, 80px) 0;
}
.foot__grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: clamp(28px, 4vw, 56px); }
.foot__brand { display: flex; flex-direction: column; gap: 16px; align-items: flex-start; }
.foot__id { display: flex; align-items: center; gap: 14px; }
.foot__logo { width: 44px; height: auto; }
.foot__id span { font-family: var(--display); font-weight: 500; font-size: 1.5rem; line-height: 1.1; color: var(--tx); }
.foot__brand p { font-size: .84rem; max-width: 36ch; }
.foot__col { display: flex; flex-direction: column; gap: 10px; }
.foot__col h4 { font-family: var(--sans); font-size: .75rem; font-weight: 600; letter-spacing: .13em; text-transform: uppercase; color: var(--tx); margin-bottom: 4px; }
.foot__col a, .foot__col span { font-size: .88rem; transition: color .3s ease; }
.foot__col a:hover { color: var(--accent-deep); }
.foot__disclaim {
  margin-top: clamp(40px, 5vw, 64px); padding-top: 26px; border-top: 1px solid var(--line);
  font-size: .76rem; line-height: 1.65; max-width: 92ch;
}
.foot__base {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px;
  padding-block: 24px 28px; margin-top: 20px; border-top: 1px solid var(--line);
  font-size: .74rem;
}
/* The sign-off: the name set as large as the page is wide, cropped by the
   bottom edge so it reads as a ground rather than a heading. */
.foot { overflow: hidden; }
.foot__mega {
  margin: clamp(8px, 2vw, 24px) 0 0; padding-inline: var(--gut);
  font-family: var(--display); font-weight: 400; letter-spacing: -.04em;
  font-size: clamp(3.2rem, 14.8vw, 14.4rem); line-height: .8; white-space: nowrap;
  text-align: center; margin-bottom: -.12em; user-select: none;
}
.foot__mega em { font-style: italic; }
@media (max-width: 860px) { .foot__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .foot__grid { grid-template-columns: 1fr; } }

/* ── Mobile dock ─────────────────────────────────────────────────────── */
.dock {
  position: fixed; z-index: 90; left: 12px; right: 12px; bottom: 12px;
  display: none; gap: 8px; padding: 8px; border-radius: 100px;
  background: rgba(255,255,255,.9); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  box-shadow: 0 18px 44px -14px rgba(31,14,26,.28), inset 0 0 0 1px var(--line);
  transform: translateY(140%); transition: transform .55s var(--ease);
  padding-bottom: max(8px, env(safe-area-inset-bottom));
}
.dock.is-up { transform: none; }
.dock a {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 7px;
  padding: 12px 8px; border-radius: 100px; font-size: .82rem; font-weight: 500; color: var(--tx);
}
.dock svg { width: 17px; height: 17px; }
.dock__primary { background: linear-gradient(135deg, var(--accent-btn), var(--accent)); color: #FFFFFF !important; flex: 1.2; }
@media (max-width: 860px) {
  /* Visible from first paint rather than gated on scroll: on a phone this is
     the only CTA guaranteed to be on screen at all times. */
  .dock { display: flex; transform: none; }
  body { padding-bottom: 78px; }
}

/* ── Scroll reveal ───────────────────────────────────────────────────── */
[data-reveal] {
  opacity: 0; transform: translateY(26px);
  transition: opacity .9s var(--ease), transform .9s var(--ease);
  transition-delay: calc(var(--d, 0) * 90ms);
}
[data-reveal].is-in { opacity: 1; transform: none; }

/* ── Reduced motion ──────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
  [data-reveal] { opacity: 1; transform: none; }
  .ambient, .grain, .cursor-glow, .laser-sweep { display: none; }
  .marquee__track, .revmarq__track { animation: none; }
}

/* ══ MOTION LAYER ══════════════════════════════════════════════════════════
   Multi-speed parallax and line-mask reveals. Technique notes and the
   analysis of where they come from are in MOTION.md. Driven by motion.js. */

/* ── Parallax ────────────────────────────────────────────────────────────
   Promoted to their own layer so the per-frame transform never touches
   layout or paint. */
[data-px], [data-px-cover] > img { will-change: transform; }

/* A clipped frame with an oversized child.

   The image is 130% of the frame and pulled up by 15%, so it overhangs evenly
   top and bottom. That symmetric slack — 11.5% of the image's own height on
   each side — is exactly the travel budget the drift in motion.js is allowed
   to spend. Anchoring the image at the top instead would give it slack in one
   direction only, and drifting the other way would open a gap at the top of
   the frame. */
[data-px-cover] { overflow: hidden; position: relative; }
[data-px-cover] > img {
  position: absolute; top: -15%; left: 0;
  width: 100%; height: 130%; object-fit: cover; display: block;
}

/* Floating accent imagery — the layered pieces that move at their own speed
   against the section they sit in. */
.float {
  position: absolute; border-radius: 18px; overflow: hidden;
  box-shadow: 0 26px 60px -30px rgba(31, 14, 26, .35);
  pointer-events: none; z-index: 1;
}
.float img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── Line-mask reveal ────────────────────────────────────────────────────
   Each rendered line gets a clipping box; the inner span rises out of it.
   105% rather than 100% so descenders clear the mask edge. */
.ln { display: block; overflow: hidden; }
.ln__i {
  display: block; transform: translateY(105%);
  transition: transform 1.15s var(--ease-tk, cubic-bezier(.17,.84,.44,1));
  transition-delay: calc(var(--i, 0) * 110ms);
}
[data-lines].is-in .ln__i { transform: none; }
/* Measuring wrapper — only exists between split and rebuild. */
.ln__w { display: inline-block; }

@media (prefers-reduced-motion: reduce) {
  [data-px], [data-px-cover] > img { transform: none !important; will-change: auto; }
  /* Drop the overhang too — the -15% offset that pairs with it would leave a
     gap at the bottom of the frame once the drift is gone. */
  [data-px-cover] > img { top: 0; height: 100%; }
  .float { display: none; }
  .ln__i { transform: none; transition: none; }
}

/* ── Floating parallax layers ────────────────────────────────────────────
   The decorative pieces that give each section more than one speed. They
   live in the outer gutter and the section's vertical padding, never over
   copy, and they are the first thing dropped as the viewport narrows —
   below 1200px there is no gutter left to put them in.

   Deliberately quiet: reduced opacity and a soft shadow so they read as
   depth behind the content rather than as images competing with it. */
#botox, #laser, #facial, #doctor { overflow-x: clip; }

/* Anchored to the media column, not the section, and pushed into the empty
   space above and below the image — with align-items:center the shorter
   column has a deep well of whitespace at both ends, which is the only place
   on this layout genuinely free of copy. Anchoring here also means the
   flipped sections mirror for free.

   They bleed a little past the page edge; the section's overflow-x: clip
   catches that, and the crop reads as intentional. */
/* One inset per frame, laid over the photograph's lower corner like a print
   on a print. A paper border so it reads as placed, not as a stray image. */
.float--inset {
  width: 30%; aspect-ratio: 1 / 1; right: -6%; bottom: -12%; z-index: 2;
  border: 7px solid var(--paper); border-radius: 22px;
  box-shadow: 0 30px 60px -28px rgba(31, 14, 26, .45);
}
.deep--flip .float--inset { right: auto; left: -6%; }

@media (max-width: 1200px) { .float { display: none; } }

/* Fallback for a heading that carries inline markup — see the splitter's
   guard in motion.js. Reveals as one block instead of line by line. */
.ln-whole { display: block; opacity: 0; transform: translateY(28px);
  transition: opacity .9s var(--ease-tk, cubic-bezier(.17,.84,.44,1)),
              transform .9s var(--ease-tk, cubic-bezier(.17,.84,.44,1)); }
.ln-whole.is-in { opacity: 1; transform: none; }

/* ── Mochi, the mascot ───────────────────────────────────────────────────
   One drawing, every face: mochi.js sets data-pose on the SVG and these
   rules show that pose's eyes, mouth and effect. Blink, breathing, hops and
   sparkles are CSS, so they run on the compositor. Notes in MOCHI.md. */
.mochi { display: block; width: 100%; height: 100%; overflow: visible; }
.mochi .m-shadow { fill: var(--accent-deep); opacity: .12; transform-origin: 60px 104px; }
.mochi .m-body   { transform-origin: 60px 102px; transition: rotate .45s var(--ease); }
.mochi .m-skin   { fill: #FFFFFF; stroke: var(--accent-deep); stroke-width: 3; }
.mochi .m-belly  { fill: var(--blush); }
.mochi .m-shine  { fill: none; stroke: var(--blush); stroke-width: 5; stroke-linecap: round; }
.mochi .m-cheek  { fill: var(--accent-hi); opacity: .35; transition: opacity .35s ease; }
.mochi .m-face   { transform: translate(var(--lx, 0px), var(--ly, 0px)); }
.mochi .m-eyes ellipse, .mochi .m-eyes circle, .mochi .m-o { fill: #3A0B2E; }
.mochi .m-eyes .m-glint { fill: #FFFFFF; }
.mochi .m-line   { fill: none; stroke: #3A0B2E; stroke-width: 2.8; stroke-linecap: round; }
.mochi .m-grin   { fill: var(--accent-deep); }
.mochi .m-spark  { fill: var(--accent-hi); transform-origin: 100px 33.5px; }
.mochi .m-drop   { fill: var(--brand-cyan); transform-origin: 100px 52px; }
.mochi .m-z      { fill: none; stroke: var(--accent); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }

/* Pose map: everything optional starts hidden */
.mochi .m-eyes, .mochi .m-mouth, .mochi .m-fx { display: none; }
.mochi:is([data-pose="idle"], [data-pose="happy"], [data-pose="shy"]) .m-happy,
.mochi:is([data-pose="look"], [data-pose="think"], [data-pose="bounce"]) .m-open,
.mochi[data-pose="shock"] .m-wide,
.mochi[data-pose="sleepy"] .m-shut,
.mochi:is([data-pose="idle"], [data-pose="shock"], [data-pose="sleepy"]) .m-o,
.mochi:is([data-pose="look"], [data-pose="bounce"], [data-pose="shy"]) .m-smile,
.mochi[data-pose="happy"] .m-grin,
.mochi[data-pose="think"] .m-hmm,
.mochi[data-pose="happy"] .m-spark,
.mochi[data-pose="shock"] .m-drop,
.mochi[data-pose="sleepy"] .m-z { display: inline; }
.mochi[data-pose="shy"] .m-cheek { opacity: .75; }
.mochi[data-pose="think"] .m-body { rotate: -7deg; }
.mochi[data-pose="sleepy"] .m-body { rotate: 5deg; }

@media (prefers-reduced-motion: no-preference) {
  .mochi .m-body { animation: m-breathe 3s ease-in-out infinite; }
  .mochi[data-pose="sleepy"] .m-body { animation-duration: 5s; }
  .mochi .m-open { animation: m-blink 4.4s infinite; transform-origin: 60px 68px; }
  .mochi:is([data-pose="happy"], [data-pose="bounce"]) .m-body { animation: m-hop .56s cubic-bezier(.33, 1, .68, 1) infinite; }
  .mochi:is([data-pose="happy"], [data-pose="bounce"]) .m-shadow { animation: m-shade .56s cubic-bezier(.33, 1, .68, 1) infinite; }
  .mochi[data-pose="bounce"] :is(.m-body, .m-shadow) { animation-duration: .36s; }
  .mochi .m-spark { animation: m-twinkle 1.1s ease-in-out infinite; }
  .mochi .m-drop  { animation: m-drip 1.2s ease-in infinite; }
  .mochi .m-z     { animation: m-float 2.6s ease-in-out infinite; }
  .mochi .m-z2    { animation-delay: -1.3s; }
}
@keyframes m-breathe { 50% { transform: scale(1.03, .965); } }
@keyframes m-blink   { 0%, 93%, 100% { transform: scaleY(1); } 96% { transform: scaleY(.1); } }
@keyframes m-hop {
  0%, 100% { transform: translateY(0) scale(1.07, .92); }
  45%      { transform: translateY(-14px) scale(.96, 1.05); }
}
@keyframes m-shade   { 45% { transform: scale(.7); opacity: .06; } }
@keyframes m-twinkle { 50% { transform: scale(.5) rotate(45deg); opacity: .5; } }
@keyframes m-drip    { 0% { transform: translateY(-4px); opacity: 0; } 30% { opacity: 1; } 100% { transform: translateY(6px); opacity: 0; } }
@keyframes m-float   { 0% { transform: translate(0, 4px); opacity: 0; } 30% { opacity: 1; } 100% { transform: translate(4px, -8px); opacity: 0; } }

/* The companion. Sized and moved by mochi.js; never takes clicks except
   on the drawing itself, and only while it's on screen. */
.mochi-pal {
  position: fixed; left: 0; top: 0; z-index: 95;
  width: 76px; height: 76px; transform-origin: 0 0;
  pointer-events: none; will-change: transform;
}
.mochi-pal__show {
  width: 100%; height: 100%; opacity: 0; transform: translateY(24px) scale(.6);
  transform-origin: 50% 90%; transition: opacity .5s var(--ease), transform .6s var(--ease);
}
.mochi-pal.is-shown .mochi-pal__show { opacity: 1; transform: none; }
.mochi-pal__tip { width: 100%; height: 100%; transform-origin: 50% 88%; }
.mochi-pal__pop {
  width: 100%; height: 100%; transform-origin: 50% 86%;
  cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
.mochi-pal.is-shown .mochi-pal__pop { pointer-events: auto; }

.mochi-say {
  position: fixed; left: 0; top: 0; z-index: 96;
  width: max-content; max-width: min(250px, calc(100vw - 24px));
  padding: 14px 34px 14px 16px; border-radius: 18px;
  background: var(--paper); color: var(--tx); font-size: .86rem; line-height: 1.45;
  box-shadow: inset 0 0 0 1px var(--line), 0 18px 40px -18px rgba(31,14,26,.4);
  opacity: 0; scale: .92; transform-origin: var(--tail, 50%) 100%;
  transition: opacity .28s var(--ease), scale .4s var(--ease);
}
.mochi-say.is-open { opacity: 1; scale: 1; }
.mochi-say::after {
  content: ""; position: absolute; left: var(--tail, 50%); bottom: -6px;
  width: 12px; height: 12px; margin-left: -6px; rotate: 45deg;
  background: var(--paper); box-shadow: inset -1px -1px 0 var(--line);
}
.mochi-say__cta {
  display: inline-flex; margin-top: 10px; padding: 8px 14px; border-radius: 100px;
  background: linear-gradient(180deg, var(--accent-btn), var(--accent));
  color: #FFFFFF; font-weight: 600; font-size: .8rem;
}
.mochi-say__x {
  position: absolute; top: 6px; right: 8px; width: 24px; height: 24px;
  border: 0; background: none; color: var(--tx-mute); font-size: 1.1rem; line-height: 1; cursor: pointer;
}

/* The seat on the booking form: Mochi flies over and sits on the card's
   top edge. Empty until then; it only marks the spot. */
.form { position: relative; }
.mochi-seat {
  --seat: 96px;
  position: absolute; right: clamp(20px, 4vw, 44px); top: calc(var(--seat) * -.9 + 1px);
  width: var(--seat); height: var(--seat); pointer-events: none;
}
@media (max-width: 860px) { .mochi-seat { --seat: 72px; } }

/* ── Two-layer flip (ported from Lakova) ─────────────────────────────────
   Two photographs stacked in one frame. motion.js wipes the upper one away
   with a scrubbed clip-path, uncovering a different photograph underneath.
   This resting state is the no-JS state: the upper photo fully covers, so if
   the motion layer never runs you get a normal photograph, not a half-wiped
   one. Both images sit at scale(1.2): 10% of overhang past each edge, which
   is the room the opposing drift in motion.js is allowed to spend. */
.flip { position: relative; overflow: hidden; isolation: isolate; background: var(--blush); }
.flip__layer { position: absolute; inset: 0; overflow: hidden; }
.flip__layer img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.2); will-change: transform;
}
.flip__layer--up { z-index: 1; clip-path: inset(0% 0% 0% 0%); will-change: clip-path; }
/* Without the motion, show where the animation would have ended. */
@media (prefers-reduced-motion: reduce) {
  .flip__layer img { transform: none; will-change: auto; }
  .flip__layer--up { display: none; }
}
