:root{
  --bg:#0B0B0C;
  --panel:#141415;
  --cream:#F1F0EC;
  --dim:#8E8B84;
  --faint:#54524C;
  --accent:#F2A33C;
  --amber:#F2A33C;
  --sans:'General Sans',sans-serif;
  --mono:'IBM Plex Mono',monospace;
}
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%}
body{background:var(--bg);color:var(--cream);font-family:var(--sans);font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased;overflow-x:hidden}
::selection{background:var(--accent);color:#171106}
#spacer{height:1710vh;position:relative;z-index:0} /* ~107vh per beat × 16 beats */

/* ---------- cover-grid plate ----------
   The desktop vault, sunk right back. Two scrims over it: a flat wash to kill
   contrast so copy stays legible, and a vignette so the centre never competes
   with the record. Drops further back once we reach the apartment. */
.covergrid{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.covergrid::before{content:"";position:absolute;inset:0;
  background:url('assets/bg_covergrid.jpg') center/cover no-repeat;
  opacity:.22;filter:saturate(.45) brightness(.6) blur(2.5px);
  transition:opacity 1.4s ease}
/* copy lives at the left and right edges, so the scrim is heaviest there —
   a centre-only vignette would leave the grid brightest exactly under the text */
.covergrid::after{content:"";position:absolute;inset:0;
  background:
    linear-gradient(90deg, rgba(11,11,12,.97) 0%, rgba(11,11,12,.9) 30%, rgba(11,11,12,.62) 50%, rgba(11,11,12,.9) 70%, rgba(11,11,12,.97) 100%),
    linear-gradient(180deg, rgba(11,11,12,.85), rgba(11,11,12,.55) 45%, rgba(11,11,12,.9))}
/* the copy columns get their own wash — the plate was still showing through
   behind the type at the left and right edges, where every beat puts its copy */
@media(max-width:720px){
  .covergrid::after{background:linear-gradient(180deg, rgba(11,11,12,.92), rgba(11,11,12,.78) 45%, rgba(11,11,12,.94))}
  .covergrid::before{opacity:.14}
}
body[data-beat="10"] .covergrid::before,body[data-beat="11"] .covergrid::before,
body[data-beat="12"] .covergrid::before,body[data-beat="13"] .covergrid::before,
body[data-beat="14"] .covergrid::before{opacity:.05}
@media (prefers-reduced-motion: reduce){.covergrid::before{transition:none}}

/* ---------- warm glow field + apartment mood ---------- */
.glowfield{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.glowfield::after{ /* concentric groove texture, echoing the app background */
  content:"";position:absolute;inset:-20%;
  background:repeating-radial-gradient(circle at 74% 16%, rgba(240,240,238,.022) 0 1px, transparent 1px 30px);
}
.glow{position:absolute;border-radius:50%;filter:blur(90px);opacity:0;transition:opacity 1.4s ease}
.glow.a{width:70vmax;height:70vmax;left:-25vmax;bottom:-30vmax;background:radial-gradient(circle,#403112,transparent 65%)}
.glow.b{width:60vmax;height:60vmax;right:-20vmax;top:-25vmax;background:radial-gradient(circle,#232323,transparent 65%)}
.glow.c{width:50vmax;height:50vmax;left:20vw;top:55vh;background:radial-gradient(circle,#1B1B1C,transparent 60%)}
body[data-beat="2"] .glow.a,body[data-beat="3"] .glow.a{opacity:.9}
body[data-beat="1"] .glow.b,body[data-beat="2"] .glow.b,body[data-beat="5"] .glow.b{opacity:.6}
body[data-beat="0"] .glow.c,body[data-beat="4"] .glow.a,body[data-beat="6"] .glow.c{opacity:.55}

/* window light + plants appear for the apartment beats (8-10) */
.windowlight{position:absolute;right:-10vw;top:-14vh;width:70vw;height:80vh;opacity:0;transition:opacity 1.6s ease;
  background:radial-gradient(ellipse at 70% 20%,rgba(255,244,224,.10),rgba(255,238,214,.03) 45%,transparent 70%)}
.plant{position:absolute;opacity:0;transition:opacity 1.6s ease;filter:blur(5px) brightness(.5) saturate(.7)}
.plant svg{display:block}
.plant.p1{left:-60px;bottom:-40px;width:min(38vw,420px)}
.plant.p2{right:-70px;bottom:-30px;width:min(30vw,340px);transform:scaleX(-1) rotate(6deg)}
.plant.p3{right:8vw;top:-60px;width:min(22vw,240px);transform:rotate(168deg);filter:blur(7px) brightness(.4)}
body[data-beat="10"] .windowlight,body[data-beat="11"] .windowlight,body[data-beat="12"] .windowlight,body[data-beat="13"] .windowlight,body[data-beat="14"] .windowlight{opacity:1}
body[data-beat="12"] .plant.p1,body[data-beat="12"] .plant.p2,body[data-beat="12"] .plant.p3,
body[data-beat="14"] .plant.p1,body[data-beat="14"] .plant.p2{opacity:1}
body[data-beat="9"] .plant.p2{opacity:.7}

/* ---------- fixed stage ---------- */
#stage{position:fixed;inset:0;width:100%;height:100%;display:block;z-index:1;pointer-events:none}

/* ---------- chrome ---------- */
.chrome{position:fixed;z-index:30}
.wordmark{top:22px;left:clamp(22px,3.5vw,44px);font-weight:700;font-size:21px;letter-spacing:.045em;text-transform:uppercase;color:var(--cream);text-decoration:none;
  display:flex;align-items:center;gap:11px}
/* the mark is amber-on-charcoal with its own black field — blend it into the
   page so it reads as a logo, not a pasted tile */
.wordmark .mark{width:34px;height:34px;object-fit:contain;mix-blend-mode:screen;flex:none}
@media(max-width:720px){.wordmark .mark{width:28px;height:28px}.wordmark{font-size:18px;gap:9px}}
nav.chrome{top:30px;right:clamp(22px,3.5vw,44px);display:flex;gap:26px}
nav.chrome a{font-size:10.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);text-decoration:none;transition:color .25s}
nav.chrome a:hover,nav.chrome a:focus-visible{color:var(--cream)}
nav.chrome a.active{color:var(--cream);border-bottom:1px dotted var(--dim);padding-bottom:3px}
/* log in only — there is no web signup, accounts are created in the app */
nav.chrome a.login{color:var(--cream);border:1px solid rgba(242,163,60,.45);border-radius:3px;
  padding:7px 14px;margin:-8px 0 0 4px;transition:background .25s,border-color .25s}
nav.chrome a.login:hover,nav.chrome a.login:focus-visible{background:var(--accent);border-color:var(--accent);color:#171106}
@media(max-width:720px){nav.chrome{display:flex}nav.chrome a:not(.login){display:none}
  nav.chrome{top:24px;right:18px;gap:0}}
.side-tab{right:0;top:64px;background:var(--accent);color:#171106;writing-mode:vertical-rl;padding:18px 8px;font-size:10px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;border-radius:3px 0 0 3px}
.scroll-hint{bottom:22px;left:50%;transform:translateX(-50%);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--faint);display:flex;align-items:center;gap:8px;transition:opacity .5s}
.scroll-hint::before{content:"↓";color:var(--dim)}
body:not([data-beat="0"]) .scroll-hint{opacity:0}
@media(max-width:720px){nav.chrome{display:none}}

/* ---------- beats ---------- */
.beat{position:fixed;inset:0;z-index:20;pointer-events:none;opacity:0;visibility:hidden}
.beat.live{visibility:visible}
.beat .can{pointer-events:auto}
.pad{position:absolute;inset:0;padding:clamp(22px,4vw,56px)}
.w{display:inline-block;white-space:pre;
  opacity:clamp(0, calc(var(--t,0)*2.2 - var(--d,0)), 1);
  filter:blur(calc(clamp(0, calc(1 - (var(--t,0)*2.2 - var(--d,0))), 1)*14px));
  transform:translateY(calc(clamp(0, calc(1 - (var(--t,0)*2.2 - var(--d,0))), 1)*14px));
}
.display{font-weight:600;text-transform:uppercase;line-height:1.02;letter-spacing:.005em;color:var(--cream);text-shadow:0 2px 28px rgba(0,0,0,.65),0 1px 3px rgba(0,0,0,.45)}
.display.xl{font-size:clamp(38px,5.8vw,86px)}
.display.lg{font-size:clamp(30px,4.4vw,64px)}
.body-block{font-size:clamp(16px,1.45vw,21px);line-height:1.5;color:var(--dim);font-weight:500;text-shadow:0 1px 14px rgba(0,0,0,.6),0 1px 2px rgba(0,0,0,.4)}
.body-block b{color:var(--cream);font-weight:600}
.label{font-size:10px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--dim)}
.footnote{font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint)}
.asterisk{color:var(--accent)}
.formula{font-weight:500;font-size:clamp(18px,2vw,26px);color:var(--dim)}
.glass{background:rgba(244,240,232,.05);border:1px solid rgba(244,240,232,.08);backdrop-filter:blur(14px);border-radius:6px;padding:26px 26px 30px;max-width:340px}
.glass .label{color:var(--cream);margin-bottom:12px;display:block}
.glass p{font-size:14.5px;color:var(--dim);line-height:1.6}

/* beat layouts */
/* hero: one left column carries the pitch, the vault screen sits right.
   The tagline used to float on the right, which is where the app screen
   now needs to be. */
.b0 .tagline{margin-top:20px;max-width:430px}
.b0 .sell{list-style:none;margin-top:20px;display:flex;flex-direction:column;gap:9px;max-width:460px}
.b0 .sell li{position:relative;padding-left:20px;font-size:clamp(13px,1.05vw,15px);line-height:1.45;
  color:var(--dim);text-shadow:0 1px 10px rgba(0,0,0,.6)}
.b0 .sell li b{color:var(--cream);font-weight:600}
.b0 .sell li::before{content:"";position:absolute;left:0;top:.55em;width:6px;height:6px;
  border-radius:50%;background:var(--accent)}
.b0 .phone{right:clamp(28px,6vw,110px);
  transform:translateY(calc(-50% + (1 - var(--t,0))*30px)) perspective(1200px) rotateY(-10deg) rotateX(2deg)}
.b0 .glass{position:absolute;left:clamp(22px,4vw,56px);bottom:clamp(60px,9vh,100px)}
@media(max-height:820px){.b0 .sell li{font-size:12.5px;gap:7px}.b0 .glass{display:none}}
.b0 .glass .sub{margin-top:16px;padding-top:14px;border-top:1px dotted rgba(244,240,232,.2);font-size:13px;text-align:right;color:var(--dim)}
.b0 .kick{position:absolute;left:clamp(22px,4vw,56px);top:88px;max-width:min(52vw,560px)}
.soon{display:inline-block;margin-left:8px;padding:3px 9px;border-radius:99px;
  background:rgba(242,163,60,.14);border:1px solid rgba(242,163,60,.5);color:var(--accent);
  font-size:9.5px;letter-spacing:.14em;font-weight:600;vertical-align:middle}
.b1 .left{position:absolute;left:clamp(22px,5vw,84px);top:44%;transform:translateY(-50%);max-width:min(52vw,640px);display:flex;flex-direction:column;gap:22px}
.b1 .left .body-block{max-width:340px}
.b1 .foot{position:absolute;right:clamp(22px,5vw,84px);bottom:34px;text-align:right}
.b2 .head{position:absolute;left:50%;top:12%;transform:translateX(-50%);text-align:center;white-space:nowrap}
.b2 .note{position:absolute;left:50%;bottom:12%;transform:translateX(-50%);max-width:420px;text-align:center}
.bf .glass{position:absolute;top:88px}
.fL .glass{left:clamp(22px,4vw,56px)}
.fR .glass{right:clamp(22px,4vw,56px)}
.bf .big{position:absolute;bottom:clamp(40px,7vh,72px)}
.fL .big{left:clamp(22px,4vw,56px);max-width:40vw}
.fR .big{right:clamp(22px,4vw,56px);text-align:right;max-width:40vw}
.bf .anno{position:absolute;bottom:clamp(44px,7vh,76px);display:flex;align-items:baseline;gap:16px}
.fL .anno{right:clamp(22px,4vw,56px)}
.fR .anno{left:clamp(22px,4vw,56px)}
/* iPhone mockup: drop real screenshots at assets/screens/{name}.png */
.phone{
  position:absolute;top:47%;width:clamp(200px,21vw,340px);aspect-ratio:9/19;
  border-radius:38px;border:3px solid #352C1C;background:#0F0C07;overflow:hidden;
  box-shadow:0 40px 80px rgba(0,0,0,.55),inset 0 0 0 2px rgba(244,240,232,.05);
  opacity:var(--t,0);
  filter:blur(calc((1 - var(--t,0))*10px));
}
.fL .phone{right:clamp(30px,6vw,90px);transform:translateY(calc(-50% + (1 - var(--t,0))*30px)) perspective(1200px) rotateY(-9deg) rotateX(2deg)}
.fR .phone{left:clamp(30px,6vw,90px);transform:translateY(calc(-50% + (1 - var(--t,0))*30px)) perspective(1200px) rotateY(9deg) rotateX(2deg)}
.phone .notch{position:absolute;top:10px;left:50%;transform:translateX(-50%);width:34%;height:16px;border-radius:10px;background:#000;z-index:3}
/* fill, not cover: the captures are 0.461 aspect against a 9/19 (0.474) frame,
   so this squeezes height by <3% — invisible — and shows the whole screen
   instead of cropping the top or bottom off the UI */
.phone img{position:absolute;inset:0;width:100%;height:100%;object-fit:fill;z-index:2}
.phone .fallback{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:10px;text-align:center;padding:20px;background:linear-gradient(170deg,#1B150C,#0F0C07 60%)}
.phone .fallback .label{color:var(--accent)}
.phone .fallback p{font-size:10.5px;color:var(--dim);letter-spacing:.06em;text-transform:uppercase;line-height:1.7}
@media(max-width:820px){
  .bf .big{max-width:78vw !important}
  .phone{width:34vw;top:auto;bottom:16vh}
}
/* aux screens: beats that already own their layout get a smaller mockup at the
   outer edge, so it reads as supporting evidence rather than the subject.
   Deliberately not repositioning the record's keyframes — these sit in front. */
/* two screens fanned — one photo in, the result out. Reads as a sequence and
   fills the empty half of these beats, which were type-only before. */
.fan{position:absolute;top:47%;transform:translateY(-50%);pointer-events:none}
.fan.pR{right:clamp(26px,6vw,96px)}
.fan.pL{left:clamp(26px,6vw,96px)}
/* the container is zero-width, so anchor children to its right edge —
   otherwise they extend rightwards off the viewport */
.fan .phone{position:absolute;top:auto;left:auto;right:0;bottom:auto;pointer-events:auto}
.fan .phone.back{
  width:clamp(150px,15.5vw,246px);
  /* offset most of its own width so the screen reads, not just an edge */
  transform:translate(-82%,-56%) perspective(1200px) rotateY(-13deg) rotateZ(-5deg) scale(.94);
  opacity:calc(var(--t,0)*.9);filter:blur(calc((1 - var(--t,0))*10px)) brightness(.8);
}
.fan .phone.front{
  width:clamp(190px,19.5vw,310px);
  transform:translate(0,-44%) perspective(1200px) rotateY(-9deg) rotateX(2deg);
}
/* mirrored: on a left-hand fan the second screen fans out to the right */
.fan.pL .phone{right:auto;left:0}
.fan.pL .phone.back{transform:translate(82%,-56%) perspective(1200px) rotateY(13deg) rotateZ(5deg) scale(.94)}
.fan.pL .phone.front{transform:translate(0,-44%) perspective(1200px) rotateY(9deg) rotateX(2deg)}
@media(max-width:820px){.fan .phone.back{display:none}}

.phone.aux{width:clamp(190px,19.5vw,310px);top:47%}
.phone.aux.pR{right:clamp(26px,5vw,80px);transform:translateY(calc(-50% + (1 - var(--t,0))*30px)) perspective(1200px) rotateY(-9deg) rotateX(2deg)}
.phone.aux.pL{left:clamp(26px,5vw,80px);transform:translateY(calc(-50% + (1 - var(--t,0))*30px)) perspective(1200px) rotateY(9deg) rotateX(2deg)}
@media(max-width:820px){.phone.aux{display:none}}
.b5 .head{position:absolute;left:clamp(22px,4vw,56px);top:88px;max-width:520px}
.b5 .sub{position:absolute;right:clamp(22px,5vw,84px);top:30%;max-width:300px}
.review-strip{position:absolute;left:0;right:0;bottom:0;padding:0 clamp(22px,4vw,56px) 26px}
.review-strip .rule{display:flex;justify-content:space-between;align-items:center;border-top:1px dotted var(--faint);padding:10px 0 16px}
.review-strip .stars{color:var(--amber);letter-spacing:3px;font-size:13px}
.review-strip blockquote{font-size:clamp(16px,1.6vw,21px);max-width:420px;color:var(--dim);font-weight:500;line-height:1.45}
.review-strip blockquote em{font-style:normal;color:var(--accent)}
.review-strip .who{margin-top:12px}
.review-strip .who b{display:block;font-size:13px;color:var(--cream)}
.b6 .head{position:absolute;left:50%;top:80px;transform:translateX(-50%);text-align:center;white-space:nowrap}
/* align-items:flex-start so each card sizes to its own list — the free column
   is half the length of Pro and was stretching into a tall empty panel */
.b6 .cols{position:absolute;left:0;right:0;bottom:clamp(40px,8vh,80px);display:flex;justify-content:center;align-items:flex-start;gap:clamp(18px,4vw,64px);padding:0 clamp(22px,4vw,56px)}
/* the record passes right behind these two cards on this beat, and its amber
   label was showing straight through the plan lists — a near-opaque panel
   rather than the light glass the other beats use */
.b6 .col{width:min(38vw,268px);text-align:left;background:rgba(14,14,15,.93);border:1px solid rgba(244,240,232,.11);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);border-radius:6px;padding:20px 22px 18px;
  box-shadow:0 20px 50px rgba(0,0,0,.5)}
.b6 .col.pro{border-color:rgba(242,163,60,.42);background:rgba(17,14,10,.94)}
.b6 .col .label{color:var(--cream);margin-bottom:6px;display:block}
.b6 .col .price{display:block;font-size:clamp(22px,2.4vw,30px);font-weight:600;color:var(--cream);line-height:1.1;margin-bottom:14px}
.b6 .col .price em{font-style:normal;font-size:12px;color:var(--dim);font-weight:500;letter-spacing:.04em}
.b6 .col.pro .price{color:var(--accent)}
.b6 .plan{list-style:none;display:flex;flex-direction:column;gap:6px;margin:0 0 14px}
.b6 .plan li{font-size:12.5px;color:var(--dim);line-height:1.4;padding-left:15px;position:relative}
.b6 .plan li::before{content:"";position:absolute;left:0;top:.52em;width:5px;height:5px;border-radius:50%;background:var(--faint)}
.b6 .col.pro .plan li::before{background:var(--accent)}
.b6 .plan li b{color:var(--cream);font-weight:600}
.b6 .col .foot-note{display:block;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--faint);
  border-top:1px dotted rgba(244,240,232,.16);padding-top:10px}
.b6 .col.pro .foot-note{color:var(--accent)}
@media(max-width:820px){.b6 .col{padding:15px 16px 13px}.b6 .plan li{font-size:11.5px}}
@media(max-width:720px){.b6 .cols{flex-direction:column;align-items:center;gap:12px}
  .b6 .col{width:min(88vw,320px)}.b6 .plan{gap:4px}}
.b7 .paperwrap{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:min(1040px,90vw);display:grid;grid-template-columns:1.2fr 1fr;gap:clamp(28px,4vw,72px)}
.b7 h5{font-size:10px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--faint);margin-bottom:10px}
.b7 .blk{margin-bottom:30px}
.b7 p{font-size:14px;color:var(--dim);line-height:1.65}
.b7 p b{color:var(--cream);font-weight:600}
.b7 p em{font-style:normal;color:var(--accent)}
.b7 pre{font-family:var(--mono);font-size:11px;line-height:1.7;color:var(--dim);background:rgba(244,240,232,.04);border-radius:4px;padding:18px;overflow-x:auto}
@media(max-width:820px){.b7 .paperwrap{grid-template-columns:1fr;top:54%}.b7 .blk{margin-bottom:20px}}

/* landing */
.anno-corner{position:absolute;left:clamp(22px,4vw,56px);bottom:clamp(44px,7vh,76px);display:flex;flex-direction:column;gap:4px}
.anno-corner.right{left:auto;right:clamp(22px,4vw,56px);text-align:right}
.b8 .head-stack{position:absolute;left:clamp(22px,4vw,56px);top:96px;max-width:520px;display:flex;flex-direction:column;gap:18px}
.b8 .head-stack .sub{max-width:300px}
.b8 .anno{position:absolute;right:clamp(22px,4vw,56px);bottom:clamp(44px,7vh,76px);text-align:right}
/* the deck beat carries the BPM/set-builder pitch — the only beat that showed
   the turntable with no product on screen. Glass sits bottom-left, under the
   head stack; the anno owns the opposite corner. */
.b8 .glass{position:absolute;left:clamp(22px,4vw,56px);bottom:clamp(44px,7vh,76px)}
@media(max-height:780px){.b8 .head-stack{top:82px}.b8 .glass p{font-size:13px}}
/* needle */
.b9 .anno{position:absolute;left:clamp(22px,4vw,56px);bottom:clamp(44px,7vh,76px)}
.b9 .anno .formula{display:block;margin-top:6px}
.b9 .head{position:absolute;right:clamp(22px,4vw,56px);top:96px;max-width:420px;text-align:right}
/* top-down finale + footer */
.b10 .statement{position:absolute;right:clamp(22px,5vw,84px);top:14%;max-width:720px;text-align:right}
.b10 .statement .two{margin-top:22px;color:var(--dim)}
.b10 .newsletter{position:absolute;left:clamp(22px,5vw,84px);bottom:22vh;width:min(340px,80vw)}
.b10 .newsletter .label{margin-bottom:12px;display:block}
.b10 .newsletter .label:first-child{color:var(--cream);margin-bottom:6px}
.b10 .newsletter .sub-label{margin-bottom:12px}
.b10 .newsletter .line{display:flex;align-items:center;gap:14px;border-bottom:1px dotted var(--dim);padding-bottom:10px}
.b10 .newsletter input{flex:1;background:none;border:none;color:var(--cream);font-family:var(--sans);font-size:13px;letter-spacing:.08em}
.b10 .newsletter input::placeholder{color:var(--faint);text-transform:uppercase;font-size:11px;letter-spacing:.14em}
.b10 .newsletter input:focus{outline:none}
.b10 .newsletter button{background:var(--accent);border:none;color:#171106;width:30px;height:22px;border-radius:3px;cursor:pointer;font-size:13px}
.b10 .foot-links{position:absolute;left:clamp(22px,4vw,56px);bottom:26px;display:flex;gap:26px;flex-wrap:wrap}
.b10 .foot-links a{color:var(--dim);text-decoration:none;font-size:10px;font-weight:600;letter-spacing:.14em;text-transform:uppercase}
.b10 .foot-links a:hover{color:var(--cream)}
.b10 .disclaimer{position:absolute;right:clamp(22px,4vw,56px);bottom:26px;max-width:340px;text-align:right;font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);line-height:1.7}
/* left of the small print, quiet and not competing with it */
/* sits ABOVE the footer links — both were pinned to bottom:26px and printed
   on top of each other */
.b10 .memoriam{position:absolute;left:clamp(22px,4vw,56px);bottom:56px;font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--dim);font-weight:500}
@media(max-width:820px){.b10 .statement{right:22px;left:22px;text-align:left;top:12%}}

body.apt .plant{opacity:0 !important}
#progressBar{position:fixed;top:0;left:0;height:2px;width:0;background:var(--accent);z-index:60}
.beat-rail{right:12px;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:7px;z-index:40}
.beat-rail .bdot{width:5px;height:5px;border-radius:3px;border:none;padding:0;background:rgba(241,240,236,.22);cursor:pointer;transition:background .3s,height .3s}
.beat-rail .bdot.on{background:var(--accent);height:16px}
.beat-rail .bdot:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* beat steppers — touch only. A drag crosses several beats at once on a
   ~1800vh spacer, so these step one at a time. Hidden on desktop, where the
   wheel and the rail dots already give fine control. */
.beat-step{display:none}
@media(max-width:720px){
  .beat-step{
    display:flex;flex-direction:column;gap:10px;
    position:fixed;right:10px;top:50%;transform:translateY(-50%);z-index:41;
  }
  .beat-step .step{
    width:38px;height:38px;border-radius:50%;padding:0;cursor:pointer;
    background:rgba(11,11,12,.62);border:1px solid rgba(242,163,60,.42);
    backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
    display:grid;place-items:center;
  }
  .beat-step .step::before{
    content:"";width:9px;height:9px;
    border-left:2px solid var(--accent);border-top:2px solid var(--accent);
  }
  .beat-step .step.up::before{transform:rotate(45deg);margin-top:3px}
  .beat-step .step.down::before{transform:rotate(-135deg);margin-bottom:3px}
  .beat-step .step:active{background:var(--accent)}
  .beat-step .step:active::before{border-color:#171106}
  /* the 17-dot rail is unusable at this size; the steppers replace it */
  .beat-rail{display:none}
}

/* ---------- mobile overhaul: flow layout, overlap-proof ---------- */
@media(max-width:720px){
  .display.xl{font-size:clamp(25px,8.6vw,38px)}
  .display.lg{font-size:clamp(20px,6.8vw,29px)}
  .body-block{font-size:14px}
  .side-tab{display:none}
  .beat-rail{right:7px;gap:6px}
  .b2 .head,.b6 .head{white-space:normal}

  /* the record is rendered on the canvas ABOVE the covergrid scrim, so the
     grid's wash does nothing for it — copy was printing over the bright amber
     centre label. Each live beat lays its own scrim between the canvas and its
     copy: heaviest at the top where the type lives, lifting towards the bottom
     so the record and the screenshot still read. */
  .beat .pad::before{
    content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
    background:linear-gradient(180deg,
      rgba(11,11,12,.92) 0%,
      rgba(11,11,12,.86) 55%,
      rgba(11,11,12,.5) 100%);
  }

  /* every beat becomes a natural vertical stack — nothing absolute,
     nothing can overlap, headlines push content down as they wrap */
  .beat .pad{
    display:flex;flex-direction:column;align-items:flex-start;
    gap:16px;padding:74px 18px calc(24px + env(safe-area-inset-bottom));
    overflow:hidden;
  }
  .beat .pad>*{
    position:static !important;
    transform:none !important;
    left:auto !important;right:auto !important;top:auto !important;bottom:auto !important;
    max-width:100% !important;width:auto !important;
    text-align:left !important;
  }
  .glass{padding:14px 16px}
  .glass p{font-size:12.5px}
  .b0 .glass .sub{font-size:11.5px}
  .bf .anno{display:none !important}
  .b5 .sub{display:none !important}
  .b10 .disclaimer{display:none !important}

  /* pin the closing element of a beat to the bottom of the stack */
  .b0 .glass,.review-strip,.b6 .cols,.b8 .anno,.b9 .anno,.anno-corner,.b10 .foot-links{margin-top:auto !important}

  /* Phone mockup on mobile: the screenshots ARE the pitch, so they take every
     pixel the copy above them doesn't need. `flex:1 1 auto` with height:auto
     lets the frame GROW into the leftover space instead of sitting at a fixed
     height with a dead gap above it — short copy gets a big screen, a headline
     that wraps to four lines gets a smaller one. Width follows from the 9/19
     aspect (never set a width: `.beat .pad>*` forces width:auto !important, which
     is why these once collapsed to nothing). max-width keeps the aspect honest on
     wide phones and small tablets, where an unclamped frame would grow past the
     column and the browser would squash the ratio to fit. */
  .beat .phone{
    display:block !important;
    position:static !important;
    flex:1 1 auto;
    height:auto !important;
    min-height:190px;
    max-height:min(64svh,560px);
    width:auto !important;
    max-width:min(74vw,300px) !important;
    aspect-ratio:9/19;
    margin:14px auto 0 auto !important;
    align-self:center !important;
    border-radius:26px;
    transform:translateY(calc((1 - var(--t,0))*22px)) !important;
  }
  /* The fan is a desktop device. On mobile the mobile-phone rule above wins
     with !important and un-hides the second screen, which then stacks below
     the first at 80% brightness. Show the front one only, in flow. */
  .fan{position:static !important;transform:none !important;width:auto !important;
    margin:14px auto 0 auto !important;align-self:center !important;display:flex !important;
    flex-direction:column;align-items:center;flex:1 1 auto;min-height:0}
  .fan .phone.back{display:none !important}
  /* the fan — not the screen inside it — is the flex child of .pad, so the
     growth has to be handed down a level or the frame sits at its floor */
  .fan .phone.front{flex:1 1 auto;max-height:none;margin:0 !important}
  /* Hero on mobile: headline, tagline, screenshot. The four selling points
     made the stack too tall to breathe on a 390px screen and squeezed the
     vault screen out — the features get their own beats a scroll later. */
  .b0 .sell{display:none !important}
  .b0 .glass{display:none !important}
  /* the hero's copy is short, so let its screen run to the full budget */
  .b0 .phone{max-height:min(70svh,620px)}
  .fan .phone.front{opacity:var(--t,0);filter:blur(calc((1 - var(--t,0))*10px))}
  .phone .notch{width:30%;height:11px;top:7px}
  /* the pricing beat's two plan lists already fill the column */
  .b6 .phone.aux{display:none !important}

  .review-strip{padding:0}
  .review-strip .rule{flex-wrap:wrap;gap:6px}
  .review-strip .rule .label:last-child{display:none}
  .review-strip blockquote{font-size:13.5px}
  .b6 .cols{flex-direction:column;gap:14px;padding:0;align-self:stretch}
  .b6 .col{max-width:none;text-align:left}
  .b6 .col p{display:block;font-size:12px}
  /* this beat uses .paperwrap instead of .pad, so it misses the mobile padding
     the other beats get — without this the copy runs under the wordmark */
  .b7 .paperwrap{position:static !important;transform:none !important;width:100%;display:block;
    padding:74px 18px calc(24px + env(safe-area-inset-bottom));
    height:100vh;overflow-y:auto;max-height:none;-webkit-overflow-scrolling:touch}
  .b7 p{font-size:12px}
  .b7 pre{font-size:9px;padding:12px}
  .b7 .blk{margin-bottom:14px}
  .b10 .newsletter{align-self:stretch}
  .b10 .foot-links{gap:14px;flex-wrap:wrap}
  .b10 .statement .two{margin-top:10px}
}
/* landscape phone: ~400px of height can't hold a 9/19 frame AND the copy —
   the frame would sit at its floor and push the paragraph out of the pad,
   which clips it (the pad is overflow:hidden). The words win here. */
@media(max-width:720px) and (max-height:520px){
  .beat .phone,.fan{display:none !important}
  .beat .pad{padding-top:58px;gap:10px}
  .glass p{font-size:12px}
}
/* ---------- apartment beats: legibility over a bright plate ----------
   From beat 11 the apartment GLB fills the frame with pale walls and warm
   wood, and the palette's muted greys (--dim, --faint) disappear into it.
   These beats get white type with a real drop shadow, and the glass panel
   flips from light-translucent to dark so it reads as a panel at all. */
.b8o .glass,.b8 .glass,.b9 .glass,.b10 .glass{
  background:rgba(11,11,12,.66);
  border-color:rgba(244,240,232,.14);
  box-shadow:0 18px 50px rgba(0,0,0,.45);
}
.b8o .glass p,.b8 .glass p,.b9 .glass p,.b10 .glass p{color:var(--cream)}
.b8o .label,.b8 .label,.b9 .label,.b10 .label,
.b8o .formula,.b8 .formula,.b9 .formula,.b10 .formula,
.b8o .body-block,.b8 .body-block,.b9 .body-block,.b10 .body-block,
.b10 .foot-links a,.b10 .memoriam,.b10 .disclaimer{
  color:var(--cream);
  text-shadow:0 2px 10px rgba(0,0,0,.85),0 1px 3px rgba(0,0,0,.7);
}
.b8o .glass p,.b8 .glass p,.b9 .glass p{text-shadow:0 1px 4px rgba(0,0,0,.6)}
.b10 .disclaimer{color:rgba(241,240,236,.62)}
.b10 .memoriam{color:rgba(241,240,236,.8)}
/* the record's own annotations sit right on the deck, so give them the most */
.b8 .anno .label,.b9 .anno .label,.anno-corner .label,.anno-corner .formula{
  text-shadow:0 2px 12px rgba(0,0,0,.9),0 1px 3px rgba(0,0,0,.8);
}

@media (prefers-reduced-motion: reduce){.glow,.plant,.windowlight,.beat-rail .bdot{transition:none}}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
