/* ============================================================
   WOWO · Wax On Wax Off — v3 "Light Editorial"
   2026-07-25

   The change from v2 in one line:
   cream stops being the page and becomes a tint; matcha stops
   being decoration and becomes one deliberate move.

     FIELD   near-white          (the page, ~60% of it)
     TINT    cream               (alternating bands only)
     INK     near-black          (type, footer)
     MATCHA  reserved            (primary CTAs + ONE deep band)

   Written as a single clean cascade. v2 had grown three stacked
   override blocks fighting each other; do not re-patch this file
   at the bottom, edit the rule in place.
   ============================================================ */

/* ---- Self-hosted type: Geist everywhere, Trajan Pro for the wordmark only ---- */
@font-face { font-family: 'Geist'; src: url('fonts/Geist-Regular.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Geist'; src: url('fonts/Geist-Medium.woff2') format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Geist'; src: url('fonts/Geist-SemiBold.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'Geist'; src: url('fonts/Geist-Bold.woff2') format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: 'Trajan Pro'; src: url('fonts/TrajanPro-Regular.woff2') format('woff2'); font-weight: 400 700; font-style: normal; font-display: swap; }

:root {
  /* --- the field ---
     2026-07-27: cream and beige removed entirely at Cybil's call. The bands are
     now neutral grey, so warmth only ever comes from the photography. Nothing
     in the palette carries a yellow or brown cast any more. */
  --paper:       #FFFFFF;   /* default page. true white, no warm bias */
  --paper-lift:  #FFFFFF;   /* cards; separated by a hairline, not a tone */
  --tint:        #F4F4F5;   /* neutral grey, alternating bands only */
  --tint-deep:   #E8E8EA;   /* rare, for a card edge on tint */

  /* --- ink --- */
  --ink:         #12110F;   /* near-black. THIS is what kills the dated feel */
  --ink-soft:    #52525B;   /* body copy. was #57534C, still warm-brown */
  --ink-mute:    #8A8A93;   /* eyebrows, captions. was #8A857C, a warm grey */
  --line:        rgba(18, 17, 15, 0.10);
  --line-soft:   rgba(18, 17, 15, 0.06);

  /* --- the action colour (2026-07-27) ---
     Matcha is retired. It read heavy against a white field, and with the beige
     gone it was the last loud thing on the page. Every CTA is now soft cherry
     blossom, the brand's own flower, doing the job the reference site gives its
     pastel blue. Type on it is a deep blossom ink at 7.4:1, so a pastel button
     still passes AA. --matcha* tokens are gone; do not reintroduce them. */
  --cta:         #F7DCE4;   /* pastel cherry blossom. secondary / read-more */
  --cta-hover:   #EFC4D1;
  --cta-ink:     #6B2B3D;   /* type ON blossom */
  /* Primary actions (Book / Join / Gift) are BLACK. Blossom everywhere flattened
     the hierarchy: the primary read the same weight as a read-more link. Black
     for the ask, blossom for the invitation. Cybil's call, 2026-07-28. */
  --cta-solid:       #12110F;
  --cta-solid-hover: #2E2A26;
  --cta-solid-ink:   #FFFFFF;
  --sakura:      #F7DCE4;   /* same value, kept for accent marks */
  --sakura-deep: #EFC4D1;
  --sakura-ink:  #6B2B3D;

  --serif: 'Geist', system-ui, sans-serif;
  --sans:  'Geist', system-ui, sans-serif;
  --jp:    'Noto Serif JP', serif;

  --maxw: 1200px;
  --gut:  clamp(1.5rem, 5vw, 4.5rem);
  /* 2026-07-27: 7rem was still too generous. Cybil: "more scrolling when it's
     that large". Space should separate sections, not pad them out. Section gap
     now tops out at 4.5rem, and blocks that already carry an inset panel
     (founders, offers) sit tighter again. */
  --space: clamp(1.7rem, 1.2rem + 1.5vw, 2.7rem);
  --radius: 16px;
  --radius-sm: 12px;
  --ribbon-h: 44px;
  --dur: 600ms;
  --dur-fast: 200ms;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 120px; -webkit-font-smoothing: antialiased; }
body {
  font-family: var(--sans);
  font-size: clamp(1rem, 0.96rem + 0.25vw, 1.09rem);
  line-height: 1.65;
  color: var(--ink-soft);
  background: var(--paper);
  overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }

/* Editorial type: bigger, tighter, blacker than v2 */
h1, h2, h3 {
  font-family: var(--serif); font-weight: 600; color: var(--ink);
  line-height: 1.02; letter-spacing: -0.03em;
}
h3 { letter-spacing: -0.02em; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding-inline: var(--gut); }

/* Eyebrow: NO longer matcha. Muted ink, so matcha means "act". */
.eyebrow {
  font-family: var(--sans); font-weight: 600; font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.22em; color: var(--ink-mute);
  display: inline-flex; align-items: center; gap: 0.85em;
}
.eyebrow.center { justify-content: center; }

/* the giant kanji watermarks stay retired */
.kanji { display: none !important; }

.whisper {
  display: inline-flex; align-items: center; gap: 0.6em;
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-mute); font-weight: 600;
}
.whisper .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--sakura-deep); flex: none; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 0.55em;
  font-family: var(--sans); font-weight: 600; font-size: 0.88rem; letter-spacing: 0.01em;
  padding: 1.05rem 2rem; border-radius: 999px; cursor: pointer;
  border: 1px solid transparent;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.btn .arrow { transition: transform var(--dur-fast) var(--ease); }
.btn:hover .arrow { transform: translateX(5px); }
/* .btn--matcha keeps its class name so every page and landing page picks the
   change up at once. It is no longer matcha and no longer blossom: it is the
   PRIMARY, and the primary is black. Dark surfaces override it below. */
.btn--matcha { background: var(--cta-solid); color: var(--cta-solid-ink); }
.btn--matcha:hover { background: var(--cta-solid-hover); transform: translateY(-2px); }
/* Header sits transparent over the dark hero until you scroll, where a black
   pill would vanish. White at the top, black once the header goes solid. */
header:not(.scrolled) .nav-links .btn--matcha { background: var(--paper); color: var(--ink); }
header:not(.scrolled) .nav-links .btn--matcha:hover { background: #fff; }
/* ...but the open mobile panel is paper, so white-on-white would disappear. */
header .nav-links.open .btn--matcha { background: var(--cta-solid); color: var(--cta-solid-ink); }
header .nav-links.open .btn--matcha:hover { background: var(--cta-solid-hover); }
.btn--outline { background: transparent; color: var(--ink); border-color: var(--line); }
.btn--outline:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.btn--cream { background: var(--paper); color: var(--ink); }
.btn--cream:hover { background: #fff; transform: translateY(-2px); }
.btn--sakura { background: var(--cta); color: var(--cta-ink); }
.btn--sakura:hover { background: var(--cta-hover); transform: translateY(-2px); }

/* ---------- focus-visible ---------- */
a:focus-visible, button:focus-visible, summary:focus-visible, .book-chip:focus-visible {
  outline: 2px solid var(--ink); outline-offset: 3px; border-radius: 4px;
}
.visiting a:focus-visible, .visiting button:focus-visible,
.hero a:focus-visible, footer a:focus-visible { outline-color: var(--paper); }

/* ---------- booking cluster ---------- */
.booking { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.3rem; }
.booking .btn.btn--matcha { background: var(--cta-hover); color: var(--cta-ink); }
.booking .btn.btn--matcha:hover { background: var(--cta); }
.booking .book-chip { border-color: #6B7F58; color: #59684A; }
.booking .book-chip .badge { background: #6B7F58; }
.booking .book-chip:hover { border-color: #59684A; }
.book-chip .badge--whatsapp, .booking .book-chip .badge--whatsapp { background: #25D366; }
.book-chip .badge--whatsapp svg { display: block; }
.booking__alt { display: inline-flex; align-items: center; gap: 0.7rem; font-size: 0.82rem; color: var(--ink-mute); }
.booking__alt .lbl { font-weight: 600; }
.book-chip {
  display: inline-flex; align-items: center; gap: 0.5em; font-weight: 600; font-size: 0.84rem;
  color: var(--ink); padding: 0.6em 1em; border: 1px solid var(--line);
  border-radius: 999px; transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.book-chip .badge {
  width: 22px; height: 22px; border-radius: 50%; background: var(--ink); color: #fff;
  display: grid; place-items: center; font-size: 0.62rem; font-weight: 700;
}
.book-chip:hover { border-color: var(--ink); }

/* ---------- top ribbon (evergreen gift strip) ---------- */
.hero__fd {
  position: fixed; inset: 0 0 auto 0; z-index: 200;
  background: var(--ink); color: rgba(255,255,255,0.92);
  display: flex; align-items: center; justify-content: center; gap: 0.9rem; flex-wrap: wrap;
  padding: 0.5rem var(--gut); min-height: var(--ribbon-h);
  font-size: 0.8rem; text-align: center;
}
.hero__fd, .hero__fd:hover, .hero__fd:focus { background: var(--ink); }
.hero__fd-text { font-weight: 400; }
.hero__fd-tag { font-weight: 700; text-transform: uppercase; letter-spacing: 0.16em; font-size: 0.68rem; color: #fff; margin-right: 0.55rem; }
.hero__fd-tag::after { content: "·"; margin-left: 0.55rem; opacity: 0.45; }
.hero__fd-cta { display: inline-flex; align-items: center; gap: 0.4em; white-space: nowrap; font-weight: 600; font-size: 0.82rem; color: #fff; border-bottom: 1px solid rgba(255,255,255,0.5); padding-bottom: 1px; }
.hero__fd:hover .arrow { transform: translateX(4px); }
.hero__fd .arrow { transition: transform var(--dur-fast) var(--ease); }

/* ---------- nav ---------- */
header {
  position: fixed; inset: var(--ribbon-h) 0 auto 0; z-index: 100;
  transition: background var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
header.scrolled {
  background: color-mix(in oklab, var(--paper) 72%, transparent);
  -webkit-backdrop-filter: blur(22px) saturate(1.4); backdrop-filter: blur(22px) saturate(1.4);
  box-shadow: 0 1px 0 var(--line-soft);
}
.nav { display: flex; align-items: center; justify-content: space-between; padding-block: 1.1rem; }
.brand { font-family: 'Trajan Pro', serif; font-weight: 700; letter-spacing: 0.22em; font-size: 0.9rem; color: #fff; }
.nav-links { display: flex; align-items: center; gap: 1.9rem; }
.nav-links a.navlink { font-size: 0.85rem; letter-spacing: 0.01em; color: #fff; position: relative; }
.nav-links a.navlink::after {
  content: ""; position: absolute; left: 0; bottom: -5px; width: 0; height: 1.5px;
  background: currentColor; transition: width var(--dur) var(--ease);
}
.nav-links a.navlink:hover::after { width: 100%; }
header.scrolled .brand, header.scrolled .nav-links a.navlink { color: var(--ink); }
header.scrolled .nav-toggle span { background: var(--ink); }

.nav-toggle { display: none; background: none; border: 0; cursor: pointer; width: 42px; height: 42px; flex-direction: column; justify-content: center; align-items: center; gap: 5px; padding: 8px; margin-left: auto; }
.nav-toggle span { display: block; height: 2px; width: 24px; background: #fff; transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease); }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 940px) {
  .nav-toggle { display: flex; }
  .nav-links {
    position: absolute; top: 100%; left: 0; right: 0; z-index: 250;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--paper); border-top: 1px solid var(--line-soft);
    max-height: 0; overflow: hidden; opacity: 0; visibility: hidden;
    padding: 0 var(--gut);
    transition: max-height var(--dur) var(--ease), opacity var(--dur) var(--ease), padding var(--dur) var(--ease);
  }
  .nav-links.open {
    max-height: 80vh; opacity: 1; visibility: visible; padding: 1.1rem var(--gut) 1.4rem;
    box-shadow: 0 18px 30px -16px rgba(18,17,15,0.28);
  }
  header .nav-links a.navlink,
  header.scrolled .nav-links a.navlink { color: var(--ink); }
  .nav-links a.navlink { display: block; width: 100%; padding: 0.95rem 0; font-size: 1rem; border-bottom: 1px solid var(--line-soft); }
  .nav-links.open a.navlink:first-of-type { padding-top: 0.3rem; }
  .nav-links a.navlink::after { display: none; }
  .nav-links .btn--matcha { margin-top: 1.1rem; width: 100%; justify-content: center; }
}

/* ---------- hero ---------- */
.hero { position: relative; min-height: 100svh; display: grid; align-content: end; background: var(--ink); overflow: hidden; }
.hero__bg { position: absolute; inset: 0; z-index: 0; }
/* mirrored so the subject sits RIGHT and the headline never crosses her face */
.hero__bg img { width: 100%; height: 100%; object-fit: cover; object-position: 62% 32%; transform: scaleX(-1); filter: saturate(1.06) contrast(1.04); }
/* NO MIRROR on this clip, unlike the still above it. The still is a fixed frame
   with the subject on the left, so scaleX(-1) was the only way to clear the
   headline. In this footage she WALKS, tracking centre to centre-right for the
   whole 16s, which already leaves the left third open. Mirroring would drag her
   straight into the copy.

   20% is measured against the two tightest frames in the loop, t=0 and t=9,
   where she tracks closest to the copy. At 58% the lead paragraph's last line
   ran into her arm; 20% shows more of the source's left edge, which seats her
   clear of both the headline and the lead for the whole 16s. */
.hero__bg .hero__video {
  width: 100%; height: 100%; object-fit: cover; object-position: 20% 42%;
  filter: saturate(1.06) contrast(1.04);
  /* The poster is letterboxed by default while the video buffers, which flashes
     bars before playback. object-fit covers the poster too. */
  display: block;
}
/* Reduced motion is handled by PAUSING the video in JS, not by hiding it and
   swapping in a CSS background. A background image cannot be mirrored, and the
   mirror is load-bearing here: unmirrored, the subject sits under the headline.
   A paused video shows its poster, which the same transform mirrors correctly,
   so the reduced-motion view is the identical frame, just still. */
/* 2026-07-29: the scrim is GONE. Cybil: "do not add overlay as the video goes
   dark on one side". The 90deg gradient below was blacking out the left third to
   buy contrast for the headline, which is exactly the darkening he is objecting
   to. Legibility now comes from a shadow on the TYPE (see .hero__inner), which
   darkens the letters instead of the footage. */
.hero__bg::after { content: none; }
/* The desktop scrim, which blacked out the left third, is removed for the same
   reason. Nothing replaces it on the image. */
/* Contrast without touching the picture. With the scrim removed the copy sits
   straight on bright sand and surf, so each text layer carries its own shadow.
   A shadow tracks the glyph edges, so it buys legibility over the few hundred
   pixels the letters actually occupy rather than dimming the whole left third. */
.hero__inner :is(h1, .hero__lead, .hero__rating, .hero__whisper) {
  text-shadow: 0 1px 2px rgba(12,11,10,.42), 0 2px 18px rgba(12,11,10,.55);
}
.hero__inner {
  position: relative; z-index: 3;
  padding: calc(var(--ribbon-h) + 6rem) var(--gut) clamp(2.5rem, 5vw, 5rem);
}
.hero__inner > * { max-width: 46ch; }
.hero__inner .eyebrow { color: rgba(255,255,255,0.78); }
/* Sized so the longest line clears the subject on the right at every width.
   At 1440 the headline must stop by ~560px; she starts around 610px. */
.hero__inner h1 {
  color: #fff; font-size: clamp(2.8rem, 1.4rem + 4vw, 4.9rem);
  line-height: 0.96; letter-spacing: -0.04em; max-width: 13ch; margin: 1rem 0 1.1rem;
}
.hero__inner h1 em { font-style: normal; color: var(--sakura); }
/* "Get Beach / READY". READY drops to its own line and comes in larger, so the
   payoff word carries the weight rather than the setup. display:block does the
   line break, so there is no <br> to keep in sync with the type size. The
   tighter line-height closes the gap the bigger word would otherwise open. */
.hero__h1 em {
  display: block;
  font-size: 1.42em;
  line-height: 0.88;
  letter-spacing: -0.045em;
}
.hero__lead { color: rgba(255,255,255,0.9); max-width: 40ch; font-size: clamp(1.05rem, 1rem + 0.45vw, 1.28rem); line-height: 1.55; }
.hero .booking__alt { color: rgba(255,255,255,0.8); }
.hero .book-chip { color: #fff; border-color: rgba(255,255,255,0.4); }
.hero .book-chip:hover { border-color: #fff; }
.hero__rating { margin-top: 1.2rem; color: #fff; font-weight: 600; font-size: 0.86rem; opacity: 0.92; }
/* opt out of the 46ch cap so the three-part line doesn't wrap and orphan its dot */
.hero__whisper { color: rgba(255,255,255,0.75); margin-top: 1.1rem; max-width: none; }
.hero__stamp {
  position: absolute; right: clamp(1.2rem, 4vw, 2.6rem); top: calc(var(--ribbon-h) + 78px); z-index: 3;
  width: 48px; height: 48px; display: grid; place-items: center;
  font-family: var(--jp); font-size: 1.45rem; color: #fff;
  background: transparent; border: 1px solid rgba(255,255,255,0.45); border-radius: 50%; opacity: 0.85;
}

@media (max-width: 880px) {
  /* z-index: the hero's gift strip (.hero__fd, order:-1) was painting over the
     OPEN burger menu and swallowing the first nav item. The header owns the
     menu, so it has to win the stack. */
  /* sticky, NOT relative: relative scrolled the nav away entirely, so on a
     phone there was no way back to the menu without scrolling to the top. The
     gift ribbon still scrolls off, the nav does not. */
  header { position: sticky; top: 0; z-index: 400; inset: 0 0 auto 0; background: var(--paper); box-shadow: 0 1px 0 var(--line-soft); }
  .nav-links.open { background: var(--paper); }
  .brand, .nav-links a.navlink { color: var(--ink); }
  .nav-toggle span { background: var(--ink); }

  /* Mobile hero is an OVERLAY, same as desktop. It used to stack: video on top,
     copy in a black block underneath. That block ate most of a phone screen and
     read as a separate panel rather than a hero. The video now fills the whole
     section and the copy sits over the sand at bottom-left, clear of her. */
  .hero { position: relative; display: flex; flex-direction: column; min-height: 76svh; }
  /* 2026-08-15: most traffic here arrives from social, straight onto this hero --
     the gift ribbon ate a big share of a phone's first screen before they ever
     saw the studio. Desktop keeps it (position: fixed, untouched by this query);
     mobile drops it entirely rather than shrinking it, so the video is the very
     first thing a visitor sees. */
  .hero__fd { display: none; }
  /* inset 0 puts the video behind the gift ribbon too, which is fine: the
     ribbon is opaque ink and covers it. */
  .hero__bg { position: absolute; inset: 0; height: auto; order: 0; }
  /* Same left-of-model crop as desktop. A LOWER percentage shows more of the
     scene to her left, which pushes her toward the right of the frame and keeps
     the copy column clear. 58% centred her straight over the headline. */
  .hero__bg .hero__video { object-position: 44% 42%; }
  .hero__inner { order: 1; margin-top: auto; background: transparent;
                 padding: 1.6rem var(--gut) 2.2rem; }
  /* Hold the copy in a left-hand column. Unconstrained, the lead and the
     whisper ran the full width and crossed onto her, where white type over a
     lit bikini has no contrast left to spend. */
  .hero__inner > * { max-width: 22ch; }
  /* Smaller than the desktop clamp: at 2.8rem "Get Beach" filled a 390px screen
     edge to edge and READY, 1.42x larger again, overflowed it. */
  .hero__inner h1 { font-size: clamp(2rem, 1rem + 5.4vw, 2.9rem); margin: 0.5rem 0 0.7rem; }
  .hero__h1 em { font-size: 1.28em; }
  .hero__lead { font-size: 0.95rem; line-height: 1.45; max-width: 21ch; }
  .hero__rating { margin-top: 0.7rem; font-size: 0.78rem; }
  /* Cybil's call, 2026-07-29: the three-part whisper wrapped to three lines on
     a phone and there was no width left to keep them off her. Dropped on mobile
     only, which lets the rest of the copy sit in a narrower column clear of her.
     It still runs on desktop, where the room exists. */
  .hero__whisper { display: none; }
  .hero__stamp { top: auto; bottom: auto; }
}

/* ============================================================
   BAND RHYTHM — this is the whole redesign.
   White is the default. Cream appears only on .block--cream.
   Exactly ONE band is deep matcha (.visiting).
   ============================================================ */
/* NB: no `section` qualifier on the base — an element-qualified selector would
   out-specify the tint modifiers below and flatten every band to white.
   Base first, tint modifiers last. */
.block { padding-block: var(--space); background: var(--paper); }
/* Two blocks on the same field stack padding-bottom onto padding-top and open a
   trough twice the intended size. Collapse the join. */
.block + .block { padding-top: 0; }
.block--cream, .gift, .pricing, .moment, .reviews, .location { background: var(--paper); }

/* Cream earns TWO bands on the whole page, and only where content fills the
   field — the membership cards, and the FAQ list. Everywhere else is white.
   (Tinting all five .block--cream sections left thin sections like the three
   pillars floating in a large empty cream field, which read as beige-heavy.) */
#smooth-season, .faq { background: var(--tint); }

.head { max-width: 54ch; margin-bottom: clamp(1.4rem, 0.9rem + 1.6vw, 2.4rem); }
.head.center { margin-inline: auto; text-align: center; }
.head h2 { font-size: clamp(2.1rem, 1.4rem + 2.6vw, 3.6rem); margin: 0.6rem 0 0.8rem; }
.lead-p { font-size: clamp(1.08rem, 1rem + 0.5vw, 1.3rem); color: var(--ink-soft); line-height: 1.6; }

/* ---------- gift ---------- */
.gift-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.25rem, 3vw, 2rem); margin-top: clamp(2rem, 4vw, 3rem);
  max-width: 860px; margin-inline: auto;
}
/* Section needs a wash behind it or the glass cards below have nothing to
   blur against — same pattern as .founders-panel / .offer-panel. */
.block.gift { background: linear-gradient(135deg, var(--tint) 0%, var(--paper) 100%); }
.gift-card {
  position: relative; display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: clamp(2.2rem, 4vw, 3.2rem) 1.75rem;
  border-radius: var(--radius);
  box-shadow: 0 1px 2px rgba(18,17,15,.03), 0 24px 48px -32px rgba(18,17,15,.35);
}
/* 2026-08-10, third pass: flat #f5f5ff → the same frosted-glass gradient used
   on the founders panel and the offer panel, so all three "moment" cards on
   this page share one glass language. Base card keeps a matcha outline
   (matcha is otherwise retired site-wide, see the action-colour token note
   above; this is a deliberate one-off exception at Cybil's direct call), the
   feature card a blossom outline. Text stays plain ink on both. */
.gift-card {
  background: linear-gradient(135deg, rgba(255,255,255,0.62), rgba(255,255,255,0.32));
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  backdrop-filter: blur(22px) saturate(160%);
  border: 1.5px solid #8FA37C;
}
.gift-card--feature { border: 1.5px solid var(--cta-hover); color: var(--ink); }
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .gift-card { background: #f5f5ff; }
}
.gift-card__eyebrow { font-weight: 600; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.22em; color: var(--ink-mute); }
.gift-card--feature .gift-card__eyebrow { color: var(--ink-mute); opacity: 1; }
.gift-card__value {
  font-family: var(--serif); font-weight: 600; line-height: 0.95; letter-spacing: -0.04em;
  font-size: clamp(3.4rem, 2.2rem + 4vw, 5rem); color: var(--ink); margin: 0.7rem 0 0.3rem;
}
.gift-card--feature .gift-card__value { color: var(--ink); }
.gift-card__value span {
  display: inline-block; font-family: var(--sans); font-weight: 600; letter-spacing: 0.2em;
  font-size: 0.66rem; text-transform: uppercase; vertical-align: super; margin-left: 0.4em; color: var(--ink-mute);
}
.gift-card--feature .gift-card__value span { color: var(--ink-mute); }
.gift-card__pay { font-size: 1.05rem; color: var(--ink-soft); }
.gift-card--feature .gift-card__pay { color: var(--ink-soft); opacity: 1; }
.gift-card__pay strong { font-weight: 700; color: var(--ink); }
.gift-card--feature .gift-card__pay strong { color: var(--ink); }
.gift-card__back {
  display: inline-block; margin-top: 0.8rem; padding: 0.32rem 0.9rem;
  background: var(--tint); color: var(--ink); border-radius: 999px;
  font-weight: 700; font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
}
.gift-card__btn { margin-top: 1.7rem; }
/* Experiment, Cybil 2026-08-10: colour-match each button to its card's
   outline instead of the usual black — just to see how it reads. Not the
   standing black-for-primary-actions rule, revert if it doesn't land. */
.gift-card:not(.gift-card--feature) .gift-card__btn { background: #6B7F58; color: #fff; }
.gift-card:not(.gift-card--feature) .gift-card__btn:hover { background: #59684A; }
.gift-card--feature .gift-card__btn { background: var(--cta-hover); color: var(--cta-ink); }
.gift-card--feature .gift-card__btn:hover { background: var(--cta); }
.gift-note { text-align: center; max-width: 58ch; margin: clamp(1.2rem, 1.8vw, 1.7rem) auto 0; font-size: 0.9rem; color: var(--ink-mute); }

/* ---------- smooth season / rewards ---------- */
.ss-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.25rem, 3vw, 2rem); margin-top: clamp(2rem, 4vw, 3rem);
  max-width: 960px; margin-inline: auto; align-items: stretch;
}
.ss-card {
  position: relative; display: flex; flex-direction: column;
  padding: clamp(2rem, 3.5vw, 2.9rem);
  background: var(--paper-lift); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 1px 2px rgba(18,17,15,.03), 0 24px 48px -32px rgba(18,17,15,.35);
}
.ss-card--feature { background: var(--ink); border-color: var(--ink); }
.ss-card__eyebrow { font-weight: 600; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.22em; color: var(--ink-mute); }
.ss-card--feature .ss-card__eyebrow { color: rgba(255,255,255,0.55); }
.ss-card__title { font-family: var(--serif); font-weight: 600; line-height: 1.05; font-size: clamp(1.7rem, 1.2rem + 1.6vw, 2.25rem); margin: 0.7rem 0 0.5rem; }
.ss-card--feature .ss-card__title { color: #fff; }
.ss-card__lead { color: var(--ink-soft); font-size: 0.98rem; line-height: 1.55; }
.ss-card--feature .ss-card__lead { color: rgba(255,255,255,0.78); }
.ss-card__price { font-family: var(--serif); font-weight: 600; line-height: 1; letter-spacing: -0.03em; font-size: clamp(2.2rem, 1.6rem + 2vw, 3rem); color: var(--ink); margin: 1.1rem 0 0; }
.ss-card--feature .ss-card__price { color: #fff; }
.ss-card__price small { font-family: var(--sans); font-size: 0.85rem; font-weight: 500; letter-spacing: 0; color: var(--ink-mute); }
.ss-card--feature .ss-card__price small { color: rgba(255,255,255,0.6); }
.ss-card__perks { list-style: none; margin: 1.4rem 0 0; padding: 0; display: grid; gap: 0.65rem; font-size: 0.95rem; color: var(--ink-soft); }
.ss-card__perks li { display: flex; gap: 0.7rem; align-items: flex-start; }
.ss-card__perks li::before { content: ""; flex: none; width: 5px; height: 5px; margin-top: 0.62em; border-radius: 50%; background: var(--ink); }
.ss-card--feature .ss-card__perks { color: rgba(255,255,255,0.82); }
.ss-card--feature .ss-card__perks li::before { background: rgba(255,255,255,0.55); }
.ss-card__cta { margin-top: auto; padding-top: 1.8rem; }
.ss-card__cta .btn { width: 100%; justify-content: center; }
.ss-card--feature .ss-card__cta .btn--matcha { background: var(--cta); color: var(--cta-ink); }
.ss-card--feature .ss-card__cta .btn--matcha:hover { background: var(--cta-hover); }

@media (max-width: 620px) {
  .gift-grid { grid-template-columns: 1fr; max-width: 380px; }
  .ss-grid { grid-template-columns: 1fr; max-width: 420px; }
}

/* ---------- pricing / service cards ---------- */
.pricing .wrap { padding-block: clamp(3rem, 5vw, 5rem); }
.pricing__eyebrow { display: block; margin-bottom: 1.6rem; }
.pricing__grp { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1rem, 2vw, 1.5rem); }
.pi {
  position: relative; display: flex; flex-direction: column;
  background: var(--paper-lift); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; padding: 0.5rem 0.5rem 1.25rem;
  box-shadow: 0 1px 2px rgba(18,17,15,.03), 0 22px 46px -30px rgba(18,17,15,.4);
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.pi:hover { transform: translateY(-4px); box-shadow: 0 2px 5px rgba(18,17,15,.05), 0 34px 66px -28px rgba(18,17,15,.45); }
.pi__img { display: block; width: 100%; aspect-ratio: 4/5; object-fit: cover; border-radius: var(--radius-sm); }
.pi .k { position: absolute; top: 1rem; right: 1.15rem; z-index: 2; font-family: var(--jp); font-size: 1.4rem; color: #fff; opacity: 0.85; text-shadow: 0 1px 10px rgba(0,0,0,0.3); }
.pi .lbl { font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; font-weight: 700; color: var(--ink); margin-top: 1.1rem; padding-inline: 0.55rem; }
.pi .desc { font-size: 0.85rem; color: var(--ink-mute); line-height: 1.45; padding-inline: 0.55rem; margin-top: 0.3rem; }
.pi .val { font-family: var(--serif); font-weight: 700; font-size: clamp(1.9rem, 1.5rem + 1.2vw, 2.5rem); letter-spacing: -0.03em; color: var(--ink); margin-top: 0.7rem; padding-inline: 0.55rem; line-height: 1; }
.pi .val small { font-family: var(--sans); font-size: 0.56rem; font-weight: 700; color: var(--ink-mute); letter-spacing: 0.14em; margin-left: 0.45em; vertical-align: middle; }
.pricing__menu {
  display: inline-block; margin-top: 2rem; font-size: 0.88rem; font-weight: 600;
  color: var(--ink); border-bottom: 1px solid var(--ink); padding-bottom: 2px;
  transition: opacity var(--dur-fast) var(--ease);
}
.pricing__menu:hover { opacity: 0.6; }
@media (max-width: 820px) { .pricing__grp { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .pricing__grp { grid-template-columns: 1fr; } }

/* ============================================================
   THE ONE DARK BAND — deep matcha. This is where the depth
   comes from, and the only place matcha owns a whole field.
   ============================================================ */
.visiting { background: var(--tint); color: var(--ink-soft); position: relative; overflow: hidden; }
/* World map replaces the flat black field. Faded and pushed right so it reads
   as texture behind the stats grid, not competing with the copy on the left. */
.visiting__mapbg {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: 78% 42%;
  pointer-events: none;
}
/* 2026-08-15: swapped the flat grey map for a saturated 3D wax-relief photo.
   Vivid enough that text needs a readable field again -- the old map was
   pale enough to sit under copy with no scrim at all, this one isn't. */
.visiting__scrim {
  display: block; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(90deg, var(--tint) 0%, var(--tint) 32%, rgba(244,244,245,0.55) 52%, rgba(244,244,245,0) 68%);
}
@media (max-width: 880px) {
  .visiting__scrim { background: linear-gradient(180deg, var(--tint) 0%, var(--tint) 38%, rgba(244,244,245,0.5) 58%, rgba(244,244,245,0) 78%); }
}
.visiting .wrap { padding-block: clamp(3.5rem, 2rem + 5vw, 7rem); }
.visiting__inner { position: relative; z-index: 1; display: grid; grid-template-columns: 1.05fr 0.95fr; gap: clamp(2.5rem, 5vw, 5rem); align-items: center; }
.eyebrow--cream { color: var(--ink-mute); }
.visiting__lead h2 { font-size: clamp(2.1rem, 1.3rem + 2.6vw, 3.4rem); line-height: 1.02; color: var(--ink); margin: 1rem 0 1.2rem; }
.visiting__copy { max-width: 54ch; color: var(--ink-soft); font-size: 1.05rem; line-height: 1.7; }
.visiting__copy strong { color: var(--ink); font-weight: 600; }
.visiting__cta { margin-top: 2rem; background: var(--cta-solid); color: var(--cta-solid-ink); }
.visiting__cta:hover { background: var(--cta-solid-hover); transform: translateY(-2px); }
.visiting__points { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
/* 2026-08-15: the wax-map photo is vivid everywhere, not just faded like the
   old flat map, so each stat gets its own frosted card instead of sitting
   bare on top of whatever part of the image lands under it. */
.visiting__points li {
  display: flex; gap: 0.95rem; align-items: flex-start;
  background: linear-gradient(135deg, rgba(255,255,255,0.72), rgba(255,255,255,0.42));
  -webkit-backdrop-filter: blur(16px) saturate(160%); backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid rgba(255,255,255,0.5); border-radius: 14px; padding: 1rem 1.1rem;
  box-shadow: 0 1px 2px rgba(18,17,15,.05), 0 14px 30px -20px rgba(18,17,15,.35);
}
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .visiting__points li { background: rgba(255,255,255,0.88); }
}
.vp-ic {
  flex: none; width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center;
  background: var(--paper); border: 1px solid var(--line);
  font-weight: 700; font-size: 0.8rem; color: var(--ink);
  box-shadow: 0 1px 2px rgba(18,17,15,.04), 0 8px 20px -14px rgba(18,17,15,.25);
}
.vp-ic--whatsapp { background: #25D366; border-color: #25D366; }
/* the label/sub pairs inherit body line-height 1.65 and drift apart; tighten both */
.visiting__points li > div { line-height: 1.3; }
.visiting__points strong { display: block; font-size: 0.98rem; color: var(--ink); font-weight: 600; line-height: 1.25; margin-bottom: 0.3rem; }
/* `li > div span`, NOT any span in the list: the unscoped selector also matched
   .vp-ic and forced it from grid to block, so every icon sat in the top-left
   corner of its circle instead of centred. */
.visiting__points li > div span { display: block; font-size: 0.84rem; color: var(--ink-soft); line-height: 1.4; }
/* Star + "Google" here reuse the review section's gold/gradient treatment
   (.review .stars, .who__google) so the same 5.0★/158-reviews claim reads
   consistently wherever it repeats across pages. */
/* Two classes beats the ".visiting__points li > div span" grey-text rule
   above (3 element selectors outscore 1 class + 0 elements) — that rule was
   silently winning and rendering the star grey instead of gold. */
.visiting__points .visiting__star { display: block; color: #E3B341; letter-spacing: 0.15em; font-size: 0.85rem; margin-bottom: 0.3rem; }
@media (max-width: 880px) {
  .visiting__inner { grid-template-columns: 1fr; }
  .visiting__points { grid-template-columns: 1fr; gap: 1.3rem; }
}

/* ---------- philosophy ---------- */
.philosophy { text-align: center; }
/* rem, not ch: `ch` resolves against THIS element's 1rem font, not the 2.4rem
   the paragraph inside is set at, so 38ch measured ~300px and broke the
   statement into seven lines of three words. */
.philosophy__inner { max-width: min(34rem, 100%); margin-inline: auto; }
.philosophy__inner p { font-family: var(--serif); font-size: clamp(1.5rem, 1.1rem + 1.5vw, 2.4rem); line-height: 1.3; letter-spacing: -0.03em; color: var(--ink); }

/* ---------- pillars ---------- */
.pillars-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(2rem, 4vw, 3.5rem); }
.pillar { position: relative; padding-top: 2rem; border-top: 1px solid var(--line); }
.pillar .num { font-family: var(--jp); font-size: 1.4rem; color: var(--ink); opacity: 0.22; position: absolute; top: -1.15rem; right: 0; }
.pillar h3 { font-size: 1.45rem; margin-bottom: 0.6rem; }
.pillar p { color: var(--ink-soft); }
/* Four disciplines on the founders page. The base grid is 3-up, which left a
   single orphaned pillar on a second row. */
.pillars-grid--four { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1000px) { .pillars-grid--four { grid-template-columns: 1fr 1fr; } }
@media (max-width: 760px) { .pillars-grid { grid-template-columns: 1fr; gap: 2.2rem; }
                            .pillars-grid--four { grid-template-columns: 1fr; } }

/* 2026-08-12: founders "what each brought" — glass-card pass, same gradient
   wash + blur + hairline border as the reviews / gift / offer panels, so the
   four disciplines read as objects instead of a bare top-rule list. Needs the
   .founders-pillars wash class on the section (see founders.html) for the
   glass to have something to blur against. */
.founders-pillars { background: linear-gradient(135deg, var(--tint) 0%, var(--paper) 100%); }
.pillars-grid--four .pillar {
  border-top: 0; padding: 1.9rem 1.6rem 1.7rem;
  background: linear-gradient(135deg, rgba(255,255,255,0.62), rgba(255,255,255,0.32));
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  backdrop-filter: blur(22px) saturate(160%);
  border: 1px solid rgba(255,255,255,0.55);
  border-radius: var(--radius);
  box-shadow: 0 1px 2px rgba(18,17,15,.03), 0 18px 40px -32px rgba(18,17,15,.4);
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.pillars-grid--four .pillar:hover { transform: translateY(-3px); box-shadow: 0 2px 5px rgba(18,17,15,.05), 0 26px 50px -28px rgba(18,17,15,.42); }
.pillars-grid--four .pillar .num { position: static; display: block; margin-bottom: 0.7rem; opacity: 0.32; }
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .pillars-grid--four .pillar { background: rgba(255,255,255,0.9); }
}

/* ---------- founders panel ----------
   Trial 2026-07-27: the four-sisters block as a single dark inset card, the way
   the reference site does it. Photo left, copy right, headline UNDER the story
   (their order, and it works: you read who they are, then the line lands), one
   CTA out to the About page. Previous cream-band version is parked in
   outputs/wowo-v2/_story_block_previous.html if we revert.
   2026-08-10: last black block on the v3 homepage (after the gift card and
   reviews band both moved off --ink). Swapped the solid black inset for a
   frosted glass card, same glass language as .svc-card__body (blur + saturate
   + translucent border). First pass tinted the gradient toward blossom pink —
   Cybil: looked terrible, dropped for a plain neutral wash. Headline also
   moved off the image column (was dead space below a short photo) to sit
   above the copy instead, so the card padding could come down. */
.founders-panel {
  padding: calc(var(--space) * 0.6) 0;
  background: linear-gradient(135deg, var(--tint) 0%, var(--paper) 100%);
}
.founders-panel__inner {
  background: linear-gradient(135deg, rgba(255,255,255,0.62), rgba(255,255,255,0.32));
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  backdrop-filter: blur(22px) saturate(160%);
  border: 1px solid rgba(255,255,255,0.55);
  box-shadow: 0 18px 48px -28px rgba(18,17,15,0.32);
  color: var(--ink-soft);
  border-radius: clamp(20px, 2vw, 28px);
  padding: clamp(1.3rem, 2.4vw, 2.2rem);
  display: grid; grid-template-columns: 0.9fr 1.1fr;
  gap: clamp(1.6rem, 3.5vw, 3.4rem);
  align-items: center;
}
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .founders-panel__inner { background: rgba(255,255,255,0.88); }
}
.founders-panel__media img, .founders-panel__media video { width: 100%; height: auto; display: block; border-radius: 14px; border: 1px solid var(--line); }
.founders-panel__copy h2 {
  color: var(--ink); margin: 0 0 1rem;
  font-size: clamp(1.7rem, 1.05rem + 1.9vw, 2.45rem); letter-spacing: -0.035em; line-height: 1.05;
}
.founders-panel__copy p { font-size: 0.98rem; line-height: 1.62; }
.founders-panel__copy .eyebrow { color: var(--ink-mute); margin-bottom: 0.9rem; }
.founders-panel__copy .principles { margin: 1.1rem 0; }
.founders-panel__copy .principles p { color: var(--ink); font-weight: 500; }
@media (max-width: 860px) {
  .founders-panel__inner { grid-template-columns: 1fr; gap: 1.6rem; }
  .founders-panel__media { aspect-ratio: 4 / 3; }
}


/* ---------- first-visit offers ----------
   2026-07-27 v2. First attempt split this across three tiles plus a strip
   underneath, which took four elements to say what the reference says in one
   paragraph. Rebuilt to match the sample exactly: ONE panel, copy left, image
   right, a single button. Panel is the blossom pastel, the job their pale blue
   does. First-visit PRICES ARE HELD (Cybil, 2026-07-28) until the Fresha margin
   is run: the copy names the offer, not the rand. Only R249 Smooth Season, which
   is already live on Paystack, carries a number. */
/* Was solid --cta (blossom pink fill). Same "too much colour" call as the
   founders panel: glass card instead of a flat fill, blossom kept only as
   the outline so the section still reads as the "offer" moment. Cybil
   2026-08-10. */
.offer-panel { padding: calc(var(--space) * 0.7) 0; background: linear-gradient(135deg, var(--tint) 0%, var(--paper) 100%); }
.offer-panel__inner {
  background: linear-gradient(135deg, rgba(255,255,255,0.62), rgba(255,255,255,0.32));
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  backdrop-filter: blur(22px) saturate(160%);
  border: 1px solid var(--cta-hover);
  box-shadow: 0 18px 48px -28px rgba(18,17,15,0.28);
  color: var(--ink-soft);
  border-radius: clamp(20px, 2vw, 28px);
  padding: clamp(1.8rem, 3.4vw, 3.4rem);
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(1.6rem, 4vw, 3.6rem); align-items: center;
}
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .offer-panel__inner { background: rgba(255,255,255,0.9); }
}
.offer-panel__copy h2 {
  color: var(--ink); margin: 0 0 1.1rem;
  font-size: clamp(1.9rem, 1.2rem + 2.4vw, 3rem); letter-spacing: -0.035em; line-height: 1.04;
}
.offer-panel__copy p { color: var(--ink-soft); font-size: 0.98rem; line-height: 1.6; max-width: 52ch; }
.offer-panel__copy strong { color: var(--ink); font-weight: 600; }
.offer-panel__copy .btn { margin-top: 1.5rem; }
/* height:100% inside an auto-height grid item collapsed this to zero once
   aspect-ratio was also set. Let the ratio drive the height. */
/* Full natural size (1200x1400, ratio 0.857) made the panel taller than the
   copy column, growing the card's padding. Cybil: crop it slightly — not
   back to the original 4/3 landscape crop, just enough to bring the height
   down closer to the copy. */
.offer-panel__media img { width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; object-position: 50% 22%; border-radius: 14px; display: block; border: 1px solid var(--line); }
@media (max-width: 860px) {
  .offer-panel__inner { grid-template-columns: 1fr; gap: 1.6rem; }
  .offer-panel__media { order: -1; }
}

/* ---------- service cards (home, 4 up) ----------
   The restructure's centrepiece. Three text-only columns asked the client to
   read; four image cards let them recognise what they came for and tap it.
   Each card is a link straight into its category on menu.html, so the path
   from "I want my legs done" to a price is two taps. */
.svc-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-top: 1.8rem; }
/* Apple-style resting outline: a 1px hairline + a very soft ambient shadow so
   the tile reads as a distinct object on white even before it's loaded or
   hovered, instead of looking like a missing/broken placeholder. Cybil's
   standing preference — apply this same treatment anywhere an image sits on
   a plain background, not just this grid. */
.svc-card {
  position: relative; display: block; aspect-ratio: 3 / 4;
  border-radius: var(--radius); overflow: hidden; background: var(--tint);
  border: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(18,17,15,.04), 0 12px 28px -20px rgba(18,17,15,.18);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.svc-card:hover { transform: translateY(-4px); box-shadow: 0 18px 40px -24px rgba(18,17,15,0.35); }
.svc-card__img { position: absolute; inset: 0; }
.svc-card__img img { width: 100%; height: 100%; object-fit: cover; transition: transform 900ms var(--ease); }
.svc-card:hover .svc-card__img img { transform: scale(1.04); }
/* See-through glass, deliberately SHALLOW. The first version carried a
   description as well and grew tall enough to cover the subject: on the brows
   card it sat straight over the brow, which is the only thing that photo is
   about. Name and price only, two tight lines. The description was doing no
   work here anyway, the menu page carries the detail. */
.svc-card__body {
  position: absolute; left: 0.55rem; right: 0.55rem; bottom: 0.55rem;
  background: rgba(255, 255, 255, 0.30);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  backdrop-filter: blur(18px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, 0.45);
  box-shadow: 0 8px 24px -14px rgba(18, 17, 15, 0.45);
  border-radius: 11px; padding: 0.5rem 0.7rem 0.55rem;
  /* Stacked, not side by side: at 4-up the card is ~250px and "Brazilian &
     Hollywood" next to a price wrapped onto two lines anyway. Each line now
     gets the full width, so nothing wraps and the panel stays two lines. */
  display: flex; flex-direction: column; gap: 0.1rem;
}
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .svc-card__body { background: rgba(255, 255, 255, 0.82); }
}
.svc-card__body h3 { font-size: 0.92rem; letter-spacing: -0.02em; color: var(--ink); font-weight: 700; line-height: 1.2; }
/* Description, NOT price. The cards are the shop window; the first-visit offer
   panel is where a number should do the persuading. A full price on the card
   argues against the loss-leader before the client has reached the offer. */
.svc-card__body p { font-size: 0.76rem; line-height: 1.35; color: var(--ink); opacity: 0.82; font-weight: 500; }
.svc-card__from { display: none; }
.svc-card__from .arrow { transition: transform var(--dur-fast) var(--ease); display: inline-block; }
.svc-card:hover .svc-card__from .arrow { transform: translateX(4px); }
/* the brow is low in its frame; lift the crop so the glass never lands on it */
.svc-card__img img[src*="svc-face"] { object-position: 50% 38%; }
@media (max-width: 1000px) { .svc-cards { grid-template-columns: repeat(2, 1fr); } }
/* Keeps the desktop 3/4 portrait crop. A 4/3 landscape card here re-cropped
   every photo from the middle, which cut the heads off the men's and brows
   shots: the same image, framed differently, is not the same image. */
@media (max-width: 520px)  { .svc-cards { grid-template-columns: 1fr; gap: 0.8rem; } }

/* ---------- splits ---------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2.5rem, 6vw, 5.5rem); align-items: center; }
.split--reverse .split__media { order: 2; }
.split__media {
  aspect-ratio: 4/5; border-radius: var(--radius); overflow: hidden; position: relative;
  border: 1px solid var(--line);
  box-shadow: 0 40px 80px -46px rgba(18,17,15,.5);
}
.split__media img, .split__media video { width: 100%; height: 100%; object-fit: cover; }
.split__media .k { position: absolute; right: 1.3rem; bottom: 0.8rem; font-family: var(--jp); font-size: 2.6rem; color: #fff; opacity: 0.85; text-shadow: 0 2px 14px rgba(0,0,0,0.35); }
@media (max-width: 820px) { .split { grid-template-columns: 1fr; } .split--reverse .split__media { order: 0; } }

.detail-list { margin-top: 0.5rem; }
.detail-list .di { display: flex; gap: 1rem; padding: 0.95rem 0; border-bottom: 1px solid var(--line-soft); }
.detail-list .di .mk { color: var(--ink); font-weight: 700; }
.detail-list .di p { margin: 0; color: var(--ink-soft); }

.tick-list { list-style: none; margin-top: 1rem; }
.tick-list li { position: relative; padding: 0.8rem 0 0.8rem 1.7rem; border-bottom: 1px solid var(--line-soft); color: var(--ink-soft); }
.tick-list li::before { content: ""; position: absolute; left: 0; top: 1.35rem; width: 6px; height: 6px; border-radius: 50%; background: var(--sakura-deep); }

/* ---------- the quiet moment ---------- */
.moment { text-align: center; }
/* the three lines recede so the brand line lands; 0.32 read as broken/disabled */
.moment__inner p { font-family: var(--serif); font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.5rem); line-height: 1.35; letter-spacing: -0.03em; color: var(--ink); opacity: 0.52; }
.moment__inner p.final { margin-top: 2rem; font-weight: 600; color: var(--ink); opacity: 1; }
.moment .label { display: none; }

/* ---------- founders ---------- */
.founders__media { aspect-ratio: auto; border-radius: var(--radius); background: transparent; border: 1px solid var(--line); box-shadow: 0 40px 80px -46px rgba(18,17,15,.45); }
.founders__media img { width: 100%; height: auto; object-fit: contain; border-radius: var(--radius); }
.founders__story p { margin-bottom: 1.15rem; color: var(--ink-soft); }
.principles { display: flex; flex-direction: column; gap: 0.3rem; margin: 1.6rem 0; }
.principles p { font-family: var(--serif); font-size: 1.2rem; letter-spacing: -0.02em; color: var(--ink); margin: 0; }

/* ---------- experience steps ---------- */
/* 2026-08-15: was 4 columns of grey body copy under a thin kanji + rule-line
   divider -- too faint to register next to the glass-card language used
   everywhere else on the site. Rebuilt as full-bleed photo cards (real
   photography, not placeholders) with the title/kanji/copy overlaid on a
   bottom scrim, same treatment as the hero videos elsewhere on the site. */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.6rem; }
.step {
  position: relative; aspect-ratio: 4 / 5; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 1px 2px rgba(18,17,15,.03), 0 18px 40px -32px rgba(18,17,15,.4);
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.step:hover { transform: translateY(-4px); box-shadow: 0 2px 5px rgba(18,17,15,.05), 0 34px 66px -26px rgba(18,17,15,.45); }
.step__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.step__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(18,17,15,0) 40%, rgba(18,17,15,0.78) 100%);
}
.step__body { position: absolute; left: 0; right: 0; bottom: 0; padding: 1.3rem 1.4rem 1.4rem; color: #fff; }
.step__body h3 { font-size: 1.15rem; margin-bottom: 0.35rem; color: #fff; }
.step__body p { font-size: 0.86rem; color: rgba(255,255,255,0.85); line-height: 1.4; }
@media (max-width: 820px) { .steps { grid-template-columns: 1fr 1fr; gap: 1.4rem; } }
@media (max-width: 480px) { .steps { grid-template-columns: 1fr; } .step { aspect-ratio: 4 / 3.2; } }

/* ---------- reviews ----------
   2026-08-10: brought into the same glass-card language as the founders /
   offer / gift panels (subtle gradient wash behind, frosted glass cards,
   hairline border) instead of flat white — was the one section on the page
   that hadn't been touched. Stars go gold: grey read as barely-there next
   to a "5.0★ · 158 reviews" claim that's the section's whole point. */
.block.reviews { background: linear-gradient(135deg, var(--tint) 0%, var(--paper) 100%); }
.reviews-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; margin-top: 1rem; }
.review {
  background: linear-gradient(135deg, rgba(255,255,255,0.62), rgba(255,255,255,0.32));
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  backdrop-filter: blur(22px) saturate(160%);
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 2.1rem 1.9rem; display: flex; flex-direction: column; gap: 1.1rem;
  box-shadow: 0 1px 2px rgba(18,17,15,.03), 0 18px 40px -32px rgba(18,17,15,.4);
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .review { background: rgba(255,255,255,0.9); }
}
.review:hover { transform: translateY(-4px); box-shadow: 0 2px 5px rgba(18,17,15,.05), 0 34px 66px -26px rgba(18,17,15,.45); }
.review .stars { color: #E3B341; letter-spacing: 0.15em; font-size: 1rem; }
.review .quote { font-family: var(--serif); font-size: 1.15rem; line-height: 1.45; letter-spacing: -0.02em; color: var(--ink); }
.review .who { font-size: 0.76rem; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 600; color: var(--ink-mute); margin-top: auto; }
.review .who__name { color: #2E7D32; }
.who__google {
  background: linear-gradient(90deg, #4285F4 0%, #EA4335 35%, #FBBC05 65%, #34A853 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
/* the 4th tile is a CTA, not a review: run it full width as a closing band
   so a 4-item grid never leaves an orphan sitting alone on row two. Same
   glass treatment as the other three, with a real button instead of the
   small underlined text link it had before. */
.review--cta {
  grid-column: 1 / -1;
  flex-direction: row; align-items: center; justify-content: space-between;
  gap: 1.5rem; padding: 1.9rem 2.2rem;
}
.review--cta:hover { transform: none; }
.review--cta .stars { color: #E3B341; font-size: 1.1rem; }
.review--cta .quote { color: var(--ink); font-size: clamp(1.2rem, 1rem + 0.8vw, 1.6rem); font-weight: 600; }
.review--cta .who { text-transform: none; letter-spacing: 0; }
.review--cta .btn { white-space: nowrap; }
.review--cta .btn.btn--matcha { background: #6B7F58; color: #fff; }
.review--cta .btn.btn--matcha:hover { background: #59684A; }
@media (max-width: 820px) {
  .reviews-grid { grid-template-columns: 1fr; }
  .review--cta { flex-direction: column; align-items: flex-start; gap: 1rem; }
}

/* ---------- faq ----------
   2026-08-12: glass-card pass. Each question was a row in one long divided
   list; now every row is its own frosted-glass card, same gradient wash +
   blur + hairline border as .review / .founders-panel__inner / .gift-card,
   so the FAQ page joins the same glass language as the rest of v3 instead
   of being the one page still on flat dividers. Section gets the tint-to-
   paper wash behind it so the glass has something to blur against. */
.block.faq { background: linear-gradient(135deg, var(--tint) 0%, var(--paper) 100%); }
/* Left-aligned to the hero above it, not a narrow floating centred column
   (the head-block that used to visually anchor a centred list is gone —
   see faqs.html 2026-08-12). Flush-left reads as one continuous column with
   the hero instead of jumping sideways, and it's the same on mobile since
   the max-width never binds below 740px anyway. */
.faq__list { max-width: 740px; margin: 0; border-top: 0; display: flex; flex-direction: column; gap: 0.85rem; }
.faq-item {
  border: 1px solid rgba(255,255,255,0.55);
  border-radius: var(--radius);
  background: linear-gradient(135deg, rgba(255,255,255,0.62), rgba(255,255,255,0.32));
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  backdrop-filter: blur(22px) saturate(160%);
  box-shadow: 0 1px 2px rgba(18,17,15,.03), 0 18px 40px -32px rgba(18,17,15,.4);
  padding-inline: 1.7rem;
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.faq-item:hover { transform: translateY(-2px); box-shadow: 0 2px 5px rgba(18,17,15,.05), 0 28px 54px -30px rgba(18,17,15,.45); }
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .faq-item { background: rgba(255,255,255,0.9); }
}
.faq-item summary {
  list-style: none; cursor: pointer; position: relative;
  display: flex; align-items: center; gap: 1rem; padding: 1.4rem 2rem 1.4rem 0;
  font-family: var(--serif); font-size: clamp(1.15rem, 1.05rem + 0.55vw, 1.45rem);
  font-weight: 600; letter-spacing: -0.02em; color: var(--ink); line-height: 1.3;
  transition: opacity var(--dur) var(--ease);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: ""; position: absolute; right: 0.2rem; top: 50%; width: 15px; height: 15px; margin-top: -7.5px;
  background:
    linear-gradient(var(--ink),var(--ink)) center/15px 1.5px no-repeat,
    linear-gradient(var(--ink),var(--ink)) center/1.5px 15px no-repeat;
  transition: transform var(--dur) var(--ease);
}
.faq-item[open] summary::after { transform: rotate(135deg); }
.faq-item summary:hover { opacity: 0.6; }
.faq-a { padding: 0 2rem 1.5rem 0; }
.faq-a p { margin: 0; color: var(--ink-soft); max-width: 64ch; }
.faq-item[open] .faq-a { animation: faqIn var(--dur) var(--ease); }
@keyframes faqIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.faq__cta { text-align: left; margin-top: 2.8rem; font-family: var(--serif); font-size: 1.15rem; letter-spacing: -0.02em; color: var(--ink); }
.faq__cta a { font-weight: 600; border-bottom: 1px solid var(--ink); }
.faq__cta a:hover { opacity: 0.6; }

/* ---------- location ---------- */
.location__grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: clamp(2.5rem, 5vw, 4.5rem); align-items: stretch; }
.location__map { border-radius: var(--radius); overflow: hidden; min-height: 380px; box-shadow: 0 30px 60px -38px rgba(18,17,15,.45); }
.location__map iframe { width: 100%; height: 100%; min-height: 380px; border: 0; display: block; border-radius: var(--radius); }
.location__info h2 { font-size: clamp(2rem, 1.4rem + 2vw, 3rem); }
.location .divider { width: 40px; height: 1.5px; background: var(--ink); margin: 1.2rem 0 1.6rem; }
.location__row { margin-bottom: 1.2rem; color: var(--ink-soft); }
.location__row strong { color: var(--ink-mute); font-weight: 700; font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; display: block; margin-bottom: 0.3rem; }
.location__row a { border-bottom: 1px solid var(--line); }
.location__row a:hover { border-color: var(--ink); }
@media (max-width: 820px) { .location__grid { grid-template-columns: 1fr; } }

/* ---------- footer ---------- */
footer { background: var(--ink); color: rgba(255,255,255,0.62); padding-block: clamp(3.5rem, 2rem + 4vw, 6rem) 2.4rem; }
.foot-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr; gap: 2.5rem; margin-bottom: 3rem; }
.foot-grid--lean { grid-template-columns: 1.5fr 1fr; }
.foot .brand { color: #fff; letter-spacing: 0.22em; margin-bottom: 1.1rem; display: block; }
.foot p { font-size: 0.92rem; }
.foot .whisper { color: rgba(255,255,255,0.55); }
.foot-col h4 { font-family: var(--sans); font-size: 0.68rem; letter-spacing: 0.2em; text-transform: uppercase; color: rgba(255,255,255,0.5); margin-bottom: 1.1rem; font-weight: 700; }
.foot-col a { font-size: 0.92rem; color: rgba(255,255,255,0.72); display: block; margin-bottom: 0.5rem; transition: color var(--dur-fast) var(--ease); }
.foot-col a:hover { color: #fff; }
.foot-bottom { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; padding-top: 2rem; border-top: 1px solid rgba(255,255,255,0.12); font-size: 0.78rem; color: rgba(255,255,255,0.42); }
.foot-bottom .kanji-min { font-family: var(--jp); }
@media (max-width: 760px) { .foot-grid { grid-template-columns: 1fr; gap: 2rem; } }

/* ---------- reveal ---------- */
.reveal { opacity: 0; transform: translateY(24px); transition: opacity 800ms var(--ease), transform 800ms var(--ease); }
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
  .btn, .nav-links a.navlink::after, .faq-item[open] .faq-a { transition: none; animation: none; }
}
