/* ═══════════════════════════════════════════════════════════════════════
   Where the game happens · Social Gameplay Lite · build 3

   INK AND SIGNAL. Warm paper, ink diagrams. Red is people and
   relationships. Blue is the app speaking. Gameplay objects stay ink.

   THE CANVAS. Every scene is drawn on a fixed 1512 x 982 canvas and scaled
   to the viewport by --k (index.html sets it). Title zone y 60 to 130,
   content y 160 to 882, the bottom 100px empty. No footers.

   FRAMES. A phone is the asset at its own aspect ratio: --w and --ar,
   never a height, never object-fit. Only screens under 0.444 (w/h) sit in
   a scroll window, which is itself a 0.462 phone. Pins are children of the
   image box, in percent of the image, measured in source pixels.

   TYPE. Inter Tight for titles, display, statements and numbers, Inter for
   everything read, IBM Plex Mono for a date standing alone. Sentence case.
   Floor 20px on the canvas. Weight 600 only on titles, display, the first
   statement and numbers; everything read is 400, with ink against ink-2
   doing the emphasis.

   THE BUILD. app.js (untouched) releases .rv elements one data-step per
   key on scenes with data-hold. State changes hang off zero-size markers
   <i class="rv m m--k" data-step="k"> and sibling selectors.
   phone.js owns the scroll phones.
   ═══════════════════════════════════════════════════════════════════ */

:root{
  --paper:#F3F3F3; --panel:#ECE8DF; --line:rgba(20,20,26,.16);
  --ink:#14141A; --ink-2:#4A4B55; --red:#C8102E; --blue:#2F4B8F;
  --sans:'Inter',system-ui,sans-serif; --tight:'Inter Tight',var(--sans);
  --mono:'IBM Plex Mono',ui-monospace,Menlo,monospace;
  --safe-x:72px;
  --ease-standard:cubic-bezier(.4,0,.2,1); --ease-decel:cubic-bezier(0,0,.2,1);
  --ease-land:cubic-bezier(.16,1,.3,1); --k:1;
}
*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;height:100%;background:var(--paper);overscroll-behavior:none;scrollbar-width:none}
html::-webkit-scrollbar,body::-webkit-scrollbar{width:0;height:0;display:none}
body{font-family:var(--sans);color:var(--ink);-webkit-font-smoothing:antialiased;font-variant-numeric:tabular-nums}
#stage{-webkit-user-select:none;user-select:none}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
img,video{display:block}
p,h2,h3,ol,ul,figure,dl,dd{margin:0}
ol,ul{padding:0;list-style:none}

/* ── Scene and canvas ─────────────────────────────────────────────────── */
.scene{position:relative;width:100vw;height:100dvh;overflow:hidden;background:var(--paper)}
.scene:focus,.scene:focus-visible{outline:none}
/* The canvas is the Figma artboard, 1:1. Keeping the same 1920x1080 space the
   source file is drawn in means every coordinate in this deck is the number
   Figma reports, with no scale factor to re-derive and no rounding drift. The
   whole board is then fitted to the viewport by --k, which index.html
   already computed from 1920x1080 while this box was 1512x982, so the board
   never actually filled the screen. */
.canvas{position:absolute;left:50%;top:50%;width:1920px;height:1080px;
  transform:translate(-50%,-50%) scale(var(--k));transform-origin:center}
.scene:not(.scene--dp) .canvas{
  transform:translate(-50%,-50%) scale(var(--k)) translateY(-16px)}
.at{position:absolute;left:var(--x);top:var(--y);width:var(--w,auto)}

/* ── Type roles ───────────────────────────────────────────────────────── */
.label{font-size:20px;font-weight:500;line-height:1.3;color:var(--ink-2)}
.label--ink{color:var(--ink)}.label--blue{color:var(--blue)}.label--red{color:var(--red)}
.title{position:absolute;left:var(--safe-x);top:60px;max-width:1368px;
  font-family:var(--tight);font-size:40px;font-weight:600;letter-spacing:-.02em;line-height:1.15}
.display{font-family:var(--tight);font-size:104px;font-weight:600;letter-spacing:-.04em;line-height:.96}
.display--chapter{font-size:76px;letter-spacing:-.03em;line-height:1}
.lede{font-size:26px;line-height:1.4;color:var(--ink-2)}
.lede em,.body em,.caption em{font-style:normal;font-weight:400;color:var(--ink)}
.body{font-size:22px;line-height:1.45;color:var(--ink)}
.body--2{color:var(--ink-2)}
.caption{font-size:22px;line-height:1.4;color:var(--ink-2)}
.statement{font-family:var(--tight);font-size:64px;font-weight:600;letter-spacing:-.02em;line-height:1.1;color:var(--ink)}
.statement--2{font-weight:500}
.num{font-family:var(--tight);font-size:56px;font-weight:600;letter-spacing:-.02em;line-height:1}
.date{font-family:var(--mono);font-size:20px;font-weight:500;color:var(--ink-2)}
.date--red{color:var(--red)}
.note{font-size:20px;line-height:1.4;color:var(--ink-2)}

/* ── The people glyph. Red is people. ─────────────────────────────────── */
.p{display:inline-grid;place-items:center;width:64px;height:64px;border-radius:50%;background:var(--red);color:var(--paper);
  font-family:var(--tight);font-size:22px;font-weight:600;flex:none}
.p--ghost{background:none;border:2px dashed var(--red);color:var(--red)}
.p--ink{background:var(--ink)}

/* ── Reveals: the engine's contract ───────────────────────────────────── */
.rv{opacity:0}
.is-in .rv{opacity:1;transition:none}
.is-in .rv.held{opacity:0;transition:none}
.m{position:absolute;width:0;height:0;overflow:hidden}

/* ── Badges ───────────────────────────────────────────────────────────── */
.tab,.dsq{display:inline-grid;place-items:center;width:32px;height:32px;flex:none;background:var(--ink);color:var(--paper);
  font-family:var(--tight);font-size:20px;font-weight:600;line-height:1}
.tab{border-radius:50%}
.tab--red{background:var(--red)}.tab--blue{background:var(--blue)}
.dsq{border-radius:8px;background:var(--red)}
.dsq--outline{background:none;border:1.5px solid var(--ink-2);color:var(--ink-2)}

/* ── Phones: the asset at its own ratio ───────────────────────────────── */
.phone{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.phone>img,.phone>video{width:100%;height:auto;aspect-ratio:var(--ar);border:2px solid var(--ink);border-radius:24px;background:#fff}
.phone--bare>img,.phone--bare>video{border:0;border-radius:0;background:none}
/* Scroll window: a 0.462 phone; the page inside is the whole image. */
.phone--scroll{aspect-ratio:.462;border:2px solid var(--ink);border-radius:24px;background:#fff;overflow:hidden}
.phone--scroll .ph-scroll{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;scrollbar-width:none;touch-action:pan-y;border-radius:22px}
.phone--scroll .ph-scroll::-webkit-scrollbar{display:none}
.ph-page{position:relative}
.ph-page img{width:100%;height:auto;aspect-ratio:var(--par)}
.ph-fade{position:absolute;left:0;right:0;bottom:0;height:56px;border-radius:0 0 22px 22px;background:linear-gradient(transparent,var(--fade,#fff));pointer-events:none;z-index:2;transition:opacity 200ms linear}
.phone.at-end .ph-fade,.phone.fits .ph-fade{opacity:0}

/* ── Pins: a child of the image box, in percent of the image ──────────── */
.pin{position:absolute;left:var(--l);top:var(--t);width:var(--w);height:var(--h);border:3px solid var(--ink);border-radius:6px;
  box-shadow:inset 0 0 0 2px #fff;z-index:3;pointer-events:none;transition:opacity 300ms linear}
.pin.rv{transform:none}
/* The badge sits outside the box, on the side the callouts are on. */
.pin::before{content:attr(data-n);position:absolute;top:50%;left:calc(100% + 14px);transform:translateY(-50%);width:32px;height:32px;border-radius:50%;
  background:var(--ink);color:var(--paper);font-family:var(--tight);font-size:20px;font-weight:600;line-height:32px;text-align:center}
.pin--l::before{left:auto;right:calc(100% + 14px)}
/* Inside a scroll window the badge sits above the box so the window never clips it. */
.ph-page .pin::before{top:auto;bottom:calc(100% + 8px);left:0;transform:none}
.pin--red{border-color:var(--red)}.pin--red::before{background:var(--red)}
.pin--blue{border-color:var(--blue)}.pin--blue::before{background:var(--blue)}
/* In a scroll window only the current pin stays: the previous one retires when the next is released. */
.is-in .m--2:not(.held) ~ .phone--scroll .pin[data-n="1"],.is-in .m--3:not(.held) ~ .phone--scroll .pin[data-n="2"],
.is-in .m--4:not(.held) ~ .phone--scroll .pin[data-n="3"]{opacity:0}
/* The last press of a pinned scene: the screen is seen whole. */
.is-in .m--whole:not(.held) ~ .phone .pin,.is-in .m--whole:not(.held) ~ .comp .pin{opacity:0}

/* ── Components: cut-outs at readable size ────────────────────────────── */
.comp{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.comp>img{width:100%;height:auto;aspect-ratio:var(--ar);border:1.5px solid var(--line);border-radius:12px;background:#fff}
.comp--bare>img{border:0;border-radius:0;background:none}

/* ── Callouts: the current one in ink, the ones already said in ink-2 ── */
.callouts{position:absolute;left:var(--x);top:var(--y);width:var(--w);display:flex;flex-direction:column;gap:28px}
.callouts li{display:grid;grid-template-columns:32px 1fr;gap:16px;align-items:start;font-size:22px;line-height:1.4;color:var(--ink);transition:color 300ms linear}
.callouts li .tab{transform:translateY(-1px)}
.callouts li.cap{grid-template-columns:1fr;color:var(--ink-2)}
/* A callout released on press k-1 carries data-step k; marker m--k fires on press k, one press later. */
.is-in .m--2:not(.held) ~ .callouts li[data-step="2"],.is-in .m--3:not(.held) ~ .callouts li[data-step="3"],
.is-in .m--4:not(.held) ~ .callouts li[data-step="4"],.is-in .m--5:not(.held) ~ .callouts li[data-step="5"],
.is-in .m--6:not(.held) ~ .callouts li[data-step="6"],.is-in .m--7:not(.held) ~ .callouts li[data-step="7"]{color:var(--ink-2)}
.captions{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.captions .caption+.caption{margin-top:20px}
.caption .tab{display:inline-grid;margin-right:12px;vertical-align:-7px}

/* ── Decisions and the spine ──────────────────────────────────────────── */
.dec{position:absolute;left:var(--safe-x);top:300px;width:900px}
.dec .label{display:flex;align-items:center;gap:14px;height:32px;color:var(--ink-2)}
.dec .label .date{margin-left:6px}
.dec .line{margin-top:22px;font-family:var(--tight);font-size:44px;font-weight:500;letter-spacing:-.015em;line-height:1.2;color:var(--ink)}
.dec .cost{margin-top:28px;font-size:24px;line-height:1.4;color:var(--ink-2)}
.spine{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.spine .head{margin-bottom:12px}
.spine li{display:flex;align-items:center;gap:14px;height:52px;border-top:1px solid var(--line);font-size:20px;color:var(--ink-2);transition:color 300ms linear}
.spine li:last-child{border-bottom:1px solid var(--line)}
.spine li.on{color:var(--ink)}
.spine li i{flex:1;height:8px;border-radius:4px;background:var(--panel)}
.spine li.on i{display:none}
.spine-full{position:absolute;left:var(--safe-x);top:160px;width:1368px}
.spine-full li{display:grid;grid-template-columns:32px 150px 1fr 1fr;gap:28px;align-items:center;height:120px;border-top:1px solid var(--line)}
.spine-full li:last-child{border-bottom:1px solid var(--line)}
.spine-full li b{font-family:var(--tight);font-size:32px;font-weight:500;letter-spacing:-.015em;line-height:1.15}
.spine-full li .cost{font-size:22px;line-height:1.4;color:var(--ink-2)}
.spine-full li .cost.rv{transform:none}

/* ── Gate ─────────────────────────────────────────────────────────────── */
#gate{position:fixed;inset:0;z-index:80;background:var(--paper);color:var(--ink);cursor:pointer;transition:opacity 260ms var(--ease-standard)}
#gate.gone{opacity:0;pointer-events:none}
.g-dots{overflow:visible}
.g-link{stroke:var(--ink);stroke-width:2;stroke-dasharray:6 8}
.g-dot{fill:var(--red);transform-box:fill-box;transform-origin:center}
.g-prompt{display:inline-flex;align-items:center;padding:12px 22px;border:2px solid var(--ink);border-radius:999px;font-size:20px;font-weight:500;
  transition:background 160ms linear,color 160ms linear}
#gate:hover .g-prompt,#gate:focus-visible .g-prompt{background:var(--ink);color:var(--paper)}
#gate:focus-visible{outline:none}
#gate.rolling .g-dot--1{animation:g-meet 540ms var(--ease-land) forwards}
#gate.rolling .g-dot--2{animation:g-meet-2 540ms var(--ease-land) forwards}
@keyframes g-meet{to{transform:translateX(150px)}}
@keyframes g-meet-2{to{transform:translateX(-150px)}}

/* ── Match day ────────────────────────────────────────────────────────── */
.ml-track{position:absolute;left:180px;top:300px;width:1152px;height:2px;background:var(--ink)}
.ml-tick{position:absolute;top:-8px;width:2px;height:18px;background:var(--ink)}
.ml-tick .label{position:absolute;top:-52px;left:50%;transform:translateX(-50%);white-space:nowrap;color:var(--ink);font-size:22px}
.ml-tick--live{width:14px;height:14px;top:-6px;margin-left:-6px;border-radius:50%}
.ml-tick--live .label{top:-54px}
.bubble{position:absolute;max-width:480px;padding:20px 28px;border-radius:26px 26px 26px 6px;background:var(--red);color:var(--paper);
  font-family:var(--tight);font-size:34px;font-weight:500;letter-spacing:-.01em;line-height:1.15;white-space:nowrap;
  transition:background 400ms linear,color 400ms linear,opacity 280ms var(--ease-standard),transform 320ms var(--ease-land)}
.bubble--r{border-radius:26px 26px 6px 26px}
.is-in .m--retire:not(.held) ~ .bubble{background:var(--panel);color:var(--ink-2)}
.ml-people .p{width:80px;height:80px;font-size:26px}
.ml-line{font-family:var(--tight);font-size:36px;font-weight:500;letter-spacing:-.015em;line-height:1.2}

/* ── A team ───────────────────────────────────────────────────────────── */
.game{position:absolute;left:72px;top:160px;width:1368px;height:700px}
.cluster b{position:absolute;left:var(--x);top:var(--y);width:28px;height:28px;border-radius:50%;background:var(--ink);
  transition:transform 900ms var(--ease-land),background 400ms linear,opacity 400ms linear}
.is-in .m--ring:not(.held) ~ .cluster--a b{transform:translate(var(--tx),var(--ty));background:var(--red)}
.cluster--ghost b{background:var(--panel)}
.game .ring{position:absolute;left:760px;top:120px;width:280px;height:280px;border-radius:50%;border:2px solid var(--red);opacity:0;
  transform:scale(.6);transition:opacity 400ms 500ms linear,transform 700ms 500ms var(--ease-land)}
.is-in .m--ring:not(.held) ~ .ring{opacity:1;transform:none}
.game .lab{position:absolute;font-size:24px;line-height:1.35;color:var(--ink)}
.game .lab--ring{left:700px;top:430px;width:400px;text-align:center;color:var(--red)}

/* ── The brief ────────────────────────────────────────────────────────── */
.goals{display:flex;gap:40px;font-size:26px;color:var(--ink-2)}
.illus{position:absolute;top:240px;width:300px}
.illus img{width:300px;height:238px;object-fit:contain}
.illus .caption{margin-top:12px;color:var(--ink);text-align:center}

/* ── Three bets ───────────────────────────────────────────────────────── */
.bet{position:absolute;top:740px;width:420px}
.bet .name{font-size:22px;color:var(--ink);line-height:1.35}
.bet .verdict{margin-top:8px;font-size:22px;line-height:1.35;color:var(--ink-2)}
.bet .verdict--red{color:var(--red)}

/* ── Statements ───────────────────────────────────────────────────────── */
.stack{position:absolute;left:var(--safe-x);right:var(--safe-x);top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:40px}
.stack--top{top:160px;transform:none}

/* ── We asked ─────────────────────────────────────────────────────────── */
.bignum{font-family:var(--tight);font-size:88px;font-weight:600;letter-spacing:-.03em;line-height:1;color:var(--ink)}
.board{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.board img{width:100%;height:auto;border:1.5px solid var(--line);border-radius:14px;background:#fff}

/* ── Personas ─────────────────────────────────────────────────────────── */
.axis{position:absolute;left:72px;top:160px;width:1368px;height:60px}
.axis .line{position:absolute;left:0;right:0;top:58px;height:2px;background:var(--ink)}
.axis .line::after{content:"";position:absolute;right:-2px;top:-7px;border:8px solid transparent;border-left:14px solid var(--ink);border-right:0}
.axis .label{position:absolute;top:10px}
.axis .label--r{right:0}
.persona{position:absolute;top:270px;width:250px}
.persona .p{width:96px;height:96px;font-size:30px;margin-bottom:22px}
.persona .who{font-family:var(--tight);font-size:28px;font-weight:500;letter-spacing:-.015em;line-height:1.15}
.persona .city{display:block;margin-top:4px;font-family:var(--sans);font-size:20px;color:var(--ink-2);letter-spacing:0}
.persona .does{margin:16px 0 14px;font-size:22px;color:var(--red)}
.persona .quote{font-size:22px;line-height:1.4;color:var(--ink-2)}
.axisrow{position:absolute;left:72px;top:340px;width:1368px;height:132px}
.axisrow .col{position:absolute;top:0;width:250px}
.axisrow .p{transition:transform 900ms var(--ease-land),opacity 400ms linear}
.axisrow .name{margin-top:16px;font-size:24px;color:var(--ink);transition:color 400ms linear}
.axisrow .base{position:absolute;left:0;right:0;top:130px;height:2px;background:var(--ink)}
.is-in .m--meet:not(.held) ~ .axisrow .col--k .p{transform:translateX(104px)}
.is-in .m--meet:not(.held) ~ .axisrow .col--n .p{transform:translateX(-104px)}
.is-in .m--meet:not(.held) ~ .axisrow .col--dim .p{opacity:.55}
.is-in .m--meet:not(.held) ~ .axisrow .col--dim .name{color:var(--ink-2)}
.scene[data-id="Turn two"] .statement{font-size:56px}

/* ── Bars, tiles, charts ──────────────────────────────────────────────── */
.bars{position:absolute;left:72px;top:160px;width:1368px}
.bar{display:grid;grid-template-columns:520px 1fr 120px;align-items:center;gap:24px;height:88px}
.bar.rv{transform:none}
.bar .bl{font-size:22px;line-height:1.2;color:var(--ink)}
.bar i{display:block;height:44px;width:calc(var(--v) * 100%);background:var(--ink);border-radius:4px;transform:scaleX(0);transform-origin:left;
  transition:transform 900ms var(--ease-decel),background 400ms linear}
.is-in .bar:not(.held) i{transform:scaleX(1)}
.bar b{font-family:var(--tight);font-size:40px;font-weight:500;letter-spacing:-.02em;text-align:right;transition:color 400ms linear}
.is-in .m--red:not(.held) ~ .bars .bar:first-child i{background:var(--red)}
.is-in .m--red:not(.held) ~ .bars .bar:first-child b{color:var(--red)}
.tile{position:absolute;left:var(--x);top:var(--y);width:var(--w);background:var(--panel);border-radius:16px;padding:24px 28px}
.tile .label{margin-bottom:12px}
.tile .num{font-size:64px}
.chart{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.chart .head{font-size:22px;line-height:1.3;color:var(--ink);height:60px}
.chart .row{display:grid;grid-template-columns:150px 1fr 110px;align-items:center;gap:20px;height:76px;position:relative}
.chart .row .bl{font-size:22px;color:var(--ink)}
.chart .row i{display:block;height:40px;width:calc(var(--v) * 100%);background:var(--ink);border-radius:4px;transform:scaleX(0);transform-origin:left;
  transition:transform 900ms var(--ease-decel)}
.chart--b .row i{background:var(--blue)}
.chart .row b{font-family:var(--tight);font-size:34px;font-weight:500;letter-spacing:-.02em;text-align:right}
.chart .row--ring::after{content:"";position:absolute;inset:-2px -12px;border:2px solid var(--red);border-radius:12px}
.is-in .chart:not(.held) .row i{transform:scaleX(1)}

/* ── The reset ────────────────────────────────────────────────────────── */
.wipe{position:absolute;left:var(--x);top:var(--y);width:var(--w);height:var(--h);overflow:hidden;border-radius:16px}
.wipe .under,.wipe .over{position:absolute;inset:0}
.wipe .over{clip-path:inset(0 100% 0 0);transition:clip-path 700ms var(--ease-decel)}
.wipe::after{content:"";position:absolute;top:0;bottom:0;left:0;width:2px;background:var(--red);opacity:0;transition:transform 700ms var(--ease-decel),opacity 100ms linear}
.is-in .m--wipe:not(.held) ~ .wipe .over{clip-path:inset(0 0 0 0)}
.is-in .m--wipe:not(.held) ~ .wipe::after{transform:translateX(calc(var(--w) - 2px));opacity:1}
.wipe .under{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:40px;background:var(--panel)}
.wipe .under .label{position:absolute;left:32px;top:28px}
.wipe .under .big{font-family:var(--tight);font-size:44px;font-weight:500;letter-spacing:-.02em;color:var(--ink);
  text-decoration:line-through;text-decoration-color:var(--red);text-decoration-thickness:3px}
.wipe .over img{width:100%;height:100%;object-fit:contain;background:#fff}

/* ── The squad ────────────────────────────────────────────────────────── */
.chip{padding:14px 16px;border:1.5px solid var(--ink);border-radius:12px;margin-top:12px;font-size:22px;line-height:1.3}
.chip .tag{margin-right:8px}
.chip--ship .tag{color:var(--blue)}.chip--park .tag{color:var(--red)}
.chip--park{border-style:dashed;color:var(--ink-2)}
.card{padding:28px 32px;border:2px solid var(--ink);border-radius:16px;background:#fff}
.card h3{font-family:var(--tight);font-size:28px;font-weight:500;letter-spacing:-.02em;margin:12px 0 18px}
.card dl{display:grid;grid-template-columns:150px 1fr;gap:12px 20px;font-size:20px;line-height:1.4}
.card dt{color:var(--red);padding-top:2px}
.byline{margin-top:16px}

/* ── Chapter card and rail ────────────────────────────────────────────── */
.rail--big li{display:flex;gap:18px;align-items:center;height:52px;border-top:1px solid var(--line);font-size:24px;color:var(--ink)}
.rail--big li:last-child{border-bottom:1px solid var(--line)}
.rail--big li .tab{background:none;border:1.5px solid var(--ink-2);color:var(--ink-2)}

/* ── Moments ──────────────────────────────────────────────────────────── */
.moments li{position:relative;padding-left:40px;margin-bottom:26px;font-size:22px;line-height:1.35;color:var(--ink-2);transition:color 300ms linear}
.moments li::before{content:"";position:absolute;left:0;top:8px;width:14px;height:14px;border-radius:50%;background:var(--ink-2);transition:background 300ms linear}
.moments li.on{color:var(--ink)}
.moments li.on::before{background:var(--blue)}

/* ── Scrub ────────────────────────────────────────────────────────────── */
.scrub{position:absolute;left:var(--x);top:var(--y);width:400px;height:50px}
.scrub .line{position:absolute;left:0;right:0;top:32px;height:2px;background:var(--ink)}
.scrub .tick{position:absolute;top:0;font-family:var(--mono);font-size:20px;font-weight:500;color:var(--ink);transition:color 300ms linear}
.scrub .tick--b{right:0;color:var(--ink-2)}
.scrub .playhead{position:absolute;left:-6px;top:26px;width:14px;height:14px;border-radius:50%;background:var(--red);transition:transform 600ms var(--ease-standard)}
.is-in .m--scrub:not(.held) ~ .scrub .playhead{transform:translateX(398px)}
.is-in .m--scrub:not(.held) ~ .scrub .tick--b{color:var(--ink)}
.is-in .m--scrub:not(.held) ~ .scrub .tick--a{color:var(--ink-2)}
.state{position:absolute;left:var(--x);top:var(--y);width:var(--w);transition:color 400ms linear}
.state .h{font-size:24px;line-height:1.35;color:var(--ink);transition:color 400ms linear}
.state .b{margin-top:10px;font-size:22px;line-height:1.4;color:var(--ink-2)}
.is-in .m--scrub:not(.held) ~ .state--a .h{color:var(--ink-2)}
.is-in .m--scrub:not(.held) ~ .discs .p--ghost{opacity:0}
.is-in .m--scrub:not(.held) ~ .discs .p--k{transform:translateX(4px)}
.is-in .m--scrub:not(.held) ~ .discs .p--n{transform:translateX(-4px)}

/* ── Pair ─────────────────────────────────────────────────────────────── */
.discs{position:absolute;display:flex;align-items:center;gap:10px}
.discs .p{transition:transform 900ms var(--ease-land),opacity 400ms linear}
.ringpair{display:inline-flex;padding:12px;border:2px solid var(--red);border-radius:999px;gap:6px}
.ringpair--ink{border-color:var(--ink)}
.vs{margin:0 14px;font-size:22px;color:var(--ink)}
.checks li{display:flex;gap:16px;align-items:baseline;padding:14px 0;border-top:1px solid var(--line);font-size:22px;line-height:1.4;color:var(--ink)}
.checks li:last-child{border-bottom:1px solid var(--line)}
.chk{flex:none;width:28px;height:28px;border-radius:6px;background:var(--ink);color:var(--paper);display:grid;place-items:center;font-size:20px;transform:translateY(4px)}

/* ── Closer ───────────────────────────────────────────────────────────── */
.scene--payne{background:var(--red)}
.c-ring{fill:none;stroke:var(--paper);stroke-width:2;stroke-dasharray:6 8}
.c-dot{fill:var(--paper);transform-box:fill-box;transform-origin:center;transition:transform 540ms 200ms var(--ease-land)}
.is-in .c-dot--1{transform:translateX(96px)}
.is-in .c-dot--2{transform:translateX(-96px)}
.closer{font-family:var(--tight);font-size:60px;font-weight:500;letter-spacing:-.03em;line-height:1.05;color:var(--paper)}
.closer--em{font-weight:600}
.scene--payne .rv{transform:none}
.scene--payne.is-in .rv{transition:opacity 900ms var(--ease-standard)}
.on-payne #counter,.on-payne #mute{color:rgba(247,245,240,.85)}

/* ── Appendix table ───────────────────────────────────────────────────── */
.tbl{position:absolute;left:72px;top:160px;width:1368px;border-collapse:collapse;font-size:22px}
.tbl th,.tbl td{text-align:left;padding:16px 12px;border-top:1px solid var(--line)}
.tbl th{font-weight:500;color:var(--ink-2)}
.tbl tr:last-child td{border-bottom:1px solid var(--line)}
.tbl td.n{font-family:var(--tight);font-size:28px;font-weight:500}

/* ── The portfolio's navigation, inside the deck ──────────────────────── */
#deckNav{position:fixed;top:0;left:0;right:0;z-index:60;transform:translateY(-100%);opacity:0;pointer-events:none;
  transition:transform 260ms var(--ease-decel),opacity 200ms linear}
#deckNav.on{transform:none;opacity:1;pointer-events:auto}
.dn-bar{display:flex;align-items:center;gap:24px;height:56px;padding:0 var(--safe-x);background:rgba(247,245,240,.9);backdrop-filter:blur(18px);border-bottom:1px solid var(--line)}
.dn-logo{display:grid;place-items:center;width:30px;height:30px;flex:none;border-radius:7px;background:var(--ink);color:var(--paper);font-size:13px;font-weight:600;text-decoration:none}
.dn-links{display:flex;align-items:center;gap:24px;margin-left:auto}
.dn-link{position:relative;background:none;border:0;padding:6px 2px;cursor:pointer;display:inline-flex;align-items:center;gap:6px;
  font-family:var(--sans);font-size:14px;font-weight:500;color:var(--ink-2);text-decoration:none;transition:color 160ms linear}
.dn-link:hover,.dn-link:focus-visible{color:var(--ink)}
.dn-link--back{color:var(--red)}
.dn-drop{position:relative}
.dn-menu{position:absolute;top:calc(100% + 12px);right:0;min-width:248px;display:flex;flex-direction:column;padding:8px;background:rgba(247,245,240,.98);
  backdrop-filter:blur(18px);border:1px solid var(--line);border-radius:12px;box-shadow:0 18px 44px rgba(20,20,26,.28)}
.dn-menu[hidden]{display:none}
.dn-menu a{padding:9px 12px;border-radius:8px;font-size:14px;color:var(--ink-2);text-decoration:none;white-space:nowrap;transition:background 140ms linear,color 140ms linear}
.dn-menu a:hover,.dn-menu a:focus-visible{background:rgba(20,20,26,.06);color:var(--ink)}
.dn-rule{height:1px;margin:6px 8px;background:var(--line)}

/* ── Chrome ───────────────────────────────────────────────────────────── */
#counter,#mute{transition:opacity 220ms var(--ease-standard);position:fixed;bottom:16px;z-index:40;
  padding:8px 14px;font-family:var(--sans);font-size:14px;font-weight:500;background:none;
  color:#6E6E78;border:0;opacity:0;pointer-events:none}
#counter{right:22px}
#mute{right:118px;cursor:pointer;padding:8px;line-height:0}
#overview{position:fixed;inset:0;z-index:60;background:rgba(20,20,26,.94);display:grid;place-items:center;padding:48px}
#overview[hidden]{display:none}
#ovGrid{display:grid;grid-template-columns:repeat(8,1fr);gap:16px;max-width:1280px;width:100%}
#ovGrid button{aspect-ratio:1512/982;border:2px solid transparent;border-radius:8px;background-size:contain;background-position:center;background-repeat:no-repeat;background-color:var(--paper);
  cursor:pointer;color:var(--ink);font-family:var(--sans);font-size:12px;font-weight:500;display:grid;place-items:end center;padding:5px;overflow:hidden}
#ovGrid button[aria-current="true"]{border-color:var(--red)}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{transition:none!important;animation:none!important}
  .ph-scroll{scroll-behavior:auto}
}

/* ═══════════════════════════════════════════════════════════════════════
   SOCIAL GAMEPLAY LITE — v2 design layer
   Retunes the concise deck to the 1920x1080 Figma language: 88px margins,
   larger type, tinted tiles, verdict boxes, step cards, chips.
   Appended so every component rule above still applies; these win on
   cascade order, not on specificity hacks.
   ═══════════════════════════════════════════════════════════════════ */
:root{
  --safe-x:88px;
  --panel:#ECE8DF;
  --green:#2E7D4F; --green-bg:#CFE6D2;
  --red-bg:#F6D9DE;
  --ink-3:#6A6A72;
  --tight:'Inter',system-ui,sans-serif;
}
.canvas{width:1920px;height:1080px}

/* ── Type, retuned for a 1920 canvas ─────────────────────────────────── */
.title{top:130px;max-width:1744px;font-size:58px;font-weight:600;letter-spacing:-.022em;line-height:1.16}
.title--sm{font-size:48px}
.display{font-size:118px;letter-spacing:-.035em;line-height:1.02}
.display--chapter{font-size:88px;line-height:1.04}
.lede{font-size:26px;line-height:1.5}
.body{font-size:22px;line-height:1.48}
.label{font-size:20px}

/* Eyebrow: the red kicker that sits above every title */
.eyebrow{position:absolute;left:var(--safe-x);top:88px;
  font-size:20px;font-weight:600;color:var(--red);letter-spacing:0}
.eyebrow--muted{color:var(--ink-3)}
.eyebrow--pale{color:#F4C3CB}

/* Micro label used inside tiles and column heads */
.micro{font-size:15px;font-weight:600;letter-spacing:.10em;text-transform:uppercase;color:var(--red)}
.micro--muted{color:var(--ink-3)}

/* ── Tinted information tile ─────────────────────────────────────────── */
.tile{position:absolute;left:var(--x);top:var(--y);width:var(--w);
  background:var(--panel);border-radius:16px;padding:30px}
.tile .micro{display:block;margin-bottom:10px}
.tile p{font-size:22px;line-height:1.48;color:var(--ink)}

/* ── Verdict box: the pass/fail judgement on a column ────────────────── */
.verdict{border-radius:12px;padding:22px 24px;font-size:21px;line-height:1.45}
.verdict--bad{background:var(--red-bg);color:var(--ink)}
.verdict--ok{background:var(--panel);color:var(--ink)}
.verdict--good{background:var(--green-bg);color:var(--ink)}
.verdict b{font-weight:600}

/* ── Column with a red head and a rule, used for FEED / CHAT / WINNERS ── */
.col{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.col > h3{font-size:22px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--red);padding-bottom:12px;border-bottom:2px solid var(--ink);margin-bottom:24px}
.col ul{list-style:none;margin:20px 0 0}
.col li{position:relative;padding-left:26px;margin-bottom:14px;font-size:20px;line-height:1.45}
.col li::before{content:"";position:absolute;left:0;top:.55em;width:9px;height:9px;border-radius:50%;background:var(--ink)}
.col li.neg::before{background:var(--red)}
.col li.pos::before{background:var(--green)}

/* ── Numbered step card, for the four-step explainer ─────────────────── */
.step{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.step .n{display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:9px;background:var(--ink);color:var(--paper);
  font-size:17px;font-weight:600;margin-bottom:14px}
.step p{font-size:21px;line-height:1.4;color:var(--ink)}
.step.is-dim{opacity:.32}
.step{transition:opacity 420ms var(--ease-standard)}

/* ── Process chips ───────────────────────────────────────────────────── */
.chips{position:absolute;left:var(--x);top:var(--y);display:flex;align-items:center;gap:18px}
.chip{background:var(--panel);color:var(--ink);border-radius:30px;padding:14px 30px;
  font-size:26px;font-weight:600;white-space:nowrap}
.chip--on{background:var(--ink);color:var(--paper)}
.chips .sep{width:44px;height:1.5px;background:#9E9B92;flex:none}

/* ── Dark mandate block ──────────────────────────────────────────────── */
.mandate{position:absolute;left:var(--x);top:var(--y);width:var(--w);
  background:var(--ink);border-radius:20px;padding:38px}
.mandate .k{font-size:24px;color:#C9C7CE;margin-bottom:14px}
.mandate .v{font-size:34px;font-weight:600;line-height:1.3;color:var(--paper)}

/* ── Big statistic ───────────────────────────────────────────────────── */
.stat{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.stat b{display:block;font-size:80px;font-weight:600;letter-spacing:-.03em;line-height:1;color:var(--ink)}
.stat span{display:block;margin-top:14px;font-size:21px;line-height:1.5;color:var(--ink-2)}
.stat--red b{color:var(--red)}

/* ── Full-bleed dark scene, for the 91% turn ─────────────────────────── */
.scene--dark{background:var(--ink)}
.scene--dark .title,.scene--dark .display,.scene--dark .lede,.scene--dark .body{color:var(--paper)}
.scene--dark .lede,.scene--dark .body{color:#C9C7CE}
.on-dark #counter,.on-dark #mute{color:rgba(247,245,240,.66)}
.huge{position:absolute;left:var(--x);top:var(--y);
  font-size:300px;font-weight:600;letter-spacing:-.04em;line-height:.9;color:var(--paper)}

/* ── Red act break ───────────────────────────────────────────────────── */
.scene--break{background:var(--red)}
.scene--break .display,.scene--break .title{color:var(--paper)}
.scene--break .lede{color:#FADDE2}
.on-break #counter,.on-break #mute{color:rgba(247,245,240,.85)}

/* ── Rule accent ─────────────────────────────────────────────────────── */
.accent{position:absolute;left:var(--x);top:var(--y);width:5px;height:var(--h);
  background:var(--red);border-radius:3px}

/* ── Tap-to-enlarge affordance on device shots ───────────────────────── */
.phone.zoomable,.comp.zoomable{cursor:zoom-in}
.phone.zoomable::after,.comp.zoomable::after{content:"";position:absolute;inset:0;
  border-radius:inherit;box-shadow:0 0 0 0 rgba(20,20,26,0);transition:box-shadow 160ms var(--ease-standard)}
.phone.zoomable:hover::after,.comp.zoomable:hover::after{box-shadow:0 0 0 3px rgba(20,20,26,.22)}
.tile b{display:block;font-size:52px;font-weight:600;line-height:1.05;letter-spacing:-.02em;color:var(--ink)}
.tile .micro{margin-bottom:8px}
.steprow .step p{min-height:58px}

/* ── Click to enlarge a device screen ────────────────────────────────── */
.zoomwrap{position:fixed;inset:0;z-index:120;display:grid;place-items:center;
  background:rgba(20,20,26,.72);opacity:0;transition:opacity 200ms var(--ease-standard);padding:48px}
.zoomwrap.on{opacity:1}
.zoomwrap img{max-width:min(90vw,860px);max-height:90vh;border-radius:22px;
  box-shadow:0 30px 90px rgba(0,0,0,.45);background:#fff}
.zoomclose{position:absolute;top:28px;right:28px;width:48px;height:48px;border:0;border-radius:50%;
  background:var(--paper);color:var(--ink);font-size:18px;line-height:1;cursor:pointer}
.zoomclose:focus-visible{outline:2px solid var(--red);outline-offset:3px}
.zoomable:focus-visible{outline:2px solid var(--red);outline-offset:4px}
@media (prefers-reduced-motion: reduce){ .zoomwrap{transition:none} }

/* ── Device frames: 16px radius, hairline border, soft shadow ─────────
   This matches the frames in the Figma design and is deliberate. ───── */
.phone>img,.phone>video{border:1px solid rgba(20,20,26,.14);border-radius:16px;
  box-shadow:0 18px 44px rgba(20,20,26,.16),0 2px 6px rgba(20,20,26,.08)}
.phone--scroll{border:1px solid rgba(20,20,26,.14);border-radius:16px;
  box-shadow:0 18px 44px rgba(20,20,26,.16),0 2px 6px rgba(20,20,26,.08)}
.phone--scroll .ph-scroll{border-radius:15px}
.comp>img{border:1px solid rgba(20,20,26,.14);border-radius:16px;
  box-shadow:0 18px 44px rgba(20,20,26,.16),0 2px 6px rgba(20,20,26,.08)}
.phone--bare>img,.comp--bare>img{border:0;border-radius:0;box-shadow:none}

/* ── Value-first tile, as drawn in the design: number then label ────── */
.tile--v{padding:22px 24px;border-radius:14px}
.tile--v b{display:block;font-size:42px;font-weight:600;line-height:1.08;letter-spacing:-.02em;color:var(--ink)}
.tile--v span{display:block;margin-top:14px;font-size:16px;font-weight:400;line-height:1.35;color:var(--ink-2)}

/* ── Compact paired bar chart ────────────────────────────────────────── */
.minibars{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.minibars h4{font-size:19px;font-weight:500;color:var(--ink-2);margin-bottom:22px}
.minibar{display:grid;grid-template-columns:118px 1fr 84px;align-items:center;gap:18px;height:58px}
.minibar span{font-size:19px;color:var(--ink)}
.minibar i{display:block;height:26px;width:calc(var(--v)*100%);background:var(--ink);border-radius:4px}
.minibar--alt i{background:var(--blue)}
.minibar b{font-size:26px;font-weight:600;text-align:right;letter-spacing:-.01em}

/* ── Quiet sequence label, replacing the process chips ───────────────── */
.seq{position:absolute;left:var(--x);top:var(--y);
  font-size:15px;font-weight:600;letter-spacing:.10em;text-transform:uppercase;color:var(--red)}

/* h1 and h4 were missing from the reset on line 44, so their default
   margins were displacing absolutely positioned elements: an h1 at 118px
   carries a 0.67em top margin, which pushed the cover headline 79px down
   into its own lead. */
h1,h4{margin:0}
.minibars h4{margin:0 0 22px}

/* ── Archetype column: the five stay five; grouping is shown beneath ─── */
.arch{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.arch .av{width:72px;height:72px;border-radius:50%;background:var(--red);color:var(--paper);
  display:flex;align-items:center;justify-content:center;font-size:26px;font-weight:600;
  letter-spacing:-.01em;margin-bottom:22px}
.arch .nm{font-size:26px;font-weight:600;line-height:1.2;color:var(--ink)}
.arch .ct{font-size:18px;line-height:1.3;color:var(--ink-3);margin-top:5px}
.arch .rl{font-size:18px;font-weight:600;line-height:1.3;color:var(--red);margin-top:14px}
.arch .qt{font-size:20px;line-height:1.48;color:var(--ink-2);margin-top:14px}
/* the grouping band */
.gband{position:absolute;left:var(--x);top:var(--y);width:var(--w)}
.gband i{display:block;height:2px;background:var(--ink)}
.gband--aside i{background:#C6C2B7}
.gband .gl{display:block;margin-top:18px;font-size:15px;font-weight:600;letter-spacing:.10em;
  text-transform:uppercase;color:var(--red)}
.gband--aside .gl{color:var(--ink-3)}
.gband p{margin-top:12px;font-size:20px;line-height:1.48;color:var(--ink-2)}

/* ── Cover meta, from node 932:5079 ───────────────────────────────────── */
.cv-label{margin:0;font-size:22px;font-weight:500;line-height:1.22;letter-spacing:.08em;
  text-transform:uppercase;color:#6A6A72}
.cv-value{margin:12px 0 0;font-size:25px;font-weight:500;line-height:135%;color:#000;
  /* Figma's boxes are fixed width and let the value run past them; without
     this the browser wraps 'Design Lead' and the date onto two lines. */
  white-space:nowrap}

/* ── Social Gameplay: roles taken from the source deck ────────────────── */
.sg-eyebrow{margin:0;font-size:20px;font-weight:600;line-height:1.2;color:#14141A}
.sg-h1{margin:0;font-weight:700;letter-spacing:-.01em;color:#14141A}
/* eyebrow and title are one block, and the block reproduces the spacing in
   the source file: a 24px eyebrow box from y88, then 18px, so the title box
   opens at y130 on every slide no matter what size the title is set in. */
.sg-head > .sg-h1{margin-top:18px;line-height:118%}
.sg-h2{margin:0;font-size:32px;font-weight:600;line-height:1.22;color:#14141A}
/* Slide 04 sets a 32px label at x0 against a 22px body at x274 inside one row,
   which is the two-column figure the source uses four times down that slide.
   The body style is also used on its own elsewhere, so the indent belongs to
   the row, not to the body. */
/* No position here: .at is already absolute, which is the containing block
   the label needs. Declaring position:relative on .sg-row overrode .at at
   equal specificity, dropped all four rows into normal flow, and pushed the
   last one 261px down the slide. */
.sg-rl{margin:0;font-size:32px;font-weight:600;line-height:1.22;color:#14141A;
  position:absolute;left:0;top:0;width:234px}
.sg-row .sg-rb{margin-left:274px}
.sg-rb{margin:0;font-size:22px;line-height:148%;color:#14141A;font-weight:400}
.sg-rb b{font-weight:600}
.sg-rule{display:block;height:1px;background:#C9C9C9}
.sg-card{background:#fff;border:1px solid #A3A3A3;border-radius:16px}
.sg-tenet-h{margin:0;font-size:22px;font-weight:700;line-height:148%;text-align:center;color:#14141A}
.sg-tenet-b{margin:0;font-size:18px;font-weight:400;line-height:150%;text-align:center;color:var(--ink-2)}

/* Slide 09 is the deck's one dark statement; the ground is the source's own
   ink, not the paper. */
.scene--ink{background:#14141A}

/* Slide 10's white tiles and the number/label pair inside them. */
.sg-tile{background:#fff;border-radius:12px}
.sg-tile-h{margin:0;font-size:20px;font-weight:600;line-height:1.2;color:#14141A}
.sg-fig{margin:0;color:#14141A}
.sg-fig b{display:block;font-size:52px;font-weight:600;line-height:1.21}
/* A figure's label is a hug box in the source: it sits on one line. */
.sg-fig span{display:block;margin-top:8px;font-size:20px;font-weight:400;line-height:148%;white-space:nowrap}
.sg-q{margin:0;font-size:22px;font-weight:700;font-style:italic;line-height:148%;color:#14141A}
.sg-ql{margin:0;font-size:20px;font-weight:400;line-height:148%;color:#14141A}

/* stat card, slide 02 — white plate, figure over label */
.sg-stat{background:#fff;border-radius:14px;padding:22px 20px;margin:0}
.sg-stat b{display:block;font-size:42px;font-weight:600;line-height:1.21;color:#14141A}
.sg-stat span{display:block;margin-top:8px;font-size:20px;font-weight:400;line-height:135%;color:#4A4B55}

/* numbered step, slide 03 — badge then the line it labels */
/* no position here: .at already makes this box the positioning parent. */
.sg-step{margin:0;padding-left:46px;font-size:20px;font-weight:400;line-height:145%;color:#14141A}
.sg-step b{position:absolute;left:0;top:0;display:grid;place-items:center;width:30px;height:30px;
  border-radius:8px;background:#14141A;color:#fff;font-size:15px;font-weight:600;line-height:1}

/* verdict panel, slides 06 to 08 — a mark, a heading, then the plain list */
.sg-vh{margin:0;padding-left:70px;min-height:58px;display:flex;align-items:center;
  font-size:22px;font-weight:700;line-height:148%;color:#14141A}
.sg-vh svg{position:absolute;left:0;top:0;width:58px;height:58px}
.sg-li{margin:0;font-size:22px;font-weight:400;line-height:148%;color:#14141A}
.sg-out{margin:0;font-size:32px;font-weight:500;color:#14141A}

/* archetype column, slide 11 — round portrait over name and voice */
.sg-arch-n{margin:0;font-size:24px;font-weight:600;line-height:130%;color:#14141A}
.sg-arch-q{margin:0;font-size:20px;font-weight:400;line-height:148%;color:#4A4B55}
/* the collaborative-to-competitive spectrum */
.sg-band{margin:0;font-size:32px;font-weight:600;line-height:1.22;color:#14141A}
.sg-bandb{margin:0;font-size:20px;font-weight:400;line-height:148%;color:#4A4B55}
.sg-dot{display:block;width:15px;height:15px;border-radius:50%;background:#14141A}
.sg-seg{display:block;height:6px;background:#14141A}

/* process pipeline, slide 13 — pills the arrows run between */
.sg-pill{display:flex;align-items:center;justify-content:center;text-align:center;margin:0;
  padding:0 24px;border-radius:50px;background:#D9D9D9;
  font-size:17px;font-weight:600;line-height:148%;color:#14141A}
.sg-arrow{display:block;overflow:visible}
.sg-arrow path{stroke:#14141A;stroke-width:1.5;fill:none}
/* scored criterion: name on the left, what it means on the right */
.sg-crit{margin:0;font-size:32px;font-weight:600;line-height:1.22;color:#14141A}
.sg-critb{margin:0;font-size:22px;font-weight:400;line-height:148%;color:#14141A}

/* caption under a screen. These are hug boxes in the source, so the only
   breaks are the authored ones. */
.sg-cap{margin:0;font-size:20px;font-weight:600;line-height:28px;color:#14141A;white-space:nowrap}
/* margin note pointing at a detail on the screen */
.sg-note{margin:0;font-size:18px;font-weight:500;line-height:1.22;color:#575757}
.sg-mark{display:block;border:1.5px solid #000}

/* ── Focus groups: the click moves attention, it does not add content ────
   A group holds a frame and everything that belongs to it (its caption, its
   rule, its arrow, its note). The zero-size step markers app.js already
   toggles drive which group is lit; focus.js keeps the videos in step. */
/* The group keeps a (no-op) filter and its own layer while lit, so lighting
   it never creates or drops a compositing layer: that switch is the
   one-frame flash some GPUs show when blur is applied to a large frame. */
.fg{filter:blur(0) saturate(1);will-change:opacity,filter}
/* The deck cuts to a slide in the same frame it applies that slide's held
   state, and is-in lands two frames later. A group must therefore change
   state instantly on entry and animate only once the scene is in, or the
   lit-to-dim change plays out on screen right after the cut. */
.is-in .fg{transition:opacity 300ms var(--ease-standard),filter 300ms var(--ease-standard)}
.fg--2,.fg--3{opacity:.12;filter:saturate(.22) blur(7px)}
.m--2:not(.held) ~ .fg--2{opacity:1;filter:none}
.m--3:not(.held) ~ .fg--3{opacity:1;filter:none}
.m--2:not(.held) ~ .fg--1{opacity:.12;filter:saturate(.22) blur(7px)}
.m--3:not(.held) ~ .fg--2{opacity:.12;filter:saturate(.22) blur(7px)}
@media (prefers-reduced-motion:reduce){ .fg{transition:none} }

/* ── Bulleted lists ──────────────────────────────────────────────────────
   The box sits at the bullet, and the text is indented past it, so one
   element carries both and lands on the source coordinate. */
.sg-bul{margin:0;padding-left:19px;font-size:20px;font-weight:400;line-height:150%;color:#14141A}
.sg-bul::before{content:'\2022';position:absolute;left:0;top:4px;
  font-size:18px;line-height:22px;color:#14141A}
.sg-bul b{font-weight:700}
/* a list heading is a hug box in the source: it sits on one line. */
.sg-listh{margin:0;font-size:24px;font-weight:700;line-height:130%;color:#14141A;white-space:nowrap}
/* the plate some of those lists sit on */
.sg-plate{display:block;background:#fff;border:1px solid #E5E7EB;border-radius:16px}

/* ── Strike-through as a beat, not as typography ─────────────────────────
   A word is set, then a rule is drawn across it, then the replacement
   arrives. The line is an element so it can be timed; text-decoration
   cannot be animated. */
.sg-strike{position:relative;white-space:nowrap}
.sg-strike::after{content:'';position:absolute;left:-.02em;right:-.02em;top:.52em;
  height:.058em;background:currentColor;transform:scaleX(0);transform-origin:left center;
  transition:transform 460ms cubic-bezier(.22,.61,.36,1)}
.m--strike:not(.held) ~ * .sg-strike::after{transform:scaleX(1)}
@media (prefers-reduced-motion:reduce){ .sg-strike::after{transition:none} }

/* ── Archetype column: icon, name and voice share one centre ───────────── */
.sg-arch-n,.sg-arch-q{text-align:center}

/* ── The research statement, set as one centred block ──────────────────── */
.sg-centre{display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;gap:var(--gap,40px)}

/* Something that was true and is not any more: it is set, struck, then it
   leaves as its replacement arrives. */
.sg-was{transition:opacity 340ms var(--ease-standard)}
.m--gone:not(.held) ~ .sg-was{opacity:0}


/* ── Arrows, as drawn in the file ───────────────────────────────────────
   Dashed 8/8, two pixels, an open V head, and a filled dot at the tail on
   the flow arrows. The wrapper sits on the exact coordinate and the svg is
   hung off it, so the line lands on the source's y and the head can
   overhang without moving the anchor. */
.sg-arw{display:block;height:0}
.sg-arw svg{position:absolute;overflow:visible}
.sg-arw path{fill:none;stroke-width:2;stroke-dasharray:8 8;stroke-linecap:butt;stroke-linejoin:round}
.sg-arw .hd{fill:none;stroke-width:2;stroke-dasharray:none;stroke-linecap:round;stroke-linejoin:round}
.sg-arw .dot{stroke:none}

/* ── The centre screen arrives from the left ────────────────────────────
   Across both series the centre screen is the constant: it is what the
   previous slide was looking at, so it travels in from where it was and
   the callouts land on it afterwards. */
.sg-enter{transform:translateX(-300px);opacity:0;
  transition:transform 620ms var(--ease-land),opacity 420ms var(--ease-standard)}
.is-in .sg-enter{transform:none;opacity:1}
@media (prefers-reduced-motion:reduce){ .sg-enter{transition:none} }

/* ── The stage is a fixed pane ───────────────────────────────────────────
   Scenes stack inside it and app.js translates it. The document itself
   never scrolls, which is what makes fullscreen safe: requestFullscreen on
   the root makes the root the fullscreen element, and a fullscreen root
   does not scroll, so a deck that moved by scrollTo pinned on slide one the
   moment the presenter went fullscreen. */
html,body{overflow:hidden;height:100%}
#stage{position:fixed;left:0;top:0;width:100%;will-change:transform}

/* Screen caption, at the spec the file now carries. */
.sg-cap{font-size:20px;font-weight:500;line-height:1.24;color:#6A6A72;white-space:nowrap}
/* A scene steps back as smoothly as it steps forward: the entrance settles
   from whichever side, and stepping back re-arms it. */
.sg-enter{transform:translateX(-220px)}

/* ── Slide 14: the three failures convert into the ecosystem ─────────────
   They do not vanish and get replaced. Struck, they pull inward to the
   region the map will occupy, shrink and dim to a single mass, and the map
   resolves out of them. The card lands first so the map has a surface to
   arrive on rather than appearing over bare ground, and the words only
   reach zero once the map is past halfway, so the shared region never
   carries two dark images at full strength. */
.sg-was{transform-origin:center}
.m--gone:not(.held) ~ .sg-w1{animation:sg-cv1 860ms cubic-bezier(.4,0,.2,1) 120ms forwards}
.m--gone:not(.held) ~ .sg-w2{animation:sg-cv2 860ms cubic-bezier(.4,0,.2,1)  60ms forwards}
.m--gone:not(.held) ~ .sg-w3{animation:sg-cv3 860ms cubic-bezier(.4,0,.2,1)    0s forwards}
@keyframes sg-cv1{0%{opacity:1;transform:none}72%{opacity:.16}100%{opacity:0;transform:translate(180px,190px) scale(.72)}}
@keyframes sg-cv2{0%{opacity:1;transform:none}72%{opacity:.16}100%{opacity:0;transform:translate(180px,76px)  scale(.72)}}
@keyframes sg-cv3{0%{opacity:1;transform:none}72%{opacity:.16}100%{opacity:0;transform:translate(180px,-38px) scale(.72)}}
/* the card lands under the map */
.is-in .rv.sg-plate--land{transition:opacity 420ms cubic-bezier(.22,.61,.36,1) 180ms,
                                     transform 420ms cubic-bezier(.22,.61,.36,1) 180ms}
.sg-plate--land{transform:scale(.985);transform-origin:center}
.is-in .rv.sg-plate--land{transform:none}
.is-in .rv.sg-map {transition:opacity 560ms cubic-bezier(.22,.61,.36,1) 300ms}
.is-in .rv.sg-badge{transition:opacity 300ms cubic-bezier(.22,.61,.36,1) 600ms}
@media (prefers-reduced-motion:reduce){
  .m--gone:not(.held) ~ .sg-was{animation:none;opacity:0}
  .is-in .rv.sg-plate--land,.is-in .rv.sg-map,.is-in .rv.sg-badge{transition:none}
  .sg-plate--land{transform:none}
}

/* ── Slide 14: the struck words hand over to the map ─────────────────────
   One cross. The words leave while the card and map arrive, overlapping
   just enough that the region is never empty and never doubled. */
.sg-was{transition:opacity 520ms var(--ease-standard)}
.m--gone:not(.held) ~ .sg-was{opacity:0}
.is-in .rv.sg-fadein{transition:opacity 560ms var(--ease-standard) 140ms}
@media (prefers-reduced-motion:reduce){
  .sg-was,.is-in .rv.sg-fadein{transition:none}
}



/* ── One screen carried across slides ───────────────────────────────────
   The deck cuts between scenes, but the phone in the middle is the same
   object in the talk. So on arrival it starts at the position and size it
   held on the slide before and travels to its own. The cut is instant and
   the picture identical, so the eye reads one object moving rather than
   two slides. --dx/--dy/--ds are the delta from the previous slide. */
.sg-glide{transform:translate(var(--dx,0px),var(--dy,0px)) scale(var(--ds,1));
  transform-origin:top left;
  transition:transform 640ms var(--ease-land)}
.is-in .sg-glide{transform:none}

/* Where the frame does not move, the screen turns over instead: same place,
   new content. */
.sg-flip{transform:perspective(1600px) rotateY(-12deg);opacity:.001;
  transform-origin:center;
  transition:transform 560ms var(--ease-land),opacity 300ms var(--ease-standard)}
.is-in .sg-flip{transform:none;opacity:1}

/* Slide 14 hands over as a reveal: the map wipes in from the left over the
   ground the struck words are leaving. */
.sg-reveal{clip-path:inset(0 100% 0 0 round 16px);
  transition:clip-path 700ms cubic-bezier(.22,.61,.36,1) 120ms}
.is-in .rv.sg-reveal{clip-path:inset(0 0 0 0 round 16px)}

@media (prefers-reduced-motion:reduce){
  .sg-glide,.sg-flip,.sg-reveal{transition:none}
  .sg-flip{transform:none;opacity:1}
  .sg-reveal{clip-path:none}
}

/* ── One shadow, everywhere ──────────────────────────────────────────────
   Every frame in the deck sits on the same shadow. The per-node values the
   file carries differ by fractions of a pixel and reading them individually
   only made the deck look inconsistent. */
.sh-a,.sh-b,.sh-c,.sh-d,.sh-e,.sh-f,.sh-g,.sh-h,.sh-i,.sh-j{
  box-shadow:0 4.14px 12.421px 0 rgba(0,0,0,.15)}

/* ── The flight layer ────────────────────────────────────────────────────
   Lives on the body, outside #stage: .scene is overflow:hidden and the
   canvas is scaled, so a shared element can only cross a cut from here.
   The shell is sized in artboard pixels and scaled whole, so cloned
   shadows and radii render at the scale they were authored at. */
#flight{position:fixed;inset:0;pointer-events:none;z-index:60;contain:layout style}
.hero-flyer{position:absolute;left:0;top:0;transform-origin:0 0;will-change:transform}
.hero-flyer > *{display:block}
/* The destination waits, by visibility not opacity: .rv already owns
   opacity and flips it with no transition, so the two would fight. */
.hero-hold{visibility:hidden}

/* Callouts that belong to a screen land the moment the screen does, rather
   than costing a second press. */
.af{opacity:0}
.is-in .af{animation:af-in 1ms linear 540ms forwards}
@keyframes af-in{to{opacity:1}}
@media (prefers-reduced-motion:reduce){ .af{opacity:1} .is-in .af{animation:none} }


/* ---- Asset unit scaling -----------------------------------------------
   Slides that show design work scale the whole unit to use the vertical
   space the layout leaves above and below it. One transform on the group
   means every coordinate, arrow, caption and corner radius inside keeps
   exactly the relationship the Figma file drew. Nothing is re-measured,
   so nothing can drift. The header stays outside the group and holds its
   position. --f is the scale, --ox/--oy the unit's own centre, --dy the
   nudge that re-centres it in the band between header and slide number. */
.unit{position:absolute;left:0;top:0;width:1920px;height:1080px;
  transform-origin:var(--ox) var(--oy);
  transform:translate(var(--dx,0px),var(--dy)) scale(var(--f))}

/* ---- Gentler turnover on the Groups chapter ---------------------------
   Everywhere else a step cuts, which is right when the whole screen
   changes. Slides 18 to 27 hold one phone still and swap the explanation
   around it, and a cut there reads as a flicker. These cross-fade instead.
   The rest of the deck is untouched. */
.scene--soft.is-in .rv{transition:opacity 300ms var(--ease-standard)}
.scene--soft.is-in .rv.held{transition:opacity 220ms var(--ease-standard)}
.scene--soft.is-in .af{animation:af-soft 320ms var(--ease-standard) 480ms forwards}
@keyframes af-soft{from{opacity:0}to{opacity:1}}
.scene--soft.is-in .fg{transition:opacity 380ms var(--ease-standard),filter 380ms var(--ease-standard)}
/* entry frame: focus.js sets no-fx while the slide's held state lands */
.scene.no-fx .fg,.scene.no-fx .rv{transition:none!important}

/* ---- Audio control --------------------------------------------------- */
#mute svg{width:22px;height:22px;display:block}
#mute .spk{fill:currentColor;stroke:currentColor;stroke-width:1.6;stroke-linejoin:round}
#mute .wav path,#mute .x{fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
#mute .x{opacity:0}
#mute[aria-pressed="true"] .wav{opacity:0}
#mute[aria-pressed="true"] .x{opacity:1}

@media (prefers-reduced-motion:reduce){
  .scene--soft.is-in .rv,.scene--soft.is-in .rv.held,.scene--soft .fg{transition:none}
  .scene--soft.is-in .af{animation:none;opacity:1}
  .fg--2,.fg--3{filter:saturate(.25)}
}


/* ---- Borrowed DreamPlay slides ---------------------------------------
   The slide itself renders in a frame that carries DreamPlay's own
   stylesheet, because both decks use .scene, .rv and #stage and would
   otherwise repaint each other. The proxy scene behind it only holds the
   place in the running order, so it is plain dark ground. */
.scene--dp{background:#0B0B0F}
#dpFrame{position:fixed;inset:0;width:100%;height:100%;border:0;z-index:5;
  background:#0B0B0F;opacity:0;visibility:hidden;pointer-events:none}
#dpFrame.on{opacity:1;visibility:visible}

/* The closing summary carries four figures and one card, which is light for a
   full board. The cards take more room so the slide reads as composed rather
   than parked at the top. */
.sg-stat--lg{padding:32px 28px}
.sg-stat--lg b{font-size:56px}
.sg-stat--lg span{margin-top:12px;font-size:21px}

/* The handover into DreamPlay. It borrows that product's ground, signal colour
   and wordmark so the room has already changed worlds before the first
   DreamPlay slide arrives. */
.scene--dpintro{background:#000}

/* The page number and audio control answer to the same hover as the nav bar.
   They are chrome, so they stay out of the slide until asked for. */
body.chrome-on #counter{opacity:1}
body.chrome-on #mute{opacity:1;pointer-events:auto}

/* ── Zoom (js/deck-zoom.js) ──────────────────────────────────────────────
   A lifted member carries one rigid transform. Dimming is a filter on the
   siblings along the member's ancestor path, so it works under any
   stacking context and is not undone by an opacity animation. */
.cz-mem{z-index:5;transform-origin:0 0;transition:transform 380ms var(--ease-standard)}
.cz-mem:not(.at){position:relative}
.cz-out{z-index:4}
.cz-path{z-index:5!important;filter:none!important;opacity:1!important;will-change:auto!important}
.cz-dim{filter:blur(7px) opacity(.08)!important;transition:filter 380ms var(--ease-standard)}
.scene.cz-can img{cursor:zoom-in}
.cz-mem img,img.cz-mem{cursor:zoom-out}
@media (prefers-reduced-motion:reduce){.cz-mem,.cz-dim{transition:none}}
