/* ============================================================
   KARINE S. MATTHEWS — STYLES
   Golden hour: warm cream and sand, candlelight gold + soft
   terracotta rose, editorial serif on the emotional lines.
   Vanilla CSS. Themes off :root. Mirrors the proven Goldy engine.
   ============================================================ */

/* -------- TOKENS -------- */
:root {
  /* ------------------------------------------------------------
     GOLDEN HOUR — warm cream, sand and candlelight gold.
     The surface ramp is POSITIONAL, not literal: --surface is the
     page base and --surface-3 is the most raised panel. Everything
     below reads from these tokens, so a theme pivot is a value edit
     in this block alone. No colour is hardcoded outside :root.
     ------------------------------------------------------------ */

  /* Surface — warm cream to sand */
  --surface:      #FDF8EF;
  --surface-1:    #F9F1E3;
  --surface-2:    #F4E8D6;
  --surface-3:    #EEDFC7;
  --line:         rgba(74, 52, 24, 0.14);
  --line-strong:  rgba(74, 52, 24, 0.20);

  /* Dusk band — the deep warm band that breaks up the light */
  --dusk:            #2B1D10;
  --dusk-2:          #382614;
  --dusk-text:       #FBF3E6;
  --dusk-text-body:  #E4D3BC;
  --dusk-text-muted: #B9A388;
  --dusk-line:       rgba(251, 243, 230, 0.16);

  /* Candlelight gold (accent 1) — deepened so it reads on cream */
  --gold:         #B07C24;
  --gold-warm:    #DFA84B;
  --gold-deep:    #7E5412;
  --gold-bright:  #F0CE86;   /* light gold — dusk band only */
  /* Gold TEXT on cream. --gold is a fill/line colour and only reaches 3.4:1
     as type, which fails AA. Anything readable uses this instead.
     Darkened from #8A5E15 on 2026-08-10: it cleared AA on a bare cream surface
     but NOT on a --gold-soft chip, where the tint pulls the background down and
     the service prices landed at 4.31:1 and the Coming soon badges at 4.45:1.
     Fixed at the token, as --text-muted was. Verified every one of the 33 usages
     paints on a light surface (bg luminance 0.886-0.942), so nothing regresses;
     worst case is now 4.93:1. */
  --gold-ink:     #7F5610;
  --on-gold:      #241305;   /* ink that sits ON a gold fill (buttons, chips) */
  /* The DARK END of the primary button's gradient, and only that.
     --gold-deep (#7E5412) was doing this job and it fails AA: --on-gold on it is
     2.70:1, and sampled where the label actually sits it was 3.96:1 (3.42:1 under
     the arrow) against the 4.5 a 16px/600 label needs. That is the site's main
     CTA, 19 of them. It hid from earlier sweeps because averaging a gradient's
     stops reads ~5:1 and passes — always sample the DARKEST stop under the text.
     Deliberately a separate token: --gold-deep still has to stay deep for the
     foil text gradient and the gold type that sits on cream, where lightening it
     would break contrast the other way. */
  --gold-btn-end: #AF7C24;
  --gold-soft:    rgba(176, 124, 36, 0.10);
  --gold-line:    rgba(176, 124, 36, 0.42);

  /* Warm rose / terracotta (accent 2) — the sunrise counterpoint */
  --rose:         #C0764E;
  --rose-lily:    #E9BFA4;   /* light tint — dusk band only */
  --rose-deep:    #8E4A26;
  --rose-soft:    rgba(192, 118, 78, 0.12);
  --rose-line:    rgba(192, 118, 78, 0.28);

  /* Text — deep warm brown on cream */
  --text-primary: #3A2913;
  --text-body:    #5D4629;
  --text-muted:   #745C3F;   /* darkened from #7C6446: hit 4.49:1 on the --surface-3 sand panel (AA needs 4.5) */
  --text-faint:   #8A7457;

  /* Scrims — warm overlays for imagery (replaces the old near-black) */
  --scrim:        rgba(46, 30, 14, 0.55);
  --scrim-soft:   rgba(46, 30, 14, 0.26);
  --scrim-cream:  rgba(253, 248, 239, 0.88);

  /* Panel lift — ink-alpha, so panels raise on a light surface */
  --panel-lift:       rgba(58, 41, 19, 0.045);
  --panel-lift-hover: rgba(58, 41, 19, 0.085);

  /* Drifting dust motes (shared by CSS and the hero canvas in script.js) */
  --mote:         rgba(198, 150, 74, 0.55);

  /* Type — serif display (emotion) + clean sans (UI/body) */
  --font-display: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --font-body:    'Jost', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;

  /* Rhythm */
  --gap-section:    clamp(5rem, 10vw, 9rem);
  --gap-inner:      clamp(2rem, 4vw, 4rem);
  --gap-section-tight: clamp(4rem, 7.5vw, 7rem);
  --pad-card:       clamp(1.5rem, 3.2vw, 2.1rem);
  --container:      min(1200px, 92vw);
  --container-narrow: min(880px, 92vw);

  /* Radius */
  --r-sm: 10px; --r: 16px; --r-lg: 24px; --r-xl: 32px; --r-pill: 999px;

  /* Shadow — warm, ink-tinted and low-alpha, so cards sit on cream
     without the bruised look a dark-theme shadow gives a light page */
  --shadow-card:   0 24px 60px -30px rgba(58, 41, 19, 0.28);
  --shadow-deep:   0 50px 100px -45px rgba(58, 41, 19, 0.34);
  --shadow-soft:   0 10px 30px -16px rgba(58, 41, 19, 0.18);

  /* Warm lift — a light surface cannot glow, so hover "glow" is a soft cast shadow */
  --glow-warm:     0 18px 50px -22px rgba(176, 124, 36, 0.42);
  --glow-rose:     0 18px 50px -22px rgba(192, 118, 78, 0.38);

  /* Gradients */
  --grad-foil: linear-gradient(100deg, var(--gold-deep) 0%, #C0862C 40%, var(--rose-deep) 72%, var(--gold-deep) 100%);
  --grad-foil-dusk: linear-gradient(100deg, var(--gold-bright) 0%, var(--rose-lily) 46%, var(--gold-bright) 100%);
  --grad-sunwash: radial-gradient(circle at 26% 20%, rgba(223, 168, 75, 0.16), transparent 62%),
                  radial-gradient(circle at 80% 66%, rgba(192, 118, 78, 0.12), transparent 58%);

  /* Motion */
  --ease-out:    cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-emph:   cubic-bezier(0.2, 0.7, 0.2, 1);
  --ease-float:  cubic-bezier(0.45, 0, 0.55, 1);
}

/* -------- RESET -------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--surface);
  color: var(--text-primary);
  font-family: var(--font-body);
  /* Jost has a smaller apparent size than Manrope at the same px, so body
     steps up slightly and gains a touch more leading to stay comfortable. */
  font-size: 17.5px;
  line-height: 1.68;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'kern' 1, 'liga' 1;
  font-kerning: normal;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  hyphens: none;
  word-break: keep-all;
}
img, video, canvas { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 4px; }

.skip-link {
  position: absolute; left: -999px; top: 0; z-index: 200;
  background: var(--gold); color: var(--on-gold); padding: 0.8rem 1.2rem;
  border-radius: 0 0 var(--r-sm) 0; font-weight: 700;
}
.skip-link:focus { left: 0; }

/* Type primitives */
.eyebrow {
  font-family: var(--font-body);
  /* Jost's caps read smaller than Manrope's, so up a step and tracked back */
  font-size: 0.84rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text-muted);
}
.eyebrow .dot {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--gold); margin-right: 0.7em; vertical-align: middle;
  box-shadow: 0 0 0 3px var(--gold-soft);
  animation: dotPulse 2.6s var(--ease-in-out) infinite;
}
@keyframes dotPulse { 0%,100% { opacity: 0.6; transform: scale(1); } 50% { opacity: 1; transform: scale(1.3); } }

/* Cormorant Garamond is a small-on-the-em-box, low-weight face: at Fraunces'
   sizes and weights it reads thin and undersized. Everything below is bumped
   a step in size and weight to compensate, and tracked optically - display
   sizes get NEGATIVE tracking (large type needs less air between letters),
   small uppercase gets positive. Ratios follow a ~1.25 modular scale. */
h1, h2 { font-family: var(--font-display); font-weight: 600; line-height: 1.1; letter-spacing: -0.012em; margin: 0; color: var(--text-primary); text-wrap: balance; }
h3, h4 { font-family: var(--font-display); font-weight: 600; line-height: 1.22; letter-spacing: 0; margin: 0; color: var(--text-primary); }
h2 { font-size: clamp(2.15rem, 4.6vw, 3.5rem); }
h3 { font-size: clamp(1.16rem, 1.9vw, 1.38rem); }
h4 { font-size: 1.15rem; }
p { margin: 0; color: var(--text-body); text-wrap: pretty; }

/* Emotional gold-foil accents (on <em>) */
.hero-title em, .section-head h2 em, .split em, .foil-line em {
  font-style: italic;
  font-family: var(--font-display);
  background: var(--grad-foil);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
.foil-line {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.75rem, 3.8vw, 3rem);
  line-height: 1.22; letter-spacing: -0.008em;
  color: var(--text-primary);
  margin: 0 auto 1.2rem;
  text-wrap: balance;
}
/* .foil-line is added to some section <h2>s at runtime and was silently
   downgrading them to a different size AND weight than the <h2>s that do not
   get it. Keep the heading scale when the two collide. */
h2.foil-line { font-size: clamp(2.15rem, 4.6vw, 3.5rem); font-weight: 600; line-height: 1.1; }
/* .section-head > p (0,1,1) outranks .foil-line (0,1,0), which was painting
   two of the biggest display lines on the page in muted body brown. */
.section-head > p.foil-line { color: var(--text-primary); }

/* -------- LAYOUT -------- */
.container { width: var(--container); margin-inline: auto; }
.container-narrow { width: var(--container-narrow); margin-inline: auto; }
section { padding-block: var(--gap-section); position: relative; }
.section-head { max-width: 56rem; margin: 0 auto var(--gap-inner); text-align: center; }
.section-head .eyebrow { display: inline-block; margin-bottom: 1.1rem; }
.section-head h2 { margin-bottom: 0.9rem; }
.section-head > p { color: var(--text-muted); max-width: 54ch; margin-inline: auto; }

/* Dusk bands flip the ink ramp. The page is light, so these deep warm
   bands are what keep the scroll rhythm from going flat. Everything a
   dusk band contains has to flip too, not just the headings. */
.band--dusk { background: var(--dusk); color: var(--dusk-text-body); }
.band--dusk h1, .band--dusk h2, .band--dusk h3, .band--dusk h4 { color: var(--dusk-text); }
.band--dusk p { color: var(--dusk-text-body); }
.band--dusk .foil-line { color: var(--dusk-text); }
.band--dusk .eyebrow { color: var(--dusk-text-muted); }
.band--dusk .section-head > p { color: var(--dusk-text-muted); }
/* On dusk the pale foil is the readable one, so the ramp inverts */
.band--dusk .foil-line em, .band--dusk .section-head h2 em, .band--dusk .split em,
.band--dusk .hero-title em {
  background: var(--grad-foil-dusk);
  -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
}
/* Components that sit inside a dusk band need the inverted surface too */
.band--dusk .btn-ghost { background: rgba(251, 243, 230, 0.07); color: var(--dusk-text); border-color: var(--dusk-line); }
.band--dusk .btn-ghost:hover { background: rgba(251, 243, 230, 0.13); }

/* Moon-phase divider */
.divider {
  position: relative; height: 1px; width: min(680px, 80vw); margin: 0 auto;
  background: linear-gradient(90deg, transparent 0%, var(--gold-line) 50%, transparent 100%);
  transform-origin: center; transform: scaleX(0);
  transition: transform 1.1s var(--ease-out);
}
.divider.is-in { transform: scaleX(1); }
.divider::after {
  content: '✦'; position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%); color: var(--gold-ink);
  font-size: 0.72rem; background: var(--surface); padding: 0 0.7rem;
}

/* -------- BUTTONS -------- */
.btn {
  display: inline-flex; align-items: center; gap: 0.6rem;
  padding: 1rem 1.6rem; min-height: 48px; border-radius: var(--r-pill);
  /* Jost 700 is blockier than Manrope 700; 600 at a step up sits better
     next to a Cormorant headline. */
  font-family: var(--font-body); font-weight: 600; font-size: 1rem;
  letter-spacing: 0.02em; white-space: nowrap;
  transition: transform 220ms var(--ease-out), background 220ms var(--ease-out), box-shadow 220ms var(--ease-out);
}
.btn-primary {
  background: linear-gradient(135deg, var(--gold-warm) 0%, var(--gold) 55%, var(--gold-btn-end) 100%);
  color: var(--on-gold);
  box-shadow: var(--glow-warm), inset 0 1px 0 rgba(255, 255, 255, 0.45);
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 26px 56px -18px rgba(176, 124, 36, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.55); }
/* Glass, not a tint: a 4% ink wash vanishes over the bright hero photo, so the
   ghost button carries its own cream fill and a border strong enough to hold. */
.btn-ghost {
  background: rgba(253, 248, 239, 0.78); color: var(--text-primary);
  border: 1px solid rgba(74, 52, 24, 0.28); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.btn-ghost:hover { background: rgba(253, 248, 239, 0.94); border-color: var(--gold-ink); transform: translateY(-2px); }
.btn.is-disabled { opacity: 0.5; pointer-events: none; box-shadow: none; }
.btn .arrow { display: inline-block; transition: transform 220ms var(--ease-out); }
.btn:hover .arrow { transform: translateX(4px); }

/* -------- NAV -------- */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50; padding: 1.1rem 0;
  background: linear-gradient(180deg, var(--scrim-cream) 0%, rgba(253, 248, 239, 0) 100%);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  transition: padding 240ms var(--ease-out), background 240ms var(--ease-out);
}
.nav.is-scrolled { padding: 0.7rem 0; background: var(--scrim-cream); border-bottom: 1px solid var(--line); }
.nav-inner { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; }
.brand-mark {
  font-family: var(--font-display); font-weight: 600; font-size: 1.55rem; letter-spacing: 0.1em;
  display: inline-flex; align-items: center; min-height: 44px;
  background: linear-gradient(90deg, var(--gold-deep) 0%, var(--rose-deep) 40%, var(--gold) 70%, var(--gold-deep) 100%);
  background-size: 200% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: shimmer 9s linear infinite; position: relative; z-index: 1;
}
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.nav-links { display: flex; gap: 2rem; list-style: none; margin: 0; padding: 0; }
.nav-links a { font-size: 0.9rem; color: var(--text-body); position: relative; transition: color 200ms var(--ease-out); }
.nav-links a:hover { color: var(--text-primary); }
.nav-links a::after {
  content: ''; position: absolute; left: 0; bottom: -6px; width: 100%; height: 1px;
  background: var(--gold); transform: scaleX(0); transform-origin: left; transition: transform 280ms var(--ease-out);
}
.nav-links a:hover::after { transform: scaleX(1); }
.nav-cta { display: flex; align-items: center; gap: 0.8rem; }

.burger { display: none; width: 44px; height: 44px; position: relative; }
.burger span { position: absolute; left: 11px; right: 11px; height: 1.5px; background: var(--text-primary); transition: transform 280ms var(--ease-out), opacity 200ms var(--ease-out); }
.burger span:nth-child(1) { top: 17px; }
.burger span:nth-child(2) { top: 22px; }
.burger span:nth-child(3) { top: 27px; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

.drawer {
  position: fixed; inset: 0; background: var(--surface); z-index: 49;
  padding: 6rem 8vw calc(2rem + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 0.6rem;
  transform: translateY(-100%); transition: transform 420ms var(--ease-emph);
  height: 100dvh; overflow-y: auto; overscroll-behavior: contain;
}
.drawer.is-open { transform: translateY(0); }
.drawer a {
  font-family: var(--font-display); font-weight: 500; font-size: 1.5rem; letter-spacing: -0.01em;
  padding: 0.6rem 0; min-height: 44px; border-bottom: 1px solid var(--line); color: var(--text-primary);
}
.drawer a:last-of-type { border-bottom: none; }
.drawer .btn { margin-top: 1.4rem; align-self: flex-start; color: var(--on-gold); }

/* -------- HERO (golden hour) -------- */
.hero {
  position: relative; min-height: 100vh; min-height: 100svh; min-height: 100dvh;
  display: flex; align-items: center; padding: 9rem 0 5rem; overflow: hidden; isolation: isolate;
  background: radial-gradient(120% 90% at 70% 40%, var(--surface-2) 0%, var(--surface) 62%);
}
.hero-bg { position: absolute; inset: 0; z-index: -2; }
.hero-aura { position: absolute; inset: 0; background: var(--grad-sunwash), radial-gradient(circle at 66% 46%, rgba(223, 168, 75, 0.20), transparent 62%); }
/* Sun glints on water — the daylight answer to the old starfield. Same
   radial-dot technique, warm and sparse instead of cold and scattered. */
.hero-glints {
  position: absolute; inset: 0; opacity: 0.5;
  background-image:
    radial-gradient(1.6px 1.6px at 22% 58%, rgba(223, 168, 75, 0.60), transparent),
    radial-gradient(1.2px 1.2px at 34% 66%, rgba(223, 168, 75, 0.75), transparent),
    radial-gradient(2px 2px at 47% 54%, rgba(223, 168, 75, 0.55), transparent),
    radial-gradient(1.1px 1.1px at 58% 63%, rgba(223, 168, 75, 0.7), transparent),
    radial-gradient(1.5px 1.5px at 15% 64%, rgba(223, 168, 75, 0.50), transparent),
    radial-gradient(1.3px 1.3px at 41% 72%, rgba(223, 168, 75, 0.45), transparent),
    radial-gradient(1.2px 1.2px at 66% 57%, rgba(223, 168, 75, 0.6), transparent),
    radial-gradient(1px 1px at 28% 51%, rgba(223, 168, 75, 0.40), transparent);
  animation: glint 6s var(--ease-in-out) infinite;
}
@keyframes glint { 0%,100% { opacity: 0.42; } 50% { opacity: 0.66; } }
/* Cinematic video hero: her real pendulum, graded warm and lifted for daylight */
.hero-media { position: absolute; inset: 0; background-size: cover; background-position: 20% 42%; }
.hero-video {
  /* Panned left of centre so the pendulum sits further right and clears the
     headline. Only ~10% of a 16:9 frame is croppable at this container ratio,
     so this is most of the room available. */
  width: 100%; height: 100%; object-fit: cover; object-position: 20% 44%;
  filter: brightness(1.02) saturate(1.04) contrast(0.99);
}
.hero-media::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(255, 244, 224, 0.10) 0%, rgba(253, 248, 239, 0.22) 100%);
}
/* The clip already carries its own sunrise sky + bokeh, so soften our overlays */
.hero.has-video .hero-glints { opacity: 0.16; }
.hero.has-video .hero-aura { opacity: 0.45; }
/* width/height 100% override the reset's `canvas{height:auto}` (canvas is a
   replaced element, so inset:0 alone collapses it to its intrinsic 300x150). */
.hero-motes { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; }
/* Inverted from the old night scrim: a light page needs a CREAM wash, not a
   dark one. Heaviest on the left where the headline sits, clearing to nothing
   on the right so the pendulum and the sun path stay bright and untouched. */
.hero::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(253,248,239,0.94) 0%, rgba(253,248,239,0.72) 38%, rgba(253,248,239,0.16) 68%, rgba(253,248,239,0) 100%),
    linear-gradient(180deg, rgba(253,248,239,0.58) 0%, rgba(253,248,239,0) 26%),
    radial-gradient(130% 80% at 50% 100%, rgba(253,248,239,0.72) 0%, transparent 62%);
}
/* Full container width. Capping this instead would re-centre the box (it is
   margin-inline:auto) and push the headline INTO the pendulum, so the copy
   is capped on .hero-title / .hero-sub and stays left on the gutter. */
.hero-content { position: relative; will-change: opacity, transform; }
/* Karine's banner structure: gold italic kicker, the name, then her four
   pillars as gold-dotted small caps. Wording is hers, verbatim. */
.hero-kicker {
  font-family: var(--font-display); font-style: italic; font-weight: 500;
  font-size: clamp(1.35rem, 2.2vw, 1.85rem); line-height: 1;
  letter-spacing: 0.01em; margin: 0 0 0.35rem;
  background: var(--grad-foil); background-size: 200% auto;
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
/* Her four pillars. Karine, 2026-08-10: "make that stand out more a bit more
   involved so it stands out more what it is that I am."
   Same move that worked on her business card — a step larger, a step heavier,
   and into the primary ink instead of muted brown — plus a gold hairline above
   so the row reads as a stated credential rather than a caption. The sizes are
   measured, not guessed: at 390px the four pillars wrap to three lines inside
   the 92vw container with no overflow, which is why the tracking eases off and
   the gap tightens below 640px. */
.hero-tagline {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.45rem 0.7rem;
  font-family: var(--font-body); font-size: clamp(0.9rem, 1.15vw, 1.06rem);
  font-weight: 600; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--text-primary); margin: 0 0 1.7rem;
  padding-top: 1.05rem; max-width: 34rem;
  border-top: 1px solid var(--gold-line);
}
.hero-tagline > span { position: relative; padding-bottom: 2px; }
/* A short gold underline under each pillar — the "more involved" bit. */
.hero-tagline > span::after {
  content: ''; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px;
  background: var(--grad-foil); opacity: 0.5;
}
.hero-tagline .tagline-dot {
  font-style: normal; font-size: 0.7em; line-height: 1;
  background: var(--grad-foil); -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
.hero-title {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(2.9rem, 6.9vw, 5.5rem); line-height: 1.07; letter-spacing: -0.018em; margin: 0 0 1.6rem;
  /* ch is font-relative: Cormorant's narrow zero makes 17ch far tighter than
     it was in Fraunces, so this is retuned to keep the headline on two lines
     while still clearing the pendulum. */
  max-width: 22ch;
  font-feature-settings: 'kern' 1, 'liga' 1, 'dlig' 1;
}
.hero-title .line { display: block; }
.hero-sub { font-family: var(--font-body); font-size: clamp(1.05rem, 1.5vw, 1.2rem); color: var(--text-body); max-width: 40rem; margin: 0 0 2.2rem; line-height: 1.65; }
.hero-ctas { display: flex; gap: 0.9rem; flex-wrap: wrap; }
.scroll-cue { position: absolute; bottom: 2rem; left: 50%; transform: translateX(-50%); width: 1px; height: 60px; background: linear-gradient(180deg, transparent, var(--gold)); opacity: 0.85; }
.scroll-cue::after { content: ''; position: absolute; top: 0; left: 50%; width: 5px; height: 12px; background: var(--gold); border-radius: 999px; transform: translateX(-50%); animation: scrollSlide 2.4s var(--ease-in-out) infinite; }
@keyframes scrollSlide { 0% { transform: translate(-50%, 0); opacity: 1; } 100% { transform: translate(-50%, 60px); opacity: 0; } }

/* -------- OVERTURE -------- */
.overture { position: fixed; inset: 0; z-index: 100; background: var(--surface); display: flex; align-items: center; justify-content: center; pointer-events: none; }
.overture-bloom {
  position: absolute; width: 60vmin; height: 60vmin; border-radius: 50%; filter: blur(10px); transform: scale(0);
  background: radial-gradient(circle at center, rgba(223, 168, 75, 0.42) 0%, rgba(192, 118, 78, 0.20) 32%, transparent 66%);
}
.overture-mark {
  position: relative; font-family: var(--font-display); font-weight: 400; font-style: italic;
  font-size: clamp(2.6rem, 9vw, 6rem); letter-spacing: 0.12em;
  background: var(--grad-foil); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.overture-mark .char { display: inline-block; opacity: 0; transform: translateY(20px); }

/* -------- SERVICES -------- */
.services { background: linear-gradient(180deg, var(--surface) 0%, var(--surface-1) 100%); }
.services-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 1.5rem; }
.svc-card {
  position: relative; isolation: isolate; overflow: hidden;
  padding: 2.2rem 1.9rem; display: flex; flex-direction: column; gap: 1rem;
  background: linear-gradient(180deg, var(--surface-1) 0%, var(--surface-2) 100%);
  border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-card);
  transition: transform 320ms var(--ease-out), border 320ms var(--ease-out), box-shadow 320ms var(--ease-out);
}
.svc-card:hover { transform: translateY(-6px); border-color: var(--gold-line); box-shadow: var(--glow-warm); }
.svc-card-glow {
  position: absolute; inset: -40% 30% auto; height: 60%; z-index: -1; opacity: 0; pointer-events: none;
  background: radial-gradient(circle, var(--rose-soft), transparent 70%);
  transition: opacity 400ms var(--ease-out);
}
.svc-card:hover .svc-card-glow { opacity: 1; }
.svc-name { font-family: var(--font-display); font-weight: 500; font-size: 1.4rem; line-height: 1.15; letter-spacing: -0.01em; }
.svc-modality { font-size: 0.82rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--gold-ink); }
.svc-blurb { font-size: 1.02rem; color: var(--text-body); line-height: 1.6; }
.svc-options { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: auto; }
.svc-opt {
  display: inline-flex; align-items: baseline; gap: 0.4rem; padding: 0.5rem 0.85rem;
  border: 1px solid var(--gold-line); border-radius: var(--r-pill); background: var(--gold-soft);
}
.svc-opt-label { font-size: 0.82rem; color: var(--text-muted); }
.svc-opt-price { font-family: var(--font-display); font-weight: 600; color: var(--gold-ink); font-size: 1.1rem; }
.svc-price-enquire { margin-top: auto; font-family: var(--font-display); font-style: italic; font-weight: 500; color: var(--rose-deep); font-size: 1.05rem; }
.svc-cta { display: flex; flex-direction: column; gap: 0.7rem; margin-top: 0.4rem; }
.svc-cta .btn { justify-content: center; }
.svc-link { font-size: 0.85rem; color: var(--text-muted); text-align: center; display: flex; align-items: center; justify-content: center; min-height: 44px; transition: color 200ms var(--ease-out); }
.svc-link:hover { color: var(--gold-ink); }

/* -------- REIKI SUPPORTS -------- */
.supports { background: var(--surface-1); }
.supports-grid {
  list-style: none; padding: 0; margin: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: 0.8rem;
  max-width: 940px; margin-inline: auto;
}
.support-chip {
  padding: 1.1rem 1.3rem; background: var(--panel-lift); border: 1px solid var(--line);
  border-radius: var(--r); font-size: 0.98rem; color: var(--text-body); position: relative; padding-left: 2.6rem;
  transition: border 200ms var(--ease-out), background 200ms var(--ease-out);
}
.support-chip::before {
  content: ''; position: absolute; left: 1.1rem; top: 50%; transform: translateY(-50%);
  width: 8px; height: 8px; border-radius: 50%; background: var(--rose); box-shadow: none;
}
.support-chip:hover { border-color: var(--rose-line); background: var(--rose-soft); }

/* -------- JOURNEY (dusk band) -------- */
.journey { overflow: hidden; }
.journey .section-head { margin-bottom: var(--gap-inner); }
.journey-track-wrap { position: relative; height: 100vh; display: flex; align-items: center; }
.journey-track { display: flex; gap: 2vw; padding-inline: 4vw; will-change: transform; }
.journey-card {
  flex: 0 0 min(420px, 78vw); background: var(--dusk-2); border: 1px solid var(--dusk-line);
  border-radius: var(--r-lg); padding: 2.2rem; box-shadow: inset 0 1px 0 rgba(251, 243, 230, 0.06);
  display: flex; flex-direction: column; gap: 0.8rem;
}
.journey-step { font-family: var(--font-display); font-weight: 500; font-size: 3rem; line-height: 1; background: var(--grad-foil-dusk); -webkit-background-clip: text; background-clip: text; color: transparent; }
.journey-card-title { font-size: 1.3rem; color: var(--dusk-text); }
.journey-card-body { color: var(--dusk-text-body); font-size: 1.02rem; line-height: 1.6; }
.journey-modes { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-top: 3rem; }
.mode-card {
  display: flex; gap: 1.1rem; align-items: flex-start; padding: 1.6rem 1.8rem;
  background: var(--dusk-2); border: 1px solid var(--dusk-line); border-radius: var(--r-lg);
}
.mode-glyph { flex: 0 0 auto; width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center; background: rgba(233, 191, 164, 0.12); color: var(--rose-lily); }
.mode-glyph svg { width: 24px; height: 24px; }
.mode-title { color: var(--dusk-text); margin-bottom: 0.3rem; }
.mode-body { color: var(--dusk-text-body); font-size: 1rem; line-height: 1.55; }

/* -------- PENDULUM SHOP -------- */
.shop { background: linear-gradient(180deg, var(--surface-1) 0%, var(--surface) 100%); }
/* --- The pendulum RAIL (2026-08-10) ------------------------------------
   Karine's ten pendulums scroll sideways INSIDE their own container. This is a
   native overflow-x scroller, not a pinned GSAP track: the page keeps scrolling
   vertically straight past it, which is exactly what Nicholas asked for.
     • `overscroll-behavior-x: contain` stops a horizontal fling chaining into
       browser back-navigation.
     • NO `touch-action` override — setting it here would swallow vertical page
       scroll on mobile (the trap documented on the Goldy condition slider).
     • `overflow-y: hidden` keeps the rail from ever growing its own vertical
       scrollbar; the block padding is what gives the card hover-lift and its
       drop shadow room to breathe instead.
     • The page itself must never scroll horizontally, so the rail lives inside
       .container and only the track overflows.
   ---------------------------------------------------------------------- */
.rail { position: relative; }
.rail-track {
  /* Card width is a token so one rail implementation serves several sections:
     the shop wants a compact product card, the reviews want a wider column so
     Karine's paragraphs do not turn into a ladder of three-word lines. */
  --rail-card: min(17.5rem, 76vw);
  display: flex; gap: 1.5rem;
  overflow-x: auto; overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 0.25rem;
  padding-block: 0.6rem 2.2rem;      /* room for the -6px hover lift + card shadow */
  padding-inline: 0.25rem;
  scrollbar-width: thin;
  scrollbar-color: var(--gold-line) transparent;
  /* Edge fade: the content itself feathers out, so it works over the section's
     gradient without pinning a colour. The two custom properties are toggled by
     .at-start / .at-end so a fully-scrolled end never sits behind a soft edge. */
  --fade-l: 0px; --fade-r: 2.5rem;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, rgb(0 0 0) var(--fade-l), rgb(0 0 0) calc(100% - var(--fade-r)), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, rgb(0 0 0) var(--fade-l), rgb(0 0 0) calc(100% - var(--fade-r)), transparent 100%);
}
.rail-track.at-start { --fade-l: 0px; }
.rail-track:not(.at-start) { --fade-l: 2.5rem; }
.rail-track.at-end { --fade-r: 0px; }
.rail-track::-webkit-scrollbar { height: 6px; }
.rail-track::-webkit-scrollbar-track { background: transparent; }
.rail-track::-webkit-scrollbar-thumb { background: var(--gold-line); border-radius: 999px; }
.rail-track:focus-visible { outline: 2px solid var(--gold-ink); outline-offset: 4px; border-radius: var(--r); }
.rail-track > * { scroll-snap-align: start; flex: 0 0 var(--rail-card); }
.rail-track--voices { --rail-card: min(24rem, 84vw); }

/* Prev/next sit above the track, before it in the tab order, so keyboard users
   meet the controls first and every Order-by-text button stays reachable after.
   Hidden on touch, where the native swipe is the better affordance. */
.rail-controls { display: flex; justify-content: flex-end; gap: 0.6rem; margin-bottom: 0.9rem; }
.rail-btn {
  width: 44px; height: 44px; display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--gold-line); border-radius: 50%;
  cursor: pointer; color: var(--gold-ink);
  transition: background 200ms var(--ease-out), border-color 200ms var(--ease-out), transform 200ms var(--ease-out);
}
.rail-btn:hover { background: var(--gold-soft); border-color: var(--gold-ink); transform: translateY(-2px); }
.rail-btn:focus-visible { outline: 2px solid var(--gold-ink); outline-offset: 3px; }
/* aria-disabled, not `disabled`: a disabled button drops focus the instant you
   reach the end of the rail, which orphans the keyboard user. */
.rail-btn[aria-disabled="true"] { opacity: 0.34; cursor: default; transform: none; background: var(--surface); border-color: var(--line-strong); }
.rail-arrow { width: 10px; height: 10px; border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor; }
.rail-arrow-prev { transform: translateX(2px) rotate(135deg); }
.rail-arrow-next { transform: translateX(-2px) rotate(-45deg); }
@media (hover: none) {
  .rail-controls { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  /* No animated snap-back and no smooth glide; everything stays reachable. */
  .rail-track { scroll-snap-type: none; scroll-behavior: auto; }
  .rail-btn { transition: none; }
  .rail-btn:hover { transform: none; }
}

.pendulum-card {
  display: flex; flex-direction: column; gap: 0.7rem; padding: 1.4rem;
  background: linear-gradient(180deg, var(--surface-1) 0%, var(--surface-2) 100%);
  border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-card);
  transition: transform 320ms var(--ease-out), border 320ms var(--ease-out), box-shadow 320ms var(--ease-out);
}
.pendulum-card:hover { transform: translateY(-6px); border-color: var(--gold-line); box-shadow: var(--glow-warm); }
.pendulum-media { position: relative; aspect-ratio: 1 / 1; border-radius: var(--r); overflow: hidden; background: var(--surface-3); isolation: isolate; }
.pendulum-media::after { content: ''; position: absolute; inset: 0; background: radial-gradient(circle at 50% 40%, var(--rose-soft), transparent 70%); pointer-events: none; }
.pendulum-media img { width: 100%; height: 100%; object-fit: cover; position: relative; z-index: 1; }
.pendulum-flag { position: absolute; top: 0.8rem; left: 0.8rem; z-index: 2; padding: 3px 10px; background: var(--scrim-cream); border: 1px solid var(--line-strong); color: var(--text-muted); font-size: 0.76rem; letter-spacing: 0.08em; text-transform: uppercase; border-radius: 999px; }
.pendulum-name { font-family: var(--font-display); font-weight: 500; font-size: 1.2rem; }
.pendulum-material { font-size: 0.8rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--gold-ink); }
.pendulum-blurb { font-size: 0.98rem; color: var(--text-body); line-height: 1.55; }
.pendulum-price { font-family: var(--font-display); font-weight: 600; font-size: 1.5rem; color: var(--gold-ink); margin-top: auto; }
.pendulum-price small { font-size: 0.55em; color: var(--text-muted); font-weight: 500; letter-spacing: 0.05em; }
.pendulum-card .btn { justify-content: center; }

/* -------- ATMOSPHERE / GALLERY -------- */
.atmosphere { background: var(--surface); }
/* ⚠️ 2026-08-10 — DO NOT PUT A FIXED ROW HEIGHT BACK ON THIS GRID.
   It used to be `grid-template-columns: repeat(3,1fr); grid-auto-rows: 240px`
   with `object-fit: cover`, which forced every tile to one aspect ratio no
   matter which way the photo was shot. Measured at 1440px: tiles came out
   309 x 205 (1.51:1), so her PORTRAIT shots (1066 x 1600, 0.67:1) showed only
   44% of their height, the portrait in the `wide` tile showed 19%, and the
   landscape in the `tall` tile showed 45% of its width. On a phone the single
   column was closer to square so it read as "fine on iPhone, broken on laptop".
   Two bugs compounded it: the UA `figure { margin: 1em 40px }` was never reset,
   which is why the tiles were 309 wide inside 389px columns.
   This is now a masonry column layout: every tile takes the photo's OWN height
   and nothing is cropped at any width. */
.atmosphere-grid { columns: 3; column-gap: 1rem; }
.atmosphere-tile {
  position: relative; overflow: hidden; border-radius: var(--r);
  background: var(--surface-1); border: 1px solid var(--line); isolation: isolate;
  margin: 0 0 1rem;                 /* also resets the UA figure margin */
  break-inside: avoid; -webkit-column-break-inside: avoid;
  display: block; width: 100%;
}
.atmosphere-tile img { display: block; width: 100%; height: auto; transition: transform 800ms var(--ease-out); }
.atmosphere-tile:hover img { transform: scale(1.04); }
.atmosphere-tile::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 58%, rgba(253, 248, 239, 0.55) 100%); pointer-events: none; }
.atmosphere-tile .tag { position: absolute; bottom: 0.9rem; left: 0.9rem; z-index: 1; padding: 4px 9px; background: rgba(253, 248, 239, 0.86); border: 1px solid var(--gold-line); color: var(--gold-ink); font-size: 0.76rem; letter-spacing: 0.08em; text-transform: uppercase; border-radius: 999px; backdrop-filter: blur(6px); }

/* -------- VOICES / TESTIMONIALS -------- */
.voices { background: linear-gradient(180deg, var(--surface) 0%, var(--surface-1) 100%); }
/* The reviews live in a .rail (see the PENDULUM SHOP block for the mechanics).
   They were a grid until 2026-08-11; the grid equalised ROW heights, so the
   tallest quote (~765px) left a crater beside every short one. */
.voice-card { background: var(--surface); box-shadow: var(--shadow-soft); border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--pad-card); display: flex; flex-direction: column; gap: 0.9rem; }
.voice-quote-mark { font-family: var(--font-display); font-size: 2.4rem; line-height: 0.5; color: var(--gold-ink); }
.voice-quote { font-family: var(--font-display); font-weight: 500; font-size: 1.28rem; line-height: 1.5; color: var(--text-primary); }
/* margin-top:auto pins the attribution to the bottom edge: rail cards stretch
   to the tallest in the row, so a short quote reads as deliberate rather than
   half-empty. */
.voice-meta { display: flex; flex-direction: column; gap: 0.15rem; margin-top: auto; border-top: 1px solid var(--line); padding-top: 0.9rem; }
.voice-name { color: var(--text-primary); font-weight: 700; font-size: 0.92rem; }
.voice-service { color: var(--text-muted); font-size: 0.8rem; }
/* Source line: only on quotes the reviewer chose to publish themselves. The
   privately texted reflections stay anonymous and carry nothing here, which is
   how Karine's "kept anonymous unless they published it" policy reads on-page. */
.voice-source {
  display: flex; align-items: center; gap: 0.42rem;
  margin-top: 0.15rem; color: var(--gold-ink);
  font-size: 0.76rem; letter-spacing: 0.04em;
}
.voice-source-dot { flex: none; width: 5px; height: 5px; border-radius: 50%; background: var(--gold); }

/* --- Long reviews: clamp, never truncate -------------------------------
   Kel S. writes 673 characters; on the old grid that quote set the row height
   for everyone. In the rail the quote clamps to eight lines and opens IN PLACE,
   so her reviewers' words are always fully readable — no ellipsis that leads
   nowhere. The clamp is `max-height` + a mask rather than a nested scroller on
   purpose: a scrollable box inside the card would swallow vertical page scroll
   the moment a thumb landed on it, which is the exact thing this rail must not
   do. Clipped text stays in the DOM and in the accessibility tree.
   JS measures and only marks a card `.is-clamped` when it actually overflows. */
/* A rail stretches every card to the tallest, so a short quote would sit at the
   top of a tall card with a crater beneath it (very visible at 390). Free space
   is split above and below instead, which reads as deliberate centring. Only
   short quotes get this — a clamped one already fills its card. The quote mark
   travels with its text so the two stay one optical block. */
.voice-card:not(.is-clamped) .voice-quote-mark { margin-top: auto; }
.voice-card:not(.is-clamped) .voice-quote { margin-bottom: auto; }
.voice-card:not(.is-clamped) .voice-meta { margin-top: 0; }
.voice-card.is-clamped .voice-quote {
  max-height: 12em;                   /* 8 lines at line-height 1.5 */
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, rgb(0 0 0) calc(100% - 3.4em), transparent 100%);
          mask-image: linear-gradient(180deg, rgb(0 0 0) calc(100% - 3.4em), transparent 100%);
}
.voice-card.is-clamped.is-open .voice-quote {
  max-height: none; overflow: visible;
  -webkit-mask-image: none; mask-image: none;
}
.voice-more {
  display: none; align-self: flex-start;
  min-height: 44px; padding: 0 0.1rem;
  align-items: center; gap: 0.35rem;
  background: none; border: 0; cursor: pointer;
  font-family: var(--font-body); font-size: 0.84rem; letter-spacing: 0.04em;
  color: var(--gold-ink); text-decoration: underline; text-underline-offset: 4px;
}
.voice-card.is-clamped .voice-more { display: inline-flex; }
.voice-more:focus-visible { outline: 2px solid var(--gold-ink); outline-offset: 3px; border-radius: var(--r-sm); }
.voice-more-chev { width: 8px; height: 8px; border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor; transform: translateY(-2px) rotate(45deg); }
.voice-card.is-open .voice-more-chev { transform: translateY(1px) rotate(-135deg); }
.voice-proof { align-items: flex-start; gap: 0.5rem; }
.voice-metric { font-family: var(--font-display); font-weight: 500; font-size: 1.7rem; background: var(--grad-foil); -webkit-background-clip: text; background-clip: text; color: transparent; }
.voice-label { font-size: 0.82rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.voice-sub { color: var(--text-body); font-size: 1rem; line-height: 1.55; }

/* -------- ABOUT -------- */
.about { background: linear-gradient(180deg, var(--surface-1) 0%, var(--surface) 100%); }
.about-grid { display: grid; grid-template-columns: 1fr 1.1fr; gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.about-portrait { aspect-ratio: 4/5; border-radius: var(--r-lg); overflow: hidden; border: 1px solid var(--line-strong); position: relative; background: var(--surface-3); box-shadow: var(--shadow-deep); }
.about-portrait img { width: 100%; height: 100%; object-fit: cover; }
.about-portrait::before { content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: radial-gradient(circle at 50% 30%, var(--rose-soft), transparent 70%); animation: breathe 7s var(--ease-in-out) infinite; }
@keyframes breathe { 0%,100% { opacity: 0.5; transform: scale(1); } 50% { opacity: 0.9; transform: scale(1.05); } }
.about-portrait::after { content: ''; position: absolute; inset: 0; z-index: 1; background: linear-gradient(190deg, transparent 62%, rgba(253, 248, 239, 0.42) 100%); pointer-events: none; }
.about-portrait.is-empty { display: grid; place-items: center; }
.portrait-note { position: relative; z-index: 2; color: var(--text-faint); font-family: var(--font-display); font-style: italic; font-weight: 500; font-size: 0.9rem; letter-spacing: 0.04em; text-align: center; padding: 1rem; }
.about-text .eyebrow { margin-bottom: 1rem; }
.about-text h2 { margin-bottom: 0.9rem; }
.about-text p { margin-bottom: 1rem; font-size: 1.06rem; line-height: 1.7; }
.about-signature { font-family: var(--font-display); font-style: italic; font-weight: 500; color: var(--gold-ink); font-size: 1.3rem; margin-top: 1.5rem; }

/* -------- SACRED CONTENT + SOCIALS -------- */
.sacred { background: var(--surface); }
.sacred .section-head { max-width: 44rem; }
.sacred-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.2rem; margin-bottom: var(--gap-inner); }
.sacred-card { padding: var(--pad-card); background: linear-gradient(180deg, var(--surface-1) 0%, var(--surface-2) 100%); border: 1px solid var(--line); border-radius: var(--r-lg); display: flex; flex-direction: column; gap: 0.7rem; transition: transform 320ms var(--ease-out), border 320ms var(--ease-out); }
.sacred-card:hover { transform: translateY(-6px); border-color: var(--gold-line); box-shadow: var(--glow-warm); }
.sacred-glyph { width: 40px; height: 40px; color: var(--gold-ink); }
.sacred-glyph svg { width: 100%; height: 100%; }
.sacred-card-title { font-size: 1.08rem; }
.sacred-card-body { color: var(--text-body); font-size: 1rem; line-height: 1.55; }
.sacred-socials { display: flex; flex-wrap: wrap; gap: 0.8rem; justify-content: center; }
.social-pill { display: inline-flex; align-items: center; gap: 0.7rem; padding: 0.8rem 1.3rem; min-height: 48px; border: 1px solid var(--line-strong); border-radius: var(--r-pill); background: var(--panel-lift); transition: border 200ms var(--ease-out), background 200ms var(--ease-out), transform 200ms var(--ease-out); }
.social-pill:hover { border-color: var(--rose-line); background: var(--rose-soft); transform: translateY(-2px); }
.social-glyph { color: var(--rose-deep); display: grid; place-items: center; }
.social-meta { display: flex; flex-direction: column; }
.social-label { font-size: 0.76rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
.social-handle { font-family: var(--font-display); font-weight: 600; color: var(--text-primary); font-size: 0.98rem; }

/* -------- FAQ -------- */
.faq { background: linear-gradient(180deg, var(--surface) 0%, var(--surface-1) 100%); }
.faq-list { max-width: 760px; margin: 0 auto; display: grid; gap: 0.7rem; }
.faq-item { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; transition: border 220ms var(--ease-out); }
.faq-item[open] { border-color: var(--gold-line); background: linear-gradient(180deg, var(--surface-1) 0%, var(--gold-soft) 100%); }
.faq-q { font-family: var(--font-display); font-weight: 600; font-size: 1.08rem; padding: 1.2rem 1.4rem; min-height: 44px; cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.faq-q::-webkit-details-marker { display: none; }
.faq-q::after { content: '+'; font-family: var(--font-body); font-size: 1.4rem; font-weight: 400; color: var(--gold-ink); transition: transform 240ms var(--ease-out); }
.faq-item[open] .faq-q::after { transform: rotate(45deg); }
.faq-a { padding: 0 1.4rem 1.4rem; color: var(--text-body); font-size: 1.04rem; line-height: 1.65; }

/* -------- CTA STRIP -------- */
.cta-strip { padding-block: var(--gap-section-tight); background: var(--surface-1); text-align: center; position: relative; overflow: hidden; }
.cta-strip::before { content: ''; position: absolute; inset: 0; background: radial-gradient(50% 90% at 50% 0%, rgba(223, 168, 75, 0.18) 0%, transparent 60%); pointer-events: none; }
.cta-strip .eyebrow { display: inline-block; margin-bottom: 1.2rem; position: relative; }
.cta-strip .foil-line { position: relative; margin-bottom: 1rem; font-size: clamp(2rem, 4.5vw, 3.2rem); }
.cta-strip > .container > p { color: var(--text-body); max-width: 50ch; margin: 0 auto 2rem; position: relative; }
.cta-strip-ctas { display: inline-flex; gap: 0.8rem; flex-wrap: wrap; justify-content: center; position: relative; }

/* -------- CONTACT -------- */
.contact-side > .eyebrow { display: inline-block; }
.contact-channels { display: grid; gap: 0.7rem; }
.channel { display: flex; align-items: center; gap: 0.9rem; padding: 1rem 1.2rem; min-height: 48px; border-radius: var(--r); background: var(--surface-1); border: 1px solid var(--line); transition: border 200ms var(--ease-out), background 200ms var(--ease-out); }
.channel:hover { border-color: var(--gold-line); background: linear-gradient(180deg, var(--surface-1), var(--gold-soft)); }
.channel-icon { width: 38px; height: 38px; border-radius: 10px; background: var(--gold-soft); color: var(--gold-ink); display: grid; place-items: center; flex: 0 0 auto; }
.channel-meta { display: flex; flex-direction: column; }
.channel-label { font-size: 0.76rem; color: var(--text-muted); letter-spacing: 0.05em; text-transform: uppercase; }
.channel-value { font-family: var(--font-display); font-weight: 600; color: var(--text-primary); font-size: 1.02rem; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem; }
.form-submit { margin-top: 0.4rem; }
.form-submit .btn { width: 100%; justify-content: center; }
.form-note { margin-top: 0.9rem; font-size: 0.82rem; color: var(--text-muted); text-align: center; }

/* -------- FOOTER -------- */
/* The footer is a dusk surface, so it takes the dusk ink ramp — the light
   theme's muted brown would only reach 2.9:1 down here. */
.footer { background: var(--dusk); border-top: 1px solid var(--dusk-line); padding: 4rem 0 2rem; }
.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 2rem; margin-bottom: 3rem; }
.footer h3 { font-family: var(--font-body); font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--dusk-text-muted); margin-bottom: 1rem; }
.footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.4rem; }
.footer a { color: var(--dusk-text-body); font-size: 0.92rem; display: inline-flex; align-items: center; padding: 0.6rem 0; min-height: 44px; transition: color 180ms var(--ease-out); }
.footer a:hover { color: var(--gold-bright); }
.footer-tag { font-family: var(--font-display); font-weight: 500; font-size: 1.15rem; letter-spacing: 0.02em; background: var(--grad-foil-dusk); -webkit-background-clip: text; background-clip: text; color: transparent; margin-bottom: 0.8rem; }
.footer-blurb { color: var(--dusk-text-muted); font-size: 0.9rem; max-width: 34ch; }
.footer-bottom { display: flex; justify-content: space-between; align-items: center; padding-top: 1.6rem; border-top: 1px solid var(--dusk-line); font-size: 0.82rem; color: var(--dusk-text-muted); flex-wrap: wrap; gap: 0.8rem; }

/* -------- FLOATING MESSAGE (mobile) -------- */
.float-call { position: fixed; bottom: calc(1.2rem + env(safe-area-inset-bottom)); right: calc(1.2rem + env(safe-area-inset-right)); z-index: 40; width: 56px; height: 56px; border-radius: 50%; background: linear-gradient(135deg, var(--gold-warm), var(--gold-deep)); color: var(--on-gold); display: none; align-items: center; justify-content: center; box-shadow: var(--glow-warm); transform: translateY(20px) scale(0.9); opacity: 0; transition: transform 320ms var(--ease-out), opacity 320ms var(--ease-out); }
.float-call.is-visible { transform: translateY(0) scale(1); opacity: 1; }

/* -------- CURSOR GLOW (desktop only, via JS) -------- */
/* `screen` is a no-op over near-white, so on the light theme the cursor
   warmth is a soft `multiply` wash instead of an additive glow. */
.cursor-glow { position: fixed; top: 0; left: 0; width: 260px; height: 260px; border-radius: 50%; background: radial-gradient(circle, rgba(223, 168, 75, 0.18) 0%, rgba(192, 118, 78, 0.10) 40%, transparent 62%); pointer-events: none; z-index: 30; mix-blend-mode: multiply; transform: translate(-50%, -50%); opacity: 0; transition: opacity 240ms var(--ease-out); will-change: transform, opacity; }
body.has-cursor .cursor-glow { opacity: 1; }

/* -------- REVEAL UTILS -------- */
.has-js [data-reveal] { opacity: 0; transform: translateY(28px); transition: opacity 800ms var(--ease-out), transform 800ms var(--ease-out); }
.has-js [data-reveal].is-in { opacity: 1; transform: translateY(0); }
.has-js .foil-line { opacity: 0; transform: translateY(20px); transition: opacity 800ms var(--ease-out), transform 800ms var(--ease-out); }
.has-js .foil-line.is-in { opacity: 1; transform: none; }

/* SplitText (word-level, hand-rolled) */
.split-word { display: inline-block; overflow: hidden; vertical-align: top; }
.split-word > span { display: inline-block; transform: translateY(110%); transition: transform 700ms var(--ease-emph); }
.has-js .split.is-in .split-word > span { transform: translateY(0); }

/* -------- RESPONSIVE -------- */
@media (max-width: 1024px) {
  .nav-links { display: none; }
  .nav-cta .btn { display: none; }   /* burger + drawer carry the Book CTA on mobile */
  .burger { display: block; }
  .sacred-grid { grid-template-columns: repeat(2, 1fr); }
  .about-grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .contact-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .atmosphere-grid { columns: 2; }
  .journey-modes { grid-template-columns: 1fr; }

  /* Journey: unpin and stack vertically (pin+scrub broken on iOS Safari with Lenis) */
  .journey-track-wrap { height: auto; display: block; }
  .journey-track { flex-direction: column; padding-inline: 0; gap: 1.2rem; transform: none !important; }
  .journey-card { flex: 1 1 auto; width: 100%; }

  /* No hover on touch → drop promoted layers that cost GPU memory for zero benefit */
  .atmosphere-tile { will-change: auto; }
}

@media (max-width: 640px) {
  body { font-size: 16.5px; }
  .hero { padding-top: 7.5rem; padding-bottom: 4rem; }
  .scroll-cue { display: none; }
  .sacred-grid { grid-template-columns: 1fr; }
  .atmosphere-grid { columns: 1; }
  .footer-grid { grid-template-columns: 1fr; }
  .field-row { grid-template-columns: 1fr; }
  .contact-side h2 { text-align: center; }
  .float-call { display: flex; }
  /* 16px minimum stops iOS Safari auto-zooming the page on input focus */
}

/* -------- REDUCED MOTION -------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .has-js [data-reveal], .has-js .foil-line, .has-js .split-word > span { opacity: 1 !important; transform: none !important; }
  .hero-motes, .cursor-glow, .overture { display: none !important; }
  .hero-glints, .scroll-cue, .brand-mark, .about-portrait::before, .eyebrow .dot { animation: none !important; }
}

/* ============================================================
   COMING SOON
   ============================================================ */
.coming-soon { background: linear-gradient(180deg, var(--surface) 0%, var(--surface-1) 100%); }
.coming-soon .section-head { max-width: 44rem; }
.cs-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; max-width: 820px; margin: 0 auto var(--gap-inner); }
.cs-card { padding: var(--pad-card); background: linear-gradient(180deg, var(--surface-1), var(--surface-2)); border: 1px solid var(--line); border-radius: var(--r-lg); display: flex; flex-direction: column; gap: 0.7rem; }
.cs-glyph { width: 40px; height: 40px; color: var(--rose-deep); }
.cs-glyph svg { width: 100%; height: 100%; }
.cs-title { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; font-size: 1.15rem; }
.cs-badge { font-family: var(--font-body); font-size: 0.74rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold-ink); border: 1px solid var(--gold-line); background: var(--gold-soft); padding: 3px 8px; border-radius: 999px; }
.cs-body { color: var(--text-body); font-size: 1.02rem; line-height: 1.6; }
.cs-cta { text-align: center; }

/* ============================================================
   BOOKING BUILDER
   ============================================================ */
.booking { background: var(--surface); }
.booking-grid { display: grid; grid-template-columns: 1.35fr 1fr; gap: clamp(1.6rem, 4vw, 3.2rem); align-items: start; }
.booking-form { background: var(--surface-1); border: 1px solid var(--line); border-radius: var(--r-lg); padding: clamp(1.4rem, 3vw, 2.4rem); display: grid; gap: 1.1rem; }
.bk-field { border: 0; margin: 0; padding: 0; display: grid; gap: 0.5rem; min-inline-size: 0; }
.bk-field legend, .bk-field > label { font-size: 0.9rem; font-weight: 600; color: var(--text-primary); letter-spacing: 0.01em; padding: 0; }
.bk-field input[type="text"], .bk-field input[type="tel"], .bk-field textarea {
  width: 100%; padding: 0.85rem 1rem; background: var(--panel-lift); border: 1px solid var(--line);
  border-radius: var(--r-sm); color: var(--text-primary); font: inherit; font-size: 0.96rem;
  transition: border 180ms var(--ease-out), background 180ms var(--ease-out);
}
.bk-field input:focus, .bk-field textarea:focus { border-color: var(--gold-ink); background: var(--gold-soft); outline: none; }
.bk-field textarea { min-height: 84px; resize: vertical; }
.bk-sessions { display: grid; gap: 0.6rem; }
.bk-session { position: relative; display: flex; align-items: center; gap: 1rem; padding: 0.95rem 1.1rem; border: 1px solid var(--line); border-radius: var(--r); cursor: pointer; transition: border 180ms var(--ease-out), background 180ms var(--ease-out); }
.bk-session input { position: absolute; opacity: 0; width: 0; height: 0; }
.bk-session::before { content: ''; width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--line-strong); flex: 0 0 auto; transition: border 180ms var(--ease-out), box-shadow 180ms var(--ease-out); }
.bk-session-main { flex: 1; display: flex; flex-direction: column; gap: 0.1rem; }
.bk-session-title { font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; color: var(--text-primary); }
.bk-session-dur { font-size: 0.82rem; color: var(--text-muted); }
.bk-session-note { font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--rose-deep); margin-top: 0.15rem; }
.bk-session-price { font-family: var(--font-display); font-weight: 600; color: var(--gold-ink); }
.bk-session.is-selected { border-color: var(--gold-line); background: var(--gold-soft); }
.bk-session.is-selected::before { border-color: var(--gold-ink); box-shadow: inset 0 0 0 4px var(--gold); }
.bk-radios { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.bk-radio { position: relative; display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.7rem 1.1rem; min-height: 44px; border: 1px solid var(--line); border-radius: var(--r-pill); cursor: pointer; color: var(--text-body); transition: border 180ms var(--ease-out), background 180ms var(--ease-out), color 180ms var(--ease-out); }
.bk-radio input { position: absolute; opacity: 0; }
.bk-radio:has(input:checked) { border-color: var(--gold-ink); background: var(--gold-soft); color: var(--text-primary); }
.bk-radio.is-disabled { opacity: 0.4; cursor: not-allowed; }
/* --- Mindset coaching: presented as an inclusion, deliberately NOT a card,
   so it never reads as a fourth bookable service. --- */
.inclusion {
  margin-top: clamp(1.6rem, 3.5vw, 2.6rem);
  padding: var(--pad-card);
  border: 1px dashed var(--gold-line);
  border-radius: var(--r-lg);
  background: var(--gold-soft);
  /* `width: 100%` matters: as a grid item, `margin-inline: auto` alone makes
     the panel shrink to its max-content, so a text-only panel came out 804px
     next to a 992px panel with a photo. Stacked panels must share an edge. */
  max-width: 62rem; width: 100%; margin-inline: auto;
}
.inclusion[hidden] { display: none; }
.inclusion .eyebrow { display: inline-block; margin-bottom: 0.7rem; }
.inclusion-title { font-size: 1.32rem; margin-bottom: 0.3rem; }
.inclusion-emotional {
  font-family: var(--font-display); font-style: italic; font-weight: 500;
  font-size: clamp(1.1rem, 1.9vw, 1.35rem); line-height: 1.35;
  color: var(--text-primary); margin-bottom: 0.9rem;
}
.inclusion-emotional em {
  font-style: italic;
  background: var(--grad-foil); -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
.inclusion-p { color: var(--text-body); line-height: 1.62; max-width: 70ch; }
.inclusion-p + .inclusion-p { margin-top: 0.8em; }

/* --- Gatherings: psychic parties + psychic expos. Same panel language as the
   session inclusions, but these are things she is asked FOR, not things
   already included in a session. Stacked, so the panel's own top margin goes. --- */
.gatherings-panels { display: grid; gap: clamp(1.2rem, 2.6vw, 1.8rem); }
.gatherings-panels .inclusion { margin-top: 0; }
.gatherings-cta { margin-top: clamp(1.6rem, 3.5vw, 2.4rem); text-align: center; }

/* --- Karine writes in paragraphs. These carry her breaks. --- */
.svc-blurb + .svc-blurb,
.about-bio-p + .about-bio-p,
.welcome-body-p + .welcome-body-p,
.voice-quote-p + .voice-quote-p,
.voices-sub-p + .voices-sub-p { margin-top: 0.85em; }
/* The bare `p` rule sets colour directly, so it beats what these would
   otherwise inherit from their .voice-quote / .welcome-body container. */
.voice-quote-p { color: var(--text-primary); }
.about-bio-p { color: var(--text-body); line-height: 1.68; }
.about-bio-p:first-child { font-family: var(--font-display); font-weight: 500; font-size: 1.35rem; color: var(--text-primary); }
.voices-sub-p { color: var(--text-muted); max-width: 62ch; margin-inline: auto; }
/* Her per-service tagline, e.g. "Reconnect with Clarity, Guidance & Spirit." */
.svc-tagline {
  font-family: var(--font-display); font-style: italic; font-weight: 500;
  font-size: 1.1rem; line-height: 1.35; margin-top: 0.15rem;
  background: var(--grad-foil); -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
.voices-subhead {
  font-family: var(--font-display); font-style: italic; font-weight: 500;
  font-size: clamp(1.15rem, 1.9vw, 1.4rem); color: var(--text-primary); margin-bottom: 0.7rem;
}

.bk-hint { font-size: 0.82rem; color: var(--text-muted); }
/* The real inputs are visually hidden, so the focus ring has to live on the label */
.bk-session:has(input:focus-visible), .bk-radio:has(input:focus-visible) { outline: 2px solid var(--gold-ink); outline-offset: 2px; }

/* Platform picker — revealed only for an online session */
.bk-platform { display: grid; gap: 0.5rem; margin-top: 0.3rem; padding-top: 0.8rem; border-top: 1px dashed var(--line); }
.bk-platform[hidden] { display: none; }
.bk-platform-label { font-size: 0.86rem; font-weight: 600; color: var(--text-primary); }

/* Day × time-of-day grid. Karine wants exact slots, not free text. */
.bk-when { display: grid; gap: 0.3rem; }
/* Column count follows content.booking.dayParts — renderBooking() sets
   --bk-parts, so dropping "Evening" cannot leave a phantom empty column. */
.bk-when-head, .bk-when-row { display: grid; grid-template-columns: minmax(4.6rem, 1fr) repeat(var(--bk-parts, 3), minmax(0, 1fr)); gap: 0.35rem; align-items: center; }
/* A day she does not work: holds the cell so the grid stays aligned. */
.bk-slot--closed { display: block; min-height: 44px; }
.bk-slot--closed::after {
  content: ""; display: block; height: 100%;
  border-radius: var(--r-sm);
  border: 1px dashed var(--line);
  opacity: 0.45;
}
.bk-hours-note { margin-top: 0.7rem; font-size: 0.82rem; line-height: 1.5; color: var(--text-muted); }
.bk-when-head { font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); padding-bottom: 0.2rem; }
.bk-when-head span { text-align: center; }
.bk-when-day { font-size: 0.86rem; color: var(--text-body); }
.bk-slot { position: relative; display: block; cursor: pointer; }
.bk-slot input { position: absolute; opacity: 0; width: 0; height: 0; }
.bk-slot > span {
  display: block; min-height: 44px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--panel-lift);
  transition: border 160ms var(--ease-out), background 160ms var(--ease-out), box-shadow 160ms var(--ease-out);
}
.bk-slot:hover > span { border-color: var(--gold-line); }
.bk-slot > span::after {
  content: '✦'; position: absolute; inset: 0; display: grid; place-items: center;
  color: var(--gold-ink); font-size: 0.85rem; opacity: 0; transform: scale(0.6);
  transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out);
}
.bk-slot:has(input:checked) > span { border-color: var(--gold-ink); background: var(--gold-soft); box-shadow: inset 0 0 0 1px var(--gold-line); }
.bk-slot:has(input:checked) > span::after { opacity: 1; transform: scale(1); }
.bk-slot input:focus-visible + span { outline: 2px solid var(--gold-ink); outline-offset: 2px; }

/* Selfie instruction — a real step, so it reads as guidance not fine print */
.bk-selfie {
  font-size: 0.86rem; line-height: 1.55; color: var(--text-body);
  background: var(--rose-soft); border-left: 2px solid var(--rose);
  padding: 0.75rem 0.9rem; border-radius: 0 var(--r-sm) var(--r-sm) 0; margin-top: 0.2rem;
}

/* Payment explainer */
.bk-payment { border-top: 1px solid var(--line); padding-top: 1.1rem; margin-top: 0.2rem; }
.bk-payment h3 { font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 0.6rem; }
.bk-payment ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
.bk-payment li { font-size: 0.92rem; line-height: 1.55; color: var(--text-body); padding-left: 1.1rem; position: relative; }
.bk-payment li::before { content: '·'; position: absolute; left: 0.25rem; color: var(--gold-ink); font-weight: 700; }
.booking-side { position: sticky; top: 5.5rem; }
.booking-side h3 { margin-bottom: 1rem; font-size: 1.15rem; }
.booking-side .contact-channels { margin-bottom: 1.4rem; }
.booking-reassure { color: var(--text-muted); font-size: 0.92rem; line-height: 1.6; font-style: italic; font-family: var(--font-display); font-weight: 500; }
.pendulum-price-enquire { color: var(--rose-deep); font-family: var(--font-display); font-weight: 500; font-style: italic; font-size: 1.05rem; margin-top: auto; }

@media (max-width: 1024px) {
  .booking-grid { grid-template-columns: 1fr; }
  .booking-side { position: static; }
}
@media (max-width: 640px) {
  .cs-grid { grid-template-columns: 1fr; }
  .bk-field input[type="text"], .bk-field input[type="tel"], .bk-field textarea { font-size: 16px; }
}

/* ============================================================
   FUNNEL MOMENTS — elevated (hero trust · welcome questions · early proof)
   ============================================================ */

/* Above-the-fold reassurance cues — a refined, hairline-topped starred stack */
.hero-trust {
  list-style: none; margin: 2rem 0 0; padding: 1.5rem 0 0;
  display: flex; flex-direction: column; gap: 0.62rem;
  max-width: 26rem; border-top: 1px solid var(--line);
}
.hero-trust li {
  position: relative; padding-left: 1.5rem;
  font-size: 0.9rem; color: var(--text-body); letter-spacing: 0.012em;
}
.hero-trust li::before {
  content: '✦'; position: absolute; left: 0; top: 0.14em;
  color: var(--gold-ink); font-size: 0.76rem;
  /* was an emissive glow; a light surface cannot glow, so the mark just reads as gold */
}

/* Welcome / intro — Karine's three proven questions (the empathy centrepiece).
   Editorial: hanging star markers, generous rhythm, a soft aura off-centre. */
.welcome { position: relative; overflow: hidden; }
.welcome::before {
  content: ''; position: absolute; z-index: 0; pointer-events: none;
  right: -14vw; top: -18%; width: min(560px, 60vw); height: min(560px, 60vw);
  background: radial-gradient(circle, rgba(223, 168, 75, 0.16) 0%, rgba(192, 118, 78, 0.08) 40%, transparent 68%);
  animation: auraBreath 11s var(--ease-in-out) infinite;
}
.welcome-inner { position: relative; z-index: 1; text-align: left; }
.welcome-inner > .eyebrow { display: inline-block; margin-bottom: 1.6rem; }
.welcome-questions {
  list-style: none; margin: 0 0 2rem; padding: 0;
  display: flex; flex-direction: column; gap: 0.9rem;
}
.welcome-questions li {
  position: relative; padding-left: 2.5rem;
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.25rem, 2.6vw, 1.85rem); line-height: 1.34;
  letter-spacing: -0.012em; color: var(--dusk-text);
}
.welcome-questions li::before {
  content: '✦'; position: absolute; left: 0; top: 0.28em;
  font-size: 0.82rem; color: var(--gold-deep);
  background: var(--grad-foil-dusk);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
/* 26ch was a Fraunces measure and .foil-line's `margin: 0 auto` was
   block-centring this inside a left-aligned band. Both corrected. */
.welcome-emotional { max-width: 32ch; margin-inline: 0; }
.welcome-body { max-width: 60ch; }

/* --- Signature moment: her real pendulum, swinging on your scroll ---
   Hangs from the top edge of the dusk band. JS writes --a each frame. */
/* ⚠️ 2026-08-10 — THE `right` OFFSET IS LOAD-BEARING, NOT DECORATION.
   The cutout is much taller than it is wide, so its tip sweeps sideways by
   height x sin(angle) on every swing. It used to sit `right: clamp(.5rem,5vw,4.5rem)`
   (72px at 1440px) while the element reached 193.6px past its own pivot at the
   15° extreme — 65.6px further right than the band had room for.
   `.welcome { overflow: hidden }` then sliced the crystal cone off vertically
   at the far end of every swing. That fix stands; the numbers below were
   re-measured for the new asset, they were not loosened.

   ⚠️ 2026-08-11 — THE ASSET CHANGED SHAPE, SO EVERY NUMBER HERE IS DERIVED.
   The old 220 x 1059 cutout was itself cropped: opaque pixels ran off the
   canvas on three sides and the filigree cap + the crystal's widest shoulder
   were simply missing from the file (the second "missing corner" report — no
   CSS could have restored them). Re-matted from her original photo to
   288 x 1082 with the whole pendulum present and 24px of transparent margin on
   all four sides, so a future rotation can never clip it again.
   Everything below follows from that canvas — recompute all of it if the asset
   is ever regenerated:
     content box   = x 24..263, y 24..1057  (240 x 1034 inside 288 x 1082)
     chain top     = (148.5, 24)  ->  transform-origin 51.5625% 2.218%
     top offset    = -24/288 of --swing-w, so the chain's cut end still meets
                     the band's top edge exactly as it did before
     --swing-w     = old clamp x 1.3167, which keeps the RENDERED PENDULUM THE
                     SAME HEIGHT (449px @1440). The box is wider only because it
                     now carries the padding and the restored 10% of cap width.
     right         = 1x --swing-w. It dropped from 1.35x because that multiple
                     was sized against a box with no padding; measured on the
                     real alpha, the content now reaches 122.0px right of the
                     pivot at 15° with 185.8px of room — 63.7px spare, up from
                     55.8px before. Do NOT "restore" 1.35x; it would shove the
                     pendulum into the copy column for no clearance gain.

   ⚠️ MEASURE THE ARC AT 22.43°, NOT AT 15°. `MAX` in script.js clamps the
   spring's TARGET, not the angle. The damped spring overshoots its target by up
   to 1.495x before it settles, so a hard scroll really does reach ±22.43° on
   desktop and ±11.96° on mobile (verified live, and it is an asymptote — no
   scroll speed exceeds it). Every clearance number above was then re-checked
   there: 164.1px of reach against 185.8px of room, 21.6px spare on desktop and
   9.1px on mobile — both better than the old asset managed. */
.swing {
  --swing-w: clamp(74px, 8.69vw, 126px);
  position: absolute;
  top: calc(var(--swing-w) * -0.08333);
  right: max(0.75rem, var(--swing-w));
  width: var(--swing-w); z-index: 2; pointer-events: none;
  transform-origin: 51.5625% 2.218%;
  transform: rotate(var(--a, 0deg));
  will-change: transform;
}
.swing-img { width: 100%; height: auto; display: block; filter: drop-shadow(0 20px 34px rgba(12, 6, 0, 0.45)); }
@media (max-width: 640px) {
  /* A phone cannot spare the desktop clearance, so the arc is tightened to 8°
     in script.js and the pendulum shrinks: at 53px wide the box is 199px tall,
     its content sweeps 37.4px sideways at 8° against 54.5px of room, and the
     whole arc lands inside the 390px viewport. `.welcome-inner` reserves the
     matching gutter below so the copy never runs under it. */
  .swing { --swing-w: 53px; right: calc(var(--swing-w) * 0.55); opacity: 0.8; }
  .welcome-inner { padding-right: 3.3rem; }
}
@media (prefers-reduced-motion: reduce) { .swing { display: none; } }

/* Early proof — a cinematic featured reflection: breathing sun bloom, warm
   drifting motes, an oversized foil quote mark and a hairline attribution. */
.proof-early {
  position: relative; overflow: hidden;
  padding-block: clamp(4.5rem, 9vw, 7.5rem);
  background: radial-gradient(135% 120% at 50% -12%, var(--surface-1) 0%, var(--surface) 62%);
}
.proof-early::before {
  content: ''; position: absolute; left: 50%; top: 47%; z-index: 0; pointer-events: none;
  width: min(760px, 88vw); height: min(760px, 88vw); transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(223, 168, 75, 0.22) 0%, rgba(192, 118, 78, 0.10) 34%, transparent 66%);
  animation: auraBreath 9s var(--ease-in-out) infinite;
}
.proof-early::after {
  content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: 0.5;
  background-image:
    radial-gradient(2.2px 2.2px at 16% 26%, rgba(192, 118, 78, 0.34), transparent),
    radial-gradient(1.8px 1.8px at 82% 30%, rgba(176, 124, 36, 0.30), transparent),
    radial-gradient(1.6px 1.6px at 30% 74%, rgba(192, 118, 78, 0.26), transparent),
    radial-gradient(2px 2px at 70% 78%, rgba(176, 124, 36, 0.26), transparent),
    radial-gradient(1.5px 1.5px at 92% 60%, rgba(192, 118, 78, 0.22), transparent),
    radial-gradient(1.5px 1.5px at 8% 58%, rgba(176, 124, 36, 0.22), transparent);
}
.proof-early .container-narrow { position: relative; z-index: 1; }
.proof-early-card {
  position: relative; max-width: 60rem; margin: 0 auto; text-align: center;
  padding: clamp(1rem, 3vw, 2rem);
}
.proof-early-mark {
  display: block; font-family: var(--font-display); font-weight: 500;
  font-size: clamp(3.4rem, 6vw, 4.6rem); line-height: 0.7; margin-bottom: 0.4rem;
  background: var(--grad-foil); background-size: 200% auto;
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent; opacity: 0.85;
}
.proof-early-quote {
  margin: 0 0 1.7rem; font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.55rem, 3.4vw, 2.5rem); line-height: 1.36;
  letter-spacing: -0.015em; color: var(--text-primary); text-wrap: balance;
}
.proof-early-meta {
  display: inline-flex; align-items: center; gap: 0.9rem;
  font-size: 0.8rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-muted);
}
.proof-early-meta::before, .proof-early-meta::after {
  content: ''; width: 28px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold-line), transparent);
}

/* ============================================================
   ELEVATION LAYER — signature motion + depth (desktop gated via .fx)
   Grain, aurora drift, gold-foil shimmer, waxing-moon scroll dial,
   star-trail cursor, 3D card tilt, constellation, staggered reveals.
   ============================================================ */

/* --- Film grain: analogue depth, the thing that stops a light theme
   reading as a flat SaaS page. `soft-light` greys cream out, so on the
   light theme it is a much lighter `multiply`. --- */
body::after {
  content: ''; position: fixed; inset: 0; z-index: 45; pointer-events: none;
  opacity: 0.032; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='150' height='150' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 150px 150px;
}

/* --- Aurora keyframes --- */
@keyframes auraBreath { 0%, 100% { opacity: 0.55; transform: translate(-50%, -50%) scale(1); } 50% { opacity: 1; transform: translate(-50%, -50%) scale(1.09); } }
@keyframes auroraDrift { 0% { transform: translate(0, 0) scale(1); } 100% { transform: translate(3%, -2.5%) scale(1.08); } }
/* welcome aura uses its own transform origin (not centred) */
.welcome::before { animation-name: auraBreathOff; }
@keyframes auraBreathOff { 0%, 100% { opacity: 0.5; transform: scale(1); } 50% { opacity: 0.95; transform: scale(1.08); } }

/* Hero aura slowly drifts for living depth (desktop only) */
.fx .hero-aura { animation: auroraDrift 24s var(--ease-in-out) infinite alternate; will-change: transform; }

/* --- Gold-foil shimmer: light travelling through the emotional accents --- */
@keyframes foilShimmer { from { background-position: 0% center; } to { background-position: 200% center; } }
.fx .hero-title em, .fx .section-head h2 em, .fx .split em, .fx .foil-line em,
.fx .band--dusk .foil-line em, .fx .band--dusk .section-head h2 em, .fx .band--dusk .split em,
.fx .journey-step, .fx .voice-metric, .fx .footer-tag, .fx .proof-early-mark {
  background-size: 200% auto;
  animation: foilShimmer 7.5s var(--ease-in-out) infinite alternate;
}

/* --- Staggered reveal utility (children rise + fade in cascade) --- */
.has-js .stagger > * { opacity: 0; transform: translateY(18px); transition: opacity 0.75s var(--ease-out), transform 0.75s var(--ease-out); }
.has-js .stagger.is-in > * { opacity: 1; transform: none; }
.stagger.is-in > *:nth-child(1) { transition-delay: 0.02s; }
.stagger.is-in > *:nth-child(2) { transition-delay: 0.13s; }
.stagger.is-in > *:nth-child(3) { transition-delay: 0.24s; }
.stagger.is-in > *:nth-child(4) { transition-delay: 0.35s; }
.stagger.is-in > *:nth-child(5) { transition-delay: 0.46s; }
.stagger.is-in > *:nth-child(6) { transition-delay: 0.57s; }

/* Per-word cascade for split headings (JS sets --i on each word) */
.has-js .split.is-in .split-word > span { transition-delay: calc(var(--i, 0) * 42ms); }

/* --- Rising-sun scroll-progress dial (desktop) ---
   Same mechanism as the old moon dial: JS writes --p (0 to 1) and a mask
   slides across the disc. On a light page the mask is the page colour, so
   the sun reads as rising rather than the moon waxing. --- */
.sun-dial {
  position: fixed; right: 26px; bottom: 26px; width: 42px; height: 42px;
  z-index: 35; pointer-events: none; opacity: 0;
  transform: translateY(10px) scale(0.9); transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out);
}
.fx .sun-dial.is-ready { opacity: 1; transform: none; }
.sun-dial::after {
  content: ''; position: absolute; inset: -6px; border-radius: 50%;
  border: 1px solid var(--gold-line); box-shadow: var(--shadow-soft);
  background: var(--surface);
}
.sun-disc {
  position: absolute; inset: 0; border-radius: 50%; overflow: hidden; z-index: 1;
  background: radial-gradient(circle at 36% 32%, var(--gold-warm) 0%, var(--gold) 55%, var(--gold-deep) 100%);
  box-shadow: 0 6px 18px -6px rgba(176, 124, 36, 0.55), inset 0 0 10px rgba(255, 255, 255, 0.35);
}
.sun-shadow {
  position: absolute; inset: -2px; border-radius: 50%;
  background: radial-gradient(circle at 60% 42%, var(--surface), var(--surface-2) 75%);
  transform: translateX(calc(var(--p, 0) * 116%)); filter: blur(0.6px);
  transition: transform 0.15s linear;
}

/* --- Warm dust-mote cursor trail (desktop) ---
   Was a star trail on `screen`, which is invisible on cream. Now warm motes
   that drift sideways on the breeze rather than rising like sparks. --- */
.cursor-star {
  position: fixed; top: 0; left: 0; width: 6px; height: 6px; border-radius: 50%;
  pointer-events: none; z-index: 29; transform: translate(-50%, -50%);
  background: radial-gradient(circle, var(--gold-warm) 0%, var(--gold) 52%, transparent 72%);
  will-change: transform, opacity;
  animation: starFade 1150ms var(--ease-out) forwards;
}
.cursor-star.rose { background: radial-gradient(circle, var(--rose) 0%, var(--rose-deep) 52%, transparent 72%); }
@keyframes starFade {
  0% { opacity: 0.75; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-24%, -120%) scale(0.2); }
}

/* --- 3D tilt + pointer-follow glow on the richer cards (desktop) ---
   These rules own the card transform (specificity ties the reveal rule and
   wins on source order), composing the reveal-rise (--ty 22px → 0), the
   hover-lift (−6px) and the live pointer tilt (--rx/--ry) into one transform. */
.fx [data-reveal].svc-card, .fx [data-reveal].pendulum-card, .fx [data-reveal].voice-card {
  transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translate3d(0, var(--ty, 22px), 0);
  transform-style: preserve-3d;
  transition: transform 0.4s var(--ease-out), border-color 0.32s var(--ease-out), box-shadow 0.32s var(--ease-out);
}
.fx [data-reveal].svc-card.is-in, .fx [data-reveal].pendulum-card.is-in, .fx [data-reveal].voice-card.is-in { --ty: 0px; }
.fx [data-reveal].svc-card.is-in:hover, .fx [data-reveal].pendulum-card.is-in:hover, .fx [data-reveal].voice-card.is-in:hover { --ty: -6px; }
/* Pointer-tracked glow inside service cards */
.fx .svc-card .svc-card-glow {
  inset: 0; height: auto;
  background: radial-gradient(220px circle at var(--gx, 50%) var(--gy, 0%), var(--rose-soft), transparent 60%);
}

/* --- Shoreline draw-on in the closing CTA (desktop-friendly, cheap) ---
   Same stroke-dashoffset machinery as the old constellation, but a flowing
   horizon curve instead of a star map. A light line on a light ground needs
   more weight and opacity than it did on the night sky. --- */
.constellation {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 0; opacity: 0.9;
}
.constellation .c-line {
  stroke: var(--gold); stroke-width: 1.6; fill: none; opacity: 0.75;
  stroke-linecap: round;
  stroke-dasharray: var(--len, 900); stroke-dashoffset: var(--len, 900);
  transition: stroke-dashoffset 2.4s var(--ease-out);
}
.constellation.is-in .c-line { stroke-dashoffset: 0; }
.constellation .c-star { fill: var(--gold); opacity: 0; transform: scale(0); transform-box: fill-box; transform-origin: center; transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out); }
.constellation.is-in .c-star { opacity: 0.85; transform: scale(1); }
.constellation.is-in .c-star:nth-child(2) { transition-delay: 0.6s; }
.constellation.is-in .c-star:nth-child(3) { transition-delay: 1s; }
.constellation.is-in .c-star:nth-child(4) { transition-delay: 1.4s; }
.cta-strip > .container { position: relative; z-index: 1; }

/* --- Responsive: keep signature chrome desktop-only, protect the phone --- */
@media (max-width: 1024px) {
  .sun-dial { display: none; }
  .welcome::before { right: -30vw; opacity: 0.6; }
}
@media (max-width: 640px) {
  .hero-trust { max-width: none; }
  .footer-bottom { justify-content: flex-start; }
  .bk-when-head { font-size: 0.7rem; letter-spacing: 0.04em; }
  .welcome-questions li { padding-left: 2rem; }
  body::after { opacity: 0.028; }
  /* A portrait crop of a 16:9 frame throws the pendulum out of shot, and the
     pendulum is the point. Pan the crop right so it stays in view, and swap
     the left-to-right cream wash for a top-down one that protects the copy
     while leaving the lower frame clear for the swing. */
  .hero-video { object-position: 72% 42%; }
  .hero-media { background-position: 72% 42%; }
  .hero::before {
    background:
      linear-gradient(180deg, rgba(253,248,239,0.95) 0%, rgba(253,248,239,0.90) 50%, rgba(253,248,239,0.56) 72%, rgba(253,248,239,0.34) 100%),
      linear-gradient(90deg, rgba(253,248,239,0.46) 0%, rgba(253,248,239,0) 62%);
  }
}

/* --- Reduced motion: everything visible + still, no decorative chrome --- */
@media (prefers-reduced-motion: reduce) {
  .sun-dial, .cursor-star { display: none !important; }
  .constellation .c-line { stroke-dashoffset: 0 !important; transition: none !important; }
  .constellation .c-star { opacity: 0.9 !important; transform: none !important; transition: none !important; }
  .welcome::before, .proof-early::before { animation: none !important; }
  .has-js .stagger > * { opacity: 1 !important; transform: none !important; }
}

/* ============================================================
   DISCLOSURE (accordion) — 2026-08-10
   Nicholas: "make them a drop-down so that there's not as much writing at
   once." Used for the session descriptions, the mindset-coaching panel and
   the five-paragraph Psychic Parties copy.

   The panel animates its own `height` with a plain CSS transition. No JS
   per-frame work, so there is no second raf and nothing for Lenis to fight —
   Lenis reads scroll position, not layout, and ScrollTrigger is refreshed on
   transitionend. `visibility` is switched with it so collapsed copy leaves
   the accessibility tree instead of being read out invisibly.
   ============================================================ */
.disclose { display: grid; }
.disclose-toggle {
  display: flex; align-items: center; justify-content: space-between; gap: 0.9rem;
  width: 100%; min-height: 44px; padding: 0.7rem 0;
  background: none; border: 0; border-top: 1px solid var(--line);
  cursor: pointer; text-align: left; color: var(--text-primary);
  font-family: var(--font-body); font-size: 0.88rem; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  transition: color 200ms var(--ease-out);
}
.disclose-toggle:hover { color: var(--gold-ink); }
.disclose-toggle:focus-visible { outline: 2px solid var(--gold-ink); outline-offset: 3px; border-radius: var(--r-sm); }
.disclose-chev {
  flex: 0 0 auto; width: 22px; height: 22px; position: relative;
  border: 1px solid var(--gold-line); border-radius: 50%;
  transition: transform 320ms var(--ease-out), background 200ms var(--ease-out);
}
.disclose-chev::before, .disclose-chev::after {
  content: ''; position: absolute; top: 50%; left: 50%; width: 9px; height: 1.5px;
  background: var(--gold-ink); border-radius: 2px;
  transition: transform 320ms var(--ease-out), opacity 240ms var(--ease-out);
}
.disclose-chev::before { transform: translate(-50%, -50%); }
.disclose-chev::after  { transform: translate(-50%, -50%) rotate(90deg); }
.disclose-toggle:hover .disclose-chev { background: var(--gold-soft); }
.disclose-toggle[aria-expanded="true"] .disclose-chev::after { transform: translate(-50%, -50%) rotate(0deg); opacity: 0; }

.disclose-panel {
  height: 0; overflow: hidden; visibility: hidden;
  transition: height 380ms var(--ease-out), visibility 0s linear 380ms;
}
.disclose-panel.is-open { visibility: visible; transition: height 380ms var(--ease-out), visibility 0s; }
.disclose-inner { padding-bottom: 1rem; }
/* Reduced motion renders the copy raw (no toggle at all) — this is the
   belt-and-braces half of hard rule 6. */
.disclose-static { display: block; }
@media (prefers-reduced-motion: reduce) {
  .disclose-toggle { display: none !important; }
  .disclose-panel { height: auto !important; overflow: visible !important; visibility: visible !important; transition: none !important; }
}

/* ============================================================
   HER PHOTOS, SPREAD THROUGH THE PAGE — 2026-08-10
   Nicholas: "i want to spread the photos out make it look amazing. I don't
   want to just have like a big sectional." Four of the seven room photos now
   ride with the copy they belong to instead of all landing in one grid.
   ⏭️ Her expo photos slot in the same way when they reach this machine.
   ============================================================ */
.svc-media {
  margin: calc(var(--pad-card) * -1) calc(var(--pad-card) * -1) 0.2rem;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  overflow: hidden; aspect-ratio: 16 / 10; background: var(--surface-2);
}
.svc-media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 900ms var(--ease-out);
}
.svc-card:hover .svc-media img { transform: scale(1.05); }

/* Inclusion / gathering panels: photo beside the copy, stacked on narrow. */
/* The photo column STRETCHES to the copy's height rather than carrying a fixed
   aspect ratio. With a collapsed disclosure the panel is only ~11rem tall, and
   a locked 4/5 photo left a large dead area beside two lines of text. */
.inclusion.has-media {
  display: grid; grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
  gap: clamp(1.1rem, 2.6vw, 2rem); align-items: stretch;
}
.inclusion-media { border-radius: var(--r); overflow: hidden; background: var(--surface-2); min-height: 11rem; }
.inclusion-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Centred against the photo column: with the disclosure shut the copy is much
   shorter than the image, and top-aligning left all the slack under the text. */
.inclusion-body { min-width: 0; align-self: center; }
/* --- The sage clip (2026-08-10). Her own phone footage of the altar, and it
   earns its place ONLY as a small, quiet supporting tile: honest but imperfect
   (a magenta runner against a cream page, thin smoke, a domestic background).
   So it is deliberately held to ~280px wide, in the panel's own media column.
   It is never full-bleed and never a section background. --- */
.inclusion.has-video { grid-template-columns: minmax(0, 17.5rem) minmax(0, 1fr); }
.inclusion-media--video {
  min-height: 0; align-self: center;
  aspect-ratio: 135 / 196;              /* the clip's real 540 x 784 */
  max-width: 26.25rem;
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-soft);
}
.inclusion-media--video video,
.inclusion-media--video img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* --- A row of photos UNDER the copy (the Psychic Expos panel, 2026-08-13).
   Deliberately not `.inclusion-media`: that column is narrow and crops with
   object-fit: cover, which cut Karine out of two portrait shots. These keep
   the photo's own ratio (`height: auto`), exactly like the atmosphere grid.
   ⚠️ Do NOT give these a fixed height or object-fit: cover — same bug, same
   photos, and it was measured once already. --- */
/* Was a hard 2-up, which orphaned a lone third photo on its own row with a
   dead half-row beside it. auto-fit lets the row take however many she has,
   so 2, 3 or 4 photos all fill their row instead of leaving a gap. The
   min() keeps a single item from being forced wider than the panel. */
.inclusion-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: clamp(0.7rem, 1.6vw, 1rem);
  margin-top: clamp(1.1rem, 2.4vw, 1.5rem);
}
.inclusion-shot {
  margin: 0; overflow: hidden; border-radius: var(--r);
  border: 1px solid var(--gold-line); background: var(--surface-2);
  box-shadow: var(--shadow-soft);
}
.inclusion-shot img { display: block; width: 100%; height: auto; }
@media (max-width: 760px) {
  .inclusion.has-media { grid-template-columns: 1fr; }
  .inclusion-media { min-height: 0; aspect-ratio: 16 / 10; }
  /* One at a time on a phone: two portrait shots side by side land at ~150px
     wide, which is too small to see her face. */
  .inclusion-gallery { grid-template-columns: 1fr; }
  /* Portrait clip stays portrait on a phone, and stays small. */
  .inclusion.has-video { grid-template-columns: 1fr; }
  .inclusion-media--video { aspect-ratio: 135 / 196; max-width: min(17.5rem, 72%); margin-inline: auto; }
}

/* ============================================================
   GIFT VOUCHERS — 2026-08-10
   Karine: "a section where they can order a gift voucher."
   Nicholas: "match the sessions and also a custom amount also show an example
   of it." The card on the left is that example, and it updates live as the
   choice changes. There is no checkout on this site, so the button composes a
   text, exactly like the pendulum shop.
   ============================================================ */
.vouchers { background: linear-gradient(180deg, var(--surface-1) 0%, var(--surface) 100%); }
.vouchers-grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.6rem, 4vw, 3.2rem); align-items: start;
}
.voucher-preview { margin: 0; position: sticky; top: 5.5rem; }
.voucher-card {
  position: relative; isolation: isolate;
  padding: clamp(1.6rem, 3.4vw, 2.4rem);
  border-radius: var(--r-lg);
  background: linear-gradient(160deg, var(--dusk) 0%, var(--dusk-2) 100%);
  border: 1px solid var(--dusk-line);
  box-shadow: var(--shadow-deep);
  text-align: center;
  overflow: hidden;
}
.voucher-card::before {
  content: ''; position: absolute; inset: 10px; border-radius: var(--r);
  border: 1px solid var(--gold-line); pointer-events: none;
}
.voucher-card::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  /* 0.10, not 0.16: at 0.16 the bloom lifted the dusk ground under the kicker
     to a measured 4.56:1 against --dusk-text-muted, which clears AA by 0.06.
     At 0.10 the worst point on the card is 5.32:1. */
  background: radial-gradient(circle at 50% 0%, rgba(240, 206, 134, 0.10), transparent 62%);
}
.voucher-corner { position: absolute; width: 34px; height: 34px; pointer-events: none; z-index: 1; }
.voucher-corner::before, .voucher-corner::after { content: ''; position: absolute; background: var(--grad-foil-dusk); opacity: 0.8; }
.voucher-corner::before { width: 100%; height: 1px; }
.voucher-corner::after  { width: 1px; height: 100%; }
.voucher-corner--tl { top: 20px; left: 20px; }
.voucher-corner--br { bottom: 20px; right: 20px; }
.voucher-corner--br::before { bottom: 0; right: 0; }
.voucher-corner--br::after  { bottom: 0; right: 0; }
.voucher-kicker {
  position: relative; z-index: 1;
  font-family: var(--font-body); font-size: 0.76rem; font-weight: 600;
  letter-spacing: 0.28em; text-transform: uppercase; color: var(--dusk-text-muted);
  margin: 0 0 0.7rem;
}
.voucher-brand {
  position: relative; z-index: 1;
  font-family: var(--font-display); font-weight: 600; font-size: clamp(1.3rem, 2.4vw, 1.7rem);
  line-height: 1.15; margin: 0 0 1.1rem;
  background: var(--grad-foil-dusk); -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
.voucher-amount {
  position: relative; z-index: 1;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(2.6rem, 6vw, 3.6rem); line-height: 1; color: var(--dusk-text);
  margin: 0 0 0.35rem;
}
.voucher-detail {
  position: relative; z-index: 1;
  font-family: var(--font-display); font-style: italic; font-size: 1.05rem;
  color: var(--dusk-text-body); margin: 0 0 1.4rem;
}
.voucher-lines {
  position: relative; z-index: 1;
  display: grid; gap: 0.6rem; text-align: left;
  padding: 1.1rem 0; margin: 0 0 1.1rem;
  border-top: 1px solid var(--dusk-line); border-bottom: 1px solid var(--dusk-line);
}
.voucher-line { display: flex; align-items: baseline; gap: 0.7rem; }
.voucher-line-label {
  flex: 0 0 auto; font-family: var(--font-body); font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--dusk-text-muted);
}
.voucher-line-value {
  flex: 1 1 auto; font-family: var(--font-display); font-size: 1.15rem;
  color: var(--dusk-text); border-bottom: 1px dashed var(--dusk-line); padding-bottom: 2px;
}
.voucher-line-value.is-blank { color: var(--dusk-text-muted); font-style: italic; }
.voucher-foot {
  position: relative; z-index: 1;
  font-size: 0.76rem; line-height: 1.5; color: var(--dusk-text-muted); margin: 0;
}
.voucher-caption { margin-top: 0.9rem; text-align: center; font-size: 0.82rem; color: var(--text-muted); }

/* ⚖️ Issue date + expiry, printed on the card itself. Kept on the card rather
   than only in the terms because the ACL wants the expiry displayed
   prominently, and a gift is often forwarded on without the page around it. */
.voucher-validity {
  position: relative; z-index: 1;
  display: grid; gap: 0.25rem; text-align: left;
  margin: 0 0 1.1rem; padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--dusk-line);
}
.voucher-validity-row {
  display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap;
  font-size: 0.84rem; color: var(--dusk-text);
}
.voucher-validity-label {
  flex: 0 0 auto; font-family: var(--font-body); font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--dusk-text-muted);
}

/* ⚖️ The short voucher terms, spanning both columns under the card and form.
   Four lines, not a wall. The full version is terms.html#vouchers. */
.voucher-terms {
  grid-column: 1 / -1;
  margin-top: clamp(0.4rem, 1.6vw, 1rem);
  padding: var(--pad-card);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.voucher-terms[hidden] { display: none; }
.voucher-terms-title {
  font-family: var(--font-display); font-size: 1.16rem; font-weight: 600;
  color: var(--text-primary); margin: 0 0 0.9rem;
}
.voucher-terms-list {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: 0.6rem; max-width: 70ch;
}
.voucher-terms-list li {
  position: relative; padding-left: 1.5rem;
  font-size: 0.94rem; color: var(--text-body);
}
.voucher-terms-list li::before {
  content: ''; position: absolute; left: 0; top: 0.66em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--gold); opacity: 0.85;
}
.voucher-terms-link { margin: 1rem 0 0; }
.voucher-terms-link a {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: 0.9rem; color: var(--gold-ink); border-bottom: 1px solid var(--gold-line);
}
.voucher-terms-link a:hover { color: var(--rose-deep); border-bottom-color: var(--rose-line); }
.voucher-form {
  background: var(--surface-1); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: clamp(1.4rem, 3vw, 2.4rem);
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.1rem;
}
/* `.btn` is `white-space: nowrap` globally, and this label carries the chosen
   amount, so at 390px it demanded 360px inside a 314px box and pushed the page
   sideways. It is the one button on the site allowed to wrap. */
.voucher-form .form-submit .btn {
  width: 100%; justify-content: center;
  white-space: normal; text-align: center; line-height: 1.35;
}
.voucher-custom[hidden] { display: none; }
.voucher-form input[type="text"] {
  width: 100%; padding: 0.85rem 1rem; border-radius: var(--r);
  border: 1px solid var(--line); background: var(--surface);
  color: var(--text-primary); font-family: var(--font-body); font-size: 1rem;
  transition: border 200ms var(--ease-out), background 200ms var(--ease-out);
}
.voucher-form input[type="text"]:focus { border-color: var(--gold-ink); background: var(--gold-soft); outline: none; }
@media (max-width: 1024px) {
  /* minmax(0, 1fr), never a bare 1fr: a bare fr track has an `auto` minimum,
     so the big display amount and the session rows pushed the track wider than
     the container and put 32px of horizontal overflow on a 390px screen. */
  .vouchers-grid { grid-template-columns: minmax(0, 1fr); }
  .voucher-preview { position: static; }
}
@media (max-width: 640px) {
  .voucher-form input[type="text"] { font-size: 16px; }
  /* The pillars wrap to two lines here. The separator dots are flex items, so
     a wrap leaves one dangling at the end of a line — the per-pillar gold
     underline already does the separating, so the dots go. */
  .hero-tagline { letter-spacing: 0.1em; gap: 0.4rem 0.9rem; padding-top: 0.9rem; }
  .hero-tagline .tagline-dot { display: none; }
}

/* ============================================================
   ⚖️ LEGAL PAGES — privacy.html · terms.html · disclaimer.html
   ------------------------------------------------------------
   A reading document, not a landing page: one narrow column,
   generous leading, no motion, no reveal states. Tokens only.
   These pages never get the `has-js` class, so nothing here may
   rely on .foil-line or [data-reveal] to become visible.
   ============================================================ */
.legal-page { background: var(--surface); }

/* -------- header -------- */
.legal-nav {
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  position: sticky; top: 0; z-index: 20;
  backdrop-filter: blur(10px);
}
.legal-nav-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; min-height: 68px; padding-block: 0.6rem;
}
.legal-brand {
  font-family: var(--font-display); font-weight: 600; font-size: 1.24rem;
  letter-spacing: 0.16em; color: var(--text-primary);
  display: inline-flex; align-items: center; min-height: 44px;
}
.legal-brand:hover { color: var(--gold-ink); }
.legal-nav-cta { padding: 0.7rem 1.3rem; font-size: 0.86rem; }

/* -------- the document -------- */
.legal-main { padding-block: clamp(2.5rem, 6vw, 4.5rem) var(--gap-section-tight); }
.legal-doc { color: var(--text-body); }
/* `section { padding-block: var(--gap-section) }` is the page-level rhythm and
   is far too much between the clauses of one document. */
.legal-doc .legal-section { padding-block: 0; margin-top: clamp(2rem, 4vw, 2.9rem); }

.legal-back { margin: 0 0 1.6rem; }
.legal-back a {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: 0.88rem; letter-spacing: 0.04em;
  color: var(--text-muted);
}
.legal-back a:hover { color: var(--gold-ink); }

.legal-head { padding-bottom: clamp(1.4rem, 3vw, 2rem); border-bottom: 1px solid var(--line); }
.legal-doc h1 {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(2.3rem, 5.4vw, 3.6rem); line-height: 1.1;
  letter-spacing: -0.012em; color: var(--text-primary); margin: 0;
}
.legal-intro {
  margin: 1rem 0 0; max-width: 52ch;
  font-size: 1.06rem; color: var(--text-body);
}
.legal-meta {
  margin: 1.5rem 0 0; display: flex; flex-wrap: wrap; gap: 0.35rem 1.1rem;
  font-size: 0.83rem; letter-spacing: 0.05em; color: var(--text-muted);
}
.legal-meta-business { position: relative; }
.legal-meta-business::before {
  content: '·'; position: absolute; left: -0.68rem; color: var(--gold-ink);
}

.legal-doc h2 {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.5rem, 2.9vw, 1.95rem); line-height: 1.18;
  color: var(--text-primary); margin: 0 0 0.85rem;
}
.legal-doc .legal-section p { margin: 0 0 1rem; max-width: 66ch; }
.legal-doc .legal-section p:last-child { margin-bottom: 0; }

.legal-list {
  list-style: none; padding: 0; margin: 0 0 1rem;
  display: grid; gap: 0.75rem; max-width: 66ch;
}
.legal-list li { position: relative; padding-left: 1.5rem; }
.legal-list li::before {
  content: ''; position: absolute; left: 0; top: 0.72em;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--gold); opacity: 0.85;
}

/* -------- closing panel -------- */
.legal-aside {
  margin-top: clamp(3rem, 6vw, 4.5rem);
  padding: var(--pad-card);
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-soft);
}
.legal-aside p { margin: 0 0 1rem; }
.legal-aside p:last-child { margin-bottom: 0; }
.legal-aside-lead {
  font-family: var(--font-display); font-size: 1.3rem;
  color: var(--text-primary); line-height: 1.3;
}
.legal-crosslinks { font-size: 0.9rem; color: var(--text-muted); }
.legal-crosslinks a {
  display: inline-flex; align-items: center; min-height: 44px;
  color: var(--gold-ink); margin-right: 1.1rem;
  border-bottom: 1px solid var(--gold-line);
}
.legal-crosslinks a:hover { color: var(--rose-deep); border-bottom-color: var(--rose-line); }

/* -------- the quiet legal row in the footer (both here and on index) -------- */
.footer-legal { display: flex; flex-wrap: wrap; gap: 0 1.1rem; }
.footer-legal a { font-size: 0.82rem; color: var(--dusk-text-muted); }
.footer-legal a:hover { color: var(--gold-bright); }

@media (max-width: 640px) {
  .legal-nav-cta { padding: 0.65rem 1rem; font-size: 0.8rem; }
  .legal-brand { font-size: 1.08rem; letter-spacing: 0.12em; }
  /* The business line sits under the date on a phone, so its leading dot
     separator would be dangling in mid-air. */
  .legal-meta { flex-direction: column; gap: 0.2rem; }
  .legal-meta-business::before { content: none; }
}
