/* ═══════════════════════════════════════════════════════
   PAPA BEAR SALON  |  Global Styles
   ═══════════════════════════════════════════════════════ */

:root {
  color-scheme: dark; /* native controls (date picker, select) render dark */

  /* ── Semantic palette — dark editorial default (v1.5) ── */
  --bg: #000000;          /* page */
  --bg-alt: #0a0a0a;      /* alternating sections (was off-white) */
  --surface: #101010;     /* cards, inputs, modal */
  --fg: #f4f2ee;          /* primary text / light fills */
  --fg-soft: #b0aba2;     /* body copy (was #555) */
  --fg-faint: #7a766d;    /* meta text (was #888) */
  --line: #262521;        /* borders (was #ebebeb) */
  --accent: #c9a181;      /* warm tan, lifted for dark-bg contrast */
  --ink: #0a0a0a;         /* dark ink used ON light fills */

  --font-display: 'DM Sans', sans-serif;
  --font-body: 'DM Sans', sans-serif;
  --transition: 0.38s cubic-bezier(0.4, 0, 0.2, 1);

  /* Fluid scale — one rule that scales continuously across every
     viewport instead of snapping at fixed breakpoints. */
  --space-section-y: clamp(64px, 11vw, 120px);
  --space-section-x: clamp(20px, 5vw, 40px);
  --space-lg: clamp(32px, 6vw, 80px);
  --space-md: clamp(20px, 4vw, 48px);
  --nav-h: clamp(64px, 8vw, 72px);
}

html, body { max-width: 100%; }

/* v1.083 — BELT AND BRACES AGAINST PHANTOM SIDEWAYS SCROLL.
   `body { overflow-x: hidden }` further down has been the only thing holding
   any over-wide decoration inside the screen, and on real mobile browsers it
   is not dependable — see the note on .blogs. `overflow-x: clip` on the root
   is the modern answer to the same problem and is safe here for one specific
   reason: unlike `hidden`, `clip` does NOT create a scroll container, so it
   cannot break `position: sticky` (the Services detail image) or interfere
   with Lenis. Where it is unsupported nothing changes and the old behaviour
   stands, so this can only ever help. */
html { overflow-x: clip; }

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

html { scroll-behavior: smooth; font-size: 16px; scroll-padding-top: var(--nav-h); }

body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--fg);
  overflow-x: hidden;
  cursor: default;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

img { display: block; width: 100%; object-fit: cover; }
a { text-decoration: none; color: inherit; }
ul { list-style: none; }

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

/* ═══════════════ SCROLLBAR ═══════════════ */
::-webkit-scrollbar { width: 4px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: #3d3b36; }

/* ═══════════════ NAVBAR ═══════════════ */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 900;
  display: flex;
  align-items: center;
  padding: 0 var(--space-section-x);
  height: var(--nav-h);
  transition: background var(--transition), box-shadow var(--transition);
}

.nav.scrolled {
  /* solid glass — backdrop blur repainted on every scroll frame and
     was a measurable jank source */
  background: rgba(0, 0, 0, 0.96);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.07);
}

.nav.hero-nav { color: var(--fg); }
.nav.hero-nav .nav__links a { color: rgba(255,255,255,0.9); }
/* v1.36 — over the hero the CTA is liquid glass: frosted capsule,
   hairline border, specular top edge. (Scrolled state stays the
   solid mark — glass over the solid black bar would show nothing.) */
.nav.hero-nav .nav__cta {
  background: rgba(255, 255, 255, 0.12);
  color: var(--fg);
  border-color: rgba(255, 255, 255, 0.26);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  backdrop-filter: blur(16px) saturate(150%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 10px 30px rgba(0, 0, 0, 0.28);
}
.nav.hero-nav .nav__cta:hover {
  background: rgba(255, 255, 255, 0.22);
  color: var(--fg);
}

.nav__logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
.nav__logo-img {
  width: auto;
  height: clamp(46px, 5.2vw, 58px);
  display: block;
}

.nav__links {
  display: flex;
  gap: clamp(20px, 3vw, 40px);
  margin-left: clamp(24px, 5vw, 60px);
  flex: 1;
}

.nav__links a {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  opacity: 0.8;
  transition: opacity 0.2s;
}
.nav__links a:hover { opacity: 1; }

.nav__cta {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.5px;
  margin-left: clamp(12px, 1.4vw, 18px);   /* v1.56 — clear gap from the brochure pill */
  padding: 10px 22px;
  border: 1.5px solid var(--fg);
  border-radius: 999px;   /* v1.36 — capsule in both states */
  background: var(--fg);
  color: var(--ink);
  transition: var(--transition);
}
.nav__cta:hover { background: transparent; color: var(--fg); }

/* ═══════════════ HERO — FULL-BLEED CLASSIC (v1.9) ═══════════════
   The original hero, kept: full-bleed photograph, tagline + CTA
   above, the giant title anchored at the very bottom — now forced
   onto ONE line with per-word mask reveals. CSS keyframes remain
   the no-JS fallback; GSAP owns the motion when available. */

.hero {
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 560px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
}

.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero__img {
  width: 100%; height: 100%;
  object-fit: cover;
  transform: scale(1.05);
  animation: heroZoom 8s ease-out forwards;
}

@keyframes heroZoom {
  from { transform: scale(1.05); }
  to   { transform: scale(1); }
}

/* Bottom tinted to --bg so the photo melts into the dark page */
.hero__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0,0.3) 0%,
    rgba(0, 0, 0,0.0) 40%,
    rgba(0, 0, 0,0.75) 100%
  );
}

.hero__nav-spacer { height: var(--nav-h); }

.hero__content {
  position: relative;
  z-index: 2;
  padding: 0 clamp(20px, 5vw, 50px) clamp(24px, 5vw, 40px);
  animation: fadeUp 1s 0.4s both;
}

.hero__tagline {
  color: rgba(255,255,255,0.9);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.3px;
  margin-bottom: 8px;
}

.hero__link {
  display: inline-block;
  color: var(--fg);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.5px;
  border-bottom: 1.5px solid var(--fg);
  padding-bottom: 2px;
  transition: opacity 0.2s;
}
.hero__link:hover { opacity: 0.7; }

.hero__title {
  position: relative;
  z-index: 2;
  padding: 0 clamp(16px, 4vw, 28px) clamp(20px, 4vw, 28px);
  animation: fadeUp 1s 0.2s both;
}

.hero__title-text {
  font-family: var(--font-display);
  font-size: clamp(36px, 10.4vw, 126px);
  font-weight: 900;
  color: var(--fg);
  line-height: 0.9;
  letter-spacing: clamp(-4px, -0.03em, -2px);
  text-transform: uppercase;
  display: block;
  white-space: nowrap;    /* BEAUTY SALON always on one line */
}

.hero-word { display: inline-block; overflow: hidden; vertical-align: bottom; }
.hero-word__inner { display: inline-block; will-change: transform; }

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(30px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ═══════════════ ABOUT — THE STATEMENT (v1.71) ═══════════════
   The statement sits in a naturally-wrapped paragraph. PHONES: the
   words rise + fade into place as the section arrives. DESKTOP: the
   words start scattered across the section and converge into the
   sentence as you scroll through it, scrubbed to scroll position so
   scrolling back up pulls them apart again (animations.js).

   The convergence needs NO runway and NO pin — it plays out in normal
   document flow while the page scrolls past, so this section keeps
   its plain full-viewport height. Words are moved with transforms
   only, so nothing here affects layout, and animations.js clamps
   every scattered word inside this section's own content box: the
   hero above and the showreel below are never touched. overflow:clip
   is belt-and-braces for odd viewport ratios (it clips without
   creating a scroll container, so it can't silence anything).

   The column is 1440px so the statement sets in three monumental
   lines, breaking on its own commas. The convergence is driven by
   animations.js reading this section's live geometry every frame —
   NOT by ScrollTrigger — so it runs inside the Customizer preview
   iframe too, and it LANDS with this section squared up to the frame,
   which is where the centring below puts the sentence. No-JS /
   reduced-motion: the assembled statement, static. */

.about {
  background: var(--bg);
}
@supports (overflow: clip) {
  .about { overflow: clip; }
}

.about__inner {
  min-height: 100vh;
  min-height: 100svh;
  max-width: 1440px;
  margin: 0 auto;
  padding: calc(var(--nav-h) + 4vh) var(--space-section-x) 8vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(22px, 3.2vw, 34px);
}

.scatter__statement {
  font-family: var(--font-display);
  font-size: clamp(40px, 5.6vw, 92px);  /* 12 words, three monumental lines */
  font-weight: 900;
  text-transform: uppercase;
  line-height: 1.08;
  letter-spacing: clamp(-1.5px, -0.015em, -0.5px);
  color: var(--fg);
  text-wrap: balance;   /* lines break at even lengths where supported */
}

.sc-word {
  display: inline-block;
  will-change: transform;   /* transform owned by GSAP */
}

/* JS owns the glide once animations boot (Lenis / anchor tweens);
   the CSS smooth scroll stays on for no-JS visitors. */
html.pb-anim { scroll-behavior: auto; }

/* Horizontal clipping without creating a scroll container, so
   position:sticky can never be silenced by it (modern browsers;
   others keep the overflow-x:hidden declared on body above). */
@supports (overflow: clip) {
  body { overflow-x: clip; }
}

/* v1.35 — the tagline steps back to a quiet supporting line so the
   statement owns the section */
.scatter__tagline {
  font-family: var(--font-display);
  font-size: clamp(14px, 1.3vw, 17px);
  font-weight: 500;
  line-height: 1.6;
  letter-spacing: 0;
  color: var(--fg-soft);
  max-width: 52ch;
}

.scatter__eyebrow {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: var(--fg-faint);
}

/* ═══════════════ SECTION TITLE ═══════════════ */
.section-title {
  font-family: var(--font-display);
  font-size: clamp(34px, 8vw, 88px);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: clamp(-3px, -0.025em, -1.5px);
  line-height: 1;
  margin-bottom: clamp(24px, 4vw, 40px);
}

/* ═══════════════ SERVICES OVERVIEW ═══════════════ */
.services-overview {
  background: var(--bg-alt);
  padding: var(--space-section-y) var(--space-section-x);
}

.services-overview__inner {
  max-width: none;      /* cards run edge-to-edge inside the section
                           padding — no dead space left/right */
  margin: 0 auto;
  text-align: center;   /* title, View All centered (reference) */
}

/* Overview title runs smaller than the display headlines (measured
   ~46px caps at a 1294px viewport in the reference ≈ 3.6vw) */
.services-overview .section-title {
  font-size: clamp(28px, 3.6vw, 52px);
  letter-spacing: -0.02em;
  margin-bottom: clamp(24px, 2.9vw, 40px);
}

.services-overview__grid {
  display: grid;
  /* LOCKED to 3 columns: auto-fit was re-flowing 6 cards into six
     skinny columns after View More. Every batch of 3 now forms a
     new full-size row. */
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(12px, 1.6vw, 21px);
  margin-bottom: clamp(32px, 3.8vw, 52px);
}

.overview-card {
  display: block;          /* v1.74 — the card is an <a> now (see main.js) */
  color: inherit;
  position: relative;
  aspect-ratio: 10 / 11;   /* measured 392×433 in the reference */
  overflow: hidden;
  cursor: pointer;
  /* v1.58 — cards are VISIBLE by default; the Möbius left → right wipe is
     driven by GSAP (see animations.js) so a card can never get stuck
     hidden if the reveal doesn't fire. */
}

/* It's focusable now that it's a real link — so it has to show it. */
.overview-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.overview-card__img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.6s cubic-bezier(0.4,0,0.2,1);
}
.overview-card:hover .overview-card__img { transform: scale(1.06); }

.overview-card__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.6) 0%, transparent 50%);
  transition: opacity 0.3s;
}

.overview-card__info {
  position: absolute;
  bottom: 20px;
  left: 20px;
  color: var(--fg);
  text-align: left;
}

.overview-card__name {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1px;
}

.overview-card__count {
  font-size: 12px;
  opacity: 0.8;
  margin-top: 2px;
}

.view-all {
  display: inline-block;
  font-size: 15px;
  font-weight: 600;
  border-bottom: 1.5px solid var(--fg);
  padding-bottom: 3px;
  transition: opacity 0.2s;
}
.view-all:hover { opacity: 0.5; }

/* ═══════════════ SERVICES DETAIL ═══════════════ */
.services-detail {
  padding: var(--space-section-y) var(--space-section-x);
  background: var(--bg);
}

.services-detail__inner {
  max-width: 1200px;
  margin: 0 auto;
}

/* Tabs */
.services-tabs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);  /* 4 tabs per View More row */
  gap: clamp(12px, 1.6vw, 21px);
  margin-bottom: clamp(18px, 2.4vw, 28px);
}

.tab-btn {
  padding: 16px 18px;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  border: 1.5px solid var(--line);
  background: none;
  color: var(--fg); /* buttons don't inherit color — UA default would be dark-on-dark */
  cursor: pointer;
  transition: var(--transition);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;             /* label sits at the bottom */
  gap: 4px;
  position: relative;
  overflow: hidden;
  min-height: clamp(110px, 13.8vw, 180px); /* measured 179px tall boxes */
  text-align: left;
}

/* v1.75 — ALWAYS ON. The thumb used to be opacity:0 until its tab was
   hovered or active, so a strip of eight categories read as one photo and
   seven black rectangles. Every tab now shows its own image; what marks the
   ACTIVE one is the state below, not the image's presence. */
.tab-btn .tab-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: 1;
  z-index: 0;
}

/* The scrim that buys the label its contrast. It has to exist now: the label
   sits on a photograph in every state, not just the active one, and some of
   these frames are bright. Sits between the image (z 0) and the text (z 2),
   and lifts on hover/active so the chosen tab's photo reads clearly. */
.tab-btn::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to top,
              rgba(0, 0, 0, 0.86) 0%,
              rgba(0, 0, 0, 0.58) 58%,
              rgba(0, 0, 0, 0.42) 100%);
  transition: background 0.35s ease;
}

.tab-btn:hover::before,
.tab-btn.active::before {
  background: linear-gradient(to top,
              rgba(0, 0, 0, 0.74) 0%,
              rgba(0, 0, 0, 0.3) 62%,
              rgba(0, 0, 0, 0.1) 100%);
}

.tab-btn:hover,
.tab-btn.active {
  border-color: var(--fg);
  color: var(--fg);
}

.tab-btn .tab-label,
.tab-btn .tab-count {
  position: relative;
  z-index: 2;
}

.tab-btn .tab-label { font-size: 13px; font-weight: 700; }
.tab-btn .tab-count { font-size: 11px; opacity: 0.8; }

/* Category info block */
.services-info {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(28px, 5vw, 60px);
  margin-bottom: clamp(28px, 5vw, 48px);
  padding-bottom: clamp(24px, 4vw, 40px);
  border-bottom: 1px solid var(--line);
}

.services-info__name {
  font-family: var(--font-display);
  font-size: clamp(28px, 3.6vw, 54px);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: clamp(-1.5px, -0.02em, -0.5px);
  line-height: 1;
}

.services-info__right {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: clamp(14px, 1.6vw, 15px);
  line-height: 1.7;
  color: var(--fg-soft);
  justify-content: center;
}

/* Detail Layout */
.services-detail__layout {
  display: grid;
  grid-template-columns: 1fr 1.6fr;
  gap: 32px;
  align-items: start;
}

.services-detail__image {
  position: sticky;
  top: calc(var(--nav-h) + 28px);
}

.services-detail__image img {
  aspect-ratio: 4 / 5;
  object-fit: cover;
  /* The box is 4:5 but the photos aren't, so cover always crops something.
     Centre what survives — it's the browser default, but it is stated here
     because it's a decision, not an accident: the ALL category's photo
     (v1.76) is a tall 736x1078 and would otherwise be at the mercy of it. */
  object-position: center;
}

/* v1.60 — "Back" to the 3-tab overview from the full-treatments view */
.services-back {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-bottom: clamp(20px, 2.6vw, 34px);
  padding: 8px 16px 8px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--fg-soft);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  cursor: pointer;
  transition: var(--transition);
}
.services-back:hover { color: var(--fg); border-color: var(--fg-faint); }
.services-back svg { flex-shrink: 0; transition: transform 0.32s cubic-bezier(0.22, 0.9, 0.24, 1); }
.services-back:hover svg { transform: translateX(-3px); }

.services-detail__cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}

/* Service Card */
.service-card {
  border: 1.5px solid var(--line);
  padding: 24px;
  cursor: pointer;
  transition: var(--transition);
  position: relative;
  overflow: hidden;
  /* v1.75 — see the note on ::after. `position: relative` alone is NOT a
     stacking context (z-index is auto), which left the fill below to be
     composited against an ancestor instead of against this card. */
  isolation: isolate;
}

/* THE HOVER FILL — a light panel that rises from the card's bottom edge.
   v1.75 — IT USED TO ESCAPE THE CARD. The card is rounded (--radius, applied
   in the SOFT CORNERS block) and clips with overflow:hidden, so in theory the
   fill was already contained. In practice it wasn't: a rounded clip and a
   TRANSFORMED, transitioning child is the one combination browsers routinely
   get wrong — the child gets promoted to its own compositor layer and the
   layer is clipped to a RECTANGLE, so four hard white corners appeared outside
   the card's curve, on a black page, at the exact moment the eye was on it.
   (Reproduced in Chrome at 4x zoom before the fix.)

   The fix is to stop relying on the clip: the fill now carries the curve
   ITSELF. `inset: 0` puts it on the padding box, whose corner radius is the
   card's radius less its 1.5px border — so that is what it is given, and the
   fill lines up with the inside of the border exactly whether the clip helps
   or not. isolation:isolate above gives it a stacking context of its own to be
   composited in, which is what stopped the promotion misbehaving in the first
   place. Belt and braces, deliberately: this is a paint bug, and paint bugs
   come back. */
.service-card::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: calc(var(--radius) - 1.5px);
  background: var(--fg);   /* light fill rises on the dark card */
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform 0.35s cubic-bezier(0.4,0,0.2,1);
  z-index: 0;
  pointer-events: none;
}

.service-card:hover::after { transform: scaleY(1); }
.service-card:hover { border-color: var(--fg); color: var(--ink); }
.service-card > * { position: relative; z-index: 1; }

.service-card__name {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 8px;
}

.service-card__desc {
  font-size: 13px;
  line-height: 1.6;
  color: inherit;
  opacity: 0.7;
  margin-bottom: 16px;
}

.service-card__meta {
  font-size: 12px;
  opacity: 0.6;
}

/* v1.76 — THE ACTIONS ARE ALWAYS LAID OUT; ONLY THEIR PAINT IS TOGGLED.
   This was `display: none` -> `display: flex` on hover, and that one line was
   behind BOTH glitches the client filmed:

     · THE BOXES JUMPING. Revealing the button added 30px to the card's
       content. These cards are grid items in auto-sized rows, so the ROW grew
       by 30px — taking its two neighbours with it, since grid items stretch —
       and every row below it was pushed down. Measured: hovering card 1 moved
       rows 2 and 3 down 30px and grew the page by 21px. Moving the cursor
       across the grid pumped the whole layout up and down, once per card.

     · THE IMAGE SHAKING. The image shares that grid row and is sticky. Its box
       is a fixed 562px; the cards column at rest was 553px, so the row was
       562px and the image had EXACTLY 0px of travel — it could not stick.
       Hovering pushed the cards column to 583px, so the row became 583px and
       the image suddenly had 21px of travel and snapped to its stuck position.
       Un-hovering collapsed the travel back to 0 and it snapped back. That
       21px snap, toggling on and off with the cursor, IS the shake.

   Reserving the row's height fixes both at once: the card, the row, the column
   and the page are now exactly the same size hovered or not, so there is
   nothing left to reflow and the sticky travel never changes. visibility (not
   opacity alone) keeps the button out of the tab order and the a11y tree while
   hidden, exactly as display:none did. Cards sit ~30px taller at rest, which is
   simply the height touch devices have always rendered — see the media query
   below, which this now matches instead of contradicting. */
.service-card__actions {
  display: flex;
  gap: 12px;
  margin-top: 16px;
  visibility: hidden;
  opacity: 0;
  /* visibility flips instantly on the way in, and waits for the fade on the
     way out — otherwise the button would vanish before it had faded. */
  transition: opacity 0.28s ease, visibility 0s linear 0.28s;
}

.service-card:hover .service-card__actions {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.28s ease, visibility 0s;
}

/* Touch devices can't hover — the actions just stay on, as they always have. */
@media (hover: none) {
  .service-card__actions { visibility: visible; opacity: 1; transition: none; }
}

/* Styled for BOTH card states: light chip on the dark resting card,
   flipping to dark ink once the light hover-fill rises. Keeps them
   visible on touch devices where actions always show. */
.btn-book {
  font-size: 12px;
  font-weight: 700;
  padding: 8px 16px;
  background: var(--fg);
  color: var(--ink);
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
  border: none;
  transition: opacity 0.2s, background 0.2s, color 0.2s;
}
.service-card:hover .btn-book { background: var(--ink); color: var(--fg); }
.btn-book:hover { opacity: 0.8; }

/* ═══════════════ BROCHURE VIEWER (v1.62) ═══════════════
   Opens the brochure PDF inside the site (an embedded viewer) instead of
   triggering a browser download. */
.brochure-modal { position: fixed; inset: 0; z-index: 1400; display: none; }
.brochure-modal.open { display: block; }
.brochure-modal__backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.82); }
.brochure-modal__dialog {
  position: absolute;
  inset: clamp(10px, 3vw, 40px);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 30px 90px rgba(0,0,0,0.55);
}
.brochure-modal__bar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.brochure-modal__title {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 1.5px;
  font-size: 15px;
  color: var(--fg);
  margin-right: auto;
}
.brochure-modal__open {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  color: var(--accent);
  text-decoration: none;
}
.brochure-modal__open:hover { text-decoration: underline; }

/* ─── Download (v1.77) ───
   The control that was missing on phones. It sits in the bar on EVERY screen
   size — on desktop the embedded viewer has its own download button in its
   toolbar, but that toolbar is easy to miss and belongs to the browser, not
   to us. Styled as a bordered pill so it reads as the primary action next to
   the quieter "Open in new tab" text link. */
.brochure-modal__dl {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  padding: 7px 13px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--fg);
  background: transparent;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.brochure-modal__dl:hover,
.brochure-modal__dl:focus-visible {
  background: var(--fg);
  color: var(--ink);
  border-color: var(--fg);
}
.brochure-modal__dl-ic { flex: 0 0 auto; }

.brochure-modal__close {
  background: none;
  border: 0;
  color: var(--fg-soft);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 4px;
}
.brochure-modal__close:hover { color: var(--fg); }
.brochure-modal__body { flex: 1; min-height: 0; background: #2a2a2a; }
.brochure-modal__frame { width: 100%; height: 100%; border: 0; display: block; }

/* ─── Mobile fallback (v1.77) ───
   Hidden by default; below 768px it REPLACES the iframe. iOS Safari and
   Android Chrome do not render PDFs in an iframe — they show a blank or grey
   box — so on phones the frame is removed from the layout entirely and this
   takes its place. Deliberately a CSS breakpoint rather than a capability
   sniff: embedded-PDF support is not reliably feature-detectable, and the
   cost of being wrong here is a visitor staring at an empty rectangle.
   main.js also skips setting the frame's src below the same breakpoint, so
   nothing is fetched to fill a box that never renders. */
.brochure-fallback { display: none; }

@media (max-width: 768px) {
  .brochure-modal__frame { display: none; }

  .brochure-fallback {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    height: 100%;
    padding: clamp(24px, 7vw, 40px) 22px;
    gap: 12px;
    background: var(--surface);
  }
  .brochure-fallback__ic { color: var(--accent); margin-bottom: 4px; }
  .brochure-fallback__title {
    font-family: var(--font-display);
    font-size: 19px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--fg);
  }
  .brochure-fallback__copy {
    font-size: 13.5px;
    line-height: 1.6;
    color: var(--fg-soft);
    max-width: 34ch;
    margin-bottom: 10px;
  }
  /* Full-width taps, comfortably above the 44px minimum target. */
  .brochure-fallback__btn {
    width: 100%;
    max-width: 320px;
    padding: 15px 20px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--fg);
  }
  .brochure-fallback__btn--primary {
    background: var(--fg);
    color: var(--ink);
    border-color: var(--fg);
  }

  /* The bar has four children on a narrow screen. Let "Open in new tab" drop
     away rather than crush the Download pill — the fallback panel below
     already offers "Open full screen", so nothing is lost. */
  .brochure-modal__bar { gap: 10px; padding: 10px 12px; }
  .brochure-modal__open { display: none; }
  .brochure-modal__title { font-size: 14px; }
}

/* ═══════════════ MODAL ═══════════════ */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.75);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s;
  padding: clamp(12px, 4vw, 20px);
}

.modal-backdrop.open {
  opacity: 1;
  pointer-events: all;
}

.modal {
  background: var(--surface);
  display: grid;
  grid-template-columns: 1fr 1fr;
  max-width: 900px;
  width: 100%;
  max-height: 90vh;
  max-height: 90svh;
  overflow-y: auto;
  transform: translateY(30px) scale(0.97);
  transition: transform 0.35s cubic-bezier(0.4,0,0.2,1);
  position: relative;
}

.modal-backdrop.open .modal {
  transform: translateY(0) scale(1);
}

.modal__close {
  position: absolute;
  top: 16px; right: 16px;
  background: none;
  border: none;
  color: var(--fg); /* explicit — buttons don't inherit color */
  font-size: 18px;
  cursor: pointer;
  z-index: 10;
  opacity: 0.5;
  transition: opacity 0.2s;
}
.modal__close:hover { opacity: 1; }

.modal__images {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.modal__images img {
  aspect-ratio: 5 / 4;
  object-fit: cover;
  flex: 1;
}

.modal__info {
  padding: clamp(24px, 4vw, 36px) clamp(20px, 4vw, 32px);
  overflow-y: auto;
}

.modal__rating {
  font-size: 14px;
  color: var(--accent);
  font-weight: 600;
  margin-bottom: 12px;
}

.modal__title {
  font-family: var(--font-display);
  font-size: clamp(26px, 5vw, 38px);
  font-weight: 900;
  text-transform: uppercase;
  line-height: 1;
  letter-spacing: -0.5px;
  margin-bottom: 16px;
}

.modal__meta {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-bottom: 20px;
}

.modal__duration {
  font-size: 13px;
  color: var(--fg-faint);
}

.modal__desc {
  font-size: 14px;
  line-height: 1.7;
  color: var(--fg-soft);
  margin-bottom: 20px;
}

.modal__ideal, .modal__involved {
  margin-bottom: 16px;
}

.modal__ideal strong, .modal__involved strong {
  font-size: 12px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  display: block;
  margin-bottom: 6px;
}

.modal__ideal p { font-size: 13px; color: var(--fg-soft); }

.modal__involved ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.modal__involved ul li {
  font-size: 13px;
  color: var(--fg-soft);
}

.modal__involved ul li strong {
  font-size: 13px;
  text-transform: none;
  letter-spacing: 0;
  display: inline;
  margin-right: 4px;
  color: var(--fg);
}

.modal__book {
  display: inline-block;
  margin-top: 24px;
  background: var(--fg);
  color: var(--ink);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.5px;
  padding: 14px 32px;
  text-transform: uppercase;
  transition: opacity 0.2s;
}
.modal__book:hover { opacity: 0.8; }

/* ═══════════════ CONTACT / FOOTER ═══════════════ */
.contact {
  background: var(--bg-alt);
  padding: var(--space-section-y) var(--space-section-x) 0;
}

.contact__inner {
  max-width: 1200px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-lg);
  padding-bottom: clamp(48px, 6vw, 80px);
  border-bottom: 1px solid var(--line);
}

.contact__headline {
  font-family: var(--font-display);
  font-size: clamp(32px, 6vw, 72px);
  font-weight: 900;
  text-transform: uppercase;
  line-height: 1;
  letter-spacing: clamp(-2.5px, -0.02em, -1px);
  margin-bottom: 24px;
}

.contact__left p {
  font-size: 15px;
  color: var(--fg-soft);
  line-height: 1.7;
  max-width: 380px;
}

.contact__form { display: flex; flex-direction: column; gap: 14px; }

.form-group input,
.form-group select {
  width: 100%;
  padding: 16px 18px;
  border: 1.5px solid var(--line);
  background: var(--surface);
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--fg);
  outline: none;
  transition: border-color 0.2s;
  -webkit-appearance: none;
}

.form-group input::placeholder { color: var(--fg-faint); }

.form-group input:focus,
.form-group select:focus { border-color: var(--accent); }

/* v1.085 — .form-submit REMOVED. IT WAS THE WHITE RECTANGLE ROUND THE
   "Post comment" BUTTON, and it is a ten-line lesson in dead code.

   These rules styled the submit button of the fake booking form — the one
   deleted in v1.77 because it never sent anything. The markup went; the CSS
   stayed, orphaned, styling a class no file in this theme emits any more.

   Harmless right up until v1.084 added comments, because WordPress's
   comment_form() wraps its button in <p class="form-submit">. That paragraph
   then inherited `background: var(--fg)` — #f4f2ee, i.e. off-white — plus
   18px of padding and width:100%, and painted a pale slab behind the real
   button. Nothing was wrong with the comment styling: an orphan from three
   years of releases ago collided with a core class name.

   Deleted rather than overridden. An override would leave the same trap set
   for the next thing WordPress or a plugin outputs with that class. */

/* Footer */
.footer {
  max-width: 1200px;
  margin: 0 auto;
  padding: clamp(24px, 4vw, 40px) 0 clamp(32px, 5vw, 60px);
  display: flex;
  align-items: center;
  gap: clamp(16px, 3vw, 40px);
}

.footer__logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
.footer__logo-img {
  width: auto;
  height: 58px;
  display: block;
}

.footer__links {
  display: flex;
  gap: 28px;
  flex: 1;
}

.footer__links a {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  opacity: 0.6;
  transition: opacity 0.2s;
}
.footer__links a:hover { opacity: 1; }

.footer__copy {
  font-size: 12px;
  color: var(--fg-faint);
  flex-shrink: 0;
}

/* ═══════════════ SCROLL ANIMATIONS ═══════════════ */

/* v1.79 — THE HIDDEN START STATE IS NOW CONDITIONAL ON JAVASCRIPT.
   Until now `.reveal` was `opacity: 0` from the very first paint, and the
   ONLY thing that ever brought it back was the IntersectionObserver in
   js/main.js adding `.visible`. That makes every reveal-wrapped row —
   including the Visit us details — invisible content by default, and it
   stays invisible if the observer never runs. On this install that is not
   hypothetical: an optimizer plugin has already served a stale/stripped
   script here once (see v1.48–1.49 in the README), and js/main.js is
   deferred, so anything that breaks or delays it takes the copy with it.

   `html.js` is set by a one-line inline script at the top of header.php,
   which runs synchronously before first paint. So: JS alive → identical
   behaviour to 1.78, no flash. JS dead, stripped, blocked or errored →
   the content simply renders, unanimated. Text can no longer go missing
   because an animation didn't fire. */
.reveal { transition: opacity 0.8s, transform 0.8s; }

html.js .reveal {
  opacity: 0;
  transform: translateY(30px);
}

.reveal.visible,
html.js .reveal.visible { opacity: 1; transform: none; }

/* v1.79 — ONE-WAY REVEALS.
   The default reveal REPLAYS: the observer toggles `.visible` off again the
   moment an element leaves the viewport, so it fades back out and re-enters
   on the way back. That is deliberate for the big showpiece sections, but
   it is wrong for a row of contact details, and it is what produces the
   "it appears, then it disappears" flicker: an element parked on the
   viewport edge crosses the 12% threshold back and forth on the smallest
   scroll, and on phones the URL bar collapsing/expanding resizes the
   viewport and re-triggers it without the user scrolling at all.

   `.reveal--once` opts a row out: it fades in on first entry and then stops
   being watched, so it can never be taken away again. Applied to the whole
   Visit us block in template-parts/section-location.php. */
html.js .reveal--once.visible { opacity: 1; transform: none; }

/* ═══════════════ RESPONSIVE ═══════════════
   Sizing, spacing and type now scale continuously via clamp() above.
   What's left here are genuine STRUCTURAL changes — layouts that need
   to re-flow (grid → stack, sticky → static, nav links wrapping) —
   not numeric overrides chasing three fixed screen widths. */

@media (max-width: 1024px) {
  .services-detail__layout { grid-template-columns: 1fr; }
  .services-detail__image { position: relative; top: 0; }
  .services-info { grid-template-columns: 1fr; }
}

@media (max-width: 768px) {
  /* v1.51 — mobile menu restored as a Möbius-style full-screen curtain.
     The inline links + Book CTA are hidden and a "Menu" text button
     (top-right) opens the overlay. Button + overlay styling lives in the
     MOBILE MENU block near the end of this file; here the bar is reset to
     just logo | Menu. */
  .nav {
    height: var(--nav-h);
    align-items: center;
  }
  .nav__links { display: none; }
  .nav > .nav__cta { display: none; }
  .nav > .nav__brochure { display: none; }

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

  .modal { grid-template-columns: 1fr; }
  .modal__images { flex-direction: row; }

  .contact__inner { grid-template-columns: 1fr; }

  .footer { flex-direction: column; text-align: center; gap: 20px; }
  .footer__links { flex-wrap: wrap; justify-content: center; gap: 16px; }
}

/* Respect reduced-motion preference across all scroll/hover animations */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ═══════════════ HEADLINE MAGNETS (v1.3) ═══════════════
   Decoded from the reference at pixel level: each mark is a tall
   rounded square-bracket "C" — twice as tall as wide, chunky
   0.058em stroke, spanning nearly the full cap height — and the
   pairs face each other like magnet jaws gripping the label.
   Left pair opens right, right pair opens left.
   All sizing in em so it tracks any headline's fluid size.
   Default (no-JS) state is OPEN — js/animations.js collapses the
   magnets on init and plays the reveal. */

.hl-line { white-space: nowrap; }

.magnet {
  display: inline-flex;
  vertical-align: middle;
  overflow: hidden;
  position: relative;
  top: -0.04em;               /* optical centering against the caps */
}

.magnet__frame {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 0.94em;             /* jaws span almost the full cap height */
  padding: 0 0.30em;
  margin: 0 0.10em;
  white-space: nowrap;
}

.magnet__label {
  font-style: normal;
  font-size: 0.14em;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  line-height: 1;
}

/* Magnet jaws — rounded-bracket C shapes, measured from the
   reference: 0.15em wide × 0.29em tall, 0.058em stroke */
.magnet__c {
  position: absolute;
  width: 0.15em;
  height: 0.29em;
  border: 0.058em solid currentColor;
}
.magnet__c--tl { top: 0;    left: 0;  border-right: 0; border-radius: 0.09em 0 0 0.09em; }
.magnet__c--bl { bottom: 0; left: 0;  border-right: 0; border-radius: 0.09em 0 0 0.09em; }
.magnet__c--tr { top: 0;    right: 0; border-left: 0;  border-radius: 0 0.09em 0.09em 0; }
.magnet__c--br { bottom: 0; right: 0; border-left: 0;  border-radius: 0 0.09em 0.09em 0; }

/* Slightly tighter magnets on narrow phones so the opened lines
   still fit without wrapping mid-animation */
@media (max-width: 480px) {
  .magnet__frame { padding: 0 0.22em; margin: 0 0.07em; }
  .magnet__label { font-size: 0.125em; letter-spacing: 0.10em; }
}

/* ═══════════════ SERVICES — DETAIL HEADLINE (v1.3) ═══════════════ */
.services-detail__headline {
  font-family: var(--font-display);
  font-size: clamp(34px, 5.2vw, 76px);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: clamp(-2px, -0.02em, -1px);
  line-height: 1;
  text-align: center;
  margin-bottom: clamp(36px, 4.9vw, 66px);
}

/* Hidden state helper (detail is hidden until a category is opened) */
[hidden] { display: none !important; }

/* ═══════════════ VIDEO GALLERY — THE REEL (v1.5) ═══════════════
   Five films standing as spines in one cinematic strip. The active
   spine expands into the stage (where playback happens, large);
   the rest compress beside it. No featured/small hierarchy — every
   film takes the stage when chosen. Odd stage ratios letterbox
   with black, which dissolves into the dark theme.
   Desktop: horizontal shelf. Phones: stacked bars, active opens
   to cinema height. */

.gallery {
  background: var(--bg);
  padding: var(--space-section-y) var(--space-section-x);
}

.gallery__inner {
  max-width: none;   /* the Reel runs edge-to-edge inside the section
                        padding — same treatment as the services cards */
  margin: 0 auto;
}

.gallery__headline {
  font-family: var(--font-display);
  font-size: clamp(34px, 5.2vw, 76px);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: clamp(-2px, -0.02em, -1px);
  line-height: 1;
  text-align: center;
  margin-bottom: clamp(36px, 4.9vw, 66px);
}

.gallery__reel {
  display: flex;
  gap: clamp(8px, 1.1vw, 14px);
  height: clamp(380px, 44vw, 600px);
}

.reel-item {
  position: relative;
  overflow: hidden;
  flex: 1 1 0%;
  min-width: 0;
  cursor: pointer;
  background: #101010;
  transition: flex-grow 0.75s cubic-bezier(0.22, 0.9, 0.24, 1);
}
.reel-item.is-active { flex-grow: 7; cursor: default; }

.reel-item__thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(0.85) brightness(0.55);
  transform: scale(1.04);
  transition: filter 0.6s, transform 0.8s cubic-bezier(0.22, 0.9, 0.24, 1);
}
.reel-item:hover .reel-item__thumb { filter: grayscale(0.4) brightness(0.7); }
.reel-item.is-active .reel-item__thumb { filter: grayscale(0) brightness(0.9); transform: scale(1); }

.reel-item__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.1) 45%, rgba(0,0,0,0.35) 100%);
  transition: opacity 0.5s;
}

/* Spine — vertical title + index, visible while collapsed */
.reel-item__spine {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 18px 0 20px;
  color: var(--fg);
  transition: opacity 0.35s;
}
.reel-item__num {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1px;
  opacity: 0.75;
}
.reel-item__name {
  font-family: var(--font-display);
  font-size: clamp(14px, 1.5vw, 19px);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  white-space: nowrap;
  max-height: 78%;
  overflow: hidden;
}
.reel-item.is-active .reel-item__spine { opacity: 0; pointer-events: none; }

/* Face — horizontal title + play ring, visible on the active stage */
.reel-item__face {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s 0.25s;
  color: var(--fg);
}
.reel-item.is-active .reel-item__face { opacity: 1; pointer-events: auto; }

.reel-item__title {
  position: absolute;
  bottom: 22px;
  left: 24px;
  right: 96px;
  font-family: var(--font-display);
  font-size: clamp(17px, 2vw, 24px);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1px;
  line-height: 1.15;
}
.reel-item__play {
  position: absolute;
  bottom: 22px;
  right: 22px;
  width: 52px;
  height: 52px;
  border: 1.5px solid rgba(255,255,255,0.9);
  border-radius: 50%;
  transition: var(--transition);
}
.reel-item__play::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-42%, -50%);
  border-left: 13px solid var(--fg);
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  transition: var(--transition);
}
.reel-item.is-active:hover .reel-item__play,
.reel-item__play:hover { background: var(--fg); }
.reel-item.is-active:hover .reel-item__play::after,
.reel-item__play:hover::after { border-left-color: var(--ink); }

/* Playing state — iframe owns the stage */
.reel-item__frame {
  position: absolute;
  inset: 0;
}
.reel-item__frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.reel-item.is-playing .reel-item__thumb,
.reel-item.is-playing .reel-item__scrim,
.reel-item.is-playing .reel-item__face { opacity: 0; pointer-events: none; }

.reel-item:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 3px;
}

/* Phones — the shelf rotates: stacked bars, active opens tall */
@media (max-width: 760px) {
  .gallery__reel {
    flex-direction: column;
    height: auto;
    gap: 10px;
  }
  .reel-item {
    flex: none;
    height: 62px;
    transition: height 0.6s cubic-bezier(0.22, 0.9, 0.24, 1);
  }
  .reel-item.is-active { height: min(62vw, 420px); }
  .reel-item__spine {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 14px;
    padding: 0 18px;
  }
  .reel-item__name {
    writing-mode: horizontal-tb;
    transform: none;
    max-height: none;
    max-width: 82%;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .reel-item__title { left: 18px; bottom: 16px; right: 84px; }
  .reel-item__play { right: 16px; bottom: 14px; width: 44px; height: 44px; }
}

/* ═══════════════ NAIL DIARIES — THE PARADE (v1.9) ═══════════════
   A perpetual runway: two shelves of diary polaroids drifting in
   opposite directions, forever. The shelves listen to scroll
   velocity — fast scrolling makes the parade rush and lean, and
   both shelves reverse when you scroll up. Hovering a shelf slows
   it to let you look. Bounded strips in normal flow: structurally
   incapable of touching the text.
   No-JS / reduced-motion: the shelves become plain scrollable
   strips, every card reachable. */

.nails {
  background: var(--bg-alt);
  padding: var(--space-section-y) 0 clamp(48px, 6vw, 84px);
  overflow: hidden;
}

.nails__inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--space-section-x);
}

.nails__headline {
  font-family: var(--font-display);
  font-size: clamp(34px, 5.2vw, 76px);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: clamp(-2px, -0.02em, -1px);
  line-height: 1;
  text-align: center;
  margin-bottom: clamp(16px, 2vw, 26px);
}

.nails__desc {
  font-size: clamp(14px, 1.6vw, 16px);
  line-height: 1.7;
  color: var(--fg-soft);
  max-width: 540px;
  margin: 0 auto clamp(36px, 5vw, 60px);
  text-align: center;
}

/* Full-bleed shelves */
.parade {
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2.2vw, 26px);
  margin-bottom: clamp(36px, 5vw, 60px);
}

.parade__row {
  overflow: hidden;               /* motion mode: track drifts inside */
  padding: 6px 0;                 /* room for the hover lift */
}

.parade__track {
  display: flex;
  gap: clamp(14px, 1.8vw, 22px);
  width: max-content;
  will-change: transform;
}

.parade__set {
  display: flex;
  gap: clamp(14px, 1.8vw, 22px);
  flex-shrink: 0;
}

/* Diary polaroid, in-flow on the shelf */
.nail-card {
  position: relative;
  width: clamp(190px, 22vw, 280px);
  flex-shrink: 0;
}

.nail-card__lift {
  background: var(--surface);
  border: 1px solid var(--line);
  padding: 8px 8px 0;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
  transition: transform 0.45s cubic-bezier(0.22, 0.9, 0.24, 1);
}
.nail-card:hover { z-index: 5; }
.nail-card:hover .nail-card__lift { transform: translateY(-8px); }

.nail-card__img {
  aspect-ratio: 3 / 4;
  object-fit: cover;
  display: block;
  width: 100%;
  filter: saturate(0.85);
  transition: filter 0.4s;
}
.nail-card:hover .nail-card__img { filter: saturate(1); }

.nail-card__caption {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 4px 12px;
  text-align: left;
}
.nail-card__num {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1px;
  color: var(--fg-faint);
  flex-shrink: 0;
}
.nail-card__meta { min-width: 0; text-align: right; }
.nail-card__title {
  display: block;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--fg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.nail-card__tag {
  display: block;
  font-size: 11px;
  color: var(--fg-soft);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}


/* Reduced motion: the shelves become plain scrollable strips */
@media (prefers-reduced-motion: reduce) {
  .parade__row {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 10px;
  }
  .parade__track { padding: 0 var(--space-section-x); }
}

@media (max-width: 560px) {
  .nail-card { width: clamp(170px, 52vw, 220px); }
}

/* ═══════════════ LIGHTBOX + DRAGGABLE PARADE (v1.10) ═══════════════ */

/* Shelves are grabbable */
.parade__row {
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}
.parade__row .nail-card__img { -webkit-user-drag: none; }
.parade__row.is-dragging { cursor: grabbing; }
.parade__row.is-dragging .nail-card { pointer-events: none; } /* no hover pops mid-drag */

/* Full-bleed lightbox — PhotoSwipe pattern: pure black, the image
   as large as the viewport allows, counter top-left, zoom + close
   top-right, bare chevrons at the screen edges. Same anatomy on
   desktop and mobile. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 1100;
  background: rgba(0, 0, 0, 0.98);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.28s;
}
.lightbox.open { opacity: 1; pointer-events: all; }

.lightbox__viewport {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.lightbox__img {
  max-width: 100vw;
  max-height: 100vh;
  max-height: 100svh;
  width: auto;
  height: auto;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
}

/* Zoomed: the image outgrows the viewport and pans natively */
.lightbox.is-zoomed .lightbox__viewport {
  display: block;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  cursor: move;
}
.lightbox.is-zoomed .lightbox__img {
  max-width: none;
  max-height: none;
  width: auto;
  height: 175vh;
  margin: 0 auto;
}

.lightbox__topbar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: clamp(12px, 2.4vw, 22px) clamp(14px, 2.6vw, 26px);
  pointer-events: none;   /* only the controls catch the pointer */
}
.lightbox.open .lightbox__topbar > * { pointer-events: auto; }

.lightbox__counter {
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 1px;
  color: rgba(255, 255, 255, 0.92);
}

.lightbox__actions { display: flex; align-items: center; gap: 6px; }

.lightbox__btn {
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.85);
  cursor: pointer;
  padding: 9px;
  display: flex;
  transition: opacity 0.2s, color 0.2s;
}
.lightbox__btn:hover { color: #fff; }
.lightbox__btn[aria-pressed="true"] { color: #fff; }

.lightbox__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.85);
  cursor: pointer;
  padding: 14px 12px;
  display: flex;
  transition: color 0.2s, opacity 0.2s, background 0.25s, border-color 0.25s;
}
.lightbox__nav:hover { color: #fff; }
/* v1.36 — the long arrows glide toward their direction on hover */
.lightbox__nav svg { transition: transform 0.32s cubic-bezier(0.22, 0.9, 0.24, 1); }
.lightbox__nav--prev:hover svg { transform: translateX(-3px); }
.lightbox__nav--next:hover svg { transform: translateX(3px); }
.lightbox__nav--prev { left: clamp(4px, 1.6vw, 22px); }
.lightbox__nav--next { right: clamp(4px, 1.6vw, 22px); }

@media (max-width: 600px) {
  .lightbox__nav svg { width: 26px; height: 18px; }
  .lightbox__nav--prev { left: 2px; }
  .lightbox__nav--next { right: 2px; }
}


/* ═══════════════ PORTED FROM THE LIVE STATIC SITE (v1.13) ═══════════════

   Gender split, hair gallery, reviews — design preserved as-is.

   Adaptations only: their Barlow tokens map to this theme's DM Sans

   (the project's v1.0 typography rule), their black/white vars map

   to the dark tokens (identical values), and their .hgallery class

   is namespaced to .hgallery to avoid colliding with the video

   Reel. Bebas Neue is loaded for the giant display type. */

.gender-split {
  display: flex;
  width: 100%;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}

.gender-half {
  position: relative;
  flex: 1;
  overflow: hidden;
  cursor: pointer;
}

.gender-half__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  filter: grayscale(100%);
  transition: transform 0.7s cubic-bezier(0.25, 0.46, 0.45, 0.94),
              filter 0.5s ease;   /* v1.38 — colour blooms on hover */
}

.gender-half:hover .gender-half__img {
  transform: scale(1.04);
  filter: grayscale(0%);
}

.gender-half__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    transparent 50%,
    rgba(0, 0, 0, 0.55) 100%
  );
  z-index: 1;
}

.gender-half__label {
  position: absolute;
  bottom: 40px;
  left: 0;
  right: 0;
  text-align: center;
  text-transform: uppercase;

  /* v1.38 — the site's own voice (DM Sans), not the ported Bebas */
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(20px, 2vw, 28px);
  letter-spacing: 0.5em;
  text-indent: 0.5em;   /* recenters wide-tracked text */
  color: #ffffff;
  z-index: 2;
  user-select: none;
  transition: letter-spacing 0.4s ease;
}

.gender-half:hover .gender-half__label {
  letter-spacing: 0.38em;
}

/* thin divider line between halves */
.gender-half--female {
  border-right: 0px solid rgba(255, 255, 255, 0.18);
}

.hgallery {
  background: var(--bg);
  padding: 48px 48px 80px;
  position: relative;
  overflow: hidden;
}

/* Top bar */
.hgallery__topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 32px;
  position: relative;
  z-index: 3;
}
.hgallery__trust {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: rgba(255,255,255,0.5);
}
.hgallery__viewmore {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: #fff;
  background: none;
  border: none;
  border-bottom: 1px solid rgba(255,255,255,0.5);
  cursor: pointer;
  padding-bottom: 2px;
  transition: border-color 0.25s, color 0.25s;
}
.hgallery__viewmore:hover { border-color: #fff; }
.hgallery__viewmore.active { color: rgba(255,255,255,0.5); }

/* Giant title — behind images */
.hgallery__title-wrap {
  position: absolute;
  top: 72px;
  left: 40px;
  z-index: 1;
  pointer-events: none;
  line-height: 1;
}
.hgallery__title {
  font-family: 'Bebas Neue', sans-serif;
  font-size: clamp(120px, 14vw, 200px);
  color: #fff;
  text-transform: uppercase;
  letter-spacing: -2px;
  line-height: 0.9;
  display: block;
}

/* Main grid */
.hgallery__grid {
  display: grid;
  grid-template-columns: 210px 1fr 210px;
  grid-template-rows: auto;
  gap: 0 20px;
  position: relative;
  z-index: 2;
  align-items: start;
}

/* Individual items */
.hgallery__item {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.hgallery__item img {
  width: 100%;
  display: block;
  object-fit: cover;
  filter: grayscale(100%);
  transition: filter 0.4s ease;
}
.hgallery__item:hover img { filter: grayscale(0%); }
.hgallery__label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: rgba(255,255,255,0.6);
  display: block;
}
.hgallery__desc {
  font-size: 13px;
  line-height: 1.7;
  color: rgba(255,255,255,0.45);
  margin-top: 8px;
  max-width: 280px;
}

/* ── Grid placements ── */

/* Col 1 */
.g-annete   { grid-column: 1; grid-row: 1; margin-top: 140px; }
.g-annete img   { height: 260px; }

.g-stiik    { grid-column: 1; grid-row: 2; margin-top: 32px; }
.g-stiik img    { height: 195px; }

.g-smartcut { grid-column: 1; grid-row: 3; margin-top: 32px; }
.g-smartcut img { height: 240px; }

/* Col 2 */
.g-wolfcut  { grid-column: 2; grid-row: 1; margin-top: 80px; }
.g-wolfcut img  { height: 310px; }

.g-fade     { grid-column: 2; grid-row: 2 / span 2; margin-top: 28px; }
.g-fade img     { height: 360px; }

/* Col 3 */
.g-cascade  { grid-column: 3; grid-row: 1; margin-top: 160px; }
.g-cascade img  { height: 210px; }

.g-classic  { grid-column: 3; grid-row: 2; margin-top: 20px; }
.g-classic img  { height: 250px; }

.g-mallet   { grid-column: 3; grid-row: 3; margin-top: 28px; }
.g-mallet img   { height: 245px; }

/* ── Expanded section ── */
.hgallery__expanded {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.8s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.6s ease;
  opacity: 0;
}
.hgallery__expanded.open {
  max-height: 900px;
  opacity: 1;
}

.hgallery__grid--extra {
  margin-top: 40px;
  grid-template-columns: 210px 1fr 210px;
  gap: 20px;
  align-items: start;
}

.g-extra1 { grid-column: 1; }
.g-extra1 img { height: 280px; }

.g-extra2 { grid-column: 2; }
.g-extra2 img { height: 340px; }

.g-extra3 { grid-column: 3; }
.g-extra3 img { height: 260px; }

.g-extra4 { grid-column: 1; margin-top: 20px; }
.g-extra4 img { height: 230px; }

.g-extra5 { grid-column: 2; margin-top: 20px; }
.g-extra5 img { height: 300px; }

.g-extra6 { grid-column: 3; margin-top: 20px; }
.g-extra6 img { height: 250px; }

/* ═══════════════ GALLERY OVERLAY (v1.39) ═══════════════
   The hair gallery opens here, over everything, from the "Gallery"
   nav item. Closed: inert (no paint, no pointer, out of tab order).
   Open: a dark stage the frames cascade onto (motion in main.js). */
.gallery-overlay {
  position: fixed;
  inset: 0;
  z-index: 1300;
  visibility: hidden;
  pointer-events: none;
}
.gallery-overlay.is-open {
  visibility: visible;
  pointer-events: auto;
}

.gallery-overlay__backdrop {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(130% 120% at 50% -10%, #17140f 0%, #0a0908 48%, #000 100%);
  opacity: 0;                       /* GSAP fades it in; CSS is the no-JS fallback */
  transition: opacity 0.55s ease;
}
.gallery-overlay.is-open .gallery-overlay__backdrop { opacity: 1; }

/* Scroll surface — the overlay scrolls internally, never the page */
.gallery-overlay__scroll {
  position: relative;
  z-index: 2;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.gallery-overlay__scroll::-webkit-scrollbar { width: 6px; }
.gallery-overlay__scroll::-webkit-scrollbar-thumb { background: #3d3b36; border-radius: 3px; }

.gallery-overlay__inner {
  min-height: 100%;
  padding-top: clamp(58px, 8vh, 96px);   /* clear the close button + let the wordmark breathe */
}
/* the ported section drops its own black bg — the overlay owns the stage */
.gallery-overlay__inner .hgallery { background: transparent; }

/* Close — pinned to the viewport corner, above the scrolling frames */
.gallery-overlay__close {
  position: absolute;
  top: clamp(14px, 2.2vw, 26px);
  right: clamp(14px, 2.2vw, 26px);
  z-index: 5;
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  color: var(--fg);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.18);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  backdrop-filter: blur(12px) saturate(140%);
  cursor: pointer;
  transition: background 0.25s, transform 0.35s cubic-bezier(0.22, 0.9, 0.24, 1), border-color 0.25s;
}
.gallery-overlay__close:hover {
  background: rgba(255, 255, 255, 0.16);
  border-color: rgba(255, 255, 255, 0.42);
  transform: rotate(90deg);
}
.gallery-overlay__close:active { transform: rotate(90deg) scale(0.94); }

/* lock the page behind the open overlay */
body.gallery-open { overflow: hidden; }

@media (max-width: 720px) {
  .gallery-overlay__inner { padding-top: clamp(52px, 9vh, 74px); }
  .gallery-overlay__close { width: 42px; height: 42px; }
}

.reviews {
  background: var(--bg); /* ← black bg */
  padding: 52px 48px 72px;
}

/* Top bar */
.reviews__topbar {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 36px;
}

.reviews__eyebrow {
  display: block;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: rgba(255,255,255,0.45); /* ← muted white */
  margin-bottom: 4px;
}

.reviews__title {
  font-family: var(--font-display);
  font-size: clamp(56px, 8vw, 92px);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: -1px;
  line-height: 0.9;
  color: var(--fg); /* ← white */
  margin: 0;
}

.reviews__morelink {
  font-size: 13px;
  font-weight: 500;
  color: var(--fg); /* ← white */
  background: none;
  border: none;
  border-bottom: 1px solid var(--fg); /* ← white border */
  padding-bottom: 2px;
  cursor: pointer;
  letter-spacing: 0.3px;
  transition: opacity 0.25s;
  white-space: nowrap;
  margin-top: 6px;
}
.reviews__morelink:hover { opacity: 0.5; }

/* Grid */
.reviews__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

/* Card */
.reviews__card {
  background: var(--bg); /* ← black */
  border-radius: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.reviews__photo-wrap {
  width: 100%;
  height: 330px;
  overflow: hidden;
  flex-shrink: 0;
}
.reviews__photo-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
  filter: grayscale(100%); /* ← grayscale to match b&w theme */
  transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94), filter 0.4s ease;
}
.reviews__card:hover .reviews__photo-wrap img {
  transform: scale(1.04);
  filter: grayscale(0%); /* ← colour reveals on hover */
}

.reviews__body {
  padding: 20px 4px 24px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.reviews__date {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4); /* ← muted white */
}

.reviews__name {
  font-family: var(--font-body);
  font-size: 22px;
  font-weight: 400;
  color: var(--fg); /* ← white */
  margin: 0;
  letter-spacing: -0.2px;
}

.reviews__text {
  font-size: 13px;
  line-height: 1.65;
  color: rgba(255,255,255,0.5); /* ← muted white */
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Expanded section */
.reviews__expanded {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height 0.8s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.6s ease;
}
.reviews__expanded.open {
  max-height: 700px;
  opacity: 1;
}
.reviews__grid--extra {
  margin-top: 20px;
}

/* ── Responsive completion for the ported sections ──
   The source static file shipped NO mobile rules for these three
   sections (its fixed 210px/1fr/210px collage overflows phones).
   Desktop design untouched; these are structural reflows only. */
@media (max-width: 900px) {
  .hgallery { padding: 40px var(--space-section-x) 64px; }
  .hgallery__grid,
  .hgallery__grid--extra { grid-template-columns: 1fr 1fr; gap: 20px; }
  .hgallery__grid .hgallery__item,
  .hgallery__grid--extra .hgallery__item { grid-column: auto; grid-row: auto; margin-top: 0; }
  .hgallery__title { font-size: clamp(72px, 15vw, 120px); }
  /* v1.67 — on the reflowed mobile grid the images sat ON TOP of the title
     (it was half-hidden behind the first photo). Lift the title above the
     grid so it reads in front of the images. Desktop keeps the collage's
     intentional peek-behind (this only applies at the mobile breakpoint). */
  .hgallery__title-wrap { z-index: 3; }
  .reviews { padding: 44px var(--space-section-x) 60px; }
  .reviews__grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
  .gender-split { flex-direction: column; height: auto; }
  .gender-half { height: 52svh; min-height: 320px; }
  .hgallery__grid,
  .hgallery__grid--extra { grid-template-columns: 1fr; }
  .hgallery__grid .hgallery__item img,
  .hgallery__grid--extra .hgallery__item img { height: auto; aspect-ratio: 4 / 3; }
  .hgallery__topbar { flex-wrap: wrap; gap: 10px; }
  .reviews__grid { grid-template-columns: 1fr; }
  .reviews__photo-wrap { height: 300px; }
}

/* Logo: a living mark — transform work happens on the img.
   v1.44 — the permanent `will-change: transform` promoted the logo to its own
   compositor layer, and some GPUs periodically flush/re-rasterise that layer,
   which showed as the mark "blinking" every few seconds. The logo isn't
   continuously animated (it only pops in on load and waves on hover), so the
   hint bought nothing and cost stability. Removed — GSAP creates a temporary
   layer only for the brief entrance/hover tweens and drops it after, so the
   mark now sits perfectly still at rest. */
.nav__logo-img,
.footer__logo-img { transform-origin: 50% 88%; }


/* ═══════════════ GOURMET — FULL-SCREEN IMAGE (v1.19) ═══════════════
   Zara grammar = this site's own hero grammar: a full-viewport
   photograph, text living ON the image, uppercase and sparse. Same
   overlay recipe as the hero, so it blends by construction. The
   only motion is a slow parallax drift, scrubbed both directions. */

.gourmet {
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 560px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
}

.gourmet__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.gourmet__img {
  display: block;
  width: 100%;
  height: 112%;
  margin-top: -6%;
  object-fit: cover;
  will-change: transform;
}

/* Same stops as the hero overlay — top hint, bottom melts into --bg */
.gourmet__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0,0.35) 0%,
    rgba(0, 0, 0,0.05) 40%,
    rgba(0, 0, 0,0.78) 100%
  );
}

.gourmet__content {
  position: relative;
  z-index: 2;
  padding: 0 clamp(20px, 5vw, 50px) clamp(40px, 7vw, 72px);
  max-width: 900px;
}

.gourmet__eyebrow {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.75);
  margin-bottom: clamp(12px, 1.8vw, 18px);
}

.gourmet__title {
  font-family: var(--font-display);
  font-size: clamp(34px, 6vw, 84px);
  font-weight: 900;
  text-transform: uppercase;
  line-height: 0.98;
  letter-spacing: clamp(-2.5px, -0.02em, -1px);
  /* the big display glyph carries more left side-bearing than the small
     tracked eyebrow, so pull it left a hair to line their left edges up */
  text-indent: -0.04em;
  color: var(--fg);
  margin-bottom: clamp(14px, 2vw, 20px);
}

.gourmet__copy {
  font-size: clamp(14px, 1.6vw, 15px);
  line-height: 1.7;
  color: rgba(255, 255, 255, 0.85);
  max-width: 480px;
}


/* ═══════════════ SOFT CORNERS (v1.20) ═══════════════
   The whole site loses its razor edges: buttons, inputs, cards and
   framed media pick up a gentle radius. One auditable block. */
:root { --radius: 10px; --radius-sm: 6px; }

.btn-book,
.modal__book { border-radius: var(--radius-sm); }
/* (.nav__cta left out since v1.36 — it's a full capsule now,
   declared with its base rule) */

.form-group input,
.form-group select { border-radius: var(--radius-sm); }

.tab-btn,
.service-card,
.overview-card,
.reel-item,
.modal,
.nail-card__lift,
.reviews__card,
.reviews__photo-wrap,
.gourmet__img { border-radius: var(--radius); }

.reviews__photo-wrap { overflow: hidden; }
.nail-card__img { border-radius: calc(var(--radius) - 4px); }
.hgallery__item img { border-radius: var(--radius); }
.lightbox__img { border-radius: var(--radius-sm); }
.g-pill { border-radius: 999px; } 






/* View More — the underline button used by the overview and the
   treatment grid */
.view-more-btn {
  display: inline-block;
  background: none;
  border: none;
  border-bottom: 1.5px solid var(--fg);
  padding: 0 0 3px;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 600;
  color: var(--fg);
  cursor: pointer;
  transition: opacity 0.2s;
}
.view-more-btn:hover { opacity: 0.5; }

.services-detail__cardswrap { min-width: 0; }
.cards-more-row {
  text-align: center;
  margin-top: clamp(22px, 3vw, 32px);
}

/* WhatsApp float — bottom right, always reachable */
.wa-float {
  position: fixed;
  right: clamp(16px, 3vw, 28px);
  bottom: clamp(16px, 3vw, 28px);
  z-index: 950;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: #25d366;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45);
  transition: transform 0.25s cubic-bezier(0.22, 0.9, 0.24, 1), box-shadow 0.25s;
}
.wa-float:hover {
  transform: translateY(-3px) scale(1.06);
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.55);
}
@media (max-width: 560px) {
  .wa-float { width: 48px; height: 48px; }
  .wa-float svg { width: 24px; height: 24px; }
}


/* v1.23 — tabs View More row */
.tabs-more-row {
  text-align: center;
  margin-bottom: clamp(48px, 9vw, 120px);
}


/* ═══════════════ LOCATION — ADDRESS + MAP (v1.24) ═══════════════
   Its own section below the appointment block: details with clean
   line icons on the left, the map filling the right. */

.location {
  background: var(--bg);
  padding: var(--space-section-y) var(--space-section-x);
}

.location__inner {
  max-width: 1200px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}

.location__eyebrow {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-bottom: clamp(12px, 1.6vw, 18px);
}

.location__headline {
  font-family: var(--font-display);
  font-size: clamp(30px, 4.4vw, 60px);
  font-weight: 900;
  text-transform: uppercase;
  line-height: 1.02;
  letter-spacing: clamp(-1.5px, -0.02em, -0.5px);
  margin-bottom: clamp(26px, 3.4vw, 40px);
}

.location__item {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: clamp(14px, 1.8vw, 18px) 0;
  border-top: 1px solid var(--line);
}
.location__item:last-of-type { border-bottom: 1px solid var(--line); }

.location__icon {
  flex-shrink: 0;
  width: 46px;
  height: 46px;
  border: 1px solid var(--line);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--fg-soft);
  transition: var(--transition);
}
a.location__item:hover .location__icon {
  border-color: var(--fg);
  color: var(--fg);
}

.location__text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.location__label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.location__value {
  font-size: 15px;
  line-height: 1.55;
  color: var(--fg-soft);
  transition: color 0.2s;
}
a.location__item:hover .location__value { color: var(--fg); }

/* v1.69 — FOLLOW US. Sits below the last item's rule, and the circles
   land in the same left-hand column as the address/email/phone icons
   above, so the details column keeps one alignment all the way down.
   Same 46px ring, same border token, same transition — these are the
   only outbound links in the section, so they earn a stronger hover
   than the rows do: the ring fills and the glyph inverts. */
.location__follow {
  padding-top: clamp(20px, 2.4vw, 26px);
}
.location__follow .location__label {
  display: block;
  margin-bottom: clamp(12px, 1.4vw, 16px);
}
.location__social {
  display: flex;
  gap: clamp(10px, 1vw, 12px);
}
.location__social-link {
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--fg-soft);
  transition: var(--transition);
}
.location__social-link:hover,
.location__social-link:focus-visible {
  background: var(--fg);
  border-color: var(--fg);
  color: var(--ink);
  transform: translateY(-3px);
}
@media (prefers-reduced-motion: reduce) {
  .location__social-link:hover,
  .location__social-link:focus-visible { transform: none; }
}

.location__map {
  height: 100%;
  min-height: 340px;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
}
.location__map iframe {
  width: 100%;
  height: 100%;
  border: 0;
  filter: invert(90%) hue-rotate(180deg) grayscale(0.2) contrast(0.9);
}

@media (max-width: 860px) {
  .location__inner { grid-template-columns: 1fr; }
  .location__map { min-height: 280px; }
}

/* Footer band: full-width background wrapper (the footer lived
   inside the contact section before and borrowed its padding) */
.footer-wrap {
  background: var(--bg-alt);
  padding: 0 var(--space-section-x);
}

/* Overview grid breakpoints (the locked 3-col needs explicit steps) */
@media (max-width: 900px) {
  .services-overview__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .services-overview__grid { grid-template-columns: 1fr; }
}


/* ═══════════════ SHOWREEL — VIDEO OVER MARQUEE (v1.27) ═══════════════
   Möbius reference: one giant sentence marqueeing continuously at
   the section's vertical center; the video card floats on top, the
   line sliding visibly at both sides and passing behind it.
   Reduced motion: the global rule freezes the marquee. */

.showreel {
  position: relative;
  background: var(--bg);
  min-height: 88vh;
  min-height: 88svh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: clamp(56px, 8vw, 110px) 0;
}

.showreel__marquee {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  overflow: hidden;
}

.showreel__track {
  display: flex;
  flex-shrink: 0;
  will-change: transform;
  animation: showreelMarquee 32s linear infinite;
}

.showreel__line {
  flex-shrink: 0;
  white-space: nowrap;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(64px, 11vw, 170px);
  line-height: 1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--fg);
  padding-right: 0.55em;
}

@keyframes showreelMarquee {
  to { transform: translateX(-50%); }
}

.showreel__frame {
  position: relative;
  z-index: 2;
  width: min(88vw, 1060px);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55);
}
@media (min-width: 900px) {
  .showreel__frame { width: min(73vw, 1170px); }  /* +10% per client */
}

.showreel__video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: #000;
}


/* ═══════════════ v1.28 — MASK LINES, LIQUID GLASS LIGHTBOX ═══════════════ */

/* Masked line rise — shared by contact + reviews headlines */
.mask-line { display: block; overflow: hidden; }
.mask-line__inner { display: block; will-change: transform; }
.reviews__title .mask-line { display: inline-block; }
.reviews__title .mask-line__inner { display: inline-block; }

/* LIQUID GLASS LIGHTBOX — desktop & tablet. The page behind is
   scroll-locked while the lightbox is open, so this blur renders
   once — none of the per-frame repaint cost that retired the nav
   blur. v1.54: phones get the same frosted treatment in the
   max-width:767px block below (the old full-bleed-black version
   left ugly letterbox bars around the portrait nail shots). */
@media (min-width: 768px) {
  .lightbox {
    background: rgba(6, 6, 6, 0.42);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    backdrop-filter: blur(14px) saturate(140%);
  }

  /* the image holds ~60% of the frame, set like a glass slide */
  .lightbox:not(.is-zoomed) .lightbox__img {
    max-width: 60vw;
    max-height: 76vh;
    border-radius: var(--radius);
    border: 1px solid rgba(255, 255, 255, 0.14);
    box-shadow: 0 40px 100px rgba(0, 0, 0, 0.6);
  }
  .lightbox.is-zoomed .lightbox__img {
    border-radius: 0;
    border: none;
    box-shadow: none;
  }

  /* frosted control chips */
  .lightbox__btn {
    background: rgba(255, 255, 255, 0.08);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 50%;
    padding: 10px;
  }
  .lightbox__btn:hover { background: rgba(255, 255, 255, 0.16); }

  .lightbox__nav {
    background: rgba(255, 255, 255, 0.08);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 999px;   /* v1.36 — frosted pill around the long arrow */
    padding: 15px 18px;
  }
  .lightbox__nav:hover {
    background: rgba(255, 255, 255, 0.18);
    color: #fff;
    border-color: rgba(255, 255, 255, 0.3);
  }

  .lightbox__counter {
    background: rgba(255, 255, 255, 0.08);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 999px;
    padding: 6px 14px;
  }
}

/* LIQUID GLASS LIGHTBOX — phones (v1.54). The portrait nail shots are
   wider in aspect than a phone screen, so the old full-bleed-black
   lightbox letterboxed them with tall dead-black bars top and bottom.
   Now the backdrop frosts the page behind (rendered once — the body is
   scroll-locked while open) and the image sits as a rounded glass card,
   so those margins read as blurred glass instead of ugly black. */
@media (max-width: 767px) {
  .lightbox {
    background: rgba(6, 6, 6, 0.44);
    -webkit-backdrop-filter: blur(16px) saturate(135%);
    backdrop-filter: blur(16px) saturate(135%);
  }

  /* the image becomes a floating glass slide (zoom drops the framing) */
  .lightbox:not(.is-zoomed) .lightbox__img {
    max-width: 92vw;
    max-height: 84vh;
    border-radius: var(--radius);
    border: 1px solid rgba(255, 255, 255, 0.14);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
  }
  .lightbox.is-zoomed .lightbox__img {
    border-radius: 0;
    border: none;
    box-shadow: none;
  }

  /* frosted control chips, matching the desktop glass treatment */
  .lightbox__btn {
    background: rgba(255, 255, 255, 0.08);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 50%;
    padding: 9px;
  }
  .lightbox__counter {
    background: rgba(255, 255, 255, 0.08);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 999px;
    padding: 6px 13px;
  }
  .lightbox__nav {
    background: rgba(255, 255, 255, 0.08);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 999px;
    padding: 10px 12px;
  }
}


/* v1.29 — showreel marquee sized down on phones; Lenis base rules */
@media (max-width: 767px) {
  .showreel__line { font-size: clamp(52px, 15.4vw, 60px); }
  /* v1.54 — on phones the 88vh min-height left the small video floating
     with a tall empty stretch above it and (the gap the client flagged)
     below it before the gender split. Drop the min-height and let padding
     alone set the breathing room so the video, marquee and gender split
     read as one continuous beat. */
  .showreel {
    min-height: 0;
    padding: clamp(52px, 13vw, 84px) 0;
  }
  /* v1.55/56 — section 2 (About) doesn't need a full 100svh stage on
     phones: at phone type sizes that left a big empty band above and
     below the statement. But the tight v1.55 collapse read as cramped,
     so give it a calm ~62svh with the statement centred — real
     breathing room, no dead space. (Desktop keeps the full-viewport
     stage from .about__inner above; since v1.68 neither one scatters.) */
  .about__inner {
    min-height: 62svh;
    justify-content: center;
    padding-top: calc(var(--nav-h) + 4vh);
    padding-bottom: clamp(48px, 11vw, 84px);
    gap: clamp(22px, 6vw, 32px);
  }
}

html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }


/* ═══════════════ IN REVIEWS — THE COUNT (v1.38) ═══════════════
   Per the client's annotated screenshot: one grid, three areas —
   the title and the 3 × 2 review grid stack on the LEFT; the
   counting 4.7 owns the RIGHT column across BOTH rows, its top
   rising to the title's line (the client's red line). The cards
   are deliberately QUIETER — smaller type, tighter padding — so
   title and figure carry the section's weight. No pin — normal
   flow. No-JS reads 4.7 and the full grid. */

.innum {
  position: relative;
  background: var(--bg);
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
  padding: calc(var(--nav-h) + clamp(20px, 3.5vh, 40px)) var(--space-section-x) clamp(48px, 7vh, 84px);
}

/* title + cards left, the monument right across both rows */
.innum__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.38fr) minmax(320px, 1fr);
  grid-template-rows: auto 1fr;
  /* v1.43 — the figure now spans ONLY the cards row (not the title row), so
     "center" means centered against the review boxes: top edge of the top
     row → bottom edge of the bottom row. The cell beside the title is left
     empty. */
  grid-template-areas:
    "title  ."
    "cards  figure";
  column-gap: clamp(20px, 2.4vw, 36px);
  row-gap: clamp(36px, 5.4vh, 68px);   /* v1.39 — clear air between the title and the review grid (client note) */
  align-items: start;
}

.innum__title {
  grid-area: title;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(50px, 8.4vw, 132px);
  line-height: 0.9;
  letter-spacing: -0.03em;
  margin: -0.1em 0 0;
  color: var(--fg);
}

/* Six reviews, 3 × 2 — quieter than the title and the figure */
.innum__cards {
  grid-area: cards;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: clamp(10px, 1vw, 14px);
}

.innum__review {
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.012));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(14px, 1.3vw, 18px);
  transition: transform 0.42s cubic-bezier(0.22, 0.9, 0.24, 1),
              border-color 0.42s, background 0.42s;
}
.innum__review:hover {
  transform: translateY(-5px);
  border-color: rgba(201, 161, 129, 0.42);
  background: linear-gradient(180deg, rgba(255,255,255,0.065), rgba(255,255,255,0.02));
}

.innum__review-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}

.innum__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(13px, 1.15vw, 14.5px);
  letter-spacing: 0.2px;
  color: var(--fg);
}

.innum__stars {
  color: var(--accent);
  font-size: 10px;
  letter-spacing: 2px;
  flex-shrink: 0;
}

.innum__text {
  font-size: clamp(12px, 1vw, 13px);
  line-height: 1.6;
  color: var(--fg-soft);
}

/* THE FIGURE — no panel, no video: the monument owns the right
   column from the title's line down, sized to outweigh the grid */
.innum__figure {
  grid-area: figure;
  align-self: stretch;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* v1.43 — the rating is centered against the review boxes (the figure now
     lives only in the cards row). The ::before below mirrors the GOOGLE
     RATING label's height so the NUMBER lands dead-center, not the
     number+caption as a group. Natural proportions, no stretch. */
  justify-content: center;
  gap: clamp(6px, 1.2vh, 14px);
}
/* invisible top spacer = same height as the label beneath, so the glyphs
   sit exactly on the vertical midline of the review grid */
.innum__figure::before {
  content: "";
  display: block;
  flex: 0 0 auto;
  width: 0;
  height: 12px;
}

.innum__num {
  position: relative;
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(230px, 30.5vw, 620px);
  line-height: 0.78;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;  /* digits never jitter width */
  color: var(--fg);
  margin-top: 0;   /* cap line sits level with "In Reviews"; natural proportions, no stretch */
}
.innum__numinner {
  display: block;
  will-change: transform;
  transform-origin: 50% 60%;
}
/* glassy sheen down the glyphs (on the transformed inner span so the
   gradient rides the count's rise; solid --fg where unsupported) */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .innum__numinner {
    background: linear-gradient(180deg, #ffffff 4%, rgba(255, 255, 255, 0.6) 96%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

.innum__figlabel {
  position: relative;
  font-size: 12px;
  line-height: 1;   /* known height (matches the ::before spacer that centers the number) */
  font-weight: 600;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: var(--fg-faint);
}

/* below ~1180px the split can't hold: title, then the monument,
   then the grid at 2 × 3 */
@media (max-width: 1180px) {
  .innum__grid {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto;
    grid-template-areas:
      "title"
      "figure"
      "cards";
  }
  .innum__figure {
    width: min(560px, 100%);
    margin: 0 auto;
    padding: clamp(8px, 2vh, 20px) 0;
  }
  .innum__cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    width: 100%;
    max-width: 740px;
    margin: 0 auto;
  }
  .innum__num { font-size: clamp(150px, 26vw, 260px); margin-top: 0; line-height: 0.85; }
}

@media (max-width: 900px) {
  .innum { justify-content: flex-start; padding-top: calc(var(--nav-h) + 3.5vh); }
  .innum__title { font-size: clamp(40px, 12vw, 84px); }
}

/* phones: one clean stack */
@media (max-width: 620px) {
  .innum__cards { grid-template-columns: 1fr; max-width: 520px; }
  .innum__num { font-size: clamp(130px, 40vw, 200px); }
}

/* Short desktop viewports: don't vertically center (keeps title clear of the nav) */
@media (min-width: 901px) and (max-height: 860px) {
  .innum { justify-content: flex-start; }
}


/* ═══════════════ MONOCHROME DISCIPLINE (v1.38) ═══════════════
   Every still image on the site lives in black & white and blooms
   to colour under the cursor — the hair-gallery / In Motion / nail
   mechanic, applied everywhere (the client's call). Sections whose
   images sit under overlays reveal on the card/section hover.
   Exempt: the brand marks, the lightbox (a focused view), the
   themed map, and anything that plays — video and iframes. */

.hero__img,
.overview-card__img,
.services-info__right img,
.gourmet__img,
.modal__images img {
  filter: grayscale(1);
}
.hero__img { transition: filter 0.6s ease; }
.services-info__right img,
.gourmet__img,
.modal__images img { transition: filter 0.5s ease; }
/* overview cards already transition transform — restate both */
.overview-card__img {
  transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1), filter 0.5s ease;
}
/* v1.75 — tab thumbs are always visible; mono is now what tells a resting tab
   from the chosen one, together with the scrim + border above. */
.tab-btn .tab-img { filter: grayscale(1); transition: filter 0.4s ease; }

.hero:hover .hero__img,
.overview-card:hover .overview-card__img,
.tab-btn:hover .tab-img,
.tab-btn.active .tab-img,
.services-info__right:hover img,
.gourmet:hover .gourmet__img,
.modal__images img:hover { filter: grayscale(0); }


/* ═══════════════════════════════════════════════════════════════════════
   v1.44 ADDITIONS
   ═══════════════════════════════════════════════════════════════════════ */

/* ─── REVIEWS: dates + "read all on Google" link ─── */

/* cards + the Google link share the "cards" cell so the link hugs the boxes
   (not the giant number's baseline) */
.innum__stack {
  grid-area: cards;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* the time-ago line — pinned to the bottom of each card so every date sits
   on the same line across the 3 × 2 grid, quiet like a real Google review */
.innum__date {
  margin-top: auto;              /* push to the card floor */
  padding-top: clamp(9px, 1vw, 13px);
  font-family: var(--font-body);
  font-size: clamp(10.5px, 0.85vw, 11.5px);
  font-weight: 500;
  letter-spacing: 0.3px;
  color: var(--fg-faint);
}

.innum__more {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: clamp(18px, 1.9vw, 24px);
  padding: 2px 1px 3px;
  font-family: var(--font-display);
  font-size: clamp(12.5px, 1.05vw, 14px);
  font-weight: 600;
  letter-spacing: 0.2px;
  color: var(--fg-soft);
  border-bottom: 1px solid rgba(201, 161, 129, 0.30);
  transition: color 0.3s, border-color 0.3s, gap 0.3s;
}
.innum__more:hover {
  color: var(--accent);
  border-color: var(--accent);
  gap: 11px;
}
.innum__more-ic {
  flex-shrink: 0;
  transition: transform 0.35s cubic-bezier(0.22, 0.9, 0.24, 1);
}
.innum__more:hover .innum__more-ic { transform: translate(2px, -2px); }

/* stacked layout (≤1180px): the link centers under the centered cards */
@media (max-width: 1180px) {
  .innum__stack { align-items: center; width: 100%; }
  .innum__more { align-self: center; margin-top: clamp(16px, 2.4vh, 22px); }
}

/* ─── NAV: brochure download link ───
   Lives on its own now (no longer crammed into the .nav__links row) — a
   quiet ghost-pill that reads as a secondary action, with its own breathing
   room ahead of the solid Book CTA instead of competing with it inline. */
.nav__brochure {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-left: clamp(18px, 2.6vw, 32px);
  padding: 9px 18px 9px 16px;
  border-radius: 999px;
  color: var(--fg-soft);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  transition: var(--transition);
}
.nav__brochure:hover {
  color: var(--fg);
}
.nav__brochure-ic {
  flex-shrink: 0;
  opacity: 0.85;
  transform: translateY(0.5px);
  transition: transform 0.32s cubic-bezier(0.22, 0.9, 0.24, 1), opacity 0.25s;
}
.nav__brochure:hover .nav__brochure-ic {
  opacity: 1;
  transform: translateY(2.5px);   /* the icon dips like a download */
}
/* over the hero photo the pill goes translucent-glass, matching the CTA */
.nav.hero-nav .nav__brochure {
  color: rgba(255, 255, 255, 0.85);
}
.nav.hero-nav .nav__brochure:hover {
  color: #fff;
}

/* ═══════════════ EVENTS — COMING SOON (v1.44) ═══════════════
   A quiet, premium teaser in the site's own dark grammar: one soft warm
   aura breathing slowly behind giant mask-revealed type, a live "rolling
   out soon" pulse, and a notify-me capture that confirms in place. Nothing
   flashes; the only ambient motion is the ultra-slow aura and the pulse
   ring (both stilled under prefers-reduced-motion). */
.events {
  position: relative;
  isolation: isolate;
  background: var(--bg);
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: calc(var(--nav-h) + clamp(48px, 9vh, 96px)) var(--space-section-x) clamp(64px, 11vh, 120px);
}

.events__aura {
  position: absolute;
  z-index: 0;
  top: 44%;
  left: 50%;
  width: min(1100px, 132vw);
  height: min(1100px, 132vw);
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side,
      rgba(201, 161, 129, 0.17) 0%,
      rgba(201, 161, 129, 0.07) 38%,
      rgba(201, 161, 129, 0) 72%);
  pointer-events: none;
  animation: eventsAura 16s ease-in-out infinite;
}
@keyframes eventsAura {
  0%, 100% { transform: translate(-50%, -50%) scale(1);    opacity: 0.92; }
  50%      { transform: translate(-50%, -52%) scale(1.07); opacity: 1;    }
}

.events__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* live "rolling out soon" chip */
.events__kicker {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 8px 16px 8px 13px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  font-family: var(--font-body);
  font-size: clamp(10.5px, 1vw, 12px);
  font-weight: 600;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: rgba(244, 242, 238, 0.86);
  margin-bottom: clamp(22px, 3.4vh, 34px);
}
.events__pulse {
  position: relative;
  width: 8px; height: 8px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent);
  animation: eventsPulse 2.4s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes eventsPulse {
  0%   { box-shadow: 0 0 0 0 rgba(201, 161, 129, 0.5); }
  70%  { box-shadow: 0 0 0 9px rgba(201, 161, 129, 0); }
  100% { box-shadow: 0 0 0 0 rgba(201, 161, 129, 0); }
}

.events__headline {
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: clamp(40px, 8.4vw, 116px);
  line-height: 0.92;
  letter-spacing: clamp(-3px, -0.028em, -1.5px);
  color: var(--fg);
  margin: 0;
}
.events__headline .mask-line { display: block; }

.events__lede {
  max-width: 560px;
  margin: clamp(20px, 3vh, 30px) auto 0;
  font-size: clamp(14px, 1.55vw, 16px);
  line-height: 1.7;
  color: var(--fg-soft);
}

/* notify-me — hairline glass field + solid pill (the hero-CTA vocabulary) */
.events__notify {
  margin-top: clamp(28px, 4.2vh, 44px);
  width: 100%;
  max-width: 480px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.events__field {
  display: flex;
  width: 100%;
  gap: 8px;
  padding: 6px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.045);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  backdrop-filter: blur(16px) saturate(150%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
  transition: border-color 0.3s, box-shadow 0.3s;
}
.events__field:focus-within {
  border-color: rgba(201, 161, 129, 0.5);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 0 0 3px rgba(201, 161, 129, 0.12);
}
.events__input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: none;
  outline: none;
  padding: 0 8px 0 16px;
  color: var(--fg);
  font-family: var(--font-body);
  font-size: clamp(13.5px, 1.3vw, 15px);
  letter-spacing: 0.2px;
}
.events__input::placeholder { color: var(--fg-faint); }
.events__input:disabled { color: var(--fg-soft); -webkit-text-fill-color: var(--fg-soft); opacity: 1; }
.events__btn {
  flex-shrink: 0;
  border: none;
  cursor: pointer;
  padding: 12px 24px;
  border-radius: 999px;
  background: var(--fg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: clamp(13px, 1.2vw, 14px);
  font-weight: 600;
  letter-spacing: 0.4px;
  white-space: nowrap;
  transition: transform 0.3s cubic-bezier(0.22, 0.9, 0.24, 1), background 0.3s, color 0.3s;
}
.events__btn:hover { transform: translateY(-1px); background: var(--accent); color: var(--ink); }
.events__btn:disabled { cursor: default; transform: none; }
.events__btn.is-done { background: #2a7a4b; color: #fff; }

.events__note {
  display: block;
  margin-top: 14px;
  font-family: var(--font-body);
  font-size: clamp(11.5px, 1vw, 12.5px);
  letter-spacing: 0.2px;
  color: var(--fg-faint);
  transition: color 0.3s;
}
.events__note.is-error { color: #e0736b; }
.events__note.is-ok { color: rgba(201, 161, 129, 0.96); }

@media (max-width: 900px) {
  .events { min-height: auto; padding-top: calc(var(--nav-h) + clamp(56px, 10vh, 90px)); padding-bottom: clamp(72px, 12vh, 110px); }
}
@media (max-width: 560px) {
  .events__field { flex-direction: column; gap: 8px; padding: 8px; border-radius: 20px; }
  .events__input { padding: 12px 14px; text-align: center; }
  .events__btn { width: 100%; padding: 14px 24px; }
}

/* ═══════════════ STANDALONE SUB-PAGES (Events, Gallery) — v1.47 ═══════════════
   Events + Gallery were lifted off the homepage onto their own pages
   (page-events.php / page-gallery.php). The .events section already bakes the
   nav height into its top padding, so it clears the fixed bar on its own; the
   .hgallery grid does not, so the gallery page gets a nav-height offset. Both
   keep the site's dark background so there's never a white flash. */
.subpage { background: var(--bg); }
.subpage--gallery { padding-top: var(--nav-h); }
.subpage--services { padding-top: var(--nav-h); }

/* ═══════════════ ABOUT + CONTACT PAGES (v1.77) ═══════════════
   "About Us" and "Contacts" used to be anchors into other pages — #founders
   on the homepage and #contact at the foot of Services. Both are standalone
   Pages now (page-about.php / page-contact.php), built from the same
   template parts the homepage uses, so they inherit the site's styling and
   scroll choreography without a single new layout rule.

   Only the top offset needs stating, and only for Contact: the About page
   opens on `.about__inner`, which already carries
   `padding-top: calc(var(--nav-h) + 4vh)` and clears the fixed bar on its
   own. `.contact` does not, so it gets the nav height the same way the
   Services and Gallery pages do. */
.subpage--contact { padding-top: var(--nav-h); }

/* The location block is a mid-page section on the homepage but the CLOSING
   section on the Contact page, where its default top padding stacks with the
   booking block's bottom padding and opens a visible trench between them. */
.subpage--contact .location { padding-top: clamp(40px, 6vw, 64px); }

/* ═══════════════ BOOKING PANEL (v1.77) ═══════════════
   Replaces the booking form, which never sent anything (see
   template-parts/section-booking.php). Sits in the right-hand column of the
   `.contact` grid, exactly where the form's four fields used to, so the
   section's proportions and its masked-headline reveal are unchanged. */
.bookpanel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
  padding: clamp(24px, 3.2vw, 38px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  align-self: start;
}

.bookpanel__label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--accent);
}

.bookpanel__copy {
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--fg-soft);
}

/* The primary action on the page. Full width so it reads as the button the
   form's submit used to be, rather than as another link in a paragraph. */
.bookpanel__cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  margin-top: 4px;
  padding: 18px;
  background: var(--fg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  border-radius: var(--radius-sm);
  transition: opacity 0.2s;
}
.bookpanel__cta:hover { opacity: 0.8; }
.bookpanel__cta-ic { flex: 0 0 auto; }

/* Booking online suits most people; some would rather call. Kept visually
   quieter than the CTA so it reads as an alternative, not a competitor. */
.bookpanel__alt {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  width: 100%;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.bookpanel__alt-label {
  font-size: 12.5px;
  color: var(--fg-faint);
}
.bookpanel__alt-links { display: flex; flex-wrap: wrap; gap: 14px; }
.bookpanel__alt-link {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.4px;
  color: var(--fg);
  border-bottom: 1px solid var(--line);
  padding-bottom: 2px;
  transition: color 0.2s, border-color 0.2s;
}
.bookpanel__alt-link:hover,
.bookpanel__alt-link:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
}

/* ═══════════════ "BOOK NOW" AS A LINK (v1.77) ═══════════════
   The treatment cards' Book Now became an <a> to the booking portal (it was
   a <button> that opened the same modal the card already opened). An anchor
   is inline where a button is inline-block, so it needs the box behaviour
   spelled out — everything else it inherits from .btn-book above, which is
   why the hover/active states and the light-on-dark card flip still hold. */
a.btn-book {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}



/* ═══════════════════════════════════════════════════════════════════
   MOBILE MENU  ·  Möbius-style full-screen curtain            (v1.51)
   ───────────────────────────────────────────────────────────────────
   The desktop nav is UNTOUCHED. At ≤768px the inline links + Book CTA
   are hidden and a "Menu" text button (top-right) opens a pure-black
   overlay that DROPS DOWN from the top of the screen; the links then
   stagger in top→bottom. Closing lets the curtain keep falling down
   and off (both motions travel downward, exactly like the reference).

   Mechanism — a clip-path curtain with NO transition in its idle
   state, so returning to idle after a close is instant (no reverse
   morph). Only the .menu-open / .menu-closing states carry a
   transition, so both the open and the close animate top→bottom.
   ═══════════════════════════════════════════════════════════════════ */

/* Trigger + overlay exist in the DOM at every width but only paint on
   phones (shown inside the media query below). */
.nav__toggle { display: none; }
.mobmenu     { display: none; }

/* ── The Menu button (matches the nav link type: uppercase, spaced) ── */
.nav__toggle {
  align-items: center;
  gap: 9px;
  margin-left: auto;
  padding: 10px 2px 10px 14px;
  background: none;
  border: 0;
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  z-index: 1002;            /* above the fixed nav, below the overlay */
}
.nav__toggle-txt { transition: opacity 0.15s; }

/* ── The overlay curtain ── */
.mobmenu {
  position: fixed;
  inset: 0;
  z-index: 1001;
  background: #000;
  color: var(--fg);
  padding: 0 var(--space-section-x);
  /* idle / closed: clipped to a zero-height sliver at the very top,
     and NON-transitioning so the post-close reset is instantaneous */
  clip-path: inset(0 0 100% 0);
  visibility: hidden;
  flex-direction: column;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  overflow-y: auto;
}
/* Only the active states animate — both sweep the clip top→bottom */
body.menu-open .mobmenu,
body.menu-closing .mobmenu {
  visibility: visible;
  transition: clip-path 0.56s cubic-bezier(0.76, 0, 0.24, 1);
}
body.menu-open   .mobmenu { clip-path: inset(0 0 0 0); }       /* drop down to cover */
body.menu-closing .mobmenu { clip-path: inset(100% 0 0 0); }   /* keep falling, uncovering top→bottom */

/* Overlay top bar: logo (left) + Close (right), aligned to the nav row */
.mobmenu__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--nav-h);
  flex: 0 0 auto;
}
.mobmenu__logo-img {
  width: auto;
  height: clamp(46px, 5.2vw, 58px);
  display: block;
}
.mobmenu__close {
  background: none;
  border: 0;
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  line-height: 1;
  padding: 10px 2px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Nav stack — large editorial links, generous rhythm */
.mobmenu__nav {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(6px, 1.4vh, 14px);
  padding: clamp(20px, 5vh, 48px) 0;
  list-style: none;
  margin: 0;
}
.mobmenu__link {
  display: inline-block;
  width: max-content;
  font-family: var(--font-display);
  font-size: clamp(34px, 11vw, 58px);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.04;
  color: var(--fg);
  text-decoration: none;
  transition: color var(--transition);
}
.mobmenu__link:active { color: var(--accent); }

/* Brochure sits as the last nav item (below Contacts) instead of
   crowding the footer next to the CTA — same big link treatment,
   just a smaller trailing download glyph so it still reads as an
   action rather than another page. */
.mobmenu__link--brochure {
  display: inline-flex;
  align-items: center;
  gap: 0.14em;
  color: var(--fg-soft);
}
.mobmenu__link-ic {
  width: 0.62em;
  height: 0.62em;
  flex: 0 0 auto;
}

/* Footer of the overlay: primary Book CTA */
.mobmenu__foot {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: clamp(20px, 4vh, 40px) 0 calc(env(safe-area-inset-bottom, 0px) + clamp(24px, 5vh, 48px));
  border-top: 1px solid var(--line);
}
.mobmenu__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 16px 26px;
  border-radius: 999px;
  background: var(--fg);
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.3px;
  text-decoration: none;
  transition: var(--transition);
}
/* Staggered entrance for the overlay contents (top→bottom).
   Links start low + transparent; when the body is .menu-open they
   settle, each a beat after the last — matching the reference where
   Work→Studio→Feed→Contact resolve in sequence as the curtain lands. */
.mobmenu__link,
.mobmenu__foot > * {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
body.menu-open .mobmenu__link,
body.menu-open .mobmenu__foot > * {
  opacity: 1;
  transform: none;
}
body.menu-open .mobmenu__nav  li:nth-child(1) .mobmenu__link { transition-delay: 0.20s; }
body.menu-open .mobmenu__nav  li:nth-child(2) .mobmenu__link { transition-delay: 0.26s; }
body.menu-open .mobmenu__nav  li:nth-child(3) .mobmenu__link { transition-delay: 0.32s; }
body.menu-open .mobmenu__nav  li:nth-child(4) .mobmenu__link { transition-delay: 0.38s; }
body.menu-open .mobmenu__nav  li:nth-child(5) .mobmenu__link { transition-delay: 0.44s; }
body.menu-open .mobmenu__nav  li:nth-child(6) .mobmenu__link { transition-delay: 0.50s; }
/* v1.080 — a seventh item (Blogs) joined the list, so the ladder needed a
   seventh rung. Without it the last link would have no delay at all and would
   arrive FIRST, ahead of the five above it. */
body.menu-open .mobmenu__nav  li:nth-child(7) .mobmenu__link { transition-delay: 0.56s; }
body.menu-open .mobmenu__foot > *:nth-child(1) { transition-delay: 0.56s; }

/* Lock the page behind the open overlay */
body.menu-open { overflow: hidden; }

@media (max-width: 768px) {
  .nav__toggle { display: inline-flex; }
  .mobmenu     { display: flex; }
}

@media (prefers-reduced-motion: reduce) {
  body.menu-open .mobmenu,
  body.menu-closing .mobmenu { transition-duration: 0.001s; }
  .mobmenu__link,
  .mobmenu__foot > * { transition-duration: 0.001s; }
  body.menu-open .mobmenu__nav li .mobmenu__link,
  body.menu-open .mobmenu__foot > * { transition-delay: 0s; }
}


/* ═══════════════════════════════════════════════════════════════════
   OUR FOUNDERS  ·  editorial split, scroll-revealed             (v1.51)
   ───────────────────────────────────────────────────────────────────
   Mirrors the Möbius "Our Founders" section — heading top-left, a
   narrative paragraph lower-left, and the founders' portraits filling
   the right — rebuilt in Papa Bear's dark palette so it sits naturally
   after In Reviews. On scroll-in the heading, portraits and paragraph
   fade + rise in sequence (replaying on re-entry, like the rest of the
   site). Collapses to a single column on phones.

   Photos: each .founder__photo shows an initials monogram until a real
   image is added. To drop a photo in later, place
     <img class="founder__img" src="…" alt="…">
   as the FIRST child of .founder__photo — it fills the frame and hides
   the monogram automatically. Nothing else needs to change.
   ═══════════════════════════════════════════════════════════════════ */
.founders {
  position: relative;
  background: var(--bg-alt);
  border-top: 1px solid var(--line);
  padding: clamp(84px, 13vh, 172px) var(--space-section-x);
  overflow: hidden;
}
.founders__inner {
  max-width: 1560px;
  margin: 0 auto;
  display: grid;
  /* v1.59 — cards get more room on desktop (was 0.8fr / 1.2fr); the ≤1024
     rule below collapses this to a single column, so this only affects the
     two-column desktop layout. */
  grid-template-columns: minmax(0, 0.66fr) minmax(0, 1.34fr);
  gap: clamp(24px, 2.6vw, 48px);
  align-items: center;   /* rail copy sits centred against the tall cards */
}

/* Left rail — eyebrow, title, then the shared narrative underneath. */
.founders__text {
  display: flex;
  flex-direction: column;
}
.founders__eyebrow {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 clamp(18px, 2.4vw, 28px);
}
.founders__title {
  font-family: var(--font-display);
  font-size: clamp(38px, 5.6vw, 68px);
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.0;
  color: var(--fg);
  margin: 0;
}
.founders__lead {
  margin: clamp(22px, 3.2vw, 36px) 0 0;
  max-width: 44ch;
  color: var(--fg-soft);
  font-size: clamp(15px, 1.12vw, 17px);
  line-height: 1.68;
}
.founders__lead strong { color: var(--fg); font-weight: 600; }

/* v1.59 — desktop only: the left rail was visually out-weighing the
   portraits, so the title is dialled down and the copy set a touch
   narrower. Mobile/tablet (≤1024, single column) keep their sizes. */
@media (min-width: 1025px) {
  .founders__title { font-size: clamp(36px, 4vw, 52px); }
  .founders__lead  { max-width: 52ch; }
}

/* v1.63 — founders lead: force the intro break so the names sit on line 1.
   Desktop (wide): line 1 ends "...Nikitha Narohna," and "Papa" drops below.
   Phone: line 1 ends "...Nikitha" and "Narohna" drops below. In between the
   copy just wraps naturally. */
.fbreak-mob, .fbreak-desk { display: none; }
@media (min-width: 1200px) { .fbreak-desk { display: inline; } }
@media (max-width: 600px)  { .fbreak-mob  { display: inline; } }

/* Right — two large portrait cards, name + role set over the photo */
.founders__people {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(14px, 1.4vw, 22px);
}
.founder { position: relative; transition: transform var(--transition); }
.founder__photo {
  position: relative;
  margin: 0;
  aspect-ratio: 3 / 4;
  border-radius: 10px;
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 50% 12%, rgba(201,161,129,0.16), transparent 60%),
    linear-gradient(165deg, var(--surface), #0c0c0c 70%);
  display: grid;
  place-items: center;
  box-shadow: 0 22px 54px rgba(0, 0, 0, 0.42);
  transition: box-shadow var(--transition);
}
/* Initials monogram placeholder (hidden once a real .founder__img exists) */
.founder__monogram {
  font-family: var(--font-display);
  font-size: clamp(44px, 7vw, 92px);
  font-weight: 800;
  letter-spacing: 0.02em;
  color: rgba(201, 161, 129, 0.42);
  user-select: none;
}
.founder__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(100%);         /* portraits stay fully black & white */
  z-index: 1;                       /* covers the monogram */
  transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}
/* Bottom scrim keeps the overlaid name legible over any photo — only
   drawn once a real photo has replaced the monogram. */
.founder__photo::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 62%;
  background: linear-gradient(to top, rgba(0,0,0,0.86), rgba(0,0,0,0.34) 46%, transparent);
  opacity: 0;
  transition: opacity var(--transition);
  pointer-events: none;
  z-index: 2;
}
.founder__photo:has(.founder__img)::after { opacity: 1; }

/* Name + role, set over the photo (Mobius-style) */
.founder__caption {
  position: absolute;
  left: clamp(16px, 1.7vw, 26px);
  right: clamp(16px, 1.7vw, 26px);
  bottom: clamp(15px, 1.7vw, 24px);
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 6px;
  pointer-events: none;
}
.founder__name {
  font-family: var(--font-display);
  font-size: clamp(23px, 2.1vw, 34px);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.04;
  color: #fff;
}
.founder__role {
  font-size: clamp(11px, 0.85vw, 12.5px);
  font-weight: 600;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--accent);
}

/* Hover (pointer devices) — the card lifts and the photo eases in.
   The lift lives on .founder (untouched by GSAP); the photo's own
   transform is owned by the reveal, so only its box-shadow/border move. */
@media (hover: hover) {
  .founder:hover { transform: translateY(-5px); }
  .founder:hover .founder__photo {
    box-shadow: 0 32px 70px rgba(0, 0, 0, 0.54);
  }
  .founder:hover .founder__img { transform: scale(1.05); }
}

/* Scroll-reveal — GSAP-driven (see animations.js: FOUNDERS reveal), matching
   the mask-rise / stagger grammar the rest of the site uses (Contact,
   Events, Services). Elements are visible by default here so the section
   still reads correctly with GSAP absent or prefers-reduced-motion on;
   the JS sets the hidden "from" state itself before animating in. */

/* ── Responsive ── */
@media (max-width: 1024px) {
  .founders__inner { grid-template-columns: 1fr; gap: clamp(36px, 6vw, 56px); align-items: start; }
  .founders__lead  { max-width: 62ch; }
}
@media (max-width: 600px) {
  .founders__people { grid-template-columns: 1fr; gap: clamp(18px, 5vw, 26px); }
  .founder__photo   { aspect-ratio: 4 / 5; }   /* a touch less tall when full-width */
  .founder__name    { font-size: clamp(24px, 7vw, 32px); }
}


/* ═══════════════════════════════════════════════════════════════════
   PAGE TRANSITIONS (v1.74)
   ═══════════════════════════════════════════════════════════════════
   THE BUG THIS FIXES — measured frame-by-frame off two screen
   recordings, not eyeballed:

     papabear   click → ONE-frame cut to #000 → the screen sits at a
                mean luminance of 12 with an inter-frame delta of
                EXACTLY 0.00 for 330–730ms (nothing is being painted
                at all) → content then fades up over a further
                400–830ms.
     apogee     click → the SAME one-frame cut → dead frame lasts
                ~100ms and is luminance 188 on a 224-bright site →
                content settles in ~170ms.

   Apogee is not doing anything we lack. It has the identical hard
   cut. It simply (a) never parks on a dead frame long enough to
   perceive and (b) is white-on-white, so its dead frame looks like
   the page minus content. Ours is #000 on a dark-but-not-black page,
   so the same gap reads as the screen switching off. Two-thirds of a
   second of that is what "stuck" is.

   The dead frame IS the HTML round trip. No animation can be painted
   during it — so it is removed rather than covered:

     1. THE OLD PAGE STAYS ON SCREEN WHILE THE NEW ONE LOADS.
        @view-transition hands the swap to the browser: it holds the
        outgoing page, waits for the incoming document, and crossfades.
        There is no longer any moment at which nothing is painted,
        however slow the server is.
     2. THE WAIT ITSELF IS PREFETCHED AWAY (js/pb-transition.js), so
        the crossfade starts ~80ms after the click, not 700ms.

   Chrome/Edge 126+ and Safari 18.2+ run this. Firefox ignores the
   at-rule for now and falls back to a plain navigation — which the
   prefetch alone already brings to roughly apogee's ~100ms, so the
   fallback path lands on the thing we were asked to match anyway.  */

@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}

/* 300ms out / 380ms in, overlapping. The incoming page carries a 12px
   rise so arriving has a direction — this is the whole of the entry
   animation now. The GSAP page-entry cascades that used to blank the
   page and fade it back over 1.39s are gone (see animations.js). */
::view-transition-old(root) {
  animation: pb-vt-out 300ms cubic-bezier(0.4, 0, 1, 1) both;
}
::view-transition-new(root) {
  animation: pb-vt-in 380ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes pb-vt-out { to   { opacity: 0; } }
@keyframes pb-vt-in  { from { opacity: 0; transform: translateY(12px); } }

/* THE FURNITURE DOESN'T MOVE. The navbar and the WhatsApp button are
   identical on every page, so lifting them out of the crossfade makes
   them PERSIST across the navigation instead of dissolving and
   re-forming. This is the single detail that makes apogee read as
   "the content changed" rather than "a page loaded" — their header
   never flinches. Names must be unique per document; both of these
   are single instances (#navbar, one .wa-float in footer.php), and a
   duplicate name would throw and skip the whole transition. */
.nav      { view-transition-name: pb-nav; }
.wa-float { view-transition-name: pb-wa; }

::view-transition-group(pb-nav),
::view-transition-group(pb-wa)        { animation: none; }
::view-transition-image-pair(pb-nav),
::view-transition-image-pair(pb-wa)   { isolation: none; }
::view-transition-old(pb-nav),
::view-transition-old(pb-wa)          { display: none; }
::view-transition-new(pb-nav),
::view-transition-new(pb-wa)          { animation: none; }

/* The mobile curtain is fixed-position and full-bleed; captured
   mid-close it would smear across the transition. It is never meant
   to persist across a navigation. */
.mobmenu { view-transition-name: none; }


/* ═══════════════════════════════════════════════════════════════════════
   v1.080 — THE BLOG
   ═══════════════════════════════════════════════════════════════════════
   The posts the client writes in wp-admin, in the site's own language: black
   page, DM Sans, the tan accent, monochrome photography that blooms to colour
   under the cursor, hairline glass panels and capsule buttons. Nothing new is
   invented here — the kicker chip and aura are the Events page's, the cards
   borrow the overview cards' image treatment, the back button is the Services
   page's, and the headline uses the same .mask-line reveal as Events and
   Contact.
   ═══════════════════════════════════════════════════════════════════════ */

.subpage--blogs { padding-top: var(--nav-h); }
.subpage--post  { padding-top: var(--nav-h); }

/* ─── The nav item you are currently on ───
   The only nav item with children (a post, a category, a tag), so the only one
   worth lighting up. Full opacity plus a tan hairline under it — enough to
   read as "you are here" without turning into a second button. */
.nav__links a.is-current { opacity: 1; }
.nav__links a.is-current::after {
  content: '';
  display: block;
  height: 1.5px;
  margin-top: 4px;
  background: var(--accent);
  border-radius: 2px;
}

/* Six links now sit between the logo and the brochure pill. On a 13" laptop
   that is tight, so the row tightens with it rather than wrapping or
   colliding — phones are unaffected, they get the curtain menu at 768px. */
@media (min-width: 769px) and (max-width: 1180px) {
  .nav__links   { gap: clamp(13px, 1.9vw, 26px); margin-left: clamp(14px, 2.6vw, 34px); }
  .nav__links a { font-size: 12px; letter-spacing: 0.5px; }
  .nav__cta     { padding: 9px 16px; font-size: 12px; margin-left: 10px; }
  .nav__brochure { padding: 8px 13px; font-size: 11.5px; }
}

/* ═══════════════ BLOG INDEX ═══════════════ */
.blogs {
  position: relative;
  isolation: isolate;
  background: var(--bg);
  /* v1.083 — THIS ONE DECLARATION IS THE MOBILE BUG.
     .blogs__aura below is 140vw wide and centred, so it hangs ~20vw off each
     side of the screen. .events has carried `overflow: hidden` since v1.44 for
     exactly that reason; .blogs was written without it and leaned on
     `body { overflow-x: hidden }` instead.

     That rule is the difference between a desktop browser and a phone. Desktop
     honours it, which is why device emulation in DevTools looked perfectly
     aligned. Real mobile browsers apply body-level overflow-x far less
     reliably, so the aura escaped, the document became ~78px wider than the
     screen, and the page could be panned sideways — which is what "not
     aligned" looks like from the reader's side: a headline touching the left
     edge, the first two letters of a line missing.

     Clipped at the section, like Events, it cannot escape in the first place. */
  overflow: hidden;
  padding: clamp(48px, 8vh, 88px) var(--space-section-x) clamp(56px, 9vh, 96px);
}

/* The same slow warm breath that sits behind the Events headline, pulled up
   behind the masthead so the top of the page isn't flat black. */
.blogs__aura {
  position: absolute;
  z-index: 0;
  top: 0;
  left: 50%;
  width: min(1200px, 140vw);
  height: min(760px, 90vw);
  transform: translate(-50%, -34%);
  background: radial-gradient(closest-side,
      rgba(201, 161, 129, 0.15) 0%,
      rgba(201, 161, 129, 0.06) 40%,
      rgba(201, 161, 129, 0) 72%);
  pointer-events: none;
  animation: eventsAura 16s ease-in-out infinite;
}

.blogs__head {
  position: relative;
  z-index: 1;
  max-width: 900px;
  margin: 0 auto clamp(40px, 6vh, 68px);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.blogs__kicker {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 8px 16px 8px 13px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  font-size: clamp(10.5px, 1vw, 12px);
  font-weight: 600;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: rgba(244, 242, 238, 0.86);
  margin-bottom: clamp(20px, 3vh, 30px);
}
.blogs__pulse {
  width: 8px; height: 8px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent);
  animation: eventsPulse 2.4s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

.blogs__headline {
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: clamp(38px, 7.4vw, 104px);
  /* v1.081 — 0.96, not the 0.92 the other headlines use. Those are single
     monumental statements; this one stacks two words of the brand name and at
     phone sizes 0.92 closed the gap between the lines until "PAPA BEAR" and
     "BLOGS" read as one run-on word. Four hundredths of an em is the whole
     difference and nothing else about the type changed. */
  line-height: 0.96;
  letter-spacing: clamp(-3px, -0.028em, -1.5px);
  color: var(--fg);
  margin: 0;
  text-wrap: balance;
  /* An archive headline is a term the client named, so it can be any length
     — it wraps instead of overflowing, unlike the fixed site headlines. */
  overflow-wrap: anywhere;
}
.blogs__headline .mask-line { display: block; }

.blogs__lede {
  max-width: 620px;
  margin: clamp(18px, 2.6vh, 26px) auto 0;
  font-size: clamp(14px, 1.55vw, 16px);
  line-height: 1.7;
  color: var(--fg-soft);
}

/* ─── The grid ───
   auto-fill rather than auto-fit: with two posts published, auto-fit would
   stretch them across the full width into two enormous cards; auto-fill keeps
   them card-sized and lets the row end early, which is what a young blog
   should look like. */
.blogs__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: clamp(18px, 2.2vw, 30px);
  max-width: 1400px;
  margin: 0 auto;
}

/* ═══════════════ POST CARD ═══════════════ */
.blogcard {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color 0.4s ease, transform 0.45s cubic-bezier(0.22, 0.9, 0.24, 1), box-shadow 0.45s ease;
}
.blogcard:hover {
  border-color: rgba(201, 161, 129, 0.4);
  transform: translateY(-4px);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.45);
}

.blogcard__link {
  display: flex;
  flex-direction: column;
  height: 100%;
  color: inherit;
}
.blogcard__link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -3px;
}

.blogcard__media {
  display: block;
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: #141414;
  flex-shrink: 0;
}
.blogcard__img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Monochrome discipline (v1.38) — every still on this site is black & white
     until you point at it. */
  filter: grayscale(1);
  transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1), filter 0.5s ease;
}
.blogcard:hover .blogcard__img { filter: grayscale(0); transform: scale(1.05); }

/* The stand-in for a post with no image in it — the post's own initial over
   the tan wash, not a stock photo and not a grey rectangle. */
.pb-ph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%; height: 100%;
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(201, 161, 129, 0.20) 0%, rgba(201, 161, 129, 0) 68%),
    linear-gradient(160deg, #171717 0%, #0d0d0d 100%);
}
.pb-ph__mark {
  font-family: var(--font-display);
  font-size: clamp(46px, 7vw, 78px);
  font-weight: 900;
  letter-spacing: -0.04em;
  color: rgba(201, 161, 129, 0.5);
  line-height: 1;
}

/* Category chip — a sibling of the card link, not a child (nested anchors are
   invalid and browsers un-nest them), floated over the image. */
.blogcard__cat {
  position: absolute;
  z-index: 2;
  top: 14px; left: 14px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(10, 10, 10, 0.62);
  -webkit-backdrop-filter: blur(12px) saturate(150%);
  backdrop-filter: blur(12px) saturate(150%);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: rgba(244, 242, 238, 0.92);
  transition: var(--transition);
}
.blogcard__cat:hover { background: var(--accent); color: var(--ink); border-color: var(--accent); }

.blogcard__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: clamp(18px, 2vw, 26px);
  gap: 10px;
}

.blogcard__meta {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.blogcard__dot {
  width: 3px; height: 3px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.7;
}

/* v1.081 — TITLE AND EXCERPT ARE LINE-CLAMPED.
   A post's title is whatever the client types, and the Hair Botox one runs to
   four lines on a phone before the excerpt has even started — so one card
   filled the screen and the grid below it read as an accident. Clamping both
   gives every card the same shape whatever the copy does, which is what makes
   a row of them scan as a list.
   Progressive by design: where line-clamp is unsupported the text simply
   shows in full. Nothing is ever hidden with no way back — the excerpt is a
   trailer, and the whole card is a link to the rest of it. */
.blogcard__title {
  font-family: var(--font-display);
  font-size: clamp(18px, 1.6vw, 22px);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.015em;
  color: var(--fg);
  transition: color 0.3s ease;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}
.blogcard:hover .blogcard__title { color: var(--accent); }

.blogcard__excerpt {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  font-size: 14px;
  line-height: 1.68;
  color: var(--fg-soft);
}

/* Pushed to the bottom of the card so the "Read article" line sits on one
   baseline across a row, however long the titles are. */
.blogcard__more {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: auto;
  padding-top: 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  color: var(--accent);
}
.blogcard__more svg { transition: transform 0.32s cubic-bezier(0.22, 0.9, 0.24, 1); }
.blogcard:hover .blogcard__more svg { transform: translateX(4px); }

/* ─── LEAD CARD (first post, page one only) ───
   The image moves beside the copy instead of above it and the card spans the
   full grid, which gives the newest post the weight an editorial index gives
   its lead. Below 900px it simply reverts to an ordinary card. */
@media (min-width: 900px) {
  .blogcard--lead {
    grid-column: 1 / -1;
  }
  .blogcard--lead .blogcard__link {
    flex-direction: row;
    align-items: stretch;
  }
  .blogcard--lead .blogcard__media {
    width: 54%;
    aspect-ratio: auto;
    min-height: 340px;
  }
  .blogcard--lead .blogcard__body {
    width: 46%;
    justify-content: center;
    padding: clamp(28px, 3.4vw, 52px);
    gap: 14px;
  }
  .blogcard--lead .blogcard__title { font-size: clamp(26px, 2.5vw, 38px); line-height: 1.14; -webkit-line-clamp: 3; line-clamp: 3; }
  .blogcard--lead .blogcard__excerpt { font-size: 15px; -webkit-line-clamp: 4; line-clamp: 4; }
}

/* ═══════════════ PAGINATION ═══════════════ */
.blogpag {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 8px;
  margin: clamp(40px, 6vh, 68px) auto 0;
}
.blogpag__item a,
.blogpag__item span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 40px;
  height: 40px;
  padding: 0 14px;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.6px;
  color: var(--fg-soft);
  transition: var(--transition);
}
.blogpag__item a:hover { color: var(--fg); border-color: var(--fg-faint); }
.blogpag__item .current {
  background: var(--fg);
  border-color: var(--fg);
  color: var(--ink);
}
.blogpag__item .dots { border-color: transparent; padding: 0 4px; min-width: 0; }

/* ═══════════════ EMPTY STATE ═══════════════
   A blog with nothing in it yet is the NORMAL first state of this feature, not
   an error, so it gets a designed panel rather than a blank page — and a way
   out of it. */
.blogs__empty {
  position: relative;
  z-index: 1;
  max-width: 520px;
  margin: 0 auto;
  padding: clamp(32px, 4vw, 48px);
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.blogs__empty-ic { color: var(--accent); margin: 0 auto 16px; opacity: 0.9; }
.blogs__empty-title {
  font-family: var(--font-display);
  font-size: clamp(20px, 2.2vw, 26px);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--fg);
}
.blogs__empty-copy {
  margin-top: 10px;
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--fg-soft);
}
.blogs__empty-btn {
  display: inline-block;
  margin-top: 22px;
  padding: 12px 26px;
  border: 1.5px solid var(--fg);
  border-radius: 999px;
  background: var(--fg);
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.5px;
  transition: var(--transition);
}
.blogs__empty-btn:hover { background: transparent; color: var(--fg); }

.blogs__backrow {
  display: flex;
  justify-content: center;
  padding: 0 var(--space-section-x) clamp(48px, 8vh, 84px);
}
.blogs__backrow .services-back { margin-bottom: 0; }

/* ═══════════════════════════════════════════════════════════════════════
   THE POST PAGE
   ═══════════════════════════════════════════════════════════════════════ */
.post { position: relative; }

/* ─── Header with a hero photograph ───
   The post's first main image, full-bleed, with the title set over its lower
   half — the hero grammar the homepage already uses. */
.post__head {
  position: relative;
  isolation: isolate;
  overflow: hidden;   /* same 140vw aura, same fix — see .blogs above */
  padding: clamp(40px, 6vh, 72px) var(--space-section-x) clamp(32px, 5vh, 56px);
}

.post__head--hero {
  display: flex;
  align-items: flex-end;
  min-height: clamp(420px, 62vh, 640px);
  padding-top: clamp(80px, 14vh, 150px);
}

.post__hero {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}
.post__hero-img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* The hero is the one still on the site that stays in colour — it is the
     subject of the page, not a thumbnail of something else. */
  transform: scale(1.03);
}
/* Melts the photograph into the black page, exactly as .hero__overlay does */
.post__hero-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, var(--bg) 0%, rgba(0,0,0,0.72) 32%, rgba(0,0,0,0.28) 62%, rgba(0,0,0,0.42) 100%);
}

/* No image? Then no empty frame — the aura from the Events page instead. */
.post__aura {
  position: absolute;
  z-index: -1;
  top: 0; left: 50%;
  width: min(1100px, 140vw);
  height: min(680px, 90vw);
  transform: translate(-50%, -40%);
  background: radial-gradient(closest-side,
      rgba(201, 161, 129, 0.16) 0%,
      rgba(201, 161, 129, 0.06) 40%,
      rgba(201, 161, 129, 0) 72%);
  pointer-events: none;
}
.post__head--plain { padding-top: clamp(48px, 8vh, 88px); }

.post__head-inner {
  position: relative;
  width: 100%;
  max-width: 860px;
  margin: 0 auto;
}

.post__back { margin-bottom: clamp(16px, 2.2vw, 26px); }
.post__head--hero .post__back {
  border-color: rgba(255, 255, 255, 0.22);
  background: rgba(10, 10, 10, 0.42);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}

.post__cat {
  display: inline-block;
  margin-bottom: 16px;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid rgba(201, 161, 129, 0.45);
  background: rgba(201, 161, 129, 0.1);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--accent);
  transition: var(--transition);
}
.post__cat:hover { background: var(--accent); color: var(--ink); }

.post__title {
  font-family: var(--font-display);
  font-size: clamp(30px, 4.6vw, 62px);
  font-weight: 800;
  line-height: 1.06;
  letter-spacing: clamp(-2px, -0.025em, -1px);
  color: var(--fg);
  text-wrap: balance;
}

.post__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: clamp(14px, 2vw, 20px);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.post__head--hero .post__meta { color: rgba(244, 242, 238, 0.72); }
.post__dot { width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: 0.7; }

/* ─── THE ARTICLE BODY ───
   Everything WordPress can emit from the editor, styled once. Without this
   block a post renders in browser defaults — Times, blue underlined links,
   white bullets — inside a black page, which is the one place a custom theme
   most obviously falls apart. Measure is capped at 760px because long lines
   are the fastest way to make a long read feel like work. */
.post__body {
  max-width: 760px;
  margin: 0 auto;
  padding: clamp(28px, 5vh, 52px) var(--space-section-x) clamp(20px, 3vh, 32px);
  font-size: clamp(15.5px, 1.4vw, 17.5px);
  line-height: 1.85;
  color: var(--fg-soft);
}

.post__body > * + * { margin-top: 1.15em; }

.post__body h1,
.post__body h2,
.post__body h3,
.post__body h4,
.post__body h5,
.post__body h6 {
  font-family: var(--font-display);
  color: var(--fg);
  font-weight: 800;
  line-height: 1.16;
  letter-spacing: -0.018em;
  margin-top: 1.9em;
  margin-bottom: 0.5em;
}
.post__body h2 { font-size: clamp(23px, 2.6vw, 33px); }
.post__body h3 { font-size: clamp(19px, 2vw, 25px); }
.post__body h4 { font-size: clamp(17px, 1.7vw, 20px); }
.post__body h5,
.post__body h6 {
  font-size: 13px;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: var(--accent);
}
.post__body > :first-child { margin-top: 0; }

/* The opening paragraph carries a little more weight — a lede without the
   client having to mark one up. */
.post__body > p:first-of-type {
  font-size: 1.08em;
  color: rgba(244, 242, 238, 0.86);
}

.post__body a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color 0.25s ease;
}
.post__body a:hover { color: var(--fg); }

.post__body strong, .post__body b { color: var(--fg); font-weight: 700; }
.post__body em, .post__body i { font-style: italic; }
.post__body mark { background: rgba(201, 161, 129, 0.28); color: var(--fg); padding: 0 3px; }

.post__body ul,
.post__body ol { padding-left: 1.35em; }
.post__body ul { list-style: disc; }
.post__body ol { list-style: decimal; }
.post__body li { margin-top: 0.5em; }
.post__body li::marker { color: var(--accent); }
.post__body li > ul,
.post__body li > ol { margin-top: 0.5em; }

.post__body blockquote {
  margin: 1.9em 0;
  padding: 4px 0 4px clamp(18px, 3vw, 30px);
  border-left: 2px solid var(--accent);
  font-family: var(--font-display);
  font-size: 1.16em;
  font-weight: 500;
  font-style: normal;
  line-height: 1.5;
  color: var(--fg);
}
.post__body blockquote cite,
.post__body blockquote footer {
  display: block;
  margin-top: 0.7em;
  font-family: var(--font-body);
  font-size: 0.66em;
  font-style: normal;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--fg-faint);
}

.post__body img,
.post__body video,
.post__body iframe { max-width: 100%; height: auto; border-radius: var(--radius); }
.post__body figure { margin: 1.9em 0; }
.post__body figure img { width: 100%; }
.post__body figcaption {
  margin-top: 10px;
  font-size: 12.5px;
  line-height: 1.6;
  letter-spacing: 0.2px;
  color: var(--fg-faint);
  text-align: center;
}

/* Wide / full-width block alignments — the editor offers them, so they work */
.post__body .alignwide  { width: min(100vw - 2 * var(--space-section-x), 1000px); max-width: none; margin-left: 50%; transform: translateX(-50%); }
.post__body .alignfull  { width: 100vw; max-width: none; margin-left: 50%; transform: translateX(-50%); border-radius: 0; }
.post__body .alignfull img { border-radius: 0; }
.post__body .aligncenter { margin-left: auto; margin-right: auto; text-align: center; }
@media (min-width: 900px) {
  .post__body .alignleft  { float: left;  margin: 0.4em 1.6em 1.2em 0; max-width: 46%; }
  .post__body .alignright { float: right; margin: 0.4em 0 1.2em 1.6em; max-width: 46%; }
}

.post__body hr {
  height: 1px;
  border: 0;
  margin: 2.6em 0;
  background: var(--line);
}

.post__body code,
.post__body kbd {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.86em;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--fg);
}
.post__body pre {
  padding: clamp(16px, 2.4vw, 24px);
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--line);
  overflow-x: auto;
  font-size: 13.5px;
  line-height: 1.65;
}
.post__body pre code { padding: 0; border: 0; background: none; }

.post__body table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92em;
}
.post__body th,
.post__body td {
  padding: 11px 14px;
  border: 1px solid var(--line);
  text-align: left;
}
.post__body th { background: var(--surface); color: var(--fg); font-weight: 700; letter-spacing: 0.4px; }

.post__body .wp-block-button__link {
  display: inline-block;
  padding: 12px 26px;
  border-radius: 999px;
  background: var(--fg);
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  transition: var(--transition);
}
.post__body .wp-block-button__link:hover { background: var(--accent); color: var(--ink); }

/* Multi-page posts (<!--nextpage-->) */
.post__pages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 2.4em;
  padding-top: 1.6em;
  border-top: 1px solid var(--line);
  font-size: 13px;
}
.post__pages-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-right: 4px;
}
.post__pages a span,
.post__pages > span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px; height: 34px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--fg-soft);
  transition: var(--transition);
}
.post__pages a:hover span { color: var(--fg); border-color: var(--fg-faint); }
.post__pages > span { background: var(--fg); border-color: var(--fg); color: var(--ink); }

/* ─── TAGS ─── */
.post__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  max-width: 760px;
  margin: 0 auto;
  padding: clamp(20px, 3vh, 30px) var(--space-section-x) 0;
}
.post__tag {
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: var(--fg-faint);
  transition: var(--transition);
}
.post__tag:hover { color: var(--accent); border-color: rgba(201, 161, 129, 0.45); }

/* ─── PREVIOUS / NEXT ─── */
.postnav {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(12px, 1.6vw, 18px);
  max-width: 900px;
  margin: clamp(36px, 6vh, 64px) auto 0;
  padding: 0 var(--space-section-x);
}
.postnav__item {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: clamp(18px, 2.2vw, 26px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color 0.35s ease, transform 0.35s cubic-bezier(0.22, 0.9, 0.24, 1);
}
.postnav__item:hover { border-color: rgba(201, 161, 129, 0.4); transform: translateY(-3px); }
.postnav__item--next { text-align: right; align-items: flex-end; }
.postnav__label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--accent);
}
.postnav__title {
  font-family: var(--font-display);
  font-size: clamp(15px, 1.4vw, 18px);
  font-weight: 700;
  line-height: 1.32;
  color: var(--fg);
}

.post__comments {
  max-width: 760px;
  margin: clamp(32px, 5vh, 56px) auto 0;
  padding: 0 var(--space-section-x);
  color: var(--fg-soft);
}

/* ─── PHONES (reworked v1.081) ───
   Measured off the client's screen recording at 388x848 rather than guessed
   at. Three things were wrong, and none of them were the grid:

   (1) THE MASTHEAD ATE THE SCREEN. font-size bottomed out at its 38px floor
       while line-height stayed at 0.92, so two lines of caps nearly touched
       and the block still ran the full width. The floor is lifted and tied to
       the viewport instead (12vw, capped at 54px), so the name sets at a size
       the phone chose — bigger AND better spaced, which sounds contradictory
       until you see that the old version was neither.
   (2) ONE CARD WAS A SCREENFUL. A four-line title plus a six-line excerpt is
       most of a phone viewport before the second post exists. The line clamps
       above cap it; here the type also steps down and the padding tightens.
   (3) THE BOOKING BLOCK SAT IN A TRENCH. .blogs' bottom padding and .contact's
       top padding stack, exactly as they did on the Contact page in v1.77,
       and the same one-line fix applies. */
@media (max-width: 768px) {
  /* v1.083 — SPACING IS SIZED IN vw, NOT vh, ON PHONES.
     vh on a phone is measured against the viewport with the URL bar HIDDEN, and
     that bar collapses and expands as you scroll. Every vh-based padding
     therefore changes size mid-scroll, so the page never quite settles — a
     wobble that does not exist in desktop device emulation, where there is no
     URL bar to collapse. This theme has met that behaviour before: it is what
     made the opening hours flicker in v1.79. vw is fixed for a given screen. */
  .blogs {
    padding-left: var(--space-section-x);
    padding-right: var(--space-section-x);
    padding-top: clamp(32px, 11vw, 52px);
    padding-bottom: clamp(40px, 13vw, 64px);
  }
  .blogs__grid { grid-template-columns: 1fr; gap: 16px; }

  .blogs__head   { margin-bottom: clamp(26px, 8vw, 40px); }
  .blogs__kicker {
    margin-bottom: 15px;
    padding: 7px 13px 7px 10px;
    letter-spacing: 1.25px;
  }
  .blogs__headline { font-size: clamp(40px, 12vw, 54px); line-height: 1; }
  .blogs__lede     { font-size: 14px; line-height: 1.62; margin-top: 13px; }

  .blogcard__media   { aspect-ratio: 3 / 2; }
  .blogcard__body    { padding: 16px 16px 18px; gap: 8px; }
  .blogcard__meta    { font-size: 10.5px; letter-spacing: 1px; }
  .blogcard__title   { font-size: 19px; }
  .blogcard__excerpt { font-size: 13.5px; line-height: 1.62; }
  .blogcard__more    { font-size: 11.5px; }
  .blogcard__cat     { top: 12px; left: 12px; padding: 5px 10px; font-size: 10px; }
  /* The lift-on-hover is a pointer gesture. On a touch screen it only ever
     fires as a jolt after the tap has already navigated. */
  .blogcard:hover { transform: none; box-shadow: none; }

  .blogpag { margin-top: clamp(28px, 9vw, 42px); gap: 6px; }

  .blogs__empty { padding: 28px 22px; }

  /* svh = the viewport with the URL bar SHOWING, so the hero does not resize
     under the reader when the bar collapses. Plain vh stays first as the
     fallback for anything that doesn't know svh. */
  .post__head--hero { min-height: clamp(340px, 52vh, 460px); min-height: clamp(340px, 52svh, 460px); }
  .post__body .alignwide { width: auto; margin-left: 0; transform: none; }
  .postnav__item--next { text-align: left; align-items: flex-start; }
}

/* v1.085 — the booking hand-off no longer appears on the Blogs page or on a
   post (the client's call: the blog should be the blog), so the rule that
   closed the gap above it went with it. */

/* Motion off — the aura and the pulse stop breathing; nothing else in this
   block moves without a cursor on it. */
@media (prefers-reduced-motion: reduce) {
  .blogs__aura,
  .blogs__pulse { animation: none; }
  .blogcard,
  .blogcard__img,
  .postnav__item { transition: none; }
}

/* ═══════════════ NOT FOUND (v1.082) ═══════════════
   The theme had no 404 template, so every unresolved URL drew the homepage at
   HTTP 200 — which is why a broken link on this site reads as "it redirected
   me to the homepage" rather than as an error. Same aura, kicker and masked
   headline as the Events and Blogs pages; nothing new invented. */
.subpage--404 { padding-top: var(--nav-h); }

.nf {
  position: relative;
  isolation: isolate;
  background: var(--bg);
  min-height: 70vh;
  min-height: 70svh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: clamp(56px, 10vh, 110px) var(--space-section-x) clamp(64px, 11vh, 120px);
}
.nf__aura {
  position: absolute;
  z-index: 0;
  top: 46%; left: 50%;
  width: min(1000px, 130vw);
  height: min(1000px, 130vw);
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side,
      rgba(201, 161, 129, 0.15) 0%,
      rgba(201, 161, 129, 0.06) 40%,
      rgba(201, 161, 129, 0) 72%);
  pointer-events: none;
  animation: eventsAura 16s ease-in-out infinite;
}
.nf__inner {
  position: relative;
  z-index: 1;
  max-width: 680px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.nf__code {
  font-family: var(--font-display);
  font-size: clamp(13px, 1.3vw, 15px);
  font-weight: 700;
  letter-spacing: 4px;
  color: var(--accent);
  margin-bottom: clamp(16px, 2.4vh, 24px);
}
.nf__headline {
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: clamp(36px, 7vw, 88px);
  line-height: 0.96;
  letter-spacing: clamp(-3px, -0.028em, -1.5px);
  color: var(--fg);
  margin: 0;
}
.nf__headline .mask-line { display: block; }
.nf__lede {
  max-width: 480px;
  margin: clamp(18px, 2.6vh, 26px) auto 0;
  font-size: clamp(14px, 1.55vw, 16px);
  line-height: 1.7;
  color: var(--fg-soft);
}
.nf__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: clamp(26px, 4vh, 40px);
}
.nf__btn {
  display: inline-block;
  padding: 12px 26px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: var(--fg-soft);
  transition: var(--transition);
}
.nf__btn:hover { color: var(--fg); border-color: var(--fg-faint); }
.nf__btn--primary {
  background: var(--fg);
  border-color: var(--fg);
  color: var(--ink);
}
.nf__btn--primary:hover { background: transparent; color: var(--fg); }

@media (prefers-reduced-motion: reduce) { .nf__aura { animation: none; } }

/* ═══════════════════════════════════════════════════════════════════════
   v1.084 — COMMENTS
   ═══════════════════════════════════════════════════════════════════════
   The theme had no comments.php, so WordPress fell back to its deprecated
   theme-compat template: class-less markup, browser-default grey textareas,
   labels jammed against inputs, a system submit button. Nothing was broken —
   there was simply nothing for a stylesheet to hold on to.

   Built from vocabulary the site already owns: the .bookpanel surface, the
   Events notify-field's hairline glass inputs, the capsule buttons, the tan
   accent for anything interactive. No new ideas, so a thread under an article
   reads like part of Papa Bear rather than like WordPress showing through.
   ═══════════════════════════════════════════════════════════════════════ */

.post__comments { /* wrapper from single.php — measure matches the article */ }

.pbcom {
  margin-top: clamp(36px, 6vh, 60px);
  padding-top: clamp(28px, 4vh, 44px);
  border-top: 1px solid var(--line);
}

.pbcom__title {
  font-family: var(--font-display);
  font-size: clamp(19px, 2vw, 25px);
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--fg);
  margin-bottom: clamp(20px, 3vw, 30px);
}

/* ─── the thread ─── */
.pbcom__list { list-style: none; padding: 0; margin: 0; }
.pbcom__list .children {
  list-style: none;
  margin: 14px 0 0;
  padding-left: clamp(14px, 3vw, 34px);
  border-left: 1px solid var(--line);
}
.pbcom__item { margin-bottom: 14px; }

.pbcom__body {
  padding: clamp(16px, 2vw, 22px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color 0.35s ease;
}
.pbcom__item:hover > .pbcom__body { border-color: #33312c; }

/* the post's own author, so a reply from the salon is legible as one */
.pbcom__item.bypostauthor > .pbcom__body {
  border-color: rgba(201, 161, 129, 0.42);
  background: linear-gradient(180deg, rgba(201, 161, 129, 0.07), rgba(201, 161, 129, 0) 60%), var(--surface);
}

.pbcom__head {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-bottom: 12px;
}
.pbcom__avatar {
  width: 40px; height: 40px;
  flex-shrink: 0;
  border-radius: 50%;
  object-fit: cover;
  filter: grayscale(1);
}
.pbcom__who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pbcom__author {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.1px;
  color: var(--fg);
}
.pbcom__author a { color: inherit; }
.pbcom__author a:hover { color: var(--accent); }
.pbcom__date {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--fg-faint);
  transition: color 0.25s ease;
}
.pbcom__date:hover { color: var(--fg-soft); }

.pbcom__pending {
  margin-bottom: 10px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  background: rgba(201, 161, 129, 0.1);
  border: 1px solid rgba(201, 161, 129, 0.3);
  font-size: 12.5px;
  color: var(--accent);
}

.pbcom__text {
  font-size: 15px;
  line-height: 1.72;
  color: var(--fg-soft);
}
.pbcom__text > * + * { margin-top: 0.9em; }
.pbcom__text a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.pbcom__text ul, .pbcom__text ol { padding-left: 1.3em; }
.pbcom__text ul { list-style: disc; }
.pbcom__text ol { list-style: decimal; }
.pbcom__text blockquote {
  padding-left: 14px;
  border-left: 2px solid var(--line);
  color: var(--fg-faint);
}

.pbcom__actions {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 12px;
}
.pbcom__actions a {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--accent);
  transition: opacity 0.25s ease;
}
.pbcom__actions a:hover { opacity: 0.65; }
.pbcom__edit a { color: var(--fg-faint); }

.pbcom__closed {
  margin-top: 18px;
  font-size: 13.5px;
  color: var(--fg-faint);
}

/* ─── the form ─── */
.pbform {
  margin-top: clamp(28px, 4vw, 40px);
  padding: clamp(20px, 3vw, 32px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
/* When replying, WordPress moves this whole block under the comment being
   answered — the accent edge makes it obvious where it went. */
.pbcom__item .pbform { border-color: rgba(201, 161, 129, 0.4); }

.pbform__title {
  font-family: var(--font-display);
  font-size: clamp(17px, 1.8vw, 21px);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--fg);
}
.pbform__title small { font-size: 12px; font-weight: 500; }
.pbform__cancel a {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.pbform__cancel a:hover { color: var(--accent); }

.pbform__note,
.pbform .comment-notes,
.pbform .logged-in-as {
  margin-top: 6px;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--fg-faint);
}
.pbform .logged-in-as a { color: var(--accent); }

.pbform__form { margin-top: clamp(16px, 2.4vw, 22px); }

.pbform__row { margin-bottom: 14px; }
.pbform__row label {
  display: block;
  margin-bottom: 7px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--fg-soft);
}
.pbform__req { color: var(--accent); }
.pbform__opt {
  font-weight: 500;
  letter-spacing: 0.6px;
  text-transform: none;
  color: var(--fg-faint);
}

/* Name / Email / Website sit on one row from tablet up — three short fields
   stacked was most of a screen before the comment box even started. */
@media (min-width: 700px) {
  .pbform__form { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 14px; }
  .pbform__row--full,
  .pbform__consent,
  .pbform__note,
  .pbform .comment-notes,
  .pbform .logged-in-as,
  .pbform .form-submit { grid-column: 1 / -1; }
}

.pbform__input,
.pbform__textarea,
.pbform input[type="text"],
.pbform input[type="email"],
.pbform input[type="url"],
.pbform textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.045);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  backdrop-filter: blur(16px) saturate(150%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 15px;   /* 16px-ish: anything under 16 makes iOS Safari zoom on focus */
  line-height: 1.6;
  outline: none;
  transition: border-color 0.3s, box-shadow 0.3s;
}
.pbform__textarea,
.pbform textarea { min-height: 132px; resize: vertical; display: block; }

.pbform__input::placeholder,
.pbform__textarea::placeholder,
.pbform textarea::placeholder { color: var(--fg-faint); }

.pbform__input:focus,
.pbform__textarea:focus,
.pbform input:focus,
.pbform textarea:focus {
  border-color: rgba(201, 161, 129, 0.5);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 0 0 3px rgba(201, 161, 129, 0.12);
}

.pbform__consent {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 4px 0 16px;
}
.pbform__consent input[type="checkbox"] {
  width: 16px; height: 16px;
  margin-top: 2px;
  flex-shrink: 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.pbform__consent label {
  font-size: 13px;
  line-height: 1.5;
  color: var(--fg-faint);
  cursor: pointer;
}

/* Explicit, so no future rule (a plugin, a page builder) can paint this
   paragraph the way the orphaned .form-submit above did. */
.pbform .form-submit {
  margin: 0;
  padding: 0;
  width: auto;
  background: none;
  border: 0;
}
.pbform__submit,
.pbform input[type="submit"],
.pbform button[type="submit"] {
  display: inline-block;
  padding: 13px 30px;
  border: 1.5px solid var(--fg);
  border-radius: 999px;
  background: var(--fg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.5px;
  cursor: pointer;
  transition: var(--transition);
}
.pbform__submit:hover,
.pbform input[type="submit"]:hover,
.pbform button[type="submit"]:hover { background: var(--accent); border-color: var(--accent); color: var(--ink); }
.pbform__submit:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Comments off entirely, with none posted: core prints this on its own. */
.pbcom .no-comments {
  font-size: 13.5px;
  color: var(--fg-faint);
}

@media (max-width: 700px) {
  .pbform { padding: 18px 16px; }
  .pbcom__body { padding: 15px 14px; }
  .pbcom__avatar { width: 34px; height: 34px; }
}
