/* ==========================================================================
   Norvi : cold coffee, NIGHT theme
   A warm near-black ground, cream type, amber only on numerals, and one red
   that belongs to the brand: the signature, the headline's red words, the
   buttons and focus. Nothing red lives in the photographs.
   ========================================================================== */

:root{
  --canvas:#13100E;        /* warm near-black, tinted toward the night picture's shadows */
  --panel:#1D1916;         /* cards, rows */
  --raised:#27221E;        /* inputs, hovered rows, selected states */
  --text-primary:#F3ECE1;  /* cream, the mug's glaze */
  --text-secondary:#A89F94;
  --accent:#C81E1E;        /* Norvi red: button fills, the mark, focus */
  --accent-hover:#A81717;
  --accent-text:#EC5A58;   /* red as text: 5.57:1 on the canvas, 4.7:1 on a card */
  --accent-muted:#3A1512;  /* whisper level */
  --ember:#F2B86B;         /* amber numerals only: times, prices, counts */
  --oxblood:#5A110F;
  --oxblood-deep:#380A08;
  --line:#3A332D;          /* decorative hairlines */
  --line-mid:#4A423B;      /* card edges */
  --line-strong:#7A7066;   /* interactive borders, 3.9:1 */

  /* owner's pick, feedback round 1 (2026-09-24): modern, with warmth */
  --display:'Bricolage Grotesque',system-ui,sans-serif;
  --body:'Geist',system-ui,sans-serif;
  --mono:'Geist Mono',ui-monospace,monospace;

  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-io:cubic-bezier(.65,0,.35,1);

  /* a dark lift behind light type on the picture */
  --tshadow:0 1px 2px rgba(10,8,7,.9),0 3px 14px rgba(10,8,7,.7),0 10px 44px rgba(10,8,7,.6);

  --gut:clamp(16px,4vw,64px);
  --measure:62ch;
}

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

/* Bricolage Grotesque is variable in optical size. The display cut (opsz 96)
   has the tight joins and the character; the text cut is too plain for a
   headline, so every display use asks for 96. */
.h-display,.h2,.gate-n,.qs summary,.f-serif{
  font-variation-settings:'opsz' 96;
}

html,body{
  overflow-x:hidden;      /* fallback first */
  overflow-x:clip;
}
html{scroll-behavior:smooth}

body{
  margin:0;
  background:var(--canvas);
  color:var(--text-primary);
  font-family:var(--body);
  font-size:clamp(16px,1.05vw,18px);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  opacity:0;
  animation:pagein .7s var(--ease-out) forwards;
}
@keyframes pagein{to{opacity:1}}

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

.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--accent);color:#fff;padding:12px 18px;border-radius:0 0 8px 0;font-family:var(--mono);font-size:13px}
.skip:focus{left:0}

:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}

/* ── the one fixed environment layer ─────────────────────────────────
   Slow rings: a phone ringing, and the ring a cold cup leaves on a counter.
   site.js draws the SVG. Each ring grows and fades on a 64s cycle, staggered
   by negative delays so it is mid-cycle at first paint. */
.env{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.env canvas{position:absolute;inset:0;width:100%;height:100%;display:block}

/* ── nav ─────────────────────────────────────────────────────────────── */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:40;
  display:flex;align-items:center;justify-content:space-between;
  padding:18px var(--gut);
  background:linear-gradient(to bottom,rgba(19,16,14,.82),rgba(19,16,14,0));
  backdrop-filter:blur(6px);
  transition:background-color .35s var(--ease),box-shadow .35s var(--ease);
}
/* past the hero the fade becomes a backing: content scrolling under the bar
   used to read straight through the logo */
.nav.solid{background-color:rgba(19,16,14,.9);box-shadow:0 1px 0 var(--line);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
.brand{display:inline-flex;align-items:center;gap:.28em;text-decoration:none;color:var(--text-primary);font-family:var(--display);font-weight:800;font-variation-settings:'opsz' 96;letter-spacing:-.035em;line-height:1;font-size:22px;padding:8px 0;margin:-8px 0}   /* a 38px target, laid out as 22 */
.nav-links{display:flex;align-items:center;gap:clamp(14px,2vw,28px)}
/* :not(.btn) matters: without it this rule beats .btn on specificity and paints
   the call to action's label grey on red, which measures 1.09:1. */
.nav-links a:not(.btn):not(.btn-answer){color:var(--text-secondary);text-decoration:none;font-size:14px;transition:color .3s var(--ease)}
.nav-links a:not(.btn):not(.btn-answer):hover{color:var(--text-primary)}

/* ── buttons ─────────────────────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--accent);color:#fff;text-decoration:none;
  font-family:var(--body);font-weight:500;font-size:15px;
  padding:13px 24px;border-radius:12px;border:0;cursor:pointer;
  text-shadow:none;
  transition:background .3s var(--ease),transform .3s var(--ease);
}
.btn:hover{background:var(--accent-hover);transform:translateY(-1px)}
.btn-wide{width:100%;padding:15px 24px;font-size:16px}
.btn-ghost{
  display:inline-flex;align-items:center;
  color:var(--text-primary);text-decoration:none;font-size:15px;
  padding:13px 4px;border-bottom:1px solid var(--text-primary);
  transition:opacity .3s var(--ease);
}
.btn-ghost:hover{opacity:.62}
@media (pointer:coarse){
  .btn{min-height:44px}
  .btn-ghost{min-height:44px}
}

/* ══════════════════════════════════════════════════════════════════════
   HERO : cold coffee
   Two stops, morning and night. The picture is the stage; everything that
   must land on it lives inside .cover, which is the picture's own 16:9
   space, sized to cover the stage. So the lens, the clips and the red N
   land on the same pixel of the photograph whatever shape the screen is.
   ══════════════════════════════════════════════════════════════════════ */
.hero{position:relative;height:200vh;z-index:1}
.stage{
  position:sticky;top:0;height:100vh;height:100svh;overflow:hidden;
  background:var(--canvas);container-type:size;
}
.frame{position:absolute;inset:0;overflow:hidden;touch-action:pan-y}
.cover{
  position:absolute;left:50%;top:50%;
  width:max(100vw,177.78vh);aspect-ratio:16/9;
  transform:translate(-50%,-50%);
}
@supports (width:1cqw){ .cover{width:max(100cqw,calc(100cqh * 16 / 9))} }
.cover .still,.cover video{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block;
}
/* the clips wait under the still until they are really playing */
.cover video{opacity:0;transition:opacity .6s var(--ease)}
.cover .loop.on{opacity:1}
/* the phone loop is the 4:5 middle of the frame, so it sits exactly there */
.cover .loop.tall{left:28.594%;width:45%}

/* the night. Without WebGL it shows through a circle, only while a
   pointer is over the picture (--rr is 0 at rest). With it (.fx), the
   canvas does the revealing and this layer is the whole night, shown only
   once the day has passed. */
.night{
  position:absolute;inset:0;
  clip-path:circle(var(--rr,0px) at var(--mx,65%) var(--my,55%));
}
/* the night: the morning's own footage relit to 9:40 PM, frame for frame.
   The hole looks into it, and once the day has passed it is the picture. */
.cover .revealloop.on{opacity:1}
.cover .revealloop.tall{left:28.594%;width:45%}
.stage.is-night .night{opacity:1;clip-path:circle(150% at var(--mx,65%) var(--my,55%))}
/* only while the state changes, never while the lens follows a pointer */
.stage.anim .night{transition:clip-path 1s var(--ease-io),opacity .3s var(--ease)}
.nightfx{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;display:none}
.stage.fx .nightfx{display:block}
.stage.fx .night{clip-path:none;opacity:0;transition:opacity .7s var(--ease)}
.stage.fx.is-night .night{opacity:1}
.stage.fx.snap .night{transition:none}
/* The day passing (owner, round 3): one take. The morning keeps playing
   and the relit night, on the same frame, comes up over it, so the owner
   never changes pace or pose and only the light moves. With WebGL the
   canvas does it (and switches the lamp on partway); this is the same
   fade without WebGL, lamp and all, on the same curve (DUSK_MS, DAWN_MS
   in app.js). After the rules above so it wins at equal weight. */
/* the circle's layer rests fully opaque behind a circle of nothing, so it
   drops to nothing at once when the circle goes, and only then fades up */
.stage.dusk:not(.fx) .night{clip-path:none;opacity:0;transition:none}
.stage.dusk:not(.fx).is-night .night{opacity:1;transition:opacity 3.6s cubic-bezier(.37,0,.63,1)}
.stage.dusk.dawn:not(.fx) .night{transition:opacity 1.6s cubic-bezier(.37,0,.63,1)}

.lens{
  position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;
  transform:translate3d(var(--lx,0px),var(--ly,0px),0);
  opacity:0;transition:opacity .35s var(--ease);
}
.stage.dusk .lens,.stage.is-night .lens{opacity:0}

.scrim-top{
  position:absolute;left:0;right:0;top:0;height:22%;pointer-events:none;
  background:linear-gradient(to bottom,rgba(19,16,14,.6),rgba(19,16,14,0));
}
.scrim-bottom{
  position:absolute;left:0;right:0;bottom:0;height:38%;pointer-events:none;
  background:linear-gradient(to bottom,rgba(19,16,14,0) 0%,rgba(19,16,14,.52) 42%,rgba(19,16,14,.88) 78%,var(--canvas) 100%);
}

/* ── the words on the picture ───────────────────────────────────────── */
/* the whole block fades as the page moves down, the hint with the
   headline, so nothing of the morning is left under the night's words
   (owner, round 4: "it halfway goes over it") */
.hero-copy{
  position:absolute;left:var(--gut);right:var(--gut);bottom:clamp(24px,5.5vh,60px);
  z-index:5;pointer-events:none;opacity:var(--hfade,1);
}
/* the one hint, a small chip over the photograph until it has done its job
   (owner, round 4: no clock, no counts; just how to use the picture) */
.hero-copy .hint{
  display:inline-block;margin:0 0 16px;
  font-size:13.5px;font-weight:500;color:var(--text-primary);
  background:rgba(19,16,14,.66);border:1px solid rgba(243,236,225,.1);border-radius:999px;
  padding:6px 15px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  transition:opacity .5s var(--ease);
}
.hero-copy .hint.gone,.stage.is-night .hero-copy .hint{opacity:0}
.hint-touch{display:none}
@media (pointer:coarse){ .hint-fine{display:none} .hint-touch{display:inline} }

.hero-h{
  margin:0;color:var(--text-primary);font-weight:750;
  font-family:var(--display);letter-spacing:-.045em;font-variation-settings:'opsz' 96;   /* the spaces between the spans too */
  font-size:clamp(36px,min(5.8vw,9.4vh),110px);line-height:1.0;
  text-shadow:var(--tshadow);
}
.ln{display:block;white-space:nowrap}
/* the slide is scroll-driven on the outer span; the entrance lives on the
   inner one, so the two can never fight over one transform */
.ln-1{transform:translate3d(calc(var(--slide,0) * -62vw),0,0)}
.ln-2{transform:translate3d(calc(var(--slide,0) * 62vw),0,0)}
.ln-in{display:inline-block;animation:lnin 1.15s var(--ease-out) .15s both}
.ln-2 .ln-in{animation-name:lnin2;animation-delay:.27s}
@keyframes lnin{from{transform:translate3d(-9vw,0,0);opacity:0}to{transform:none;opacity:1}}
@keyframes lnin2{from{transform:translate3d(9vw,0,0);opacity:0}to{transform:none;opacity:1}}
.f-serif,.f-sans{font-family:var(--display);font-weight:750;letter-spacing:-.045em;font-variation-settings:'opsz' 96}
.f-red{color:var(--accent-text)}

/* ── the settle, when the night lands ───────────────────────────────── */
.settle{
  position:absolute;left:var(--gut);bottom:clamp(24px,5.5vh,60px);z-index:6;
  width:min(640px,calc(100% - 2 * var(--gut)));
  opacity:0;pointer-events:none;text-shadow:var(--tshadow);
}
.settle.on{pointer-events:auto}
/* the night's own scrim: it deepens only while the settle is on, and dies
   out before the corners so the lamp and the mug stay lit */
.settle::before{
  content:"";position:absolute;inset:-34% -30% -30% -22%;z-index:-1;pointer-events:none;
  background:radial-gradient(ellipse 62% 58% at 38% 52%,rgba(12,10,9,.74) 0%,rgba(12,10,9,.5) 48%,rgba(12,10,9,0) 78%);
  opacity:0;transition:opacity .8s var(--ease);
}
.settle.on::before{opacity:1}
.h-display{
  font-family:var(--display);font-weight:800;
  font-size:clamp(34px,4.6vw,72px);line-height:1.02;letter-spacing:-.022em;
  margin:0 0 .45em;max-width:16ch;
}
.h-sub{
  font-size:clamp(16px,1.3vw,20px);line-height:1.5;color:var(--text-primary);
  margin:0;max-width:40ch;
}
.h-cta{display:flex;flex-wrap:wrap;align-items:center;gap:18px;margin-top:26px}
.h-cta .btn,.h-cta .btn-answer{text-shadow:none}
.h-cta .btn-ghost{color:var(--text-primary)}

.cue{position:absolute;right:calc(var(--gut) + 8px);bottom:30px;z-index:6;width:1px;height:38px;background:linear-gradient(to bottom,transparent,var(--text-primary));opacity:.5}
.cue span{position:absolute;left:-2px;bottom:0;width:5px;height:5px;border-radius:50%;background:var(--text-primary);animation:cuedrop 2.8s var(--ease) -.6s infinite}
@keyframes cuedrop{0%{transform:translateY(-32px);opacity:0}30%{opacity:1}100%{transform:translateY(0);opacity:0}}
.stage.is-night .cue{opacity:0}

/* ══════════════════════════════════════════════════════════════════════
   SPLIT TEXT
   The hero snaps, so a caption is arriving, present, or leaving. Nothing
   here reads scroll position: the .on class flips and CSS does the timing,
   which is the only way to get a curve worth looking at.
   ══════════════════════════════════════════════════════════════════════ */
.w{display:inline-block;white-space:nowrap}
.c{
  display:inline-block;
  opacity:0;
  transform:translateY(.46em) scale(.97);
  transform-origin:50% 100%;
  /* leaving is fast and together; arriving is slow and staggered */
  transition:opacity .34s var(--ease) 0s, transform .34s var(--ease) 0s;
}
.band.on .c{
  opacity:1;
  transform:none;
  transition:
    opacity .62s cubic-bezier(.19,.72,.3,1) calc(var(--i,0) * 17ms),
    transform .78s cubic-bezier(.16,.84,.28,1) calc(var(--i,0) * 17ms);
}
/* the sub and the buttons come in behind the last character of the line */
.band .h-sub,.band .h-cta{
  opacity:0;transform:translateY(12px);
  transition:opacity .3s var(--ease) 0s, transform .3s var(--ease) 0s;
}
.band.on .h-sub{
  opacity:1;transform:none;
  transition:opacity .6s cubic-bezier(.19,.72,.3,1) calc(var(--n,14) * 17ms + 90ms),
             transform .7s cubic-bezier(.16,.84,.28,1) calc(var(--n,14) * 17ms + 90ms);
}
.band.on .h-cta{
  opacity:1;transform:none;
  transition:opacity .6s cubic-bezier(.19,.72,.3,1) calc(var(--n,14) * 17ms + 230ms),
             transform .7s cubic-bezier(.16,.84,.28,1) calc(var(--n,14) * 17ms + 230ms);
}
/* the band itself cross-fades under the words */
.band{transition:opacity .42s var(--ease)}
.band.on{opacity:1}

/* Compositor hints go on only while a band is working. Left on permanently
   they cost three extra layers for the whole page's life. */
.band.on .c,.band.on .h-sub,.band.on .h-cta{will-change:transform,opacity}

/* ══════════════════════════════════════════════════════════════════════
   SECTIONS
   ══════════════════════════════════════════════════════════════════════ */
.sec{
  position:relative;z-index:2;
  padding:clamp(88px,13vh,170px) var(--gut);
  padding-left:calc(var(--gut) + clamp(22px,4vw,64px));
  max-width:1440px;
}
/* owner, round 4: the small labels were a typewriter in capitals, which
   read as a terminal. Plain words in the body face, in the brand's red. */
.kicker{
  font-family:var(--body);font-size:clamp(14px,1vw,15px);font-weight:500;
  letter-spacing:.005em;
  color:var(--accent-text);margin:0 0 20px;
}
.h2{
  font-family:var(--display);font-weight:700;
  font-size:clamp(28px,3.9vw,56px);
  line-height:1.06;letter-spacing:-.02em;
  margin:0 0 24px;max-width:17ch;
}
.lede{font-size:clamp(16px,1.25vw,19px);color:var(--text-secondary);max-width:52ch;margin:0 0 34px}

/* entrances: prefixed with the container class so nothing cancels them */
.sec .rise{opacity:0;transform:translateY(20px);transition:opacity .85s var(--ease-out),transform .85s var(--ease-out)}
.sec.in .rise{opacity:1;transform:none}
.sec.in .rise:nth-child(2){transition-delay:.07s}
.sec.in .rise:nth-child(3){transition-delay:.14s}
.sec.in .rise:nth-child(4){transition-delay:.21s}
/* retire the stagger so later hovers do not inherit the delay */
.sec.done .rise,.sec.done .rise:nth-child(2),.sec.done .rise:nth-child(3),.sec.done .rise:nth-child(4){transition-delay:0s !important}

/* ── 2. anatomy of a call (owner, rounds 2 and 4) ──────────────────────
   One screen, no scroll lock. The steps on the left as a timeline; on the
   right a real picture of the forty seconds, and over its corner a card
   that plays one call through when it comes into view, told as the
   conversation it is. Round 4 took out the terminal: no typewriter type,
   no log of timestamps, no grid of hairlines. The card is driven by one
   attribute, data-stage 0 to 6, written by app.js; every change below is
   an eased transition on transform or opacity. */
.call-grid{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,640px);
  gap:clamp(36px,5vw,96px);align-items:center;
}
.sec-call .h2{max-width:19ch;margin:0}

/* the steps: a line of stops, the one playing lit red */
.beats{position:relative;list-style:none;margin:clamp(24px,3.6vh,40px) 0 0;padding:0;max-width:46ch}
.beats::before{content:"";position:absolute;left:5px;top:22px;bottom:22px;width:1px;background:var(--line-mid)}
.beat{
  position:relative;display:block;width:100%;
  padding:8px 0 8px 32px;margin:0;background:none;border:0;
  color:inherit;font:inherit;text-align:left;cursor:pointer;
  /* 0.72 measures 6.8:1 on the canvas: never dimmer, or the steps fail
     the body-text bar before anyone has pressed anything */
  opacity:.72;transition:opacity .45s var(--ease);
}
.beat::before{
  content:"";position:absolute;left:0;top:15px;width:11px;height:11px;border-radius:50%;
  background:var(--canvas);border:1.5px solid var(--line-strong);
  transition:background-color .45s var(--ease),border-color .45s var(--ease),box-shadow .45s var(--ease);
}
.beat:hover{opacity:.92}
.beat[aria-current="step"]{opacity:1}
.beat[aria-current="step"]::before{background:var(--accent);border-color:var(--accent);box-shadow:0 0 0 5px rgba(200,30,30,.2)}
.beat-t{display:flex;align-items:baseline;gap:10px;font-family:var(--display);font-variation-settings:'opsz' 96;font-weight:700;font-size:18px;letter-spacing:-.01em;line-height:1.3}
.beat-at{font-family:var(--body);font-weight:500;font-size:13px;letter-spacing:0;color:var(--ember);font-variant-numeric:tabular-nums}
.beat-d{display:block;font-size:15px;line-height:1.45;color:var(--text-secondary);margin-top:2px}
.beat[aria-current="step"] .beat-d{color:var(--text-primary)}

/* the picture, and the card over its corner */
.call-scene{position:relative;padding:0 0 clamp(28px,4vh,44px) clamp(56px,9vw,150px)}
.call-pic{
  position:relative;margin:0 0 0 auto;width:min(100%,470px);aspect-ratio:4/5;
  border-radius:22px;overflow:hidden;background:var(--panel);
}
.call-pic img{display:block;width:100%;height:100%;object-fit:cover}
.call-pic::after{content:"";position:absolute;inset:0;background:linear-gradient(to bottom,rgba(19,16,14,0) 55%,rgba(19,16,14,.45))}

.callcard{
  position:absolute;left:0;bottom:0;width:min(372px,78%);
  background:rgba(29,25,22,.86);
  -webkit-backdrop-filter:blur(16px) saturate(1.15);backdrop-filter:blur(16px) saturate(1.15);
  border:1px solid rgba(243,236,225,.1);border-radius:22px;
  padding:18px 18px 16px;
  box-shadow:0 40px 90px -30px rgba(0,0,0,.8),0 1px 0 rgba(243,236,225,.05) inset;
}
.cc-top{display:flex;align-items:center;gap:12px}
.cc-ring{
  flex:none;width:38px;height:38px;border-radius:50%;display:grid;place-items:center;
  background:var(--raised);
  transition:background-color .5s var(--ease);
}
.cc-ring svg{width:16px;height:18px;fill:var(--text-primary);overflow:visible}
.cc-ring .ring{fill:none;stroke:var(--text-primary);stroke-width:2.6;stroke-linecap:round;opacity:0;transition:opacity .3s var(--ease)}
.cc-ring .hs{transform-origin:24px 30px;transition:transform .5s var(--ease-out)}
.callcard[data-stage="0"] .cc-ring{background:var(--accent)}
.callcard[data-stage="0"] .cc-ring .ring{opacity:1}
.callcard.playing[data-stage="0"] .cc-ring svg{animation:ccrattle .9s var(--ease) infinite}
.callcard:not([data-stage="0"]) .cc-ring .hs{transform:translateY(-3px) rotate(-10deg)}
@keyframes ccrattle{0%,50%,100%{transform:none}10%,30%{transform:rotate(-9deg)}20%,40%{transform:rotate(9deg)}}
.cc-who{flex:1;min-width:0;display:flex;flex-direction:column}
.cc-name{font-size:15px;font-weight:600;line-height:1.3}
.cc-state{position:relative;height:1.4em;font-size:13px;color:var(--text-secondary)}
.cc-state .st{position:absolute;left:0;top:0;white-space:nowrap;opacity:0;transform:translateY(5px);transition:opacity .4s var(--ease),transform .5s var(--ease-out)}
.callcard[data-stage="0"] .st-0,
.callcard[data-stage="1"] .st-1,.callcard[data-stage="2"] .st-1,.callcard[data-stage="3"] .st-1,.callcard[data-stage="4"] .st-1,
.callcard[data-stage="5"] .st-2,.callcard[data-stage="6"] .st-2{opacity:1;transform:none}
.cc-time{font-size:16px;font-weight:600;color:var(--ember);font-variant-numeric:tabular-nums}
.cc-bar{position:relative;height:3px;margin:14px 0 4px;background:rgba(243,236,225,.08);border-radius:3px;overflow:hidden}
.cc-fill{position:absolute;inset:0;background:var(--ember);border-radius:3px;transform-origin:left;transform:scaleX(var(--p,0))}

/* the conversation: the card starts as just the call and grows upward a
   line at a time, like a chat. Each line opens its row (grid rows 0fr to
   1fr, so the height eases) and then fades up into it. */
.cc-chat{display:flex;flex-direction:column;margin-top:5px}
.cc-row{display:grid;grid-template-rows:0fr;transition:grid-template-rows .5s var(--ease-out)}
.cc-in{min-height:0;overflow:hidden}
.cc-msg,.cc-day,.cc-booked{
  margin:9px 0 0;opacity:0;transform:translateY(8px);
  transition:opacity .45s var(--ease) .12s,transform .55s var(--ease-out) .12s;
}
.cc-msg{width:fit-content;max-width:88%;padding:9px 13px;border-radius:16px;font-size:14.5px;line-height:1.4}
.cc-them{background:var(--raised);border-bottom-left-radius:5px}
.cc-us{margin-left:auto;background:var(--text-primary);color:var(--canvas);border-bottom-right-radius:5px}
.cc-us b{font-weight:600}
.callcard:is([data-stage="1"],[data-stage="2"],[data-stage="3"],[data-stage="4"],[data-stage="5"],[data-stage="6"]) .r1,
.callcard:is([data-stage="2"],[data-stage="3"],[data-stage="4"],[data-stage="5"],[data-stage="6"]) .r2,
.callcard:is([data-stage="3"],[data-stage="4"],[data-stage="5"],[data-stage="6"]) .r3,
.callcard:is([data-stage="4"],[data-stage="5"],[data-stage="6"]) :is(.r4,.r5){grid-template-rows:1fr}
.callcard:is([data-stage="1"],[data-stage="2"],[data-stage="3"],[data-stage="4"],[data-stage="5"],[data-stage="6"]) .r1 .cc-in > *,
.callcard:is([data-stage="2"],[data-stage="3"],[data-stage="4"],[data-stage="5"],[data-stage="6"]) .r2 .cc-in > *,
.callcard:is([data-stage="3"],[data-stage="4"],[data-stage="5"],[data-stage="6"]) .r3 .cc-in > *,
.callcard:is([data-stage="4"],[data-stage="5"],[data-stage="6"]) :is(.r4,.r5) .cc-in > *{opacity:1;transform:none}
/* the booking lands a moment after the caller says yes */
.callcard[data-stage="4"] .r5{transition-delay:.6s}
.callcard[data-stage="4"] .r5 .cc-booked{transition-delay:.72s}

/* the afternoon, read: taken hours filled, free ones open */
.cc-day{padding:9px 11px 11px;border-radius:14px;border:1px solid rgba(243,236,225,.08)}
.cc-day-l{display:block;font-size:12.5px;color:var(--text-secondary)}
.cc-strip{position:relative;display:grid;grid-template-columns:repeat(6,1fr);gap:5px;margin-top:7px;overflow:hidden;border-radius:8px}
.cc-slot{position:relative;height:30px;border-radius:8px;display:grid;place-items:center}
.cc-slot i{position:relative;font-style:normal;font-size:12px;font-weight:500;color:var(--text-secondary);font-variant-numeric:tabular-nums;transition:color .4s var(--ease)}
.cc-slot.busy{background:rgba(243,236,225,.1)}
.cc-free{border:1px dashed rgba(243,236,225,.22);transition:border-color .45s var(--ease),background-color .45s var(--ease)}
.callcard:is([data-stage="3"],[data-stage="4"],[data-stage="5"],[data-stage="6"]) .cc-free{border:1px solid var(--ember);background:rgba(242,184,107,.1)}
.callcard:is([data-stage="3"],[data-stage="4"],[data-stage="5"],[data-stage="6"]) .cc-free i{color:var(--ember)}
.cc-new{position:absolute;inset:-1px;border-radius:8px;background:var(--text-primary);transform:scaleY(0);transform-origin:bottom;transition:transform .55s var(--ease-out)}
.callcard:is([data-stage="4"],[data-stage="5"],[data-stage="6"]) .cc-new{transform:none}
.callcard:is([data-stage="4"],[data-stage="5"],[data-stage="6"]) .f2 i{color:var(--canvas)}
/* the check: one pass along the afternoon, reading what is taken */
.cc-scan{position:absolute;top:0;bottom:0;left:0;width:34%;pointer-events:none;background:linear-gradient(90deg,transparent,rgba(242,184,107,.4),transparent);opacity:0}
.callcard[data-stage="2"] .cc-scan{animation:ccscan 1.5s var(--ease-io) forwards}
@keyframes ccscan{0%{opacity:0;transform:translateX(-100%)}15%{opacity:1}85%{opacity:1}100%{opacity:0;transform:translateX(300%)}}

.cc-booked{
  width:fit-content;display:flex;align-items:center;gap:8px;
  padding:7px 12px 7px 9px;border-radius:10px;font-size:13.5px;
  background:rgba(242,184,107,.12);border:1px solid rgba(242,184,107,.34);
}
.cc-booked b{font-weight:600;color:var(--ember)}
.cc-booked svg{flex:none;width:16px;height:16px;fill:none;stroke:var(--ember);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}

.cc-hand{
  display:flex;align-items:center;gap:10px;margin-top:14px;padding-top:12px;
  border-top:1px solid rgba(243,236,225,.08);font-size:13px;line-height:1.4;color:var(--text-secondary);
  transition:color .45s var(--ease);
}
.cc-hand svg{flex:none;width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:transform .6s var(--ease-out)}
.callcard[data-stage="5"] .cc-hand,.callcard[data-stage="6"] .cc-hand{color:var(--text-primary)}
.callcard[data-stage="5"] .cc-hand svg{transform:translateX(4px);color:var(--ember)}

.cc-again{
  position:absolute;right:4px;bottom:-44px;
  background:none;border:0;padding:8px 0;cursor:pointer;
  font:inherit;font-size:13.5px;color:var(--text-secondary);
  border-bottom:1px solid var(--line-strong);
  opacity:0;pointer-events:none;transition:opacity .4s var(--ease),color .3s var(--ease);
}
.cc-again:hover{color:var(--text-primary)}
.callcard[data-stage="6"] .cc-again{opacity:1;pointer-events:auto}
@media (max-width:900px){
  .call-grid{grid-template-columns:1fr}
  /* the card grows up over the foot of the picture; the room it grows
     into is kept, so nothing below it moves */
  .call-scene{padding:0 0 250px;margin-bottom:44px;max-width:560px}
  .call-pic{width:min(86%,440px)}
  .callcard{left:0;right:auto;width:min(100%,380px)}
}

/* ── 2a. the dashboard (owner, round 4) ────────────────────────────────
   An example of the dashboard, in the page's own materials: the panel and
   raised tones, cream words, ember only on the counts and the booked
   times. Heading left, words right, then the wide panel: a different
   skeleton from the call section above it. */
.dash-head{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:clamp(24px,5vw,90px);align-items:end}
.sec-dash .h2{max-width:15ch;margin:0}
.dash-aside .lede{margin:0 0 20px;max-width:44ch}
.dash{
  margin-top:clamp(34px,5vh,56px);
  background:linear-gradient(180deg,#211c18,var(--panel) 30%);
  border:1px solid var(--line-mid);border-radius:24px;
  padding:clamp(16px,2.2vw,30px);
  box-shadow:0 50px 110px -50px rgba(0,0,0,.85),0 1px 0 rgba(243,236,225,.05) inset;
}
.dash-top{display:flex;flex-wrap:wrap;align-items:center;gap:10px 18px;padding:0 2px 16px;border-bottom:1px solid var(--line)}
.dash-name{display:inline-flex;align-items:center;gap:10px;font-weight:600;font-size:15px}
.dash-name .mark{width:18px;height:20px;fill:var(--accent)}
.dash-live{display:inline-flex;align-items:center;gap:7px;font-size:13px;color:var(--text-secondary)}
.dash-live i{width:7px;height:7px;border-radius:50%;background:#8CCB99}   /* the same green as the dashboard's own */
.dash.live .dash-live i{animation:dlive 2.4s var(--ease) infinite}
@keyframes dlive{0%{box-shadow:0 0 0 0 rgba(140,203,153,.45)}70%,100%{box-shadow:0 0 0 7px rgba(140,203,153,0)}}
.dash-day{margin-left:auto;font-size:13.5px;color:var(--text-secondary)}
.dash-ex{font-size:12px;color:var(--text-secondary);padding:3px 9px;border:1px solid var(--line-mid);border-radius:7px}

.dash-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(8px,1vw,14px);margin:clamp(16px,2vw,22px) 0}
.ds{padding:clamp(12px,1.4vw,18px) clamp(14px,1.5vw,20px);border-radius:16px;background:rgba(243,236,225,.035);border:1px solid var(--line)}
.ds b{display:block;font-family:var(--display);font-variation-settings:'opsz' 96;font-weight:700;font-size:clamp(28px,2.8vw,42px);line-height:1;letter-spacing:-.02em;color:var(--ember);font-variant-numeric:tabular-nums}
.ds span{display:block;margin-top:8px;font-size:13.5px;color:var(--text-secondary)}

.dash-body{display:grid;grid-template-columns:minmax(0,1.75fr) minmax(0,1fr);gap:clamp(14px,1.8vw,24px);align-items:start}
.dash-h{margin:0 0 6px;font-size:13.5px;font-weight:600;color:var(--text-secondary)}
.dash-list,.dash-sched{list-style:none;margin:0;padding:0}
/* a row that can open (grid rows 0fr to 1fr), for the call that arrives */
.dl,.sc{display:grid;grid-template-rows:1fr;transition:grid-template-rows .6s var(--ease-out)}
.dl-in{min-height:0;overflow:hidden}
.dl .dl-g{
  display:grid;grid-template-columns:clamp(62px,6vw,78px) minmax(0,1fr) auto;gap:14px;align-items:center;
  padding:11px 2px;border-top:1px solid var(--line);
}
.dl-t{font-size:13.5px;color:var(--text-secondary);font-variant-numeric:tabular-nums;white-space:nowrap}
.dl-what{display:flex;flex-direction:column;min-width:0}
.dl-who{font-size:12.5px;color:var(--text-secondary)}
.dl-sum{font-size:15px;line-height:1.35;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dl-out{position:relative;display:grid;justify-items:end}
.out{grid-area:1/1;font-size:12.5px;font-weight:500;white-space:nowrap;padding:5px 10px;border-radius:8px;transition:opacity .4s var(--ease),transform .5s var(--ease-out)}
.out-booked{color:var(--ember);background:rgba(242,184,107,.1);border:1px solid rgba(242,184,107,.3)}
.out-plain{color:var(--text-primary);background:rgba(243,236,225,.06);border:1px solid transparent}
.out-you{color:var(--text-primary);border:1px solid var(--line-strong)}
.out-quiet{color:var(--text-secondary);border:1px solid transparent}
.out-ring{color:var(--text-primary);background:var(--raised);border:1px solid var(--line-mid);opacity:0}
.dash-more{margin:0;padding:11px 2px 0;border-top:1px solid var(--line);font-size:13px;color:var(--text-secondary)}

.dash-side{padding:clamp(14px,1.4vw,18px);border-radius:18px;background:rgba(243,236,225,.035);border:1px solid var(--line)}
.sc .dl-g{display:grid;grid-template-columns:clamp(86px,8vw,104px) minmax(0,1fr);gap:12px;align-items:baseline;padding:10px 0;border-top:1px solid var(--line)}
.dash-sched .sc:first-child .dl-g{border-top:0}
.dash:is(.pre,.ringing) .sc-arrive + .sc .dl-g{border-top-color:transparent}
.sc-t{font-size:13px;color:var(--text-secondary);white-space:nowrap}
.sc-t b{font-weight:600;color:var(--text-primary)}
.sc-w{font-size:14.5px;line-height:1.35}
.sc-w em{display:block;font-style:normal;font-size:12.5px;color:var(--ember);margin-top:2px}
.sc-call .sc-t b{color:var(--ember)}
.dash-mins{margin-top:14px;padding-top:14px;border-top:1px solid var(--line)}
.dash-mins p{display:flex;justify-content:space-between;gap:10px;margin:0 0 9px;font-size:13px;color:var(--text-secondary)}
.dash-mins b{font-weight:600;color:var(--ember)}
.dash-bar{display:block;height:6px;border-radius:6px;background:rgba(243,236,225,.08);overflow:hidden}
.dash-bar i{display:block;height:100%;width:43%;border-radius:6px;background:var(--ember)}

/* before it is seen: the last call has not come in yet (app.js) */
.dash.pre .dl-arrive,.dash.pre .sc-arrive{grid-template-rows:0fr}
.dash.pre .dl-arrive .dl-in,.dash.pre .sc-arrive .dl-in{opacity:0}
.dl-arrive .dl-in,.sc-arrive .dl-in{transition:opacity .5s var(--ease) .2s}
.dash.ringing .out-ring{opacity:1}
.dash.ringing .sc-arrive{grid-template-rows:0fr}
.dash.ringing .sc-arrive .dl-in{opacity:0}
.dash.ringing .dl-arrive .out-booked{opacity:0;transform:translateY(4px)}

@media (max-width:900px){
  .dash-head{grid-template-columns:1fr;gap:18px}
  .dash-stats{grid-template-columns:repeat(2,minmax(0,1fr))}
  .dash-body{grid-template-columns:1fr}
}
@media (max-width:560px){
  .dl .dl-g{grid-template-columns:minmax(0,1fr) auto;gap:4px 12px}
  .dl-t{grid-column:1/-1;font-size:12.5px}
  .dash-day{margin-left:0}
}

.price-rows div{display:grid;grid-template-columns:clamp(96px,11vw,140px) 1fr;gap:18px;padding:15px 0;border-top:1px solid var(--line)}
.price-rows div:last-child{border-bottom:1px solid var(--line)}
.price-rows dt{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent-text);padding-top:.3em}
.price-rows dd{margin:0;font-size:15.5px}
.price-close{font-size:16px;color:var(--text-secondary);margin:0}

/* ── 5. faq ──────────────────────────────────────────────────────────── */
.qs{max-width:68ch}
.qs details{border-top:1px solid var(--line)}
.qs details:last-child{border-bottom:1px solid var(--line)}
.qs summary{
  list-style:none;cursor:pointer;padding:19px 34px 19px 0;position:relative;
  font-family:var(--display);font-weight:600;font-size:clamp(17px,1.5vw,21px);
  letter-spacing:-.008em;transition:color .3s var(--ease);
}
.qs summary::-webkit-details-marker{display:none}
.qs summary:hover{color:var(--accent-text)}
.qs summary::after{
  content:"";position:absolute;right:4px;top:50%;width:11px;height:11px;
  border-right:1.5px solid var(--accent);border-bottom:1.5px solid var(--accent);
  transform:translateY(-70%) rotate(45deg);transition:transform .35s var(--ease);
}
.qs details[open] summary::after{transform:translateY(-30%) rotate(225deg)}
.qs details p{margin:0 0 21px;color:var(--text-secondary);max-width:60ch;font-size:15.5px}

/* ── 6. cta + form ───────────────────────────────────────────────────── */
.sec-cta{padding-bottom:clamp(100px,15vh,190px)}
.h2-cta{max-width:15ch}

/* ── footer ──────────────────────────────────────────────────────────── */
.foot-bar{position:relative;z-index:2;border-top:1px solid var(--line);padding:36px var(--gut) 44px}
.foot-in{display:flex;flex-wrap:wrap;align-items:center;gap:18px clamp(20px,4vw,52px);max-width:1440px}
.foot-brand{display:inline-flex;align-items:center;gap:.28em;font-family:var(--display);font-weight:800;font-variation-settings:'opsz' 96;letter-spacing:-.035em;line-height:1;font-size:20px}
.foot-links{display:flex;gap:22px;flex-wrap:wrap}
.foot-links a{color:var(--text-secondary);text-decoration:none;font-size:14px;transition:color .3s var(--ease);padding:7px 2px;white-space:nowrap}   /* 24px minimum target, and never split a two-word link */
.foot-links a:hover{color:var(--text-primary)}
.foot-note{font-family:var(--mono);font-size:11.5px;line-height:1.7;color:var(--text-secondary);margin:0;flex:1 1 320px}

/* ══════════════════════════════════════════════════════════════════════
   THE FIVE GATES : the compact hero
   Phones, portrait tablets, coarse-pointer portrait, landscape phones and
   reduced motion. These five queries must match the JS GATES array
   character for character. Pictures work everywhere, so this is not an
   apology still: the lens, the signature and the steam all stay. What goes
   is the scroll-long stage, the snap and the day clip.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 720px),
       (orientation: portrait) and (max-width: 1024px),
       (orientation: portrait) and (pointer: coarse),
       (orientation: landscape) and (pointer: coarse) and (max-height: 560px),
       (prefers-reduced-motion: reduce){
  .hero{height:auto}
  .stage{position:relative;height:auto;overflow:visible;container-type:normal;padding-bottom:clamp(40px,7vh,72px)}
  .frame{position:relative;inset:auto;width:100%;aspect-ratio:16/9;max-height:84vh;container-type:size}
  .cover{width:100%;left:0;top:0;transform:none}
  .scrim-bottom{height:26%;background:linear-gradient(to bottom,rgba(19,16,14,0),var(--canvas))}
  .hero-copy{position:relative;left:auto;right:auto;bottom:auto;padding:26px var(--gut) 0}
  .hero-h{font-size:clamp(28px,7.2vw,64px);line-height:1.04}
  .ln{white-space:normal}
  .ln-1{transform:translate3d(calc(var(--slide,0) * -26vw),0,0)}
  .ln-2{transform:translate3d(calc(var(--slide,0) * 26vw),0,0)}
  .settle{position:relative;left:auto;bottom:auto;width:auto;opacity:1;pointer-events:auto;padding:30px var(--gut) 0;text-shadow:none}
  .settle::before{display:none}
  .hero-copy .hint{background:none;border:0;padding:0;-webkit-backdrop-filter:none;backdrop-filter:none;color:var(--text-secondary)}
  .settle .c,.settle .w,.settle .h-sub,.settle .h-cta{opacity:1;transform:none;transition:none}
  .settle .h-display{font-size:clamp(28px,6.4vw,52px)}
  .cue,.stops{display:none}
  .sec{padding-left:var(--gut)}
  /* A portrait screen gets the 4:5 middle of the picture: the owner and
     the mug, cropped by CSS so the lens keeps its spot. */
  @media (max-aspect-ratio: 1/1){
    .frame{aspect-ratio:4/5;max-height:none}
    .cover{width:222.222%;height:100%;left:-63.542%;aspect-ratio:auto}
  }
}

/* short windows: keep the hero, drop the overlays */
@media (max-height:560px){
  .cue{display:none}
}


/* ══════════════════════════════════════════════════════════════════════
   REDUCED MOTION : honored completely, including pseudo-elements
   ══════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    transition-delay:0s !important;
    scroll-behavior:auto !important;
  }
  body{opacity:1;animation:none}
  .sec .rise{opacity:1;transform:none}
  .band .c,.band .h-sub,.band .h-cta{opacity:1;transform:none}
  .cc-scan{display:none}
  /* the logo never rings; the contour ground is one still frame (topo.js) */
  .mark .hs,.mark .ring,.close-mark .hs,.close-mark .ring{animation:none !important}
  .btn-answer .knob svg,.btn-answer .knob .hs,.btn-answer .knob .ring,
  .btn-answer .knob::before,.btn-answer .knob::after{animation:none !important}
  .ln-in{animation:none}
  /* positional transforms re-applied per breakpoint, never blanket-removed */
  .cue span{transform:translateY(0)}
}

/* paused: not inherited, so it has to hit every element and pseudo-element */
body.paused *,body.paused *::before,body.paused *::after{animation-play-state:paused !important}

/* ══════════════════════════════════════════════════════════════════════
   MULTI-PAGE: nav, menu, buttons with more life, shared furniture
   ══════════════════════════════════════════════════════════════════════ */

/* ── the mark ─────────────────────────────────────────────────────────
   The cradle n: the arch is a handset, thinner at the handle, resting on
   two posts with a thin cut between them. The svg hugs the letter, so it
   sizes in em beside the wordmark (Bricolage 800): its foot on the baseline,
   its top level with the dot of the i. Owner-approved 2026-09-24; masters in brand/.
   It rings once (the handset rattles, two ring lines), then the handset
   lifts off the posts and sets back down: Norvi answers on the first ring.
   The rest state is still. Rings once a session on load, and on hover. */
.mark{width:.658em;height:.731em;flex:none;display:block;overflow:visible;position:relative;top:-.03em;fill:var(--accent)}
.mark .ring,.close-mark .ring{fill:none;stroke:var(--accent);stroke-width:1.9;stroke-linecap:round;opacity:0;transform-box:fill-box;transform-origin:50% 50%}
.mark .hs,.close-mark .hs{transform-box:fill-box;transform-origin:50% 100%}
.ringing .mark .hs,.close-mark.ringing .hs{animation:nv-pickup 1.9s cubic-bezier(.3,.7,.3,1) both}
.ringing .mark .ring,.close-mark.ringing .ring{animation:nv-ring 1.9s linear both}
@keyframes nv-pickup{
  0%{transform:none}
  4%{transform:rotate(-6deg)} 8%{transform:rotate(6deg)} 12%{transform:rotate(-5deg)}
  16%{transform:rotate(5deg)} 20%{transform:rotate(-3deg)} 25%{transform:rotate(1deg)} 29%{transform:none}
  36%{transform:none;animation-timing-function:cubic-bezier(.2,.9,.3,1)}
  56%{transform:translate(1px,-8px) rotate(-13deg)}
  74%{transform:translate(1px,-8px) rotate(-13deg);animation-timing-function:cubic-bezier(.5,0,.6,1)}
  90%{transform:translate(0,.5px) rotate(0)}
  100%{transform:none}
}
@keyframes nv-ring{0%{opacity:0;transform:scale(.7)}6%{opacity:1;transform:none}24%{opacity:1}32%{opacity:0;transform:scale(1.15)}100%{opacity:0}}
.foot-brand .mark{top:-.03em}

/* ── nav with a real menu ─────────────────────────────────────────── */
.nav-links{gap:clamp(10px,1.6vw,26px)}
.nav-links a:not(.btn):not(.btn-answer){position:relative;padding:9px 4px;font-size:14.5px}   /* 24px minimum target */
.nav-links a:not(.btn):not(.btn-answer)::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1.5px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform .32s var(--ease-out);
}
.nav-links a:not(.btn):not(.btn-answer):hover::after,
.nav-links a[aria-current="page"]::after{transform:scaleX(1)}
.nav-links a[aria-current="page"]{color:var(--text-primary)}

.menu-btn{display:none;background:none;border:0;padding:8px;cursor:pointer;color:var(--text-primary)}
.menu-btn svg{display:block;width:22px;height:22px}

/* ══════════════════════════════════════════════════════════════════════
   BUTTONS
   Three weights, all built the same way, all carrying an arrow that moves.
   The arrow is drawn from borders rather than an SVG so the markup stays
   clean and it inherits colour, weight and size from the button itself.
   ══════════════════════════════════════════════════════════════════════ */
.btn,.btn-quiet,.btn-ghost{
  position:relative;display:inline-flex;align-items:center;gap:11px;
  font-family:var(--body);font-weight:500;letter-spacing:.005em;
  cursor:pointer;text-decoration:none;white-space:nowrap;
}
/* the arrow: a chevron and the shaft it slides along */
.btn::after,.btn-quiet::after,.btn-ghost::after{
  content:"";flex:none;width:.44em;height:.44em;
  border-right:1.8px solid currentColor;border-top:1.8px solid currentColor;
  transform:rotate(45deg);
  transition:transform .34s var(--ease-out);
}
.btn:hover::after,.btn-quiet:hover::after,.btn-ghost:hover::after{transform:rotate(45deg) translate(2.5px,-2.5px)}

/* ── primary ──────────────────────────────────────────────────────── */
.btn{
  overflow:hidden;justify-content:center;
  background:linear-gradient(177deg,#D62525 0%,var(--accent) 46%,#B31A1A 100%);
  box-shadow:
    0 1px 0 rgba(255,255,255,.28) inset,
    0 -1px 0 rgba(90,10,10,.45) inset,
    0 2px 5px rgba(150,25,25,.22),
    0 10px 24px -10px rgba(150,25,25,.55);
  transition:transform .22s var(--ease),box-shadow .3s var(--ease),filter .3s var(--ease);
}
.btn::before{                      /* a light sweep, only on hover */
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 32%,rgba(255,255,255,.3) 50%,transparent 68%);
  transform:translateX(-120%);
}
.btn:hover{
  /* restated, because the base .btn:hover further up sets a flat colour and
     would erase the gradient exactly when it is most visible */
  background:linear-gradient(177deg,#DF2A2A 0%,#CC2020 46%,#B31A1A 100%);
  transform:translateY(-2px);filter:saturate(1.06);
  box-shadow:
    0 1px 0 rgba(255,255,255,.3) inset,
    0 -1px 0 rgba(90,10,10,.45) inset,
    0 4px 9px rgba(150,25,25,.26),
    0 18px 36px -14px rgba(150,25,25,.66);
}
.btn:hover::before{transform:translateX(120%);transition:transform .72s var(--ease-out)}
.btn:active{
  transform:translateY(1px);
  box-shadow:0 2px 6px rgba(150,25,25,.3) inset,0 1px 2px rgba(150,25,25,.2);
}

/* ── quiet: the second choice, still a real button ────────────────── */
.btn-quiet{
  justify-content:center;color:var(--text-primary);
  background:rgba(243,236,225,0.068);
  font-size:15px;padding:12px 22px;border-radius:12px;
  border:1.5px solid var(--line-mid);
  box-shadow:0 1px 0 rgba(243,236,225,.07) inset,0 2px 6px rgba(0,0,0,.3);
  transition:border-color .3s var(--ease),background .3s var(--ease),transform .22s var(--ease),box-shadow .3s var(--ease);
}
.btn-quiet:hover{
  border-color:var(--accent);color:var(--text-primary);background:var(--raised);transform:translateY(-2px);
  box-shadow:0 1px 0 rgba(243,236,225,.09) inset,0 10px 24px -12px rgba(200,30,30,.45);
}
.btn-quiet:active{transform:translateY(1px);box-shadow:0 2px 5px rgba(0,0,0,.12) inset}

/* ── ghost: a link that behaves like a button ─────────────────────── */
.btn-ghost{
  padding:6px 2px;color:var(--text-secondary);border:0;background:none;
  transition:color .3s var(--ease)}
.btn-ghost::before{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1.5px;
  background:currentColor;transform-origin:right;transform:scaleX(1);
  transition:transform .34s var(--ease-out),background-color .3s var(--ease);
}
.btn-ghost:hover{opacity:1;color:var(--accent-text)}
.btn-ghost:hover::before{transform-origin:left}

/* the wide variants keep the arrow but centre the pair */
.btn-wide{width:100%;padding:15px 24px;font-size:16px}
@media (pointer:coarse){.btn-quiet{min-height:44px}}

/* ══════════════════════════════════════════════════════════════════════
   GET STARTED: SLIDE TO ANSWER (owner's pick, feedback round 1)
   Built like the control you swipe to pick up a call. At rest the knob
   rings every few seconds, the way a call comes in: the handset rattles
   and two pulses spread out. Point at it (or tab to it) and you answer:
   the red fills from the knob across the track, the knob slides to the far
   end and turns cream, and the handset lifts off. It rings only while it
   is on screen (.live, set by site.js), never under reduced motion.
   ══════════════════════════════════════════════════════════════════════ */
.btn-answer{
  --h:60px;--k:48px;--in:6px;--w:252px;--gap:14px;
  --travel:calc(var(--w) - var(--k) - 2 * var(--in));
  position:relative;isolation:isolate;overflow:hidden;
  display:inline-flex;align-items:center;flex:none;
  height:var(--h);width:var(--w);padding:0 18px 0 calc(var(--k) + var(--in) + var(--gap));
  border-radius:999px;border:1px solid rgba(243,236,225,.24);
  background:rgba(243,236,225,.07);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  color:var(--text-primary);text-decoration:none;text-shadow:none;white-space:nowrap;cursor:pointer;
  font-family:var(--body);font-weight:500;font-size:16px;line-height:1.15;
  transition:border-color .4s var(--ease),transform .25s var(--ease);
}
/* the red that follows the knob across */
.btn-answer::before{
  content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;
  background:linear-gradient(177deg,#D62525 0%,var(--accent) 46%,#B31A1A 100%);
  clip-path:inset(0 calc(100% - var(--k) - 2 * var(--in)) 0 0 round 999px);
  transition:clip-path .6s var(--ease-out);
}
.btn-answer .knob{
  position:absolute;left:var(--in);top:calc((var(--h) - var(--k)) / 2 - 1px);z-index:1;
  width:var(--k);height:var(--k);border-radius:50%;
  display:grid;place-items:center;background:var(--accent);color:#FBF6F0;
  box-shadow:0 6px 18px -6px rgba(200,30,30,.75),0 1px 0 rgba(255,255,255,.25) inset;
  transition:transform .6s var(--ease-out),background-color .35s var(--ease),color .35s var(--ease);
}
.btn-answer .knob svg{width:36%;height:40%;overflow:visible;fill:currentColor}
.btn-answer .knob .ring{fill:none;stroke:currentColor;stroke-width:2.6;stroke-linecap:round;opacity:0;transform-box:fill-box;transform-origin:50% 50%}
.btn-answer .knob .hs{transform-box:fill-box;transform-origin:50% 100%}
.btn-answer .knob::before,.btn-answer .knob::after{
  content:"";position:absolute;inset:0;border-radius:50%;pointer-events:none;
  border:1.5px solid rgba(236,90,88,.9);opacity:0;
}
.btn-answer .lbl{position:relative;z-index:1;transition:transform .6s var(--ease-out)}
.btn-answer .lbl small{
  display:block;margin-top:3px;font-family:var(--mono);font-size:10.5px;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;color:#CFC6BA;transition:color .35s var(--ease);   /* 4.5:1+ on the track */
}
/* the call coming in */
.btn-answer.live .knob svg{animation:ans-rattle 6s var(--ease) -1.2s infinite}
.btn-answer.live .knob .ring{animation:ans-lines 6s linear -1.2s infinite}
.btn-answer.live .knob::before{animation:ans-pulse 6s var(--ease-out) -1.2s infinite}
.btn-answer.live .knob::after{animation:ans-pulse 6s var(--ease-out) -.95s infinite}
@keyframes ans-rattle{
  0%,16%,100%{transform:none}
  2%{transform:rotate(-12deg)} 4%{transform:rotate(12deg)} 6%{transform:rotate(-10deg)}
  8%{transform:rotate(10deg)} 10%{transform:rotate(-6deg)} 12%{transform:rotate(4deg)}
}
@keyframes ans-lines{0%{opacity:0;transform:scale(.7)}2%{opacity:1;transform:none}12%{opacity:1}16%{opacity:0;transform:scale(1.15)}100%{opacity:0}}
@keyframes ans-pulse{0%{opacity:.85;transform:scale(1)}18%{opacity:0;transform:scale(1.9)}100%{opacity:0;transform:scale(1.9)}}
/* answered */
.btn-answer:hover,.btn-answer:focus-visible{border-color:rgba(236,90,88,.7)}
.btn-answer:hover::before,.btn-answer:focus-visible::before{clip-path:inset(0 0 0 0 round 999px)}
.btn-answer:hover .knob,.btn-answer:focus-visible .knob{transform:translateX(var(--travel));background:#FBF6F0;color:var(--accent)}
.btn-answer:hover .lbl,.btn-answer:focus-visible .lbl{transform:translateX(calc((var(--k) + var(--gap) - 18px) * -1))}
.btn-answer:hover .lbl small,.btn-answer:focus-visible .lbl small{color:rgba(251,246,240,.84)}
.btn-answer:hover .knob svg,.btn-answer:focus-visible .knob svg,
.btn-answer:hover .knob::before,.btn-answer:focus-visible .knob::before,
.btn-answer:hover .knob::after,.btn-answer:focus-visible .knob::after{animation:none}
.btn-answer:hover .knob .hs,.btn-answer:focus-visible .knob .hs{animation:nv-pickup 1.9s cubic-bezier(.3,.7,.3,1) .3s both}
.btn-answer:hover .knob .ring,.btn-answer:focus-visible .knob .ring{animation:nv-ring 1.9s linear .3s both}
.btn-answer:active{transform:scale(.985)}
/* the top bar's own, smaller */
.btn-answer-sm{--h:42px;--k:32px;--in:5px;--w:158px;--gap:10px;font-size:14px}
@media (pointer:coarse){.btn-answer-sm{--h:44px;--k:34px}}

/* ── inner pages ──────────────────────────────────────────────────── */
.page{position:relative;z-index:2;padding-top:clamp(104px,13vh,150px)}   /* above .env, which is fixed at z-index 0 */
.page-head{padding:0 var(--gut);max-width:1440px;margin:0 auto clamp(40px,7vh,80px)}
.page-head .kicker{margin-bottom:18px}
.h1{
  font-family:var(--display);font-weight:800;
  font-size:clamp(38px,6.4vw,84px);line-height:1.0;letter-spacing:-.028em;
  margin:0 0 20px;max-width:16ch;
  font-variation-settings:'opsz' 96;
}
/* a page head with a picture beside it, stacked on narrow screens */
.page-head.with-pic{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);gap:0 clamp(24px,4vw,64px);align-items:end}
.page-head.with-pic > :not(.head-pic){grid-column:1}
.head-pic{grid-column:2;grid-row:1 / span 3;margin:0;aspect-ratio:3/2;overflow:hidden;border-radius:18px;border:1px solid var(--line-mid);background:var(--panel)}
.head-pic img,.prose-pic img{display:block;width:100%;height:100%;object-fit:cover}
.prose-pic{margin:clamp(34px,5vh,52px) 0 0;aspect-ratio:3/2;overflow:hidden;border-radius:16px;border:1px solid var(--line-mid);background:var(--panel)}
@media (max-width:900px){
  .page-head.with-pic{grid-template-columns:1fr}
  .head-pic{grid-column:1;grid-row:auto;margin-top:clamp(26px,4vh,38px)}
}
.page-lede{font-size:clamp(17px,1.5vw,22px);line-height:1.5;color:var(--text-secondary);max-width:54ch;margin:0}

/* prose for the about page */
.prose{max-width:66ch;padding:0 var(--gut)}
.prose h2{font-family:var(--display);font-weight:700;font-size:clamp(21px,2.3vw,30px);letter-spacing:-.02em;margin:clamp(40px,6vh,64px) 0 14px;font-variation-settings:'opsz' 96}
.prose p{font-size:16.5px;line-height:1.7;margin:0 0 17px;color:var(--text-primary)}
.prose p.dim{color:var(--text-secondary)}

/* ── plan cards for the subscription page ─────────────────────────── */
.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,290px),1fr));gap:20px;padding:0 var(--gut);max-width:1000px}
.plan{
  position:relative;padding:30px 28px 28px;border-radius:20px;
  background:rgba(243,236,225,0.06);border:1.5px solid var(--line-mid);
  transition:border-color .35s var(--ease),transform .35s var(--ease-out),box-shadow .35s var(--ease);
}
.plan:hover{transform:translateY(-4px);border-color:var(--line-mid);box-shadow:0 18px 44px -20px rgba(0,0,0,.28)}
.plan.featured{border-color:var(--accent);background:rgba(243,236,225,0.074)}
.plan-tag{position:absolute;top:-11px;left:28px;background:var(--accent);color:#fff;font-family:var(--mono);font-size:10.5px;letter-spacing:.11em;text-transform:uppercase;padding:5px 11px;border-radius:999px}
.plan-name{font-family:var(--mono);font-size:11.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--accent-text);margin:0 0 14px}
.plan-price{font-family:var(--display);font-weight:800;font-size:46px;line-height:1;letter-spacing:-.03em;margin:0;font-variation-settings:'opsz' 96}
.plan-price small{font-family:var(--body);font-weight:400;font-size:15px;letter-spacing:0;color:var(--text-secondary)}
.plan-note{color:var(--text-secondary);font-size:14.5px;margin:8px 0 20px}
.plan ul{list-style:none;margin:0 0 24px;padding:0}
.plan li{display:flex;gap:10px;align-items:flex-start;padding:7px 0;font-size:15px;line-height:1.45}
.plan li svg{flex:none;width:16px;height:16px;margin-top:3px;stroke:var(--accent);stroke-width:2.4;fill:none}

/* ══════════════════════════════════════════════════════════════════════
   THE APP: sign in, dashboard, add a receptionist, choose a number
   Front end only. Nothing here talks to a server; see the banner.
   ══════════════════════════════════════════════════════════════════════ */

/* A warning nobody can scroll past. It is fixed, so it stays true for the
   whole session, and --bar-h (measured in site.js) keeps the nav clear of it
   however many lines it wraps to on a narrow phone. */
.demo-bar{
  position:fixed;top:0;left:0;right:0;z-index:60;
  background:var(--text-primary);color:#1B1917;
  font-family:var(--mono);font-size:12px;line-height:1.5;
  padding:9px var(--gut);text-align:center;
}
.demo-bar strong{color:#A81717;font-weight:500}
body.has-demo-bar .nav{top:34px}
body.has-demo-bar .page{padding-top:clamp(132px,16vh,178px)}

.app{padding:0 var(--gut) clamp(80px,12vh,140px);max-width:1180px;margin:0 auto}

/* sign in */
.signin{max-width:420px;margin:0 auto;text-align:left}
.signin .h1{font-size:clamp(30px,4vw,46px);max-width:none}
.tabs{display:flex;gap:4px;background:var(--panel);padding:4px;border-radius:999px;margin:0 0 26px}
.tabs button{
  flex:1;border:0;background:transparent;cursor:pointer;border-radius:999px;
  font-family:var(--body);font-size:14.5px;font-weight:500;color:var(--text-secondary);
  padding:10px 14px;transition:background .3s var(--ease),color .3s var(--ease);
}
.tabs button[aria-selected="true"]{background:var(--raised);color:var(--text-primary);box-shadow:0 1px 3px rgba(0,0,0,.12)}

/* dashboard shell */
.app-head{display:flex;flex-wrap:wrap;gap:16px;align-items:flex-end;justify-content:space-between;margin:0 0 30px}
.app-head h2{font-family:var(--display);font-weight:800;font-size:clamp(28px,3.6vw,44px);letter-spacing:-.026em;margin:0;font-variation-settings:'opsz' 96}
.app-sub{color:var(--text-secondary);font-size:15.5px;margin:6px 0 0}

/* the empty state: the first thing a new customer sees */
.empty{
  text-align:center;padding:clamp(48px,9vh,88px) 28px;border-radius:22px;
  border:2px dashed var(--line-mid);background:rgba(243,236,225,0.049);
}
.empty .mark{width:40px;height:44px;margin:0 auto 20px;opacity:.85;top:0}
.empty h3{font-family:var(--display);font-weight:700;font-size:clamp(20px,2.4vw,28px);letter-spacing:-.02em;margin:0 0 10px;font-variation-settings:'opsz' 96}
.empty p{color:var(--text-secondary);max-width:44ch;margin:0 auto 26px;font-size:15.5px;line-height:1.55}

/* receptionist cards */
.recs{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,320px),1fr));gap:16px}
.rec{
  padding:22px;border-radius:18px;background:rgba(243,236,225,0.062);
  border:1.5px solid var(--line-mid);
  transition:border-color .35s var(--ease),transform .35s var(--ease-out),box-shadow .35s var(--ease);
}
.rec:hover{transform:translateY(-3px);border-color:var(--line-mid);box-shadow:0 16px 40px -20px rgba(0,0,0,.26)}
.rec-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin:0 0 14px}
.rec-name{font-family:var(--display);font-weight:700;font-size:19px;letter-spacing:-.018em;margin:0;font-variation-settings:'opsz' 96}
.rec-cat{font-family:var(--mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--text-secondary);margin:4px 0 0}
.rec-num{font-family:var(--mono);font-size:15px;color:var(--text-primary);margin:0 0 14px;letter-spacing:.01em}
.rec-stats{display:flex;gap:22px;padding-top:14px;border-top:1px solid var(--line)}
.rec-stats div span{display:block}
.rec-stats .n{font-family:var(--display);font-weight:800;font-size:22px;letter-spacing:-.02em;font-variation-settings:'opsz' 96}
.rec-stats .k{font-family:var(--mono);font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--text-secondary);margin-top:2px}

/* the add flow */
.steps-bar{display:flex;gap:8px;margin:0 0 28px;flex-wrap:wrap}
.steps-bar span{
  font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  padding:7px 13px;border-radius:999px;background:var(--panel);color:var(--text-secondary);
}
.steps-bar span[data-on="1"]{background:var(--accent);color:#fff}
.form-grid{display:grid;gap:17px;max-width:520px}
.field{display:flex;flex-direction:column;gap:7px}
.field > span{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-secondary)}
.field input,.field select{
  font-family:var(--body);font-size:16px;color:var(--text-primary);
  background:rgba(243,236,225,0.062);border:1px solid var(--line-strong);border-radius:9px;padding:13px 15px;width:100%;
  transition:border-color .3s var(--ease),background .3s var(--ease);
}
.field input:hover,.field select:hover{border-color:var(--text-secondary)}
.field input:focus,.field select:focus{border-color:var(--accent);background:var(--raised);outline:none}
.hint{font-size:13.5px;color:var(--text-secondary);margin:2px 0 0}

/* the phone number step */
.num-choice{display:grid;gap:12px;max-width:560px;margin:0 0 24px}
.opt{
  display:flex;gap:14px;align-items:flex-start;padding:17px 18px;border-radius:14px;cursor:pointer;
  background:rgba(243,236,225,0.055);border:1.5px solid var(--line-mid);
  transition:border-color .3s var(--ease),background .3s var(--ease);
}
.opt:hover{border-color:var(--line-mid)}
.opt input{margin-top:3px;accent-color:var(--accent);width:17px;height:17px;flex:none}
.opt:has(input:checked){border-color:var(--accent);background:rgba(243,236,225,0.076)}
.opt b{display:block;font-weight:500;font-size:15.5px;margin-bottom:3px}
.opt small{color:var(--text-secondary);font-size:13.5px;line-height:1.5}
.numbers{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,200px),1fr));gap:10px;max-width:660px;margin:16px 0 0}
.numbers button{
  font-family:var(--mono);font-size:15px;color:var(--text-primary);cursor:pointer;
  background:rgba(243,236,225,0.062);border:1.5px solid var(--line-mid);border-radius:11px;padding:14px;
  transition:border-color .3s var(--ease),background .3s var(--ease),transform .2s var(--ease);
}
.numbers button:hover{border-color:var(--accent);transform:translateY(-2px)}
.numbers button[aria-pressed="true"]{border-color:var(--accent);background:var(--raised)}

.app-actions{display:flex;gap:14px;align-items:center;flex-wrap:wrap;margin-top:28px}
/* NOT .done: the section entrances already put a 'done' class on every .sec
   when its stagger retires, and a bare .done rule centred every section on
   the site the moment it scrolled into view. */
.finished{text-align:center;padding:clamp(40px,8vh,76px) 24px}
.finished .big{color:var(--text-primary);font-family:var(--display);font-weight:800;font-size:clamp(26px,3.4vw,40px);letter-spacing:-.024em;margin:0 0 12px;font-variation-settings:'opsz' 96}
.finished p{color:var(--text-secondary);max-width:46ch;margin:0 auto 24px;font-size:15.5px}

@media (max-width:860px){
  .menu-btn{display:block}
  /* .nav uses backdrop-filter, which makes it the containing block for any
     fixed child, and that block is the nav's padding box, which already spans
     the viewport. So 0/0 is full width and top:100% is exactly the nav's
     bottom edge, wherever the preview bar has pushed it to. */
  .nav-links{
    position:fixed;top:100%;left:0;right:0;
    flex-direction:column;align-items:stretch;gap:0;
    background:var(--canvas);padding:6px var(--gut) 26px;
    box-shadow:0 22px 50px -22px rgba(0,0,0,.35);
    opacity:0;visibility:hidden;transform:translateY(-10px);
    transition:opacity .26s var(--ease-out),transform .34s var(--ease-out),visibility 0s .34s;
  }
  .nav-links.open{
    opacity:1;visibility:visible;transform:translateY(0);
    transition:opacity .26s var(--ease-out),transform .34s var(--ease-out),visibility 0s 0s;
  }
  .nav-links a:not(.btn):not(.btn-answer){display:block;padding:15px 2px;font-size:19px;border-bottom:1px solid var(--line)}
  .nav-links a:not(.btn):not(.btn-answer)::after{display:none}
  .nav-links .btn,.nav-links .btn-answer{margin-top:20px;align-self:flex-start}
}

/* ── the live pip on a receptionist card ────────────────────────────── */
.rec-live{
  display:inline-flex;align-items:center;gap:7px;flex:none;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;
  color:#8CCB99;background:rgba(140,203,153,.12);border-radius:999px;padding:5px 10px 5px 9px;
}
.rec-live i{width:6px;height:6px;border-radius:50%;background:#8CCB99;animation:pip 2.4s var(--ease) infinite}
@keyframes pip{0%,100%{opacity:1}50%{opacity:.35}}
.rec-src{font-size:13.5px;color:var(--text-secondary);margin:0 0 4px}
.rec-wait{font-size:14px;color:var(--text-secondary);margin:0;padding-top:14px;border-top:1px solid var(--line)}

/* The subscription block borrows .sec for its vertical rhythm but not its
   gutter, because .app has already applied one. Scoped through .page so it
   outranks the .page .sec rule further down, which ties on specificity. */
.page .app .sec{padding-left:0;padding-right:0;max-width:none}

/* the drawer covers the page, so the page must not scroll behind it */
body.nav-open{overflow:hidden}

/* [hidden] loses to any rule that sets display, and .field is a flex column,
   so the attribute quietly did nothing. It has to win outright. */
[hidden]{display:none !important}

/* Script moves focus to a heading when the view changes, so a screen reader
   lands in the right place. A heading is not a control, so it gets no ring. */
[tabindex="-1"]:focus,[tabindex="-1"]:focus-visible{outline:none}


/* ══════════════════════════════════════════════════════════════════════
   INNER PAGES
   .sec was tuned for the home page, where a spine runs down the left and
   every section is indented to clear it. There is no spine on these pages,
   so the indent is just a left edge that disagrees with the one above it.
   ══════════════════════════════════════════════════════════════════════ */
.page .sec{
  padding-left:var(--gut);
  padding-top:clamp(56px,8vh,104px);
  padding-bottom:clamp(56px,8vh,104px);
}
.page .sec-cta{padding-top:clamp(60px,9vh,116px);padding-bottom:clamp(76px,11vh,140px)}

/* the plan cards: whatever the bullet count, the buttons line up */
.plan{display:flex;flex-direction:column}
.plan ul{flex:1}
.plan > :last-child{margin-top:auto}

/* ── the about page's editorial rhythm ───────────────────────────────
   One long column on a wide screen is a column of text in a field of
   nothing. The heading moves out into the margin instead, which is how a
   printed page would set it, and the measure stays readable. */
@media (min-width:1080px){
  .prose{max-width:none;display:grid;grid-template-columns:clamp(200px,22vw,300px) minmax(0,62ch);gap:0 clamp(32px,4vw,64px)}
  .prose > *{grid-column:2}
  .prose h2{
    grid-column:1;justify-self:end;text-align:right;
    font-size:clamp(19px,1.6vw,23px);line-height:1.25;
    margin:clamp(40px,6vh,64px) 0 0;padding-top:.15em;
  }
  /* the paragraph that follows a heading must start on the heading's line */
  .prose h2 + p{margin-top:clamp(40px,6vh,64px)}
}

/* ══════════════════════════════════════════════════════════════════════
   THE DRAWER, PROPERLY
   .nav carries z-index 40, which makes it a stacking context, so the open
   drawer painted over the brand and over the very button that closes it.
   Lifting those two inside the nav puts the way out back on screen.
   ══════════════════════════════════════════════════════════════════════ */
.brand,.menu-btn{position:relative;z-index:1}

/* the three lines fold into a cross, so the button says what it will do */
.burger line{
  transform-origin:center;
  transition:transform .34s var(--ease-out),opacity .2s var(--ease);
}
.menu-btn[aria-expanded="true"] .burger line:nth-child(1){transform:translateY(6px) rotate(45deg)}
.menu-btn[aria-expanded="true"] .burger line:nth-child(2){opacity:0}
.menu-btn[aria-expanded="true"] .burger line:nth-child(3){transform:translateY(-6px) rotate(-45deg)}

@media (max-width:860px){
  /* clear the nav bar itself, not an eyeballed 84px */
}

/* everything the fixed bar has to push down */
body.has-demo-bar .nav{top:var(--bar-h,34px)}
body.has-demo-bar .page{padding-top:calc(clamp(104px,13vh,150px) + var(--bar-h,34px))}

/* ══════════════════════════════════════════════════════════════════════
   THE EIGHT RECEPTIONISTS
   A numbered rail on the left, the receptionist's own spec on the right.
   Each one is a separate assistant, so each one gets its own block rather
   than a row in a comparison table.
   ══════════════════════════════════════════════════════════════════════ */
.recept{padding:0 var(--gut);max-width:1180px}
.rp{
  display:grid;grid-template-columns:auto minmax(0,1fr) minmax(0,.8fr);gap:0 clamp(18px,3vw,44px);
  padding:clamp(30px,4.5vh,48px) 0;border-top:1px solid var(--line);
}
.rp:first-child{border-top:0;padding-top:0}
.rp-n{
  font-family:var(--display);font-weight:800;font-size:clamp(30px,4.6vw,62px);
  line-height:.9;letter-spacing:-.03em;color:var(--ember);margin:0;
  font-variant-numeric:tabular-nums;font-variation-settings:'opsz' 96;
  opacity:.28;transition:opacity .4s var(--ease);
}
.rp:hover .rp-n{opacity:1}
.rp-body h2{
  font-family:var(--display);font-weight:700;font-size:clamp(22px,2.7vw,34px);
  line-height:1.1;letter-spacing:-.022em;margin:0 0 8px;
  font-variation-settings:'opsz' 96;
}
.rp-who{color:var(--text-secondary);font-size:15.5px;line-height:1.55;margin:0 0 22px;max-width:56ch}
.rp .price-rows{margin:0;max-width:64ch}
.rp .price-rows div{padding:12px 0}
.rp .price-rows dd{font-size:15px;line-height:1.55}

/* each receptionist has the trade it was built for beside it */
.rp-pic{
  margin:0;align-self:start;aspect-ratio:3/2;overflow:hidden;border-radius:16px;
  border:1px solid var(--line-mid);background:var(--panel);
}
.rp-pic img{display:block;width:100%;height:100%;object-fit:cover;transition:transform 1.1s var(--ease-out)}
.rp:hover .rp-pic img{transform:scale(1.035)}
@media (max-width:900px){
  .rp{grid-template-columns:auto minmax(0,1fr)}
  .rp-pic{grid-column:2;margin-top:24px;max-width:560px}
}
@media (max-width:640px){
  .rp{grid-template-columns:1fr;gap:0}
  .rp-pic{grid-column:1}
  .rp-n{font-size:26px;opacity:1;margin-bottom:6px}
  .rp .price-rows div{grid-template-columns:1fr;gap:5px}
}

/* four plans need a tighter card than two did */
.plans-4{max-width:1180px;grid-template-columns:repeat(auto-fit,minmax(min(100%,250px),1fr))}
.plans-4 .plan{padding:26px 22px 24px}
.plans-4 .plan-price{font-size:40px}
.plans-4 .plan li{font-size:14.5px;padding:6px 0}
.plans-4 .plan li b{font-weight:500;color:var(--text-primary)}

/* ── the comparison table ─────────────────────────────────────────────
   It scrolls sideways inside its own box on a phone rather than forcing
   the whole page to scroll, and the row headings stay put while it does. */
.tw{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:0 0 26px;padding-bottom:4px}
.cmp{border-collapse:collapse;width:100%;min-width:560px;font-size:15px}
.cmp th,.cmp td{text-align:left;padding:13px 16px;border-bottom:1px solid var(--line)}
.cmp thead th{
  font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--accent-text);font-weight:500;border-bottom:1.5px solid var(--line);
}
.cmp tbody th{
  font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-secondary);font-weight:500;white-space:nowrap;
  position:sticky;left:0;background:var(--canvas);
}
.cmp tbody tr:hover td,.cmp tbody tr:hover th{background:rgba(243,236,225,0.055)}
.cmp td{font-variant-numeric:tabular-nums}
/* the plan most people take, marked in the table too */
.cmp th:nth-child(3),.cmp td:nth-child(3){background:rgba(243,236,225,0.058);font-weight:500}
.cmp thead th:nth-child(3){color:var(--accent-text)}

/* .plan li is a flex row; the bullet text is one item, never several */
.plan li > span{flex:1;min-width:0}

/* ── the picked receptionist's spec, shown before committing ─────────── */
.spec{
  margin:22px 0 0;max-width:600px;padding:20px 22px;
  background:rgba(243,236,225,0.062);border:1px solid var(--line-mid);border-radius:16px;
}
.spec-who{margin:0 0 4px;font-size:14.5px;color:var(--text-secondary)}
.spec .price-rows{margin:0;max-width:none}
.spec .price-rows div{padding:11px 0;grid-template-columns:clamp(84px,9vw,110px) 1fr;gap:14px}
.spec .price-rows div:last-child{border-bottom:0;padding-bottom:0}
.spec .price-rows dd{font-size:14.5px;line-height:1.5}

/* ── changing plan from the dashboard ────────────────────────────────── */
.plan-switch{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,160px),1fr));gap:10px;max-width:760px;margin:4px 0 12px}
.plan-switch button{
  display:flex;flex-direction:column;gap:5px;text-align:left;cursor:pointer;
  font-family:var(--body);font-size:15.5px;font-weight:500;color:var(--text-primary);
  background:rgba(243,236,225,0.061);border:1.5px solid var(--line-mid);border-radius:13px;padding:14px 16px;
  transition:border-color .3s var(--ease),background .3s var(--ease),transform .2s var(--ease);
}
.plan-switch button small{font-family:var(--mono);font-size:11px;letter-spacing:.04em;color:var(--text-secondary);font-weight:400}
.plan-switch button:hover:not(:disabled){border-color:var(--accent);transform:translateY(-2px)}
.plan-switch button[aria-pressed="true"]{border-color:var(--accent);background:var(--raised)}
.plan-switch button[aria-pressed="true"] small{color:var(--accent-text)}
.plan-switch button:disabled{opacity:.45;cursor:not-allowed}

/* the plan limit, said on the dashboard rather than sprung at step three */
.limit{
  margin:20px 0 0;max-width:62ch;padding:14px 18px;font-size:14.5px;line-height:1.55;
  color:var(--text-primary);background:var(--accent-muted);border-radius:12px;
}

/* ══════════════════════════════════════════════════════════════════════
   THE TWO DOORS
   The home page used to carry the full list of receptionists and the full
   price ladder, both of which now have their own page. These replace them:
   two panels that say what is behind each door and nothing more. They are
   also the only cards on the page, which breaks a run of five sections
   that were all kicker, headline, rows.
   ══════════════════════════════════════════════════════════════════════ */
.gates{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,330px),1fr));gap:20px;max-width:1080px}
.gate{
  --gp:clamp(28px,3.4vw,42px);
  position:relative;display:flex;flex-direction:column;
  padding:var(--gp);border-radius:22px;text-decoration:none;color:var(--text-primary);
  background:linear-gradient(168deg,rgba(243,236,225,.07),rgba(243,236,225,.035));
  border:1px solid var(--line-mid);overflow:hidden;
  box-shadow:0 2px 4px rgba(0,0,0,.04);
  transition:transform .42s var(--ease-out),box-shadow .42s var(--ease-out),border-color .42s var(--ease);
}
/* the accent washes up from the bottom edge on hover, rather than the whole
   card changing colour, so the text never has to fight for contrast */
.gate::before{
  content:"";position:absolute;inset:auto 0 0 0;height:100%;pointer-events:none;
  background:linear-gradient(to top,rgba(200,30,30,.14),transparent 62%);
  opacity:0;transition:opacity .42s var(--ease);
}
.gate:hover,.gate:focus-visible{
  transform:translateY(-5px);border-color:var(--line-mid);
  box-shadow:0 24px 54px -26px rgba(0,0,0,.34);
}
.gate:hover::before,.gate:focus-visible::before{opacity:1}
/* each door opens on a picture from the same shop: the pegboard of every
   trade's tools in the morning, the cold cup at night. Edge to edge across
   the card's top, easing into the panel, and leaning in a little on hover. */
.gate-pic{
  position:relative;display:block;overflow:hidden;aspect-ratio:3/2;
  margin:calc(var(--gp) * -1) calc(var(--gp) * -1) clamp(22px,2.6vw,30px);
  border-radius:21px 21px 0 0;background:var(--panel);
}
.gate-pic img{display:block;width:100%;height:100%;object-fit:cover;transition:transform 1.1s var(--ease-out)}
.gate-pic::after{content:"";position:absolute;inset:auto 0 0 0;height:34%;pointer-events:none;background:linear-gradient(to top,rgba(33,29,26,.72),rgba(33,29,26,0))}
.gate:hover .gate-pic img,.gate:focus-visible .gate-pic img{transform:scale(1.04)}
.gate-n{
  font-family:var(--display);font-weight:800;font-size:clamp(58px,7.4vw,104px);
  line-height:.82;letter-spacing:-.045em;color:var(--ember);margin-bottom:14px;
  font-variation-settings:'opsz' 96;
}
.gate-h{
  font-family:var(--display);font-weight:700;font-size:clamp(19px,1.9vw,25px);
  line-height:1.2;letter-spacing:-.018em;margin-bottom:14px;max-width:20ch;
  font-variation-settings:'opsz' 96;
}
.gate-p{color:var(--text-secondary);font-size:15.5px;line-height:1.58;margin-bottom:26px;max-width:46ch}
.gate-go{
  margin-top:auto;display:inline-flex;align-items:center;gap:10px;
  font-family:var(--mono);font-size:11.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--accent-text);
}
.gate-go::after{
  content:"";width:.5em;height:.5em;flex:none;
  border-right:1.8px solid currentColor;border-top:1.8px solid currentColor;
  transform:rotate(45deg);transition:transform .34s var(--ease-out);
}
.gate:hover .gate-go::after{transform:rotate(45deg) translate(3px,-3px)}

/* the demo's one honest line, on the screen where it matters most */
.finished .hint{max-width:48ch;margin:0 auto 4px;color:var(--text-secondary);font-size:14px;line-height:1.55}

/* ══════════════════════════════════════════════════════════════════════
   THE STOP MARKERS
   Three notes, three marks. They say how many there are, which one you are
   on, and give a way through the hero that never touches the wheel.
   ══════════════════════════════════════════════════════════════════════ */
.stops{
  position:absolute;right:calc(var(--gut) - 6px);top:50%;transform:translateY(-50%);
  z-index:7;display:flex;flex-direction:column;gap:14px;padding:6px;
}
.stop-dot{
  position:relative;width:26px;height:26px;padding:0;border:0;background:none;cursor:pointer;
  display:grid;place-items:center;
}
.stop-dot::after{
  content:"";width:7px;height:7px;border-radius:50%;
  background:var(--text-primary);opacity:.3;
  transition:opacity .4s var(--ease),transform .4s var(--ease-out),background-color .4s var(--ease);
}
.stop-dot:hover::after{opacity:.6;transform:scale(1.2)}
.stop-dot[aria-current="true"]::after{background:var(--accent);opacity:1;transform:scale(1.5)}
.stop-dot:focus-visible{outline:2px solid var(--accent);outline-offset:1px;border-radius:50%}
@media (max-width:720px){.stops{display:none}}

/* ══════════════════════════════════════════════════════════════════════
   SCENES
   A tall section with a sticky stage inside it: the hero. (The anatomy of
   a call was one too, until round 2 took its scroll lock away.)
   ══════════════════════════════════════════════════════════════════════ */
.scene{position:relative;z-index:2}

/* ══════════════════════════════════════════════════════════════════════
   WHO IT IS FOR (owner, feedback rounds 1 and 4)
   Twenty trades on a slow drift, edge to edge. Pointing at it stops it; it
   only moves while it is on screen (.moving, set by site.js). Under
   reduced motion it is a still grid of the twenty.
   ══════════════════════════════════════════════════════════════════════ */
.reel{
  margin:clamp(28px,5vh,52px) calc(var(--gut) * -1) 0;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent);
}
.reel-track{display:flex;gap:clamp(12px,1.6vw,20px);width:max-content;list-style:none;margin:0;padding:0 var(--gut)}
.reel.moving .reel-track{animation:reel 212s linear infinite}   /* the same pace as six cards in 64 s */
.reel:hover .reel-track{animation-play-state:paused}
@keyframes reel{to{transform:translate3d(-50%,0,0)}}
.reel-card{flex:none;width:clamp(210px,21vw,300px)}
.reel-card figure{margin:0}
.reel-card img{display:block;width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;border-radius:16px;border:1px solid var(--line-mid);background:var(--panel)}
.reel-card figcaption{
  margin-top:12px;font-family:var(--mono);font-size:11.5px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;color:var(--text-secondary);
}
@media (prefers-reduced-motion:reduce){
  .reel{-webkit-mask-image:none;mask-image:none;margin-left:0;margin-right:0}
  .reel.moving .reel-track{animation:none}
  .reel-track{flex-wrap:wrap;width:auto;padding:0}
  .reel-card[aria-hidden="true"]{display:none}
}

/* ══════════════════════════════════════════════════════════════════════
   THE DARK CLOSE
   The page has been cream from the first pixel. It ends on the oxblood that
   was in the footage all along, which is the one place a colour change
   earns itself.
   ══════════════════════════════════════════════════════════════════════ */
.sec-dark{
  position:relative;
  background:
    radial-gradient(120% 90% at 18% 0%, rgba(250,212,156,.14), transparent 62%),
    linear-gradient(168deg, var(--oxblood) 0%, var(--oxblood-deep) 100%);
  color:#F7F1EA;
  margin-top:clamp(50px,8vh,96px);
  padding-left:var(--gut);
  border-radius:26px 26px 0 0;
  overflow:hidden;
}
.sec-dark .h2,.sec-dark .h2-cta{color:#FBF6F0}
.sec-dark .lede{color:rgba(247,241,234,.74)}
/* the ember rule: it draws itself once, when the section arrives */
.sec-dark::before{
  content:"";position:absolute;left:var(--gut);top:0;height:2px;width:min(340px,42vw);
  background:linear-gradient(90deg,var(--ember),rgba(250,212,156,0));
  transform:scaleX(0);transform-origin:left;
  transition:transform 1.15s var(--ease-out) .15s;
}
.sec-dark.in::before{transform:scaleX(1)}

.sec-dark .btn-ghost{color:rgba(247,241,234,.72)}
.sec-dark .btn-ghost:hover{color:var(--ember)}

@media (max-width:720px){ .sec-dark{border-radius:20px 20px 0 0} }

/* the film, carried into the dark close and fading into the oxblood so the
   left half stays a clean ground for the words */
.cta-film{
  /* full width, so the only edge is the one the mask draws. At 58% the
     element's own left edge showed as a seam, because a luminosity blend
     still changes the ground wherever the element is, mask or no mask. */
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:62% 26%;
  z-index:0;pointer-events:none;
  opacity:.5;
  filter:saturate(.72) contrast(1.06) brightness(.62);
  mix-blend-mode:luminosity;
  -webkit-mask-image:linear-gradient(97deg,transparent 30%,rgba(0,0,0,.28) 48%,rgba(0,0,0,.8) 68%,#000 86%);
          mask-image:linear-gradient(97deg,transparent 30%,rgba(0,0,0,.28) 48%,rgba(0,0,0,.8) 68%,#000 86%);
}
.sec-dark > :not(.cta-film){position:relative;z-index:1}
@media (max-width:860px){
  .cta-film{width:100%;opacity:.26;
    -webkit-mask-image:linear-gradient(to top,transparent 0%,rgba(0,0,0,.6) 34%,#000 80%);
            mask-image:linear-gradient(to top,transparent 0%,rgba(0,0,0,.6) 34%,#000 80%);}
}

/* ══════════════════════════════════════════════════════════════════════
   THE CLOSE SIGNS OFF
   The logo once more, above the last headline, ringing once as the section
   arrives: the phone rings, Norvi picks up, and the page asks you to put it
   on your line. Cream, because red on oxblood would vanish.
   ══════════════════════════════════════════════════════════════════════ */
.close-mark{
  display:block;width:clamp(34px,3.4vw,46px);height:auto;aspect-ratio:27/30;
  overflow:visible;fill:#FBF6F0;margin:0 0 clamp(22px,3.4vh,34px);
}
.close-mark .ring{stroke:#FBF6F0}
