/* Knead Massage Studio — shared system
   World: "Lines of Pressure, after dark" (direction contract 10a44dff), in the owner's brand-guide palette
   (site-docs/brand, hero-brand spec 2026-11-05): Dim the Lights ground, Linen ink, Ember for Book only,
   Hot Stone hairline thread. Token names are the original ones; the values below are the brand's. */

/* self-hosted fonts (SIL OFL, licences in /fonts; from Google Fonts Karla v33 + Libre Caslon Display v18,
   2026-10-30). Same origin + preload in every <head>, so they usually land before first paint. */
@font-face { font-family: "Karla"; font-style: italic; font-weight: 300 800; font-display: swap; src: url("/fonts/karla-italic-latin-ext.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Karla"; font-style: italic; font-weight: 300 800; font-display: swap; src: url("/fonts/karla-italic-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Karla"; font-style: normal; font-weight: 300 800; font-display: swap; src: url("/fonts/karla-latin-ext.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Karla"; font-style: normal; font-weight: 300 800; font-display: swap; src: url("/fonts/karla-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Libre Caslon Display"; font-style: normal; font-weight: 400; font-display: swap; src: url("/fonts/libre-caslon-display-latin-ext.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Libre Caslon Display"; font-style: normal; font-weight: 400; font-display: swap; src: url("/fonts/libre-caslon-display-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
/* Caslon Display ships no italic: the blush <em> word borrows Libre Caslon Text Italic v5 (OFL, 2026-10-30)
   as the family's italic, so the browser draws real italic letterforms instead of slanting the upright.
   Text is cut larger (x-height 54 vs 43, caps 77 vs 69 at 100px, measured in Chrome): 85% splits the two. */
@font-face { font-family: "Libre Caslon Display"; font-style: italic; font-weight: 400; font-display: swap; size-adjust: 85%; src: url("/fonts/libre-caslon-text-italic-latin-ext.woff2") format("woff2"); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: "Libre Caslon Display"; font-style: italic; font-weight: 400; font-display: swap; size-adjust: 85%; src: url("/fonts/libre-caslon-text-italic-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

/* metric-matched stand-ins while the Google fonts load, so the swap does not move text (CLS).
   Measured in Chrome 2026-10-30 against Arial/Georgia; re-measure if either web font changes. */
@font-face { font-family: "Karla Fallback"; src: local("Arial"); size-adjust: 101.71%; ascent-override: 90.46%; descent-override: 24.58%; line-gap-override: 0%; }
@font-face { font-family: "Caslon Fallback"; src: local("Georgia"); size-adjust: 83.56%; ascent-override: 116.09%; descent-override: 32.31%; line-gap-override: 0%; }

:root {
  /* WCAG ratios (computed, flat colours) in the spec, section 5.2 */
  --lacquer: #23211C;                      /* Dim the Lights */
  --lacquer-2: #2C2A24;                    /* DTL lifted: sheets, fields */
  --lacquer-deep: #1A1915;                 /* DTL deepened: footer, hero ground */
  --ivory: #F4EFEE;                        /* Linen, 14.11 on DTL */
  --ivory-2: rgba(244, 239, 238, .74);     /* 8.28 */
  --ivory-3: rgba(244, 239, 238, .52);     /* 4.82 (4.53 on lacquer-2) */
  --amber: #896247;                        /* Ember: Book fill only */
  --amber-2: #7F5C43;                      /* Ember darkened: Book hover (Linen on it 5.24) */
  --blush: #9C8E82;                        /* Hot Stone + 10% Linen: 5.06 (exact Hot Stone is 4.39, short of 4.5 for small text) */
  --blush-2: #928376;                      /* Hot Stone: underlines, scrollbar (non-text) */
  --rule: rgba(146, 131, 118, .38);        /* Hot Stone hairline, as visible as the old one */
  --rule-2: rgba(146, 131, 118, .19);
  --on-book: #F4EFEE;                      /* text on a Book fill: Linen on Ember 4.72 (dark text would be 2.99) */
  --book-edge: #A3846F;                    /* Ember lifted: the Book's 1px edge on the dark ground (4.66) */
  --flag: #A98C79;                         /* [CONFIRM] placeholders: 5.14 on DTL, 4.59 on lacquer-2 */

  --display: "Libre Caslon Display", "Caslon Fallback", "Libre Caslon Text", Georgia, serif;
  --body: "Karla", "Karla Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;

  --pad: clamp(20px, 4.4vw, 60px);
  --inset: 40px;               /* content sits this far right of the thread */
  --max: 1320px;
  --nav-h: 64px;
  --ease: cubic-bezier(.16, 1, .3, 1);
}

@media (max-width: 699px) { :root { --inset: 22px; } }

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--lacquer);
  color: var(--ivory);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.55;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--blush); color: var(--lacquer); }
::-moz-selection { background: var(--blush); color: var(--lacquer); }
html { scrollbar-color: var(--blush-2) var(--lacquer); scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: var(--lacquer); }
::-webkit-scrollbar-thumb { background: var(--blush-2); border: 3px solid var(--lacquer); }
::-webkit-scrollbar-thumb:hover { background: var(--blush); }

:focus { outline: none; }
/* 2px since owner round 3 batch 2 (2026-11-09, fresh review #19: the 1px ring was hard to see) */
:focus-visible { outline: 2px solid var(--blush); outline-offset: 4px; }
.btn:focus-visible { outline-offset: 3px; }

img, video, svg { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
p a, li a, dd a { text-decoration: underline; text-underline-offset: .22em; text-decoration-thickness: 1px; text-decoration-color: var(--blush-2); }
p a:hover, li a:hover, dd a:hover { text-decoration-color: var(--blush); }
ul, ol { margin: 0; padding: 0; list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
h1, h2, h3, h4 { margin: 0; font-family: var(--display); font-weight: 400; text-wrap: balance; }
p { margin: 0; }
.num, .price, .board td, .strip b, time { font-variant-numeric: tabular-nums lining-nums; }

.sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.sr:focus-visible { position: fixed; top: 12px; left: var(--pad); z-index: 60; width: auto; height: auto; margin: 0; padding: 12px 18px; clip: auto; background: var(--lacquer); color: var(--ivory); }

.wrap { max-width: var(--max); margin-inline: auto; padding-inline: var(--pad); }

/* ---------- type scale ---------- */
h1 { font-size: clamp(2.75rem, 5.6vw, 5rem); line-height: .98; letter-spacing: -.015em; }
h1 em { font-style: italic; color: var(--blush); }
h2 { font-size: clamp(2rem, 3.8vw, 3.25rem); line-height: 1.04; letter-spacing: -.01em; }
h3 { font-size: clamp(1.35rem, 2vw, 1.75rem); line-height: 1.3; }
.lede { font-size: clamp(1.05rem, 1.4vw, 1.25rem); line-height: 1.5; color: var(--ivory-2); max-width: 36em; }
.small { font-size: .9rem; color: var(--ivory-2); }
.meta { font-size: .85rem; letter-spacing: .02em; color: var(--ivory-3); }
mark.confirm {
  background: none; color: var(--flag); font-family: var(--body); font-size: .72em;
  letter-spacing: .04em; vertical-align: super; line-height: 0; margin-left: .15em;
}
.confirm-note { color: var(--flag); font-size: .85rem; margin-top: 18px; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 46px; padding: 0 22px;
  font-weight: 600; font-size: .95rem; letter-spacing: .01em; line-height: 1;
  border: 1px solid transparent; border-radius: 0;
  transition: background-color .28s var(--ease), color .28s var(--ease), border-color .28s var(--ease), transform .28s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn-book { background: var(--amber); color: var(--on-book); border-color: var(--book-edge); }
.btn-book:hover { background: var(--amber-2); border-color: var(--amber-2); }
.link {
  display: inline-block; font-weight: 600; font-size: .95rem; color: var(--ivory);
  border-bottom: 1px solid var(--blush-2); padding-bottom: 2px;
  transition: border-color .28s var(--ease), color .28s var(--ease);
}
.link:hover { border-color: var(--blush); color: var(--blush); }

/* ---------- nav ---------- */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  height: var(--nav-h);
  background: linear-gradient(to bottom, rgba(26, 25, 21, .72), rgba(26, 25, 21, 0));
  transition: background-color .35s var(--ease);
}
.nav.solid { background: var(--lacquer); border-bottom: 1px solid var(--rule-2); }
.nav .wrap { height: 100%; display: flex; align-items: center; gap: clamp(18px, 3vw, 40px); }
.brand { display: inline-flex; align-items: center; gap: 12px; margin-right: auto; }
/* the brand guide's primary KNEAD wordmark, inline (currentColor follows the look's ink); the box is fixed, so no shift */
.brand .wm { display: block; width: 110px; height: 22px; color: var(--ivory); }
.nav-links { display: flex; gap: clamp(16px, 2.2vw, 30px); }
.nav-links a {
  font-size: .92rem; letter-spacing: .02em; color: var(--ivory-2); padding: 6px 0;
  border-bottom: 1px solid transparent; transition: color .25s var(--ease), border-color .25s var(--ease);
}
.nav-links a:hover { color: var(--ivory); }
.nav-links a.on { color: var(--ivory); border-bottom-color: var(--blush); }
.nav .btn-book { min-height: 40px; padding: 0 18px; }
.menu-btn { display: none; width: 44px; height: 44px; margin-right: -10px; position: relative; }
.menu-btn span, .menu-btn::before, .menu-btn::after {
  content: ""; position: absolute; left: 11px; right: 11px; height: 1px; background: var(--ivory);
  transition: transform .3s var(--ease), opacity .3s var(--ease);
}
.menu-btn::before { top: 16px; } .menu-btn span { top: 22px; } .menu-btn::after { top: 28px; }
.menu-btn[aria-expanded="true"]::before { transform: translateY(6px) rotate(45deg); }
.menu-btn[aria-expanded="true"] span { opacity: 0; }
.menu-btn[aria-expanded="true"]::after { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 899px) {
  .nav-links {
    position: fixed; top: var(--nav-h); left: 0; right: 0;
    flex-direction: column; gap: 0; padding: 8px var(--pad) 20px;
    background: var(--lacquer); border-bottom: 1px solid var(--rule-2);
    /* review fix 2026-11-07 #1: with Treatments open the sheet outgrew the screen and could not scroll (every page but /) */
    max-height: calc(100svh - var(--nav-h)); overflow-y: auto; overscroll-behavior: contain;
    transform: translateY(-8px); opacity: 0; visibility: hidden;
    transition: transform .35s var(--ease), opacity .3s var(--ease), visibility 0s .35s;
  }
  .nav.open .nav-links { transform: none; opacity: 1; visibility: visible; transition-delay: 0s; }
  .nav.open { background: var(--lacquer); }
  .nav-links a { font-size: 1.15rem; padding: 14px 0; border-bottom: 1px solid var(--rule-2) !important; }
  .nav-links a.on { color: var(--blush); }
  .menu-btn { display: block; }
  .nav .btn-book { display: none; }
}

/* ---------- the thread ----------
   One blush hairline runs down the left of every section below the hero;
   each heading sits on it with a dot. Sections keep the same ground so it
   reads as one continuous line. */
.sec { position: relative; padding-block: clamp(64px, 7vw, 104px); }
/* a section holding one row or one paragraph, and the closing Book list, would float in the full rhythm */
.sec.short { padding-block: clamp(40px, 4.4vw, 64px); }
.sec.bookat { padding-top: clamp(36px, 3.6vw, 52px); }
.sec .wrap { position: relative; padding-left: calc(var(--pad) + var(--inset)); }
.sec .wrap::before {
  content: ""; position: absolute; top: -200px; bottom: -200px; left: var(--pad);
  width: 1px; background: var(--rule);
}
.sec:last-of-type .wrap::before { bottom: 0; }
.sec h2 { position: relative; margin-bottom: clamp(28px, 4vw, 52px); }
.sec h2::before {
  content: ""; position: absolute; left: calc(-1 * var(--inset) - 5px); top: .42em;
  width: 11px; height: 11px; border-radius: 50%;
  border: 1px solid var(--blush); background: var(--lacquer);
  box-shadow: inset 0 0 0 3px var(--lacquer), inset 0 0 0 6px var(--blush);
}
.sec-head { display: grid; grid-template-columns: 1fr auto; align-items: end; gap: 24px; margin-bottom: clamp(28px, 4vw, 52px); }
.sec-head h2 { margin-bottom: 0; }
.sec-head .link { margin-bottom: .55em; }
@media (max-width: 699px) {
  .sec-head { grid-template-columns: 1fr; }
  .sec-head .link { margin-bottom: 0; justify-self: start; }
}

/* ---------- rules and rows ---------- */
.rows { border-top: 1px solid var(--rule); }
.row { display: grid; gap: 18px 32px; padding: 22px 0; border-bottom: 1px solid var(--rule); align-items: baseline; }

/* ---------- sticky mobile bar ---------- */
.stick {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: none; grid-template-columns: 1fr 1fr; gap: 1px;
  background: var(--rule); border-top: 1px solid var(--rule);
  padding-bottom: env(safe-area-inset-bottom);
}
.stick a, .stick button {
  display: flex; align-items: center; justify-content: center; min-height: 56px;
  font-weight: 600; font-size: 1rem; background: var(--lacquer);
}
.stick .book { background: var(--amber); color: var(--on-book); }
.call-sheet {
  position: fixed; left: 0; right: 0; bottom: calc(56px + env(safe-area-inset-bottom)); z-index: 39;
  background: var(--lacquer-2); border-top: 1px solid var(--rule);
  transform: translateY(12px); opacity: 0; visibility: hidden;
  transition: transform .35s var(--ease), opacity .3s var(--ease), visibility 0s .35s;
}
.call-sheet.open { transform: none; opacity: 1; visibility: visible; transition-delay: 0s; }
.call-sheet a { display: flex; justify-content: space-between; align-items: baseline; padding: 16px var(--pad); border-bottom: 1px solid var(--rule-2); }
.call-sheet a:last-child { border-bottom: 0; }
.call-sheet b { font-family: var(--display); font-weight: 400; font-size: 1.15rem; }
.call-sheet span { color: var(--ivory-2); font-size: .95rem; }
@media (max-width: 899px) {
  .stick { display: grid; transition: transform .3s var(--ease), visibility 0s; }
  body { padding-bottom: calc(56px + env(safe-area-inset-bottom)); }
  /* a page whose first section has its own Book (data-hero-book): the bar shows only while that Book is off
     screen, so Book is on screen exactly once (script.js adds .is-in). Hidden from first paint = not focusable,
     not announced; the body keeps its padding, so nothing moves. Without JS (.no-js stays on <html>) it shows
     from the start. If script.js never takes over (.stick-on is set right before it starts watching), the
     failsafe brings the bar back after 4 s. */
  html:not(.no-js) body:has([data-hero-book]) .stick:not(.is-in) { transform: translateY(100%); visibility: hidden; transition: transform .3s var(--ease), visibility 0s .3s; }
  html:not(.no-js):not(.stick-on) body:has([data-hero-book]) .stick:not(.is-in) { animation: stick-failsafe 0s 4s forwards; }
  /* any page: while one of its in-page Books (homepage stations, Buccal, the closing "Book at your studio" rows)
     is on screen, script.js steps the bar away the same way (.is-out), so Book never shows twice */
  .stick.is-out { transform: translateY(100%); visibility: hidden; transition: transform .3s var(--ease), visibility 0s .3s; }
}
@keyframes stick-failsafe { to { transform: none; visibility: visible; } }
@media (max-width: 899px) and (prefers-reduced-motion: reduce) {
  .stick, html:not(.no-js) body:has([data-hero-book]) .stick:not(.is-in), .stick.is-out { transition: none; }
}

/* ---------- footer ---------- */
.foot { border-top: 1px solid var(--rule); padding: clamp(48px, 6vw, 80px) 0 calc(36px + 0px); background: var(--lacquer-deep); }
.foot .wrap { display: grid; grid-template-columns: 1.2fr repeat(3, 1fr); gap: 40px 32px; }
.foot h3 { font-size: 1.2rem; margin-bottom: 10px; }
.foot p, .foot li { font-size: .95rem; color: var(--ivory-2); line-height: 1.6; }
.foot a:hover { color: var(--ivory); }
.foot .brand { margin: 0 0 14px; }
.foot .foot-links { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 18px; }
.foot .foot-links a { color: var(--ivory-2); font-size: .9rem; }
.foot .legal { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 10px 24px; justify-content: space-between; margin-top: 24px; padding-top: 24px; border-top: 1px solid var(--rule-2); }
.foot .legal, .foot .legal a { font-size: .82rem; color: var(--ivory-3); }
.foot .legal mark.confirm { font-size: .82rem; vertical-align: baseline; line-height: inherit; margin-left: 8px; }
@media (max-width: 899px) { .foot .wrap { grid-template-columns: 1fr 1fr; } .foot .brand-col { grid-column: 1 / -1; } }
@media (max-width: 520px) { .foot .wrap { grid-template-columns: 1fr; } }
@media (max-width: 899px) {
  /* batch 2 H (owner round 3, 2026-11-09, fresh review #15): tap targets of 44px or more on phones. The footer's legal
     links stack two to a row (font-size 0 hides the middot separators between them); small inline links grow their
     hit area without moving the text: vertical padding, cancelled by an equal negative margin where it is a box. */
  .foot .legal > span:last-child { display: flex; flex-wrap: wrap; width: 100%; font-size: 0; }
  .foot .legal a { display: flex; align-items: center; flex: 0 0 50%; min-height: 44px; font-size: .9rem; }
  .foot .foot-links a { display: inline-flex; align-items: center; min-height: 44px; }
  .treatment-link, .acc .treatment-link, .board-layout .treatment-link { padding-block: 15px; margin-block: -15px; }
  .score .meta a, .words .more a { display: inline-block; padding-block: 15px; margin-block: -15px; }
}
@media (max-width: 899px) {
  /* review fix MED-2 (2026-11-09): the footer's studio names, phone numbers, email and logo were 18-24px tall on phones.
     Same trick as batch 2 H: vertical padding grows the hit area, an equal negative margin keeps the text where it was
     (the logo keeps its 14px gap below: 14 - 13 = 1px) */
  .foot h3 a, .foot p a { display: inline-block; padding-block: 13px; margin-block: -13px; }
  .foot .brand { padding-block: 13px; margin-block: -13px 1px; }
}

/* ---------- reveal (one authored motion: content settles up as it enters) ---------- */
.in { opacity: 0; transform: translateY(14px); transition: opacity .9s var(--ease), transform 1.1s var(--ease); }
.in.on { opacity: 1; transform: none; }
.in:nth-child(2) { transition-delay: .08s; } .in:nth-child(3) { transition-delay: .16s; } .in:nth-child(4) { transition-delay: .24s; }
/* hero life N1: a hero's Book row or price strip never beats its lede; scoped to the hero copy so longer lists (the
   board's rows) keep the 0-.24s ramp and their order (code review 2026-11-06) */
.hero-copy > .in:nth-child(5) { transition-delay: .32s; } .hero-copy > .in:nth-child(6) { transition-delay: .4s; }
/* first screen: the same settle as a CSS animation, visible from first paint (no wait on script.js, LCP) */
main > section:first-of-type .in { opacity: 1; transform: none; transition: none; animation: settle 1.1s var(--ease) both; }
main > section:first-of-type .in:nth-child(2) { animation-delay: .08s; } main > section:first-of-type .in:nth-child(3) { animation-delay: .16s; } main > section:first-of-type .in:nth-child(4) { animation-delay: .24s; }
main > section:first-of-type .hero-copy > .in:nth-child(5) { animation-delay: .32s; } main > section:first-of-type .hero-copy > .in:nth-child(6) { animation-delay: .4s; }
@keyframes settle { from { transform: translateY(14px); } }
@media (prefers-reduced-motion: reduce) {
  .in { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
.no-js .in { opacity: 1; transform: none; }

/* =====================================================================
   HOMEPAGE
   ===================================================================== */

/* ---------- hero ---------- */
.hero { position: relative; min-height: 100svh; display: flex; flex-direction: column; justify-content: flex-end; isolation: isolate; overflow: hidden; }
.hero-media { position: absolute; inset: 0; z-index: -2; background: var(--lacquer-deep); }
.hero-media video, .hero-media img {
  width: 100%; height: 100%; object-fit: cover; object-position: center 40%;
  filter: brightness(.66) contrast(1.06) saturate(.92);   /* the footage is muted into the lacquer world */
}
.hero-media::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(to bottom, rgba(35, 33, 28, .60) 0, rgba(35, 33, 28, .40) 90px, rgba(35, 33, 28, 0) 260px),   /* nav links over footage (AA measured on poster pixels) */
    linear-gradient(to top, rgba(35, 33, 28, .96) 0%, rgba(35, 33, 28, .74) 30%, rgba(35, 33, 28, .16) 62%, rgba(35, 33, 28, .20) 100%),
    linear-gradient(to right, rgba(35, 33, 28, .74) 0%, rgba(35, 33, 28, .48) 38%, rgba(35, 33, 28, 0) 66%);
}
.vpause {
  position: absolute; z-index: 3; right: var(--pad); top: calc(var(--nav-h) + 18px);
  width: 40px; height: 40px; display: grid; place-items: center;
  border: 1px solid var(--rule); color: var(--ivory-2); background: rgba(35, 33, 28, .35);
  transition: border-color .25s var(--ease), color .25s var(--ease);
}
.vpause:hover { border-color: var(--blush); color: var(--ivory); }
.vpause svg { width: 14px; height: 14px; fill: currentColor; }
.vpause .ic-play { display: none; }
.vpause[aria-pressed="true"] .ic-pause { display: none; }
.vpause[aria-pressed="true"] .ic-play { display: block; }

.hero > .wrap { width: 100%; padding-top: calc(var(--nav-h) + 40px); }
.hero-copy { max-width: 46rem; padding-bottom: 20px; }
.hero-copy h1 { margin-bottom: 20px; }
.hero-copy .lede { margin-bottom: 24px; color: var(--ivory); }   /* full ivory over footage (contrast measured on poster pixels) */
/* owner round 2 #5 (Phat 2026-11-08): the slogan's second half opens the homepage lede on its own line, above the
   services line ("a quiet space." is the intro's three drops; the h1 keeps "Tune into what your body kneads.") */
.lede-tag { display: block; }
.hero-ctas { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 28px; margin-bottom: clamp(26px, 3vw, 34px); }

/* four from-prices in a ruled strip */
.strip { display: flex; flex-wrap: wrap; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.strip a { flex: 1 1 140px; padding: 16px 20px 14px 0; border-right: 1px solid var(--rule-2); margin-right: 20px; }
.strip a:last-child { border-right: 0; margin-right: 0; }
.strip b { display: block; font-family: var(--display); font-weight: 400; font-size: clamp(1.5rem, 2.2vw, 1.9rem); line-height: 1; margin-bottom: 6px; }
.strip span { font-size: .88rem; color: var(--ivory-2); }
.strip a:hover span { color: var(--ivory); }
.strip + .prose { margin-top: 20px; }
.hero:not(.sh) .strip span { display: block; margin-bottom: 8px; }
.hero:not(.sh) .strip b { margin-bottom: 0; }
.hero:not(.sh) .strip small { font-family: var(--body); font-size: .8rem; color: var(--ivory-2); }

/* three studio stations threaded on the blush line */
.stations-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 24px; padding: 12px 0 10px var(--inset); }
.stations-head h2 { font-size: 1.5rem; line-height: 1.3; }
.stations-head p { font-size: .88rem; color: var(--ivory-2); }
.stations { position: relative; padding: 46px 0 clamp(24px, 3vw, 36px); }
.stations .line { position: absolute; left: calc(-1 * var(--pad)); right: calc(-1 * var(--pad)); top: 0; height: 60px; width: calc(100% + 2 * var(--pad)); pointer-events: none; }
.stations .line path, .wave path { fill: none; stroke: var(--blush); stroke-width: 1; vector-effect: non-scaling-stroke; }
.stations .line path:nth-child(1), .wave path:nth-child(1) { opacity: .9; } .stations .line path:nth-child(2), .wave path:nth-child(2) { opacity: .7; }
.stations .line path:nth-child(3), .wave path:nth-child(3) { opacity: .5; } .stations .line path:nth-child(4), .wave path:nth-child(4) { opacity: .36; } .stations .line path:nth-child(5), .wave path:nth-child(5) { opacity: .24; }
.stations::after { content: ""; position: absolute; left: 0; top: 30px; bottom: 0; width: 1px; background: var(--rule); }
.stations ol { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px clamp(24px, 4vw, 64px); }
.st { position: relative; padding: 18px 0 0 var(--inset); }
.st::before {
  content: ""; position: absolute; left: -5px; top: -21px; width: 11px; height: 11px; border-radius: 50%;
  border: 1px solid var(--blush); background: var(--lacquer);
  box-shadow: inset 0 0 0 3px var(--lacquer), inset 0 0 0 6px var(--blush);
}
.st h3 { font-size: clamp(1.35rem, 1.9vw, 1.7rem); line-height: 1.3; margin: 0 0 8px; }
.st .studio-link { display: inline-flex; align-items: baseline; gap: 12px; text-decoration: none; border-bottom: 1px solid var(--rule); padding-bottom: 3px; }
.st .studio-link span { font-family: var(--body); font-size: 1rem; color: var(--blush); }
.st .studio-link:hover { color: var(--blush); border-color: var(--blush); }
.st .addr { font-size: .92rem; color: var(--ivory-2); }
/* owner round 2026-11-07 #6: the address is the directions link (like the studio pages' heroes) */
/* review fix #3: a taller hit area (line + 15px, ~35px on phones), cancelled by the margin so nothing moves; the 3px top
   stays inside the gap under the studio-name link, the bottom runs over the hours line (text only; the link sits above it) */
.st .addr a { position: relative; display: inline-block; padding: 3px 0 12px; margin: -3px 0 -12px; text-decoration: underline; text-underline-offset: .22em; text-decoration-thickness: 1px; text-decoration-color: var(--rule); transition: color .25s var(--ease), text-decoration-color .25s var(--ease); }
.st .addr a:hover { color: var(--ivory); text-decoration-color: var(--blush); }
/* owner round #5: the visible "Call" label is phones only (below); wider screens show the number */
.st .call-l { display: none; }
.st .open { font-size: .92rem; color: var(--ivory-2); margin: 2px 0 16px; }
.st .open.late { color: var(--blush); }
.st .acts { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; }
.st .btn-book { min-height: 44px; padding: 0 18px; }
.st .call { font-size: .9rem; color: var(--ivory-2); border-bottom: 1px solid var(--rule); padding-bottom: 1px; }
.st .call:hover { color: var(--ivory); border-color: var(--blush); }

@media (max-width: 899px) {
  .hero { min-height: 0; }
  /* 42 (a golden step) keeps at least half the hero Book above the sticky bar's 56px band, so script.js counts it
     on screen and the bar stays away: Book never twice (hero-brand spec 2.3; 26 would leave only 16px visible) */
  .hero > .wrap { min-height: 100svh; display: flex; flex-direction: column; justify-content: flex-end; padding-bottom: calc(42px + env(safe-area-inset-bottom)); }
  .hero-copy { padding-bottom: 0; }
  .stations-wrap { background: var(--lacquer); }
  .stations-head { padding-top: 26px; }
  .stations ol { grid-template-columns: 1fr; gap: 0; }
  .st { padding: 20px 0 22px var(--inset); border-bottom: 1px solid var(--rule-2); }
  .st:last-child { border-bottom: 0; }
  .st::before { display: none; }
  .st:first-child::before { display: block; top: -23px; }
}
@media (max-width: 699px) {
  .hero-media video, .hero-media img { object-position: center center; }
  /* on phones .hero-media spans the hero AND the studio list under it, so this whole-box scrim is thin behind the copy */
  .hero-media::after { background: linear-gradient(to top, rgba(35, 33, 28, .96) 0%, rgba(35, 33, 28, .86) 38%, rgba(35, 33, 28, .62) 62%, rgba(35, 33, 28, .30) 82%, rgba(35, 33, 28, .22) 100%); }
  /* the copy zone gets its own scrim on the first screen (the 100svh wrap), in px from its bottom: the copy is
     bottom-anchored and ~240px tall on every phone (golden split), so the Hot Stone em holds >= 3 over the brightest
     poster pixels, and the footage above stays open (hero-brand spec 2.2; contrast.mjs) */
  .hero:not(.sh) > .wrap { position: relative; }
  .hero:not(.sh) > .wrap::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: linear-gradient(to top, rgba(35, 33, 28, .9) 0, rgba(35, 33, 28, .86) 280px, rgba(35, 33, 28, 0) 440px); }
  .strip a { flex-basis: 40%; padding-right: 12px; margin-right: 12px; }
  .strip a:nth-child(even) { border-right: 0; margin-right: 0; }
  .strip a:nth-child(n+3) { border-top: 1px solid var(--rule-2); }
}

/* ---------- board (prices) ---------- */
.board .row { grid-template-columns: minmax(180px, 1.1fr) 2fr minmax(0, 2.2fr); }
.board .row h3 { font-size: 1.35rem; }
.board .row p { color: var(--ivory-2); font-size: .95rem; max-width: 32em; }
.board .prices { display: flex; flex-wrap: wrap; gap: 8px 28px; justify-content: flex-end; }
.board .prices span { display: inline-flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.board .prices i { font-style: normal; font-size: .85rem; color: var(--ivory-3); letter-spacing: .02em; }
.board .prices b { font-family: var(--display); font-weight: 400; font-size: 1.35rem; }
.board .row:hover .prices b { color: var(--blush); transition: color .3s var(--ease); }
@media (max-width: 899px) {
  .board .row { grid-template-columns: 1fr 1fr; }
  .board .row p { grid-column: 1 / -1; order: 3; }
}
@media (max-width: 520px) {
  .board .row { grid-template-columns: 1fr; gap: 8px; }
  .board .prices { justify-content: flex-start; }
}
@media (max-width: 520px) {
  /* batch 2 H (owner round 3, 2026-11-09, fresh review #18): studio price boards stack each length over its price,
     like the homepage's, so a third price no longer wraps onto a line alone; a grid keeps a booking row's arrow cue
     beside the last price */
  .board .prices { gap: 10px 24px; }
  .board .prices span { display: inline-grid; grid-template-columns: auto auto; align-items: baseline; gap: 6px 0; }
  .board .prices i { grid-column: 1 / -1; }
}

/* Homepage: photograph and a linked treatment menu, still grouped by rules. */
.board-layout { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.5fr); gap: clamp(32px, 4vw, 56px); align-items: start; }
.board-photo { position: sticky; top: calc(var(--nav-h) + 28px); margin: 0; }
.board-photo img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.board-photo figcaption { padding-top: 12px; color: var(--ivory-2); font-size: .88rem; }
.board-layout .row { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); gap: 12px 20px; padding-block: 24px; }
.board-layout .row:first-child { padding-top: 20px; }
.board-layout .row p { grid-column: 1 / -1; order: 3; max-width: 38em; }
.board-layout .prices { gap: 8px 16px; }
/* length over price; a grid (owner round 3 batch 2, E) so a booking row's arrow cue sits beside its last price */
.board-layout .prices span { display: inline-grid; grid-template-columns: auto auto; align-items: baseline; gap: 6px 0; }
.board-layout .prices i { grid-column: 1 / -1; color: var(--ivory-2); }
.board-layout .treatment-link { display: table; margin-top: 10px; color: var(--ivory); font-size: .88rem; }
.board-layout .treatment-link:hover { color: var(--blush); }
.board-layout .treatment-link span { margin-left: 6px; }
@media (max-width: 899px) {
  .board-layout { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .board-photo { position: static; }
  .board-photo img { aspect-ratio: 16 / 7; }
}
@media (max-width: 520px) {
  .board-photo img { aspect-ratio: 5 / 3; }
  .board-layout .row { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .board-layout .prices { gap: 24px; }
}

/* ---------- buccal spotlight ---------- */
.spot .grid { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: clamp(32px, 5vw, 80px); align-items: center; border-block: 1px solid var(--rule); padding-block: clamp(28px, 4vw, 48px); }
.spot-intro { font-family: var(--display); font-size: clamp(2rem, 3.6vw, 3.25rem); line-height: 1.08; margin-bottom: 22px; text-wrap: balance; }
.spot-booking > .small { margin-bottom: 24px; max-width: 28em; }
.spot h2 { margin-bottom: 20px; }
.spot .lede { margin-bottom: 0; }
.spot .prices { display: flex; gap: 36px; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); padding: 16px 0; margin-bottom: 28px; }
.spot .prices b { display: block; font-family: var(--display); font-weight: 400; font-size: 1.6rem; line-height: 1; margin-bottom: 6px; }
.spot .prices span { font-size: .88rem; color: var(--ivory-2); }
.spot .acts { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 28px; }
@media (max-width: 899px) { .spot .grid { grid-template-columns: 1fr; } }
/* The Combo (Phat 2026-11-07, in the Buccal's place on / and the studio pages): photo left, the four combos as rows.
   The photo fills its column's height and crops with object-fit, so a 4:5 or a 3:2 file both work. .spot.spot-combo
   outranks the looks' ".spot .prices" rules (premium, july), which style the old big price pair. */
.spot-combo .grid { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); align-items: stretch; }
.spot-fig { margin: 0; min-height: 0; overflow: hidden; }
.spot-fig img { display: block; width: 100%; height: 100%; min-height: 420px; object-fit: cover; }
.spot-combo .rows { margin-top: 28px; }
.spot-combo .row { grid-template-columns: minmax(0, 1fr) auto; gap: 8px 24px; padding-block: 18px; }
.spot-combo .row h3 { font-size: 1.3rem; }
.spot-combo .row p { grid-column: 1 / -1; order: 3; color: var(--ivory-2); font-size: .95rem; max-width: 34em; }
.spot.spot-combo .row .prices { display: flex; gap: 0; border: 0; padding: 0; margin: 0; }
.spot.spot-combo .row .prices b { display: inline; color: var(--ivory); font-size: 1.5rem; margin: 0; }
.spot-combo .acts { margin-top: 24px; }
@media (max-width: 899px) {
  .spot-combo .grid { grid-template-columns: 1fr; }
  .spot-fig img { height: auto; min-height: 0; aspect-ratio: 3 / 2; }
}
/* The membership spotlight (Phat 2026-11-11, homepage only): the owner's photo left, the three plans and their terms
   right, the way The Combo pairs its photo; the flex credits stay full width below the pair. */
.spot-member .grid { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); align-items: stretch; }
.spot-member .grid + .flex { margin-top: clamp(32px, 4vw, 48px); }
@media (max-width: 899px) {
  .spot-member .grid { grid-template-columns: 1fr; }
}

/* ---------- membership ---------- */
.member .row { grid-template-columns: minmax(0, 1.3fr) minmax(0, 2fr) auto; }
.member .row h3 { font-size: 1.3rem; }
.member .row p { color: var(--ivory-2); font-size: .95rem; }
.member .row .incl { display: block; margin-top: 6px; color: var(--ivory-3); font-size: .85rem; }
.member .price { font-family: var(--display); font-size: 1.6rem; line-height: 1; white-space: nowrap; }
.member .price small { font-family: var(--body); font-size: .8rem; color: var(--ivory-3); margin-left: 4px; }
/* the saving a visit against the menu price (owner round 3 batch 2, D) */
.member .row .save { grid-column: 2 / -1; margin-top: -6px; color: var(--ivory-2); font-size: .88rem; }
.member .terms { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px 32px; margin-top: 36px; }
.member .terms li { font-size: .92rem; color: var(--ivory-2); padding-left: 18px; position: relative; }
.member .terms li::before { content: ""; position: absolute; left: 0; top: .72em; width: 8px; height: 1px; background: var(--blush); }
.member .flex { margin-top: clamp(40px, 5vw, 64px); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 24px 48px; align-items: start; }
.member .flex.solo { margin-top: 0; }
.member .flex h3 { font-size: 1.5rem; }
.member .flex p { color: var(--ivory-2); }
.member .flex .credits { display: flex; flex-wrap: wrap; gap: 20px 36px; margin: 18px 0 20px; }
.member .flex .credits b { display: block; font-family: var(--display); font-weight: 400; font-size: 1.4rem; line-height: 1; margin-bottom: 4px; }
.member .flex .credits span { font-size: .85rem; color: var(--ivory-3); }
@media (max-width: 699px) {
  .member .row { grid-template-columns: 1fr auto; }
  .member .row p, .member .row .save { grid-column: 1 / -1; }
  .member .row .save { margin-top: 0; }
  .member .flex { grid-template-columns: 1fr; }
}

/* ---------- words (testimonials) ---------- */
.words ol { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(28px, 4vw, 56px); }
.words blockquote { margin: 0; padding-top: 20px; border-top: 1px solid var(--rule); }
.words blockquote p { font-family: var(--display); font-size: clamp(1.15rem, 1.5vw, 1.4rem); line-height: 1.35; margin-bottom: 18px; }
.words blockquote p::before { content: "\201C"; color: var(--blush); }
.words blockquote p::after { content: "\201D"; color: var(--blush); }
.words cite { font-style: normal; font-size: .9rem; color: var(--ivory-2); }
.words cite span { color: var(--ivory-3); }
@media (max-width: 899px) { .words ol { grid-template-columns: 1fr; gap: 0; } .words blockquote { padding: 24px 0; } .words li:last-child blockquote { border-bottom: 1px solid var(--rule); } }
.words .more { margin-top: 28px; font-size: .9rem; color: var(--ivory-2); }
.words .more a { color: var(--ivory); border-bottom: 1px solid var(--blush-2); }

/* ---------- careers form (Netlify Forms; the only form on the site) ---------- */
.apply form { display: grid; gap: 20px; max-width: 42em; margin-top: 8px; }
.apply .two { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.apply label { display: grid; gap: 8px; font-size: .9rem; color: var(--ivory-2); }
.apply label small { font-size: inherit; color: var(--ivory-3); }
.apply input, .apply select, .apply textarea {
  width: 100%; min-height: 46px; padding: 10px 12px;
  font: inherit; font-size: 1rem; color: var(--ivory);
  background: var(--lacquer-2); border: 1px solid var(--rule); border-radius: 0; color-scheme: dark;
  transition: border-color .28s var(--ease);
}
.apply textarea { min-height: 140px; resize: vertical; }
.apply input:focus-visible, .apply select:focus-visible, .apply textarea:focus-visible { outline: 2px solid var(--blush); outline-offset: 2px; border-color: var(--blush); }
.apply .hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.apply .fine { font-size: .9rem; color: var(--ivory-2); max-width: 42em; }
.btn-send { background: var(--ivory); color: var(--lacquer); border-color: var(--ivory); cursor: pointer; }
.btn-send:hover { background: #fff; border-color: #fff; }
.apply .btn-send { justify-self: start; }
@media (max-width: 599px) { .apply .two { grid-template-columns: 1fr; } }

/* ---------- FAQ ---------- */
.faq .list { max-width: 52rem; }
.faq details { border-bottom: 1px solid var(--rule); }
.faq details:first-child { border-top: 1px solid var(--rule); }
.faq summary {
  list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: baseline; gap: 24px;
  padding: 20px 0; font-family: var(--display); font-size: clamp(1.15rem, 1.6vw, 1.45rem); line-height: 1.3;
}
.faq summary::-webkit-details-marker { display: none; }
/* the toggle is drawn, not typed: two 1px blush strokes that turn into a cross when open */
.faq summary::after {
  content: ""; flex: 0 0 auto; width: 14px; height: 14px; align-self: center;
  background: linear-gradient(var(--blush), var(--blush)) center / 100% 1px no-repeat,
              linear-gradient(var(--blush), var(--blush)) center / 1px 100% no-repeat;
  transition: transform .3s var(--ease);
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details > div { padding: 0 0 22px; color: var(--ivory-2); max-width: 44em; }
.faq details > div p + p { margin-top: 10px; }
.faq summary:hover { color: var(--blush); }
.faq .tbc { display: block; margin-top: 4px; }

/* =====================================================================
   INNER PAGES (generated by site-docs/pages-build; chrome comes from index.html)
   ===================================================================== */

/* placeholder copy awaiting the owner: visible on purpose, removed before launch */
.tbc { color: var(--flag) !important; font-size: .9rem; letter-spacing: .01em; font-family: var(--body); font-weight: 400; }
/* third-party figure carried over from an original post: stays after launch, muted, never amber */
.fignote { font-size: .85rem; opacity: .72; font-family: var(--body); font-weight: 400; }

/* page head: the thread starts at the H1's dot */
.ph { padding-top: calc(var(--nav-h) + clamp(56px, 8vw, 120px)); padding-bottom: 0; }
p.tbc:not(:first-child) { margin-top: 16px; }
.ph .wrap::before { top: calc(clamp(2.6rem, 5.2vw, 4.6rem) * .44 + 5px); }
.ph h1 { position: relative; font-size: clamp(2.6rem, 5.2vw, 4.6rem); line-height: 1; max-width: 13em; }
.ph h1::before {
  content: ""; position: absolute; left: calc(-1 * var(--inset) - 5px); top: .44em;
  width: 11px; height: 11px; border-radius: 50%;
  border: 1px solid var(--blush); background: var(--lacquer);
  box-shadow: inset 0 0 0 3px var(--lacquer), inset 0 0 0 6px var(--blush);
}
.ph .lede { margin-top: 22px; }
.ph .lede + .lede { margin-top: 10px; }
.ph .acts { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 28px; margin-top: 30px; }
.ph .strip { margin-top: clamp(32px, 4vw, 48px); }
.ph .tbc { margin-top: 14px; }
/* page head with a still: copy left, photograph in the right column; under the copy on phones */
.ph.has-fig .wrap { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: clamp(40px, 5vw, 88px); align-items: center; }
.ph-fig { margin: 0; position: relative; justify-self: end; width: 100%; max-width: 440px; aspect-ratio: 4 / 5; overflow: hidden; background: var(--lacquer-2); }
.ph-fig img { width: 100%; height: 100%; object-fit: cover; }
.ph-fig::after { content: ""; position: absolute; inset: 0; box-shadow: inset 0 0 0 1px var(--rule-2); }
@media (max-width: 899px) {
  .ph.has-fig .wrap { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .ph-fig { justify-self: stretch; max-width: none; aspect-ratio: 5 / 4; margin-top: clamp(32px, 6vw, 48px); }
}
.call {
  font-size: .95rem; color: var(--ivory-2); border-bottom: 1px solid var(--rule); padding-bottom: 1px;
  transition: color .25s var(--ease), border-color .25s var(--ease);
}
.call:hover { color: var(--ivory); border-color: var(--blush); }

/* prices for one line */
.pricebar { display: flex; flex-wrap: wrap; gap: 16px 40px; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); padding: 16px 0; margin-top: 30px; max-width: 40rem; }
.pricebar b { display: block; font-family: var(--display); font-weight: 400; font-size: 1.6rem; line-height: 1; margin-bottom: 6px; }
.pricebar span { font-size: .88rem; color: var(--ivory-2); }

/* label / answer rows */
.facts .row { grid-template-columns: minmax(150px, .8fr) minmax(0, 3fr); }
.facts dt { font-family: var(--display); font-size: 1.25rem; line-height: 1.3; }
.facts dd { margin: 0; color: var(--ivory-2); max-width: 42em; }
.facts dd p + p { margin-top: 8px; }
.facts dd b { color: var(--ivory); font-weight: 600; }
.facts dd .open:empty { display: none; }
.facts dd .open.late { color: var(--blush); }
@media (max-width: 699px) { .facts .row { grid-template-columns: 1fr; gap: 6px; } }

/* book at your studio: the stations again, as ruled rows */
.bookat .row { grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) auto; align-items: center; }
.bookat h3 { font-size: 1.5rem; }
.bookat h3 a { transition: color .25s var(--ease); }
.bookat h3 a:hover { color: var(--blush); }
.bookat .where { font-size: .95rem; color: var(--ivory-2); }
.bookat .where .open.late { color: var(--blush); }
.bookat .acts { display: flex; align-items: center; gap: 18px; justify-content: flex-end; }
.bookat .btn-book { min-height: 44px; padding: 0 18px; }
/* owner round 3 (2026-11-09): two Fresha services per studio (RMT foot / abdominal focus), and the couples intro */
.bookat .acts-choices { flex-wrap: wrap; gap: 10px 14px; }
.bookat .prose { margin: 0 0 28px; }
@media (max-width: 699px) {
  .bookat .row { grid-template-columns: 1fr; gap: 8px; }
  .bookat .acts { justify-content: flex-start; margin-top: 6px; }
}

/* short running copy */
.prose { max-width: 40em; }
.prose p { color: var(--ivory-2); }
.prose p + p { margin-top: 14px; }
.prose .first { color: var(--ivory); font-size: clamp(1.05rem, 1.3vw, 1.2rem); }

/* board rows that link to their own page */
.board .row h3 a { transition: color .25s var(--ease); }
.board .row h3 a:hover { color: var(--blush); }
.board .prices .tbc { white-space: normal; }

/* contact */
.nap .row { grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1fr) auto; align-items: center; }
.nap h3 { font-size: 1.5rem; }
.nap p { font-size: .95rem; color: var(--ivory-2); }
.nap .acts { display: flex; align-items: center; gap: 18px; }
.nap .btn-book { min-height: 44px; padding: 0 18px; }
@media (max-width: 899px) { .nap .row { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .nap .row { grid-template-columns: 1fr; gap: 6px; } .nap .acts { margin-top: 8px; } }

/* =====================================================================
   STUDIO HOMEPAGES (/mount-pleasant, /kitsilano, /marpole; pages/studios.mjs)
   The homepage hero with this studio's photograph instead of the clip. These rules are the
   "Lines of Pressure" look; html[data-look] pages add look-*.css on top.
   ===================================================================== */
.sh { min-height: min(100svh, 900px); }
.sh .hero-media img { object-position: center 45%; }
/* nothing sits over the hero's foot here (on / the stations do), so the photograph fades fully into the ground */
.sh .hero-media::before { content: ""; position: absolute; inset: auto 0 0 0; height: 30%; z-index: 1; background: linear-gradient(to top, var(--lacquer), rgba(35, 33, 28, 0)); }
/* .st .btn: the homepage station Book buttons sit in an <li>, so "li a" underlined them (#O6, owner round 3, 2026-11-09) */
.sh .btn, .bookat .btn, .st .btn { text-decoration: none; }
.sh > .wrap { padding-bottom: clamp(48px, 7vw, 96px); }
/* fit-content: the box is the words (no visual change), so contrast is judged where the letters are (iPhone fixes) */
.sh-kicker { width: fit-content; font-size: .78rem; letter-spacing: .2em; text-transform: uppercase; color: var(--ivory-2); margin-bottom: 18px; }
.sh .hero-copy h1 { margin-bottom: 18px; }
.sh-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 0; margin-bottom: 18px; font-size: .95rem; color: var(--ivory); }
.sh-meta > * + *::before { content: "\00B7"; margin: 0 .6em; color: var(--blush); }
.sh-meta .open.late { color: var(--blush); }
.sh .hero-ctas .call { color: var(--ivory); font-size: .95rem; }
.rating { color: var(--ivory); text-decoration: underline; text-underline-offset: .22em; text-decoration-thickness: 1px; text-decoration-color: var(--blush-2); }
.rating:hover { text-decoration-color: var(--blush); }
.rating b { font-weight: 600; }
@media (max-width: 899px) {
  .sh { min-height: 0; }
  .sh > .wrap { padding-bottom: calc(40px + env(safe-area-inset-bottom)); }
}
@media (max-width: 699px) {
  .sh-kicker { margin-bottom: 12px; }
  .sh .lede { font-size: 1rem; }
  /* the rating takes its own line rather than wrapping with a stray separator */
  .sh-meta .rating { flex-basis: 100%; }
  .sh-meta .rating::before { display: none; }
}
/* the thread starts below the hero (on / the stations cover its top; here nothing does) */
.sh + .sec .wrap::before { top: 0; }

/* ---------- studio golden split: Marpole + Kitsilano (iPhone fixes 2026-11-06, spec 3 + 4 + 12.1 #1/#2/#12) ----------
   Phat: "the text kills the hero image". On phones and tablets the copy sits bottom-anchored in the first screen and
   the photograph gets the rest; each look adds its own short fade behind the copy. On phones the address is the
   Directions link (44px hit area) and the kicker, the long lede and the Directions CTA step out (they stay in the
   DOM, on tablets and on desktop). 42 = the homepage reserve: half the hero Book stays above the sticky band. */
.sh-dir { display: none; }
.sh-meta > .sh-dir + .sh-street::before { content: none; }
/* owner round 2026-11-07 #6: the video hero (Mount Pleasant) has no golden swap, so its address IS the directions link
   at every width ("mount pleasant address doesn't have a clickable link but the rest of the locations do") */
.sh:not([data-hero="golden"]) .sh-dir { display: inline; color: var(--ivory); text-decoration: underline; text-underline-offset: .22em; text-decoration-thickness: 1px; text-decoration-color: var(--blush-2); }
.sh:not([data-hero="golden"]) .sh-dir:hover { text-decoration-color: var(--blush); }
@media (max-width: 699px) { .sh:not([data-hero="golden"]) .sh-dir { display: inline-block; padding: 12px 0; margin: -12px 0; } }
@media (max-width: 699px), (max-width: 999px) and (max-height: 520px) {
  .sh[data-hero="golden"] { min-height: 0; }
  .sh[data-hero="golden"] > .wrap { min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; justify-content: flex-end; padding-top: calc(var(--nav-h) + 10px); padding-bottom: calc(42px + env(safe-area-inset-bottom)); }
  .sh[data-hero="golden"] .sh-kicker, .sh[data-hero="golden"] .lede, .sh[data-hero="golden"] .hero-ctas [data-ev="directions_click"] { display: none; }
  .sh[data-hero="golden"] .sh-street { display: none; }
  .sh[data-hero="golden"] .sh-dir { display: inline-block; padding: 12px 0; margin: -12px 0; color: var(--ivory); text-decoration: underline; text-underline-offset: .22em; text-decoration-thickness: 1px; text-decoration-color: var(--blush-2); }
  .sh[data-hero="golden"] .hero-copy h1 { margin-bottom: 16px; }
  .sh[data-hero="golden"] .sh-meta { margin-bottom: 26px; }
  .sh[data-hero="golden"] .hero-ctas { flex-wrap: wrap; margin-bottom: 0; }
  .sh[data-hero="golden"] .hero-media::before { display: none; }
}
/* tablets: the same bottom-anchored first screen, with the kicker, lede and Directions kept (review 12.1 #2) */
@media (min-width: 700px) and (max-width: 899px) {
  .sh[data-hero="golden"] { min-height: 0; }
  .sh[data-hero="golden"] > .wrap { min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; justify-content: flex-end; }
  .sh[data-hero="golden"] .hero-media::before { display: none; }
}

/* ---------- menu rows that book (iPhone fixes 2026-11-06, spec 7 + 12.1 #5/#10/#11; Phat: "the menu items should
   link to fresha") ----------
   Studio pages: the row name is a new-tab link to that studio's Fresha service, stretched over the whole row.
   /services: an absolute trigger layer opens the pick-a-studio sheet; the name link sits above it. A small arrow
   after the prices says the row books. Neither is a Book button (the sticky bar counts .btn-book only). */
.vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.row-book { position: relative; }
.row-go-on { position: relative; }
.row-book .row-link { text-decoration: none; }
.row-book .row-link::after { content: ""; position: absolute; inset: 0; }
.row-go { position: absolute; inset: 0; z-index: 0; }
.row-go-on h3 a { position: relative; z-index: 1; }
/* the homepage board rows book too since owner round 3 batch 2 (E): their Explore link stays its own target */
.row-go-on .treatment-link { position: relative; z-index: 1; }
/* on the last price, not after the prices: a flex item of its own wrapped onto a line alone on phones */
.row-book .prices > :last-child::after, .row-go-on .prices > :last-child::after { content: "\2197"; content: "\2197" / ""; margin-left: 4px; font-family: var(--body); font-style: normal; font-size: .8rem; line-height: 1; color: var(--blush); }
@media (hover: hover) {
  .row-book:hover .row-link { text-decoration: underline; text-decoration-color: var(--blush); text-decoration-thickness: 1px; text-underline-offset: .2em; }
}
.row-book .row-link:focus-visible { outline: none; }
.row-book:has(.row-link:focus-visible) { outline: 2px solid var(--blush); outline-offset: 4px; }
.row-go:focus-visible { outline: 2px solid var(--blush); outline-offset: 4px; }
@supports not selector(:has(*)) {
  .row-book .row-link:focus-visible, .row-go:focus-visible { outline: 2px solid var(--blush); outline-offset: 2px; }
}

.board-note { margin-top: 22px; font-size: .95rem; }

/* the studio's rating above the quotes */
.score { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 24px; margin-bottom: clamp(28px, 4vw, 44px); }
.score-num { font-family: var(--display); font-size: clamp(1.6rem, 2.6vw, 2.2rem); line-height: 1; color: var(--ivory); border-bottom: 1px solid var(--blush-2); padding-bottom: 4px; }
.score-num b { font-weight: 400; color: var(--blush); }
.score-num span { font-family: var(--body); font-size: .95rem; color: var(--ivory-2); }
.score-num:hover { border-color: var(--blush); }
.member > .wrap > .tbc { margin-top: 18px; }
.member .flex .tbc { display: block; margin-top: 8px; }

/* remembered studio (script.js): label next to the nav Book, and above the sticky bar on phones */
.remembered { font-size: .82rem; color: var(--ivory-2); white-space: nowrap; }
.remembered b { color: var(--ivory); font-weight: 600; }
.remembered a { color: var(--ivory-2); text-decoration: underline; text-underline-offset: .2em; text-decoration-color: var(--blush-2); }
.remembered a:hover { color: var(--ivory); }
.nav .remembered { margin-right: -16px; }
.stick .remembered { grid-column: 1 / -1; padding: 8px var(--pad); background: var(--lacquer-2); text-align: center; }
.stick .remembered a { display: inline; min-height: 0; background: none; font-weight: 400; font-size: inherit; }
@media (max-width: 1099px) { .nav .remembered { display: none; } }
.st.mine .open::after { content: " \00B7  Your studio"; color: var(--blush); }

/* =====================================================================
   BLOG (generated by site-docs/blog-build)
   ===================================================================== */

/* post head: long titles, so a smaller H1 on the same thread */
.post-head h1 { font-size: clamp(2rem, 3.6vw, 3.2rem); line-height: 1.08; max-width: 20em; }
.post-head .wrap::before { top: calc(clamp(2rem, 3.6vw, 3.2rem) * .44 + 5px); }
.post-head .meta { margin-top: 18px; }
.post { padding-top: clamp(40px, 5vw, 64px); padding-bottom: 0; }

.post-hero { margin: 0 0 clamp(32px, 4vw, 48px); max-width: 40em; }
.post-hero img, .post-prose figure img { width: 100%; }

/* long-form reading: the prose column, subheads sit on the thread */
.post-prose { max-width: 40em; font-size: 1.06rem; line-height: 1.7; }
.post-prose > * + * { margin-top: 1.1em; }
.post-prose p, .post-prose li, .post-prose td { color: var(--ivory-2); }
.post-prose strong { color: var(--ivory); font-weight: 600; }
.post-prose h2 { font-size: clamp(1.55rem, 2.4vw, 2.05rem); line-height: 1.15; margin: 2.1em 0 0; }
.post-prose h3 { font-size: clamp(1.25rem, 1.7vw, 1.45rem); margin: 1.8em 0 0; }
.post-prose h4 { font-family: var(--body); font-size: 1rem; font-weight: 600; letter-spacing: .01em; margin: 1.6em 0 0; }
.post-prose h2 strong, .post-prose h3 strong, .post-prose h4 strong { font-weight: inherit; color: inherit; }
.post-prose h2 + *, .post-prose h3 + *, .post-prose h4 + * { margin-top: .6em; }
.post-prose ul, .post-prose ol { padding-left: 1.3em; }
.post-prose ul { list-style: none; }
.post-prose ul > li { position: relative; }
.post-prose ul > li::before { content: ""; position: absolute; left: -1.05em; top: .78em; width: 6px; height: 1px; background: var(--blush); }
.post-prose ol { list-style: decimal; }
.post-prose ol > li::marker { color: var(--blush); font-variant-numeric: tabular-nums; }
.post-prose li + li { margin-top: .45em; }
.post-prose li > p + p { margin-top: .5em; }
.post-prose blockquote { margin: 1.4em 0; padding-left: 1.1em; border-left: 1px solid var(--blush); color: var(--ivory); }
.post-prose figure { margin: 1.6em 0; }
.post-prose hr { border: 0; border-top: 1px solid var(--rule); margin: 2em 0; }
.post-prose .tbc { display: inline; }
.tablewrap { overflow-x: auto; border-top: 1px solid var(--rule); }
.post-prose table { border-collapse: collapse; width: 100%; min-width: 34rem; font-size: .92rem; line-height: 1.45; }
.post-prose th { text-align: left; font-weight: 600; color: var(--ivory); padding: 12px 14px 12px 0; border-bottom: 1px solid var(--rule); }
.post-prose td { padding: 12px 14px 12px 0; border-bottom: 1px solid var(--rule-2); vertical-align: top; }
.post-back { margin-top: clamp(40px, 5vw, 64px); }

/* blog index: the three newest posts with their pictures, then every post as a ruled
   date + title row, grouped by topic on the thread */
.latest { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(24px, 3vw, 44px); }
.latest a { display: block; text-decoration: none; }
.latest img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; background: var(--lacquer-2); margin-bottom: 16px; }
.latest time { display: block; font-size: .85rem; color: var(--ivory-3); margin-bottom: 6px; }
.latest h3 { font-size: clamp(1.2rem, 1.6vw, 1.4rem); line-height: 1.25; transition: color .25s var(--ease); }
.latest a:hover h3 { color: var(--blush); }
@media (max-width: 899px) { .latest { grid-template-columns: minmax(0, 1fr); gap: 36px; } }

.bloglist .row { grid-template-columns: 7.5rem minmax(0, 1fr); align-items: baseline; padding-block: 14px; }
.bloglist time { font-size: .88rem; color: var(--ivory-3); }
.bloglist h3 { font-size: clamp(1.1rem, 1.4vw, 1.25rem); max-width: 40em; }
.bloglist h3 a { transition: color .25s var(--ease); }
.bloglist h3 a:hover { color: var(--blush); }
@media (max-width: 699px) { .bloglist .row { grid-template-columns: 1fr; gap: 2px; } }

/* =====================================================================
   HOMEPAGE HERO ON PHONES: the golden split (hero-brand spec 2 + § review amendments)
   The copy sits in the bottom ~third, the footage gets the rest. h1 44px = 17 x phi^2; gaps on phi steps 10/16/26/42.
   ===================================================================== */
/* phones, portrait or landscape: no price strip and no second link (the board is one scroll down) */
@media (max-width: 699px), (max-width: 999px) and (max-height: 520px) {
  .hero:not(.sh) .hero-copy .strip { display: none; }
  .hero:not(.sh) .hero-ctas .link { display: none; }
  .hero:not(.sh) .hero-ctas { margin-bottom: 0; }
  .hero:not(.sh) .hero-copy h1 { margin-bottom: 16px; }
  /* the SEO lede (hero-copy 2026-11-06) runs 2 lines on phones >= 360px wide and 3 at 320; never nowrap (code review
     2026-11-05 #2: nowrap clipped it inside the hero's overflow), balanced so no line ends on a lone word (#C2) */
  .hero:not(.sh) .hero-copy .lede { font-size: 1.0625rem; margin-bottom: 26px; text-wrap: balance; }
}
/* short phone screens (Safari with its bars showing, the SE): one golden step tighter; the 42px reserve stays */
@media (max-width: 699px) and (max-height: 700px) {
  .hero:not(.sh) .hero-copy h1 { margin-bottom: 10px; }
  .hero:not(.sh) .hero-copy .lede { margin-bottom: 16px; }
}
/* landscape phones (~340-430 tall): the same tighter step, and the top pad drops to nav + 10 so the first screen
   holds the copy with the Book above the sticky bar's band (otherwise the wrap ran 354px in 340 and the bar
   showed over the Book; probe-hero-golden 844x340) */
@media (max-width: 999px) and (max-height: 520px) {
  .hero:not(.sh) > .wrap { padding-top: calc(var(--nav-h) + 10px); }
  .hero:not(.sh) .hero-copy h1 { margin-bottom: 10px; }
  .hero:not(.sh) .hero-copy .lede { margin-bottom: 16px; }
}

/* ---------- homepage hero kicker + facts line (hero-life 2026-11-06, spec 3 + 9.1 R1) ----------
   The studio heroes' .sh-kicker / .sh-meta, on the homepage (and Option B, built from it). Phat 2026-11-06 (#L1
   banner, supersedes hero-life 9.1 R1): phones show the kicker and two facts ("Three studios · Open seven days";
   desktop keeps "From $47") on every portrait phone 600px+ tall; on 320x568-class and landscape phones the hero is
   h1 + lede + Book as before (the kicker would wrap and the copy climb to ~40% of the screen). */
.hero:not(.sh) .sh-kicker { margin-bottom: 18px; }
@media (min-width: 700px) and (max-width: 899px) and (min-height: 521px) {
  /* tablets (768x1024): one golden step tighter so the copy stays inside the 42% reach */
  .hero:not(.sh) .sh-kicker { margin-bottom: 10px; }
  .hero:not(.sh) .hero-copy h1 { margin-bottom: 16px; }
  .hero:not(.sh) .sh-meta { margin-bottom: 16px; }
}
@media (max-width: 699px), (max-width: 999px) and (max-height: 520px) {
  .hero:not(.sh) .sh-kicker { font-size: .72rem; margin-bottom: 10px; }
  .hero:not(.sh) .sh-meta { font-size: .9rem; margin-bottom: 10px; }
  .hero:not(.sh) .sh-meta > :nth-child(3) { display: none; }
  /* the rating (owner round 3 batch 2) takes its own line, like the studio heroes', so no stray separator leads it */
  .hero:not(.sh) .sh-meta .sh-rating { flex-basis: 100%; }
  .hero:not(.sh) .sh-meta .sh-rating::before { content: none; }
}
@media (max-width: 699px) and (max-height: 599px), (max-width: 999px) and (max-height: 520px) {
  .hero:not(.sh) .sh-kicker, .hero:not(.sh) .sh-meta { display: none; }
}

/* ---------- pick-a-studio sheet (native modal <dialog>, script.js; hero-brand spec 4 + review S11) ----------
   UA dialog styles reset; the padding lives on .book-sheet-in, so a click on the dialog box itself is the backdrop */
.book-sheet { padding: 0; border: 0; margin: auto; width: min(440px, calc(100% - 2 * var(--pad))); max-width: none; max-height: none; color: var(--ivory); background: transparent; overflow: visible; }
.book-sheet::backdrop { background: rgba(26, 25, 21, .64); }
.book-sheet-in { max-height: 100dvh; overflow-y: auto; background: var(--lacquer-2); border: 1px solid var(--rule); padding: 22px 0 6px; }
.book-sheet-h { font-size: 1.5rem; line-height: 1.2; padding: 0 var(--pad); }
.book-sheet-note { font-size: .88rem; color: var(--ivory-2); padding: 6px var(--pad) 14px; border-bottom: 1px solid var(--rule); }
.book-sheet a { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 2px 16px; min-height: 64px; padding: 12px var(--pad); border-bottom: 1px solid var(--rule-2); text-decoration: none; }
.book-sheet a b { font-family: var(--display); font-weight: 400; font-size: 1.2rem; line-height: 1.25; }
.book-sheet a > span { grid-column: 1; font-size: .9rem; color: var(--ivory-2); }
.book-sheet a i { grid-column: 2; grid-row: 1 / span 2; font-style: normal; font-size: 1.1rem; color: var(--blush); transition: transform .25s var(--ease), color .25s var(--ease); }
/* hover brightens, never dims: a mouse click on the hero Book opens the phone sheet under a still pointer, and a
   dimmed row read as disabled (code review 2026-11-05 #1). Touch never gets it. */
@media (hover: hover) {
  .book-sheet a:hover b { text-decoration: underline; text-decoration-color: var(--blush); text-decoration-thickness: 1px; text-underline-offset: 5px; }
  .book-sheet a:hover i { color: var(--ivory); transform: translate(2px, -2px); }
  .book-sheet-close:hover { color: var(--ivory); }
}
.book-sheet-close { display: block; width: 100%; min-height: 48px; padding: 0 var(--pad); text-align: left; font-weight: 600; font-size: .95rem; color: var(--ivory-2); }
/* no <dialog> support (Safari < 15.4): the closed sheet must not render after the footer */
.book-sheet:not([open]) { display: none; }
/* scroll lock; the gutter keeps the removed scrollbar's width so the page behind doesn't jump sideways on
   classic-scrollbar desktops (review #5). Only while the sheet is open: on html always, a hidden-scrollbar
   browser lost 10px of layout width (probe-p2 overflow -10, 390 page +28px). */
html:has(dialog.book-sheet[open]) { overflow: hidden; scrollbar-gutter: stable; }
@media (max-width: 899px) {
  .book-sheet { margin: auto 0 0; width: 100%; }
  .book-sheet-in { border-width: 1px 0 0; padding-bottom: calc(6px + env(safe-area-inset-bottom)); }
}
.book-sheet[open] { animation: sheet-in .35s var(--ease); }
@keyframes sheet-in { from { opacity: 0; transform: translateY(16px); } }
@media (prefers-reduced-motion: reduce) { .book-sheet[open] { animation: none; } }

/* =====================================================================
   OWNER ROUND 2026-11-07 (Phat, after a call with one of Knead's owners; tests/owner-round.test.mjs)
   ===================================================================== */

/* ---------- #3 the hero clip blends into "Choose your studio" (Phat's iPhone shot: a hard line where the clip ends) ----------
   Every width: the clip's own foot is solid lacquer, so whatever follows it starts on the same colour. Below 900 the
   stations sit on a solid ground after the clip (phones: right where the 100svh clip box ends; landscape phones: over
   it), so a lip fades the clip into that ground from above. The lip sits under the copy (z -1 in the hero's stacking
   context) and only darkens behind it, so no hero text loses contrast. Eased stops: no banding on the dark clip. */
.hero:not(.sh) .hero-media::before {
  content: ""; position: absolute; inset: auto 0 0 0; height: 16%; z-index: 1; pointer-events: none;
  background: linear-gradient(to top, rgba(35, 33, 28, 1) 0%, rgba(35, 33, 28, .4) 65%, rgba(35, 33, 28, 0) 100%);
  background: linear-gradient(to top, var(--lacquer) 0%, color-mix(in srgb, var(--lacquer) 82%, transparent) 30%, color-mix(in srgb, var(--lacquer) 40%, transparent) 65%, color-mix(in srgb, var(--lacquer) 0%, transparent) 100%);
}
@media (max-width: 899px) {
  .hero:not(.sh) .hero-media::before { display: none; }
  .hero:not(.sh) .stations-wrap { position: relative; }
  .hero:not(.sh) .stations-wrap::before {
    content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: clamp(150px, 28svh, 280px); pointer-events: none;
    /* color-mix on var(--lacquer): the fade follows each look's ground (Option B's /lab/home-warm/ is Linen); the rgba
       line first is the lacquer fallback for browsers without color-mix (Safari < 16.2) */
    background: linear-gradient(to top, rgba(35, 33, 28, 1) 0%, rgba(35, 33, 28, .78) 28%, rgba(35, 33, 28, .32) 64%, rgba(35, 33, 28, 0) 100%);
    background: linear-gradient(to top, var(--lacquer) 0%, color-mix(in srgb, var(--lacquer) 93%, transparent) 12%, color-mix(in srgb, var(--lacquer) 78%, transparent) 28%, color-mix(in srgb, var(--lacquer) 56%, transparent) 46%, color-mix(in srgb, var(--lacquer) 32%, transparent) 64%, color-mix(in srgb, var(--lacquer) 13%, transparent) 82%, color-mix(in srgb, var(--lacquer) 0%, transparent) 100%);
    z-index: -1;
  }
}

/* ---------- #4 the signature wave between sections (lib.mjs WAVE; the stations' own bundle, quieter) ----------
   Full bleed; it sweeps in from the left as it enters (script.js adds .on), drawn at once under reduced motion. */
.wave-div { position: relative; padding-block: clamp(4px, 1vw, 12px); }
/* review fix #5: between two plain sections (/services) the thread runs through the divider at one strength: the divider
   draws its own segment and the neighbours' 200px overhangs stop at their own edges (the homepage's premium layer
   already draws per box) */
.wave-div::before { content: ""; position: absolute; top: 0; bottom: 0; z-index: 0; pointer-events: none; left: calc(max(0px, (100% - var(--max)) / 2) + var(--pad)); width: 1px; background: var(--rule); }
.sec:has(+ .wave-div) .wrap::before { bottom: calc(-1 * clamp(64px, 7vw, 104px)); }
.wave-div + .sec .wrap::before { top: calc(-1 * clamp(64px, 7vw, 104px)); }
.wave-div .wave { width: 100%; height: clamp(38px, 4.2vw, 60px); opacity: .62; }
html:not(.no-js) .wave-div.in .wave { clip-path: inset(0 100% 0 0); transition: clip-path 1.8s cubic-bezier(.45, .05, .25, 1) .1s; }
html:not(.no-js) .wave-div.in.on .wave { clip-path: inset(0 0 0 0); }
.wave-div.in { transform: none; }

/* ---------- #5 "Choose your studio" on phones (it took a whole phone screen) ----------
   Each studio is one compact row: name and address/hours on the left, Book + Call on the right, one row each. The Call
   button reads "Call" and keeps the number for screen readers (.call-n is visually hidden, not removed). */
@media (max-width: 699px) {
  .stations-head { padding: 18px 0 2px var(--inset); gap: 2px 16px; }
  .stations-head h2 { font-size: 1.3rem; }
  .stations-head p { font-size: .82rem; }
  .stations { padding: 32px 0 6px; }
  .stations .line { height: 42px; }
  .stations::after { top: 21px; }
  .stations .st { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0 12px; padding: 13px 0 13px var(--inset); }
  .stations .st:first-child::before { top: -17px; }
  .st h3 { grid-column: 1; font-size: 1.22rem; line-height: 1.25; margin: 0 0 3px; }
  .st .studio-link { gap: 8px; padding-bottom: 1px; }
  .st .studio-link span { font-size: .9rem; }
  .st .addr, .st .open { grid-column: 1; font-size: .84rem; line-height: 1.45; margin: 0; }
  .st .acts { grid-column: 2; grid-row: 1 / span 3; flex-wrap: nowrap; gap: 8px; }
  .st .btn-book { min-height: 44px; padding: 0 16px; }
  .st .call { min-height: 44px; display: inline-flex; align-items: center; padding: 0 14px; border: 1px solid var(--rule); color: var(--ivory); font-weight: 600; font-size: .9rem; }
  .st .call-l { display: inline; }
  .st .call-n { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
}

/* ---------- #1a /services as an accordion (lib.mjs accRow / accCombos; script.js) ----------
   Phat: "don't do a simple one let's make it look nice". One slim ruled row per treatment: serif name, the from price,
   a small wave for a chevron (it flips when open). The panel opens by height (grid rows 0fr -> 1fr) while a blush
   hairline draws under the open row's heading. Collapsed only once JS is on (no-JS: every panel open, as before). */
.menu-acc .acc-hint { margin: calc(-1 * clamp(14px, 2.4vw, 32px)) 0 clamp(24px, 3vw, 40px); font-size: .92rem; color: var(--ivory-2); }
.acc-group { display: grid; grid-template-columns: minmax(150px, .3fr) minmax(0, 1fr); gap: 0 clamp(24px, 4vw, 64px); align-items: start; }
.acc-group + .acc-group { margin-top: clamp(26px, 3.2vw, 44px); }
/* review fix MED-1 (2026-11-09): the Add-ons group's couples link sits under its rows (last column, either layout) */
.acc-group .acc-couples { grid-column: -2 / -1; margin-top: 20px; }
.acc-group-h { padding-top: 24px; font-family: var(--body); font-size: .76rem; font-weight: 600; letter-spacing: .2em; line-height: 1.5; text-transform: uppercase; color: var(--ivory-2); }
.board .row.acc { display: block; padding: 0; scroll-margin-top: calc(var(--nav-h) + 20px); }
.acc-h { position: relative; font-size: inherit; line-height: inherit; }
.acc-h::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: var(--blush); transform: scaleX(0); transform-origin: left center; transition: transform .7s var(--ease); }
.acc.open .acc-h::after { transform: scaleX(1); }
.acc-t { width: 100%; min-height: 64px; display: grid; grid-template-columns: minmax(0, 1fr) auto 20px; align-items: baseline; gap: 18px; padding: 18px 0; text-align: left; }
.acc-name { font-family: var(--display); font-size: clamp(1.25rem, 1.8vw, 1.5rem); line-height: 1.25; transition: color .3s var(--ease); }
.acc-from { font-family: var(--display); font-size: 1.2rem; line-height: 1; white-space: nowrap; font-variant-numeric: tabular-nums lining-nums; }
.acc-from small { font-family: var(--body); font-size: .8rem; color: var(--ivory-2); margin-right: 3px; }
.acc-chev { align-self: center; width: 20px; height: 10px; fill: none; stroke: var(--blush); stroke-width: 1.3; vector-effect: non-scaling-stroke; transition: transform .5s var(--ease); }
.acc.open .acc-chev { transform: scaleY(-1); }
.acc-t:focus-visible { outline-offset: 2px; }
@media (hover: hover) {
  .acc-t:hover .acc-name { color: var(--blush); }
  .acc-t:hover .acc-chev { transform: translateY(2px); }
  .acc.open .acc-t:hover .acc-chev { transform: scaleY(-1) translateY(2px); }
}
.acc-panel { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .55s var(--ease), visibility 0s; }
.acc-in { min-height: 0; overflow: hidden; transition: opacity .45s var(--ease) .08s; }
.acc-in > p { max-width: 36em; padding-top: 2px; color: var(--ivory-2); font-size: .95rem; }
html:not(.no-js) .acc:not(.open) .acc-panel { grid-template-rows: 0fr; visibility: hidden; transition: grid-template-rows .45s var(--ease), visibility 0s .45s; }
html:not(.no-js) .acc:not(.open) .acc-in { opacity: 0; transition-delay: 0s; }
.board .acc .prices { justify-content: flex-start; margin-top: 16px; }
.acc .prices > :last-child::after { content: none; }
.acc-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 26px; padding: 22px 0 26px; }
.acc .row-go { position: static; inset: auto; display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 22px; background: var(--amber); color: var(--on-book); border: 1px solid var(--book-edge); font-weight: 600; font-size: .95rem; line-height: 1; transition: background-color .28s var(--ease); }
.acc .row-go:hover { background: var(--amber-2); }
.acc .treatment-link { color: var(--ivory); font-size: .9rem; text-decoration: underline; text-underline-offset: .22em; text-decoration-thickness: 1px; text-decoration-color: var(--blush-2); }
.acc .treatment-link:hover { text-decoration-color: var(--blush); }
@media (max-width: 899px) {
  .acc-group { grid-template-columns: minmax(0, 1fr); }
  .acc-group-h { padding: 0 0 12px; }
}
@media (max-width: 520px) {
  .acc-t { grid-template-columns: minmax(0, 1fr) auto 18px; gap: 12px; }
  .acc-from { font-size: 1.05rem; }
}
@media (prefers-reduced-motion: reduce) {
  .acc-panel, .acc-in, .acc-chev, .acc-h::after { transition: none; }
}

/* ---------- #1b the Treatments drop-down in the nav (index.html, lifted by chrome.mjs; script.js) ----------
   Desktop: a full-width sheet under the bar, the menu's groups in three columns, a quiet wave at its foot; opens on
   hover (fine pointers), on the chevron button and from the keyboard. Phones: inside the menu sheet, the chevron opens
   the list in place. Treatments itself stays a link to /services. */
.nav-drop { display: flex; align-items: center; }
.nav-drop-t { display: inline-grid; place-items: center; position: relative; width: 26px; height: 32px; margin-left: 2px; color: var(--ivory-2); transition: color .25s var(--ease); }
/* review fix #8: a 44x44 hit area around the 26x32 box, no layout change (phones size the button itself to 44). It grows
   2px left (only into its own margin, never over the Treatments link) and 16px right (the nav gap is >= 19.8px at 900px+) */
.nav-drop-t::after { content: ""; position: absolute; inset: -6px -16px -6px -2px; }
.nav-drop-t svg { width: 12px; height: 6px; fill: none; stroke: currentColor; stroke-width: 1.4; transition: transform .4s var(--ease); }
.nav-drop-t:hover, .nav-drop.open .nav-drop-t { color: var(--ivory); }
.nav-drop.open .nav-drop-t svg { transform: scaleY(-1); }
.nav-drop-panel {
  position: fixed; top: var(--nav-h); left: 0; right: 0; z-index: 2;
  background: var(--lacquer); border-top: 1px solid var(--rule-2); border-bottom: 1px solid var(--rule);
  box-shadow: 0 30px 60px rgba(14, 13, 11, .45);
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity .3s var(--ease), transform .45s var(--ease), visibility 0s .3s;
}
.nav-drop.open .nav-drop-panel { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.nd-in { position: relative; max-width: var(--max); margin-inline: auto; padding: 34px var(--pad) 0 calc(var(--pad) + var(--inset)); }
.nd-groups { columns: 3; column-gap: clamp(28px, 4vw, 64px); }
.nd-g { break-inside: avoid; display: flex; flex-direction: column; align-items: flex-start; padding-bottom: 22px; }
.nd-h { width: 100%; margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid var(--rule-2); font-size: .72rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; color: var(--ivory-2); }
.nav-links .nav-drop-panel a { font-family: var(--display); font-size: 1.12rem; letter-spacing: 0; line-height: 1.3; color: var(--ivory); padding: 5px 0; border-bottom: 0 !important; transition: color .25s var(--ease); }
.nav-links .nav-drop-panel a:hover { color: var(--blush); }
.nd-foot { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 10px 28px; padding: 14px 0 6px; border-top: 1px solid var(--rule); }
.nav-links .nav-drop-panel .nd-all { font-family: var(--body); font-size: .92rem; font-weight: 600; }
.nd-wave { width: 100%; height: 26px; margin-top: 6px; opacity: .45; }
@media (max-width: 899px) {
  .nav-drop { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; border-bottom: 1px solid var(--rule-2); }
  .nav-drop > a { border-bottom: 0 !important; }
  .nav-drop-t { width: 44px; height: 44px; margin: 0 -10px 0 0; }
  .nav-drop-t svg { width: 16px; height: 8px; }
  .nav-drop-panel {
    position: static; grid-column: 1 / -1; display: grid; grid-template-rows: 0fr;
    background: none; border: 0; box-shadow: none; opacity: 1; transform: none;
    transition: grid-template-rows .45s var(--ease), visibility 0s .45s;
  }
  .nav-drop.open .nav-drop-panel { grid-template-rows: 1fr; }
  .nd-in { min-height: 0; overflow: hidden; padding: 0 0 0 2px; }
  .nd-groups { columns: 1; padding-top: 4px; }
  .nd-g { padding-bottom: 14px; }
  .nd-h { border-bottom: 0; margin-bottom: 2px; padding-bottom: 4px; }
  .nav-links .nav-drop-panel a { font-size: 1.05rem; padding: 9px 0; }
  .nd-foot { border-top: 1px solid var(--rule-2); padding: 10px 0 12px; }
  .nd-wave { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .nav-drop-panel, .nav-drop-t svg { transition: none; }
}

.hero:not(:has(+ *)) .hero-copy { visibility: hidden; animation: hero-copy-failsafe 0s 3s forwards; }
@keyframes hero-copy-failsafe { to { visibility: visible; } }
@media (max-width: 899px) { [data-look="july"] .hero:not(:has(+ *)) .hero-media { visibility: hidden; animation: hero-copy-failsafe 0s 3s forwards; } }
