/* ==========================================================================
   EQ Wellbeing — design system
   Rebuilt off the live Squarespace site. Tokens derived from the rendered
   site, not from Squarespace defaults.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,300;0,400;0,500;0,600;1,400&display=swap');

/* Suisse Int'l — EQ's brand face, Regular (400) + SemiBold (600).
   NOTE: requires a Swiss Typefaces WEBFONT licence before going live, and the
   Regular file's provenance needs confirming. See README. */
@font-face {
  font-family: 'Suisse Intl';
  src: url('/assets/fonts/suisse-intl-regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Suisse Intl';
  src: url('/assets/fonts/suisse-intl-semibold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Surfaces */
  --bone:        #F8F8F8;  /* default page background */
  --stone:       #CFCDC7;  /* warm grey band */
  --stone-soft:  #E8E7E4;  /* footer */
  --ink:         #332F2F;  /* dark band + primary text */
  --ink-deep:    #1A1818;

  /* Type */
  --text:        #332F2F;
  --text-muted:  #6B6664;
  --text-invert: #F8F8F8;

  --line:        rgba(51, 47, 47, 0.22);
  --line-invert: rgba(248, 248, 248, 0.34);

  /* Suisse Regular carries only 229 glyphs, so Inter stays in the stack to
     cover anything outside its range rather than dropping to a system serif. */
  --font: 'Suisse Intl', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  --font-display: var(--font);
  /* Symbol stack — Suisse has no ★ or →, so these must not inherit the brand
     face or they render as tofu. */
  --font-symbol: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

  /* Rhythm */
  --gutter: 2rem;
  --maxw: 1360px;
  --section-y: clamp(4.5rem, 9vw, 9rem);
  --radius: 6px;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --------------------------------------------------------------- reset -- */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--text);
  background: var(--bone);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg, video { display: block; max-width: 100%; height: auto; }

a { color: inherit; text-decoration: none; }

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

h1, h2, h3, h4, p, figure, blockquote { margin: 0; }

ul, ol { margin: 0; padding: 0; list-style: none; }

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ------------------------------------------------------------ typography -- */

.h-display,
.h-lead,
.h-section,
.h-card {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.022em;
  line-height: 1.08;
}

.h-display { font-size: clamp(2.5rem, 6vw, 4rem); }
.h-lead    { font-size: clamp(1.75rem, 3.4vw, 2.9rem); line-height: 1.14; }
.h-section { font-size: clamp(1.5rem, 2.6vw, 2.25rem); line-height: 1.2; }
.h-card    { font-size: clamp(1.15rem, 1.6vw, 1.4rem); line-height: 1.25; }

.eyebrow {
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  margin-bottom: 1.25rem;
}

.body-lg { font-size: clamp(1rem, 1.15vw, 1.125rem); line-height: 1.65; }

.measure    { max-width: 46ch; }
.measure-wd { max-width: 62ch; }

/* --------------------------------------------------------------- layout -- */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }
.section--tight { padding-block: clamp(3rem, 5vw, 5rem); }

.band-dark  { background: var(--ink);       color: var(--text-invert); }
.band-stone { background: var(--stone);     color: var(--text); }
.band-soft  { background: var(--stone-soft); color: var(--text); }

.band-dark .eyebrow { color: rgba(248, 248, 248, 0.72); }

.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 3vw, 2.75rem);
}

.grid-2 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
}

@media (max-width: 900px) {
  .grid-3, .grid-2 { grid-template-columns: 1fr; }
}

/* -------------------------------------------------------------- buttons -- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.7rem 1.15rem;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.005em;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  transition: background-color 0.35s var(--ease), color 0.35s var(--ease),
              border-color 0.35s var(--ease);
}

.btn .arw { font-family: var(--font-symbol); transition: transform 0.35s var(--ease); }
.btn:hover { background: var(--ink); border-color: var(--ink); color: var(--text-invert); }
.btn:hover .arw { transform: translateX(4px); }

.btn--solid { background: var(--ink); border-color: var(--ink); color: var(--text-invert); }
.btn--solid:hover { background: transparent; color: var(--text); border-color: var(--line); }

/* on dark / imagery */
.btn--invert {
  border-color: var(--line-invert);
  color: var(--text-invert);
  background: rgba(248, 248, 248, 0.08);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.btn--invert:hover { background: var(--bone); color: var(--ink); border-color: var(--bone); }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2rem; }

/* ------------------------------------------------------- announcement -- */

.announce {
  background: var(--ink);
  color: var(--text-invert);
  font-size: 0.8125rem;
  text-align: center;
  padding: 0.6rem var(--gutter);
}
.announce a { text-decoration: underline; text-underline-offset: 2px; }

/* --------------------------------------------------------------- header -- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--bone);
  border-bottom: 1px solid transparent;
  transition: box-shadow 0.35s var(--ease), border-color 0.35s var(--ease);
}
.site-header.is-stuck {
  border-color: var(--line);
  box-shadow: 0 1px 18px rgba(0, 0, 0, 0.05);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  min-height: 76px;
}

.brand img { height: 34px; width: auto; }

/* The supplied EQ mark is white-on-transparent. On light surfaces we recolour
   it to ink rather than shipping a second asset — alpha is preserved. */
.logo-ink { filter: brightness(0); }

.nav-links {
  display: flex;
  align-items: center;
  gap: 1.9rem;
  font-size: 0.875rem;
}

.nav-links > li { position: relative; }

.nav-links a,
.nav-drop > button {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding-block: 0.5rem;
  color: var(--text);
  opacity: 0.85;
  transition: opacity 0.25s var(--ease);
}
.nav-links a:hover,
.nav-drop > button:hover { opacity: 1; }

.nav-links a[aria-current="page"] { opacity: 1; text-decoration: underline; text-underline-offset: 5px; }

/* dropdown */
.nav-drop > button .chev { transition: transform 0.3s var(--ease); }
.nav-drop[data-open="true"] > button .chev { transform: rotate(180deg); }

.nav-drop-panel {
  position: absolute;
  top: calc(100% + 0.55rem);
  left: -1rem;
  min-width: 236px;
  padding: 0.6rem;
  background: var(--bone);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.1);
  display: grid;
  gap: 0.1rem;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 0.28s var(--ease), transform 0.28s var(--ease), visibility 0.28s;
}
.nav-drop[data-open="true"] .nav-drop-panel {
  opacity: 1; visibility: visible; transform: translateY(0);
}
.nav-drop-panel a {
  padding: 0.55rem 0.7rem;
  border-radius: 4px;
  opacity: 0.9;
}
.nav-drop-panel a:hover { background: var(--stone); opacity: 1; }

.nav-cta { display: flex; align-items: center; gap: 0.9rem; }

/* Nested "Guided Resets" group inside the Discover panel and the mobile menu.
   Expands inline rather than flying out sideways: a second-level flyout is
   hard to keep open with a mouse and impossible to reach on touch.

   grid-template-rows 0fr → 1fr animates to the content's own height, which
   max-height cannot do without hardcoding a guess. The inner div is required —
   the animating row needs a child that can be clipped. */
.nav-sub { display: grid; }
.nav-sub__btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  padding: 0.55rem 0.7rem;
  border: 0;
  border-radius: 4px;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  opacity: 0.9;
  cursor: pointer;
}
.nav-sub__btn:hover { background: var(--stone); opacity: 1; }
.nav-sub__btn .chev { transition: transform .25s var(--ease); flex: none; }
.nav-sub[data-open="true"] .nav-sub__btn .chev { transform: rotate(180deg); }

.nav-sub__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .28s var(--ease);
}
.nav-sub__panel > div { overflow: hidden; }
.nav-sub[data-open="true"] .nav-sub__panel { grid-template-rows: 1fr; }

/* display:block so the hover highlight spans the whole row. Inside the panel
   these anchors sit in a nested div rather than being grid children, so
   without it they stay inline and only light up behind the text. */
.nav-sub__panel > div { display: grid; gap: 0.1rem; }
.nav-sub__panel a { display: block; }

/* Indented so the three children read as belonging to the row above. */
.nav-drop-panel .nav-sub__panel a { padding-left: 1.5rem; }

/* Reduced motion: no height animation, just show or hide. */
@media (prefers-reduced-motion: reduce) {
  .nav-sub__panel { transition: none; }
}



.nav-toggle { display: none; padding: 0.5rem; margin-right: -0.5rem; }
.nav-toggle span {
  display: block; width: 22px; height: 1.5px; background: var(--text);
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}
.nav-toggle span + span { margin-top: 5px; }
body.menu-open .nav-toggle span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
body.menu-open .nav-toggle span:nth-child(2) { opacity: 0; }
body.menu-open .nav-toggle span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* mobile drawer */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: var(--bone);
  padding: 6.5rem var(--gutter) 2rem;
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s var(--ease), visibility 0.35s;
}
body.menu-open .mobile-nav { opacity: 1; visibility: visible; }
body.menu-open { overflow: hidden; }

.mobile-nav a {
  display: block;
  padding: 0.85rem 0;
  font-size: 1.35rem;
  letter-spacing: -0.015em;
  border-bottom: 1px solid var(--line);
}
.mobile-nav .sub a { font-size: 1rem; padding-left: 1rem; opacity: 0.8; }
.mobile-nav .m-label {
  padding: 1.5rem 0 0.35rem;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

@media (max-width: 1040px) {
  .nav-links, .nav-cta .btn { display: none; }
  .nav-toggle { display: block; }
}

/* ----------------------------------------------------------------- hero -- */

.hero {
  position: relative;
  min-height: clamp(520px, 82vh, 860px);
  display: flex;
  align-items: flex-end;
  color: var(--text-invert);
  overflow: hidden;
}

.hero__media { position: absolute; inset: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; }

.hero__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
              rgba(20, 18, 18, 0.72) 0%,
              rgba(20, 18, 18, 0.34) 42%,
              rgba(20, 18, 18, 0.12) 100%);
}

.hero__inner { position: relative; z-index: 1; width: 100%; padding-block: clamp(3rem, 7vw, 5.5rem); }
.hero__inner p { max-width: 46ch; margin-top: 1.25rem; opacity: 0.92; }

.hero--short { min-height: clamp(360px, 52vh, 560px); }

/* ------------------------------------------------------- product cards -- */

.card { display: flex; flex-direction: column; }

.card__media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--stone);
}
.card__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 0.9s var(--ease);
}
.card:hover .card__media img { transform: scale(1.035); }

.card__body { padding-top: 1.4rem; display: flex; flex-direction: column; flex: 1; }
.card__body p { margin-top: 0.65rem; color: var(--text-muted); }
.band-dark .card__body p { color: rgba(248, 248, 248, 0.76); }
.card__body .btn { margin-top: auto; align-self: flex-start; padding-top: 0.7rem; }
.card__body .btn { margin-top: 1.5rem; }

/* --------------------------------------------------------- testimonials -- */

.stars { font-family: var(--font-symbol); letter-spacing: 0.28em; font-size: 1rem; }

.quote-list { display: grid; gap: clamp(1.5rem, 2.4vw, 2.25rem); }
.quote-list li { font-size: clamp(1.25rem, 2vw, 1.75rem); line-height: 1.28; letter-spacing: -0.018em; }

/* --------------------------------------------------------- feature band -- */

.feature {
  position: relative;
  min-height: clamp(440px, 62vh, 660px);
  display: flex;
  align-items: center;
  color: var(--text-invert);
  overflow: hidden;
}
.feature__media { position: absolute; inset: 0; }
.feature__media img { width: 100%; height: 100%; object-fit: cover; }
.feature__media::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to right,
              rgba(20, 18, 18, 0.66) 0%,
              rgba(20, 18, 18, 0.28) 58%,
              rgba(20, 18, 18, 0.05) 100%);
}
.feature__inner { position: relative; z-index: 1; width: 100%; }

/* ------------------------------------------------------------- includes -- */

/* Promises — a claim plus its proof.
   Deliberately not the .includes treatment below: no numbering, no two-column
   split, fewer items with more air. Six numbered fragments read as a spec
   sheet; four statements with evidence read as reassurance, which is what this
   part of the page is actually for. */
.prom { display: flex; flex-direction: column; }
.prom li {
  padding: clamp(1rem, 1.8vw, 1.4rem) 0;
  border-bottom: 1px solid var(--line-invert);
}
.prom li:first-child { padding-top: 0; }
.prom li:last-child  { border-bottom: 0; padding-bottom: 0; }
.rd .band-light .prom li { border-color: var(--line); }

.prom__claim {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.0625rem, 1.5vw, 1.3rem);
  line-height: 1.25;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.prom__proof {
  display: block;
  margin-top: 0.5rem;
  max-width: 52ch;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: rgba(248, 248, 248, 0.62);
  text-wrap: pretty;
}
.rd .band-light .prom__proof { color: var(--text-muted); }

.includes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.9rem 3rem;
  counter-reset: inc;
}
.includes li {
  display: flex;
  gap: 0.9rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--line);
  font-size: 0.9375rem;
}
.band-dark .includes li { border-color: var(--line-invert); }
.includes li::before {
  counter-increment: inc;
  content: counter(inc, decimal-leading-zero) '.';
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.band-dark .includes li::before { color: rgba(248, 248, 248, 0.6); }

@media (max-width: 720px) { .includes { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------------ faq -- */

.faq { border-top: 1px solid var(--line); }
.faq__item { border-bottom: 1px solid var(--line); }

.faq__q {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 2rem;
  padding: 1.35rem 0;
  text-align: left;
  font-size: clamp(1rem, 1.3vw, 1.125rem);
  letter-spacing: -0.012em;
}
.faq__q .sign {
  flex: none;
  width: 16px; height: 16px;
  position: relative;
  margin-top: 0.4rem;
}
.faq__q .sign::before,
.faq__q .sign::after {
  content: '';
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1.5px;
  background: currentColor;
  transition: transform 0.35s var(--ease);
}
.faq__q .sign::after { transform: rotate(90deg); }
.faq__item[data-open="true"] .sign::after { transform: rotate(0deg); }

.faq__a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s var(--ease);
}
.faq__item[data-open="true"] .faq__a { grid-template-rows: 1fr; }
.faq__a > div { overflow: hidden; }
.faq__a p {
  color: var(--text-muted);
  padding-bottom: 1.5rem;
  max-width: 72ch;
}
.faq__a p + p { padding-top: 0.9rem; }
.faq__a a { text-decoration: underline; text-underline-offset: 2px; }

.faq-group + .faq-group { margin-top: clamp(2.5rem, 5vw, 4rem); }
.faq-group > h3 { margin-bottom: 1.25rem; }

/* --------------------------------------------------------------- footer -- */

.site-footer { background: var(--stone-soft); padding-block: clamp(3.5rem, 6vw, 5.5rem) 2.5rem; }
.site-footer .logo { height: 40px; width: auto; margin-bottom: 3rem; }

.footer-grid {
  display: grid;
  grid-template-columns: 1.1fr 0.8fr 0.8fr 0.7fr 1.5fr;
  gap: 2.5rem;
}
.footer-grid h4 { font-size: 0.9375rem; font-weight: 600; margin-bottom: 0.9rem; }
.footer-grid li + li { margin-top: 0.4rem; }
.footer-grid a:hover { text-decoration: underline; text-underline-offset: 3px; }
.footer-grid address { font-style: normal; line-height: 1.7; }

.footer-contact { margin-top: 2.5rem; }
.footer-contact a { text-decoration: underline; text-underline-offset: 3px; display: block; }

.newsletter { display: grid; gap: 0.75rem; }
.newsletter label { font-size: 0.8125rem; color: var(--text-muted); display: block; margin-bottom: 0.3rem; }
.newsletter input {
  width: 100%;
  padding: 0.7rem 0.85rem;
  font: inherit;
  font-size: 0.9375rem;
  color: var(--text);
  background: #fff;
  border: 1px solid #C5C8C6;
  border-radius: 8px;
}
.newsletter input:focus { outline: 2px solid var(--ink); outline-offset: 0; border-color: var(--ink); }
.newsletter .row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
.newsletter button { margin-top: 0.35rem; justify-self: start; }
.form-note { font-size: 0.8125rem; color: var(--text-muted); }
.form-note--success { color: var(--text); }
.form-note--error { color: #8a3232; }

/* Honeypot — off-canvas rather than display:none, because some bots skip
   fields the layout engine has removed. People never see or tab to it. */
.newsletter .hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.social { display: flex; gap: 1rem; margin-top: 3rem; }
.social a { opacity: 0.75; transition: opacity 0.25s var(--ease); }
.social a:hover { opacity: 1; }

.acknowledgement {
  margin-top: 1.75rem;
  max-width: 42ch;
  font-size: 0.875rem;
  line-height: 1.6;
}

.footer-base {
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.8125rem;
  color: var(--text-muted);
}

@media (max-width: 1040px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .newsletter { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
  .footer-grid { grid-template-columns: 1fr; }
  .newsletter .row { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------ utilities -- */

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

.skip-link {
  position: absolute; top: 0; left: 0; z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--ink); color: var(--text-invert);
  transform: translateY(-120%);
}
.skip-link:focus { transform: translateY(0); }

/* reveal on scroll */
.reveal { opacity: 0; transform: translateY(18px); }
.reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
}

/* ==========================================================================
   REDESIGN LAYER — concept branch
   Charcoal-dominant, editorial pacing, the "ladder" progression.
   Hierarchy comes from size and space, not weight (we only ship 400/600).
   ========================================================================== */

:root {
  --section-y-lg: clamp(5rem, 8vw, 8.5rem);
}

/* Charcoal is now the primary surface, bone is the accent. */
body.rd { background: var(--ink); color: var(--text-invert); }
.rd .band-light { background: var(--bone); color: var(--text); }
.rd .band-light .eyebrow { color: var(--text-muted); }

.rd .eyebrow {
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(248, 248, 248, 0.55);
}

/* Bigger, quieter display type. */
.rd .h-display { font-size: clamp(2.1rem, 4.6vw, 3.6rem); line-height: 1.06; letter-spacing: -0.028em; font-weight: 400; }
.rd .h-lead    { font-size: clamp(1.6rem, 3.2vw, 2.6rem); line-height: 1.18; font-weight: 400; }
.rd .section--lg { padding-block: var(--section-y-lg); }

/* ------------------------------------------------------------- the hero -- */

.rd-hero { position: relative; min-height: 92vh; display: flex; align-items: flex-end; overflow: hidden; }
.rd-hero__media { position: absolute; inset: 0; }
.rd-hero__media img { width: 100%; height: 100%; object-fit: cover; }
.rd-hero__media::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(26,24,24,0.92) 0%, rgba(26,24,24,0.45) 45%, rgba(26,24,24,0.25) 100%);
}
.rd-hero__inner { position: relative; z-index: 1; width: 100%; padding-bottom: clamp(3.5rem, 7vw, 6rem); }
/* Display type needs a tighter measure than body copy, not a looser one. The
   h1 had none at all, so on a wide screen it ran the full 1360px container while
   the paragraph beneath wrapped at 40ch — a headline roughly 2.5x the width of
   its own body copy, which is what made the paragraph look squeezed.

   22ch keeps the three short heroes on one line (13, 21 and 29 characters) and
   breaks the 41-character Signature Journey one across two, which is where it
   wanted to break anyway. Same idea as .rd-stmt at 30ch for section headings. */
.rd-hero .h-display { max-width: 22ch; }
.rd-hero p { max-width: 40ch; margin-top: 1.5rem; font-size: clamp(1rem, 1.3vw, 1.2rem); color: rgba(248,248,248,0.82); }

/* --------------------------------------------------------- the position -- */

.rd-stmt { max-width: 30ch; }
.rd-stmt-body { max-width: 54ch; color: rgba(248,248,248,0.72); }
.rd-stmt-body p + p { margin-top: 1.25rem; }

/* --------------------------------------------------------- the ladder --- */

.ladder { display: grid; gap: 0; margin-top: clamp(3rem, 6vw, 5rem); }

.rung {
  display: grid;
  grid-template-columns: minmax(280px, 30%) 1fr auto;
  gap: 2.25rem;
  align-items: start;
  padding: clamp(2rem, 4vw, 3.25rem) 0;
  border-top: 1px solid var(--line-invert);
  transition: background-color 0.5s var(--ease);
}
/* No rule above the first rung. The dividers exist to separate rows from each
   other; the top one separated the list from the heading, where the section's
   own spacing already does that job. */
.rung:first-child { border-top: 0; }
.rung:last-child { border-bottom: 1px solid var(--line-invert); }
/* No row hover. The rung is an <article>, not a link — the only clickable
   thing in it is the button. Tinting the whole row on hover advertised a
   target that isn't there, and the pointer stayed an arrow the entire time,
   so it read as the page reacting to nothing. The button has its own hover,
   which is the real affordance. */

/* The cards carry their own artwork, title and feature list, so they are sized
   to be read rather than glanced at: a wider column and their native 4:5 crop
   instead of the 4:3 thumbnail the photographic version used. */
.rung__media {
  overflow: hidden;
  border-radius: var(--radius);
  aspect-ratio: 4 / 5;
  background: rgba(248, 248, 248, 0.06);
}
/* Zoom removed with the row tint above, and for the same reason: the image is
   not a link either, so it should not respond to a pointer passing over it. */
.rung__media img { width: 100%; height: 100%; object-fit: cover; }

.rung__title { font-size: clamp(1.4rem, 2.4vw, 2rem); line-height: 1.12; letter-spacing: -0.022em; }
.rung__meta { margin-top: 0.6rem; font-size: 0.875rem; color: rgba(248,248,248,0.55); }
.rung__desc { margin-top: 1rem; color: rgba(248,248,248,0.72); font-size: 0.9375rem; line-height: 1.6; max-width: 52ch; }
/* Time leads, cost follows. Time is the deciding factor for most bookings —
   people know whether they have ninety minutes long before they weigh $59
   against $150 — so the duration takes the size the price used to have and the
   price drops to a supporting line. */
.rung__commit { text-align: right; white-space: nowrap; padding-top: 0.35rem; }
.rung__time {
  display: block;
  font-size: clamp(1.25rem, 1.9vw, 1.6rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.rung__cost {
  display: block;
  margin-top: 0.45rem;
  font-size: 0.8125rem;
  color: rgba(248, 248, 248, 0.5);
  font-variant-numeric: tabular-nums;
}
.rung__cta { margin-top: 1.5rem; }

@media (max-width: 1100px) {
  .rung { grid-template-columns: 4.5rem 160px 1fr auto; gap: 1.5rem; }
}
@media (max-width: 900px) {
  .rung { grid-template-columns: 1fr auto; gap: 0.75rem 1.5rem; }
    .rung__media { grid-column: 1 / -1; aspect-ratio: 4 / 5; max-width: 340px; margin-bottom: 0.5rem; }
  .rung__commit { grid-row: 3; grid-column: 2; }
  .rung__body { grid-column: 1; grid-row: 3; }
  .rung__cta { grid-column: 1 / -1; }
}
@media (max-width: 620px) {
  /* Phones. Two things happen here.

     The artwork goes full width: it is 1080x1350, exactly the 4/5 this slot
     uses, so nothing is cropped and the card lines up with the full-bleed
     bands above it. The 340px cap in the rule above is for tablets, where a
     full-bleed 4/5 image would be taller than the screen.

     And the copy goes full width. Until now .rung__body sat in column 1 with
     the time and price in column 2, so the description and the button were
     squeezed into the narrower column for the whole height of the row and
     wrapped a good deal earlier than the rule beneath them. display: contents
     dissolves that wrapper so its children become grid items in their own
     right, which lets the title stay beside the price while the description
     and the button span the full width. It also finally activates the
     .rung__cta span rule above, which never applied while the button was a
     child of a non-grid parent.

     Row gap does the vertical rhythm here, so the flow margins the desktop
     layout relies on are zeroed rather than stacking on top of it. */
  .rung { gap: 0.6rem 1.5rem; }
  .rung__media  { grid-column: 1 / -1; grid-row: 1; max-width: none; margin-bottom: 0.4rem; }
  .rung__body   { display: contents; }
  .rung__title  { grid-column: 1;      grid-row: 2; }
  .rung__meta   { grid-column: 1;      grid-row: 3; margin-top: 0; }
  .rung__commit { grid-column: 2;      grid-row: 2 / span 2; }
  .rung__desc   { grid-column: 1 / -1; grid-row: 4; margin-top: 0.5rem; max-width: none; }
  .rung__cta    { grid-column: 1 / -1; grid-row: 5; margin-top: 0.75rem; }
}

/* -------------------------------------------------------- hero product -- */

.rd-feature { position: relative; overflow: hidden; }
.rd-feature__media { position: relative; aspect-ratio: 16 / 7; }
.rd-feature__media img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 760px) { .rd-feature__media { aspect-ratio: 4 / 3; } }

/* ------------------------------------------------------------ evidence -- */

.rd-quotes { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(2rem, 4vw, 3.5rem); }
/* Each separator hugs its own quote rather than aligning to a shared
   baseline across the row: with quotes of different lengths the aligned
   version left the short cards with a large quote-to-line gap, which read
   as inconsistent against In the media (Adrian, 18/08). Quote-to-line and
   line-to-source spacing now match .press-item on every card. */
.rd-quotes blockquote { font-size: clamp(1.05rem, 1.5vw, 1.3rem); line-height: 1.4; letter-spacing: -0.015em; }
.rd-quotes .src { margin-top: 1.25rem; padding-top: 1.25rem; border-top: 1px solid rgba(248,248,248,0.16); font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase; color: rgba(248,248,248,0.45); }
@media (max-width: 860px) { .rd-quotes { grid-template-columns: 1fr; } }

.rd-press { display: flex; flex-wrap: wrap; gap: clamp(2rem, 6vw, 5rem); align-items: baseline; }
.rd-press span { font-size: 0.9375rem; letter-spacing: 0.02em; color: rgba(51,47,47,0.55); }

/* ------------------------------------------------------------ booking --- */

/* Top-aligned: the availability list grows with the number of sessions, so
   centring leaves the heading floating against a long column. */
.rd-book { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: start; }
@media (max-width: 860px) { .rd-book { grid-template-columns: 1fr; } }

.slot-note {
  border: 1px dashed var(--line-invert);
  border-radius: var(--radius);
  padding: 2rem;
  color: rgba(248,248,248,0.6);
  font-size: 0.875rem;
  line-height: 1.6;
}

/* Buttons on charcoal default to the inverted treatment. */
.rd .btn { border-color: var(--line-invert); color: var(--text-invert); }
.rd .btn:hover { background: var(--bone); color: var(--ink); border-color: var(--bone); }
.rd .band-light .btn { border-color: var(--line); color: var(--text); }
.rd .band-light .btn:hover { background: var(--ink); color: var(--text-invert); border-color: var(--ink); }
.rd .btn--primary { background: var(--bone); color: var(--ink); border-color: var(--bone); }
.rd .btn--primary:hover { background: transparent; color: var(--text-invert); border-color: var(--line-invert); }

/* The header CTA is the one button on the page that should never look
   optional, so it does not use the standard primary hover. That hover empties
   the button out to transparent, which is fine mid-page where it de-emphasises
   politely, but in the header it makes the main action look like it switched
   off under the cursor. This one stays filled and shifts bone -> stone. */
.rd .nav-cta .btn--primary:hover {
  background: var(--stone);
  border-color: var(--stone);
  color: var(--ink);
}

/* Header/footer inherit the dark surface on the redesign. */
.rd .site-header { background: var(--ink); }
.rd .site-header.is-stuck { border-color: var(--line-invert); box-shadow: none; }
.rd .nav-links a, .rd .nav-drop > button { color: var(--text-invert); }
.rd .logo-ink { filter: none; }
.rd .nav-drop-panel { background: var(--ink-deep); border-color: var(--line-invert); }
.rd .nav-drop-panel a:hover { background: rgba(248,248,248,0.08); }
.rd .nav-toggle span { background: var(--text-invert); }
.rd .mobile-nav { background: var(--ink); }
.rd .mobile-nav a { border-color: var(--line-invert); }
.rd .site-footer { background: var(--ink-deep); color: var(--text-invert); }
.rd .site-footer .footer-base { border-color: var(--line-invert); color: rgba(248,248,248,0.5); }
.rd .form-note { color: rgba(248,248,248,0.5); }
/* State notes need to survive the dark footer: success reads as body text,
   error keeps enough red to register without fighting the charcoal. */
.rd .form-note--success { color: rgba(248,248,248,0.85); }
.rd .form-note--error { color: #d99a9a; }
.rd .newsletter label { color: rgba(248,248,248,0.6); }
.rd .announce { background: var(--ink-deep); border-bottom: 1px solid var(--line-invert); }

/* Slower, deeper reveal — the interaction should feel like an exhale. */
/* Collapse the doubled gap only where both sections sit on the same surface.

   BOTH sides have to be checked. The :not() list was only on the second
   section, so a band followed by a plain section still collapsed — and there
   the padding is not doubled whitespace to be tidied away, it is the only gap
   between a hard colour edge and the first line of text. Checking the first
   section too means the rule fires only when there is genuinely a shared
   surface, which is the case it was written for. */
.rd .section--lg:not(.band-light):not(.band-soft):not(.band-stone)
  + .section--lg:not(.band-light):not(.band-soft):not(.band-stone) { padding-top: 0; }

.rd .reveal { opacity: 0; transform: translateY(26px); }

/* Must restate opacity/transform here, not just the transition: `.rd .reveal`
   and `.reveal.is-in` have equal specificity (two classes each), so the later
   rule wins and would otherwise pin these elements at opacity 0 forever. */
.rd .reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity 1.1s var(--ease), transform 1.1s var(--ease);
}

/* Same trap for the reduced-motion escape hatch. */
@media (prefers-reduced-motion: reduce) {
  .rd .reveal { opacity: 1; transform: none; }
}

/* ------------------------------------------------ redesign: subpages -- */

/* FAQ + includes need the inverted rules on charcoal. */
.rd .faq, .rd .faq__item { border-color: var(--line-invert); }
.rd .faq__a p { color: rgba(248, 248, 248, 0.68); }
.rd .includes li { border-color: var(--line-invert); }
.rd .includes li::before { color: rgba(248, 248, 248, 0.45); }
/* Prose links underline; buttons that happen to sit inside a prose block
   must not. */
.rd .rd-stmt-body a:not(.btn) { text-decoration: underline; text-underline-offset: 3px; }

/* Session options — the ladder pattern reused at page level. */
.opts { display: grid; gap: 0; margin-top: clamp(2.5rem, 5vw, 4rem); }
.opt {
  display: grid;
  grid-template-columns: 1fr minmax(200px, 0.8fr) auto auto;
  gap: 2.5rem;
  align-items: baseline;
  padding: clamp(1.75rem, 3.5vw, 2.75rem) 0;
  border-top: 1px solid var(--line-invert);
  transition: background-color 0.5s var(--ease);
}
.opt:last-child { border-bottom: 1px solid var(--line-invert); }
/* No row hover, same reasoning as .rung: the .opt is an <article> and only the
   button inside it is clickable, so tinting the row promised a target that
   isn't there.

   .avail__row keeps its hover deliberately. That list runs to six near
   identical rows differing only by time, so the tint is doing real work
   tracking which line you are on, rather than implying a click target. */
.opt__title { font-size: clamp(1.25rem, 2.1vw, 1.7rem); letter-spacing: -0.02em; line-height: 1.15; }
.opt__meta { margin-top: 0.5rem; font-size: 0.8125rem; color: rgba(248,248,248,0.5); }
.opt__desc { font-size: 0.9375rem; line-height: 1.6; color: rgba(248,248,248,0.72); }
.opt__price { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.opt__price .amt { font-size: clamp(1.25rem, 1.8vw, 1.6rem); letter-spacing: -0.02em; }
.opt__price .sub { display: block; font-size: 0.75rem; color: rgba(248,248,248,0.45); margin-top: 0.25rem; }
/* Subordinate to the number so "From" qualifies the price without competing
   with it — the figure is still what the eye lands on. */
.opt__price .from { font-size: 0.62em; color: rgba(248,248,248,0.55); margin-right: 0.12em; }

@media (max-width: 900px) {
  .opt { grid-template-columns: 1fr auto; gap: 0.6rem 1.5rem; }
  .opt__desc { grid-column: 1 / -1; }
  .opt > .btn { grid-column: 1 / -1; justify-self: start; margin-top: 0.75rem; }
}

/* Next rung — the cross-sell that makes the ladder a system. */
.next-step {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: clamp(2.5rem, 5vw, 4rem);
  border: 1px solid var(--line-invert);
  border-radius: var(--radius);
}
.next-step .eyebrow { margin-bottom: 0.75rem; }
.next-step__title { font-size: clamp(1.4rem, 2.4vw, 2rem); letter-spacing: -0.022em; line-height: 1.15; max-width: 22ch; }
.next-step p { margin-top: 0.9rem; max-width: 46ch; color: rgba(248,248,248,0.7); font-size: 0.9375rem; }

/* Editorial two-up imagery. */
.img-pair { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1rem, 2vw, 1.75rem); }
.img-pair img { width: 100%; aspect-ratio: 4/5; object-fit: cover; border-radius: var(--radius); }
@media (max-width: 760px) { .img-pair { grid-template-columns: 1fr; } }

/* ------------------------------------------------ live availability -- */

.avail { min-height: 120px; }
.avail__msg { color: rgba(248, 248, 248, 0.55); font-size: 0.9375rem; margin-bottom: 1.25rem; }
.avail--loading .avail__msg { opacity: 0.7; }

.avail__list { border-top: 1px solid var(--line-invert); }

.avail__row {
  display: grid;
  /* Fixed when-column rather than a fraction: a fraction stretches with the
     viewport, leaving dead space after short labels like "Today" while long
     ones like "Sunday 19 Jul" sit tight. Fixed keeps every session name on the
     same left edge with no gap. */
  grid-template-columns: 150px 1fr auto auto;
  gap: 1.5rem;
  align-items: center;
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--line-invert);
  transition: background-color 0.4s var(--ease);
}
.avail__row:hover { background: rgba(248, 248, 248, 0.035); }

.avail__when { display: flex; flex-direction: column; gap: 0.15rem; }
.avail__day { font-size: 0.9375rem; }
.avail__time { font-size: 0.8125rem; color: rgba(248, 248, 248, 0.55); font-variant-numeric: tabular-nums; }

.avail__what { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.avail__name { font-size: 0.9375rem; }
.avail__dur { font-size: 0.8125rem; color: rgba(248, 248, 248, 0.5); }

.avail__meta { display: flex; flex-direction: column; align-items: flex-end; gap: 0.25rem; text-align: right; }
.avail__price { font-size: 1rem; font-variant-numeric: tabular-nums; }

/* Scarcity is only ever rendered from real remaining-spot counts. */
.avail__spots {
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #E8B4A0;
  white-space: nowrap;
}

.avail__cta { padding: 0.55rem 0.9rem; font-size: 0.75rem; }

.avail__all {
  display: inline-block;
  margin-top: 1.5rem;
  font-size: 0.875rem;
  color: rgba(248, 248, 248, 0.65);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.avail__all:hover { color: var(--text-invert); }

@media (max-width: 700px) {
  .avail__row { grid-template-columns: 1fr auto; gap: 0.5rem 1rem; padding: 1.25rem 0; }
  .avail__what { grid-column: 1; grid-row: 2; }
  .avail__meta { grid-column: 2; grid-row: 2; }
  .avail__cta { grid-column: 1 / -1; justify-self: start; margin-top: 0.75rem; }
}

/* --------------------------------------------- first-visit reassurance -- */

/* Clarity recordings show guests leaving the booking page to hunt for
   "what should I wear / bring / is it suitable" before committing. Put the
   answers ahead of the booking step instead of below it. */

/* ------------------------------------------------- hero background video -- */

/* The poster <img> stays in the DOM and is what most visitors ever see.
   The video is layered over it and fades in only once it can play through. */
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1.2s var(--ease);
  pointer-events: none;
}
.hero-video.is-playing { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .hero-video { display: none; }
}

/* ------------------------------------------------- imagery + press -- */

.rd-img { width: 100%; border-radius: var(--radius); aspect-ratio: 4/3; object-fit: cover; }

/* The image replaces the rule as the divider once there is one. */

/* Three quotes shown together rather than rotated. An auto-advancing carousel
   moves at its own pace, is regularly missed entirely, and competes with the
   scroll gesture on mobile — showing all three costs nothing and is read. */
.press-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(2rem, 4vw, 4rem);
  margin-top: clamp(2rem, 4vw, 3.5rem);
}
.press-item { display: flex; flex-direction: column; gap: 1.25rem; }
.press-item blockquote {
  font-size: clamp(1.15rem, 1.9vw, 1.6rem);
  line-height: 1.28;
  letter-spacing: -0.02em;
  flex: 1;
}
.press-item figcaption {
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}
@media (max-width: 860px) { .press-grid { grid-template-columns: 1fr; } }

/* ---------------------------------------------------- booking portal -- */

.bk-ctl-label {
  display: block;
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(248, 248, 248, 0.45);
  margin-bottom: 0.6rem;
}

.bk-controls {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  padding-bottom: 1.75rem;
}

.bk-party__opts, .bk-exp__opts { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.bk-num {
  width: 2.6rem; height: 2.6rem;
  border: 1px solid var(--line-invert);
  border-radius: 100px;
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
  color: rgba(248, 248, 248, 0.75);
  transition: background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.bk-num:hover { color: var(--text-invert); border-color: rgba(248,248,248,.6); }
.bk-num.is-on { background: var(--bone); border-color: var(--bone); color: var(--ink); }

.bk-chip {
  padding: 0.6rem 1.05rem;
  font-size: 0.8125rem;
  border: 1px solid var(--line-invert);
  border-radius: 100px;
  color: rgba(248, 248, 248, 0.75);
  transition: background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.bk-chip:hover { color: var(--text-invert); border-color: rgba(248,248,248,.6); }
.bk-chip.is-on { background: var(--bone); border-color: var(--bone); color: var(--ink); }

.bk-quick { display: flex; flex-wrap: wrap; gap: 0.5rem; padding-bottom: 1.25rem; }

/* Horizontal day strip — one tap to a day, no calendar to navigate. */
.bk-dates {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  padding-bottom: 1.75rem;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.bk-dates::-webkit-scrollbar { display: none; }

.bk-date {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  min-width: 4.1rem;
  padding: 0.7rem 0.5rem;
  border: 1px solid var(--line-invert);
  border-radius: var(--radius);
  color: rgba(248, 248, 248, 0.75);
  transition: background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.bk-date:hover { color: var(--text-invert); border-color: rgba(248,248,248,.6); }
.bk-date.is-on { background: var(--bone); border-color: var(--bone); color: var(--ink); }
.bk-date__dow { font-size: 0.6875rem; letter-spacing: 0.06em; text-transform: uppercase; opacity: 0.7; }
.bk-date__num { font-size: 1.15rem; font-variant-numeric: tabular-nums; line-height: 1.1; }
.bk-date__mon { font-size: 0.6875rem; text-transform: uppercase; opacity: 0.7; }

.bk-day__title {
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(248, 248, 248, 0.5);
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--line-invert);
}

.bk-row {
  display: grid;
  grid-template-columns: 100px 1fr auto auto;
  gap: 1.5rem;
  align-items: center;
  padding: 1.15rem 0;
  border-bottom: 1px solid var(--line-invert);
  transition: background-color .4s var(--ease);
}
.bk-row:hover { background: rgba(248, 248, 248, 0.035); }

.bk-time { font-size: 0.9375rem; font-variant-numeric: tabular-nums; }
.bk-what { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.bk-name { font-size: 0.9375rem; }
.bk-dur  { font-size: 0.8125rem; color: rgba(248, 248, 248, 0.5); }

.bk-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 0.2rem; text-align: right; }
.bk-price { font-size: 1rem; font-variant-numeric: tabular-nums; }

/* Scarcity is only ever rendered from a real remainingSpots count. */
.bk-spots {
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #E8B4A0;
  white-space: nowrap;
}

.bk-cta { padding: 0.55rem 1rem; font-size: 0.75rem; }

.bk-empty { color: rgba(248, 248, 248, 0.6); font-size: 0.9375rem; padding: 2rem 0; }
.bk-reset { text-decoration: underline; text-underline-offset: 3px; color: inherit; }

/* Escape hatch for the first-timer who landed here before deciding. */
.bk-help { margin-top: 2.5rem; font-size: 0.875rem; color: rgba(248, 248, 248, 0.55); }
.bk-help a { text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 720px) {
  .bk-controls { gap: 1.5rem; }
  .bk-row { grid-template-columns: 1fr auto; gap: 0.4rem 1rem; padding: 1.25rem 0; }
  .bk-time { grid-column: 1; font-size: 1rem; }
  .bk-meta { grid-column: 2; grid-row: 1; }
  .bk-what { grid-column: 1 / -1; }
  .bk-cta  { grid-column: 1 / -1; justify-self: start; margin-top: 0.85rem; }
}

/* ------------------------------------------------ booking: gallery -- */

.pg-grid {
  display: grid;
  /* minmax(0, 1fr) not 1fr: plain `1fr` carries an implicit min-content floor,
     which lets a card push its column wider than the viewport on narrow
     screens. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 2.5vw, 2.5rem);
}
@media (max-width: 980px) { .pg-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .pg-grid { grid-template-columns: minmax(0, 1fr); } }

.pg-card { display: flex; flex-direction: column; min-width: 0; }
.pg-card__media {
  display: block;
  overflow: hidden;
  border-radius: var(--radius);
  aspect-ratio: 4 / 3;
  background: rgba(248, 248, 248, 0.06);
}
.pg-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .9s var(--ease); }
.pg-card:hover .pg-card__media img { transform: scale(1.04); }

.pg-card__body { display: flex; flex-direction: column; flex: 1; padding-top: 1.15rem; }
.pg-card__name { font-size: 1.15rem; letter-spacing: -0.02em; }
.pg-card__blurb {
  margin-top: 0.5rem;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: rgba(248, 248, 248, 0.68);
  flex: 1;
}
.pg-card__foot {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-top: 1.1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line-invert);
}
.pg-card__price { font-size: 1rem; font-variant-numeric: tabular-nums; }
.pg-card__meta  { font-size: 0.8125rem; color: rgba(248, 248, 248, 0.5); }
.pg-card__next  { margin-top: 0.5rem; font-size: 0.75rem; letter-spacing: .06em;
                  text-transform: uppercase; color: rgba(248, 248, 248, 0.45); }

/* Deep link landed on a session with no availability. Stated plainly rather
   than styled as an error — nothing has gone wrong, the times have just gone. */
.bk-empty--notice {
  margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
  padding: 1rem 1.15rem;
  border: 1px solid var(--line-invert);
  border-radius: var(--radius);
  background: rgba(248, 248, 248, 0.04);
}

/* ----------------------------------------------- booking: skeleton -- */

.pg-card--skel { pointer-events: none; }
.skel {
  display: block;
  border-radius: var(--radius);
  background: rgba(248, 248, 248, 0.06);
  position: relative;
  overflow: hidden;
}
.skel--line { height: 0.85rem; border-radius: 3px; margin-top: 0.85rem; }
/* Placeholder day cells while times load. Sized off .bk-date so the strip does
   not resize when the real buttons replace it. */
.bk-date--skel { display: block; min-height: 4.6rem; border: 0; }
.skel--sm   { height: 0.6rem; margin-top: 0.55rem; opacity: 0.6; }

/* Sweep rather than pulse: a travelling highlight reads as work in progress,
   where a fade in and out reads as a thing that has stalled. */
.skel::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    transparent, rgba(248, 248, 248, 0.09), transparent);
  transform: translateX(-100%);
  animation: skel-sweep 1.4s var(--ease) infinite;
}
@keyframes skel-sweep { to { transform: translateX(100%); } }

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

/* ------------------------------------------------- booking: detail -- */

.pg-back {
  display: inline-block;
  margin-bottom: 2rem;
  font-size: 0.8125rem;
  color: rgba(248, 248, 248, 0.6);
}
.pg-back:hover { color: var(--text-invert); }

/* minmax floor on the media column: an <img> at width:100% contributes almost
   no min-content, so a bare 0.9fr collapses to a thumbnail once the text
   column asks for room. */
.pg-detail {
  display: grid;
  grid-template-columns: minmax(280px, 0.9fr) 1.1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
@media (max-width: 900px) { .pg-detail { grid-template-columns: 1fr; } }

.pg-detail__media img { width: 100%; aspect-ratio: 4/5; object-fit: cover; border-radius: var(--radius); }
@media (max-width: 900px) { .pg-detail__media img { aspect-ratio: 16/9; } }

.pg-detail__note {
  margin-top: 0.9rem;
  max-width: 54ch;
  font-size: 0.875rem; line-height: 1.55;
  color: rgba(248, 248, 248, 0.55);
}
/* Subheading, not footnote: sits directly under the product title. Sized
   between the title and body copy, near-full text colour, so duration and
   price are read before the description rather than hunted for after it. */
.pg-detail__meta { margin-top: 0.6rem; font-size: clamp(1.05rem, 1.5vw, 1.25rem); letter-spacing: -0.01em; color: rgba(248, 248, 248, 0.85); }

/* The meta line used to sit between the copy and this label; with it moved up
   under the title, the label needs its own gap from the description. */
.pg-detail .bk-ctl-label { margin-top: 1.75rem; }

/* Sets the expectation before the handoff, not after it. Quiet — it is a
   footnote to the times, not a warning. */
.bk-note {
  margin-top: 1rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: rgba(248, 248, 248, 0.55);
}

/* ------------------------------------------------- booking: upsell -- */

/* Sits under the photo, so it reads as context beside the decision rather than
   an interruption in the middle of it. */
.up { margin-top: 1.25rem; }

.up__link {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  gap: 1rem;
  padding: 1rem;
  border: 1px solid var(--line-invert);
  border-radius: var(--radius);
  transition: background-color .35s var(--ease), border-color .35s var(--ease);
}
.up__link:hover { background: rgba(248, 248, 248, 0.05); border-color: rgba(248, 248, 248, 0.55); }

.up__media {
  display: block;
  overflow: hidden;
  border-radius: 4px;
  aspect-ratio: 1;
  background: rgba(248, 248, 248, 0.06);
}
/* Overrides .pg-detail__media img — the thumbnail is square, not a 4:5 plate. */
.up__media img {
  width: 100%; height: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 0;
  transition: transform .9s var(--ease);
}
.up__link:hover .up__media img { transform: scale(1.05); }

.up__body { display: flex; flex-direction: column; min-width: 0; }
.up__eyebrow {
  font-size: 0.6875rem; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(248, 248, 248, 0.45);
}
.up__name { margin-top: 0.35rem; font-size: 1.0625rem; letter-spacing: -0.02em; }
.up__line {
  margin-top: 0.4rem;
  font-size: 0.875rem; line-height: 1.5;
  color: rgba(248, 248, 248, 0.68);
}
.up__foot {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.55rem;
  margin-top: 0.85rem; padding-top: 0.75rem;
  border-top: 1px solid var(--line-invert);
}
.up__price { font-size: 0.9375rem; font-variant-numeric: tabular-nums; }
.up__note  { font-size: 0.75rem; color: rgba(248, 248, 248, 0.5); }
.up__cta {
  margin-top: 0.55rem;
  font-size: 0.75rem; letter-spacing: .06em; text-transform: uppercase;
  color: rgba(248, 248, 248, 0.45);
}
.up__link:hover .up__cta { color: var(--text-invert); }

/* Stacked, the media column would otherwise put the upsell between the photo
   and the guest/day/time controls — an offer before there is a decision to
   compare it against. `display: contents` promotes the photo and the upsell to
   grid items so they can be ordered around the body. */
@media (max-width: 900px) {
  .pg-detail__media { display: contents; }
  .pg-detail__photo { order: 1; }
  .pg-detail__body  { order: 2; }
  .up { order: 3; margin-top: 0; }
}

/* Times as a wrapping set of targets, not a list to read. */
.pg-times { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0.25rem; }
.pg-time {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.7rem 1rem;
  border: 1px solid var(--line-invert);
  border-radius: var(--radius);
  transition: background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.pg-time:hover { background: var(--bone); border-color: var(--bone); color: var(--ink); }
.pg-time__t { font-size: 0.9375rem; font-variant-numeric: tabular-nums; }
.pg-time__p { font-size: 0.8125rem; opacity: 0.75; font-variant-numeric: tabular-nums; }
/* Two registers from one badge. At four or three spots this is information —
   a party of five needs it, nobody else should feel pressured by it. At two or
   fewer it earns the accent colour, because then it genuinely is scarcity.
   Without the split, widening the threshold to four would have put an urgent
   flag on a quarter of all sessions and taught people to ignore it. */
.pg-time__s { font-size: 0.6875rem; letter-spacing: .08em; text-transform: uppercase;
              color: rgba(248, 248, 248, 0.45); }
.pg-time__s.is-urgent { color: #E8B4A0; }
.pg-time:hover .pg-time__s { color: rgba(51, 47, 47, 0.55); }
.pg-time:hover .pg-time__s.is-urgent { color: #A8542F; }

/* ------------------------------------------------ booking: reviews -- */

/* Fills the run-off below the detail grid, where the page previously just had
   dead space before the packs band. Quiet by construction — this is
   reassurance for someone mid-decision, not a section competing for attention. */
.rv {
  margin-top: clamp(3rem, 6vw, 5rem);
  padding-top: clamp(2rem, 3.5vw, 3rem);
  border-top: 1px solid var(--line-invert);
}

.rv--faq { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
/* On a product page the block sits between two ordinary sections rather than
   above the packs band, so it needs its own closing rule — otherwise the row of
   quotes just trails off into the next heading. */
.rv--standalone {
  margin-top: 0;
  padding-bottom: clamp(2rem, 3.5vw, 3rem);
  border-bottom: 1px solid var(--line-invert);
}
.rv__h { font-size: 1.15rem; letter-spacing: -0.02em; margin-bottom: 1.5rem; }

.rv__head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.7rem; }
.rv__stars { font-family: var(--font-symbol); font-size: 0.8125rem; letter-spacing: .14em; color: #E8B4A0; }
.rv__score { font-size: 0.9375rem; }
.rv__count { font-size: 0.8125rem; color: rgba(248, 248, 248, 0.5); }

.rv__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
}
@media (max-width: 780px) { .rv__grid { grid-template-columns: minmax(0, 1fr); gap: 1.75rem; } }

.rv__item blockquote {
  font-size: clamp(0.9375rem, 1.15vw, 1.0625rem);
  line-height: 1.6;
  color: rgba(248, 248, 248, 0.82);
  text-wrap: pretty;
}
/* Hanging opening quote: the mark sits in the margin so the first character of
   the sentence still lines up with the column edge. */
.rv__item blockquote::before { content: '“'; margin-left: -0.42em; }
.rv__item blockquote::after  { content: '”'; }
.rv__item .src {
  margin-top: 0.8rem;
  font-size: 0.75rem; letter-spacing: .08em; text-transform: uppercase;
  color: rgba(248, 248, 248, 0.45);
}

/* ------------------------------------------------- booking page head -- */

/* Transactional page: minimal chrome, products start almost immediately. */
.pg-head {
  padding-top: clamp(2.25rem, 4vw, 3.25rem);
  padding-bottom: clamp(1.5rem, 2.5vw, 2rem);
}
.pg-head__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.75rem, 3.4vw, 2.6rem);
  line-height: 1.05;
  letter-spacing: -0.028em;
}
.pg-section { padding-top: 0; padding-bottom: clamp(3rem, 6vw, 5rem); }

/* Numbered sequence across the full width. Four items on one row so the
   progression is visible at a glance, dropping to two then one as space runs
   out rather than squeezing four narrow columns. */
.steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.75rem);
  margin-top: clamp(2.5rem, 5vw, 4rem);
  counter-reset: none;
}
@media (max-width: 900px) { .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .steps { grid-template-columns: minmax(0, 1fr); } }

.steps li {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line-invert);
}
.steps__n {
  font-size: 0.75rem; letter-spacing: 0.14em;
  color: rgba(248, 248, 248, 0.4);
  font-variant-numeric: tabular-nums;
}
.steps__t {
  font-size: 0.9375rem; line-height: 1.55;
  color: rgba(248, 248, 248, 0.78);
  text-wrap: pretty;
}
.rd .band-light .steps li { border-color: var(--line); }
.rd .band-light .steps__t { color: var(--text-muted); }

/* Image-led feature grid. Three up, matching how these run on the live site —
   the photography is doing the selling here, so the picture leads and the copy
   sits under it rather than beside it. */
.feats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}
@media (max-width: 900px) { .feats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .feats { grid-template-columns: minmax(0, 1fr); } }

.feat { display: flex; flex-direction: column; min-width: 0; }
.feat__media {
  overflow: hidden;
  border-radius: var(--radius);
  aspect-ratio: 1;
  background: rgba(248, 248, 248, 0.06);
}
.feat__media img { width: 100%; height: 100%; object-fit: cover; }
.feat__title { margin-top: 1.15rem; font-size: 1.0625rem; letter-spacing: -0.02em; }
.feat__desc {
  margin-top: 0.5rem;
  font-size: 0.9375rem; line-height: 1.55;
  color: rgba(248, 248, 248, 0.68);
  text-wrap: pretty;
}
.rd .band-light .feat__desc { color: var(--text-muted); }

/* ------------------------------------------------------- thank you -- */

.ty-head { padding-bottom: clamp(1rem, 2vw, 1.5rem); }
.ty-lede {
  max-width: 46ch;
  margin-top: 1.15rem;
  font-size: clamp(1rem, 1.3vw, 1.125rem);
  line-height: 1.6;
  color: rgba(248, 248, 248, 0.72);
  text-wrap: pretty;
}

/* The three failure modes of a first visit — arriving late, arriving without a
   towel, looking for us at street level. Given as facts to scan, not prose to
   read, because this is the screen someone glances at on the way out. */
.ty-key {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2.5rem);
  padding-top: clamp(1.5rem, 3vw, 2.25rem);
  border-top: 1px solid var(--line-invert);
}
@media (max-width: 760px) { .ty-key { grid-template-columns: minmax(0, 1fr); gap: 1.75rem; } }

.ty-key li { display: flex; flex-direction: column; }
.ty-key__label {
  font-size: 0.6875rem; letter-spacing: .12em; text-transform: uppercase;
  color: rgba(248, 248, 248, 0.45);
}
.ty-key__val {
  margin-top: 0.5rem;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.9vw, 1.5rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
}
.ty-key__note {
  margin-top: 0.5rem;
  font-size: 0.875rem; line-height: 1.5;
  color: rgba(248, 248, 248, 0.6);
}

/* The light band inverts the surface, so the borrowed dark-theme accordion and
   list colours have to invert with it or they vanish. */
.rd .band-light .faq__q { color: var(--text); }
.rd .band-light .faq__item { border-color: var(--line); }
.rd .band-light .faq__a { color: var(--text-muted); }

/* ------------------------------------------------------ about + faqs -- */

/* Mia's letter is first-person and personal; give it a comfortable measure
   and a little more air than body copy elsewhere. */
.letter { max-width: 34em; margin-inline: auto; }
.letter p {
  font-size: clamp(1.02rem, 1.2vw, 1.15rem);
  line-height: 1.72;
  color: rgba(248, 248, 248, 0.78);
}
.letter p + p { margin-top: 1.5rem; }
.letter__lead { color: var(--text-invert) !important; }
.letter__sign { margin-top: 2rem !important; color: var(--text-invert) !important; }

.faq-jump { display: flex; flex-wrap: wrap; gap: 1.25rem; margin-top: 1.5rem; }
.faq-jump a {
  font-size: 0.8125rem;
  color: rgba(248, 248, 248, 0.6);
  padding-bottom: 0.25rem;
  border-bottom: 1px solid var(--line-invert);
}
.faq-jump a:hover { color: var(--text-invert); border-color: rgba(248,248,248,0.6); }

/* Offset anchor targets so the sticky header doesn't cover the heading. */
.faq-group { scroll-margin-top: 6rem; }

/* ----------------------------------------------------- legal / docs -- */

/* Long-form policy pages: comfortable measure, clear hierarchy, nothing
   decorative. These are read for reference, not persuasion. */
.doc { max-width: 44em; }
.doc h2 {
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-invert);
  margin-top: 3rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--line-invert);
}
.doc h2:first-of-type { margin-top: 0; }
.doc p, .doc li {
  font-size: 0.9375rem;
  line-height: 1.7;
  color: rgba(248, 248, 248, 0.72);
}
.doc p { margin-top: 1rem; }
.doc ul { margin-top: 0.75rem; padding-left: 1.1rem; list-style: disc; }
.doc li { margin-top: 0.4rem; }
.doc a { text-decoration: underline; text-underline-offset: 3px; }
.doc strong { color: var(--text-invert); font-weight: 600; }
.doc__note {
  margin-top: 1rem;
  padding: 1rem 1.25rem;
  border-left: 2px solid var(--line-invert);
  font-size: 0.875rem;
}
.doc__updated { font-size: 0.8125rem; color: rgba(248,248,248,0.45); margin-top: 2.5rem; }

/* --------------------------------------------------------- packs -- */

.pack-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(1.5rem, 3vw, 2.5rem); }
@media (max-width: 760px) { .pack-grid { grid-template-columns: minmax(0, 1fr); } }

.pack { display: flex; flex-direction: column; }
.pack__media { overflow: hidden; border-radius: var(--radius); aspect-ratio: 16/9; background: rgba(248,248,248,.06); }
.pack__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .9s var(--ease); }
.pack:hover .pack__media img { transform: scale(1.04); }

.pack__body { padding-top: 1.25rem; display: flex; flex-direction: column; align-items: flex-start; }
.pack__name { font-size: 1.25rem; letter-spacing: -0.02em; }
.pack__meta { margin-top: 0.35rem; font-size: 0.8125rem; color: rgba(248,248,248,.5); }

.pack__price { display: flex; align-items: baseline; gap: 0.75rem; margin-top: 1rem; }
.pack__total { font-size: clamp(1.6rem, 2.4vw, 2rem); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.pack__unit  { font-size: 0.875rem; color: rgba(248,248,248,.6); font-variant-numeric: tabular-nums; }

/* The per-visit saving is computed from EQ's own casual rates, not a claim. */
.pack__save {
  margin-top: 0.4rem;
  font-size: 0.6875rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #E8B4A0;
}
.pack__body .btn { margin-top: 1.5rem; }

/* ------------------------------------------- booking: week + bands -- */

.bk-week { display: flex; align-items: center; gap: 0.6rem; padding-bottom: 1.75rem; }

.bk-wk {
  flex: none;
  width: 2.4rem; height: 2.4rem;
  border: 1px solid var(--line-invert);
  border-radius: 100px;
  color: rgba(248, 248, 248, 0.75);
  transition: background-color .3s var(--ease), color .3s var(--ease),
              border-color .3s var(--ease), opacity .3s var(--ease);
}
.bk-wk:hover:not(:disabled) { background: var(--bone); border-color: var(--bone); color: var(--ink); }
.bk-wk:disabled { opacity: 0.25; cursor: default; }

/* Seven fixed columns: a real week, not a scrolling list. Days with nothing
   bookable stay visible but disabled — that is how a guest learns Yin only
   runs Wednesdays, rather than the day silently vanishing. */
.bk-week .bk-dates {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.5rem;
  flex: 1;
  overflow: visible;
  padding-bottom: 0;
}

/* An unavailable day must not look like a control. The old treatment kept the
   bordered box and only dropped it to 30% opacity, so on a phone it still read
   as a button and guests tapped it: 38 dead clicks across 24 guests on the first
   day live. Removing the border is what actually changes the affordance — a
   bordered box says press me, a bare label says this is just information. The
   rule through the date confirms it, and the higher opacity means the day is
   still legible rather than merely far away. */
.bk-date.is-off {
  opacity: 1;
  cursor: default;
  border-color: transparent;
  color: rgba(248, 248, 248, 0.38);
}
.bk-date.is-off .bk-date__num {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.bk-date.is-off:hover { color: rgba(248, 248, 248, 0.38); border-color: transparent; }

/* The day the guest just asked about. Without this the only response to the tap
   sits below the fold on a phone, which is the same silence in a longer form. */
.bk-date.is-off.is-asked {
  color: rgba(248, 248, 248, 0.7);
  border-color: var(--line-invert);
  border-style: dashed;
}

/* The answer a guest gets after tapping a day the session does not run on. */
.bk-none { color: rgba(248, 248, 248, 0.72); font-size: 0.9375rem; padding: 2rem 0 0; }
.bk-none__next {
  display: inline-block;
  margin-top: 1rem;
  padding: 0.75rem 1.25rem;
  border: 1px solid var(--line-invert);
  border-radius: var(--radius);
  color: var(--text-invert);
  font-size: 0.875rem;
  transition: background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.bk-none__next:hover { background: var(--bone); border-color: var(--bone); color: var(--ink); }

.bk-band + .bk-band { margin-top: 1.5rem; }
.bk-band__label {
  display: block;
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(248, 248, 248, 0.45);
  margin-bottom: 0.7rem;
}

@media (max-width: 620px) {
  .bk-week { gap: 0.35rem; }
  .bk-week .bk-dates { gap: 0.3rem; }
  .bk-date { min-width: 0; padding: 0.6rem 0.2rem; }
  .bk-date__mon { font-size: 0.625rem; }
}


/* --------------------------------------------------- hero social proof -- */

/* Rating is hardcoded. Source is EQ's Google Business listing, figure supplied
   by Adrian. Needs a periodic check: a stale rating undersells if it climbs,
   and "150+" leaves proof on the table once the count moves on. Could be
   pulled live from the Google Places API later. */
.proof { display: inline-flex; align-items: baseline; gap: 0.55rem; margin-bottom: 1.25rem; }
.proof__stars { font-family: var(--font-symbol); letter-spacing: 0.14em; font-size: 0.8125rem; color: #E8B4A0; }
.proof__text  { font-size: 0.8125rem; letter-spacing: 0.02em; color: rgba(248, 248, 248, 0.78); }


/* ------------------------------------------------------- partner pages -- */

/* The discount code has to survive being read off a phone and typed into
   Momence at checkout, so it is set as a bordered chip rather than inline
   text. user-select:all makes one tap select the whole code. */
/* Two cards, not three: the partner pages offer exactly two experiences, and
   the default 3-column grid left one column empty. */
.pg-grid--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 700px) { .pg-grid--two { grid-template-columns: minmax(0, 1fr); } }

/* Branded card art is 4:5. The default .pg-card__media 4:3 box cropped the
   product title off the top of the poster. */
.pg-card__media--poster { aspect-ratio: 4 / 5; }

.pg-card__name a { color: inherit; text-decoration: none; }
.pg-card__name a:hover { text-decoration: underline; text-underline-offset: 0.2em; }
.pg-card .btn-row { margin-top: 1.25rem; }

.ptnr-code {
  display: inline-flex;
  align-items: center;
  gap: 0.9rem;
  margin-top: 1.5rem;
  padding: 0.7rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.ptnr-code__label {
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(248, 248, 248, 0.5);
}
.ptnr-code__value {
  user-select: all;
  -webkit-user-select: all;
  font-size: clamp(1.05rem, 1.8vw, 1.3rem);
  letter-spacing: 0.06em;
  color: var(--text-invert, #f8f8f8);
}

/* ------------------------------------------------------------ colophon -- */

/* Agency credit. Deliberately quiet: the people who might hire ASAB are the
   ones who notice a well-made site and go looking for the credit, and they
   will find a small one. A loud one only bothers EQ's actual customers.
   It names the booking experience rather than "website by", because that is
   the part that demonstrates capability to anyone fighting their own
   scheduling embed. */
.colophon {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.colophon a {
  color: var(--text);
  border-bottom: 1px solid transparent;
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease);
}
.colophon a:hover { border-bottom-color: currentColor; }


/* On the dark footer the link needs to sit in the inverted palette. */
.rd .colophon a { color: rgba(248, 248, 248, 0.85); }
.rd .colophon a:hover { color: var(--text-invert); }


/* ------------------------------------------------------------ find us -- */
/* Transport and parking, as a mode/detail pair rather than prose. Someone
   scanning for "can I park" should find it without reading a paragraph. */
.ways {
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  display: grid;
  gap: 0;
}
.ways li {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: 1rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--line);
  font-size: 0.9375rem;
  line-height: 1.5;
}
.ways li:first-child { border-top: 1px solid var(--line); }
.ways__mode { color: var(--text-muted); }
.rd .ways li { border-color: var(--line-invert); }
.rd .ways__mode { color: rgba(248, 248, 248, 0.55); }
@media (max-width: 480px) {
  .ways li { grid-template-columns: 1fr; gap: 0.2rem; }
}

/* The map is a link, so it gets a hover state. */
.mapcard {
  display: block;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
}
.rd .mapcard { border-color: var(--line-invert); }
.mapcard img { display: block; width: 100%; height: auto; }
.mapcard:hover { border-color: var(--ink); }
.rd .mapcard:hover { border-color: rgba(248, 248, 248, 0.55); }
@media (prefers-reduced-motion: no-preference) {
  .mapcard { transition: border-color 0.4s var(--ease); }
}

/* -------------------------------------------------- the difference -- */
/* Four propositions as photo cards. Text sits over the image on a gradient
   scrim rather than underneath it, so the section reads as designed rather
   than as a caption list.

   These are NOT links, so there is deliberately no hover state. */
.diff {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.4vw, 1.25rem);
}
@media (max-width: 1000px) { .diff { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .diff { grid-template-columns: 1fr; } }

.diff__card {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  /* Portrait on the 4-up row; the images are a mix of landscape and portrait
     so they are cropped to a common shape rather than left ragged. */
  aspect-ratio: 4 / 5;
  display: flex;
}
@media (max-width: 560px) { .diff__card { aspect-ratio: 3 / 2; } }

.diff__card img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Scrim. Two stops rather than a linear fade: the copy needs a solid floor to
   sit on, but the top of the image should stay untouched. */
.diff__card::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(20, 18, 18, 0.92) 0%,
    rgba(20, 18, 18, 0.78) 28%,
    rgba(20, 18, 18, 0.15) 62%,
    rgba(20, 18, 18, 0) 100%
  );
}
.diff__body {
  position: relative;
  z-index: 1;
  margin-top: auto;
  padding: clamp(1.1rem, 2vw, 1.6rem);
  color: var(--text-invert);
}
.diff__num {
  display: block;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  color: rgba(248, 248, 248, 0.5);
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.6rem;
}
.diff__title {
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  font-weight: 400;
  line-height: 1.25;
}
.diff__line {
  margin-top: 0.5rem;
  font-size: 0.875rem;
  line-height: 1.5;
  color: rgba(248, 248, 248, 0.75);
}

/* Three-up variant, for the Signature Journey modality cards. Taller than the
   4-up row because each card carries an outcome line as well as a description. */
.diff--three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.diff--three .diff__card { aspect-ratio: 3 / 4; }

/* Stronger, taller scrim than the 4-up row. These cards carry twice the copy,
   and one of the three images (the dome) is bright cyan — the standard scrim
   left that card's text sitting on near-white. */
.diff--three .diff__card::after {
  background: linear-gradient(
    to top,
    rgba(20, 18, 18, 0.96) 0%,
    rgba(20, 18, 18, 0.9) 42%,
    rgba(20, 18, 18, 0.45) 68%,
    rgba(20, 18, 18, 0) 100%
  );
}
@media (max-width: 900px) { .diff--three { grid-template-columns: 1fr; } }
@media (max-width: 900px) { .diff--three .diff__card { aspect-ratio: 3 / 2; } }

/* The outcome. Separated by a rule rather than a gap, so "what it is" and
   "what it does" read as two distinct claims rather than one long paragraph. */
.diff__out {
  margin-top: 0.85rem;
  padding-top: 0.85rem;
  border-top: 1px solid rgba(248, 248, 248, 0.18);
  font-size: 0.875rem;
  line-height: 1.5;
  color: rgba(248, 248, 248, 0.9);
}
.diff__out-label {
  display: block;
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(248, 248, 248, 0.5);
  margin-bottom: 0.3rem;
}

/* ----------------------------------------------------- sticky booking -- */
/* Travels with the reader on product pages. Bottom-anchored, because 88% of
   traffic is mobile and the thumb is already down there. */
.stickybook {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  background: var(--ink-deep);
  border-top: 1px solid var(--line-invert);
  /* Keep clear of the iOS home indicator. */
  padding-bottom: env(safe-area-inset-bottom, 0);
  transform: translateY(100%);
}
.stickybook.is-up { transform: none; }
@media (prefers-reduced-motion: no-preference) {
  .stickybook { transition: transform 0.45s var(--ease); }
}

.stickybook__inner {
  max-width: var(--maxw);
  margin-inline: auto;
  padding-block: 0.75rem;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
}
.stickybook__name {
  color: var(--text-invert);
  font-size: 1rem;
  line-height: 1.2;
}
.stickybook__meta {
  margin-top: 0.15rem;
  display: flex;
  gap: 0.6rem;
  font-size: 0.8125rem;
  color: rgba(248, 248, 248, 0.6);
}
/* Separator only between the two, so it disappears cleanly while the price is
   still loading. */
.stickybook__price::before { content: '·'; margin-right: 0.6rem; }
.stickybook__cta { flex: none; }

@media (max-width: 480px) {
  .stickybook__inner { gap: 0.85rem; }
  .stickybook__name { font-size: 0.9375rem; }
  .stickybook__cta { padding-inline: 1.1rem; }
}

/* -------------------------------------------------- guest video rail -- */
/* Four 9:16 cards on desktop, a snap carousel on mobile. The carousel is
   native overflow scrolling rather than a library, so momentum, keyboard and
   assistive tech all behave without extra code. */
.vrail-wrap { margin-top: clamp(2.5rem, 5vw, 4rem); }

.vrail {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.4vw, 1.25rem);
}

@media (max-width: 860px) {
  .vrail {
    grid-template-columns: none;
    grid-auto-flow: column;
    /* Cards sit a little under full width so the next one peeks in and the
       carousel reads as swipeable without needing an arrow. */
    grid-auto-columns: 74%;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    /* Bleed past the wrap gutter, so a centred card is centred on screen. */
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: calc(var(--gutter) + 6%);
    overscroll-behavior-x: contain;
  }
  .vrail::-webkit-scrollbar { display: none; }
  .vcard { scroll-snap-align: center; }
}
@media (max-width: 520px) { .vrail { grid-auto-columns: 80%; padding-inline: calc(var(--gutter) + 2%); } }

.vcard__frame {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--ink-deep);
  cursor: pointer;
}
.vcard__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Play affordance, shown only while the card is not playing. Cards that are
   already running should not carry a button that implies they are not. */
.vcard__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  background: rgba(248, 248, 248, 0.92);
  pointer-events: none;
}
.vcard__play::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0;
  height: 0;
  border-left: 0.85rem solid var(--ink-deep);
  border-top: 0.55rem solid transparent;
  border-bottom: 0.55rem solid transparent;
  transform: translateX(0.12rem);
}
.vcard[data-playing="true"] .vcard__play { display: none; }

.vcard__sound {
  position: absolute;
  top: 0.65rem;
  right: 0.65rem;
  width: 2.25rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(26, 24, 24, 0.62);
  color: var(--text-invert);
  cursor: pointer;
}
.vcard__sound:hover { background: rgba(26, 24, 24, 0.85); }
/* Speaker icon. This was originally drawn with borders and pseudo-elements to
   avoid shipping an asset; it rendered as an unreadable smudge at 15px. Inline
   SVG costs nothing extra (it is in the HTML either way) and is unambiguous.

   aria-pressed on the button means "is muted", so the crossed-out icon shows
   when pressed and the sound-waves icon when not. */
.vcard__ico {
  width: 1.05rem;
  height: 1.05rem;
  fill: currentColor;
}
.vcard__ico .s {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
}
.vcard__sound[aria-pressed="true"]  .vcard__ico--on  { display: none; }
.vcard__sound[aria-pressed="false"] .vcard__ico--off { display: none; }


/* Dots: carousel only. */
.vdots { display: none; }
@media (max-width: 860px) {
  .vdots {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 1.5rem;
  }
}
.vdot {
  width: 0.5rem;
  height: 0.5rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(248, 248, 248, 0.28);
  cursor: pointer;
}
.vdot.is-on { background: rgba(248, 248, 248, 0.85); }
@media (prefers-reduced-motion: no-preference) {
  .vdot { transition: background 0.3s var(--ease); }
}

/* ------------------------------------------------- pull quote on a band -- */
/* Scrim only on the quote variant. The other full-bleed bands are pure imagery
   and should not be dimmed for no reason. */
.rd-feature--quote .rd-feature__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(20, 18, 18, 0.30) 0%,
    rgba(20, 18, 18, 0.62) 55%,
    rgba(20, 18, 18, 0.72) 100%
  );
}
.bandquote {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  align-content: center;
  justify-items: center;
  text-align: center;
  padding: clamp(1.5rem, 5vw, 3rem);
  color: var(--text-invert);
}
.bandquote blockquote {
  max-width: 22ch;
  font-size: clamp(1.35rem, 3.2vw, 2.6rem);
  line-height: 1.18;
  letter-spacing: -0.022em;
  text-wrap: balance;
}
/* Quote marks are decoration, so they hang outside the measure rather than
   indenting the first line away from the others. */
.bandquote blockquote::before { content: '\201C'; }
.bandquote blockquote::after  { content: '\201D'; }
.bandquote figcaption {
  margin-top: clamp(0.9rem, 2vw, 1.4rem);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(248, 248, 248, 0.62);
}

/* ------------------------------------------------ confirmation essentials -- */
/* The three facts that decide whether a first visit goes smoothly. Typographic
   rather than photographic on purpose: these are meant to be scanned in a few
   seconds, and an image behind them would compete with the numbers. */
.essentials {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.5vw, 1.25rem);
}
@media (max-width: 820px) { .essentials { grid-template-columns: 1fr; } }

.essential {
  padding: clamp(1.5rem, 2.5vw, 2rem);
  border: 1px solid var(--line-invert);
  border-radius: var(--radius);
}
.essential__label {
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(248, 248, 248, 0.5);
}
.essential__val {
  margin-top: 0.9rem;
  font-size: clamp(1.25rem, 2vw, 1.6rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.essential__note {
  margin-top: 0.8rem;
  font-size: 0.875rem;
  line-height: 1.55;
  color: rgba(248, 248, 248, 0.62);
}

/* --------------------------------------------------- objection answers -- */
/* First-visit questions, answered in a glance. Deliberately unillustrated:
   these are things someone is actively hunting for before they book, and a
   photo above each answer pushed the words themselves off the first screen. */
.qa {
  margin-top: clamp(2rem, 4vw, 3rem);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.4vw, 1.25rem);
}
@media (max-width: 1000px) { .qa { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .qa { grid-template-columns: 1fr; } }

.qa__item {
  padding: clamp(1.4rem, 2.2vw, 1.9rem);
  border: 1px solid var(--line-invert);
  border-radius: var(--radius);
}
.qa__q {
  font-size: 1.0625rem;
  font-weight: 400;
  line-height: 1.25;
  text-wrap: balance;
}
.qa__a {
  margin-top: 0.7rem;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: rgba(248, 248, 248, 0.7);
}

/* --------------------------------------------------------- video card -- */
/* Vertical player for the welcome walkthrough. Native controls rather than a
   custom skin: this is a utility video someone needs to scrub and replay, and
   the browser's own controls are better at that than anything bespoke. */
.vidcard {
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--ink-deep);
  /* Narrower than it looks like it wants to be. At 9:16 every 100px of width
     costs 178px of height, and the copy beside it has to hold that line. */
  max-width: 300px;
}
.vidcard__video {
  display: block;
  width: 100%;
  aspect-ratio: 9 / 16;
  object-fit: cover;
}

/* The one bolded sentence in a lede paragraph: lift it to full-strength text
   rather than adding weight, which would fight the display type above it. */
.ty-lede strong { font-weight: 400; color: var(--text-invert); }

/* ---------------------------------------------------------- scroll cue -- */
/* The welcome video is 9:16 and much taller than the copy beside it, leaving a
   screen of empty space on desktop. The cue fills it rather than shrinking the
   player.

   Placement is explicit rather than relying on source order, because the two
   layouts want different orders. Desktop: cue under the copy in column one,
   with the video spanning both rows beside it. Stacked: copy, then video, then
   cue — the cue has to come after the player it refers to, which is why it
   lives in the markup as a sibling of the video rather than inside the copy. */
.cfhead {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 5rem);
}
.cfhead__copy  { grid-column: 1; grid-row: 1; }
.cfhead__media { grid-column: 2; grid-row: 1 / span 2; }

.scrollcue {
  grid-column: 1;
  grid-row: 2;
  align-self: end;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(248, 248, 248, 0.55);
  text-decoration: none;
}
.scrollcue:hover { color: var(--text-invert); }
.scrollcue__arw {
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border: 1px solid var(--line-invert);
  border-radius: 50%;
  font-size: 0.875rem;
  flex: none;
}
.scrollcue:hover .scrollcue__arw { border-color: rgba(248, 248, 248, 0.55); }
@media (prefers-reduced-motion: no-preference) {
  .scrollcue, .scrollcue__arw { transition: color 0.3s var(--ease), border-color 0.3s var(--ease), transform 0.3s var(--ease); }
  .scrollcue:hover .scrollcue__arw { transform: translateY(3px); }
}

@media (max-width: 860px) {
  /* Single column: clear every placement so source order applies, which puts
     the cue below the video where it belongs. */
  .cfhead { grid-template-columns: 1fr; gap: 2rem; }
  .cfhead__copy, .cfhead__media, .scrollcue {
    grid-column: auto;
    grid-row: auto;
  }
  .scrollcue { align-self: start; }
}
