/* Scroll-driven journey. Mobile-first. Every element lives in its own grid
   slot, so captions and stage content can never overlap at any width. Colours
   come from tokens, so it reads in light and dark. */

.jsec{position:relative}
.jsec-track{height:520vh}
.jsec-stage{position:sticky;top:0;height:100svh;min-height:520px;display:grid;
  grid-template-rows:auto auto minmax(0,1fr) auto;gap:.75rem;
  padding-block:calc(64px + .75rem) 1.25rem;
  padding-inline:max(var(--gutter),calc((100% - var(--maxw)) / 2 + var(--gutter)));
  align-content:stretch;overflow:hidden}
.jsec-stage>*{position:relative;z-index:1}
.js-side{display:contents}
.js-spine{grid-row:1;order:-1}.js-chans{grid-row:2}.js-view{grid-row:3}.js-cap{grid-row:4}

/* ---- chapter spine ---- */
/* A progress rail rather than four labels with one tinted pink: each chapter
   carries a state dot, the connector fills as you pass it, and the active
   chapter lifts off the canvas instead of changing colour. */
.js-spine{display:flex;align-items:center;justify-content:center;gap:.15rem;flex-wrap:nowrap}
.js-spine button{position:relative;display:inline-flex;align-items:center;gap:.5rem;
  font-family:var(--font-mono);font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--fg-4);padding:.5rem .8rem;border-radius:var(--r-pill);border:1px solid transparent;
  background:none;cursor:pointer;min-height:40px;white-space:nowrap;
  transition:color var(--t-base),background var(--t-base),border-color var(--t-base),
    box-shadow var(--t-base),transform var(--t-base) var(--ease-out)}
.js-spine button::before{content:"";width:7px;height:7px;border-radius:50%;flex:none;
  background:var(--border-3);
  transition:background var(--t-base),box-shadow var(--t-base),transform var(--t-base) var(--ease-snap)}
.js-spine button:hover{color:var(--fg-1)}
.js-spine button:hover::before{background:var(--fg-4)}
.js-spine button.done{color:var(--fg-3)}
.js-spine button.done::before{background:var(--coral)}
.js-spine button.on{color:var(--fg-1);background:var(--bg-surface);
  border-color:var(--border-2);box-shadow:var(--sh-sm);transform:translateY(-1px)}
.js-spine button.on::before{background:var(--coral);transform:scale(1.25);
  box-shadow:0 0 0 4px var(--coral-soft)}
/* the connector is a track that fills, not a line that recolours */
.js-spine i{width:22px;height:2px;border-radius:2px;background:var(--border-2);
  display:block;flex:none;position:relative;overflow:hidden}
.js-spine i::after{content:"";position:absolute;inset:0;background:var(--coral);
  transform:scaleX(0);transform-origin:left center;
  transition:transform .45s var(--ease-out)}
.js-spine i.done::after{transform:scaleX(1)}
@media (prefers-reduced-motion:reduce){
  .js-spine button.on{transform:none}
  .js-spine i::after{transition:none}
}
:root[data-theme="dark"] .js-spine button.on{background:var(--bg-surface);border-color:var(--border-2)}

/* ---- channel row ---- */
.js-chans{display:grid;grid-template-columns:repeat(3,1fr);gap:.5rem}
.js-chan{display:flex;flex-direction:column;align-items:center;gap:.4rem;padding:.6rem .35rem;
  background:transparent;border:1.5px solid var(--border-2);border-radius:var(--r-pill);
  opacity:.4;transform:translateY(6px);transition:opacity .45s var(--ease-out),transform .45s var(--ease-out),border-color .45s,box-shadow .45s}
.js-chan.on{opacity:1;transform:none;border-color:color-mix(in oklab,var(--c) 26%,var(--border-2));
  background:color-mix(in oklab,var(--c) 6%,transparent)}
.js-chan svg,.js-chan i{width:24px;height:24px;display:block;color:var(--c)}
.js-chan .bi{fill:currentColor;color:var(--c)}
.js-chan b{font-size:.8125rem;font-weight:var(--fw-bold);color:var(--fg-1);letter-spacing:-.01em;white-space:nowrap}
.js-bars{display:flex;align-items:flex-end;gap:2px;height:20px}
.js-bars i{width:4px;border-radius:1px;background:var(--border-3);display:block;transform:scaleY(0);transform-origin:bottom;transition:transform .6s var(--ease-out)}
.jsec-stage[data-beat="6"] .js-bars i{transform:scaleY(1)}
.js-bars i:nth-child(2){transition-delay:.06s}
.js-bars i:nth-child(3){transition-delay:.12s}
.js-bars i:nth-child(4){transition-delay:.18s}
.js-bars i:last-child{background:var(--c)}

/* ---- view: phone + graph share one cell, one is foregrounded at a time ---- */
.js-view{position:relative;display:grid;place-items:center;min-height:0;overflow:visible}
.js-phone{position:relative;width:min(320px,86vw);height:auto;min-height:0;max-height:min(100%,520px);
  display:flex;flex-direction:column;background:var(--ink-700);border:1px solid var(--border-ink);
/* No drop shadow. The overlays that cover the phone bleed only 8px past the
   view, while --sh-lg spreads ~30px, so the shadow escaped from behind them
   and painted as a smudge on the empty canvas below. */
  border-radius:22px;overflow:hidden;
  opacity:1;
  transition:opacity .6s var(--ease-out),transform .6s var(--ease-out)}
/* beat 0 is a connected, quiet channel, not an empty grey slab */
.js-listen{margin:auto;display:flex;flex-direction:column;align-items:center;gap:.55rem;
  font-family:var(--font-mono);font-size:.75rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--fg-on-ink-3);transition:opacity .35s var(--ease-out)}
.js-listen .rings{position:relative;width:36px;height:36px}
.js-listen .rings i{position:absolute;inset:0;border-radius:50%;border:1.5px solid var(--grass);
  opacity:0;animation:jsPing 2.4s var(--ease-out) infinite}
.js-listen .rings i:nth-child(2){animation-delay:.8s}
.js-listen .rings i:nth-child(3){animation-delay:1.6s}
@keyframes jsPing{0%{transform:scale(.3);opacity:.9}100%{transform:scale(1);opacity:0}}
.jsec-stage:not([data-beat="0"]) .js-listen{opacity:0;height:0;margin:0;overflow:hidden}
.js-phead{display:flex;align-items:center;gap:.55rem;padding:.6rem .7rem;border-bottom:1px solid var(--border-ink);flex:none}
.js-phead .a{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,#FF9F45,#F2514D);
  display:grid;place-items:center;color:#fff;font-weight:800;font-size:.6875rem;flex:none}
.js-phead b{display:block;color:#fff;font-size:.8125rem;font-weight:var(--fw-bold)}
.js-phead small{display:flex;align-items:center;gap:.3rem;color:var(--fg-on-ink-3);font-size:.625rem}
.js-phead small i{width:5px;height:5px;border-radius:50%;background:var(--grass);display:block}
.js-thread{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;justify-content:flex-end;gap:.45rem;padding:.7rem;overflow:hidden;
  background-color:var(--wa-bg);background-image:var(--wa-paper);background-size:240px 240px;background-repeat:repeat}
.js-thread>[data-b]{display:none;flex:none}
.js-thread>[data-b].on{display:block;animation:jsIn .45s var(--ease-out) both}
@keyframes jsIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.js-b{max-width:88%;padding:.5rem .7rem;border-radius:11px;font-size:.8125rem;line-height:1.4;color:#E9EDF0}
.js-b.in{background:#1F2C33;align-self:flex-start;border-bottom-left-radius:3px}
.js-b.out{background:#0F5C3C;align-self:flex-end;border-bottom-right-radius:3px}
.js-b .tm{display:block;font-size:0.6875rem;color:rgba(255,255,255,.45);margin-top:.2rem}
.js-appr{border:1.5px solid rgba(139,92,246,.55);border-left:3px solid var(--violet);border-radius:11px;
  padding:.55rem .6rem;background:rgba(139,92,246,.08)}
.js-appr .lbl{display:flex;align-items:center;gap:.35rem;font-family:var(--font-mono);font-size:0.6875rem;
  letter-spacing:.08em;text-transform:uppercase;color:var(--violet);margin-bottom:.35rem}
.js-appr .lbl svg{width:15px;height:19px;display:block}
.js-appr p{font-size:.75rem;line-height:1.4;color:#E9EDF0;margin:0}
.js-appr .acts{display:flex;gap:.35rem;margin-top:.5rem}
.js-appr .acts b{font-size:.625rem;font-weight:var(--fw-bold);border-radius:var(--r-pill);padding:.3rem .6rem}
.js-appr .acts .ok{background:#fff;color:#101012}
.js-appr .acts .ed{border:1px solid var(--border-ink);color:var(--fg-on-ink-2)}
.jsec-stage[data-beat="3"] .js-appr .acts .ok{box-shadow:0 0 0 3px rgba(37,211,102,.35)}
.js-co{align-self:flex-end;max-width:88%;background:#fff;border-radius:11px;overflow:hidden}
.js-co .h{display:flex;align-items:center;justify-content:space-between;padding:.4rem .55rem;border-bottom:1px solid var(--border-1)}
.js-co .h b{font-size:.6875rem;color:#14181B;font-weight:var(--fw-bold)}
.js-co .h span{background:var(--grass-soft);color:var(--grass-deep);font-size:0.625rem;font-weight:700;border-radius:var(--r-pill);padding:.15rem .4rem}
.js-co .r{display:flex;justify-content:space-between;gap:.8rem;padding:.3rem .55rem;font-size:.625rem;color:#3C464E}
.js-co .r.t{border-top:1px dashed var(--border-2);color:#14181B;font-weight:700;padding-bottom:.45rem}
.js-audit{display:flex;align-items:center;gap:.4rem;padding:.45rem .7rem;border-top:1px solid var(--border-ink);
  font-family:var(--font-mono);font-size:0.6875rem;letter-spacing:.05em;color:var(--fg-on-ink-3);flex:none;
  opacity:0;transition:opacity .5s var(--ease-out);white-space:nowrap;overflow:hidden}
.jsec-stage[data-beat="3"] .js-audit,.jsec-stage[data-beat="4"] .js-audit,
.jsec-stage[data-beat="5"] .js-audit,.jsec-stage[data-beat="6"] .js-audit{opacity:1}
.js-audit i{width:5px;height:5px;border-radius:50%;background:var(--grass);display:block;flex:none}
.js-audit .ok{color:var(--grass)}
.js-audit .hash{margin-left:auto}

/* Jo watches from the side; hidden on the narrowest screens so nothing crowds */
.js-jo{position:absolute;left:0;bottom:6%;width:66px;opacity:0;transform:translateY(14px) scale(.9);
  transition:opacity .5s var(--ease-out),transform .5s var(--ease-out);pointer-events:none}
.js-jo svg{width:100%;height:auto;display:block}
.jsec-stage[data-beat="2"] .js-jo,.jsec-stage[data-beat="3"] .js-jo{opacity:1;transform:none}
@media (max-width:420px){.js-jo{display:none}}

/* the graph fully covers the phone, so nothing ghosts through the transition */
.js-graph{position:absolute;inset:-.5rem;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:.4rem;opacity:0;pointer-events:none;transition:opacity .45s var(--ease-out);
  background-color:var(--bg-canvas);
  background-image:linear-gradient(var(--grid-line) 1px,transparent 1px),linear-gradient(90deg,var(--grid-line) 1px,transparent 1px);
  background-size:27px 27px;background-attachment:fixed;border-radius:var(--r-xl)}
.jsec-stage[data-beat="4"] .js-graph{opacity:1}
.js-node{width:min(280px,84vw);display:flex;align-items:center;gap:.55rem;padding:.5rem .65rem;
  background:var(--bg-surface);border:1.5px solid var(--border-2);border-radius:var(--r-md);box-shadow:var(--sh-sm)}
.js-node .d{width:20px;height:20px;border-radius:6px;background:var(--c);opacity:.2;flex:none;display:grid;place-items:center}
.js-node .d::after{content:"";width:8px;height:8px;border-radius:2px;background:var(--c)}
.js-node b{display:block;font-size:.9375rem;color:var(--fg-1);font-weight:var(--fw-bold);white-space:nowrap}
.js-node small{font-family:var(--font-mono);font-size:.75rem;color:var(--fg-3);white-space:nowrap}
.js-wire{width:2px;height:14px;background:var(--border-3);flex:none}
.js-arms{display:flex;gap:.5rem;width:min(280px,84vw)}
.js-arm{flex:1;text-align:center;padding:.4rem .3rem;border:1.5px solid var(--border-2);border-radius:var(--r-md);
  background:var(--bg-surface);font-size:.8125rem;line-height:1.3}
.js-arm.pick{border-color:var(--grass)}
.js-arm b{display:block;color:var(--fg-1);font-weight:var(--fw-bold)}
.js-arm.pick b{color:var(--grass-deep)}
.js-arm small{color:var(--fg-3);font-size:.75rem}

/* the review that lands back on Google. Anchored above the phone, clear of the
   bottom-anchored thread. Hidden on mobile, where the bars carry the beat. */
.js-rev{display:none}
@media (min-width:900px){
  .js-rev{position:absolute;right:-1.25rem;top:-.5rem;bottom:auto;display:flex;align-items:center;gap:.6rem;
    background:var(--bg-surface);border:1.5px solid var(--sun);border-radius:var(--r-lg);
    padding:.6rem .85rem;box-shadow:0 16px 34px -12px rgba(224,162,0,.5),var(--sh-md);white-space:nowrap;
    opacity:0;transform:translateY(14px) scale(.95);
    transition:opacity .5s var(--ease-out),transform .5s var(--ease-snap)}
  .jsec-stage[data-beat="6"] .js-rev{opacity:1;transform:none}
}
.js-rev svg{width:24px;height:24px;display:block;flex:none}
.js-rev b{display:block;font-size:.75rem;color:var(--fg-1);font-weight:var(--fw-bold)}
.js-rev small{font-size:.8125rem;color:var(--sun-star);letter-spacing:.08em;line-height:1}

/* ---- caption: a fixed slot, so swapping copy never shifts the stage ---- */
.js-cap{min-height:5.25rem;display:flex;flex-direction:column;justify-content:flex-end;text-align:center}
.js-cap .eb{font-family:var(--font-mono);font-size:.8125rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--fg-2);margin-bottom:.35rem;transition:opacity .25s;
  display:inline-flex;align-items:center;gap:.45rem;justify-content:center}
.js-cap .eb::before{content:"";width:8px;height:8px;border-radius:2px;background:var(--coral);
  transform:rotate(12deg);flex:none}
.js-cap .ln{font-size:1.125rem;font-weight:var(--fw-extra);letter-spacing:var(--track-tight);
  line-height:1.2;color:var(--fg-1);text-wrap:balance;transition:opacity .25s}
.js-cap.swap .eb,.js-cap.swap .ln{opacity:0}

/* ---------------------------- desktop ------------------------------------ */
@media (min-width:900px){
  .jsec-track{height:580vh}
  .jsec-stage{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
    grid-template-rows:minmax(0,1fr);gap:1.5rem 3rem;align-content:center;
    padding-block:calc(72px + 1rem) 2rem}
  /* The two-column stage arrives at 920 but the left column is only ~375px
     until 1040. The rail needs 473px at full size, so it wraps and stays
     compact through this band rather than overhanging the phone mock. */
  .js-side{min-width:0}
  .js-spine{grid-column:auto;grid-row:auto;justify-content:flex-start;order:0;margin-left:-.6rem;
    flex-wrap:wrap;row-gap:.2rem}
  .js-spine button{font-size:.6875rem;padding:.45rem .65rem;gap:.4rem}
  .js-spine i{display:none}
  /* the channel row is two 241px cards needing 487px in a ~391px column, so
     it wraps here too and returns to one line at 1040 */
  .js-chans{flex-wrap:wrap;min-width:0;max-width:100%}
  .js-chan{min-width:0;max-width:100%}
  .js-bars{flex:0 1 auto;min-width:0}
  /* caption first, channels beneath it, the pair centred in the column */
  .js-side{display:flex;flex-direction:column;justify-content:center;gap:1.25rem;
    grid-column:1;grid-row:1;min-height:0}
  /* the eyebrow is a stretched flex item, so its own justify-content decides
     where the dot and label sit — it has to follow the caption's alignment */
  .js-cap{order:1;grid-row:auto;grid-column:auto;min-height:0;padding-top:0;
    text-align:left;justify-content:flex-start}
  .js-cap .eb{justify-content:flex-start}
  .js-cap .ln{font-size:clamp(1.75rem,1rem + 2vw,2.625rem)}
  .js-chans{order:2;grid-row:auto;grid-column:auto;grid-template-columns:repeat(2,1fr);
    gap:.55rem;max-width:25rem}
  .js-chan{flex-direction:row;justify-content:flex-start;gap:.5rem;padding:.6rem .75rem}
  .js-chan svg,.js-chan i{width:24px;height:24px}
  .js-chan b{font-size:.9375rem}
  .js-view{grid-column:2;grid-row:1;height:100%;max-height:min(100%,600px);align-self:center;min-height:0}
  .js-phone{width:min(360px,100%);height:auto;max-height:100%}
  .js-jo{left:-3rem;width:84px}
}

/* ---- no-motion: drop the runway, show the whole story settled in one column ---- */
@media (prefers-reduced-motion:reduce){
  .jsec-track{height:auto}
  .jsec-stage{position:static;height:auto;min-height:0;padding-block:3rem;
    grid-template-columns:1fr;grid-template-rows:none;gap:1.75rem}
  .js-side{display:flex;flex-direction:column;gap:1.25rem;grid-column:1;grid-row:auto}
  .js-spine,.js-chans,.js-cap,.js-view{grid-column:1;grid-row:auto}
  .js-cap{min-height:0;order:0}
  .js-chans{order:1;max-width:none}
  .js-view{height:auto;min-height:0;display:grid;gap:1.5rem;place-items:stretch}
  .js-thread>[data-b]{display:block;animation:none}
  .js-chan{opacity:1;transform:none}
  .js-phone{opacity:1;transform:none;height:auto;max-height:none;width:min(360px,100%);justify-self:center}
  .js-listen{display:none}
  /* the overlays become real stacked blocks instead of invisible absolute layers */
  .js-graph,.js-sigs,.js-bcast{position:static;inset:auto;opacity:1;pointer-events:auto;
    background:none;padding:0;height:auto}
  .js-sigs{display:flex;flex-direction:column;gap:.5rem}
  .js-sig{position:static;opacity:1;transform:none;animation:none}
  .js-sig-note{opacity:1;animation:none}
  .js-bcast{gap:.6rem}
  .bc-prog .bar i{width:78%}
  .js-bars i{transform:scaleY(1)}
  .js-rev,.js-audit{opacity:1;transform:none}
  .js-jo{display:none}
}


/* ==================== BEAT 0: the signal wall ====================
   Real captured items from four channels, so "capture" is shown, not asserted. */
.js-sigs{position:absolute;inset:-.5rem;display:flex;flex-direction:column;justify-content:center;gap:.5rem;
  padding:.5rem;opacity:0;pointer-events:none;transition:opacity .45s var(--ease-out);
  background-color:var(--bg-canvas);
  background-image:linear-gradient(var(--grid-line) 1px,transparent 1px),linear-gradient(90deg,var(--grid-line) 1px,transparent 1px);
  background-size:27px 27px;background-attachment:fixed;border-radius:var(--r-xl)}
.jsec-stage[data-beat="0"] .js-sigs{opacity:1}
.js-sig{display:flex;align-items:center;gap:.8rem;background:var(--bg-surface);border:1px solid var(--border-1);
  border-left:4px solid var(--c);border-radius:var(--r-lg);padding:.7rem .85rem;box-shadow:var(--sh-sm);
  opacity:0;transform:translateX(-14px)}
.jsec-stage[data-beat="0"] .js-sig{animation:jsSig .5s var(--ease-snap) forwards;animation-delay:calc(var(--i) * 160ms + 120ms)}
@keyframes jsSig{to{opacity:1;transform:none}}
.js-sig img,.js-sig .th{width:clamp(42px,4vw,54px);height:clamp(42px,4vw,54px);border-radius:var(--r-md);object-fit:cover;flex:none;display:block}
.js-sig .th{display:grid;place-items:center;align-content:center;gap:1px;background:var(--sun-soft);
  color:var(--fg-1);font-size:.625rem;font-weight:var(--fw-extra);line-height:1;letter-spacing:-.01em}
.js-sig .th b{color:var(--sun-star);font-size:.875rem;line-height:1}
.js-sig .tx{flex:1;min-width:0}
.js-sig .tx b{display:block;font-size:clamp(.875rem,1.1vw,1rem);font-weight:var(--fw-bold);color:var(--fg-1);letter-spacing:-.01em}
.js-sig .tx small{display:block;font-size:clamp(.8125rem,1vw,.9375rem);color:var(--fg-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.js-sig .bi{width:20px;height:20px;fill:var(--c);flex:none}
.js-sig-note{text-align:center;font-family:var(--font-mono);font-size:.75rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--fg-4);opacity:0}
.jsec-stage[data-beat="0"] .js-sig-note{animation:jsSig .5s var(--ease-out) .8s forwards}

/* ==================== the approved template message ==================== */
.js-tpl{align-self:flex-start;max-width:88%;background:#1F2C33;border-radius:11px;
  border-bottom-left-radius:3px;overflow:hidden;padding:.3rem .3rem .45rem}
.js-tpl .tg{display:flex;align-items:center;gap:.3rem;font-family:var(--font-mono);font-size:0.625rem;
  letter-spacing:.06em;text-transform:uppercase;color:var(--grass);padding:.15rem .3rem .3rem}
.js-tpl .tg i{width:5px;height:5px;border-radius:50%;background:var(--grass);display:block;flex:none}
.js-tpl img{width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:8px;display:block}
.js-tpl p{font-size:.75rem;line-height:1.4;color:#E9EDF0;margin:.4rem .3rem 0}
.js-tpl .btns{display:grid;grid-template-columns:1fr 1fr;gap:3px;margin-top:.45rem}
.js-tpl .btns b{text-align:center;font-size:.625rem;font-weight:var(--fw-semibold);color:#53BDEB;
  background:rgba(83,189,235,.09);border-radius:7px;padding:.3rem .2rem}
.js-tpl .tm{display:block;font-size:0.6875rem;color:rgba(255,255,255,.45);margin:.3rem .3rem 0}

/* ==================== BEATS 6-7: the broadcast console ====================
   Mirrors the real Broadcasts screen: pacing, pipeline, per-state tiles. */
.js-bcast{position:absolute;inset:-.5rem;display:flex;flex-direction:column;gap:.45rem;padding:.6rem;
  opacity:0;pointer-events:none;transition:opacity .45s var(--ease-out);
  background-color:var(--bg-canvas);
  background-image:linear-gradient(var(--grid-line) 1px,transparent 1px),linear-gradient(90deg,var(--grid-line) 1px,transparent 1px);
  background-size:27px 27px;background-attachment:fixed;border-radius:var(--r-xl)}
.jsec-stage[data-beat="6"] .js-bcast,.jsec-stage[data-beat="7"] .js-bcast{opacity:1}
.bc-head{display:flex;align-items:center;gap:.5rem}
.bc-head .bi{width:18px;height:18px;fill:var(--grass);flex:none}
.bc-head b{display:block;font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--fg-1);letter-spacing:-.01em}
.bc-head small{display:block;font-family:var(--font-mono);font-size:.75rem;color:var(--fg-3)}
.bc-head span{min-width:0}
.bc-live{margin-left:auto;display:inline-flex;align-items:center;gap:.3rem;background:var(--grass-soft);
  color:var(--grass-deep);border-radius:var(--r-pill);padding:.25rem .6rem;font-size:.6875rem;
  font-weight:var(--fw-bold);letter-spacing:.04em;text-transform:uppercase;flex:none}
.bc-live i{width:5px;height:5px;border-radius:50%;background:var(--grass-deep);display:block;
  animation:jsPulse 1.6s ease-in-out infinite}
@keyframes jsPulse{0%,100%{opacity:1}50%{opacity:.3}}
.bc-vid{position:relative;border-radius:var(--r-lg);overflow:hidden;flex:none;box-shadow:var(--sh-sm)}
.bc-vid img{width:100%;aspect-ratio:16/7;object-fit:cover;display:block}
.bc-vid .pl{position:absolute;inset:0;display:grid;place-items:center}
.bc-vid .pl svg{width:34px;height:34px;fill:#fff;filter:drop-shadow(0 2px 8px rgba(0,0,0,.5))}
.bc-vid .dur{position:absolute;right:6px;bottom:6px;background:rgba(0,0,0,.78);color:#fff;
  font-size:0.6875rem;font-weight:var(--fw-semibold);padding:.1rem .3rem;border-radius:3px}
.bc-prog{background:var(--bg-surface);border:1px solid var(--border-1);border-radius:var(--r-lg);padding:.7rem .85rem}
.bc-prog .t{display:flex;align-items:baseline;justify-content:space-between;gap:.5rem}
.bc-prog .t b{font-size:.9375rem;font-weight:var(--fw-bold);color:var(--fg-1)}
.bc-prog .t span{font-family:var(--font-mono);font-size:.75rem;color:var(--fg-3)}
.bc-prog .bar{height:8px;border-radius:var(--r-pill);background:var(--neutral-100);overflow:hidden;margin:.4rem 0 .35rem}
.bc-prog .bar i{display:block;height:100%;width:0;border-radius:var(--r-pill);
  background:linear-gradient(90deg,var(--grass),var(--sky));transition:width 1.6s var(--ease-out)}
.jsec-stage[data-beat="6"] .bc-prog .bar i{width:20%}
.jsec-stage[data-beat="7"] .bc-prog .bar i{width:78%}
.bc-prog .m{display:flex;flex-wrap:wrap;gap:.2rem .9rem;font-size:.8125rem;color:var(--fg-3)}
.bc-prog .m b{color:var(--fg-1);font-weight:var(--fw-bold)}
.bc-prog .m b.fl{color:var(--sky-deep)}
.bc-tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:.35rem}
.bc-tiles div{background:var(--bg-surface);border:1px solid var(--border-1);border-radius:var(--r-md);
  padding:.5rem .6rem;text-align:left}
.bc-tiles b{display:block;font-size:clamp(1.125rem,1.5vw,1.5rem);font-weight:var(--fw-extra);color:var(--fg-1);
  letter-spacing:-.03em;line-height:1.1}
.bc-tiles b.g{color:var(--grass-deep)}
.bc-tiles small{display:block;font-family:var(--font-mono);font-size:.6875rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--fg-4);margin-top:.1rem}
.bc-foot{display:flex;align-items:center;justify-content:space-between;gap:.6rem;margin-top:auto;
  font-size:.8125rem;color:var(--fg-3);line-height:1.35}
.bc-foot b{font-family:var(--font-mono);font-size:.8125rem;color:var(--fg-1);white-space:nowrap}
/* the estimate is a figure, not a sentence: label it and give it a surface */
.bc-cost{display:flex;align-items:baseline;gap:.5rem;flex:none;
  background:var(--bg-surface);border:1px solid var(--border-1);border-radius:var(--r-md);
  padding:.35rem .6rem;box-shadow:var(--sh-xs)}
.bc-cost small{font-family:var(--font-mono);font-size:.625rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--fg-4)}
.bc-cost b{font-family:var(--font-mono);font-size:.9375rem;font-weight:var(--fw-bold);
  color:var(--fg-1);letter-spacing:-.01em}

/* the send is live, so the counters move: the numbers are the animation */
@property --bn{syntax:'<integer>';initial-value:0;inherits:false}
.bc-tiles b.n{counter-reset:bn var(--bn)}
.bc-tiles b.n::after{content:counter(bn)}
.jsec-stage[data-beat="7"] .bc-tiles b.n1{animation:bcN1 2.2s var(--ease-out) forwards}
.jsec-stage[data-beat="7"] .bc-tiles b.n2{animation:bcN2 2.2s var(--ease-out) .1s forwards}
.jsec-stage[data-beat="7"] .bc-tiles b.n3{animation:bcN3 2.2s var(--ease-out) .2s forwards}
.jsec-stage[data-beat="7"] .bc-tiles b.n4{animation:bcN4 2.2s var(--ease-out) .3s forwards}
.jsec-stage[data-beat="7"] .bc-tiles b.n5{animation:bcN5 2.2s var(--ease-out) .4s forwards}
@keyframes bcN1{from{--bn:602}to{--bn:2341}}
@keyframes bcN2{from{--bn:192}to{--bn:2190}}
@keyframes bcN3{from{--bn:29}to{--bn:1404}}
@keyframes bcN4{from{--bn:4}to{--bn:96}}
@keyframes bcN5{from{--bn:11}to{--bn:212}}

/* what keeps the number healthy, stated rather than implied */
.bc-pace{display:flex;flex-wrap:wrap;gap:.3rem .5rem}
.bc-pace .p{display:inline-flex;align-items:center;gap:.35rem;background:var(--bg-surface);
  border:1px solid var(--border-1);border-radius:var(--r-pill);padding:.3rem .65rem;
  font-size:.75rem;font-weight:var(--fw-semibold);color:var(--fg-2);white-space:nowrap}
.bc-pace .p i{width:6px;height:6px;border-radius:50%;background:var(--grass);display:block;flex:none}

/* the phone steps back while an overlay owns the stage */
.jsec-stage[data-beat="0"] .js-phone,.jsec-stage[data-beat="6"] .js-phone,
.jsec-stage[data-beat="7"] .js-phone{opacity:0;transform:scale(.97)}
.jsec-stage[data-beat="0"] .js-listen{opacity:0}

@media (max-height:700px){
  .bc-vid{display:none}
  .bc-tiles b{font-size:var(--fs-base)}
  .js-sig img,.js-sig .th{width:32px;height:32px}
}
@media (prefers-reduced-motion:reduce){
  .js-sig,.js-sig-note{opacity:1;transform:none;animation:none}
  .bc-live i{animation:none}
}

/* ---- the product, carried through every beat ---- */
.js-b.ref{padding:.3rem .3rem .45rem}
.js-b.ref .tm{margin-left:.3rem}
.js-ref{display:flex;align-items:center;gap:.5rem;background:rgba(255,255,255,.07);
  border-left:3px solid var(--grass);border-radius:8px;padding:.35rem .45rem;margin-bottom:.4rem}
.js-ref img{width:34px;height:34px;border-radius:6px;object-fit:cover;flex:none;display:block}
.js-ref b{display:block;font-size:.6875rem;font-weight:var(--fw-bold);color:#E9EDF0;letter-spacing:-.01em}
.js-ref small{display:block;font-size:0.6875rem;color:var(--grass);font-family:var(--font-mono)}
.js-b.ref{padding-left:.35rem;padding-right:.5rem}
.js-b.ref>span.js-ref+*{margin-left:.15rem}

.js-prod{display:flex;align-items:center;gap:.5rem;background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.09);border-radius:8px;padding:.35rem .45rem;margin:.1rem 0 .45rem}
.js-prod img{width:32px;height:32px;border-radius:6px;object-fit:cover;flex:none;display:block}
.js-prod span{flex:1;min-width:0}
.js-prod b{display:block;font-size:.6875rem;font-weight:var(--fw-bold);color:#E9EDF0;letter-spacing:-.01em}
.js-prod small{display:block;font-size:0.6875rem;color:var(--grass);font-family:var(--font-mono)}
.js-prod .ok{width:14px;height:14px;border-radius:50%;background:var(--grass);flex:none;position:relative}
.js-prod .ok::after{content:"";position:absolute;left:4px;top:3px;width:4px;height:7px;
  border:solid #08381f;border-width:0 1.6px 1.6px 0;transform:rotate(42deg)}
.js-co .r.p{align-items:center;gap:.45rem}
.js-co .r.p img{width:24px;height:24px;border-radius:5px;object-fit:cover;flex:none;display:block}
.js-co .r.p span:first-of-type{flex:1;min-width:0}

/* Once the column is wide enough, the rail returns to one line with its
   connectors. Measured: the four chapters plus three tracks need 473px. */
@media (min-width:1040px){
  .js-chans{flex-wrap:nowrap}
  .js-spine{flex-wrap:nowrap;row-gap:0;margin-left:-.8rem}
  .js-spine button{font-size:.8125rem;padding:.5rem 1rem;gap:.5rem}
  .js-spine i{display:block;width:22px}
}
