/* beadspoke.com: the page around the hero's drops, the film, the three
   graphics and the stack. Colours and type are the product's. No
   backdrop-filter, no masks: every soft edge here is a gradient or a
   separately blurred element. */

@font-face{font-family:Manrope;src:url(/fonts/Manrope.woff2) format('woff2');font-weight:200 800;font-display:swap}
/* V3's headline face, picked 2026-10-01: headlines only, the body and the UI
   stay Manrope. Google Fonts' latin subset, OFL (docs/landing-fonts.md). */
@font-face{font-family:'Schibsted Grotesk';src:url(/fonts/SchibstedGrotesk.woff2) format('woff2');font-weight:400 900;font-display:swap}

:root{
  --cream:#FCFAF7;--paper:#FFFFFF;--sand:#F8F4EF;--ink:#241E1A;--soft:#5F5249;--mute:#8A7C70;
  --mute-text:#776A5F; /* the mute, a shade darker: small text on cream and white at 4.5:1 */
  --hairs:#E4DCD3;--hair:#D9CFC4;--edge:#EAE3DB;
  --ember:linear-gradient(125deg,#e32f4c 0%,#ff6414 48%,#ffb300 100%);
  --cool:linear-gradient(125deg,#1F6F78 0%,#3E8E9C 48%,#93ADB8 100%);
  --gut:clamp(20px,5vw,64px);
  --sec:clamp(96px,14vh,180px);
  --ease:cubic-bezier(.2,.8,.2,1);
  --sh-pane:0 1px 2px rgba(36,30,26,.06),0 28px 70px -28px rgba(36,30,26,.30),0 10px 22px -14px rgba(36,30,26,.14);
  /* the ring first: a hairline edge, so the frame reads on the film's cream frames too */
  --sh-film:0 0 0 1px rgba(36,30,26,.07),0 1px 2px rgba(36,30,26,.06),0 30px 80px -30px rgba(36,30,26,.35),0 10px 24px -14px rgba(36,30,26,.18);
  --top-h:68px;
  --film-gap:clamp(24px,3.2vh,56px); /* the hero's foot to the film's top edge */
  --peek:clamp(120px,22vh,210px);    /* how much of the film shows under a wide hero on landing */
  /* the headline face: its family, weight, a size factor (it sets about as
     wide as Manrope at 1.02) and a tracking offset */
  --hf:'Schibsted Grotesk',Manrope,ui-sans-serif,system-ui,-apple-system,'Segoe UI',sans-serif;--hwt:800;--fk:1.02;--tk:.008em;
}
*,*::before,*::after{box-sizing:border-box}
html{background:var(--cream);-webkit-text-size-adjust:100%;text-size-adjust:100%;scroll-padding-top:calc(var(--top-h) + 16px)}
body{margin:0;background:var(--cream);color:var(--ink);font:400 18px/1.55 Manrope,ui-sans-serif,system-ui,-apple-system,'Segoe UI',sans-serif;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility}
main{position:relative;overflow-x:clip}
img,svg,video{display:block}
p,h1,h2{margin:0}
a{color:inherit}
::selection{background:#ffd9bf;color:var(--ink)}
:focus-visible{outline:3px solid #ff6414;outline-offset:3px}
.wrap{width:min(1180px,100% - 2*var(--gut));margin-inline:auto}
/* read aloud, not shown: a logo's name */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}

.skip{position:absolute;left:12px;top:-60px;z-index:100;padding:10px 16px;border-radius:999px;background:var(--ink);color:var(--cream);
  font-weight:600;font-size:15px;text-decoration:none;transition:top .2s var(--ease)}
.skip:focus{top:12px}

/* ── shared marks ─────────────────────────────────────────────────────── */
.ember{background:var(--ember);-webkit-background-clip:text;background-clip:text;color:transparent;-webkit-box-decoration-break:clone;box-decoration-break:clone}
.bead{display:inline-block;flex:none;width:10px;height:10px;border-radius:50%;background:var(--c,var(--ember))}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:48px;padding:0 24px;border-radius:999px;
  border:1px solid transparent;font:600 16px/1 Manrope,ui-sans-serif,system-ui,sans-serif;letter-spacing:-.005em;text-decoration:none;
  cursor:pointer;white-space:nowrap;-webkit-tap-highlight-color:transparent;
  transition:transform .3s var(--ease),box-shadow .3s var(--ease),background-color .2s,border-color .2s,color .2s}
.btn-ink{background:var(--ink);color:var(--cream);
  box-shadow:0 1px 2px rgba(36,30,26,.18),0 10px 22px -12px rgba(36,30,26,.55)}
.btn-ink .bead{box-shadow:0 0 10px 1px rgba(255,100,20,.55)}
.btn-ink:hover{transform:translateY(-1px);box-shadow:0 2px 4px rgba(36,30,26,.18),0 18px 30px -14px rgba(36,30,26,.6)}
.btn-ink:active{transform:translateY(0);transition-duration:.08s}

/* ── header ───────────────────────────────────────────────────────────── */
.top{position:fixed;left:0;right:0;top:0;z-index:60;background:rgba(252,250,247,0);box-shadow:0 1px 0 rgba(228,220,211,0);
  transition:background-color .35s var(--ease),box-shadow .35s var(--ease)}
/* fully solid: with no blur allowed, any see-through shows the copy behind it as ghost text.
   Without JS nothing marks it stuck, so it is solid from the start. */
.top.is-stuck,html:not(.js) .top{background:var(--cream);box-shadow:0 1px 0 var(--hairs)}
.top-in{display:flex;align-items:center;justify-content:space-between;gap:16px;height:var(--top-h)}
.brand{display:block;border-radius:6px}
.brand img{height:35.4px;width:auto} /* brand/final/beadspoke-gap.svg, its letters 1.3x the old wordmark's at 28px */
.btn-top{min-height:42px;padding:0 18px;font-size:15px;gap:9px}
.btn-top .bead{width:8px;height:8px}

/* ── hero (V3) ───────────────────────────────────────────────────────── */
/* A runway: the sticky stage is the first screen, under the header, and
   stays put for the first --pin of scroll while the orbs make their first
   movement (art/hero.js); then it scrolls away and the film comes up. At
   rest the whole screen is the client orb's colour with the coach floating
   on it; the scroll zooms out until the orb sits whole in its corner, on
   cream. The words sit left and middle (top on a phone), in ink, under the
   orbs (.hero-in), and again in cream over them (.hero-on, art/hero.js's
   copy), cut to the orb's own edge: a letter is cream on the orb and ink on
   the paper, never ink on the orb. Until the orbs are drawn (.is-live) the
   stage is the orb's colour and the words are cream; if they cannot be
   drawn (.is-failed), it is the paper and the words are ink.
   The zoom is over a little before the pinned run is (art/hero.js): the
   last of it is a still moment, carved out of the run, never added to it
   (Dawid, 2026-10-02: no empty space on the scroll). */
.hero{position:relative;--pin:60vh;height:calc(100vh + var(--pin))}
.hero-stage{position:sticky;top:0;height:100vh;min-height:520px;overflow:hidden;isolation:isolate}
@supports (height:100svh){ .hero{--pin:60svh;height:calc(100svh + var(--pin))} .hero-stage{height:100svh} }
html:not(.js) .hero{height:auto}
html:not(.js) .hero-stage{position:relative;height:auto;min-height:0;padding-bottom:40px}
.hero-bg{position:absolute;inset:0;z-index:0;background:var(--cream)}
.hero-in{position:relative;z-index:1;height:100%;display:flex;align-items:center;padding-top:var(--top-h)}
.hero-orbs{position:absolute;inset:0;z-index:2;pointer-events:none;contain:strict} /* the rings change size inside it; nothing outside relays out */
.hero-on{position:absolute;left:0;right:0;top:0;z-index:3;pointer-events:none}
/* a screen or more above the screen (landing.js): not drawn, so its layers go */
.hero.is-away .hero-stage{visibility:hidden}
/* the coach can be picked up (art/hero.js): an open hand over it, a closed
   one while it is held, and nothing under it selects while it is */
.hero.is-grab .hero-stage,.hero.is-grab .hero-stage *{cursor:grab}
.hero.is-grabbing,.hero.is-grabbing *{cursor:grabbing!important;-webkit-user-select:none;user-select:none}
html:not(.js) .hero-in{padding-block:calc(var(--top-h) + 40px) 40px}
.hero-copy{max-width:min(46rem,64%);padding-bottom:clamp(0px,4vh,40px)}
h1{font-family:var(--hf);font-weight:var(--hwt);font-size:calc(var(--h1) * var(--fk));letter-spacing:calc(-.045em + var(--tk));line-height:1;text-wrap:balance}
h1 .ember{padding-bottom:.06em}
:root{--h1:clamp(50px,7.2vw,112px)}
.lede{margin-top:clamp(18px,2.6vh,30px);max-width:30em;color:var(--soft);font-size:clamp(18px,1.45vw,22px);line-height:1.5;text-wrap:pretty}
/* the words on the orb: cream, "moments," too (Dawid, 2026-10-02: "just
   white, and only then does it become special when the orb finally
   disappears"): its ember is the ink copy's, so it shows exactly where the
   orb has uncovered the paper */
.hero-on h1,html.js .hero:not(.is-live):not(.is-failed) h1{color:var(--cream)}
.hero-on .lede,html.js .hero:not(.is-live):not(.is-failed) .lede{color:#F1ECE6}
.hero-on h1 .ember,html.js .hero:not(.is-live):not(.is-failed) h1 .ember{background:none;color:inherit}
/* the orb's colour, before the orb is drawn: its first frame lands on it */
html.js .hero:not(.is-live):not(.is-failed) .hero-bg{background:radial-gradient(130% 120% at 100% 100%,#3A8C97 0%,#24707A 46%,#185C65 100%)}
@media (max-width:699px){
  .hero{--pin:45vh}
  @supports (height:100svh){ .hero{--pin:45svh} }
  .hero-in{align-items:flex-start;padding-top:calc(var(--top-h) + clamp(18px,4vh,40px))}
  .hero-copy{max-width:100%}
  :root{--h1:min(13vw,64px)}
  .lede{font-size:17px}
}
@media (min-width:700px) and (max-width:1023.98px){ .hero-copy{max-width:78%} }

/* hero entrance: plain CSS, so it runs without JS too */
@keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.hi{animation:rise .9s var(--ease) backwards;animation-delay:calc(.08s + var(--i,0) * .09s)}

/* ── the film ─────────────────────────────────────────────────────────── */
.film-sec{margin-top:clamp(40px,9vh,110px)}
/* its own stacking context keeps the stage's glows (z-index:-1) inside it.
   2, not 0: the film is drawn after every section, not before (the
   graphics are 1, the words auto, below). Its settle plays on the scroll,
   so the compositor cannot bound where the film might go, and it would put
   every section painted after it, and all that merges with them, into
   layers of their own; painted last, it covers nothing it could not cover
   before (the sections are clear of it). */
.stage{position:relative;z-index:2;scroll-margin-top:calc(var(--top-h) + 24px)}
.stage::before{content:"";position:absolute;left:8%;right:8%;top:14%;bottom:-6%;z-index:-1;border-radius:50%;
  background:radial-gradient(closest-side,rgba(62,142,156,.16),rgba(62,142,156,0));filter:blur(40px);pointer-events:none}
.stage::after{content:"";position:absolute;left:34%;right:-2%;top:30%;bottom:-8%;z-index:-1;border-radius:50%;
  background:radial-gradient(closest-side,rgba(255,100,20,.13),rgba(255,100,20,0));filter:blur(46px);pointer-events:none}
.film{position:relative;aspect-ratio:16/9;border-radius:var(--fr,18px);overflow:hidden;isolation:isolate;background:#FBFAF5;
  box-shadow:var(--sh-film);transform:scale(var(--fs,1));transform-origin:50% 30%;animation:film-in 1s var(--ease) .2s backwards}
@keyframes film-in{from{opacity:0;translate:0 22px}to{opacity:1;translate:0 0}}
/* the entrance: the film settles from .92 to 1, its corners from 26px to 18px,
   over the first 72% of a screen of its stage coming up, on the stage's view
   timeline (the compositor plays the scale with the scroll, so it never trails
   it); where there are no view timelines, landing.js sets --fs and --fr */
@keyframes film-settle{from{transform:scale(.92)}to{transform:scale(1)}}
@keyframes film-round{from{border-radius:26px}to{border-radius:18px}}
@supports (animation-timeline:view()){
  .stage{view-timeline:--film-in block}
  .film{animation:film-in 1s var(--ease) .2s backwards,film-settle 1ms cubic-bezier(.33,1,.68,1) both,film-round 1ms cubic-bezier(.33,1,.68,1) both;
    animation-timeline:auto,--film-in,--film-in;animation-range:normal,cover 0% cover 72vh,cover 0% cover 72vh}
  /* past its range or well below the screen (landing.js): the settle off, so it is no layer; the entrance keeps its place */
  .film.fs-off{animation-name:film-in,none,none}
}
.film video{width:100%;height:100%;object-fit:cover;border-radius:inherit;background:#FBFAF5}
/* the poster (the film's cream end card) laid over the video by landing.js, faded once the
   film is rolling, so the cut from it to the film's dark first frame is a cross-fade */
.film-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;pointer-events:none;transition:opacity .7s var(--ease)}
.film.is-rolling .film-poster{opacity:0}
.film-ui[hidden]{display:none}
.film-ui{position:absolute;inset:0;pointer-events:none}
.film-ui button,.film-ui a{pointer-events:auto}

.fbtn{position:relative;display:inline-flex;align-items:center;gap:8px;height:42px;padding:0 17px 0 13px;border:0;border-radius:999px;cursor:pointer;
  background:rgba(36,30,26,.84);color:#FCFAF7;font:600 14.5px/1 Manrope,ui-sans-serif,system-ui,sans-serif;letter-spacing:-.005em;
  box-shadow:0 0 0 1px rgba(255,255,255,.14),0 10px 24px -10px rgba(20,15,12,.55);
  transition:background-color .2s,transform .3s var(--ease),box-shadow .3s var(--ease)}
@media (hover:hover){.fbtn:hover{background:rgba(36,30,26,.96);transform:translateY(-1px)}}
/* a bigger hit area than the pill shows (44 px on phones) */
.fbtn::after{content:"";position:absolute;inset:-5px;border-radius:inherit}

/* The sound button, bottom left (the film's captions own the top left). It
   is the hint that the film has sound, in plain sight for as long as the
   film is muted, with a mouse as on a touch screen (a cursor only tells the
   one who happens to cross the film); one soft ember ring leaves it when the
   film first rolls (landing.js adds .is-pulse). Once the sound is on it
   fades rather than hides, so it stays the keyboard's way to the sound. */
.film-ui .film-cue{position:absolute;left:clamp(12px,1.6vw,20px);bottom:clamp(14px,1.8vw,22px);z-index:2;
  opacity:0;translate:0 6px;pointer-events:none;
  transition:opacity .45s var(--ease),translate .45s var(--ease),background-color .2s,transform .3s var(--ease)}
.film.is-muted:not(.is-blocked) .film-cue,.film-ui .film-cue:focus-visible{opacity:1;translate:0 0;pointer-events:auto}
.film-cue .ico-sound{display:none}
.film-cue.is-on .ico-sound{display:block}
.film-cue.is-on .ico-muted{display:none}
.film-cue::before{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;box-shadow:0 0 0 0 rgba(255,100,20,0)}
.film-cue.is-pulse::before{animation:cue-ring 1.3s both}
/* two rings, the second fainter; each eases out as it spreads */
@keyframes cue-ring{
  0%{box-shadow:0 0 0 0 rgba(255,100,20,.6);animation-timing-function:cubic-bezier(.2,.8,.2,1)}
  52%{box-shadow:0 0 0 15px rgba(255,100,20,0)}
  52.1%{box-shadow:0 0 0 0 rgba(255,100,20,.36);animation-timing-function:cubic-bezier(.2,.8,.2,1)}
  100%{box-shadow:0 0 0 13px rgba(255,100,20,0)}}
/* A touch screen has no cursor to carry the glyph, so there the button stays
   once the sound is on, a step quieter, and is the way to turn it off again.
   It stays as its glyph alone: the same pill narrows in place to a disc
   (landing.js). While it narrows (.is-chipping) a clip closes over the words,
   so only paint changes from frame to frame; then it takes the disc's own
   box in one step (.is-chip), which looks the same. The glyph sits a pixel
   further left than under a mouse, where the disc's centre will be. And a
   tap flashes no highlight, and two quick taps do not zoom the page. */
@media (hover:none){
  .film,.film video,.film-cue,.film-big{-webkit-tap-highlight-color:transparent}
  .film{touch-action:manipulation}
  .film-ui .film-cue{padding-left:12px}
  .film:not(.is-blocked) .film-cue{opacity:1;translate:0 0;pointer-events:auto}
  .film:not(.is-muted):not(.is-blocked) .film-cue:not(:focus-visible){opacity:.7}
  .film-cue.is-chipping{animation:cue-chip .5s var(--ease) both}
  .film-cue.is-chipping .film-cue-t{opacity:0;transition:opacity .35s linear}
  .film-ui .film-cue.is-chip{padding:0 12px;box-shadow:0 0 0 1px rgba(255,255,255,.14)}
  .film-cue.is-chip .film-cue-t{display:none}
}
/* the clip is a circle round the glyph, from wider than the pill down to the disc and its
   hairline (--cue-d, the pill's height), so the edge that closes in ends as the disc's own;
   the words fade under it and the pill's soft shadow goes first, before the circle would cut it.
   (An inset with round corners would do, but Chrome squares them over the film on a dense screen.) */
@keyframes cue-chip{
  from{clip-path:circle(120% at calc(var(--cue-d,42px) / 2) 50%)}
  30%{box-shadow:0 0 0 1px rgba(255,255,255,.14),0 10px 24px -10px rgba(20,15,12,0)}
  to{clip-path:circle(calc(var(--cue-d,42px) / 2 + 1px) at calc(var(--cue-d,42px) / 2) 50%);
    box-shadow:0 0 0 1px rgba(255,255,255,.14),0 10px 24px -10px rgba(20,15,12,0)}}

/* Play/pause: small and quiet, tucked in the bottom right corner, for the
   rare viewer who wants the film still (a click on the film is for the
   sound). The pill's ink, a size down and see-through. With a mouse it shows
   while the pointer is over the film; on a touch screen it is always there;
   once paused it stays, so the way back is in sight. */
.film-pp{position:absolute;right:clamp(12px,1.6vw,20px);bottom:clamp(14px,1.8vw,22px);z-index:2;width:34px;height:34px;margin:0;padding:0;
  display:grid;place-items:center;border:0;border-radius:50%;cursor:pointer;color:#FCFAF7;background:rgba(36,30,26,.5);
  box-shadow:0 0 0 1px rgba(255,255,255,.14);opacity:.7;-webkit-tap-highlight-color:transparent;
  transition:opacity .45s var(--ease),background-color .2s}
.film-pp::after{content:"";position:absolute;inset:-6px;border-radius:inherit} /* 44 px or more to the touch */
.film-pp svg{width:12px;height:12px}
.film-pp .ico-play{display:none;margin-left:2px}
.film.is-stopped .film-pp .ico-play{display:block}
.film.is-stopped .film-pp .ico-pause{display:none}
@media (hover:hover) and (pointer:fine){
  .film-pp{opacity:0}
  .film:hover .film-pp,.film.is-paused .film-pp{opacity:.7}
}
.film .film-pp:focus-visible{opacity:1;background:rgba(36,30,26,.84)}
@media (hover:hover){.film .film-pp:hover{opacity:1;background:rgba(36,30,26,.84)}}
.film.is-blocked .film-pp{opacity:0;visibility:hidden}

.film-bar{position:absolute;left:0;right:0;bottom:0;height:3px;background:rgba(36,30,26,.07)}
.film-bar i{display:block;height:100%;background:var(--ember);transform-origin:0 50%;transform:scaleX(0)}
.film.is-muted .film-bar{opacity:.85}

.film-big{position:absolute;left:50%;top:73%;width:clamp(64px,8vw,92px);aspect-ratio:1;margin:0;padding:0;border:0;border-radius:50%;
  display:grid;place-items:center;color:#fff;cursor:pointer;background:var(--ember);transform:translate(-50%,-50%);
  box-shadow:0 0 0 8px rgba(255,255,255,.55),0 22px 44px -14px rgba(227,47,76,.6),0 10px 20px -10px rgba(255,100,20,.5);
  transition:transform .35s var(--ease),box-shadow .35s var(--ease)}
.film-big svg{margin-left:4px}
.film-big:hover{transform:translate(-50%,-50%) scale(1.05)}
.film-big[hidden]{display:none}

/* a mouse over the film: the pointer is the button above in small, carrying
   the glyph of what a click does (landing.js): the speaker with its waves
   while muted, struck through while it sounds, the play glyph while it stands
   still. The box only follows the pointer, exactly; the disc in it only
   fades, grows and pops, in place. */
.film.has-cursor video{cursor:none}
.film-cursor{position:fixed;left:0;top:0;z-index:59;width:0;height:0;pointer-events:none}
.fc-b{position:absolute;left:-29px;top:-29px;width:58px;height:58px;border-radius:50%;display:grid;place-items:center;
  color:#fff;background:var(--ember);
  box-shadow:0 0 0 6px rgba(255,255,255,.55),0 18px 36px -12px rgba(227,47,76,.55),0 8px 16px -8px rgba(255,100,20,.45);
  opacity:0;transform:scale(.6);transition:opacity .16s linear,transform .22s cubic-bezier(.2,.8,.2,1)}
.film-cursor.on .fc-b{opacity:1;transform:none}
.fc-b svg{display:none;width:24px;height:24px}
.film-cursor:not(.is-play):not(.is-sounding) .ico-sound,
.film-cursor.is-sounding:not(.is-play) .ico-muted{display:block}
.film-cursor.is-play .ico-play{display:block;width:20px;height:20px;margin-left:3px}

/* ── features ─────────────────────────────────────────────────────────── */
/* positioned, so each section paints above the spine's rail (spine.js lays it under them) */
.feat,.stack,.beta{position:relative}
.stack,.beta{isolation:isolate}
/* The words are painted first, then the graphics (.feat-art, below), then
   the film (.stage). The compositor takes a graphic that moves as able to
   reach anywhere on the page, so whatever is painted after it is a layer
   of its own, and what follows flush with that joins it: painted in page
   order, the rehearsal, the stack and the form were one layer three
   screens tall. A graphic does not overlap the words of the sections after
   it, so nothing changes on the screen; each graphic is its own stacking
   context (and the group its blends mix in) as its section was. */
/* The hero's stage is sticky and its rings move, and the compositor tests
   both for overlap as far as nothing clips them: unclipped, the spine, the
   sections and everything that merges with them become layers the height
   of the page (68 to 113 Mpx more at 1728x1117@2). The stage never leaves
   its runway, so clipping the runway to its own box changes nothing on
   the screen. A page-level layering rule, not the hero's look: it stays
   here, whatever the hero's own rules become. */
main>.hero{overflow:clip}
/* The same for the matrix: its idle bob is an animated transform, which the
   compositor takes as able to reach anywhere, so the film's stage (painted
   after every section) and the graphics after it became layers at every
   stand the bob runs (about 13 device Mpx at 1728x1117@2). Clipped to its
   section, it reaches no further than that. Nothing in it is painted past
   the section but the quote's shadow (at most 48 px under it, at every
   width), inside the margin; across, main already clips. Where the margin
   is not known (Safari), no clip: nothing is cut there either. */
@supports (overflow-clip-margin:64px){ .feat-matrix{overflow:clip;overflow-clip-margin:64px} }
.feat{padding-top:var(--sec)}
.feat-grid{display:grid;grid-template-columns:minmax(0,1fr);row-gap:clamp(40px,6vw,64px)}
/* a step under the hero's headline at every width: that stays the biggest type on the page */
h2{font-family:var(--hf);font-weight:var(--hwt);font-size:calc(clamp(32px,4.3vw,62px) * var(--fk));letter-spacing:calc(-.04em + var(--tk));line-height:1.03;text-wrap:balance}
h2 .ember{padding-bottom:.06em}
.body{margin-top:22px;max-width:34em;color:var(--soft);font-size:clamp(18px,1.35vw,19.5px);line-height:1.58;text-wrap:pretty}
.body+.body{margin-top:14px}
.feat-art{position:relative;z-index:1;min-width:0;container:art/inline-size}
.art{position:relative;width:100%}
/* until a graphic mounts, hold the height it will take at this width (measured
   from each module, 320 to 1180 wide), so nothing below it moves when it lands */
.art:empty{min-height:520px}
.art[data-art=wheel]:empty{min-height:clamp(520px,82.5cqw + 39px,767px)}
/* the giant matrix (art/matrix.js, measured 2026-10-01): 654 stacked, 644 under 460, 761 beside the words;
   a phone's (2026-10-04: no quote under it, it ends with its stage, a step under the last row): 558.76, and 541.68 under 460 */
.art[data-art=matrix]:empty{min-height:654px}
@media (min-width:1024px){ .art[data-art=matrix]:empty{min-height:761px} }
@media (max-width:699px){ .art[data-art=matrix]:empty{min-height:558.76px} }
/* V3's rehearsal, measured 280 to 1760 wide (2026-10-03, one view: no card,
   and from 880 up the conversation stands over the client, two lines of it
   at once; every line of the client's carries its name): stacked, its
   words' wrapping sets it; wide, it grows with its drops and, between 1180
   and 1290, with its words. Under 600 (a phone, measured again 2026-10-04):
   two lines of the conversation over the hint, and under 360 the client's
   chip on two lines */
.art[data-art=rehearsal]:empty{min-height:451px}
@container art (width < 277px){ .art[data-art=rehearsal]:empty{min-height:471px} }
@container art (width >= 289px) and (width < 330px){ .art[data-art=rehearsal]:empty{min-height:max(431px,35.3cqw + 322px)} }
@container art (width >= 330px) and (width < 360px){ .art[data-art=rehearsal]:empty{min-height:calc(32cqw + 337.5px)} }
@container art (width >= 360px) and (width < 493px){ .art[data-art=rehearsal]:empty{min-height:min(32cqw + 325px,480px)} }
@container art (width >= 493px) and (width < 600px){ .art[data-art=rehearsal]:empty{min-height:460px} }
@container art (width >= 600px) and (width < 880px){ .art[data-art=rehearsal]:empty{min-height:clamp(524px,20cqw + 404px,564px)} }
@container art (width >= 880px) and (width < 1060px){ .art[data-art=rehearsal]:empty{min-height:max(352px,20cqw + 162px)} }
@container art (width >= 1060px) and (width < 1180px){ .art[data-art=rehearsal]:empty{min-height:calc(20cqw + 171px)} }
@container art (width >= 1180px) and (width < 1290px){ .art[data-art=rehearsal]:empty{min-height:calc(27cqw + 88px)} }
@container art (width >= 1290px){ .art[data-art=rehearsal]:empty{min-height:calc(20cqw + 184px)} }
@container art (width < 560px){ .art[data-art=wheel]:empty{min-height:676px} }
@container art (width < 440px){ .art[data-art=wheel]:empty{min-height:614px} }
/* a phone's whole wheel (html[data-wheel="1"] up to 621px; art/wheel.js, PH;
   measured 2026-10-04, 320 to 430 wide). Its box is four fifths of the
   column, or what the screen's small height leaves under the bar, the
   heading (10 under the bar), the words and the gap under them (--wl: the
   heading's two lines, the body's six, seven from 323 down) and the fork
   (35 over the box, 21 under its ring), and never under 234. The wheel
   stands alone there (Dawid, 2026-10-04: "that whole area of scores and the
   impact card below the wheel should be gone"): the root is .990942 of the
   box (down to its ring's foot) and 63 of fork, 35 over it and 28 under, to
   where the thread closes */
@media (max-width:621px){
  @container art (width < 560px){
    html[data-wheel="1"] .art[data-art=wheel]:empty{--wl:calc(2.06 * var(--fk) * clamp(28px,8.2vw,34px) + 220.64px);
      min-height:calc(.990942 * clamp(234px,(100svh - var(--top-h) - var(--wl) - 66px) * 1.009141,max(80cqw,234px)) + 63px)}
  }
  @container art (width < 324px){ html[data-wheel="1"] .art[data-art=wheel]:empty{--wl:calc(2.06 * var(--fk) * clamp(28px,8.2vw,34px) + 249.08px)} }
}
@container art (width < 460px){ .art[data-art=matrix]:empty{min-height:541.68px} }
/* the giant wheel (art/wheel.js, layoutGiant) sizes itself to the screen:
   stacked, 2R + its card under it; beside the words, 2R and the rim */
html[data-wheel="2"] .art[data-art=wheel]:empty{min-height:calc(2 * clamp(220px, min(95vw, 60vh), 560px) + 344px)}
@media (min-width:1024px){ html[data-wheel="2"] .art[data-art=wheel]:empty{min-height:calc(2 * clamp(300px, 60vh, 900px) + 156px)} }
.feat-art.is-failed,html:not(.js) .feat-art{display:none}
.feat-art-wide{margin-top:clamp(40px,6vw,76px)}

/* The problem: one statement, set large, the head of sales' own pain. On a
   wide page it starts a quarter of the way in: the spine comes down out of
   the film's bottom-left corner and runs down the lane it leaves. */
.feat-problem h2{font-size:calc(clamp(32px,4.6vw,66px) * var(--fk));max-width:15.5em}
.feat-problem .body{margin-top:clamp(20px,2.2vw,30px);max-width:32em;font-size:clamp(18px,1.6vw,22.5px);line-height:1.55}
/* a phone: the headings a step under the hero's (8.4vw there) at every width */
@media (max-width:699px){ h2,.feat-problem h2{font-size:calc(clamp(28px,8.2vw,34px) * var(--fk))} }
/* a phone's whole wheel (html[data-wheel="1"], art/wheel.js PH) stands close
   under its words, so the heading, the words and the whole wheel are one
   screen: the gap takes the thread's crossing to it and no more */
@media (max-width:621px){ html[data-wheel="1"] .feat-wheel .feat-grid{row-gap:28px} }

@media (min-width:1024px){
  .feat-grid{grid-template-columns:repeat(12,minmax(0,1fr));column-gap:clamp(24px,3vw,44px);align-items:center}
  .feat-problem .feat-text{grid-column:4/-1}
  .feat-wheel .feat-text{grid-column:1/span 5}
  .feat-wheel .feat-art{grid-column:6/span 7}
  .feat-matrix .feat-art{grid-column:1/span 7;grid-row:1}
  .feat-matrix .feat-text{grid-column:8/span 5;grid-row:1}
  .feat-grid:has(.feat-art.is-failed) .feat-text,html:not(.js) .feat-grid .feat-text{grid-column:1/-1}
  .feat-head,.stack-head{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:clamp(24px,3vw,44px);align-items:end}
  .feat-title,.stack-head h2{grid-column:1/span 6}
  .feat-copy,.stack-head .body{grid-column:8/span 5;padding-bottom:4px}
  .feat-copy .body:first-child,.stack-head .body{margin-top:0}
}
/* where the copy runs taller than the title, it starts level with the H2 */
@media (min-width:1024px) and (max-width:1279px){
  .feat-head,.stack-head{align-items:start}
  .feat-copy,.stack-head .body{grid-column:7/span 6;padding-top:6px;padding-bottom:0}
}
/* stacked, the spine passes the words in the right-hand gutter: the problem's
   heading and the stack's line keep their ragged edge off it, as the
   features' copy does (the spine block below) */
@media (max-width:1023.98px){
  html[data-spine] .feat-problem h2,html[data-spine] .stack-head h2,html[data-spine] .stack-head .body{padding-right:18px}
}

/* reveal on scroll: only once landing.js has marked what is already on screen */
.rv [data-rv]{opacity:0;transform:translateY(16px);transition:opacity .7s var(--ease) var(--d,0s),transform .7s var(--ease) var(--d,0s)}
.rv [data-rv].in{opacity:1;transform:none}
/* a phone's whole wheel (html[data-wheel="1"], art/wheel.js PH) is not faded
   or slid in: it stands in its slot all along, inside the thread's fork
   (spine.js does not fold it), and opens by itself as the page brings it in.
   Faded in from its own top's crossing it was still unseen with its heading
   a third of the way down the screen (Dawid, 2026-10-04: "I am being
   introduced to the chapter without seeing the graphic at all") */
@media (max-width:621px){ html[data-wheel="1"].rv .feat-wheel .feat-art[data-rv]{opacity:1;transform:none} }

/* ── fits your stack ──────────────────────────────────────────────────── */
/* Where the page is already brown. The logos are a list in one tone that
   takes the vendors' colours as the playhead reaches them, each on
   its own quiet plate (.sk-bead): the spine threads them like beads, down a
   row through their centres, round the end and back along the next. So a
   row's plates are one height on one centre line, with room between them for
   the rail to show (--sk-gap), room at both ends for its turns (--sk-end),
   and the group names sit above their rows, never on a line. A row that runs
   out of width wraps into a second line that keeps the same rules. HubSpot
   (.sk-next) hangs apart below the last row's end, off the thread: its plate
   is a dashed ring, the only status on the page. */
.stack{padding-top:var(--sec);
  --sk-plate:54px;--sk-pad:24px;--sk-gap:clamp(32px,3.4vw,48px);--sk-row-gap:40px;--sk-end:72px;--sk-k:1;--sk-t:15px}
.stack-head .body{max-width:30em}
.sk-groups{margin-top:clamp(48px,6vw,80px);display:flex;flex-direction:column}
.sk-group+.sk-group{margin-top:44px}
.sk-group.sk-crm{margin-top:22px;align-self:flex-end;padding-right:var(--sk-end)}
.sk-label{padding-inline:var(--sk-end);margin-bottom:16px;color:var(--mute-text);font-size:14px;font-weight:600;line-height:1.3;letter-spacing:.005em}
.sk-crm .sk-label{padding-inline:0}
.sk-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sk-row-gap) var(--sk-gap);padding-inline:var(--sk-end)}
.sk-row+.sk-row{margin-top:var(--sk-row-gap)}
.sk-bead{--sk-lg:8px;display:flex;align-items:center;gap:var(--sk-lg);flex:none;height:var(--sk-plate);padding-inline:var(--sk-pad);border-radius:999px;
  background:var(--paper);box-shadow:0 0 0 1px var(--edge);color:var(--ink);white-space:nowrap;
  transition:background-color .9s var(--ease),box-shadow .9s var(--ease),color .9s var(--ease)}
.sk-logo{--lh:max(calc(var(--h) * var(--sk-k) * 1px),calc(var(--hmin,0) * 1px));flex:none;width:auto;height:var(--lh)}
/* each logo twice: one tone (.sk-mono) and the vendor's own colours for a
   dark ground (.sk-hue), laid exactly over it. The colour one takes no room:
   pulled back by its own width (height x the viewBox's aspect, --a) and the
   gap before it. It shows once the playhead reaches the plate (spine.js puts
   .is-lit on it) and on a brown page with no spine. Colour comes in over the
   cream, and the cream goes once it is covered, so the swap never thins out;
   going back, the other way round. The colour files are made for dark
   grounds, so a light page keeps the one tone. */
.sk-hue{margin-left:calc(var(--lh) * var(--a) * -1 - var(--sk-lg));opacity:0}
html.is-dusk .sk-bead.is-lit .sk-hue,html.is-dusk:not([data-spine="on"]) .sk-hue{opacity:1}
html.is-dusk .sk-bead.is-lit .sk-mono,html.is-dusk:not([data-spine="on"]) .sk-mono{opacity:0}
@media (prefers-reduced-motion:no-preference){
  .sk-mono,html.is-dusk .sk-bead.is-lit .sk-hue,html.is-dusk:not([data-spine="on"]) .sk-hue{transition:opacity .5s var(--ease)}
  .sk-hue,html.is-dusk .sk-bead.is-lit .sk-mono,html.is-dusk:not([data-spine="on"]) .sk-mono{transition:opacity .3s var(--ease) .2s}
}
.sk-name,.sk-your{font-size:var(--sk-t);font-weight:600;letter-spacing:-.005em;line-height:1}
.sk-your{margin-right:-1px}
.sk-next{background:transparent;box-shadow:none;border:1.5px dashed var(--hair)}
.sk-tag{margin-left:4px;padding:5px 9px;border-radius:999px;font-size:12px;font-weight:700;line-height:1;letter-spacing:.01em;
  color:var(--soft);box-shadow:inset 0 0 0 1px var(--hair)}
/* narrower than a laptop: the rows take the whole width of the screen (the
   rail turns in the gutters), and the logos go down to 0.8 */
@media (max-width:1023.98px){
  .sk-groups{margin-inline:calc(var(--gut) * -1)}
  .stack{--sk-end:max(56px,var(--gut))}
}
@media (max-width:699px){
  .stack{--sk-plate:44px;--sk-pad:14px;--sk-gap:32px;--sk-row-gap:28px;--sk-end:56px;--sk-k:.8;--sk-t:12px}
  .sk-bead{--sk-lg:6px}
  .sk-group+.sk-group{margin-top:36px}
  .sk-group.sk-crm{margin-top:20px}
  .sk-label{margin-bottom:12px;font-size:13px}
  .sk-tag{padding:4px 7px;font-size:11px}
}
@media (min-width:700px) and (max-width:1023.98px){ .stack{--sk-k:.9;--sk-t:14px;--sk-pad:20px;--sk-plate:50px} }
/* 360 to 374: a little less plate round each logo, so the recorders still pair up */
@media (max-width:374px){ .stack{--sk-pad:11px} }

/* ── V3 batch 2: the logos hung on strands of the spine ───────────────── */
/* Two ways, behind the switch (html[data-stack]). "2", drops with beads:
   while the spine is drawn (html[data-spine=on]) it lays the logos out
   itself (spine.js, layFan), every pill placed absolutely in .sk-groups,
   which takes the height the spine gives it, its strand forking round it,
   as the rail does round each plate on its rows. "1", batch 1's rail: the
   rows above, as they stand, with the spacing the forks round each plate
   need (below, with the spine). HubSpot keeps its dashed ring in both. */
html[data-spine=on]:not([data-stack="1"]) .sk-groups{display:block;position:relative;margin-top:clamp(40px,4.4vw,64px)}
html[data-spine=on]:not([data-stack="1"]) .sk-group{position:absolute;inset:0;margin:0;padding:0;align-self:normal} /* an absolute box takes align-self now: the CRM's flex-end would sink it */
html[data-spine=on]:not([data-stack="1"]) .sk-row{display:block;margin:0;padding:0}
html[data-spine=on]:not([data-stack="1"]) .sk-bead{position:absolute}

/* ── beta ─────────────────────────────────────────────────────────────── */
/* a little more air above: the two drops stand off the pane's top edge.
   A jump to #beta lands with the pane, not the section's padding, under the header. */
.beta{padding-block:calc(var(--sec) + 36px) var(--sec);scroll-margin-top:calc(56px - var(--sec) - 36px)}
/* a phone: the jump lands the pane's top edge just under the header (html's
   scroll-padding), so the form and its button are on the screen at once; and
   under the trust list half the page's step, the footer is all that is left */
@media (max-width:699px){ .beta{padding-bottom:clamp(56px,9vh,84px);scroll-margin-top:calc(0px - var(--sec) - 36px)} }
.beta-pane{position:relative;isolation:isolate}
.beta-card{position:relative;display:grid;grid-template-columns:minmax(0,1fr);gap:clamp(28px,4vw,40px);
  padding:clamp(28px,5.4vw,76px);background:var(--paper);border:1px solid var(--edge);border-radius:24px;box-shadow:var(--sh-pane)}
.beta-text .body{max-width:24em}
/* wide: heading left and its line right, then the three fields in one row, the button and
   its fine print under them, so the pane has no empty column */
@media (min-width:900px){
  .beta-card{row-gap:clamp(28px,3.4vw,44px)}
  .beta-text{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);column-gap:clamp(40px,6vw,96px);align-items:end}
  .beta-text .body{margin-top:0;padding-bottom:8px}
  .beta-form{grid-template-columns:repeat(3,minmax(0,1fr));column-gap:16px;align-items:end}
  .beta-form .form-foot{grid-column:1/-1;flex-direction:row;flex-wrap:wrap;align-items:center;column-gap:24px}
  .beta-form .form-err{order:2;flex-basis:100%}
}

.beta-slot{display:grid;min-width:0}
.beta-slot>*{grid-area:1/1}
.beta-form{display:grid;gap:18px;transition:opacity .45s var(--ease),transform .45s var(--ease)}
.beta-form[hidden]{display:none}
.beta-slot.is-instant *{transition:none!important}
.field{display:grid;gap:8px}
.field label{font-size:15px;font-weight:700;color:var(--ink);letter-spacing:-.005em}
.opt{margin-left:6px;color:var(--mute-text);font-weight:500;font-size:13px}
.field input{width:100%;height:54px;padding:0 16px;border:1px solid var(--hair);border-radius:12px;background:var(--cream);color:var(--ink);
  font:500 17px/1.2 Manrope,ui-sans-serif,system-ui,sans-serif;letter-spacing:-.005em;-webkit-appearance:none;appearance:none;
  transition:border-color .2s,background-color .2s,box-shadow .2s}
.field input:hover{border-color:#C9BCAE}
@media (hover:none){ .field input:hover{border-color:var(--hair)} } /* a finger leaves no hover behind */
.field input:focus{outline:none;background:#fff;border-color:#ff6414;box-shadow:0 0 0 3px rgba(255,100,20,.22)}
.field input:focus-visible{outline:3px solid #ff6414;outline-offset:3px;box-shadow:none}
.hp{position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden}
.form-foot{display:flex;flex-direction:column;align-items:flex-start;gap:14px;margin-top:4px}
.form-err{color:#992821;font-size:15px;font-weight:600;line-height:1.4}
.form-err:empty{display:none}
.form-err:not(:empty){animation:rise .45s var(--ease) backwards}
/* without JS, the worker's 303 lands on #beta-error or #joined, and CSS shows it */
html:not(.js) #beta-error:target{display:block}
html:not(.js) .beta-done:target{display:grid;opacity:1;transform:none}
html:not(.js) .beta-slot:has(.beta-done:target) .beta-form{display:none}
#beta-error,.beta-done{scroll-margin-top:min(38vh,300px)}
.btn-submit{min-height:54px;padding:0 28px}
/* to a finger: no lift left behind after the tap, no flash, no double-tap zoom on the form's controls or the footer's mark */
@media (hover:none){
  .btn-submit:hover{transform:none;box-shadow:0 1px 2px rgba(36,30,26,.18),0 10px 22px -12px rgba(36,30,26,.55)}
  .btn-submit,.field input,.foot-brand{touch-action:manipulation;-webkit-tap-highlight-color:transparent}
}
.btn-submit[aria-busy="true"]{cursor:progress}
.btn-submit[aria-busy="true"] .bead{animation:bead-busy 1s ease-in-out infinite}
.btn-submit[aria-busy="true"] .btn-t{opacity:.72}
@keyframes bead-busy{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(.55);opacity:.55}}
.fine{color:var(--mute-text);font-size:13px;line-height:1.45}
/* a phone: the pane keeps its height once it is under a thumb. The error
   takes the fine print's place (one cell for both, the note held open under
   it and out of sight until the next try) ... */
@supports selector(:has(*)){
  @media (max-width:640px){
    .form-foot{display:grid;grid-template-columns:minmax(0,1fr)}
    .form-foot #f-err,.form-foot .fine{grid-area:2/1}
    .form-foot #f-err{font-size:14px;line-height:1.35;text-wrap:balance}
    .form-foot:has(#f-err:not(:empty)) .fine{visibility:hidden}
  }
}

.beta-done{align-self:center;display:grid;justify-items:start;gap:0;opacity:0;transform:translateY(10px);
  transition:opacity .6s var(--ease) .15s,transform .6s var(--ease) .15s}
.beta-done[hidden]{display:none}
.beta-done:focus{outline:none}
.done-mark{display:grid;place-items:center;width:52px;height:52px;border-radius:50%;background:var(--ember);
  box-shadow:0 16px 30px -12px rgba(227,47,76,.55),0 0 0 6px rgba(255,100,20,.08)}
.done-h{margin-top:22px;font-family:var(--hf);font-weight:var(--hwt);font-size:clamp(28px,2.6vw,36px);letter-spacing:-.035em;line-height:1.08}
.done-p{margin-top:10px;color:var(--soft);font-size:18px;overflow-wrap:anywhere}
.done-p strong{color:var(--ink);font-weight:700}
.beta-slot.is-done .beta-form{opacity:0;transform:translateY(-8px);pointer-events:none;visibility:hidden;
  transition:opacity .45s var(--ease),transform .45s var(--ease),visibility 0s linear .45s}
.beta-slot.is-done .beta-done{opacity:1;transform:none}
/* ... and the thanks stand in the middle of the room the form took: the form
   stays, unseen, as the slot's height (landing.js would settle the pane to
   the note's, 250px shorter, and the page would jump with it) */
@media (max-width:640px){
  .beta-slot.is-done{height:auto!important}
  .beta-slot.is-done .beta-form[hidden]{display:grid}
}

/* ── footer ───────────────────────────────────────────────────────────── */
.foot{border-top:1px solid var(--hairs)}
.foot-in{display:flex;flex-wrap:wrap;align-items:center;gap:10px 28px;padding-block:28px 34px;color:var(--mute-text);font-size:14px}
.foot-mark{margin-right:auto}
/* the link is the mark's width, and 44 px tall to the touch without moving anything */
.foot-brand{display:block;width:max-content;padding-block:13px;margin-block:-13px;border-radius:4px}
.foot-brand img{height:22.8px;width:auto}
@media (max-width:640px){ .foot-in{padding-bottom:56px} } /* a phone: the last line stands clear of the home indicator */

/* ── widths ───────────────────────────────────────────────────────────── */
@media (max-width:374px){.top .brand img{height:28px}} /* the narrowest phones: the mark gives way before the button does */
@media (max-width:349px){.top .brand img{height:24px}.top .top-in{gap:10px}.top .btn-top{padding:0 12px;gap:7px}} /* and once more, so 24 px of air stays between them at 320 */
/* a phone's header to the touch: the button 44 px tall up to the phone's own boundary, the mark's link too, without moving anything */
@media (max-width:699px){.top .btn-top{min-height:44px}.top .brand{padding-block:10px;margin-block:-10px}.top .brand .mark-dusk{top:10px}}
@media (max-width:640px){
  :root{--top-h:62px}
  .brand img{height:32.9px}
  .btn-top{min-height:44px;padding:0 15px;font-size:14.5px}
  /* the film takes a little more of the width than the text does, and still floats */
  .film-sec .wrap{width:calc(100% - 20px)}
  /* a phone's frame is a couple of hundred pixels tall: a small sound chip bottom left,
     play/pause a size smaller bottom right, and the progress line */
  .film-ui .film-cue{left:10px;bottom:12px;height:28px;padding:0 11px 0 7px;gap:5px;font-size:12.5px;--cue-d:28px}
  .film-ui .film-cue.is-chip{padding:0 7px}
  .film-cue svg{width:14px;height:14px}
  .film-cue::after{inset:-8px}
  .film-pp{right:10px;bottom:11px;width:30px;height:30px}
  .film-pp svg{width:11px;height:11px}
  .film-pp::after{inset:-7px}
  /* the browser would not start it (Low Power Mode): the play disc a size for this frame,
     under the poster's wordmark, not on it; the whole film takes the press anyway */
  .film-big{top:78%;width:clamp(40px,11.3vw,52px);box-shadow:0 0 0 5px rgba(255,255,255,.55),0 14px 28px -12px rgba(227,47,76,.6),0 6px 14px -8px rgba(255,100,20,.5)}
  .film-big svg{width:18px;height:18px;margin-left:3px}
  .film-big::after{content:"";position:absolute;inset:-8px;border-radius:50%}
  .form-foot{align-items:stretch}
  .beta-card{border-radius:20px}
  .foot-mark{flex-basis:100%}
}
/* a phone on its side: a shorter header, the words left and the drops right
   in their compact form, so the film peeks in on landing, and a film no
   taller than the room under the header, so it can be seen whole */
@media (orientation:landscape) and (max-height:520px){
  :root{--top-h:52px}
  .brand img{height:32.9px}
  .hero-copy{max-width:58%}
  :root{--h1:clamp(24px,7.4vh,36px)}
  .lede{margin-top:10px;font-size:15.5px;max-width:34em}
  h2,.feat-problem h2{font-size:clamp(24px,6.6vh,28px)}
  .film{width:min(100%,calc((100svh - var(--top-h) - 24px) * 16 / 9));margin-inline:auto}
}
/* (a phone, not a short window with a mouse) the play disc of a film the browser would not start: clear of the poster's wordmark */
@media (orientation:landscape) and (max-height:520px) and (hover:none){ .film-big{top:76%} }
/* forced colours with a dark theme: the ink mark keeps a paper plate */
@media (forced-colors:active){
  .brand,.foot-brand{forced-color-adjust:none;background:#FCFAF7;padding:4px 8px;border-radius:8px}
}

/* ── reduced motion: final states, no loops, no parallax ──────────────── */
@media (prefers-reduced-motion:reduce){
  .hi,.film,.form-err,.btn-submit[aria-busy="true"] .bead,.film-cue::before{animation:none!important}
  .film-cue{translate:none!important}
  .film-poster{transition:none}
  .rv [data-rv]{opacity:1;transform:none;transition:none}
  .film{transform:none}
  .btn:hover,.fbtn:hover{transform:none}
  .beta-done,.beta-form{transform:none!important}
}

/* ── dusk: the page turns to the brand brown from the rehearsal down ──── */
/* spine.js sets html.is-dusk a little after the crossing above the rehearsal
   (landing.js, where there is no spine); the white panes then float on the
   product's own shell colour. Plain colour transitions only. */
:root{--dusk:#3A322C;--dusk-line:rgba(252,250,247,.14);--dusk-text:#C3B6AA;--dusk-plate:#453C35;--page-bg:var(--cream)}
html.is-dusk{--page-bg:var(--dusk)}
html,body{transition:background-color .9s var(--ease)}
.brand,.foot-brand{position:relative}
.mark-dusk{position:absolute;left:0;top:0;opacity:0;transition:opacity .9s var(--ease)}
.foot-brand .mark-dusk{top:13px}
.brand img:first-child,.foot-brand img:first-child{transition:opacity .9s var(--ease)}
.foot,.foot-in{transition:color .9s var(--ease),border-color .9s var(--ease)}
.top{transition:background-color .9s var(--ease),box-shadow .9s var(--ease)}
.btn-top{transition:background-color .9s var(--ease),color .9s var(--ease),transform .2s var(--ease),box-shadow .2s var(--ease)}
html.is-dusk,html.is-dusk body{background:var(--dusk)}
html.is-dusk .top.is-stuck{background:var(--dusk);box-shadow:0 1px 0 var(--dusk-line)}
html.is-dusk .mark-dusk{opacity:1}
html.is-dusk .brand img:first-child,html.is-dusk .foot-brand img:first-child{opacity:0}
html.is-dusk .btn-top{background:var(--cream);color:var(--ink)}
html.is-dusk .foot{border-top-color:var(--dusk-line)}
html.is-dusk .foot-in{color:var(--dusk-text)}
/* the words on the page go light with it (the ones in the panes and the beta card do not) */
.feat h2,.feat .body,.stack h2,.stack .body,.sk-label,.sk-tag,.sk-next{transition:color .9s var(--ease),border-color .9s var(--ease),box-shadow .9s var(--ease)}
.rv .feat [data-rv],.rv .stack [data-rv]{transition:opacity .7s var(--ease) var(--d,0s),transform .7s var(--ease) var(--d,0s),color .9s var(--ease)}
.rv .stack .sk-group[data-rv]{transform:none} /* the plates fade in where they stand, inside their forks */
html.is-dusk .feat h2,html.is-dusk .stack h2{color:var(--cream)}
html.is-dusk .feat .body,html.is-dusk .stack .body,html.is-dusk .sk-label{color:var(--dusk-text)}
/* the logos: cream on a plate a shade lighter than the page */
html.is-dusk .sk-bead{background:var(--dusk-plate);box-shadow:0 0 0 1px rgba(252,250,247,.07);color:var(--cream)}
html.is-dusk .sk-next{background:transparent;box-shadow:none;border-color:rgba(252,250,247,.3)}
html.is-dusk .sk-tag{color:var(--dusk-text);box-shadow:inset 0 0 0 1px rgba(252,250,247,.24)}
@media (prefers-reduced-motion:reduce){
  html,body,.top,.btn-top,.mark-dusk,.brand img,.foot-brand img,.foot,.foot-in,
  .feat h2,.feat .body,.stack h2,.stack .body,.sk-label,.sk-tag,.sk-next,.sk-bead,.rv .feat [data-rv],.rv .stack [data-rv]{transition:none}
  .fc-b{transition:opacity .12s linear;transform:none}
}
/* the panes' coloured glows read as smudges on brown, so they bow out */
.art [class$="-glow"]{transition:opacity .9s var(--ease)}
html.is-dusk .art [class$="-glow"]{opacity:0!important}

/* ── the spine: the app's play bar, down the page (spine.js) ──────────── */
/* coaching/shell.html's `.dks` at page scale: a rail in the hairline tone,
   the ink fill, the ink playhead, and each scored moment a stalk and a dot in
   its area's hue. Rail and ink are one weight all the way down, --sp-w (7px;
   6px on a phone), which spine.js sets with the rest of its sizes; only where
   it forks round a logo's plate are the two strands lighter (4px, 3px on a
   phone), thinning from the thread's weight as they leave it and back as
   they close, a weight spine.js puts on each of those pieces. The rail
   is under the sections, so every pane and every logo plate in the stack
   covers it; the discs the panes unfold out of are over them. */
/* No box here is the page's height, and nothing here is a layer of its own
   at rest: both layers are boxes of no height; the rail and the ink are
   short paths in small svgs, a patch of the page each (spine.js); the
   playhead is moved, not promoted; a moment or a disc animates inside its
   own small box (contain: paint), so its animation never makes what lies
   over it on the page into layers. */
.spine,.spine-top{position:absolute;left:0;top:0;width:100%;height:0;pointer-events:none}
.spine{z-index:0}
.spine-top{z-index:3}
.sp-bands svg{position:absolute;overflow:visible}
.sp-src{position:absolute;left:0;top:0;overflow:hidden;visibility:hidden}
/* a mark fx/beads.js is still bringing in from the background (CONTRACTS.md):
   unseen, and what it would play there plays to its end at once, so taking
   the class off shows it in place, whole and at rest (its ring is spine.js's
   to play, as the playhead plays it, and is not played for a held mark) */
.sp-await{opacity:0!important;transition:none!important}
.sp-await *{transition:none!important;animation:none!important}
.sp-rail,.sp-fill{fill:none;stroke-width:var(--sp-w,7px);stroke-linecap:round;stroke-linejoin:round}
.sp-rail{stroke:#E4DCD3;transition:stroke .9s var(--ease)}
/* the ink is in short pieces that hand on to each other: none fades, but the
   thread's first, which shows with the playhead */
.sp-fill{stroke:var(--ink);transition:stroke .9s var(--ease)}
.sp-head{transition:stroke .9s var(--ease),opacity .2s linear}
/* as the page turns to dusk and back, only the patches near the screen fade; the rest change unseen (spine.js) */
.sp-far :is(.sp-rail,.sp-fill){transition:none}
.sp-far .sp-head{transition:opacity .2s linear}
.sp-pin{position:absolute;left:0;top:0;width:var(--pin,14px);height:var(--pin,14px);margin:calc(var(--pin,14px) / -2) 0 0 calc(var(--pin,14px) / -2);
  border-radius:50%;background:var(--ink);opacity:0;transition:background-color .9s var(--ease),opacity .2s linear}
.sp-pin::after{content:"";position:absolute;inset:0;border-radius:50%;box-shadow:0 0 0 0 currentColor;color:var(--ink);opacity:0}
.spine.is-done .sp-pin::after{animation:sp-arrive 1s cubic-bezier(.33,1,.68,1) .05s backwards} /* it ends where it rests: nothing left filling (and composited) once it is done */
/* where the logos' drops part, the playhead goes into the strands, and it
   forms again where they have closed (spine.js): --pin-k is how much of it
   shows, from where the playhead is, so nothing here eases it. It goes
   over the inline opacity, which stays whether the playhead is out. */
.sp-pin.sp-part{opacity:var(--pin-k,1)!important;transition:background-color .9s var(--ease)}
@keyframes sp-arrive{from{opacity:.5;box-shadow:0 0 0 0 currentColor}to{opacity:0;box-shadow:0 0 0 18px currentColor}}

/* a scored moment: the stalk grows out of the rail and the dot rides it out.
   Its box is centred on its point on the rail (left/top; fx/beads.js reads
   it there) and holds the stalk, the dot and the ring's last ping either
   way (--R round the ends); .sp-o is that point inside it, --ox/--oy in from
   the box's corner, which spine.js puts on whole pixels (a contained box is
   painted from a whole pixel: the stalk and the dot keep the fraction of a
   pixel they stand at). Whatever plays in it stays in it (contain: paint),
   so a moment growing never makes the sections over it into layers. */
.sp-mk{position:absolute;width:calc(var(--R) * 2 + 1px);height:calc((var(--len) + var(--R)) * 2 + 1px);
  margin:calc(var(--oy) * -1) 0 0 calc(var(--ox) * -1);contain:paint;color:var(--c)}
.sp-o{position:absolute;left:var(--ox);top:var(--oy);width:0;height:0}
.sp-st{position:absolute;left:-.75px;width:1.5px;height:var(--len);background:currentColor;opacity:.5;transform:scaleY(0);
  transition:transform .3s cubic-bezier(.5,0,.75,0)}
.sp-mk[data-side=up] .sp-st{bottom:0;transform-origin:50% 100%}
.sp-mk[data-side=down] .sp-st{top:0;transform-origin:50% 0}
.sp-mk[data-side=up]{--ty:calc(var(--len) * -1)}
.sp-mk[data-side=down]{--ty:var(--len)}
.sp-mv{position:absolute;left:0;top:0;transition:transform .3s cubic-bezier(.5,0,.75,0)}
.sp-dt,.sp-mk .sp-rg{position:absolute;left:calc(var(--d) / -2);top:calc(var(--d) / -2);width:var(--d);height:var(--d);border-radius:50%}
.sp-dt{background:currentColor;transform:scale(0);transition:transform .24s cubic-bezier(.5,0,.75,0)}
.sp-rg{box-shadow:0 0 0 1.2px currentColor;opacity:0}
.sp-mk.on .sp-st{transform:scaleY(1);transition:transform .46s cubic-bezier(.33,1,.68,1)}
.sp-mk.on .sp-mv{transform:translateY(var(--ty));transition:transform .46s cubic-bezier(.33,1,.68,1)}
.sp-mk.on .sp-dt{transform:scale(1);transition:transform .34s cubic-bezier(.33,1,.68,1)}
/* the ring pings once as the dot comes out (spine.js plays it, .42 to 0 as it
   grows to 3.2 times, .7s): it ends invisible, as it rests, with no fill to
   keep a layer for */

/* the disc a pane unfolds out of: the area's disc with its mark, the way the
   app opens a moment; once the pane is out it settles to a knot on its edge */
/* its box (--B, left/top its centre, --ox/--oy as a moment's) holds the disc and its ring's last ping */
.sp-fd{position:absolute;width:calc(var(--B) + 1px);height:calc(var(--B) + 1px);margin:calc(var(--oy) * -1) 0 0 calc(var(--ox) * -1);contain:paint;color:var(--c)}
.sp-fdd{position:absolute;left:calc(var(--ox) - var(--D) / 2);top:calc(var(--oy) - var(--D) / 2);width:var(--D);height:var(--D);border-radius:50%;
  display:grid;place-items:center;background:currentColor;box-shadow:0 1px 3px rgba(36,30,26,.22);transform:scale(0);
  transition:transform .3s cubic-bezier(.5,0,.75,0)}
.sp-fdd svg{width:58%;height:58%;opacity:0;transition:opacity .12s}
.sp-fd .sp-rg{position:absolute;left:calc(var(--ox) - var(--D) / 2);top:calc(var(--oy) - var(--D) / 2);width:var(--D);height:var(--D);border-radius:50%}
.sp-fd.is-open .sp-fdd{transform:scale(1);transition:transform .42s cubic-bezier(.2,.9,.3,1.25)}
.sp-fd.is-open .sp-fdd svg{opacity:1;transition:opacity .14s .05s}
.sp-fd.is-knot .sp-fdd{transform:scale(var(--k));transition:transform .55s var(--ease)}

/* HubSpot, not on the string yet: it hangs off the last row on a stalk drawn
   in its ring's dashes, grown as the playhead passes over it like a moment's */
.sp-hang .sp-st{opacity:1;background:repeating-linear-gradient(to bottom,var(--hair) 0 4px,transparent 4px 8px)}
html.is-dusk .sp-hang .sp-st{background:repeating-linear-gradient(to bottom,rgba(252,250,247,.3) 0 4px,transparent 4px 8px)}

/* the pane, folded into its disc until the playhead reaches it */
.art{transform-origin:var(--ox,50%) var(--oy,0);
  transition:transform .82s cubic-bezier(.2,.8,.2,1),opacity .3s linear,visibility 0s}
.art.sp-fold{transform:scale(var(--s0,.05));opacity:0;visibility:hidden;
  transition:transform .5s cubic-bezier(.5,0,.75,0),opacity .22s linear .26s,visibility 0s linear .5s}
.art.sp-instant,.sp-instant .sp-mk *,.sp-instant .sp-fdd,.sp-instant .sp-fdd svg,.sp-instant .sp-rg,.sp-instant.sp-rail,.sp-instant .sp-pin{transition:none!important;animation:none!important}
.spine.sp-instant .sp-mk *,.spine-top.sp-instant *{transition:none!important;animation:none!important}

/* stacked, the rail passes the words in the right-hand gutter: keep the copy's
   ragged edge off it (the headings already stop short of it) */
@media (max-width:1023.98px){html[data-spine] .feat .body{padding-right:18px}}
/* a phone: from the first layout, not from when the spine has loaded (a paragraph took a line more as it came, and the page under it moved) */
@media (max-width:699px){html.js .feat .body,html.js .feat-problem h2,html.js .stack-head h2,html.js .stack-head .body,html.js .rh-head{padding-right:18px}}
/* side by side, it comes down between the rehearsal's title and copy, and between the stack's: give it the column */
@media (min-width:1024px) and (max-width:1279px){html[data-spine] .feat-copy,html[data-spine] .stack-head .body{grid-column:8/span 5}}
/* on the brown from the rehearsal down, through the stack's rows: the app's
   rail on its dark chrome, a shade lighter than the page and the logos'
   plates, so the thread reads between the logos and stops at their edges */
/* the rail ("1") forks round each of the stack's plates, a strand over it
   and one under: the plates stand far enough apart for the two strands to
   close back into one rail between them, and on a tablet far enough in for
   the turns */
html[data-spine=on][data-stack="1"] .stack{--sk-gap:52px}
html[data-spine=on][data-stack="1"] .sk-next{translate:var(--sk-nx,0px) 0} /* along under the last row, to hang off open rail (spine.js) */
@media (min-width:700px) and (max-width:1023.98px){ html[data-spine=on][data-stack="1"] .stack{--sk-end:max(64px,var(--gut))} }
@media (max-width:699px){
  html[data-spine=on][data-stack="1"] .stack{--sk-gap:44px;--sk-row-gap:42px} /* two rows' strands and the turn between them */
}
.spine.sp-instant .sp-fill{transition:none}

/* opaque, the 16% cream over the brown: where a fork's strands meet on the
   rail they would otherwise stack into bright knots */
html.is-dusk .sp-rail{stroke:#59524C}
html.is-dusk .sp-fill{stroke:var(--cream)}
html.is-dusk .sp-pin{background:var(--cream)}
html.is-dusk .sp-pin::after{color:var(--cream)}

@media (prefers-reduced-motion:reduce){
  .art,.art.sp-fold{transition:none}
  .sp-mk *,.sp-fdd,.sp-fdd svg,.sp-rg{transition:none!important;animation:none!important}
}
@media print{.spine,.spine-top,.film-cursor{display:none}}

/* ── V3: the header over a dark hero ──────────────────────────────────── */
/* landing.js sets html[data-head=dark] while what is under the header is the
   brown or the orb's colour: the cream mark and a cream button, as at dusk */
html[data-head=dark] .mark-dusk{opacity:1}
html[data-head=dark] .brand img:first-child{opacity:0}
html[data-head=dark] .btn-top{background:var(--cream);color:var(--ink)}
html[data-head=dark] .top.is-stuck{background:var(--dusk);box-shadow:0 1px 0 var(--dusk-line)}

/* ── V3: Rehearse it ──────────────────────────────────────────────────── */
/* The title over the line: wide, its two halves either side of it, the
   first set against it; stacked, one column. The line (the spine) comes
   down the middle, so the gutter between the halves is the rail's lane. */
.feat-head.rh-head{display:block}
.rh-title .ember{padding-bottom:.06em}
/* a phone: each of its two sentences starts a line of its own, however
   narrow; where the second needs two, the last word drops, not the first */
@media (max-width:599px){ .rh-a,.rh-b{display:block} .rh-b{text-wrap:wrap} }
@media (min-width:1024px){
  .rh-title{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:clamp(72px,8vw,120px);align-items:end}
  .rh-a{text-align:right}
  /* the words the orbs cross as they come in to land in the rehearsal, and
     as they take off again (the matrix's, beside its grid, and this title),
     over fx/journey.js's layer (z-index 2, after main): the orbs pass under
     them, so a reader who stops while they cross still reads every word.
     The spine's top, later in main at the same z-index, stays over them */
  .feat-matrix .feat-text,.rh-title{position:relative;z-index:3}
}
/* the client's words and the coach's, under their drops */
.rh-cast{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:clamp(36px,8vw,120px);margin-top:clamp(8px,1.6vw,22px)}
.rh-who{justify-self:center;max-width:21em;text-align:center}
.rh-who h3{margin:0;font-family:var(--hf);font-weight:var(--hwt);font-size:calc(clamp(20px,1.9vw,27px) * var(--fk));
  letter-spacing:calc(-.03em + var(--tk));line-height:1.1;transition:color .9s var(--ease)}
.rh-who p{margin:10px 0 0;color:var(--soft);font-size:clamp(15.5px,1.25vw,18.5px);line-height:1.5;text-wrap:pretty;transition:color .9s var(--ease)}
html.is-dusk .rh-who h3{color:var(--cream)}
html.is-dusk .rh-who p{color:var(--dusk-text)}
@media (max-width:599px){ .rh-who p{font-size:15px} .rh-who h3{font-size:calc(19px * var(--fk))} }
/* a phone: the line runs down between the two, 18px clear either side of it;
   each column's few words a line are set to an even edge */
@media (max-width:599px){ .rh-cast{column-gap:42px} .rh-who p{text-wrap:balance} }
/* One view (Dawid, 2026-10-03): with the title up under the header, the
   drops, the Try between them and the words under them are all on the
   screen (art/rehearsal.js stands the drops beside the conversation for
   it). So the gaps over and under the graphic give way on a short screen
   (14px and 10px at 720 high) and open up again on a tall one; and the
   words' two columns are halves, so each is centred under its drop, a
   quarter and three quarters across (the line keeps its lane: the words
   stop short of it). A wide screen that is not tall gives them up sooner:
   --rh-spare is what the screen has left under the header once the title,
   the graphic and the words are in (30vw + 218px, measured 1024 to 1920
   wide, and 16px more from where the words grow a step, 1290 to 1440; the
   column stops growing at 1760) and 12px stand over and under them, and
   the two gaps share it. */
@media (min-width:1024px){
  .feat-rehearsal{--rh-spare:calc(100vh - var(--top-h) - 242px - min(30vw,593px) - clamp(0px,10.7vw - 138px,16px))}
  .feat-rehearsal .feat-art-wide{margin-top:min(clamp(40px,6vw,76px),max(14px,26vh - 174px),max(14px,var(--rh-spare) * .7))}
  .feat-rehearsal .rh-cast{margin-top:min(clamp(10px,8vh - 48px,36px),max(10px,var(--rh-spare) * .3));column-gap:0}
  .feat-rehearsal .rh-who{max-width:min(21em,100% - 64px)}
}
/* The hold (Dawid, 2026-10-03: "I can very easily scroll past this section
   ... let a few scrolls pass by without moving the screen. Just let the
   timeline flow"). As the hero's: a runway under a sticky stage. Once the
   title is up under the header, with all of it in the one view, the stage
   stands still for --pin of scroll (about six notches of a wheel) while
   the line's playhead runs on down through it (spine.js); then the page
   moves on, and the next section follows straight after: the runway is
   spent under the stage, so it never shows as a blank stretch. Only where
   the section is laid out for one view and its graphic is there, and not
   under reduced motion (below 1024 it is stacked or its gaps are not
   fitted to the screen, and the orbs do not land in it).
   On a screen too short for all of it (landing.js: --rh-h is the stage's
   height, --rh-a how far down it the graphic ends) the stage stands with
   its title 4px under the header and the words under the drops run off
   the screen's foot until it lets go; and where not even the graphic is
   in view under the title there is no runway, so no hold: the page scrolls
   on as it always did. One that fits with less than its gap over it stands
   with its foot 12px clear of the screen's. Sticky, it is a stacking
   context: 3, as the title in it was, so the orbs coming in to land
   (fx/journey.js's layer, 2) still pass under the words. */
@media (min-width:1024px) and (prefers-reduced-motion:no-preference){
  html.js .feat-rehearsal:not(:has(.feat-art.is-failed)){--pin:600px}
  html.js .feat-rehearsal:not(:has(.feat-art.is-failed))::after{content:"";display:block;
    height:clamp(0px,(100vh - var(--top-h) - var(--rh-a,0px) - 16px) * 999,var(--pin))}
  html.js .feat-rehearsal:not(:has(.feat-art.is-failed)) .rh-stage{position:sticky;z-index:3;
    top:max(calc(var(--top-h) + 4px),min(calc(var(--top-h) + clamp(12px,4vh - 12px,36px)),calc(100vh - var(--rh-h,0px) - 12px)))}
}
/* stacked, the rail passes the title in the right-hand gutter */
@media (max-width:1023.98px){ html[data-spine] .rh-head{padding-right:18px} }
/* held (art/rehearsal.js, while fx/journey.js has the orbs): the pane's
   reveals never scale or slide it; the stage round the drops fades in place
   and the drops are journey's to show, exactly where they will stay. The
   fades are not the hold's: held ends in the same task as the unfold or the
   reveal that releases it, so the stage carries on fading in, never pops */
.feat-rehearsal .art.ar-held,.feat-rehearsal .art.ar-held.sp-fold{transform:none;opacity:1;visibility:visible}
.rv .feat-rehearsal .feat-art.ar-held[data-rv]{opacity:1;transform:none}
.feat-rehearsal .ar .ar-back{transition:opacity .45s var(--ease),visibility 0s}
.feat-rehearsal .rh-cast{transition:opacity .7s var(--ease) .1s,visibility 0s}
.feat-rehearsal .art.ar-held.sp-fold .ar-back{opacity:0;visibility:hidden;transition:opacity .3s linear,visibility 0s linear .3s}
.rv .feat-rehearsal .feat-art.ar-held:not(.in) :is(.ar-back,.rh-cast){opacity:0}
.feat-rehearsal .art.ar.sp-instant .ar-back{transition:none}
@media (prefers-reduced-motion:reduce){ .feat-rehearsal :is(.ar-back,.rh-cast){transition:none!important} }

/* ── V3: the trust row, under the form ────────────────────────────────── */
.trust{list-style:none;margin:clamp(22px,3vw,34px) 0 0;padding:0;display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:14px clamp(20px,3vw,40px);color:var(--soft);font-size:14.5px;font-weight:600;letter-spacing:-.005em;transition:color .9s var(--ease)}
.trust li{display:flex;align-items:center;gap:9px;white-space:nowrap}
.trust svg{flex:none}
.trust-seal{color:var(--ink);font-weight:700;transition:color .9s var(--ease)}
.trust-eu{border-radius:50%;box-shadow:0 0 0 2px rgba(255,204,0,.22)}
html.is-dusk .trust{color:var(--dusk-text)}
html.is-dusk .trust-seal{color:var(--cream)}
/* a phone: the four one under another on one left edge, never a wrap with an
   odd one out; the line icons a size up, each in the seal's width, so the
   words start on one line down the list */
@media (max-width:599px){
  .trust{flex-direction:column;align-items:flex-start;gap:8px;font-size:15px}
  .trust li{min-height:30px;gap:11px}
  .trust li>svg:not(.trust-eu){width:20px;height:20px;margin-inline:5px}
}

/* reduced motion: the orbs hold their first pose, so the hero does not hold
   the page for a movement that will not play */
@media (prefers-reduced-motion:reduce){ .hero{--pin:0px} }

/* c17/copy mockup: the good in the coach orb's own ramp, finely grained (a PNG tile, no filter); no blue in headlines */
:root{--ember:linear-gradient(125deg,#e32f4c 0%,#ff6414 50%,#ffc04a 100%);--grain:url(art/grain.png)}
.ember{background:var(--grain) 0 0/128px 128px,var(--ember);-webkit-background-clip:text;background-clip:text}
.who-cool{background:var(--grain) 0 0/128px 128px,linear-gradient(125deg,#3e8e9c 0%,#6fa9b5 50%,#9cbcc6 100%);-webkit-background-clip:text;background-clip:text;color:transparent}
.h-arrow{font-weight:500;letter-spacing:0}
@media (min-width:1024px){ .rh-br{display:block} .rh-b{text-align:left} }
.rh-who{max-width:26em}
.rh-who h3{font-size:calc(clamp(28px,3vw,48px) * var(--fk))!important}
.rh-who .rh-line{margin-top:14px;font-family:var(--hf);font-weight:var(--hwt);font-size:calc(clamp(19px,1.9vw,29px) * var(--fk));line-height:1.15;letter-spacing:-.02em;color:var(--ink);text-wrap:balance}
html.is-dusk .rh-who .rh-line{color:var(--cream)}
@media (max-width:599px){ .rh-who h3{font-size:calc(24px * var(--fk))!important} .rh-who .rh-line{font-size:calc(17px * var(--fk))} }
/* c17/copy: every section's line at the problem's size */
.feat .body,.stack-head .body{font-size:clamp(18px,1.6vw,22.5px);line-height:1.55;max-width:30em}
@media (min-width:1280px){ html[data-wide="1"] .feat .body,html[data-wide="1"] .stack-head .body{font-size:clamp(18px,min(1.6vw,max(22.5px,18px + .3125vw)),25px)} }
/* c17/copy: the lines grow with the screen (his laptop window is about 1713 wide) */
@media (min-width:1024px){
  .lede{font-size:clamp(20px,min(1.9vw,3.6vh),36px)!important;line-height:1.42;max-width:26em}
}
h1 .h1-b{display:block}
