/* ═══════════════════════════════════════════════════════════
   Prime Building Care — "What the Rain Knows"
   Mobile-first scroll-film. Portrait is the master; desktop
   is the cinema-stage adaptation.
   ═══════════════════════════════════════════════════════════ */

/* ── Fonts (self-hosted, latin subset) ────────────────────── */
@font-face{
  font-family:'Sora';src:url('fonts/sora-var.woff2') format('woff2');
  font-weight:100 800;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Source Serif';src:url('fonts/source-serif-400.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Source Serif';src:url('fonts/source-serif-400-italic.woff2') format('woff2');
  font-weight:400;font-style:italic;font-display:swap;
}

/* ── Tokens ───────────────────────────────────────────────── */
:root{
  --ink:#0F2B33;
  --deep:#1E4B57;
  --slate:#63707A;
  --mist:#A9B2B8;
  --pale:#E7EBED;
  --paper:#F7F8F9;
  --seam:#947E6C;              /* sampled from the HEALED dry room — what is
                               actually on screen at the handoff */
  --disp:'Sora',system-ui,-apple-system,'Segoe UI',sans-serif;
  --edit:'Source Serif',Georgia,'Times New Roman',serif;
  --gut:clamp(20px,5.6vw,32px);
  --maxw:1180px;
  --sat:env(safe-area-inset-top,0px);
  --sab:env(safe-area-inset-bottom,0px);
  --hdr-h:60px;
}

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

body{
  margin:0;background:var(--ink);color:var(--ink);
  font-family:var(--disp);font-weight:400;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:hidden;
}

/* iOS Safari 26+ tints its toolbar from the body background at render
   time; a scroll-driven CSS animation is the only live path. */
@supports (animation-timeline: scroll()){
  @media (prefers-reduced-motion:no-preference){
    html,body{animation:toolbar-shift linear both;animation-timeline:scroll(root)}
  }
}
@keyframes toolbar-shift{
  0%{background:#F7F8F9}
  4%{background:#F7F8F9}
  9%{background:#0F2B33}
  18%{background:#12303A}
  27%{background:#1E4B57}
  36%{background:#4E6169}
  41%{background:#927D6B}
  45%{background:#F7F8F9}
  86%{background:#F7F8F9}
  93%{background:#1E4B57}
  100%{background:#0F2B33}
}

img,svg,canvas{display:block;max-width:100%}
a{color:inherit}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}

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

.skip-link{
  position:absolute;left:-9999px;top:0;z-index:999;
  background:var(--ink);color:var(--paper);padding:12px 18px;border-radius:0 0 8px 0;
}
.skip-link:focus{left:0}

:where(a,button,summary,details):focus-visible{
  outline:2px solid currentColor;outline-offset:3px;border-radius:4px;
}

/* ── Buttons ──────────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--disp);font-weight:600;font-size:.98rem;letter-spacing:.01em;
  padding:16px 26px;border-radius:6px;text-decoration:none;
  min-height:52px;transition:background .22s,color .22s,border-color .22s,transform .22s;
}
.btn.sm{padding:13px 20px;min-height:46px;font-size:.92rem}
.btn.lg{padding:19px 34px;min-height:58px;font-size:1.06rem}
.btn.primary{background:var(--deep);color:var(--paper)}
.btn.primary:hover{background:var(--ink)}
.btn.ghost{border:1px solid currentColor;color:inherit}
.btn.ghost:hover{background:rgba(30,75,87,.08)}

/* ═══════════ HEADER ═══════════ */
#hdr{
  position:fixed;inset:0 0 auto 0;z-index:60;
  display:flex;align-items:center;gap:14px;
  padding:calc(var(--sat) + 10px) var(--gut) 10px;
  color:var(--paper);
  transition:color .35s,background .35s,backdrop-filter .35s;
}
#hdr.solid{background:rgba(15,43,51,.92);backdrop-filter:blur(10px)}
#hdr.on-light{color:var(--ink)}
#hdr.on-light.solid{background:rgba(247,248,249,.94)}

.brand{display:flex;align-items:center;gap:10px;text-decoration:none;flex:0 0 auto}
.mono{width:30px;height:30px;flex:0 0 auto}
.mono .draft{stroke:currentColor;stroke-width:1;opacity:.42;fill:none}
.mono .glyph path{stroke:currentColor;stroke-width:2.4;fill:none;stroke-linecap:butt;stroke-linejoin:miter}
.wordmark{display:flex;flex-direction:column;line-height:1}
.wordmark b{font-weight:700;font-size:.86rem;letter-spacing:.13em}
.wordmark i{font-style:normal;font-weight:600;font-size:.5rem;letter-spacing:.2em;opacity:.72;margin-top:3px}

#nav{display:none}
#nav a{
  text-decoration:none;font-size:.9rem;font-weight:600;opacity:.86;
  padding:6px 0;border-bottom:1px solid transparent;
}
#nav a:hover{opacity:1;border-bottom-color:currentColor}

.hdr-act{margin-left:auto;display:flex;align-items:center;gap:10px}
.tel{display:none;align-items:center;gap:7px;text-decoration:none;font-size:.88rem;font-weight:600;opacity:.88}
.tel svg{width:14px;height:14px;fill:currentColor}
.tel:hover{opacity:1}
.btn-book{
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--deep);color:var(--paper);text-decoration:none;
  font-weight:600;font-size:.85rem;padding:11px 16px;border-radius:5px;
  min-height:44px;white-space:nowrap;transition:background .22s;
}
#hdr.on-light .btn-book{background:var(--ink)}
.btn-book:hover{background:var(--ink)}

#burger{width:40px;height:40px;display:grid;place-content:center;gap:5px}
#burger i{display:block;width:20px;height:1.5px;background:currentColor;transition:transform .28s}
#burger[aria-expanded=true] i:first-child{transform:translateY(3.25px) rotate(45deg)}
#burger[aria-expanded=true] i:last-child{transform:translateY(-3.25px) rotate(-45deg)}

body.nav-open #nav{
  display:flex;flex-direction:column;gap:2px;
  position:fixed;inset:calc(var(--sat) + var(--hdr-h)) 0 auto 0;
  background:rgba(15,43,51,.97);backdrop-filter:blur(12px);
  padding:14px var(--gut) 22px;color:var(--paper);z-index:59;
}
body.nav-open #nav a{padding:14px 0;border-bottom:1px solid rgba(233,237,239,.12);font-size:1.02rem}

/* ═══════════ CLARITY HERO ═══════════ */
.hero{
  position:relative;background:var(--paper);color:var(--ink);
  min-height:100vh;min-height:100svh;
  display:flex;flex-direction:column;
  padding:calc(var(--sat) + var(--hdr-h) + 28px) 0 calc(var(--sab) + 22px);
  overflow:hidden;
}
/* The cue is a flow sibling, not an absolute overlay. Absolutely positioned
   it collided with the trust strip whenever the viewport got short enough for
   the centred copy to grow into its band — which is most small phones. */
.hero-in{
  position:relative;width:100%;max-width:var(--maxw);margin:0 auto;padding:0 var(--gut);
  flex:1;display:flex;flex-direction:column;justify-content:center;
}

.eyebrow{
  margin:0 0 20px;font-size:.74rem;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--slate);
}
.hero h1{
  margin:0 0 22px;font-weight:700;line-height:.98;letter-spacing:-.03em;
  font-size:clamp(2.9rem,12.4vw,5.6rem);
}
.hero h1 em{font-family:var(--edit);font-style:italic;font-weight:400;letter-spacing:-.01em;color:var(--deep)}
.lede{
  margin:0 0 32px;max-width:34ch;font-size:clamp(1.02rem,4.2vw,1.24rem);
  line-height:1.55;color:var(--slate);
}
.hero-cta{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:34px}
.hero-cta .btn{flex:1 1 auto;min-width:min(100%,220px)}

.trust{
  list-style:none;margin:0;padding:22px 0 0;border-top:1px solid var(--pale);
  display:flex;flex-wrap:wrap;gap:8px 22px;
  font-size:.82rem;font-weight:600;color:var(--slate);
}
.trust li{position:relative;padding-left:17px}
.trust li::before{
  content:'';position:absolute;left:0;top:.44em;width:8px;height:8px;
  border-left:1.6px solid var(--deep);border-bottom:1.6px solid var(--deep);
  transform:rotate(-45deg) translateY(-1px);
}

/* ═══════════ Hero photograph ═══════════
   Mobile is the master here as everywhere else: a full-bleed block in flow,
   directly under the badges and before the film. Cropped low and slightly
   right so the figure and the open case stay in frame at phone widths.
   Desktop turns the same element into the right-hand half (see min-width:900). */
.hero-photo{
  display:block;position:relative;flex:0 0 auto;
  width:auto;margin:32px calc(var(--gut) * -1) 0;
  aspect-ratio:4/3;overflow:hidden;background:var(--pale);
}
.hero-photo img{
  display:block;width:100%;height:100%;
  object-fit:cover;object-position:52% 88%;
}

/* ═══════════ The approach — first act of the film's own stage ═══════════
   One pinned surface carries both the darkening and the film. Two sequential
   sticky panels can only ever give a gap or an overlap between them. */
.scroll-cue{
  position:relative;z-index:2;flex:0 0 auto;margin-top:44px;
  display:flex;flex-direction:column;align-items:center;gap:11px;
  color:var(--slate);pointer-events:none;text-align:center;
  padding:0 var(--gut);
}
.cue-label{font-size:.71rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase}
/* The sentence carries the lede's size and ink, so it reads as a line of the
   hero's own voice handing the visitor to the film, not as a caption. */
.cue-line{
  margin:0;max-width:46ch;
  font-size:clamp(1.02rem,4.2vw,1.24rem);line-height:1.45;
  letter-spacing:0;text-transform:none;font-weight:400;
  color:var(--ink);text-wrap:balance;
}
/* Chevron, not a mouse: the gesture on a phone is a thumb, and a mouse icon
   would be a desktop metaphor on the master viewport. */
.cue-chev{
  display:block;width:20px;height:20px;margin-top:5px;
  border-right:2.2px solid var(--slate);border-bottom:2.2px solid var(--slate);
  transform:rotate(45deg);opacity:.72;
  animation:cue-fall 2.6s cubic-bezier(.45,0,.55,1) infinite;
}
@keyframes cue-fall{
  0%,100%{transform:translateY(-4px) rotate(45deg);opacity:.45}
  50%{transform:translateY(7px) rotate(45deg);opacity:1}
}
@media (prefers-reduced-motion:reduce){.cue-chev{animation:none;opacity:.72}}

/* ═══════════ THE FILM ═══════════ */
/* 700vh driver. The approach is now only 10vh of it: the stage is
   full-viewport, so ANY flat-colour phase means a screen of nothing if the
   visitor stops there. Shortening could not fix that — only removing it. The
   film now fades up almost immediately and the hero dissolves into frame. */
#film{position:relative;height:860vh;background:var(--ink)}
#stage{
  position:sticky;top:0;overflow:hidden;
  height:100vh;height:100dvh;
  background:var(--ink);
}
#reel,#gl,#bleed{position:absolute;inset:0;width:100%;height:100%}
#bleed{filter:blur(60px) brightness(.55) saturate(1.3);transform:scale(1.18);opacity:0;transition:opacity .4s}
#gl{pointer-events:none;opacity:0;transition:opacity .3s}
#gl.live{opacity:1}
#gl.live + #grain{mix-blend-mode:overlay}

#grain{
  position:absolute;inset:-40%;pointer-events:none;opacity:.13;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
  animation:grainmove 1.1s steps(3) infinite;
}
@keyframes grainmove{0%{transform:translate(0,0)}33%{transform:translate(-3%,2%)}66%{transform:translate(2%,-3%)}100%{transform:translate(0,0)}}
@media (prefers-reduced-motion:reduce){#grain{animation:none}}

/* vignette + a bottom scrim. The film resolves on a bright dry room, so
   white beat copy needs a guaranteed floor of contrast on ANY frame —
   text-shadow alone fails over the pale finale. */
#vig{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(to top,rgba(12,34,41,.80) 0%,rgba(12,34,41,.50) 24%,transparent 54%),
    radial-gradient(122% 78% at 50% 44%,transparent 42%,rgba(15,43,51,.58) 100%);
}
#seam{
  position:absolute;left:0;right:0;bottom:0;height:46%;pointer-events:none;opacity:0;
  background:linear-gradient(to bottom,transparent,var(--seam));
}

/* ── Water-path trace (Ch.1–2) ── */
#trace{
  position:absolute;inset:0;width:100%;height:100%;z-index:9;
  pointer-events:none;opacity:0;
}
#tr-path{
  fill:none;stroke:#8FC3D1;stroke-width:1.6;
  stroke-linecap:square;stroke-linejoin:miter;
  filter:drop-shadow(0 0 6px rgba(12,34,41,.85));
}
.tr-grid path{fill:none;stroke:rgba(233,237,239,.34);stroke-width:.75;stroke-dasharray:3 4}
.tr-n{opacity:0;transition:opacity .45s}
.tr-n.on{opacity:1}
.tr-n rect{fill:none;stroke:#8FC3D1;stroke-width:1.4}
.tr-n text{
  fill:var(--paper);font-family:var(--disp);font-size:11px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;
  paint-order:stroke;stroke:rgba(12,34,41,.8);stroke-width:3px;
}

/* ── Instrumented margins (desktop only) ── */
.mg{
  display:none;position:absolute;top:0;height:100%;z-index:7;
  width:calc(50vw - min(21vw,350px));pointer-events:none;
  fill:none;stroke:rgba(233,237,239,.20);stroke-width:1;
}
#mgl{left:0}
#mgr{right:0}

/* in-world threshold loader (non-blocking) */
#threshold{
  position:absolute;inset:0;z-index:8;display:grid;place-content:center;justify-items:center;gap:16px;
  background:var(--ink);color:var(--pale);opacity:0;pointer-events:none;transition:opacity .45s;
}
#threshold.show{opacity:1}
.mono-load{width:70px;height:70px}
.mono-load .draft{stroke:currentColor;stroke-width:1;opacity:.3;fill:none}
.mono-load .gl-out{stroke:rgba(233,237,239,.26);stroke-width:2.1;fill:none;stroke-linecap:butt;stroke-linejoin:miter}
.mono-load .gl-fill{stroke:#7FB4C2;stroke-width:2.1;fill:none;stroke-linecap:butt;stroke-linejoin:miter}
#threshold p{margin:0;font-size:.74rem;letter-spacing:.15em;text-transform:uppercase;opacity:.55}

/* ── HUD: moisture meter ── */
#hud{
  position:absolute;z-index:12;left:var(--gut);right:var(--gut);
  top:calc(var(--sat) + var(--hdr-h) + 14px);
  color:var(--pale);pointer-events:none;opacity:0;transition:opacity .5s;
  font-variant-numeric:tabular-nums;
}
#hud.show{opacity:1}
/* The luminance flip is sampled from the FILM. On phone the HUD sits over
   the film, so the flip is correct. On desktop it sits in the margin over
   the blurred bleed — flipping there makes it vanish. Mobile only. */
@media (max-width:1023px){
  #hud.on-light{color:var(--ink)}
  #hud.on-light .hud-lbl,#hud.on-light .hud-ch{opacity:.72}
  #hud.on-light .hud-track{background:rgba(15,43,51,.18)}
  #hud.on-light #hudbar{background:var(--deep)}
  #hud.on-light #hudbar.dry{background:#2E9E63}
  #hud.on-light .hud-stat.dry{color:#2E9E63}
}
.hud-row{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.hud-lbl,.hud-ch{font-size:.63rem;letter-spacing:.17em;text-transform:uppercase;opacity:.6}
.hud-val{display:flex;align-items:baseline;gap:4px}
.hud-val b{font-size:1.34rem;font-weight:600;letter-spacing:-.02em}
.hud-val i{font-style:normal;font-size:.58rem;letter-spacing:.12em;opacity:.6}
.hud-track{height:1.5px;background:rgba(233,237,239,.2);margin:9px 0 8px;overflow:hidden}
#hudbar{height:100%;width:100%;background:#8FC3D1;transform-origin:left;transition:background .6s}
#hudbar.dry{background:#6FCF97}
.hud-stat{font-size:.63rem;letter-spacing:.17em;text-transform:uppercase;opacity:.85}
.hud-stat.dry{color:#6FCF97;opacity:1}

/* ── Beats ── */
.beats{position:absolute;inset:0;z-index:10;pointer-events:none}
.beat{
  position:absolute;left:var(--gut);right:var(--gut);
  bottom:calc(var(--sab) + 116px);
  opacity:0;color:var(--paper);will-change:opacity,transform;
}
.beat h2{
  margin:0 0 12px;font-weight:700;line-height:1.02;letter-spacing:-.032em;
  font-size:clamp(2.15rem,9.4vw,3.5rem);
  text-shadow:0 2px 34px rgba(6,20,25,.62);
}
.beat h2 em{font-family:var(--edit);font-style:italic;font-weight:400;letter-spacing:-.012em}
.beat p{
  margin:0;max-width:30ch;font-size:clamp(.95rem,3.9vw,1.1rem);line-height:1.5;
  color:#E7EBED;text-shadow:0 1px 20px rgba(6,20,25,.66);
}
/* sits clear of the content riding up into the stage's exit tail */
.beat.finale{bottom:calc(var(--sab) + 190px)}
.beat.finale .spring{
  margin-top:26px;pointer-events:auto;will-change:transform;
  box-shadow:0 12px 40px rgba(6,20,25,.42);
}

/* ── Station ── */
#station{
  position:absolute;z-index:14;left:0;right:0;
  bottom:calc(var(--sab) + 26px);
  display:flex;flex-direction:column;align-items:center;gap:11px;
  opacity:0;pointer-events:none;transition:opacity .4s;
}
#station.show{opacity:1;pointer-events:auto}
.st-hint{
  margin:0;font-size:.68rem;font-weight:600;letter-spacing:.19em;text-transform:uppercase;
  color:var(--paper);text-shadow:0 1px 14px rgba(6,20,25,.8);
  animation:breathe 2.4s ease-in-out infinite;
}
@keyframes breathe{0%,100%{opacity:.55}50%{opacity:1}}
@media (prefers-reduced-motion:reduce){.st-hint{animation:none;opacity:.85}}
#st-btn{
  position:relative;width:78px;height:78px;display:grid;place-content:center;
  touch-action:none;-webkit-tap-highlight-color:transparent;
}
#st-btn svg{position:absolute;inset:3px;width:72px;height:72px;transform:rotate(-90deg)}
.st-bg{fill:rgba(6,20,25,.42);stroke:rgba(233,237,239,.28);stroke-width:2}
.st-fg{
  fill:none;stroke:#8FC3D1;stroke-width:2.6;stroke-linecap:round;
  stroke-dasharray:188.5;stroke-dashoffset:188.5;
}
.st-core{
  width:16px;height:16px;border-radius:50%;background:var(--paper);
  box-shadow:0 0 0 0 rgba(143,195,209,.5);transition:transform .18s,box-shadow .3s;
}
#st-btn.holding .st-core{transform:scale(.72);box-shadow:0 0 0 13px rgba(143,195,209,.16)}
#station.done .st-fg{stroke:#6FCF97}
#station.done .st-core{background:#6FCF97}

/* ── Fast path + sound ── */
#skipfilm{
  position:absolute;z-index:13;left:50%;transform:translateX(-50%);
  bottom:calc(var(--sab) + 10px);
  font-size:.66rem;font-weight:600;letter-spacing:.15em;text-transform:uppercase;
  color:var(--pale);text-decoration:none;padding:9px 14px;
  opacity:0;transition:opacity .4s,color .25s;pointer-events:none;
}
#skipfilm.show{opacity:1;pointer-events:auto}
#skipfilm:hover{color:var(--paper)}

#snd{
  position:absolute;z-index:14;right:var(--gut);
  bottom:calc(var(--sab) + 30px);
  width:46px;height:46px;display:flex;align-items:flex-end;justify-content:center;gap:3px;
  padding:13px 0;border-radius:50%;background:rgba(6,20,25,.34);
  backdrop-filter:blur(6px);opacity:0;transition:opacity .4s;pointer-events:none;
}
#snd.show{opacity:1;pointer-events:auto}
#snd i{display:block;width:2.5px;height:5px;background:var(--paper);border-radius:1px;transition:height .2s}
#snd[aria-pressed=true] i{animation:eq .9s ease-in-out infinite}
#snd[aria-pressed=true] i:nth-child(2){animation-delay:.15s}
#snd[aria-pressed=true] i:nth-child(3){animation-delay:.3s}
#snd[aria-pressed=true] i:nth-child(4){animation-delay:.45s}
@keyframes eq{0%,100%{height:5px}50%{height:15px}}
@media (prefers-reduced-motion:reduce){#snd[aria-pressed=true] i{animation:none;height:11px}}

/* ── Persistent quiet CTA ── */
/* Corner-anchored, not centred: a centre-bottom pill parks itself on the
   middle of every paragraph. Right corner keeps it in the thumb zone
   without covering the column of text being read. */
#pill{
  position:fixed;z-index:55;right:var(--gut);
  bottom:calc(var(--sab) + 14px);
  background:var(--deep);color:var(--paper);text-decoration:none;
  font-weight:600;font-size:.84rem;padding:12px 20px;border-radius:100px;
  min-height:46px;display:inline-flex;align-items:center;
  box-shadow:0 10px 34px rgba(6,20,25,.36);
  opacity:0;pointer-events:none;transform:translateY(26px);
  transition:opacity .4s,transform .4s;
}
#pill.show{opacity:1;transform:translateY(0);pointer-events:auto}
@media (min-width:1024px){#pill{right:26px}}

/* ═══════════ AFTER-FILM CONTENT ═══════════ */
/* The stage is sticky, so it always has one viewport of scrolling away after
   the film ends. Left alone that tail plus a deep gradient put ~750px of
   near-empty beige between the finale and the offer. The content starts at
   exactly the seam hex the film is fading to, so it can ride up into the
   tail with no visible join. */
#content{
  position:relative;z-index:20;background:var(--paper);color:var(--ink);
  margin-top:-20vh;margin-top:-20dvh;
}
#content::before{
  content:'';display:block;height:110px;
  background:linear-gradient(to bottom,var(--seam),var(--paper));
}
#content section{padding:clamp(64px,13vw,120px) 0}

.kicker{
  margin:0 0 14px;font-size:.7rem;font-weight:600;letter-spacing:.17em;
  text-transform:uppercase;color:var(--deep);
}
#content h2{
  margin:0 0 22px;font-weight:700;line-height:1.04;letter-spacing:-.03em;
  font-size:clamp(2rem,7.6vw,3.3rem);
}
#content h2 em{font-family:var(--edit);font-style:italic;font-weight:400}
#content h3{margin:0 0 10px;font-weight:600;font-size:1.16rem;letter-spacing:-.012em}
#content p{margin:0 0 17px;line-height:1.65;color:var(--slate);font-size:1rem}
#content .big{
  font-size:clamp(1.06rem,4.3vw,1.3rem);line-height:1.55;color:var(--ink);
  max-width:44ch;margin-bottom:26px;
}
.fine{font-size:.87rem;color:var(--slate)}
.cta-row{display:flex;flex-wrap:wrap;gap:12px;margin:8px 0 22px}

/* offer */
.s-offer{background:var(--paper)}
.s-offer h2{max-width:16ch}

/* honest answer */
.s-honest{background:var(--ink);color:var(--paper)}
.s-honest .kicker{color:#8FC3D1}
.s-honest h2{color:var(--paper)}
.s-honest p{color:#E7EBED}
.s-honest .big{color:var(--paper)}
.ticks{list-style:none;margin:26px 0;padding:0;display:grid;gap:20px}
.ticks li{position:relative;padding-left:30px;line-height:1.6;color:#E7EBED}
.ticks li b{color:var(--paper);font-weight:600}
.ticks li::before{
  content:'';position:absolute;left:2px;top:.4em;width:11px;height:11px;
  border-left:1.8px solid #8FC3D1;border-bottom:1.8px solid #8FC3D1;transform:rotate(-45deg);
}
.promise{
  margin:34px 0 14px;padding:26px 0;border-top:1px solid rgba(233,237,239,.16);
  border-bottom:1px solid rgba(233,237,239,.16);
  font-family:var(--edit);font-style:italic;font-weight:400;
  font-size:clamp(1.4rem,6vw,2.2rem);line-height:1.24;color:var(--paper);
}
.s-honest .fine{color:#A9B2B8}

/* method */
.s-method{background:var(--paper)}
.steps{list-style:none;margin:34px 0 0;padding:0;display:grid;gap:2px}
.steps li{padding:28px 0;border-top:1px solid var(--pale);position:relative}
.steps li:last-child{border-bottom:1px solid var(--pale)}
.steps .n{
  display:block;font-family:var(--edit);font-size:.95rem;color:var(--deep);
  margin-bottom:9px;letter-spacing:.06em;
}
.steps p{margin:0;max-width:56ch}
.nested{margin-top:44px;padding:26px;background:var(--pale);border-radius:8px}
.nested .kicker{margin-bottom:16px}
.chain{list-style:none;margin:0;padding:0;counter-reset:c;display:grid;gap:11px}
.chain li{counter-increment:c;font-size:.94rem;color:var(--slate);display:flex;flex-wrap:wrap;gap:4px 9px;align-items:baseline}
.chain li::before{
  content:counter(c);font-family:var(--edit);color:var(--deep);
  min-width:16px;font-size:.85rem;
}
.chain li b{color:var(--ink);font-weight:600}
.chain li span{font-size:.85rem;opacity:.8}

/* guarantee */
.s-guarantee{background:var(--deep);color:var(--paper)}
.s-guarantee .kicker{color:#A9D4DE}
.s-guarantee h2{color:var(--paper)}
.s-guarantee .big{color:var(--paper)}
.s-guarantee p{color:#E7EBED}
.s-guarantee .fine{color:#A9B2B8}
.layers{display:grid;gap:2px;margin:36px 0 26px}
.layer{padding:26px 0;border-top:1px solid rgba(233,237,239,.18)}
.layer:last-child{border-bottom:1px solid rgba(233,237,239,.18)}
.ln{
  margin:0 0 9px!important;font-family:var(--edit);font-style:italic;
  font-size:.9rem;color:#A9D4DE!important;
}
.layer h3{color:var(--paper)}
.layer p{margin:0;max-width:52ch}

/* cards */
.s-cards{background:var(--paper)}
.cards{display:grid;gap:20px}
.card{
  background:#fff;border:1px solid var(--pale);border-radius:10px;
  padding:clamp(26px,6vw,40px);
}
.card h3{font-size:clamp(1.3rem,5.2vw,1.7rem);letter-spacing:-.022em;margin-bottom:16px;line-height:1.14}
.card p{font-size:.98rem}
.card em{font-style:italic;font-family:var(--edit)}
.card .btn{margin-top:10px}

/* ═══════════ credentials ═══════════
   The guarantee's layer grammar, on a pale ground: italic label, title, one
   plain sentence, hairline between. The section heading is a real h2 so the
   item titles have something to sit under; it is dressed as the kicker every
   other section uses, and the italic tagline reads as the intro beneath it. */
.s-creds{background:var(--pale)}
#content .s-creds h2.kicker{
  margin:0 0 14px;font-size:.7rem;font-weight:600;letter-spacing:.17em;
  line-height:1.4;text-transform:uppercase;color:var(--deep);
}
.s-creds .quote{
  font-family:var(--edit);font-style:italic;font-size:clamp(1.2rem,5vw,1.7rem);
  line-height:1.32;color:var(--deep);max-width:24ch;margin:0;
}
.creds{list-style:none;margin:34px 0 0;padding:0;display:grid;gap:2px}
.cred{padding:24px 0;border-top:1px solid rgba(15,43,51,.15)}
.cred:last-child{border-bottom:1px solid rgba(15,43,51,.15)}
.cl{
  margin:0 0 9px;font-family:var(--edit);font-style:italic;
  font-size:.9rem;color:var(--deep);
}
.cred h3{margin:0 0 9px;font-size:1.06rem;line-height:1.3;color:var(--ink)}
.cred p{margin:0;max-width:52ch;font-size:.95rem;line-height:1.6;color:var(--slate)}
/* Reserved logo space. Sized for a supplied badge file and deliberately not
   blank while it waits: it carries the same tick the trust rows use, so the
   slot reads as part of the design rather than as a gap. */
.cred-mark{
  display:grid;place-content:center;width:54px;height:36px;margin:0 0 15px;
  border-radius:6px;background:rgba(15,43,51,.055);
  box-shadow:inset 0 0 0 1px rgba(15,43,51,.09);
}
/* the trust rows' tick, drawn with a long arm so the plate reads as a mark
   and not as a caret */
.cred-mark::before{
  content:'';width:14px;height:8px;
  border-left:1.7px solid var(--deep);border-bottom:1.7px solid var(--deep);
  transform:rotate(-45deg) translate(1px,-2px);opacity:.45;
}
.badge-slot{
  flex:0 0 auto;display:grid;place-content:center;
  width:76px;height:44px;border:1px dashed var(--mist);border-radius:5px;
  font-size:.6rem;letter-spacing:.1em;text-transform:uppercase;color:var(--slate);
}

/* Four items, so they take a row of four equal cards rather than the
   guarantee's three columns. Breaks at 900 with the rest of the desktop
   layout; the cards carry their own edges, so the mobile hairlines go. */
@media (min-width:900px){
  .s-creds .quote{max-width:40ch}
  .creds{grid-template-columns:repeat(4,1fr);gap:20px;margin-top:40px}
  .cred{
    padding:26px 22px;border:1px solid rgba(15,43,51,.11);border-radius:10px;
    background:#fff;
  }
  .cred:last-child{border-bottom:1px solid rgba(15,43,51,.11)}
  .cred h3{font-size:1rem}
  .cred p{font-size:.92rem}
}

/* areas */
.s-areas{background:var(--paper)}
.zones{display:grid;gap:26px;margin:34px 0 26px}
.zone{padding-top:18px;border-top:1px solid var(--pale)}
.zone h3{font-size:1rem;margin-bottom:7px}
.zone p{margin:0;font-size:.92rem;line-height:1.7}

/* faq */
.s-faq{background:var(--ink);color:var(--paper)}
.s-faq .kicker{color:#8FC3D1}
.s-faq h2{color:var(--paper)}
.s-faq details{border-top:1px solid rgba(233,237,239,.16)}
.s-faq details:last-of-type{border-bottom:1px solid rgba(233,237,239,.16)}
.s-faq summary{
  list-style:none;cursor:pointer;padding:23px 40px 23px 0;position:relative;
  font-weight:600;font-size:1.04rem;line-height:1.35;color:var(--paper);
}
.s-faq summary::-webkit-details-marker{display:none}
.s-faq summary::after{
  content:'';position:absolute;right:6px;top:29px;width:10px;height:10px;
  border-right:1.7px solid #8FC3D1;border-bottom:1.7px solid #8FC3D1;
  transform:rotate(45deg);transition:transform .26s;
}
.s-faq details[open] summary::after{transform:rotate(-135deg);top:33px}
.s-faq details p{margin:0 0 24px;max-width:62ch;color:#E7EBED}

/* final */
.s-final{background:var(--deep);color:var(--paper);text-align:center}
/* deep-teal button on a deep-teal section renders as bare text — invert it */
.s-final .btn.primary{background:var(--paper);color:var(--ink)}
.s-final .btn.primary:hover{background:#fff}
.s-final h2{color:var(--paper)}
.s-final .big{color:#E7EBED;margin:0 auto 30px;max-width:38ch}
/* The paragraph is a #content p, and that ID-carrying rule sets its side
   margins, so the auto margins above never applied and the block sat hard
   against the left of the column while everything around it was centred.
   Matching the ID puts it back on the section's centre line. */
#content .s-final .big{margin-left:auto;margin-right:auto;max-width:38ch}
.s-final .fine{color:#A9B2B8;margin-top:20px}
.s-final .fine a{color:var(--paper)}

/* Desktop closing CTA: one compact centred block.
   The headline's break is a <br> written for the phone, so it is switched off
   here and the line holds itself; the size only starts easing below about
   1150, where a single line would otherwise outrun the column. The paragraph
   gets a measure wide enough to stay on one line (the sentence measures ~84ch
   in Sora, so the cap sits above that rather than at the 60ch a shorter line
   would want). Rules carry #content because that is where the defaults they
   replace live. Mobile keeps the stacked rhythm untouched. */
@media (min-width:900px){
  #content .s-final{padding:clamp(56px,5vw,84px) 0}
  .s-final h2 br{display:none}
  #content .s-final h2{font-size:clamp(2rem,4.6vw,3.3rem);margin-bottom:18px}
  #content .s-final .big{max-width:88ch;margin-bottom:22px}
  #content .s-final .fine{margin-top:12px}
}

/* footer */
footer{background:var(--ink);color:#A9B2B8;padding:clamp(52px,10vw,84px) 0 0}
.foot{display:grid;gap:34px;padding-bottom:44px}
.fcol h4{margin:0 0 13px;font-size:.7rem;font-weight:600;letter-spacing:.17em;text-transform:uppercase;color:var(--paper)}
.fcol p{margin:0 0 8px;line-height:1.8;font-size:.92rem}
.fcol a{text-decoration:none}
.fcol a:hover{color:var(--paper);text-decoration:underline}
.fcol .mono{width:38px;height:38px;color:var(--paper);margin-bottom:14px}
.tag{font-family:var(--edit);font-style:italic;font-size:.98rem;color:var(--mist)}
.foot-b{
  display:flex;flex-wrap:wrap;gap:8px 26px;justify-content:space-between;
  padding:22px var(--gut);border-top:1px solid rgba(233,237,239,.13);
  font-size:.78rem;color:#A9B2B8;
}
.foot-b p{margin:0}

/* ═══════════ DESKTOP — THE CINEMA STAGE ═══════════ */
@media (min-width:1024px){
  :root{--hdr-h:70px}
  #nav{display:flex;gap:26px;margin-left:26px}
  .tel{display:flex}
  #burger{display:none}
  #hdr{padding:calc(var(--sat) + 16px) 34px 16px}

  /* The film's own light floods the full viewport behind the stage. */
  #bleed{opacity:1}
  .mg{display:block}

  /* The margin HUD reads as a survey instrument sitting IN that light:
     a smoked-glass panel with drafting rules, not a black box. It gives
     the readout a guaranteed contrast floor over a bright bleed while
     keeping the margins lit. */
  #hud{
    padding:16px 18px 14px;
    background:rgba(10,30,37,.62);
    -webkit-backdrop-filter:blur(3px) saturate(.9);
    backdrop-filter:blur(3px) saturate(.9);
    border-left:1px solid rgba(233,237,239,.34);
    box-shadow:inset 0 0 0 1px rgba(233,237,239,.07);
  }
  #hud::before,#hud::after{
    content:'';position:absolute;left:-1px;width:9px;height:1px;
    background:rgba(233,237,239,.5);
  }
  #hud::before{top:-1px}
  #hud::after{bottom:-1px}
  #hud .hud-lbl,#hud .hud-ch{opacity:.9}
  #hud .hud-track{background:rgba(233,237,239,.28)}
  #reel{
    left:50%;transform:translateX(-50%);
    width:min(42vw,700px);
    box-shadow:0 0 90px rgba(6,20,25,.6),0 0 0 1px rgba(233,237,239,.09);
  }
  #gl{left:50%;transform:translateX(-50%);width:min(42vw,700px)}
  /* the trace is registered to the film, so it rides the stage, not the page */
  #trace{left:50%;transform:translateX(-50%);width:min(42vw,700px)}
  #vig{background:radial-gradient(60% 70% at 50% 46%,transparent 46%,rgba(15,43,51,.72) 100%)}

  /* margins become the theatre */
  #hud{left:44px;right:auto;width:min(20vw,250px);top:calc(var(--sat) + var(--hdr-h) + 34px)}
  .beat{
    left:auto;right:44px;width:min(27vw,380px);
    bottom:auto;top:50%;transform:translateY(-50%);
    text-align:left;
  }
  .beat h2{font-size:clamp(2rem,2.8vw,2.9rem)}
  .beat.finale{bottom:auto}
  #station{left:auto;right:0;width:min(27vw,380px);bottom:76px}
  #skipfilm{left:50%;bottom:26px}
  #snd{right:44px;bottom:44px}

  .hero{padding-top:calc(var(--sat) + var(--hdr-h) + 40px)}
  .hero h1{font-size:clamp(4rem,6.6vw,6.4rem)}
  .hero-cta .btn{flex:0 0 auto;min-width:0}

  .cards{grid-template-columns:1fr 1fr;gap:26px}
  .zones{grid-template-columns:repeat(3,1fr);gap:32px}
  .layers{grid-template-columns:repeat(3,1fr);gap:2px 32px}
  .layer{border-top:1px solid rgba(233,237,239,.18)}
  .layer:last-child{border-bottom:0}
  .steps{grid-template-columns:repeat(3,1fr);gap:0 32px}
  .steps li:last-child{border-bottom:0}
  /* .creds is a row of four from 900 up — see the credentials block above */
  .foot{grid-template-columns:1.4fr 1fr 1fr 1fr;gap:44px}
  #content section{padding:clamp(88px,9vw,142px) 0}
  #content::before{height:150px}
}

@media (min-width:1400px){
  .beat{right:calc(50vw - min(21vw,350px) - 420px);width:380px}
  #hud{left:calc(50vw - min(21vw,350px) - 290px)}
}

/* ═══════════ Hero split — text left, photograph right ═══════════
   Geometry reconciled against design/hero-mockup.png by measurement. The
   mockup is a ~1910px-wide render, so its LAYOUT is expressed here in vw and
   holds at any width, while its small type sits at ordinary absolute sizes
   (its badges measure 13.1px, ours 13.12px) and stays in rem.
   Measured fractions of viewport width, mockup -> used here:
     content inset      0.0764  -> 7.64vw  (measured on the rule, which
                                              starts exactly on the box edge)
     eyebrow ink top    0.1068  -> padding-top 10.5vw
     headline font      0.0548  -> 5.48vw
     headline ink right 0.5497  -> column 47.5vw
     photo dissolve     0.45 to 0.58 of the viewport
   The centred 1180 container does not apply in the hero: the mockup's margins
   are a fraction of the viewport, not a capped column. */
@media (min-width:900px){
  .hero{padding-top:0}
  .hero-in{
    display:block;
    max-width:none;width:100%;margin:0;
    padding:10.5vw 0 0 7.64vw;
    position:static;   /* so the photograph anchors to .hero, not to this column */
  }
  /* Copy paints over the photograph's dissolve, as in the mockup. */
  .eyebrow,.hero h1,.lede,.hero-cta,.trust{position:relative;z-index:1;max-width:47.5vw}
  .lede{max-width:min(47.5vw,34ch)}

  /* Restored to the mockup's scale. The column above is sized so
     "Damp, diagnosed" holds one line at it: the string needs 8.55x the font
     size, 5.48vw x 8.55 = 46.9vw, inside a 47.5vw column at every width. */
  .hero h1{font-size:clamp(2.6rem,5.48vw,7rem)}

  /* Buttons measured off the mockup at 1910 wide, expressed as vw so the same
     absolute values return at that width:
       box height 56px = 2.932vw      h-padding 26.5px = 1.387vw
       label 16.68px = 0.8732vw       gap between 13px = 0.681vw
     (label size from "Book a survey" ink: 117px there against 110px here at
     15.68px.) */
  .hero-cta{gap:clamp(8px,0.681vw,14px)}
  .hero-cta .btn{
    flex:0 0 auto;min-width:0;
    font-size:clamp(11px,0.8732vw,17px);
    padding:0 clamp(13px,1.285vw,26px);
    min-height:clamp(36px,2.932vw,58px);
  }

  /* Lede: "We find the cause before anyone talks about a" is identical in both
     and measures 476px in the mockup against 455px here at 19.84px, giving
     20.76px = 1.0869vw. Line spacing there is 32px = 1.542 of that. */
  /* the cue's sentence tracks the lede exactly, at both viewports */
  .lede,.cue-line{font-size:clamp(13px,1.0869vw,22px);line-height:1.54}

  /* Vertical rhythm, ink to ink, measured on the mockup at 1910 and carried
     across as fractions of viewport width:
       properly. > lede    21px = 0.01099  ->  15.8px at 1440
       lede > buttons      40px = 0.02094  ->  30.2px
       buttons > divider   36px = 0.01885  ->  27.1px
       divider > badges    28px = 0.01466  ->  21.1px
     The margins below are what land those gaps once each element's own line
     box is accounted for; they were set by measuring the render, not derived. */
  .eyebrow{margin-bottom:0.96vw}
  .hero h1{margin-bottom:1.22vw}
  .lede{margin-bottom:1.69vw}
  .hero-cta{margin-bottom:1.78vw}
  /* Badge row matched to the mockup by measurement. "TrustMark registered" is
     the one string identical in both: 145px there at 1910 wide, 139px here at
     1440, giving the mockup 13.49px = 0.00706 of viewport against our 13.12px
     = 0.00911. Matching the fraction puts it at 10.17px here. Ticks and gaps
     move to em so the whole row scales as one: the mockup's tick is 0.74em,
     tick-to-text 0.74em, badge-to-badge 1.70em. Weight stays 600 - measured
     ink per em squared is 3.02 there against 2.72 here, so the mockup is if
     anything a shade heavier, and only the size was reading large.
     width:max-content puts the rule on the row, as the mockup has it. */
  .trust{
    padding-top:1.21vw;
    font-size:clamp(10px,0.706vw,13.5px);
    gap:.6em 1.70em;
    /* max-content puts the rule on the row; the column cap stops the row
       running onto the photograph at narrower desktop widths, where it wraps
       instead. */
    width:max-content;max-width:47.5vw;
  }
  .trust li{padding-left:1.48em}
  .trust li::before{width:.62em;height:.62em;top:.46em;border-width:.11em}

  /* Photograph: top on the header's bottom edge, bottom near the hero's, and
     it owns the viewport from 45% rightwards. Absolute against .hero so it can
     reach the right edge; the dissolve is baked into the file, not applied
     here. object-position pins the left edge so the baked ramp always lands on
     the box's left, even at widths where cover crops horizontally. */
  /* bottom: the photograph stops well clear of the scroll cue, which is
     bottom-anchored in the hero, so the cue reads as its own moment rather
     than as a caption hanging off the picture. On desktop this offset IS the
     gap: the hero is exactly one viewport and the cue hangs off its bottom
     edge, so the only way to open space above the cue is to end the picture
     higher. The clamp holds the clearance on short laptop viewports, where a
     plain vh would let the two meet. */
  .hero-photo{
    position:absolute;
    top:calc(var(--sat) + var(--hdr-h));bottom:clamp(175px,22vh,260px);
    left:45vw;right:0;width:auto;height:auto;
    margin:0;aspect-ratio:auto;z-index:0;
  }
  .hero-photo img{position:absolute;inset:0;object-position:0% 78%}
  .hero-photo{
    -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 7%,#000 92%,transparent 100%);
    mask-image:linear-gradient(to bottom,transparent 0,#000 7%,#000 92%,transparent 100%);
    -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
    -webkit-mask-size:100% 100%;mask-size:100% 100%;
  }
}

/* ═══════════ REDUCED MOTION — the editorial fallback ═══════════ */
@media (prefers-reduced-motion:reduce){
  #film{height:auto}
  #stage{position:relative;height:auto;min-height:0}
  #reel,#gl,#bleed,#grain,#vig,#seam,#threshold,#hud,#station,#snd,#skipfilm{display:none}
  .beats{position:static;padding:0}
  .beat{
    position:relative;left:auto;right:auto;bottom:auto;top:auto;transform:none;
    opacity:1!important;width:auto;
    padding:clamp(46px,10vw,86px) var(--gut);
    max-width:var(--maxw);margin:0 auto;
  }
  .beat + .beat{border-top:1px solid rgba(233,237,239,.14)}
  .beat h2{text-shadow:none}
  .beat p{text-shadow:none}
  .beat.finale .spring{margin-top:22px}
  #content::before{display:none}
}
/* Same fallback when frames genuinely fail to load */
body.no-film #film{height:auto}
body.no-film #stage{position:relative;height:auto}
body.no-film #reel,body.no-film #gl,body.no-film #bleed,body.no-film #grain,
body.no-film #vig,body.no-film #seam,body.no-film #threshold,body.no-film #hud,
body.no-film #station,body.no-film #snd,body.no-film #skipfilm{display:none}
body.no-film .beats{position:static}
body.no-film .beat{
  position:relative;left:auto;right:auto;bottom:auto;top:auto;transform:none;
  opacity:1!important;width:auto;padding:clamp(46px,10vw,86px) var(--gut);
  max-width:var(--maxw);margin:0 auto;
}
body.no-film .beat + .beat{border-top:1px solid rgba(233,237,239,.14)}
body.no-film #content::before{display:none}

/* placeholder slot styling — visibly provisional, never mistaken for live copy */
.revlink[data-slot]{
  display:inline-block;border-bottom:1px dashed var(--mist);
  padding-bottom:2px;color:var(--slate);font-style:italic;
}
.revlink[href]{border-bottom-style:solid;font-style:normal;color:var(--deep)}

/* Provisional copy slot — same idiom as .revlink: dashed and italic while the
   value is unconfirmed, plain once the attribute is dropped. Keeps an
   unverified scheme name from reading as a settled accreditation claim. */
.term{display:block;margin-top:3px;font-size:.78rem;color:var(--slate);line-height:1.35}
.term[data-slot]{border-bottom:1px dashed var(--mist);padding-bottom:2px;font-style:italic}

@media (prefers-reduced-motion:reduce){ .scroll-cue{display:none} }
body.no-film .scroll-cue{display:none}

/* ═══════════ Contrast — dark-section overrides ═══════════
   #content p and #content .big carry an ID, so they out-specify every
   .s-* section rule below them. That silently dropped dark-section body
   copy back to slate, and rendered .big ink-on-ink at 1:1 — invisible.
   Matching the ID restores the intended palette.
   Body on teal ≥ #E7EBED, headings #F7F8F9, quiet text #BFC7CB
   (plain --mist measures 4.43:1 on --deep, marginally under AA).
   Verified by scripts/contrast.js at both viewports. */
:root{--quiet:#BFC7CB}

#content .s-honest p,
#content .s-guarantee p,
#content .s-guarantee .layer p,
#content .s-faq details p{color:var(--pale)}

#content .s-honest .big,
#content .s-guarantee .big{color:var(--paper)}
#content .s-final .big{color:var(--pale)}

#content .s-honest .kicker,
#content .s-faq .kicker{color:#8FC3D1}
#content .s-guarantee .kicker{color:#A9D4DE}
#content .s-guarantee .ln{color:#A9D4DE}

#content .s-honest .fine,
#content .s-guarantee .fine,
#content .s-final .fine{color:var(--quiet)}

/* The brand slate #63707A measures 4.24:1 on --pale #E7EBED — just under AA.
   It passes on --paper (4.78:1), so rather than move a brand colour globally,
   the two pale-ground blocks scope a fractionally darker slate. Reads as the
   same grey; measures 5.22:1. */
.nested,.s-creds{--slate:#56626B}
.chain li span{opacity:1}

/* ═══════════ FINALE — put it right ═══════════
   Deliberately unlike station 1. That one is cool water physics on a
   small ring; this is larger, carries the monogram, and resolves to the
   same green the meter's verdict uses. UI stays on-palette — the warmth
   in the moment comes from the dry-room frame itself, not a new colour. */
#heal{
  position:absolute;z-index:15;left:0;right:0;
  bottom:calc(var(--sab) + 26px);
  display:flex;flex-direction:column;align-items:center;gap:13px;
  opacity:0;pointer-events:none;transition:opacity .5s;
}
#heal.show{opacity:1;pointer-events:auto}
#heal.done{opacity:0;pointer-events:none}
.hl-hint{
  margin:0;font-size:.7rem;font-weight:600;letter-spacing:.19em;text-transform:uppercase;
  color:var(--paper);
  /* this is the conversion moment and it sits over a bright frame —
     it carries its own ground rather than trusting the scrim */
  padding:7px 15px;border-radius:100px;
  background:rgba(8,26,32,.62);
  -webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);
  animation:breathe 2.6s ease-in-out infinite;
}
@media (prefers-reduced-motion:reduce){.hl-hint{animation:none;opacity:.9}}
#hl-btn{
  position:relative;width:92px;height:92px;display:grid;place-content:center;
  touch-action:none;-webkit-tap-highlight-color:transparent;
}
.hl-ring{position:absolute;inset:4px;width:84px;height:84px;transform:rotate(-90deg)}
.hl-bg{fill:rgba(8,26,32,.58);stroke:rgba(233,237,239,.5);stroke-width:2}
.hl-fg{
  fill:none;stroke:var(--pale);stroke-width:3;stroke-linecap:round;
  stroke-dasharray:219.9;stroke-dashoffset:219.9;
  transition:stroke .4s;
}
#hl-btn.holding .hl-fg{stroke:#B7E3C6}
.hl-mono{width:34px;height:34px;color:var(--paper);transition:transform .2s,color .4s}
.hl-mono .draft{stroke:currentColor;stroke-width:1;opacity:.45;fill:none}
.hl-mono .gl{stroke:currentColor;stroke-width:2.4;fill:none;stroke-linecap:butt;stroke-linejoin:miter}
#hl-btn.holding .hl-mono{transform:scale(.92)}
#heal.sealed .hl-fg{stroke:#6FCF97}
#heal.sealed .hl-mono{color:#6FCF97}

/* the finale beat is gated on the heal completing, not on scroll */
.beat.finale{opacity:0;transition:opacity .75s ease-out}
.beat.finale.on{opacity:1}

/* ═══════════ Booking embed ═══════════ */
.booker{
  margin-top:34px;border:1px solid var(--pale);border-radius:12px;
  overflow:hidden;background:#fff;
}
.booker-head{
  display:flex;align-items:center;gap:9px;
  padding:13px 18px;border-bottom:1px solid var(--pale);
  font-size:.72rem;font-weight:600;letter-spacing:.15em;text-transform:uppercase;
  color:var(--slate);
}
.bk-dot{
  width:7px;height:7px;border-radius:50%;background:#2E9E63;flex:0 0 auto;
  box-shadow:0 0 0 3px rgba(46,158,99,.16);
}
.booker iframe{
  display:block;width:100%;height:620px;border:0;background:#fff;
}
.booker-fb{
  margin:0!important;padding:14px 18px;border-top:1px solid var(--pale);
  font-size:.85rem;color:var(--slate);
}
.booker-fb a{color:var(--deep);font-weight:600}
@media (min-width:1024px){.booker iframe{height:720px}}
