/* ==========================================================================
   Dreamin' Head Spa & Sculpture — style.css
   Palette: deep brown/charcoal #2b2622 · off-white #f4f0e9 · gold accent
   Type: Cormorant Garamond (headings) · Karla (body)
   Mobile-first; breakpoints at 640px / 960px
   ========================================================================== */

:root {
  --ink: #2b2622;          /* deep brown / charcoal */
  --ink-soft: #4a423b;
  --cream: #f4f0e9;        /* off-white */
  --cream-deep: #ebe5da;
  --gold: #b3924f;         /* accent */
  --gold-soft: #cdb587;
  --white: #fffdf9;
  --line: rgba(43, 38, 34, 0.14);
  --line-light: rgba(244, 240, 233, 0.18);
  --serif: "Cormorant Garamond", "Noto Serif JP", Georgia, serif;
  --script: "Great Vibes", cursive;
  --sans: "Jost", "Noto Sans JP", -apple-system, sans-serif;
  --price: "Quicksand", "Jost", -apple-system, sans-serif;   /* prices only — legible, even-height figures */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

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

html { scroll-behavior: smooth; }

body {
  font-family: var(--sans);
  font-size: 16.5px;
  font-weight: 300;
  color: var(--ink);
  background: var(--cream);
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

a { color: var(--gold); text-decoration: none; transition: color 0.3s var(--ease); }
a:hover { color: var(--ink); }

h1, h2, h3 { font-family: var(--serif); font-weight: 500; line-height: 1.25; letter-spacing: 0.01em; }

h1 em, h2 em, h3 em {
  font-style: italic;
  font-weight: 400;
  color: var(--gold);
}
.section-dark h1 em, .section-dark h2 em, .cta-band h2 em, .page-hero h1 em, .hero h1 em { color: var(--gold-soft); }

/* Script accent (matches the brand's handwritten logo) */
.script-word {
  font-family: var(--script);
  font-size: clamp(38px, 5.5vw, 64px);
  color: var(--gold-soft);
  line-height: 1;
  margin-bottom: 6px;
}

/* ---------- Image placeholders (swap for real imagery later) ---------- */
.img-placeholder {
  position: relative;
  background: #d8d3ca repeating-linear-gradient(45deg, transparent, transparent 24px, rgba(43,38,34,0.04) 24px, rgba(43,38,34,0.04) 25px);
  border: 1px solid rgba(43, 38, 34, 0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.img-label {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.35em;
  color: rgba(43, 38, 34, 0.45);
  text-transform: uppercase;
}

.img-arch { border-radius: 300px 300px 10px 10px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 14px 34px;
  border-radius: 999px;               /* pill — soft, luxurious */
  border: 1px solid transparent;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.35s var(--ease), color 0.35s var(--ease),
              border-color 0.35s var(--ease), transform 0.35s var(--ease),
              box-shadow 0.35s var(--ease);
}
.btn:hover { transform: translateY(-2px); }

.btn-gold {
  position: relative;
  overflow: hidden;
  background: var(--gold);
  color: var(--white);
  box-shadow: 0 6px 18px rgba(179, 146, 79, 0.25);
}
.btn-gold:hover { background: #a3823f; color: var(--white); box-shadow: 0 10px 24px rgba(179, 146, 79, 0.35); }
/* A soft light sweep across the primary CTA on hover — one pass, then rests. */
.btn-gold::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: -60%;
  width: 40%;
  background: linear-gradient(100deg, transparent, rgba(255, 253, 249, 0.35), transparent);
  transform: skewX(-18deg);
  pointer-events: none;
}
.btn-gold:hover::before { animation: btnSheen 0.9s var(--ease); }
@keyframes btnSheen {
  to { transform: translateX(420%) skewX(-18deg); }
}

/* Online Shop — the secondary half of the header CTA pair.
   Same pill silhouette as Book Now so the two read as a set,
   outlined so Book Now stays the primary action. */
.btn-shop {
  background: transparent;
  border-color: var(--gold-soft);
  color: var(--gold-soft);
}
.btn-shop:hover { background: var(--gold-soft); color: var(--ink); border-color: var(--gold-soft); }

.btn-ghost { border-color: rgba(255, 253, 249, 0.6); color: var(--white); }
.btn-ghost:hover { background: rgba(255, 253, 249, 0.12); color: var(--white); }

.btn-outline { border-color: var(--line-light); color: var(--cream); }
.btn-outline:hover { border-color: var(--gold-soft); color: var(--gold-soft); }

.btn-outline-dark { border-color: var(--ink); color: var(--ink); }
.btn-outline-dark:hover { background: var(--ink); color: var(--cream); }

.btn-lg { padding: 17px 40px; font-size: 14px; }
.btn-block { display: block; text-align: center; width: 100%; }
.btn-header { padding: 11px 22px; font-size: 12px; }

/* ---------- Header ---------- */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  transition: background 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.site-header.is-solid {
  background: rgba(43, 38, 34, 0.96);
  box-shadow: 0 1px 0 rgba(255, 253, 249, 0.08);
  backdrop-filter: blur(8px);
}
.header-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 14px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.logo { display: flex; align-items: center; }
.logo-img { height: 44px; width: auto; display: block; transition: height 0.35s var(--ease); }
/* The mark condenses slightly once the bar turns solid — quieter over content. */
.site-header.is-solid .logo-img { height: 38px; }
.logo-footer .logo-img { height: 60px; }

.main-nav { display: none; gap: 30px; }
.main-nav a {
  color: var(--cream);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 4px 0;
  border-bottom: 1px solid transparent;
}
.main-nav a:hover, .main-nav a.is-current { color: var(--gold-soft); border-bottom-color: var(--gold-soft); }

/* Instagram: label + glyph, sitting on the same baseline (footer nav only —
   in the header the label is dropped and the glyph stands alone, see .header-ig) */
.nav-insta { display: inline-flex; align-items: center; gap: 7px; }
.icon-ig {
  width: 17px; height: 17px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  vertical-align: middle;
}
.icon-ig .ig-dot { fill: currentColor; stroke: none; }

/* Instagram in the header: glyph only, hard right of the bar. No label, so it
   needs a real tap target of its own — hence the padding rather than bare svg. */
.header-ig {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  color: var(--cream);
  transition: color 0.3s var(--ease);
}
.header-ig:hover { color: var(--gold-soft); }
.header-ig .icon-ig { width: 21px; height: 21px; }

/* e-Gift Voucher sits where Instagram used to, at the end of the nav. Reads as a
   button on desktop; inside the mobile drawer it falls back to a plain nav row,
   because a lone pill in a stack of text links looks like a mistake. */
.nav-gift { white-space: nowrap; }

/* e-Gift Voucher is a header button on desktop; inside the drawer on mobile. */
.nav-gift-mobile { display: none; }
.main-nav.is-open .nav-gift-mobile { display: block; color: var(--gold-soft); }

/* On phones the bar carries the mark and the menu, nothing else: Book Now already
   sits in the sticky bar a thumb's reach away, and Instagram is in the drawer and
   the footer — repeating either here just crowds the logo. All three come back at
   960px, where there is room for them. */
.header-actions { display: flex; align-items: center; gap: 10px; }
.header-actions .btn-shop,
.header-actions .btn-gold,
.header-ig { display: none; }

.lang-toggle {
  background: none;
  border: 1px solid rgba(255, 253, 249, 0.3);
  border-radius: 3px;
  color: var(--cream);
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.08em;
  padding: 8px 14px;
  border-radius: 999px;
  white-space: nowrap;
  cursor: pointer;
  display: flex; gap: 5px;
  transition: border-color 0.3s var(--ease);
}
.lang-toggle:hover { border-color: var(--gold-soft); }
.lang-divider { opacity: 0.4; }
.lang-toggle .lang-en { color: var(--gold-soft); font-weight: 600; }
body.lang-ja .lang-toggle .lang-en { color: var(--cream); font-weight: 300; }
body.lang-ja .lang-toggle .lang-ja { color: var(--gold-soft); font-weight: 600; }

/* Mobile burger */
.nav-burger {
  display: flex; flex-direction: column; gap: 5px;
  background: none; border: none; cursor: pointer; padding: 6px;
}
.nav-burger span {
  width: 22px; height: 1.5px;
  background: var(--cream);
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}
.nav-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* Mobile nav drawer */
.main-nav.is-open {
  display: flex;
  position: fixed;
  inset: 66px 0 auto 0;
  flex-direction: column;
  gap: 0;
  background: rgba(43, 38, 34, 0.98);
  padding: 10px 24px 26px;
}
.main-nav.is-open a { padding: 15px 0; border-bottom: 1px solid rgba(255, 253, 249, 0.08); font-size: 14px; }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--white);
  background: var(--ink);
}
.hero-bg { position: absolute; inset: 0; overflow: hidden; }

/* Hero slideshow: cross-fading full-bleed slides with a slow zoom.
   3s on screen + 0.8s cross-fade = a 3.8s beat, which is what heroZoom is
   timed to; a zoom that outlasts its slide freezes mid-move on the handover.
   The fade is half what it was because the interval is: at the old 1.6s a slide
   would spend more than half its life dissolving, which reads as one picture
   melting rather than four being shown. */
.hero-slide {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 0.8s var(--ease);
  will-change: opacity, transform;
}
.hero-slide.is-active {
  opacity: 1;
  animation: heroZoom 3.8s linear forwards;
}

/* Slide sources. Only slide 1 is named unconditionally — script.js puts
   .is-ready on the container once the page has loaded, and that is what lets
   slides 2–4 start fetching. Without the gate all four would be requested
   during the first paint and the hero would arrive four times slower. */
.hero-slide-1 { background-image: url('assets/hero-practitioner-lg.jpg'); }
.is-ready .hero-slide-2 { background-image: url('assets/hero-massage-lg.jpg'); }
.is-ready .hero-slide-3 { background-image: url('assets/hero-headbath-lg.jpg'); }
.is-ready .hero-slide-4 { background-image: url('assets/hero-headbath-wide-lg.jpg'); }

/* On a phone the hero is far taller than it is wide, so a centred `cover` of a
   16:9 file keeps only its middle third — which on these photos is wall and
   water, not the head being worked on. Swap in a 3:4 crop of the same frame. */
@media (max-width: 639px) {
  .hero-slide-1 { background-image: url('assets/hero-practitioner-sm.jpg'); }
  .is-ready .hero-slide-2 { background-image: url('assets/hero-massage-sm.jpg'); }
  .is-ready .hero-slide-3 { background-image: url('assets/hero-headbath-sm.jpg'); }
  .is-ready .hero-slide-4 { background-image: url('assets/hero-headbath-wide-sm.jpg'); }
}

@keyframes heroZoom {
  from { transform: scale(1); }
  to { transform: scale(1.07); }
}
/* Reduced motion: script.js leaves the rotation on slide 1, so all that is left
   to silence here is the zoom. The fade rule stays for the ordinary case. */
@media (prefers-reduced-motion: reduce) {
  .hero-slide { transition: opacity 0.5s linear; }
  .hero-slide.is-active { animation: none; }
}

/* Two layers, because the slides are no longer a single near-black photo. The
   head-bath shots are bright — pale wall, white water — and over them the gold
   kicker sat at 2.6:1 against #cdb587, well under the 4.5:1 small text needs.
   The ellipse does the legibility work and sits only where the copy is; the
   linear pass is kept as light as the kicker and the scroll cue allow, so the
   photograph keeps its light everywhere else. The middle of the frame is where
   the h1 sits and the h1 only needs 3:1, which is what buys the transparency.
   Numbers are measured, not guessed — see the AA check below. */
.hero-scrim {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 74% 62% at 50% 44%,
      rgba(24,20,17,0.64) 0%, rgba(24,20,17,0.34) 62%, rgba(24,20,17,0) 100%),
    linear-gradient(180deg,
      rgba(43,38,34,0.84) 0%, rgba(43,38,34,0.64) 22%,
      rgba(43,38,34,0.20) 56%, rgba(43,38,34,0.52) 100%);
}
/* A phone gets a heavier hand, and not for want of trying to avoid it: the hero
   is far taller than it is wide there, so the copy covers most of the frame
   instead of a band across its middle. There is no arrangement that leaves the
   photo bright *behind the text* when the text is the picture. */
@media (max-width: 639px) {
  .hero-scrim {
    background:
      radial-gradient(ellipse 100% 64% at 50% 44%,
        rgba(24,20,17,0.60) 0%, rgba(24,20,17,0.38) 62%, rgba(24,20,17,0) 100%),
      linear-gradient(180deg,
        rgba(43,38,34,0.84) 0%, rgba(43,38,34,0.70) 20%,
        rgba(43,38,34,0.44) 55%, rgba(43,38,34,0.66) 100%);
  }
}
/* The bottom padding reserves room for .hero-scroll, which is absolutely
   positioned at the foot of the hero. At 90px the CTA buttons collided with
   it on shorter phones, where they wrap to two rows. */
.hero-content { position: relative; z-index: 2; padding: 120px 24px 132px; max-width: 860px; }
.hero-kicker {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--gold-soft);
  margin-bottom: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
}
.hero-kicker::before, .hero-kicker::after {
  content: "";
  width: 44px;
  height: 1px;
  background: var(--gold-soft);
  opacity: 0.6;
}
/* Three lines rather than the two this used to carry, so the top of the scale
   comes down a step — at 84px the third line pushed the CTAs into the scroll
   cue on a 768px-tall laptop. */
.hero h1 {
  font-size: clamp(34px, 6.2vw, 68px);
  font-weight: 500;
  color: var(--white);
  margin-bottom: 26px;
}
/* Keep "10" in the heading serif, but force lining figures so 1 and 0 sit at
   the same height — the same fix used on the .why-num "01/02/03/04" numerals.
   Without this, Cormorant falls back to old-style figures and the "10" reads
   as an ambiguous glyph. */
.hero h1 .hero-num {
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
}
/* Opaque, where this used to be 85% white. Softening the sub-heading was cheap
   when it sat on a near-black photo; over lit ones the missing 15% is real
   contrast given away, and buying it back here costs the photograph nothing —
   the alternative was another pass of darkening over the whole frame. */
.hero-sub {
  font-size: clamp(16px, 2vw, 19px);
  color: var(--white);
  max-width: 620px;
  margin: 0 auto 10px;
}
.hero-sub.ja-line { font-size: 13px; letter-spacing: 0.14em; color: var(--gold-soft); margin-bottom: 0; }
.hero-cta { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; margin-top: 44px; }

/* Short landscape screens — a 1280x720 laptop is the common one. The heading
   runs to three lines here, and at the full desktop rhythm that pushed Book Now
   off the bottom of the hero: the page's main call to action, below the fold,
   on the machine a good share of guests browse from. Tighten the vertical
   spacing rather than shorten the heading. Keyed to height, so tall desktops
   are untouched; phones already fit and are excluded by the width bound. */
@media (min-width: 640px) and (max-height: 840px) {
  .hero .hero-content { padding-top: 84px; padding-bottom: 104px; }
  .hero .script-word { font-size: clamp(34px, 4.4vw, 46px); }
  .hero .hero-kicker { margin-bottom: 18px; }
  .hero h1 { font-size: clamp(34px, 5vw, 56px); margin-bottom: 18px; }
  .hero .hero-cta { margin-top: 28px; }
}

.hero-scroll {
  position: absolute;
  bottom: 28px; left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  font-size: 10px;
  letter-spacing: 0.35em;
  text-transform: uppercase;
  color: rgba(255, 253, 249, 0.65);
}
.hero-scroll:hover { color: var(--gold-soft); }
/* Phones have the least room between the CTAs and the foot of the hero, so the
   cue is shorter and sits closer to the edge there. */
@media (max-width: 639px) {
  .hero-scroll { bottom: 18px; gap: 7px; }
  .scroll-line { height: 28px; }
}
/* letter-spacing adds a trailing gap after the final S, which pushes the
   glyphs left of the line when the flex box centres them. Reclaim it. */
.scroll-label { margin-right: -0.35em; }
.scroll-line { width: 1px; height: 42px; background: currentColor; animation: scrollPulse 2.4s var(--ease) infinite; }
@keyframes scrollPulse {
  0%, 100% { transform: scaleY(1); opacity: 0.5; }
  50% { transform: scaleY(0.55); opacity: 1; }
}

/* ---------- Sub-page hero (dark, quiet, serif) ---------- */
.page-hero {
  background: var(--ink);
  color: var(--cream);
  text-align: center;
  padding: 190px 24px 110px;
  position: relative;
  overflow: hidden;
}
.page-hero::before {
  content: "";
  position: absolute;
  top: -140px; right: -140px;
  width: 420px; height: 420px;
  border: 1px solid rgba(205, 181, 135, 0.22);
  border-radius: 50%;
}
.page-hero > * { position: relative; }
.page-hero::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 56px;
  transform: translateX(-50%);
  width: 1px; height: 34px;
  background: var(--gold);
  opacity: 0.7;
}
.page-hero .hero-kicker { margin-bottom: 20px; }
.page-hero h1 {
  font-size: clamp(36px, 5.5vw, 62px);
  font-weight: 500;
  color: var(--white);
  margin-bottom: 16px;
}
.page-hero .page-hero-sub {
  font-size: 16.5px;
  color: rgba(255, 253, 249, 0.72);
  max-width: 560px;
  margin: 0 auto;
}
.page-hero .ja-line {
  font-size: 13px;
  letter-spacing: 0.14em;
  color: var(--gold-soft);
  margin-top: 10px;
}

/* ---------- Sections (generous whitespace = luxury pacing) ---------- */
.section { padding: 110px 0; }
.section-tight { padding-top: 0; }
.section-cream { background: var(--cream); }
.section-dark { background: var(--ink); color: var(--cream); }

.container { max-width: 1200px; margin: 0 auto; padding: 0 24px; }

.section-kicker {
  /* Stated, not inherited: a section whose only heading is its kicker sets it as
     an <h2>, and must still look exactly like the <p> kickers everywhere else. */
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 16px;
}
.section-kicker::before {
  content: "";
  width: 44px;
  height: 1px;
  background: var(--gold);
  flex: none;
}
.center .section-kicker, .section-kicker.centered { justify-content: center; }
.section-kicker.centered::after { content: ""; width: 44px; height: 1px; background: var(--gold); flex: none; }
.section-dark .section-kicker { color: var(--gold-soft); }
.section-title { font-size: clamp(34px, 5vw, 56px); line-height: 1.15; margin-bottom: 18px; }
.section-lead { max-width: 600px; font-size: 17.5px; color: var(--ink-soft); margin-bottom: 64px; }
/* The line a block of copy closes on — the owner's own words, given the serif and
   the full ink colour so it reads as the conclusion, not another paragraph. */
.statement {
  max-width: 600px;
  font-family: var(--serif);
  font-size: 23px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--ink);
}
.section-dark .statement { color: var(--cream); }
.section-dark .section-lead { color: rgba(244, 240, 233, 0.72); }

.center { text-align: center; }
.muted { opacity: 0.6; font-size: 0.92em; }

/* ---------- Why grid ----------
   Near-rectangular cards; the big number sits at the top-left corner
   and deliberately breaks out of the card frame. */
.why-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 84px 32px;
  margin-top: 96px;
}
.why-card {
  position: relative;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 52px 30px 38px;
  text-align: left;
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.why-card:hover { transform: translateY(-6px); box-shadow: 0 18px 40px rgba(43, 38, 34, 0.08); }
.why-num {
  position: absolute;
  top: -52px;
  left: 20px;
  font-family: var(--serif);
  font-size: 96px;
  font-style: normal;
  font-weight: 500;
  /* Lining + tabular figures: without these, Cormorant falls back to
     old-style numerals, where 0 and 1 sit at different heights. */
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
  line-height: 0.85;
  color: var(--gold);
  letter-spacing: 0.02em;
  pointer-events: none;
}
.why-card h3 {
  font-size: 25px; margin-bottom: 12px; min-height: 63px;   /* 2 lines — keeps body copy on one baseline */
  /* Lining figures: Cormorant's old-style "10" otherwise drops below the
     x-height and reads as "ıo" — same fix as .hero-num / .why-num. */
  font-variant-numeric: lining-nums;
  font-feature-settings: "lnum" 1;
}
.why-card p { font-size: 16px; color: var(--ink-soft); }

/* ---------- Menu ----------
   Every card shares one vertical rhythm: the tag is absolutely placed so
   tagged and untagged cards start their title at the same height, and the
   duration/price slots reserve their tallest case. Result: titles, prices,
   lists and buttons line up across every card in a row. */
.menu-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 22px;
  /* Each card is only as tall as its own content. Stretching them to a common
     height was fine when the cards were static, but now that "View detail" opens
     one of them, a shared height would hollow out every other card in the row
     with the exact amount of space the open one needed. */
  align-items: start;
}
.menu-card {
  position: relative;
  border: 1px solid var(--line-light);
  border-radius: 14px;
  padding: 62px 34px 42px;   /* top padding reserves the tag row on every card */
  display: flex;
  flex-direction: column;
  transition: border-color 0.35s var(--ease), transform 0.35s var(--ease);
}
.menu-card:hover { border-color: var(--gold-soft); transform: translateY(-4px); }
.menu-featured { border-color: var(--gold); background: rgba(179, 146, 79, 0.08); box-shadow: 0 24px 60px rgba(0, 0, 0, 0.25); }
.menu-tag {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold-soft);
  margin-bottom: 14px;
}
.menu-card .menu-tag { position: absolute; top: 36px; left: 34px; margin: 0; }
/* The tag sits outside the flow, so a card without one keeps the reserved row
   as an empty band. Drop back to the tagless top padding the compact cards use. */
.menu-card-notag { padding-top: 42px; }
.menu-card h3 { font-size: 26px; color: var(--white); margin-bottom: 6px; min-height: 33px; }
.menu-duration {
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(244, 240, 233, 0.55);
  margin-bottom: 18px;
  min-height: 44px;          /* 2 lines — the "(depending on hair length)" case */
}
.menu-price {
  font-family: var(--price);
  font-size: 42px;
  font-weight: 600;
  font-variant-numeric: lining-nums tabular-nums;
  line-height: 1.15;
  letter-spacing: 0.005em;
  color: var(--gold-soft);
  margin-bottom: 24px;
  min-height: 97px;          /* reserves the 2-line "Men / Ladies" case */
}

/* The cards used to line their rows up with subgrid, which is tighter than the
   min-heights above — but subgrid rows are shared across the whole grid row, so
   one open "View detail" pushed every neighbouring card's button down by the same
   amount and left a hole. The min-heights align the closed state, which is the
   state a guest compares in, and each card is now free to grow alone. */
.menu-price sup { font-size: 0.5em; font-weight: 600; vertical-align: 0.62em; margin-right: 1px; }
.gst {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: rgba(244, 240, 233, 0.55);
  margin-left: 10px;
}
/* Cards that carry words instead of a figure (e.g. gift cards) keep the serif. */
.menu-price-text {
  font-family: var(--serif);
  font-weight: 500;
  font-size: 30px;
  line-height: 1.3;
}
.duration-note { text-transform: none; letter-spacing: 0.04em; opacity: 0.75; }
.price-split { font-size: 25px; display: inline-block; margin-right: 18px; }

/* ---------- Menu card: length-priced service ----------
   One service, three prices (Short / Medium / Long). A stacked list would read
   as three separate offers, so the three sit side by side in one bordered
   block — the same figure, three lengths — and stay side by side on a phone,
   which is why the price uses clamp() rather than a breakpoint.
   Used by the head spa card on the front page. */
.price-tiers {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border: 1px solid rgba(205, 181, 135, 0.32);
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 14px;
}
.price-tiers li { padding: 16px 6px 15px; text-align: center; }
.price-tiers li + li { border-left: 1px solid rgba(205, 181, 135, 0.22); }
.tier-name {
  display: block;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(244, 240, 233, 0.6);
  margin-bottom: 9px;
}
.tier-price {
  display: block;
  font-family: var(--price);
  font-size: clamp(26px, 3.2vw, 34px);
  font-weight: 600;
  font-variant-numeric: lining-nums tabular-nums;
  line-height: 1;
  color: var(--gold-soft);
}
.tier-price sup { font-size: 0.5em; font-weight: 600; vertical-align: 0.62em; margin-right: 1px; }

/* The optional extra. Dashed, not solid: it has to read as an add-on to the
   block above rather than a fourth price. */
.price-option {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 12px;
  font-size: 14.5px;
  color: rgba(244, 240, 233, 0.82);
  border: 1px dashed rgba(205, 181, 135, 0.45);
  border-radius: 12px;
  padding: 13px 16px;
  margin-bottom: 26px;
}
.price-option-label {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold-soft);
}
.price-option b {
  font-family: var(--price);
  font-size: 21px;
  font-weight: 600;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--white);
  margin-left: 2px;
}
.price-option b sup { font-size: 0.55em; vertical-align: 0.55em; }
.price-option-note { font-size: 13px; color: rgba(244, 240, 233, 0.5); }

/* ---------- Menu card: full-width hero card ----------
   The two length-priced spa services carry the menu, so each takes the whole
   grid row while the three secondary services share the row underneath. A card
   that wide would leave a lake of empty space beside a single price block, so
   from tablet up it splits in two: what the service is on the left, what it
   costs and how to book it on the right. Below that width the two halves simply
   stack, which is the order they are written in. */
.menu-card-main,
.menu-card-side { display: flex; flex-direction: column; }
.menu-sub {
  font-family: var(--serif);
  font-size: 17px;
  font-style: italic;
  line-height: 1.5;
  color: rgba(244, 240, 233, 0.72);
  margin-bottom: 10px;
}
/* Two or three lines saying what the service is. It also gives the left column
   enough body to sit against the price block opposite it. */
.menu-lead {
  font-size: 15.5px;
  line-height: 1.85;
  color: rgba(244, 240, 233, 0.72);
  max-width: 52ch;
  margin-bottom: 4px;
}
/* A hero card stands alone in its row, so it has nothing to line its duration
   up with — the two-line reservation would only open a gap above the lead. */
.menu-card-wide .menu-duration { min-height: 0; margin-bottom: 22px; }
@media (min-width: 780px) {
  .menu-card-wide {
    display: grid;
    grid-template-columns: 1fr minmax(300px, 0.72fr);
    column-gap: 54px;
    align-items: start;
  }
  /* The right column starts level with the title, not with the tag above it. */
  .menu-card-wide .menu-card-side { padding-top: 4px; }
}

/* ---------- Menu card: compact variant ----------
   The three secondary services sit under the hero cards and are built a size
   down, so the eye reaches the spa prices first. No tag row to reserve either,
   which is where most of the lost top padding goes. */
.menu-card-sm { padding: 42px 26px 34px; }
/* Two lines reserved: "Silk Kaizen Treatment" wraps in a narrow column, and
   without the reservation it would drop that card's price and button out of
   line with the two beside it. */
.menu-card-sm h3 { font-size: 21px; min-height: 56px; }
.menu-card-sm .menu-duration { font-size: 11.5px; margin-bottom: 14px; min-height: 40px; }
.menu-card-sm .menu-price { font-size: 34px; min-height: 76px; margin-bottom: 18px; }
.menu-card-sm .menu-price-text { font-size: 25px; }
.menu-card-sm .price-split { font-size: 21px; margin-right: 14px; }
.menu-card-sm .menu-detail { margin-bottom: 26px; }
.menu-card-sm .menu-detail summary { font-size: 11px; letter-spacing: 0.16em; }
.menu-card-sm .menu-includes li { font-size: 14.5px; padding: 8px 0 8px 20px; }
.menu-card-sm .btn-block { padding: 14px 24px; font-size: 12px; }

.menu-includes {
  list-style: none;
  margin-bottom: 32px;
  flex: 1;
}
.menu-includes li {
  font-size: 15.5px;
  color: rgba(244, 240, 233, 0.8);
  padding: 9px 0 9px 22px;
  border-bottom: 1px solid rgba(244, 240, 233, 0.08);
  position: relative;
}
.menu-includes li::before {
  content: "—";
  position: absolute; left: 0;
  color: var(--gold);
}
/* Sub-label inside a list (e.g. "Ladies" / "Men" on Cut & Style): no dash,
   gold small-caps, extra top space to separate the two groups. */
.menu-includes-head {
  padding-left: 0;
  border-bottom: none;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold-soft);
}
.menu-includes-head + li { padding-top: 4px; }
.menu-includes li.menu-includes-head:not(:first-child) { padding-top: 20px; }
/* Qualified with .menu-includes li, or `.menu-includes li::before` outranks it
   and the dash this rule exists to remove stays on the sub-label anyway. */
.menu-includes li.menu-includes-head::before { content: none; }
/* A sentence explaining the step above it, not an item in its own right — so
   it drops the dash but keeps the indent, staying flush with its heading. */
.menu-includes li.menu-includes-desc::before { content: none; }
/* Closing remark under an includes list — a note about the service, not an
   item in it, so it sits outside the dashes and off the gold rule. */
.menu-includes-note {
  font-size: 14.5px;
  line-height: 1.75;
  color: rgba(244, 240, 233, 0.62);
  margin: 18px 0 0;
  padding-left: 18px;
  border-left: 2px solid rgba(205, 181, 135, 0.35);
}

/* ---------- Menu card: "View detail" ----------
   What's included is the detail, not the offer — folding it away keeps every
   card to name / duration / price / CTA at a glance, and makes the six cards
   comparable in one screen. Built on <details> like the FAQ, so it opens with
   JS disabled. The booking button deliberately stays outside the toggle. */
.menu-detail {
  flex: 1;
  margin-bottom: 32px;
}
.menu-detail summary {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-soft);
  transition: color 0.3s var(--ease);
}
.menu-detail summary::-webkit-details-marker { display: none; }
.menu-detail summary:hover { color: var(--gold); }
/* Reuses the FAQ's gold plus/minus, one size down to sit on a 12px label. */
.menu-detail .faq-icon { width: 26px; height: 26px; margin-top: 0; }
.menu-detail .faq-icon::before,
.menu-detail .faq-icon::after { width: 11px; }
.menu-detail[open] .faq-icon { background: var(--gold-soft); }
.menu-detail[open] .faq-icon::before,
.menu-detail[open] .faq-icon::after { background: var(--ink); }
.menu-detail[open] .faq-icon::after { transform: translate(-50%, -50%) rotate(0deg); }
.menu-detail .menu-includes {
  flex: none;
  margin: 6px 0 0;
  animation: faqReveal 0.45s var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .menu-detail .menu-includes { animation: none; }
}

/* ---------- What is a Head Spa? ----------
   Dry vs wet, stacked one above the other so the comparison reads
   top-to-bottom, each with its own image. */
.spa-types {
  display: grid;
  grid-template-columns: 1fr;
  gap: 28px;
}
.spa-type {
  display: grid;
  grid-template-columns: 1fr;
  border: 1px solid var(--line);
  border-radius: 26px;
  background: var(--white);
  overflow: hidden;          /* lets the image sit flush inside the rounded frame */
}
.spa-type-media {
  min-height: 240px;
  aspect-ratio: 4 / 3;
  border: none;
  border-bottom: 1px solid var(--line);
}
.spa-type-body { padding: 40px 34px 44px; }
.spa-type .menu-tag { color: var(--gold); position: static; margin-bottom: 14px; }
.spa-type h3 { font-size: 29px; margin-bottom: 12px; }
.spa-type p { font-size: 16.5px; color: var(--ink-soft); }
.spa-type.is-dreamin {
  border-color: var(--gold);
  background: var(--ink);
  color: var(--cream);
}
.spa-type.is-dreamin h3 { color: var(--white); }
.spa-type.is-dreamin p { color: rgba(244, 240, 233, 0.8); }
.spa-type.is-dreamin .menu-tag { color: var(--gold-soft); }
.spa-type.is-dreamin .spa-type-media { border-bottom-color: rgba(205, 181, 135, 0.3); }
.spa-type-note {
  margin-top: 18px;
  font-family: var(--serif);
  font-style: italic;
  font-size: 18px !important;
  color: var(--gold-soft) !important;
}

/* ---------- The Dreamin' Method — full-bleed photographic band ----------
   The two spa-type cards above are image-beside-text; repeating that here
   made the whole section read as one long list. So this one inverts it:
   the photo runs edge to edge and the copy sits on top of it. It also
   carries the page from the cream section into the dark menu below. */
.method-band {
  position: relative;
  isolation: isolate;
  padding: 100px 0;
  color: var(--cream);
  background: var(--ink);
  overflow: hidden;
}
/* The dark Menu section follows immediately below; without an edge the two
   read as one continuous slab. Same gold hairline the sticky CTA uses. */
.method-band::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  z-index: 1;
  background: linear-gradient(90deg, transparent 0%, rgba(205, 181, 135, 0.55) 50%, transparent 100%);
}
.method-bg {
  position: absolute;
  inset: 0;
  z-index: -2;
  background-size: cover;
  background-position: center;
}
/* Lighter on the left so the salon itself stays visible, heavy on the right
   so the panel's copy always has contrast behind it. */
.method-scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(90deg, rgba(43, 38, 34, 0.10) 0%, rgba(43, 38, 34, 0.48) 48%, rgba(43, 38, 34, 0.84) 100%),
    linear-gradient(180deg, rgba(43, 38, 34, 0.34) 0%, rgba(43, 38, 34, 0.12) 42%, rgba(43, 38, 34, 0.5) 100%);
}
.method-panel {
  background: rgba(33, 29, 26, 0.72);
  backdrop-filter: blur(7px);
  border: 1px solid rgba(205, 181, 135, 0.26);
  border-radius: 26px;
  padding: 40px 32px;
}
.method-panel .section-kicker { color: var(--gold-soft); }
.method-panel .section-kicker::before { background: var(--gold-soft); }
.method-panel h2 {
  font-size: clamp(27px, 3.2vw, 40px);
  color: var(--white);
  margin-bottom: 18px;
}
.method-panel h2 em { color: var(--gold-soft); }
.method-panel p {
  font-size: 16.5px;
  color: rgba(244, 240, 233, 0.84);
  margin-bottom: 16px;
}
.method-panel p:last-child { margin-bottom: 0; }
.method-panel p em {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.08em;
  color: var(--gold-soft);
}
/* "Inside the Dreamin' Method" is long; on a phone the leading dash strands
   it across three lines. Drop the dash and give the words the full width. */
@media (max-width: 560px) {
  .method-panel { padding: 34px 26px; }
  .method-panel .section-kicker { font-size: 11px; letter-spacing: 0.24em; gap: 0; }
  .method-panel .section-kicker::before { display: none; }
}

/* ---------- Instagram grid ---------- */
.ig-count {
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
  display: inline-block;
  margin-left: 14px;
  vertical-align: middle;
}
/* Reels are tall; stacked vertically on a phone the section ran forever.
   So they swipe sideways instead — same scroll-snap rail as the reviews.
   overflow-y is pinned to hidden: setting only overflow-x makes overflow-y
   compute to auto, and the horizontal scrollbar then steals enough height
   from the content box to raise a spurious vertical scrollbar. */
.ig-grid {
  display: flex;
  align-items: flex-start;       /* not stretch: the crop boxes size themselves */
  gap: 16px;
  margin: 48px 0 40px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  padding-bottom: 18px;          /* room for the scrollbar to sit in */
  -webkit-overflow-scrolling: touch;
  scrollbar-color: var(--gold) rgba(43, 38, 34, 0.12);
  scrollbar-width: thin;
}
.ig-grid > * {
  flex: 0 0 min(78vw, 320px);
  scroll-snap-align: start;
}
.ig-tile {
  aspect-ratio: 1;
  border-radius: 8px;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.ig-tile:hover { opacity: 0.85; transform: scale(0.985); }

/* Cropping the embed down to just the reel.
   embed.js rewrites each blockquote into a cross-origin iframe, so Instagram's
   chrome — the profile header on top, and the "View more on Instagram" link,
   like/comment/share bar and comment box underneath — cannot be styled away. It
   can only be clipped from outside, which is what .ig-embed does.

   The frame lays out the same way at any width:
       54px           profile header
       width × 1.25   the media itself (4:5)
       154px          the like / comment / share chrome
   So the wrapper takes the media's 4:5 box and the iframe is pulled up by the
   header; overflow hides what falls outside at both ends. The reel still plays —
   clicks pass straight through to the iframe.

   These are Instagram's current numbers, measured against the live embed. If they
   ever restyle it the crop will drift, and re-measuring is the fix. */
.ig-embed {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 5;                 /* the media box, exactly */
  border-radius: 12px;
  background: var(--cream-deep);       /* shows for the moment before the reel paints */
}
.ig-grid .instagram-media {
  position: absolute !important;
  top: -54px !important;               /* lop off the profile header */
  left: 0 !important;
  width: 100% !important;
  min-width: 0 !important;
  max-width: 100% !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}

/* ---------- Voice / testimonials (horizontal scroll) ---------- */
.voice-grid {
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;          /* stops the sideways rail raising a vertical scrollbar */
  scroll-snap-type: x mandatory;
  gap: 22px;
  margin-top: 26px;
  padding-bottom: 18px;
  -webkit-overflow-scrolling: touch;
  scrollbar-color: var(--gold) rgba(244, 240, 233, 0.12);
  scrollbar-width: thin;
}
.voice-card {
  flex: 0 0 min(86%, 400px);
  scroll-snap-align: start;
  border: 1px solid var(--line-light);
  border-radius: 26px;
  padding: 40px 34px 36px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  position: relative;
}
.voice-card::before {
  content: "\201C";
  position: absolute;
  top: 6px; right: 26px;
  font-family: var(--serif);
  font-size: 110px;
  line-height: 1;
  color: rgba(205, 181, 135, 0.22);
  pointer-events: none;
}
.stars { color: var(--gold-soft); letter-spacing: 0.2em; font-size: 14px; }
.voice-card blockquote {
  font-family: var(--serif);
  font-size: 21px;
  line-height: 1.55;
  color: var(--cream);
  flex: 1;
}
.voice-card figcaption {
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(244, 240, 233, 0.55);
}

/* ---------- Contact ---------- */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 44px;
  margin-top: 30px;
}
.contact-info dl { margin-bottom: 38px; }
.contact-info dt {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 6px;
}
.contact-info dd { font-size: 17px; margin: 0 0 26px; color: var(--ink-soft); }
.contact-info dd a { color: var(--ink); border-bottom: 1px solid var(--gold-soft); }
.contact-info dd a:hover { color: var(--gold); }
.contact-map { min-height: 340px; border-radius: 26px; }

/* ---------- Enquiry form ----------
   Rounded, generously spaced fields: the same silhouette as the buttons, so the
   form reads as part of the brand rather than a bolted-on WordPress widget. */
/* The header is fixed, so an #enquiry jump from another page would otherwise
   land with the heading tucked underneath it. */
#enquiry { scroll-margin-top: 90px; }
.enquiry-wrap { max-width: 760px; }
.enquiry-title { font-size: clamp(30px, 4.4vw, 44px); color: var(--gold); margin-bottom: 14px; }
.enquiry-lead { color: var(--ink-soft); margin-bottom: 38px; max-width: 62ch; }

.enquiry-form { display: flex; flex-direction: column; gap: 24px; }
.field { display: flex; flex-direction: column; gap: 8px; }
.field label {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.field .req { color: var(--gold); }
.field input,
.field textarea {
  font-family: var(--sans);
  font-size: 16.5px;
  font-weight: 300;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 26px;
  padding: 16px 22px;
  width: 100%;
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.field textarea { border-radius: 20px; resize: vertical; min-height: 180px; }
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(179, 146, 79, 0.14);
}
/* Only after a failed submit — never while the guest is still typing. */
.enquiry-form.is-validated :invalid { border-color: #b4553f; }
.field-error { font-size: 13.5px; color: #b4553f; letter-spacing: 0; text-transform: none; }
.field-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.enquiry-form .btn { align-self: flex-start; border: none; cursor: pointer; }
.form-note { font-size: 15px; color: var(--ink-soft); margin: 0; }
.form-note:empty { display: none; }
.form-note.is-error { color: #b4553f; }
.form-note.is-success { color: var(--gold); }

@media (min-width: 640px) {
  .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
}

/* Google Maps embed */
.map-embed {
  min-height: 400px;
  border-radius: 26px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--cream-deep);
}
.map-embed iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 400px;
  border: 0;
  filter: saturate(0.85);   /* keeps Google's palette from fighting the brand */
}

/* ---------- About page photography ----------
   Arch-topped, echoing the round mirrors in the salon. The images are
   portrait; the frame crops them rather than letterboxing. */
.about-photo {
  aspect-ratio: 3 / 4;              /* the photos' own shape — frames them without cropping */
  overflow: hidden;
  border-radius: 260px 260px 18px 18px;
  border: 1px solid var(--line);
  background: var(--cream-deep);
}
.section-dark .about-photo { border-color: rgba(205, 181, 135, 0.28); }
.about-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* ---------- Generic content page (privacy etc.) ---------- */
.prose { max-width: 720px; }
.prose h2 { font-size: 26px; margin: 48px 0 14px; }
.prose h2:first-child { margin-top: 0; }
.prose p, .prose li { font-size: 16.5px; color: var(--ink-soft); margin-bottom: 14px; }
.prose ul { padding-left: 20px; margin-bottom: 14px; }
.prose .updated { font-size: 12.5px; letter-spacing: 0.1em; text-transform: uppercase; opacity: 0.55; }

/* ---------- CTA band (used on sub-pages before footer) ----------
   Photographed backdrop. The shot is bright and the copy on top is white,
   so the scrim above it is doing real work — don't lighten it without
   re-checking the text and the gold button against it. */
.cta-band {
  color: var(--cream);
  text-align: center;
  padding: 110px 24px;
  position: relative;
  overflow: hidden;
  background: var(--ink);
}
.cta-band::before {
  content: "";
  position: absolute;
  bottom: -180px; left: -120px;
  width: 380px; height: 380px;
  border: 1px solid rgba(205, 181, 135, 0.2);
  border-radius: 50%;
}
.cta-band::after {
  content: "";
  position: absolute;
  top: -160px; right: -100px;
  width: 320px; height: 320px;
  border: 1px solid rgba(205, 181, 135, 0.14);
  border-radius: 50%;
}
/* The photo sits on its own layer so it can be softened. Left sharp, the
   business card's own logotype lands right behind the CTA copy and the two
   sets of type fight; blurred, it reads as brand atmosphere instead.
   The scale hides the blur's feathered edges. */
/* Note the .cta-band prefix: `.cta-band > *` below sets position:relative at
   the same specificity, and being later it would otherwise win and collapse
   this layer to zero height. */
.cta-band .cta-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: url("assets/37c173e23a55244ef5e625ebebb84173-scaled.jpg") center 66% / cover no-repeat;
  /* The shot is dominated by a large white card and the copy on top is white,
     so this has to come down hard — at anything brighter the headline sits on
     a pale slab and the card's own logotype competes with it. */
  filter: blur(5px) brightness(0.36) saturate(0.5) sepia(0.42);
  transform: scale(1.08);
  pointer-events: none;
}
.cta-band > * { position: relative; z-index: 1; }
.cta-band h2 { font-size: clamp(28px, 4vw, 42px); color: var(--white); margin-bottom: 14px; }
.cta-band p { color: rgba(244, 240, 233, 0.7); max-width: 540px; margin: 0 auto 36px; font-size: 16.5px; }

/* ---------- Footer ----------
   Tall, centred column: logo → vertical menu → copyright at the
   bottom centre. The sticky CTA hides once the footer is in view. */
.site-footer {
  background: #211d1a;
  color: var(--cream);
  padding: 56px 0 28px;
}

/* Three columns on desktop — logo left, menu centre, actions right — with the
   copyright on its own centred row beneath. On a phone it collapses to a
   single centred column, kept short: the menu goes two-up and the gift card
   shrinks, so the footer doesn't turn into a second page. */
.footer-grid {
  display: grid;
  grid-template-columns: 1fr;
  justify-items: center;
  align-items: start;
  gap: 28px;
  text-align: center;
}
.site-footer .logo-footer .logo-img { height: 48px; }

.footer-nav {
  display: grid;
  grid-template-columns: repeat(2, auto);   /* two-up on mobile — halves the height */
  justify-content: center;
  gap: 14px 30px;
}
.footer-nav a {
  color: rgba(244, 240, 233, 0.7);
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.footer-nav a:hover { color: var(--gold-soft); }
.footer-nav .nav-insta { color: var(--gold-soft); }

/* On a phone the two buttons sit side by side and the gift card and privacy
   link take their own full-width rows — a stacked column here made the footer
   almost a screen tall on its own. The desktop rule stacks them again. */
.footer-side {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 12px;
}
.footer-side .btn { text-align: center; padding: 13px 20px; font-size: 12px; }
.footer-gift, .footer-privacy { flex: 1 0 100%; }
.footer-privacy {
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(244, 240, 233, 0.55);
}
.footer-privacy:hover { color: var(--gold-soft); }

/* The gift voucher itself, as the link — the card is the affordance, so it
   gets a light plate behind it to lift off the near-black footer. */
.footer-gift {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  color: rgba(244, 240, 233, 0.7);
}
.footer-gift img {
  width: 146px;                 /* small on a phone; the desktop rule sizes it up */
  max-width: 100%;
  height: auto;
  border-radius: 6px;
  background: var(--white);
  padding: 7px;
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.footer-gift:hover img {
  transform: translateY(-3px);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35);
}
.footer-gift span {
  font-family: var(--serif);
  font-style: italic;
  font-size: 15px;
}
.footer-gift:hover span { color: var(--gold-soft); }

.copyright {
  font-size: 12.5px;
  color: rgba(244, 240, 233, 0.4);
  margin-top: 44px;
  padding: 0 24px;
  text-align: center;
}

/* ---------- Floating booking banner (hides over the footer) ---------- */
.sticky-cta {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 90;
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, rgba(33, 29, 26, 0.9) 0%, rgba(33, 29, 26, 0.98) 100%);
  backdrop-filter: blur(10px);
  border-top: 1px solid rgba(205, 181, 135, 0.3);
  transition: transform 0.45s var(--ease), opacity 0.45s var(--ease);
}
.sticky-cta::before {
  /* soft gold hairline glow along the top edge */
  content: "";
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent 0%, var(--gold-soft) 50%, transparent 100%);
  opacity: 0.9;
}
.sticky-cta.is-hidden {
  transform: translateY(110%);
  opacity: 0;
  pointer-events: none;
}
.sticky-cta-inner {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
}
.sticky-cta-brand {
  display: flex;
  align-items: center;
  gap: 16px;
  min-width: 0;
}
.sticky-cta-script {
  font-family: var(--script);
  font-size: 28px;
  line-height: 1;
  color: var(--gold-soft);
  flex: none;
  transform: translateY(-2px);
}
.sticky-cta-text {
  font-family: var(--serif);
  font-style: italic;
  font-size: 15.5px;
  color: rgba(244, 240, 233, 0.78);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border-left: 1px solid rgba(205, 181, 135, 0.35);
  padding-left: 16px;
}
.sticky-cta-text .sticky-cta-dot { color: var(--gold); margin: 0 6px; }
.sticky-cta-actions { display: flex; align-items: center; gap: 10px; flex: none; }
.sticky-cta-shop { padding: 11px 22px; font-size: 12px; letter-spacing: 0.1em; }
.sticky-cta .btn-gold { padding: 12px 30px; }
/* Both actions stay on phones — Online Shop is a destination, not a detail,
   so the buttons tighten rather than one dropping out. */
@media (max-width: 639px) {
  .sticky-cta-text { display: none; }   /* keep the script mark only */
  .sticky-cta-shop { padding: 11px 15px; font-size: 11px; letter-spacing: 0.06em; }
  .sticky-cta .btn-gold { padding: 12px 17px; font-size: 11px; letter-spacing: 0.06em; }
  .sticky-cta-inner { gap: 10px; }
  .sticky-cta-actions { gap: 8px; }
}

/* ---------- Scroll fade-in (restrained) ---------- */
.fade-in {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.fade-in.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .fade-in { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}
/* Sibling .fade-in elements get an incremental transition-delay from
   script.js, so grids and header groups reveal in sequence rather than
   as one block. Cards with their own hover transitions have .fade-in
   removed once the entrance finishes (also script.js), handing the
   transition property back to the hover styles. */

/* ---------- Entrance choreography (above the fold) ----------
   The scroll observer can't stagger content that is already in view on
   load, so the hero and sub-page heroes run a one-shot rise instead. */
@keyframes riseIn {
  from { opacity: 0; transform: translateY(26px); }
  to { opacity: 1; transform: none; }
}
.hero-content > * { animation: riseIn 0.9s var(--ease) both; }
.hero-content > *:nth-child(1) { animation-delay: 0.15s; }
.hero-content > *:nth-child(2) { animation-delay: 0.3s; }
.hero-content > *:nth-child(3) { animation-delay: 0.45s; }
.hero-content > *:nth-child(4) { animation-delay: 0.6s; }
.hero-content > *:nth-child(5) { animation-delay: 0.75s; }
/* .hero-scroll is centred with translateX(-50%). riseIn ends on
   `transform: none`, which (with fill-mode both) would wipe that out and
   leave the indicator half its width right of centre — so it rises with a
   variant that keeps the centring translate. */
@keyframes riseInCentred {
  from { opacity: 0; transform: translateX(-50%) translateY(26px); }
  to { opacity: 1; transform: translateX(-50%); }
}
.hero-scroll { animation: riseInCentred 0.9s var(--ease) 1.15s both; }

.page-hero > * { animation: riseIn 0.8s var(--ease) both; }
.page-hero > *:nth-child(1) { animation-delay: 0.1s; }
.page-hero > *:nth-child(2) { animation-delay: 0.22s; }
.page-hero > *:nth-child(3) { animation-delay: 0.34s; }

/* The gold rule beside each kicker draws itself in once the kicker
   becomes visible — a quiet cue that a new chapter is starting. */
.section-kicker.fade-in::before,
.section-kicker.fade-in.centered::after {
  width: 0;
  transition: width 0.7s var(--ease) 0.35s;
}
.section-kicker.fade-in.is-visible::before,
.section-kicker.fade-in.is-visible.centered::after { width: 44px; }

/* Decorative circles on dark heroes/bands breathe very slowly. */
@keyframes circleDrift {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(-16px, 12px); }
}
.page-hero::before, .cta-band::before { animation: circleDrift 16s ease-in-out infinite; }
.cta-band::after { animation: circleDrift 22s ease-in-out infinite reverse; }

@media (prefers-reduced-motion: reduce) {
  .hero-content > *, .hero-scroll, .page-hero > *,
  .page-hero::before, .cta-band::before, .cta-band::after { animation: none; }
  .section-kicker.fade-in::before,
  .section-kicker.fade-in.centered::after { width: 44px; transition: none; }
  .btn-gold::before { display: none; }
  .sticky-cta { transition: opacity 0.2s linear; }
  .logo-img { transition: none; }
}

/* ---------- FAQ accordion ----------
   Built on <details>/<summary> so it still opens with JS disabled and
   maps cleanly onto a WordPress accordion block later. */
.faq-list {
  max-width: 860px;
  border-top: 1px solid var(--line);
}
.faq-item {
  border-bottom: 1px solid var(--line);
}
.faq-item summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  padding: 26px 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--serif);
  font-size: 21px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink);
  transition: color 0.3s var(--ease);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--gold); }

/* Gold plus that rotates into a minus when open */
.faq-icon {
  flex: none;
  position: relative;
  width: 34px; height: 34px;
  margin-top: 2px;
  border: 1px solid var(--gold);
  border-radius: 50%;
  transition: background 0.35s var(--ease), transform 0.35s var(--ease);
}
.faq-icon::before, .faq-icon::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 13px; height: 1px;
  background: var(--gold);
  transform: translate(-50%, -50%);
  transition: transform 0.35s var(--ease), background 0.35s var(--ease);
}
.faq-icon::after { transform: translate(-50%, -50%) rotate(90deg); }
.faq-item[open] .faq-icon { background: var(--gold); }
.faq-item[open] .faq-icon::before,
.faq-item[open] .faq-icon::after { background: var(--white); }
.faq-item[open] .faq-icon::after { transform: translate(-50%, -50%) rotate(0deg); }

.faq-answer {
  padding: 0 60px 30px 0;
  font-size: 16.5px;
  color: var(--ink-soft);
  animation: faqReveal 0.45s var(--ease);
}
.faq-answer p + p { margin-top: 12px; }
.faq-answer em { font-family: var(--serif); font-size: 1.06em; color: var(--ink); }
@keyframes faqReveal {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .faq-answer { animation: none; }
}

/* Dark-section variant (Service Menu page) */
.section-dark .faq-list { border-top-color: var(--line-light); }
.section-dark .faq-item { border-bottom-color: var(--line-light); }
.section-dark .faq-item summary { color: var(--cream); }
.section-dark .faq-item summary:hover { color: var(--gold-soft); }
.section-dark .faq-icon { border-color: var(--gold-soft); }
.section-dark .faq-icon::before,
.section-dark .faq-icon::after { background: var(--gold-soft); }
.section-dark .faq-item[open] .faq-icon { background: var(--gold-soft); }
.section-dark .faq-item[open] .faq-icon::before,
.section-dark .faq-item[open] .faq-icon::after { background: var(--ink); }
.section-dark .faq-answer { color: rgba(244, 240, 233, 0.75); }
.section-dark .faq-answer em { color: var(--cream); }

/* Line under the accordion pointing at the remaining question: "still unsure? call us" */
.faq-foot {
  max-width: 860px;
  margin-top: 40px;
  font-size: 16px;
  color: var(--ink-soft);
}
.section-dark .faq-foot { color: rgba(244, 240, 233, 0.7); }
.faq-foot a { border-bottom: 1px solid var(--gold-soft); }

/* ---------- Blog / Journal ----------
   Category filter + card grid. Filtering is class-based on the cards, so
   swapping in WordPress term slugs later needs no CSS change. */
.blog-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 52px;
}
.filter-btn {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 11px 24px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background 0.3s var(--ease), color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.filter-btn:hover { border-color: var(--gold); color: var(--gold); }
.filter-btn[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--gold-soft);
}

.post-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 44px 30px;
}
.post-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.post-card:hover { transform: translateY(-6px); box-shadow: 0 18px 40px rgba(43, 38, 34, 0.09); }
.post-card.is-hidden { display: none; }
.post-media {
  aspect-ratio: 3 / 2;
  border: none;
  border-bottom: 1px solid var(--line);
}
.post-body { padding: 30px 28px 32px; display: flex; flex-direction: column; flex: 1; }
.post-cat {
  align-self: flex-start;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 14px;
}
.post-card h3 {
  font-size: 25px;
  line-height: 1.3;
  margin-bottom: 12px;
}
.post-card h3 a { color: var(--ink); }
.post-card h3 a:hover { color: var(--gold); }
.post-excerpt { font-size: 16px; color: var(--ink-soft); flex: 1; }
.post-meta {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(43, 38, 34, 0.5);
}
/* "Read →" is its own link (alongside the title), so pressing it reacts on
   Read itself — not on the title. Default black; warms to gold on hover/press
   with the arrow sliding forward (on-tone with .inline-link-arrow). No underline. */
.post-more {
  color: var(--ink);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.3s var(--ease);
}
.post-more span { display: inline-block; transition: transform 0.3s var(--ease); }
/* Hover reacts to a real pointer only, so the gold never "sticks" on Read
   after a touch tap — it returns to black once you navigate back. */
@media (hover: hover) and (pointer: fine) {
  .post-more:hover,
  .post-more:focus-visible { color: var(--gold); }
  .post-more:hover span,
  .post-more:focus-visible span { transform: translateX(5px); }
}
/* Press feedback (touch + keyboard) — momentary gold + arrow nudge, and it
   clears the instant you release, so nothing lingers after you come back. */
.post-more:active { color: var(--gold); }
.post-more:active span { transform: translateX(9px); }
@media (prefers-reduced-motion: reduce) {
  .post-more span,
  .post-more:hover span,
  .post-more:focus-visible span,
  .post-more:active span { transition: none; transform: none; }
}

/* Empty state when a filter matches nothing (relevant once posts are real) */
.post-empty {
  display: none;
  padding: 60px 0;
  font-family: var(--serif);
  font-style: italic;
  font-size: 21px;
  color: var(--ink-soft);
}
.post-empty.is-shown { display: block; }

/* ---------- Single article ---------- */
.article { max-width: 760px; margin: 0 auto; }
.article .post-cat { display: block; margin-bottom: 18px; }
.article-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  margin-bottom: 42px;
  font-size: 12.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(43, 38, 34, 0.5);
}
.article-lead {
  font-family: var(--serif);
  font-size: 23px;
  font-style: italic;
  line-height: 1.5;
  color: var(--ink);
  margin-bottom: 36px;
  padding-left: 24px;
  border-left: 2px solid var(--gold);
}
.article-media { aspect-ratio: 16 / 9; border-radius: 14px; margin: 40px 0; }
/* In-body photography. Some articles arrive with shots taken during the treatment
   they describe (see tools/pages-import/figures.py); the caption carries what a
   guest would be told about that image in the chair. A portrait phone photo at the
   full 760px column is taller than the viewport, so cap the height and centre it. */
.article-figure { margin: 40px 0; }
.article-figure img {
  display: block;
  width: auto;
  height: auto;          /* the width/height attributes are aspect-ratio hints only */
  max-width: 100%;
  max-height: 620px;
  margin: 0 auto;
  border-radius: 14px;
}
.article-figure figcaption {
  margin-top: 12px;
  font-size: 14px;
  font-style: italic;
  line-height: 1.55;
  color: rgba(43, 38, 34, 0.55);
  text-align: center;
}
/* Shots that only mean something side by side (the same scalp, four conditions). */
.article-figures {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px 20px;
  margin: 40px 0;
}
.article-figures .article-figure { margin: 0; }
.article-figures .article-figure img { width: 100%; height: auto; max-height: none; }
.article-figures .article-figure figcaption { margin-top: 10px; font-size: 13.5px; }
@media (max-width: 560px) {
  .article-figures { grid-template-columns: 1fr; gap: 30px; }
}
.article h2 { font-size: 30px; margin: 48px 0 16px; }
.article p { font-size: 17px; color: var(--ink-soft); margin-bottom: 18px; }
.article ul { padding-left: 22px; margin-bottom: 18px; }
.article li { font-size: 17px; color: var(--ink-soft); margin-bottom: 8px; }
/* Inline links in the article body (product names etc.). Plain gold on the
   light background reads as body copy, so give them the same underlined-amber
   affordance as .inline-link — using the deeper --gold for contrast on cream.
   Buttons (.btn) and the "Back to Journal" link keep their own styling. */
.article a:not(.btn):not(.article-back) {
  color: var(--gold);
  font-weight: 600;
  border-bottom: 1px solid rgba(179, 146, 79, 0.5);
  padding-bottom: 1px;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.article a:not(.btn):not(.article-back):hover,
.article a:not(.btn):not(.article-back):focus-visible {
  color: var(--ink);
  border-bottom-color: var(--ink);
}
.article blockquote {
  margin: 36px 0;
  padding: 28px 30px;
  background: var(--white);
  border-left: 2px solid var(--gold);
  border-radius: 0 14px 14px 0;
  font-family: var(--serif);
  font-size: 21px;
  line-height: 1.55;
  color: var(--ink);
}
.article blockquote cite {
  display: block;
  margin-top: 14px;
  font-family: var(--sans);
  font-size: 12px;
  font-style: normal;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(43, 38, 34, 0.5);
}
/* Comparison tables (hard vs soft water, treatment vs mask, iron temperatures…).
   The wrapper scrolls on its own so a two-column table never widens the page on a
   phone; the table itself stays full width inside it. */
.article-table {
  overflow-x: auto;
  margin: 32px 0;
  -webkit-overflow-scrolling: touch;
}
.article table {
  width: 100%;
  min-width: 420px;
  border-collapse: collapse;
  background: var(--white);
  border-radius: 14px;
  overflow: hidden;
  font-size: 16px;
}
.article thead th {
  font-family: var(--serif);
  font-size: 19px;
  font-weight: 500;
  text-align: left;
  color: var(--ink);
  background: rgba(176, 141, 79, 0.09);
  padding: 16px 20px;
  border-bottom: 1px solid var(--gold);
}
.article tbody td {
  padding: 14px 20px;
  color: var(--ink-soft);
  border-bottom: 1px solid rgba(43, 38, 34, 0.08);
  vertical-align: top;
}
.article tbody tr:last-child td { border-bottom: 0; }
.article-back {
  display: inline-block;
  margin-top: 50px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* Inline "read more" link that sits at the end of a paragraph. Given a standing
   underline + arrow so it reads as an interactive control at rest (not body
   text), and a colour lift + arrow slide on hover/focus. */
.inline-link {
  display: inline-block;
  color: var(--gold-soft);
  font-weight: 600;
  border-bottom: 1px solid rgba(205, 181, 135, 0.45);
  padding-bottom: 1px;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.inline-link:hover,
.inline-link:focus-visible {
  color: #ecdcb4;
  border-bottom-color: #ecdcb4;
}
.inline-link-arrow {
  display: inline-block;
  transition: transform 0.3s var(--ease);
}
.inline-link:hover .inline-link-arrow,
.inline-link:focus-visible .inline-link-arrow {
  transform: translateX(5px);
}

/* ---------- Language scaffold: hide JA-only lines in EN mode etc. ---------- */
/* Elements marked lang="ja" that are supplementary stay visible in both modes.
   Full bilingual content swap: add [data-en]/[data-ja] handling in script.js. */

/* ---------- Breakpoints ---------- */
.hide-sm { display: none; }

/* Keep the hero H1's first line unbroken on desktop only; mobile may wrap. */
@media (min-width: 640px) {
  .hero-nowrap { white-space: nowrap; }
}

@media (min-width: 640px) {
  .hide-sm { display: inline; }
  .why-grid { grid-template-columns: repeat(2, 1fr); }
  /* Five-card variant (home): flex so the odd row centres itself — 2+2+1 here,
     3+2 on desktop — instead of leaving an orphan in the first grid column. */
  .why-grid.is-five { display: flex; flex-wrap: wrap; justify-content: center; }
  .why-grid.is-five .why-card { flex: 0 0 calc((100% - 32px) / 2); }
  .menu-grid { grid-template-columns: repeat(2, 1fr); }
  /* The two length-priced spa cards take the whole row at every width — one
     column here, three on desktop — so the secondary services never sit beside
     them competing for the same glance. */
  .menu-card-wide { grid-column: 1 / -1; }
  .ig-grid > * { flex-basis: min(46%, 320px); }

  /* Image beside copy; the two blocks mirror each other. */
  .spa-type { grid-template-columns: 5fr 6fr; align-items: center; }
  .spa-type-media { height: 100%; aspect-ratio: auto; min-height: 300px; border-bottom: none; border-right: 1px solid var(--line); }
  .spa-type.is-dreamin .spa-type-media { order: 2; border-right: none; border-left: 1px solid rgba(205, 181, 135, 0.3); }
  .spa-type-body { padding: 48px 40px; }

  /* Copy moves off-centre, sitting to the right over the photograph. */
  .method-band { padding: 120px 0; }
  .method-panel { max-width: 560px; margin-left: auto; padding: 46px 44px; }

  .post-grid { grid-template-columns: repeat(2, 1fr); }
}

/* The three compact menu cards go three-across as soon as the hero cards split
   into two columns, so the set never breaks 2 + 1 and strands one card alone. */
@media (min-width: 780px) {
  .menu-grid { grid-template-columns: repeat(3, 1fr); }
}

/* Footer opens out into its three columns once there is room for them. */
@media (min-width: 900px) {
  .site-footer { padding: 96px 0 36px; }
  .footer-grid {
    grid-template-columns: auto 1fr auto;
    justify-items: stretch;
    align-items: start;
    gap: 48px;
    text-align: left;
  }
  .footer-grid .logo-footer { justify-self: start; }

  .footer-nav {
    grid-template-columns: auto;      /* back to one vertical column */
    justify-self: center;
    gap: 16px;
    text-align: center;
  }
  .footer-nav .nav-insta { justify-content: center; }

  .footer-side {
    justify-self: end;
    flex-direction: column;      /* back to a stack, right-aligned */
    align-items: flex-end;
    gap: 14px;
  }
  .footer-side .btn { min-width: 190px; padding: 14px 34px; font-size: 13px; }
  .footer-gift, .footer-privacy { flex: 0 0 auto; }
  .footer-gift { align-items: flex-end; }
  .footer-gift img { width: 210px; }
  .site-footer .logo-footer .logo-img { height: 60px; }
}

@media (min-width: 960px) {
  .main-nav { display: flex; }
  .nav-burger { display: none; }
  .header-actions .btn-shop,
  .header-actions .btn-gold { display: inline-block; }
  .header-ig { display: inline-flex; }

  .section { padding: 150px 0; }
  .section-tight { padding-top: 0; }
  .why-grid { grid-template-columns: repeat(4, 1fr); }
  .why-grid.is-five .why-card { flex-basis: calc((100% - 64px) / 3); }
  .menu-grid { grid-template-columns: repeat(3, 1fr); }
  /* On desktop the four reels fill the rail exactly, so nothing scrolls. */
  .ig-grid > * { flex-basis: calc((100% - 48px) / 4); }
  .contact-grid { grid-template-columns: 5fr 7fr; align-items: start; }
  /* Copy first, photo second — mirrored so the photo still lands in the
     narrow column and both About arches come out the same size. */
  .contact-grid.is-mirrored { grid-template-columns: 7fr 5fr; }
  .post-grid { grid-template-columns: repeat(3, 1fr); }
  .faq-item summary { font-size: 23px; }

  .method-band { padding: 150px 0; }
  .method-panel { max-width: 600px; padding: 52px 48px; }
}

/* Narrow phones: the accordion answer needs its full width back */
@media (max-width: 480px) {
  .faq-answer { padding-right: 0; }
  .faq-item summary { font-size: 19px; gap: 16px; }
}

/* ==========================================================================
   Footer credit bar — copyright left, build credit right
   ========================================================================== */
.footer-bar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-top: 44px;
  padding: 0 24px;
}
.footer-bar .copyright { margin-top: 0; padding: 0; }

.site-credit {
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(244, 240, 233, 0.3);
}
.site-credit span { color: rgba(244, 240, 233, 0.55); letter-spacing: 0.14em; }

@media (min-width: 760px) {
  /* Copyright dead-centre at the very bottom; the build credit stays right.
     The empty first column balances the credit so the copyright is truly
     centred on the page, not just between the two items. */
  .footer-bar {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: baseline;
    gap: 0;
    max-width: 1240px;
    margin: 44px auto 0;
    padding: 0 40px;
  }
  .footer-bar .copyright { grid-column: 2; text-align: center; }
  .footer-bar .site-credit { grid-column: 3; justify-self: end; }
}

/* ---------- Voice: theme cards (not quotes) ----------
   The decorative “ glyph and the star row belong to a real, verbatim review.
   These cards are recurring themes written in our own voice, so both are
   suppressed — styling them as quotations would be claiming something untrue.
   Restore by removing .is-theme once the real review text is in. */
.voice-card.is-theme::before { content: none; }
.voice-card.is-theme { gap: 12px; padding-top: 36px; }
.voice-theme {
  font-family: var(--serif);
  font-size: 25px;
  line-height: 1.3;
  color: var(--gold-soft);
}
.voice-card.is-theme p:not(.voice-theme) {
  font-size: 16px;
  line-height: 1.7;
  color: rgba(244, 240, 233, 0.78);
}

/* ==========================================================================
   Real photography in the media slots
   .post-media / .spa-type-media were placeholder <div>s; they are now <img>.
   The aspect-ratio already lives on those classes, so all the image needs is
   to fill the box and crop rather than distort. Most of the source photos are
   tall portraits going into landscape frames, hence object-position: center —
   the subject (the head at the basin) sits mid-frame in every one.
   ========================================================================== */
/* Journal cards carry the photo in TWO different shapes and both must look the
   same:
     static build → <img class="post-media">            (what wp/build.mjs parses)
     WordPress    → <div class="post-media"><img></div> (what the_post_thumbnail emits)
   .post-media already sets aspect-ratio: 3/2, so the box is fixed either way and
   the photo only has to fill it and crop. Keep both selectors in step. */
img.post-media,
.post-media > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
/* On the <img> form, aspect-ratio + height:100% would resolve against the card's
   flex height; pin it to the ratio instead. */
img.post-media { height: auto; flex: none; }
.post-media { overflow: hidden; }

/* Home page: the two head-spa type cards. The <img> IS the media element here,
   and .spa-type-media carries aspect-ratio: 4/3. */
img.spa-type-media {
  width: 100%;
  height: auto;
  flex: none;
  object-fit: cover;
  object-position: center;
}
