/* The story: two scenes that play as the reader scrolls (Kyle, October 18:
   "show don't tell", obvious within 2–3 scrolls). 01 the problem, 02 the work.
   Without JavaScript, or with reduced motion, the scenes are still frames,
   one after another, with every caption showing. story.js adds .story-live to
   pin one stage and scrub it with the scrollbar. What's next follows the
   episode tiles as its own section; only its checkout card moves. */
:root{
  /* Plain numbers read by story.js. Beat lengths are viewports of scrolling;
     the rest are points in a beat's own progress (0..1). */
  --cb-story-beat-1:1;
  --cb-story-beat-2:1.1;
  /* A rest stop after each scene: viewports of scrolling that hold its last
     frame, so a small overshoot never spills into the next scene. */
  --cb-story-hold:.35;
  --cb-story-crossfade:.14;
  /* 01 The problem: the brief first, then the inventory. */
  --cb-story-type-start:.05;
  --cb-story-type-end:.3;
  --cb-story-chips-start:.3;
  --cb-story-chips-end:.38;
  --cb-story-focus-start:.42;
  --cb-story-focus-end:.48;
  --cb-story-trap-start:.5;
  --cb-story-trap-end:.62;
  --cb-story-fit-start:.7;
  --cb-story-fit-end:.84;
  --cb-story-caption-fade:.04;
  --cb-story-word-rest:.14;
  --cb-story-unfocus:.4;
  --cb-story-dim:.18;
  --cb-story-square:.7;
  --cb-story-fit-scale:1.16;
  --cb-story-seed:126;
  /* 02 Findings, at scale: every run grey, then colour sweeps the grid left to right as the headline pass rate counts up. */
  --cb-story-color-start:.04;
  --cb-story-color-end:.8;
  /* How strongly a run the sweep hasn't reached yet shows (0..1): dimmer than "Other outcomes". */
  --cb-story-run-rest:.45;
  --cb-story-names:132;
  --cb-story-run-square:.72;
  /* What's next: where the checkout card lights, in the section's own progress. */
  --cb-story-next-start:.3;
  --cb-story-next-end:.62;
  --cb-story-card-rest:.45;
  /* Colours drawn on the canvases; outcomes reuse --pass and --miss. */
  --cb-story-offer:#5f5b57;
  --cb-story-other:#77726d;
}

.story{position:relative;background:var(--fx-ground)}
.story-mark{position:absolute;left:0;top:0;width:1px;height:1px;scroll-margin-top:var(--fx-nav);pointer-events:none}
.story-scene{box-sizing:border-box;display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:32px 64px;align-items:center;width:100%;max-width:calc(var(--fx-plane) + 2 * var(--fx-margin));margin:0 auto;padding:72px var(--fx-margin)}
.story-scene+.story-scene{border-top:1px solid var(--fx-hair)}
.story-copy{min-width:0}
.story-eyebrow{margin:0 0 20px}
.story-captions{position:relative;margin-top:24px}
.story-caption{margin:0;max-width:30ch;font:600 22px/1.3 var(--display);letter-spacing:-.01em;color:#fff;text-wrap:balance}
.story-caption+.story-caption{margin-top:14px}
.story-caption strong{font-weight:700}
.story-visual{position:relative;margin:0;min-width:0;height:min(62vh,600px)}
.story-visual canvas{display:block;width:100%;height:100%}
.story-visual>figcaption{position:absolute;left:0;top:-30px;font:400 12px/1.66 var(--mono);letter-spacing:2px;text-transform:uppercase;color:var(--fx-caption)}

/* 01 The problem. Left: Sam's chat. Right: the inventory, captioned where it is. */
.story-chat{margin:0;padding:16px 18px 18px;background:var(--fx-panel);border:1px solid var(--fx-edge);border-radius:20px}
.story-chat-head{display:flex;align-items:center;gap:12px;margin:0 0 14px;padding-bottom:12px;border-bottom:1px solid var(--fx-hair)}
.story-avatar{display:grid;place-items:center;flex:none;width:36px;height:36px;border-radius:50%;background:#3a3a3a;font:700 15px/1 var(--display);color:#fff}
.story-chat-head b{display:block;font:600 16px/1.2 var(--display);color:#fff}
.story-chat-head small{display:block;margin-top:2px;font:400 12px/1.3 var(--mono);letter-spacing:1.2px;text-transform:uppercase;color:var(--fx-caption)}
.story-thread{display:grid;gap:8px;justify-items:start}
.story-typing{display:inline-flex;gap:5px;padding:12px 14px;border-radius:16px 16px 16px 4px;background:#2c2c2c}
.story-typing i{width:7px;height:7px;border-radius:50%;background:var(--fx-ink)}
.story-bubble{margin:0;padding:12px 16px 13px;max-width:100%;border-radius:18px 18px 18px 4px;background:#2c2c2c;font:400 17px/1.48 var(--display);color:#fff}
/* What Sam says out loud lights up as it is typed; the locks are what Sam doesn't say. */
.story-bubble mark{margin:0 -2px;padding:0 2px;border-radius:3px;background:transparent;color:inherit;transition:background-color .35s ease}
.story-bubble mark.is-said{background:rgba(57,135,229,.34)}
.story-chat-meta{margin:2px 0 0 4px;font:400 11px/1.4 var(--mono);letter-spacing:1.2px;text-transform:uppercase;color:var(--fx-caption)}
.story-unsaid{display:flex;flex-wrap:wrap;align-items:center;gap:10px 16px;margin:16px 0 0}
.story-chips{display:flex;align-items:center;gap:10px;margin:0;padding:0;list-style:none}
.story-chips-label{margin:0;max-width:20ch;font:400 14px/1.35 var(--display);color:var(--fx-ink)}
.story-chip{display:grid;place-items:center;width:44px;height:44px;border-radius:12px;background:#2b2b2b;border:1px solid var(--fx-edge);color:var(--fx-ink)}
.story-chip svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.6}
.story-inventory{display:grid;grid-template-rows:auto minmax(0,1fr) auto;gap:18px;min-width:0;height:min(64vh,620px)}
.story-count{display:flex;align-items:baseline;gap:14px;margin:0}
.story-count b{font:700 56px/1 var(--display);letter-spacing:-.035em;color:#fff;font-variant-numeric:tabular-nums}
.story-count span{font:600 22px/1.2 var(--display);letter-spacing:-.01em;color:#fff}
.story-inventory .story-visual{height:auto;min-height:0}
.story-notes{position:relative;min-height:3.2em}
.story-note{display:flex;align-items:baseline;gap:12px;margin:0;max-width:44ch;font:600 20px/1.3 var(--display);letter-spacing:-.01em;color:#fff}
.story-note+.story-note{margin-top:10px}
.story-note i{flex:none;width:14px;height:14px;border-radius:3px;transform:translateY(1px)}
.story-note .k-trap{background:var(--miss)}
.story-note .k-fit{background:var(--pass)}
.story-note strong{font-weight:700}

/* 02 Findings, at scale (designer's simplification, Kyle 19 Oct): a smaller headline on the left,
   with the run count for scale and a line saying what the number is, beside a wider grid of every run. */
@media(min-width:768px){.story-scene[data-scene="2"]{grid-template-columns:minmax(0,3.4fr) minmax(0,8.6fr)}}
.story-work-visual{position:relative;display:grid;min-width:0}
.story-result{display:grid;gap:10px;margin:0}
.story-result b{font:700 clamp(56px,5.2vw,84px)/.9 var(--display);letter-spacing:-.045em;color:#fff}
.story-result>span{font:400 var(--fx-aud)/1.35 var(--display);color:#fff}
.story-context{margin:18px 0 0;max-width:30ch;font:400 var(--fx-body)/1.45 var(--display);color:var(--fx-ink)}
/* story.js sets the run grid's height so its rows fill the width (Kyle, 30 Oct); this ratio is its shape until then. */
.story-visual--runs{width:100%;height:auto;aspect-ratio:12/5;align-self:center;justify-self:center}
/* 02 Findings, stacked (Kyle, 22 Oct): the takeaway on top, left-aligned, and the grid below it, as wide as the
   page allows and centred, with each model's logo and name on its row. */
.story-scene[data-scene="2"]{grid-template-columns:minmax(0,1fr);align-items:start;gap:44px}
/* Its headline and line wear the charts' own style (.rs-h, .rs-p in sections.css), so the three findings read alike. */
.story-scene[data-scene="2"] .story-result{display:block;font:700 28px/1.16 var(--display);letter-spacing:-.018em;color:#fff;text-wrap:balance}
.story-scene[data-scene="2"] .story-result b,.story-scene[data-scene="2"] .story-result>span{font:inherit;letter-spacing:inherit;color:inherit}
.story-scene[data-scene="2"] .story-result b{margin-right:.25em}
.story-scene[data-scene="2"] .story-context{max-width:none;margin-top:12px;font:400 17px/1.5 var(--display);text-wrap:pretty}
/* The key hangs 16px under the grid by its top, so a key that wraps on a phone grows down, clear of the rows. */
.story-legend{position:absolute;left:0;right:0;top:calc(100% + 16px);display:flex;flex-wrap:wrap;gap:6px 22px;margin:0;padding:0;list-style:none;font:400 13px/1.4 var(--display);color:var(--fx-ink)}
.story-legend i{display:inline-block;width:10px;height:10px;margin-right:8px;border-radius:2px;vertical-align:-1px}
.story-legend .k-pass{background:var(--pass)}.story-legend .k-miss{background:var(--miss)}.story-legend .k-other{background:var(--cb-story-other)}

/* What's next lives in sections.css (the three phases as a flow). */

/* Live: the runs fill as their grid rises through the window (story.js). Since Kyle's 22 Oct note nothing
   pins: a window-tall frame left empty space above and below the grid. The scene sits in the page with a
   section's spacing; the charts follow it. */
.story-live .story-stage{display:grid}
.story-live .story-scene{grid-area:1/1;padding-block:var(--fx-pad) calc(var(--fx-pad) - 24px);border-top:0}

/* Where the reader is: one segment per scene, filling as it plays. Live story
   only. Since Kyle's 20 Oct note there is no Next button: the reader scrolls on. */
.story-progress{display:none}
.story-live .story-progress{position:absolute;left:0;right:0;bottom:0;z-index:3;display:flex;align-items:flex-end;box-sizing:border-box;width:100%;max-width:calc(var(--fx-plane) + 2 * var(--fx-margin));margin:0 auto;padding:0 var(--fx-margin) 24px;pointer-events:none}
.story-segs{display:flex;gap:12px;margin:0;padding:0;list-style:none}
.story-seg{display:grid;gap:8px;width:clamp(110px,12vw,180px)}
.story-seg b{font:400 11px/1.3 var(--mono);letter-spacing:1.6px;text-transform:uppercase;color:var(--fx-caption);transition:color .2s ease}
.story-seg.is-active b{color:#fff}
.story-seg span{position:relative;display:block;height:3px;overflow:hidden;border-radius:2px;background:#3a3a3a}
.story-seg span i{position:absolute;inset:0;background:#fff;transform-origin:left;transform:scaleX(var(--fill,0))}
/* The tracker followed the pinned scene; with nothing pinned the filling grid shows the progress itself. */
.story-live .story-progress{display:none!important}
/* Desktop (designer's simplification): the tracker stands to the right of the grid, filling downward. */
@media(min-width:768px){
  .story-live .story-progress{top:0}
  .story-live .story-segs{position:absolute;top:50%;right:max(12px,calc(var(--fx-margin) / 2 - 2px));flex-direction:column;transform:translateY(-50%)}
  .story-live .story-seg{width:auto;justify-items:center;gap:0}
  .story-live .story-seg span{width:3px;height:clamp(120px,28vh,260px)}
  .story-live .story-seg span i{transform-origin:top;transform:scaleY(var(--fill,0))}
  /* "02 | Findings" labels the scene since 22 Oct, so the tracker keeps its bar and its label goes to screen readers. */
  .story-live .story-seg b{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
}
.story-live .story-captions{min-height:5.4em}
.story-live .story-work-visual{height:auto}
.story-live .story-work-visual>*{grid-area:1/1;align-self:center}
/* The takeaway and the grid stay together at the page's spacing, the grid as wide as the page (Kyle, 22 Oct). */
@media(min-width:768px){
  .story-live .story-scene[data-scene="2"]{grid-template-rows:auto auto;gap:40px}
  .story-live .story-work-visual{box-sizing:border-box;padding-block:34px 44px}
  /* Reduced motion keeps the room under the grid for its key too. */
  .story-work-visual{padding-bottom:44px}
}
.story-live .story-caption,.story-live .story-note{position:absolute;inset:0 0 auto 0}
.story-live .story-caption+.story-caption,.story-live .story-note+.story-note{margin-top:0}
.story-live .story-scene,.story-live .story-chip,.story-live .story-caption,.story-live .story-note,.story-live .story-bubble .w,.story-live .story-result{will-change:opacity}

@media(max-width:767px){
  /* Phones show one subject at a time: the chat, then the inventory. */
  :root{--cb-story-unfocus:0}
  .story-scene{grid-template-columns:1fr;align-content:start;gap:28px}
  .story-scene{padding:40px var(--fx-margin)}
  .story-chat{padding:12px 14px 14px}
  .story-chat-head{margin-bottom:10px;padding-bottom:8px}
  .story-avatar{width:30px;height:30px;font-size:13px}
  .story-bubble{font-size:14px;padding:10px 13px}
  .story-unsaid{margin-top:10px;gap:8px 12px}
  .story-chips-label{font-size:13px}
  .story-chip{width:34px;height:34px;border-radius:10px}
  .story-captions{margin-top:14px}
  .story-caption{font-size:17px}
  .story-inventory{height:auto;gap:10px}
  .story-count b{font-size:36px}
  .story-count span{font-size:16px}
  .story-inventory .story-visual{height:220px}
  .story-note{font-size:16px}
  .story-result{gap:6px}
  .story-result b{font-size:56px}
  .story-result span{font-size:16px}
  .story-legend{font-size:11px;gap:4px 14px}
  /* The chart's caption (two lines here) and key sit outside its box; this holds them clear of the number above and,
     the key wrapped to three lines on a 320px phone, of the fold below. */
  .story-work-visual{padding-block:48px}
  .story-live .story-scene{grid-template-rows:auto auto;gap:24px}
  /* The bar keeps the height above the stage's foot it had beside the Next button. */
  .story-live .story-progress{padding-bottom:30px}
  .story-seg{width:56px;gap:0}
  .story-seg b{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
  .story-live .story-captions{min-height:4.4em}
  .story-live [data-scene="1"]{grid-template-rows:minmax(0,1fr)}
  .story-live [data-scene="1"]>.story-copy,.story-live [data-scene="1"]>.story-inventory{grid-area:1/1;align-self:stretch}
  .story-live .story-inventory{box-sizing:border-box;height:100%;padding-top:46px;grid-template-rows:auto minmax(0,1fr) auto}
  .story-live .story-inventory .story-visual{height:auto;min-height:120px}
  /* The number and the chart read as one group, centred in the frame. */
  .story-live [data-scene="2"]{grid-template-rows:auto auto;align-content:center}
  /* Phones stack as before; with no room for names the grid fills the width too, 45:22 until story.js sets its height. */
  .story-scene[data-scene="2"]{gap:24px}
  .story-scene[data-scene="2"] .story-result{font-size:24px}
  .story-visual--runs{aspect-ratio:45/22}
  .story-live .story-work-visual{height:auto}
}

/* ── Episode 1 as a scroll story (29 Oct; episode-story.js) ─────────────────────────────────────────────────
   Wide screens: the beats in a column, Sam's market pinned beside them under the section bar. Phones: the market
   pinned above on the section's ground, each beat rising into view under it and passing behind it, so the TVs
   never hide. The layout is the script's (.is-live, set as it mounts); without JavaScript the market has nothing
   to draw, so it folds away and the beats read as a list. */
.ep-story{margin-top:40px}
.ep-market{display:none}
.ep-beats{display:grid;gap:16px;margin:0;padding:0;list-style:none}
.ep-beat{max-width:560px;padding:26px 28px 28px;border-radius:16px;background:#1b1b1b;box-shadow:0 18px 44px rgba(0,0,0,.34)}
.ep-beat-k{margin:0 0 10px;font:400 12px/1.4 var(--mono);letter-spacing:1.6px;text-transform:uppercase;color:var(--fx-caption)}
.ep-beat--hidden .ep-beat-k{color:var(--fx-gold)}
.ep-beat-t{margin:0;font:600 24px/1.25 var(--display);letter-spacing:-.012em;color:#fff;text-wrap:balance}
.ep-quote{margin:0;font:400 18px/1.55 var(--display);color:var(--fx-ink);text-wrap:pretty}
.ep-beat-n{display:flex;align-items:baseline;gap:10px;margin:18px 0 0;font:400 15px/1.3 var(--display);color:var(--fx-ink)}
.ep-beat-n b{font:700 40px/1 var(--display);letter-spacing:-.03em;color:#fff;font-variant-numeric:tabular-nums}
.ep-beat-n i{flex:none;align-self:center;width:12px;height:12px;margin-right:-2px;border-radius:3px}
.ep-beat .k-pass,.ep-beats .k-pass{background:var(--pass)}
.ep-beats .k-miss{background:var(--miss)}
.ep-beats .k-other{background:var(--cb-story-other)}
/* The last beat: each model's three runs on this episode, a column each, most passes first. */
.ep-story-runs{display:flex;flex-wrap:wrap;gap:6px;margin:22px 0 0}
.ep-story-run{display:grid;gap:4px}
.ep-story-run i{display:block;width:16px;height:16px;border-radius:3px}
.ep-story-key{display:flex;flex-wrap:wrap;gap:6px 18px;margin:14px 0 0;padding:0;list-style:none;font:400 13px/1.4 var(--display);color:var(--fx-ink)}
.ep-story-key i{display:inline-block;width:10px;height:10px;margin-right:8px;border-radius:2px;vertical-align:-1px}
.article .ep-story+.c-sub.ep-lead{margin-top:72px}
/* The key explains the squares the script draws from the market file; without them it goes. */
.ep-story:not(.is-live) .ep-story-key{display:none}

.ep-story.is-live{display:grid;grid-template-columns:minmax(300px,440px) minmax(0,1fr);column-gap:clamp(32px,5vw,80px)}
.is-live .ep-market{position:sticky;top:calc(var(--fx-nav) + 32px);z-index:0;grid-area:1/2;align-self:start;display:flex;flex-direction:column;justify-content:center;gap:14px;height:calc(100vh - var(--fx-nav) - 64px);height:calc(100svh - var(--fx-nav) - 64px);max-height:720px}
.is-live .ep-market canvas{display:block;flex:1 1 auto;min-height:0;width:100%}
.ep-market-k{margin:0;font:400 12px/1.4 var(--mono);letter-spacing:1.4px;text-transform:uppercase;color:var(--fx-caption)}
.is-live .ep-beats{grid-area:1/1;position:relative;z-index:1;gap:0;padding:12vh 0 18vh}
.is-live .ep-beat+.ep-beat{margin-top:58vh}
@media(max-width:899px){
  .ep-story.is-live{grid-template-columns:minmax(0,1fr)}
  /* Tucked 6px under the section bar, which sits above it: the bar is 67px on phones, a pixel short of --fx-nav,
     and the beats showed through that gap as they scrolled under (29 Oct). The padding keeps the squares in place. */
  .is-live .ep-market{grid-area:1/1;top:calc(var(--fx-nav) - 6px);z-index:2;box-sizing:border-box;height:calc(42vh + 6px);height:calc(42svh + 6px);padding:20px 0 12px;background:var(--fx-ground)}
  .is-live .ep-beats{grid-area:2/1;padding:4vh 0 10vh}
  .is-live .ep-beat+.ep-beat{margin-top:46vh}
  .ep-beat{padding:22px 20px 24px}
  .ep-beat-t{font-size:21px}
  .ep-quote{font-size:16px}
  .ep-beat-n b{font-size:34px}
  .ep-story-run i{width:13px;height:13px}
  .ep-story-runs{gap:5px}
}
/* The run grid's shape until story.js sets its height, as it measures with the 22 models' names: about 2.6 on tablets,
   2.4 on laptops (the 12:5 above) and 2.33 on wide screens. */
@media(min-width:660px) and (max-width:1023px){.story-visual--runs{aspect-ratio:13/5}}
@media(min-width:1400px){.story-visual--runs{aspect-ratio:7/3}}
