/* Explainer engine: a case study played like a motion-graphics explainer.
   All scenes sit on one 2D canvas along a spiral; the camera travels it. Sizes inside a scene are written in
   logical px (a 1600 x 900 frame) as calc(N * var(--u)), where --u is the CSS px per logical px for this viewport,
   so the active scene renders at an effective scale of exactly 1 and its text is rasterised crisp. */

:root {
  --bg: #f3f2f0; --ink: #2b2b2b; --muted: #5c5c5c; --accent: #374c9f; --accent2: #f8db21;
  --deep: #24336f; --mist: #eceffe;
  --font: system-ui, sans-serif; --display: var(--font); --label: var(--font);
  --canvas: color-mix(in oklab, var(--deep) 52%, #000);
  --canvas-ink: #e9ebf7;
}
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--canvas); color: var(--canvas-ink); }
html { scrollbar-width: none; }
html::-webkit-scrollbar { display: none; }
body { font-family: var(--font); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; overscroll-behavior: none; }
.xp-scroll { position: relative; width: 1px; pointer-events: none; }
.xp-stage { position: fixed; inset: 0; overflow: hidden; z-index: 1; }
.xp-world { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.xp-world.is-moving { will-change: transform; }
.xp-bg { position: absolute; left: 0; top: 0; transform-origin: 0 0; pointer-events: none; overflow: visible; }

/* ---------- scene frame ---------- */
.sc {
  --fg: var(--ink); --mut: var(--muted); --hi: var(--accent); --line: color-mix(in oklab, var(--fg) 14%, transparent);
  --card: #fff; --sbg: var(--bg); --on-hi: var(--on-accentb, #fff);
  position: absolute; left: 0; top: 0; transform-origin: 0 0;
  background: var(--sbg); color: var(--fg); overflow: hidden; border-radius: calc(10 * var(--u));
  font-family: var(--font); font-size: calc(22 * var(--u)); line-height: 1.5;
  box-shadow: 0 calc(40 * var(--u)) calc(90 * var(--u)) calc(-40 * var(--u)) rgba(0, 0, 0, .55);
  opacity: .25;
}
.sc.is-dark { --on-hi: var(--on-accent2b, #fff); --fg: #fff; --mut: color-mix(in oklab, #fff 72%, var(--sbg)); --hi: var(--accent2); --line: rgba(255, 255, 255, .16); --card: rgba(255, 255, 255, .06); }
/* one hairline colour for every frame edge inside a slide (screens, image frames, window bars); --px = 1 slide px */
.sc { --ring: rgba(14, 18, 40, .12); --px: 1px; --img-r: calc(10 * var(--u)); }
.sc.is-dark { --ring: rgba(255, 255, 255, .14); }
.sc.is-white { --card: var(--mist); }
.sc__in { position: absolute; inset: 0; padding: calc(112 * var(--u)) calc(112 * var(--u)) calc(84 * var(--u));
  display: grid; gap: calc(44 * var(--u)) calc(56 * var(--u)); grid-template-rows: auto; min-height: 0; }
.sc__tag { position: absolute; left: calc(112 * var(--u)); top: calc(46 * var(--u)); display: flex; align-items: center; gap: calc(14 * var(--u));
  font: 600 calc(17 * var(--u)) / 1 var(--label); letter-spacing: .02em; color: var(--mut); }
.sc__tag::before { content: ''; width: calc(26 * var(--u)); height: calc(3 * var(--u)); border-radius: 2px; background: var(--hi); }
.sc__tag .t { color: var(--fg); opacity: .5; font-weight: 500; }
.sc:not(.is-built) .it { visibility: hidden; }

/* regions */
.rg { min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: calc(28 * var(--u)); }
.rg--top { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); align-items: end; gap: calc(80 * var(--u)); }
.rg--top > :only-child { grid-column: 1 / -1; }
.rg--top .grp--heading { grid-column: 1; }
.rg--top .grp--text { grid-column: 2; padding-bottom: calc(8 * var(--u)); }
.rg--left, .rg--right { justify-content: center; }
.rg--center { justify-content: center; }
.rg--bottom { flex-direction: row; align-items: flex-start; gap: calc(56 * var(--u)); }
.rg--bottom > .grp { flex: 1 1 0; min-width: 0; }
.rg--bottom > .grp--text { flex: 0 0 auto; max-width: calc(260 * var(--u)); align-self: flex-end; }

.grp { display: flex; flex-direction: column; gap: calc(24 * var(--u)); min-width: 0; }
.grp--card, .grp--stat, .grp--image, .grp--swatches.is-row { flex-direction: row; }
.rg--left .grp--card, .rg--right .grp--card { flex-direction: column; }
.grp--card > *, .grp--stat > * { flex: 1 1 0; min-width: 0; }
.grp--image, .grp--device { flex: 1 1 0; min-height: 0; }
.grp--image.is-stack { flex-direction: column; }
.rg--bottom .slot, .rg--top .slot { min-height: calc(240 * var(--u)); }
.grp--image.is-wall { display: grid; grid-template-columns: repeat(var(--cols), minmax(0, 1fr)); grid-auto-rows: minmax(0, 1fr); }
.grp--list { flex-direction: row; gap: calc(48 * var(--u)); }
.grp--list > * { flex: 1 1 0; min-width: 0; }
.grp--type { flex-direction: row; gap: calc(64 * var(--u)); }

/* ---------- type ---------- */
.hd { margin: 0; font: 600 calc(60 * var(--u)) / 1.08 var(--display); letter-spacing: -.022em; color: var(--fg); text-wrap: balance; }
.hd.is-long { font-size: calc(50 * var(--u)); line-height: 1.12; }
.hd.is-xl { font-size: calc(92 * var(--u)); line-height: 1.02; letter-spacing: -.03em; }
.hd .w { display: inline-block; overflow: clip; overflow-clip-margin: calc(10 * var(--u)); padding-bottom: .08em; margin-bottom: -.08em; vertical-align: top; }
.hd .wi { display: inline-block; }
.hd .em { color: var(--hi); }
.tx { margin: 0; max-width: 34em; color: var(--mut); font-size: calc(23 * var(--u)); line-height: 1.55; text-wrap: pretty; }
.tx.is-kicker { align-self: flex-start; color: var(--fg); font: 500 calc(17 * var(--u)) / 1 var(--label); padding: calc(11 * var(--u)) calc(18 * var(--u));
  box-shadow: inset 0 0 0 1px var(--line); border-radius: 999px; background: var(--card); }
.tx.is-meta { font: 500 calc(16 * var(--u)) / 1.5 var(--label); letter-spacing: .02em; color: var(--mut); padding-top: calc(20 * var(--u)); border-top: 1px solid var(--line); }
.rg--bottom .tx { font-size: calc(18 * var(--u)); }

/* ---------- card ---------- */
.card { position: relative; background: var(--card); box-shadow: inset 0 0 0 1px var(--line); border-radius: calc(20 * var(--u));
  padding: calc(32 * var(--u)) calc(32 * var(--u)) calc(34 * var(--u)); display: flex; flex-direction: column; gap: calc(12 * var(--u)); }
.card__ic { width: calc(52 * var(--u)); height: calc(52 * var(--u)); margin-bottom: calc(12 * var(--u)); display: grid; place-items: center;
  border-radius: calc(14 * var(--u)); background: color-mix(in oklab, var(--hi) 16%, transparent); color: var(--hi); font: 600 calc(22 * var(--u)) / 1 var(--display); }
.card__ic img { width: 70%; height: 70%; }
.card h3 { margin: 0; font: 600 calc(25 * var(--u)) / 1.2 var(--display); letter-spacing: -.01em; color: var(--fg); }
.card p { margin: 0; color: var(--mut); font-size: calc(18.5 * var(--u)); line-height: 1.55; }
.rg--left .card, .rg--right .card { padding: calc(26 * var(--u)) calc(28 * var(--u)); }

/* ---------- stat ---------- */
.stat { position: relative; padding-left: calc(28 * var(--u)); box-shadow: inset 1px 0 0 var(--line); display: flex; flex-direction: column; }
.stat__v { white-space: nowrap; display: grid; font: 600 calc(124 * var(--u)) / .95 var(--display); letter-spacing: -.04em; color: var(--fg); font-variant-numeric: tabular-nums; }
.stat__v > * { grid-area: 1 / 1; }
.stat__ghost { visibility: hidden; }
.stat__bar { height: calc(6 * var(--u)); width: calc(64 * var(--u)); border-radius: 3px; background: var(--hi); margin: calc(22 * var(--u)) 0 calc(18 * var(--u)); transform-origin: 0 50%; }
.stat__l { font: 600 calc(23 * var(--u)) / 1.25 var(--display); color: var(--fg); }
.stat__c { margin-top: calc(6 * var(--u)); color: var(--mut); font-size: calc(17 * var(--u)); line-height: 1.45; }
.grp--stat.is-compact .stat__v { font-size: calc(84 * var(--u)); }

/* ---------- list ---------- */
.lst { display: flex; flex-direction: column; gap: calc(14 * var(--u)); }
.lst h4 { margin: 0 0 calc(4 * var(--u)); font: 600 calc(20 * var(--u)) / 1.2 var(--display); color: var(--fg); }
.lst ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: calc(14 * var(--u)); }
.lst li { display: flex; align-items: baseline; gap: calc(14 * var(--u)); font-size: calc(21 * var(--u)); color: var(--fg); }
.lst li .mk { flex: none; width: calc(10 * var(--u)); height: calc(10 * var(--u)); border-radius: 50%; background: var(--hi); transform: translateY(calc(-2 * var(--u))); }
.lst.is-chips ul { flex-direction: row; flex-wrap: wrap; gap: calc(10 * var(--u)); }
.lst.is-chips li { padding: calc(8 * var(--u)) calc(16 * var(--u)); border-radius: 999px; font-size: calc(16.5 * var(--u)); line-height: 1.2; color: #2b2b2b; background: var(--chip, var(--card)); }
.lst.is-buttons ul { flex-direction: row; gap: calc(18 * var(--u)); }
.lst.is-buttons li { font: 500 calc(17 * var(--u)) / 1 var(--label); letter-spacing: .06em; text-transform: uppercase; padding: calc(20 * var(--u)) calc(34 * var(--u));
  border-radius: 999px; border: 2px solid var(--accent2); color: var(--accent); }
.lst.is-buttons li:nth-child(1) { background: var(--accent); border-color: var(--accent); color: var(--on-accent, var(--accent2)); }
.lst.is-buttons li:nth-child(2) { background: var(--accent2); color: var(--on-accent2, var(--accent)); }
.lst.is-meta ul { flex-direction: row; gap: calc(56 * var(--u)); padding-top: calc(22 * var(--u)); border-top: 1px solid var(--line); }
.lst.is-meta li { flex-direction: column; gap: calc(4 * var(--u)); font-size: calc(19 * var(--u)); }
.lst li .k { color: var(--mut); font: 500 calc(15 * var(--u)) / 1.3 var(--label); letter-spacing: .02em; }
.lst li .v { font-weight: 500; }

/* ---------- flow ---------- */
.flow { position: relative; width: 100%; }
.flow svg { position: absolute; left: 0; top: 0; overflow: visible; }
.flow path { fill: none; stroke: color-mix(in oklab, var(--fg) 38%, transparent); stroke-width: calc(2 * var(--u)); stroke-linecap: round; stroke-linejoin: round; }
.flow .tip { fill: color-mix(in oklab, var(--fg) 38%, transparent); stroke: none; }
.fn { position: absolute; left: 0; top: 0; white-space: nowrap; font: 500 calc(18 * var(--u)) / 1 var(--font); color: var(--fg);
  padding: calc(13 * var(--u) + 1.5px) calc(22 * var(--u) + 1.5px); border-radius: 999px; background: var(--sbg); box-shadow: inset 0 0 0 1.5px color-mix(in oklab, var(--fg) 26%, transparent); }
.fn.is-root { background: var(--fg); color: var(--sbg); box-shadow: none; font-weight: 600; }
.fn.is-hi { background: var(--hi); box-shadow: none; color: var(--on-hi, #fff); font-weight: 600; }
.is-dark .fn.is-hi { color: var(--sbg); }
.fnum { position: absolute; left: 0; top: 0; width: calc(52 * var(--u)); height: calc(52 * var(--u)); border-radius: 50%; display: grid; place-items: center;
  font: 600 calc(19 * var(--u)) / 1 var(--display); color: var(--fg); background: var(--sbg); box-shadow: inset 0 0 0 2px var(--hi); font-variant-numeric: tabular-nums; }
.fnum.is-end { background: var(--hi); color: var(--on-hi, #fff); }
.is-dark .fnum.is-end { color: var(--sbg); }
.flab { position: absolute; left: 0; top: 0; text-align: center; font-size: calc(15.5 * var(--u)); line-height: 1.3; color: var(--mut); }

/* ---------- image ---------- */
.slot { position: relative; flex: 1 1 0; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: calc(14 * var(--u)); }
.fbox { position: relative; flex: 1 1 0; min-height: 0; }
.fbox .fr { position: absolute; margin: 0; overflow: hidden; border-radius: var(--img-r); background: #fff; display: flex; flex-direction: column;
  box-shadow: 0 0 0 1px var(--ring), 0 calc(20 * var(--u)) calc(44 * var(--u)) calc(-26 * var(--u)) rgba(10, 16, 50, .34); }
/* the picture is shown whole: its frame already has the image's aspect (fitImages); contain is the safety net */
.fbox .fr .fv { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; }
.fbox .fr img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: 50% 0%; }
.fbox .fr.is-bleed img { object-fit: cover; }
.fbox .fr.is-scroll img { height: auto; will-change: transform; }
.fbox .fr.is-device { background: #0e0f13; box-shadow: 0 calc(20 * var(--u)) calc(44 * var(--u)) calc(-26 * var(--u)) rgba(10, 16, 50, .4); }
.fbox .fr.is-device .fv { border-radius: calc(var(--img-r) * .6); }
.fbox .fr.is-bare { box-shadow: none; border-radius: 0; background: none; }
.fbox .fr.is-flat { background: none; box-shadow: none; border-radius: 0; overflow: visible; }
.fbox .fr.is-flat .fv { overflow: visible; }
.fbox .fr.is-flat img { object-fit: contain; }
.ring { position: absolute; box-shadow: inset 0 0 0 calc(4 * var(--u)) var(--hi); border-radius: calc(var(--img-r) + 10 * var(--u)); pointer-events: none; }
.slot .cap { display: flex; flex-direction: column; gap: calc(2 * var(--u)); text-align: left; }
.slot .cap b { font: 600 calc(18 * var(--u)) / 1.3 var(--display); color: var(--fg); }
.slot .cap span { font-size: calc(15.5 * var(--u)); color: var(--mut); line-height: 1.4; }
.slot.is-chosen .cap b { color: var(--hi); }
/* hero: the screen bleeds off the right and bottom edges */
.lay-hero .rg--right { margin: 0 calc(-112 * var(--u)) calc(-84 * var(--u)) 0; justify-content: flex-end; }
.lay-hero .rg--right .fr { border-radius: calc(14 * var(--u)) 0 0 0; }
.lay-hero .rg--center { position: absolute; left: 47%; top: 42%; width: 15.5%; height: 50%; z-index: 2; }
.lay-hero .rg--left { justify-content: center; gap: calc(30 * var(--u)); }
.lay-hero .rg--left .grp--image { flex: none; height: calc(120 * var(--u)); }

/* ---------- swatches + type ---------- */
.sws { display: flex; gap: calc(16 * var(--u)); }
.sw { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: calc(10 * var(--u)); }
.sw i { display: block; height: calc(64 * var(--u)); border-radius: calc(14 * var(--u)); background: var(--c); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06); }
.sws.is-big .sw i { height: calc(104 * var(--u)); display: flex; align-items: flex-end; padding: calc(16 * var(--u)); }
.sw b { font: 600 calc(15.5 * var(--u)) / 1.25 var(--display); color: var(--fg); }
.sw code { font: 400 calc(14 * var(--u)) / 1.2 var(--font); color: var(--mut); text-transform: uppercase; }
.ty { flex: 1 1 0; display: flex; align-items: flex-end; gap: calc(28 * var(--u)); }
.ty__aa { font-size: calc(108 * var(--u)); line-height: .82; letter-spacing: -.02em; color: var(--fg); }
.ty__m { display: flex; flex-direction: column; gap: calc(6 * var(--u)); padding-bottom: calc(4 * var(--u)); }
.ty__m b { font: 600 calc(24 * var(--u)) / 1.2 var(--display); }
.ty__w { display: flex; gap: calc(14 * var(--u)); font-size: calc(17 * var(--u)); color: var(--fg); }
.ty__n { font-size: calc(16 * var(--u)); color: var(--mut); line-height: 1.45; max-width: 26em; }

/* ---------- device ---------- */
.dev { position: relative; flex: 1 1 0; min-height: 0; }
/* the flat device: the real screen in a drawn bezel (sizes from sizeDevFrame: --w screen width, --r outer corner,
   --b bezel, --sr screen corner, --chin). Light body with a hairline, as the case-study Phone frame; no dark backing */
.dev__poster { position: absolute; inset: 3% 5%; margin: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; background: none; padding: 0; }
.dev__poster:not(.is-sized) { visibility: hidden; }
.dev__frame { position: relative; box-sizing: content-box; width: var(--w); padding: var(--b) var(--b) calc(var(--b) + var(--chin)); border-radius: var(--r);
  background: var(--dev-body, #F4F5F7); box-shadow: inset 0 0 0 1px #D3D9E3, 0 calc(30 * var(--u)) calc(70 * var(--u)) calc(-30 * var(--u)) rgba(0, 0, 0, .45); }
.dev__scr { width: var(--w); aspect-ratio: var(--ar); border-radius: var(--sr); overflow: hidden; background: #fff; box-shadow: 0 0 0 1px rgba(20, 27, 45, .08); }
.dev__scr img { display: block; width: 100%; height: 100%; object-fit: cover; }
.dev__poster.is-phone .dev__frame { box-shadow: inset 0 0 0 1px #D3D9E3, 0 calc(26 * var(--u)) calc(60 * var(--u)) calc(-24 * var(--u)) rgba(0, 0, 0, .5); }
/* laptop: a base under the lid, wider than it; iMac / monitor: a stand */
.dev__poster.is-laptop .dev__frame { border-radius: var(--r) var(--r) calc(var(--r) * .4) calc(var(--r) * .4); }
.dev__poster.is-laptop::after { content: ''; display: block; width: calc(var(--w) * 1.14); height: calc(var(--w) * .035); margin-top: -1px;
  background: linear-gradient(#E9EBEF, #C9CED6); border-radius: 0 0 calc(var(--w) * .03) calc(var(--w) * .03); box-shadow: inset 0 1px 0 #fff, 0 12px 26px -16px rgba(0, 0, 0, .6); }
.dev__poster.is-imac::after, .dev__poster.is-monitor::after { content: ''; display: block; width: calc(var(--w) * .2); height: calc(var(--w) * .16);
  background: linear-gradient(#E6E8EC, #CDD1D8); clip-path: polygon(14% 0, 86% 0, 100% 100%, 0 100%); }
.dev.is-gl .dev__poster { visibility: hidden; }
.xp-gl { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 3; }
.co-layer { position: absolute; inset: 0; pointer-events: none; z-index: 4; }
.co-layer svg { position: absolute; left: 0; top: 0; overflow: visible; }
.co-layer path { fill: none; stroke: var(--fg); stroke-width: calc(1.6 * var(--u)); opacity: .7; }
.co-layer circle.d { fill: var(--hi); }
.co-layer circle.r { fill: none; stroke: var(--hi); stroke-width: calc(2 * var(--u)); }
.co { position: absolute; width: calc(250 * var(--u)); font: 500 calc(18 * var(--u)) / 1.35 var(--font); color: var(--fg); }
.co.is-l { text-align: right; }
.co::before { content: ''; display: block; width: calc(22 * var(--u)); height: calc(3 * var(--u)); border-radius: 2px; background: var(--hi); margin-bottom: calc(10 * var(--u)); }
.co.is-l::before { margin-left: auto; }

/* ---------- HUD ---------- */
.xh { position: fixed; z-index: 20; color: var(--canvas-ink); font-family: var(--label); }
.xh--tl { top: 22px; left: 28px; display: flex; flex-direction: column; gap: 3px; pointer-events: none; }
.xh--tl b { font: 600 17px/1.1 var(--display); letter-spacing: -.01em; }
.xh--tl span { font-size: 12.5px; opacity: .62; max-width: 44ch; }
.xh--bl { bottom: 18px; left: 22px; display: flex; align-items: center; gap: 14px; }
.xh-map { width: 64px; height: 64px; overflow: visible; }
.xh-map path { fill: none; stroke: currentColor; stroke-opacity: .28; stroke-width: 1; vector-effect: non-scaling-stroke; }
.xh-map circle { fill: currentColor; fill-opacity: .35; cursor: pointer; transition: fill-opacity .3s, r .3s; }
.xh-map circle.is-seen { fill-opacity: .75; }
.xh-map circle.is-on { fill: var(--accent2); fill-opacity: 1; }
.xh-where { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.xh-ch { font-size: 12.5px; opacity: .62; }
.xh-t { font: 600 16px/1.2 var(--display); white-space: nowrap; }
.xh--br { bottom: 22px; right: 24px; display: flex; align-items: center; gap: 8px; }
.xh-count { font: 500 13px/1 var(--label); letter-spacing: .04em; margin-right: 8px; font-variant-numeric: tabular-nums; opacity: .8; }
.xh-count b { font-weight: 600; opacity: 1; }
.xh button { position: relative; width: 40px; height: 40px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, .22); background: rgba(255, 255, 255, .06);
  color: inherit; display: grid; place-items: center; cursor: pointer; padding: 0; transition: background-color .2s, border-color .2s; }
.xh button:hover { background: rgba(255, 255, 255, .14); border-color: rgba(255, 255, 255, .4); }
.xh button:focus-visible { outline: 2px solid var(--accent2); outline-offset: 2px; }
.xh button:disabled { opacity: .35; cursor: default; }
.xh button svg { width: 14px; height: 14px; }
.xh-play .ring { position: absolute; inset: -1px; width: 40px; height: 40px; transform: rotate(-90deg); }
.xh-play .ring circle { fill: none; stroke: var(--accent2); stroke-width: 2; stroke-dasharray: 119.4; stroke-dashoffset: 119.4; }
.xh-play .i-pause { display: none; }
.is-playing .xh-play .i-pause { display: block; }
.is-playing .xh-play .i-play { display: none; }
.xh-hint { position: fixed; z-index: 20; left: 50%; bottom: 30px; transform: translateX(-50%); font: 500 13px/1 var(--label); color: var(--canvas-ink);
  opacity: .7; pointer-events: none; transition: opacity .6s; white-space: nowrap; }
.xh-hint.is-off { opacity: 0; }
.xp-ldr { position: fixed; inset: 0; display: grid; place-items: center; z-index: 50; background: var(--canvas); color: var(--canvas-ink);
  font: 500 14px/1 var(--label); letter-spacing: .04em; transition: opacity .5s; }
.xp-ldr.is-off { opacity: 0; pointer-events: none; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

@media (max-width: 700px) {
  .xh--tl span, .xh-hint { display: none; }
  .xh-map { width: 44px; height: 44px; }
  .xh-t { font-size: 14px; max-width: 46vw; overflow: hidden; text-overflow: ellipsis; }
  .xh--br .xh-prev, .xh--br .xh-next { display: none; }
}

/* portrait scenes: everything stacks */
.sc.is-portrait .rg--top { grid-template-columns: 1fr; gap: calc(24 * var(--u)); }
.sc.is-portrait .rg--top .grp--text { grid-column: 1; }
.sc.is-portrait .hd { font-size: calc(68 * var(--u)); }
.sc.is-portrait .tx { font-size: calc(30 * var(--u)); }
.sc.is-portrait .card p { font-size: calc(24 * var(--u)); }
.sc.is-portrait .card h3 { font-size: calc(30 * var(--u)); }
.sc.is-portrait .grp--card { flex-direction: column; }
.sc.is-portrait .grp--stat { flex-wrap: wrap; }
.sc.is-portrait .grp--stat > * { flex: 1 1 40%; }
.sc.is-portrait .rg--bottom { flex-direction: column; }
.sc.is-portrait .grp--list { flex-direction: column; }
.sc.is-portrait .lay-hero .rg--center, .sc.is-portrait.lay-hero .rg--center { position: static; width: auto; height: auto; flex: 1; }
.sc.is-portrait.lay-hero .rg--right { margin: 0; }

/* ---------- refinements ---------- */
.rg--center, .rg--left, .rg--right { justify-content: safe center; }
.grp--image.is-flat { flex: none; height: calc(120 * var(--u)); }
.rg--left .grp--image.is-flat .fr { left: 0 !important; }
.rg--center.is-narrow .grp--card { flex-direction: column; gap: calc(16 * var(--u)); }
.rg--center.is-narrow .card { padding: calc(20 * var(--u)) calc(24 * var(--u)); flex-direction: row; align-items: flex-start; gap: calc(18 * var(--u)); }
.rg--center.is-narrow .card__ic { flex: none; margin: 0; width: calc(44 * var(--u)); height: calc(44 * var(--u)); }
.rg--center.is-narrow .card h3 { font-size: calc(20 * var(--u)); margin-bottom: calc(6 * var(--u)); }
.rg--center.is-narrow .card p { font-size: calc(16 * var(--u)); }
.rg--center.is-narrow .card > div { min-width: 0; }
.grp--stat.is-compact .stat__bar { margin: calc(14 * var(--u)) 0 calc(12 * var(--u)); }
.rg--center.is-narrow .stat { box-shadow: none; padding-left: 0; }
/* palettes stay compact so a full visual-language frame fits */
.sws.is-big .sw i { height: calc(76 * var(--u)); }
.sws:not(.is-big) .sw i { height: calc(46 * var(--u)); border-radius: calc(10 * var(--u)); }
.sws:not(.is-big) .sw b { font-size: calc(13.5 * var(--u)); }
.sws:not(.is-big) .sw code { font-size: calc(12.5 * var(--u)); }
.sw > div { line-height: 1.2; }
.grp--swatches { gap: calc(18 * var(--u)); }
.grp--type .ty__aa { font-size: calc(84 * var(--u)); }
.lay-device .rg--left .grp--image.is-flat { height: calc(150 * var(--u)); }
.card__b { display: flex; flex-direction: column; gap: calc(12 * var(--u)); min-width: 0; }
.rg--center.is-narrow .card__b { gap: calc(4 * var(--u)); }
.tx .ln { white-space: nowrap; }
/* grid dots: a plane a few viewports wide, moved with the camera modulo one dot step (never repainted) */
.xp-dots { position: absolute; left: 0; top: 0; width: 600vmax; height: 600vmax; margin: -300vmax 0 0 -300vmax; transform-origin: 300vmax 300vmax; pointer-events: none;
  background-image: radial-gradient(circle, rgba(255, 255, 255, .085) 0 1.6px, transparent 2.2px); background-size: var(--step, 40px) var(--step, 40px);
  background-position: 300vmax 300vmax; }
.xp-dots { will-change: transform; }

.xp-dots { width: 400vmax; height: 400vmax; margin: -200vmax 0 0 -200vmax; transform-origin: 200vmax 200vmax; background-position: 200vmax 200vmax; }
.tx .w { display: inline-block; overflow: clip; overflow-clip-margin: calc(6 * var(--u)); padding-bottom: .1em; margin-bottom: -.1em; vertical-align: top; }
.tx .wi { display: inline-block; }

/* ---------- kinetic type at the viewport edges (behind the frames; never scaled, so always crisp) ---------- */
.xp-kin { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.kin { position: absolute; inset: 0; }
.kin > div { position: absolute; white-space: nowrap; font-family: var(--display); font-weight: 600; line-height: .8; will-change: transform; }
.kin__h { left: calc(var(--gut) * .45); top: calc(var(--ftop) - var(--kh) * .5); font-size: var(--kh); letter-spacing: -.045em;
  color: transparent; -webkit-text-stroke: 1.5px rgba(233, 235, 247, .2); }
.kin__l, .kin__r { top: 50%; writing-mode: vertical-rl; font-size: var(--kv); letter-spacing: -.02em; }
.kin__l { left: calc((var(--gut) - var(--kv) * .8) / 2); color: color-mix(in oklab, var(--accent2) 16%, transparent); }
.kin__r { right: calc((var(--gut) - var(--kv) * .8) / 2); color: transparent; -webkit-text-stroke: 1.5px rgba(233, 235, 247, .16); font-variant-numeric: tabular-nums; }

/* ---------- HUD: chapter segments ---------- */
.xh-chs { left: 50%; bottom: 30px; transform: translateX(-50%); width: min(420px, 34vw); display: flex; gap: 6px; }
.xh .xh-seg { position: relative; width: auto; height: 22px; border: 0; border-radius: 0; background: none; padding: 0; display: block; cursor: pointer; }
.xh .xh-seg:hover { background: none; }
.xh-seg::before { content: ''; position: absolute; left: 0; right: 0; top: 10px; height: 2px; border-radius: 1px; background: rgba(255, 255, 255, .18); }
.xh-seg i { position: absolute; left: 0; right: 0; top: 10px; height: 2px; border-radius: 1px; background: var(--accent2); transform: scaleX(0); transform-origin: 0 50%; }
.xh-seg span { position: absolute; left: 0; bottom: 16px; font-size: 11.5px; white-space: nowrap; opacity: 0; transform: translateY(4px); transition: opacity .3s, transform .3s; }
.xh-seg.is-on span, .xh-seg:hover span, .xh-seg:focus-visible span { opacity: .75; transform: none; }
.xh-hint { bottom: 64px; }
@media (max-width: 700px) { .xh-chs { display: none; } }

/* =====================================================================================================
   Scroll film: bigger hierarchy, chapter cards, HUD without codes
   ===================================================================================================== */
/* type scale, one step up across the board */
.hd { font-size: calc(72 * var(--u)); line-height: 1.04; letter-spacing: -.028em; }
.hd.is-long { font-size: calc(60 * var(--u)); line-height: 1.08; }
.hd.is-xl { font-size: calc(118 * var(--u)); line-height: .98; letter-spacing: -.035em; }
.tx { font-size: calc(25 * var(--u)); }
.rg--top .grp--text .tx { font-size: calc(24 * var(--u)); }
.stat__v { font-size: calc(150 * var(--u)); }
.card h3 { font-size: calc(28 * var(--u)); }
.card p { font-size: calc(19.5 * var(--u)); }
.sc__tag { font-size: calc(19 * var(--u)); gap: calc(12 * var(--u)); top: calc(44 * var(--u)); }
.sc__tag::before { display: none; }
.sc__tag b { font: 600 calc(19 * var(--u)) / 1 var(--display); color: var(--hi); font-variant-numeric: tabular-nums; padding-right: calc(12 * var(--u)); border-right: 2px solid var(--line); }
.sc__tag .t { opacity: .55; }

/* chapter title cards */
.lay-chapter .sc__in { padding: calc(110 * var(--u)) calc(120 * var(--u)) calc(120 * var(--u)); align-items: end; column-gap: calc(70 * var(--u)) !important; }
.lay-chapter .rg { justify-content: flex-end; }
.cnum { font: 600 calc(400 * var(--u)) / .78 var(--display); letter-spacing: -.06em; color: var(--hi); font-variant-numeric: tabular-nums; }
.cnum .w { display: inline-block; overflow: clip; overflow-clip-margin: calc(20 * var(--u)); padding: .04em 0 .02em; vertical-align: top; }
.cnum .wi { display: inline-block; }
.hd.is-mega { font-size: calc(150 * var(--u)); line-height: .92; letter-spacing: -.045em; color: #fff; }
.lst.is-toc ul { flex-direction: row; flex-wrap: wrap; gap: calc(12 * var(--u)) calc(34 * var(--u)); padding-top: calc(28 * var(--u)); border-top: 1px solid var(--line); }
.lst.is-toc li { font-size: calc(21 * var(--u)); color: var(--mut); gap: calc(10 * var(--u)); }
.lst.is-toc li .mk { width: calc(8 * var(--u)); height: calc(8 * var(--u)); }
.lay-chapter .rg--right { gap: calc(36 * var(--u)); padding-bottom: calc(16 * var(--u)); }

/* kinetic type: bigger, a touch more present */
.kin__h { -webkit-text-stroke: 2px rgba(233, 235, 247, .24); top: calc(var(--ftop) - var(--kh) * .56); }
.kin.is-card .kin__h { color: color-mix(in oklab, var(--accent2) 14%, transparent); -webkit-text-stroke: 0; }
.kin__l { color: color-mix(in oklab, var(--accent2) 22%, transparent); }

/* HUD: no counters or codes; chapter + title, chapter segments, a thin progress line, autoplay */
.xh-count, .xh-prev, .xh-next { display: none !important; }
.xh-ch { display: flex; gap: 8px; align-items: baseline; }
.xh-n { font: 600 12.5px/1 var(--display); color: var(--accent2); font-variant-numeric: tabular-nums; }
.xh-t { font-size: 17px; }
.xh-t:empty { display: none; }
.xh-map circle.is-card { fill-opacity: .55; }
.xh-bar { position: fixed; z-index: 20; left: 0; right: 0; top: 0; height: 2px; background: rgba(255, 255, 255, .06); pointer-events: none; }
.xh-bar i { position: absolute; inset: 0; background: var(--accent2); transform-origin: 0 50%; transform: scaleX(0); }
.xh-seg i { transform: scaleX(0); }
.xh-hint { display: flex; flex-direction: column; align-items: center; gap: 10px; bottom: 58px; font-size: 13px; letter-spacing: .02em; }
.xh-hint i { width: 1.5px; height: 26px; background: linear-gradient(var(--accent2), transparent); animation: xp-cue 1.8s cubic-bezier(.6, 0, .3, 1) infinite; transform-origin: 50% 0; }
@keyframes xp-cue { 0% { transform: scaleY(0); } 50% { transform: scaleY(1); transform-origin: 50% 0; } 51% { transform-origin: 50% 100%; } 100% { transform: scaleY(0); transform-origin: 50% 100%; } }
@media (prefers-reduced-motion: reduce) { .xh-hint i { animation: none; } }
.lay-hero .hd.is-xl { font-size: calc(98 * var(--u)); }
.lay-hero .rg--left { gap: calc(24 * var(--u)); }
.lay-hero .rg--left .grp--image.is-flat { height: calc(96 * var(--u)); }
.co-layer, .dev { overflow: visible; }
.co-layer { will-change: opacity; }
/* frames and the world keep their compositor layers for the whole film: no layer creation (and re-raster) at scene
   boundaries while scrolling. Frames rest at an integer translate with scale 1, so they raster at full resolution. */
.sc { will-change: transform, opacity; }
.xp-world { will-change: transform; }
.xp-dots { left: 0; top: 0; width: calc(100vw + 2 * var(--step, 40px)); height: calc(100vh + 2 * var(--step, 40px)); margin: 0; transform-origin: 0 0; background-position: 0 0; }

/* =====================================================================================================
   The frame around the slides, in the language of the industrial-design stories (Aqua Nova):
   Archivo for everything (statements at 64% width, weight 800), Martian Mono only for units and the loader number,
   sentence case, text straight on the stage at 5vw margins, one accent for hairlines, indices and the rail.
   ===================================================================================================== */
:root { --ground: var(--fr-ground, #1B2554); --chrome: var(--fr-ink, #EDEBE6); --quiet: rgba(237, 235, 230, .66); --faint: rgba(237, 235, 230, .5);
  --brass: var(--accent2, #F8DB21); --hair: color-mix(in oklab, var(--brass) 75%, transparent); --smoke: color-mix(in oklab, var(--ground) 82%, #000);
  --canvas: var(--ground); --canvas-ink: var(--chrome); --cond: 'Archivo', system-ui, sans-serif; --mono: 'Martian Mono', ui-monospace, monospace; }
html, body { background: var(--ground); color: var(--chrome); }
body { font-family: 'Archivo', system-ui, sans-serif; }
button:focus-visible, [tabindex]:focus-visible, a:focus-visible { outline: 1px solid var(--brass); outline-offset: 5px; }
.sc:not(.is-built) .it { visibility: inherit; }

/* loader (dial-loader.js turns it into the site's dial) */
html.ld { overflow: hidden; background: var(--ground); }
html.ld:not(.warm) body > :not(.ldr) { visibility: hidden; }
.ldr { position: fixed; inset: 0; z-index: 1000; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
  background: var(--ground); color: var(--chrome); transition: opacity .7s ease, visibility .7s; }
html:not(.ld) .ldr { opacity: 0; visibility: hidden; pointer-events: none; }
.ldr p { margin: 0; opacity: 0; transition: opacity .5s; }
.ldr.f p { opacity: 1; }
.ldr-t { font: 600 16px/1 'Archivo', system-ui, sans-serif; font-stretch: 80%; letter-spacing: .01em; }
.ldr-b { width: min(220px, 52vw); height: 1px; background: color-mix(in srgb, var(--chrome) 14%, transparent); }
.ldr-b i { display: block; height: 100%; background: var(--brass); transform-origin: 0 0; transform: scaleX(var(--ld, 0)); transition: transform .3s ease-out; }
.ldr-n { font: 400 11px/1 var(--mono); letter-spacing: .04em; color: var(--faint); font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) { .ldr, .ldr p, .ldr-b i { transition: none; } }

/* the journey: a tall section with a sticky stage */
.journey { position: relative; }
.xp-stage { position: sticky; top: 0; height: 100vh; overflow: hidden; z-index: auto; }
.xp-stage > * { position: absolute; }
.xp-dots { z-index: 0; opacity: .7; }
.xp-bgw, .xp-slides, .xp-narr, .xp-top { inset: 0; pointer-events: none; }
.xp-bgw { z-index: 1; }
.xp-bg { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
.xp-top { z-index: 3; }
.xp-slides { z-index: 4; }
.xp-narr { z-index: 6; }

/* slides: unchanged cards (their look and flight stay as they were) */
.xs { position: absolute; left: 0; top: 0; pointer-events: auto; will-change: transform, opacity; transform-origin: 50% 50%;
  /* each slide lays out on its own: a style read inside one (GSAP measuring a from-state) re-lays only that slide */
  contain: layout style; }
.xs .xp-tilt-inner { position: relative; width: 100%; height: 100%; will-change: transform; }
/* pointer parallax moves these whole planes: they stay layers, so a pointer move never re-layers the page */
.xp-bgw, .xp-top, .xp-slides, .xp-narr { will-change: transform; }
/* the back pill: solid here, no backdrop blur over a moving stage (an extra render pass every frame) */
html body .back { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; background: rgba(22, 19, 16, .74) !important; }
html body .back:hover, html body .back:focus-visible { background: rgba(22, 19, 16, .86) !important; }
/* one slide frame per project (motion theme slideFrame: { radius, border, shadow }, set as --sf-r / --sf-shadow):
   14px corners, no border line, one soft shadow. No ring here: a frame inside a slide never doubles its edge. */
.xs .sc { position: relative; left: auto; top: auto; opacity: 1; will-change: auto; border-radius: var(--sf-r, 14px);
  box-shadow: var(--sf-shadow, 0 calc(30 * var(--u)) calc(80 * var(--u)) calc(-34 * var(--u)) rgba(2, 4, 18, .6)); }
/* every item that builds, and the parts that build on their own, keep a layer from load: the builds are compositor
   moves (no layer made or dropped mid-scroll, no repaint of the slide), all rasterised once under the loader */
/* the pieces inside a slide are NOT promoted for good: a layer per piece (a thousand on the text-heavy decks) made
   every frame's compositing slow. GSAP lifts a piece onto its own layer only while it animates (force3D auto). */
.xs .sc__in { padding: calc(84 * var(--u)) calc(96 * var(--u)); }
.xs .lay-device .sc__in { padding: calc(56 * var(--u)); }
.cap b { color: var(--brass); font-weight: 400; margin-right: 10px; }

/* text on the stage */
.nb { inset: 0; position: absolute; will-change: opacity; }
/* the parts that fade or draw on their own get their own layers too: no repaint of the block mid-fade */
.nb .body, .nb .num b, .nb .num > span, .nb .spec tr { will-change: opacity; }
.nb .num .lead { will-change: transform; }
.mq { will-change: opacity; }
.nb .statement { position: absolute; margin: 0; font-weight: 800; font-stretch: 64%; line-height: .88; letter-spacing: -.012em; color: var(--chrome);
  font-size: min(5.6vw, 9.8vh); max-width: 11ch; text-wrap: balance; }
.nb .statement .ln { display: block; }
.nb .statement em { font-style: normal; color: var(--brass); }
.nb .body { position: absolute; margin: 0; font-size: clamp(18px, 1.3vw, 21px); line-height: 1.55; color: var(--quiet); max-width: 38ch; opacity: 0; }
.nb .num { position: absolute; width: max-content; max-width: 30vw; }
.nb .num .lead { display: block; width: 7vw; height: 1px; background: var(--hair); transform-origin: 0 50%; transform: scaleX(0); margin-bottom: 18px; }
.nb .num b { display: block; font-stretch: 75%; font-weight: 200; font-size: min(9vw, 15.5vh); line-height: .82; color: var(--chrome); letter-spacing: -.02em; opacity: 0; font-variant-numeric: tabular-nums; }
.nb .num > span { display: block; font-size: 15px; line-height: 1.4; color: var(--quiet); margin-top: 10px; max-width: 24ch; opacity: 0; }
.unit { font-family: var(--mono); font-size: .16em; letter-spacing: 0; font-weight: 400; color: var(--brass); vertical-align: .9em; margin-left: .3em; }
.nb .slot { position: absolute; }
/* text on the left (slide right) */
.nb.l .statement { left: 5vw; top: 12vh; }
.nb.l .num { left: 5vw; top: 46vh; }
.nb.l .body { left: 5.3vw; bottom: 9vh; }
.nb.l .slot { left: 5vw; top: 46vh; width: 30vw; height: 30vh; }
.nb.l:has(.num) .slot { left: 20vw; width: 16vw; }
/* text on the right (slide left) */
.nb.r .statement { left: 62vw; top: 12vh; }
.nb.r .num { left: 62vw; top: 46vh; }
.nb.r .body { left: 62.3vw; bottom: 9vh; }
.nb.r .slot { left: 62vw; top: 46vh; width: 30vw; height: 30vh; }
.nb.r:has(.num) .slot { left: 77vw; width: 16vw; }
/* centred, around a focus */
.nb.c .statement { left: 50%; top: 7vh; transform: translateX(-50%); text-align: center; max-width: none; font-size: min(4.6vw, 8.4vh); }
.nb.c .body { left: 50%; bottom: 5vh; transform: translateX(-50%); text-align: center; max-width: 60ch; }
/* the opening: hero statement bottom-left, one line under it */
.nb.hero .statement { left: 5vw; bottom: calc(8vh + 104px); font-size: min(8.6vw, 15vh); max-width: 9ch; will-change: transform; }
.nb.hero .body { left: 5.4vw; bottom: calc(8vh + 18px); max-width: 44ch; }
.nb.hero .slot { left: 40vw; top: 60vh; width: 17vw; height: 30vh; }

/* chapter statements: all type, the slides gone */
.st .statement { max-width: 14ch; font-size: min(10vw, 17vh); }
.st--xxl .statement { font-size: min(13vw, 19.5vh); max-width: 12ch; }   /* four lines still fit the stage */
.st--center .statement { left: 50%; top: 50%; transform: translate(-50%, -54%); text-align: center; }
.st--left .statement { left: 5vw; top: 13vh; }
.st .sub { left: 50%; bottom: 9vh; transform: translateX(-50%); text-align: center; font-size: 15px; }
.st.is-wipe .statement { clip-path: inset(-0.5em 100% -0.5em -0.5em); }
.st.is-last .statement { left: 5vw; top: 13vh; transform: none; text-align: left; }
.st.is-last .sub { left: 5.3vw; transform: none; text-align: left; bottom: 9vh; max-width: 40ch; }

/* datasheet, bottom-right of the last statement */
.nb .spec { position: absolute; right: 5vw; bottom: 9vh; width: min(520px, 40vw); border-collapse: collapse; font-size: 15px; line-height: 1.45; }
.nb .spec tr { border-top: 1px solid color-mix(in srgb, var(--brass) 28%, transparent); opacity: var(--o, 0); }
.nb .spec tr:last-child { border-bottom: 1px solid color-mix(in srgb, var(--brass) 28%, transparent); }
.nb .spec th { text-align: left; font-weight: 400; color: var(--faint); padding: 10px 18px 10px 0; vertical-align: top; width: 30%; }
.nb .spec td { padding: 10px 0; color: var(--chrome); }
.nb .spec .mth .msteps { display: flex; flex-wrap: wrap; row-gap: 2px; list-style: none; padding: 0; margin: 3px 0 0; font-size: 13px; opacity: .72; }
.nb .spec .mth .msteps li + li::before { content: ''; display: inline-block; width: 12px; height: 1px; background: currentColor; opacity: .55; vertical-align: middle; margin: 0 7px; }

/* marquee rows */
.mq { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: center; gap: 1vh; }
.mq__row { white-space: nowrap; font: 800 min(12vw, 22vh) / .9 var(--cond); font-stretch: 64%; color: var(--chrome); will-change: transform; width: max-content; }
.mq__row span { margin-right: 4vw; }
.mq__row .o { color: transparent; -webkit-text-stroke: 1.5px var(--faint); }
.mq__row--1 { color: var(--brass); }
.mq__row--1 .o { -webkit-text-stroke-color: color-mix(in oklab, var(--brass) 70%, transparent); }

/* lifted items carry their slide's surface */
.bo-h { position: absolute; left: 0; top: 0; transform-origin: 50% 50%; will-change: transform, opacity; pointer-events: none; overflow: visible !important;
  background: var(--sbg) !important; border-radius: calc(var(--sf-r, 14px) * .6) !important; outline: 0;
  box-shadow: 0 0 0 calc(22 * var(--u)) var(--sbg), 0 calc(40 * var(--u)) calc(90 * var(--u)) calc(-10 * var(--u)) rgba(2, 4, 18, .75) !important; }
.bo-c { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.bo-c > .fw { position: absolute; }
.bo-sh { position: absolute; left: 0; top: 0; }
.bo-h .bo { position: relative; visibility: visible; }

/* mark, rail (with chapter ticks to jump to), hint, vignette, grain */
.mark { z-index: 9; left: 5vw; top: 4.2vh; font-size: 16px; font-weight: 600; font-stretch: 80%; letter-spacing: .01em; opacity: .9; }
.rail { z-index: 9; right: 18px; top: 30vh; height: 40vh; width: 1px; background: color-mix(in srgb, var(--chrome) 12%, transparent); }
.rail > i { position: absolute; left: 0; top: 0; width: 1px; height: 100%; background: var(--brass); transform-origin: 0 0; transform: scaleY(0); will-change: transform; }
.rail__t { position: absolute; right: -6px; width: 13px; height: 13px; margin-top: -6px; padding: 0; border: 0; background: none; cursor: pointer; color: var(--chrome); }
.rail__t::before { content: ''; position: absolute; left: 2px; right: 2px; top: 6px; height: 1px; background: currentColor; opacity: .5; }
.rail__t.is-on::before { background: var(--brass); opacity: 1; }
.rail__t span { position: absolute; right: 22px; top: 50%; transform: translateY(-50%); white-space: nowrap; font-size: 13px; color: var(--quiet); opacity: 0; transition: opacity .25s; pointer-events: none; }
.rail__t:hover span, .rail__t:focus-visible span, .rail__t.is-on span { opacity: 1; }
.rail__t.is-on span { color: var(--chrome); }
.hint { z-index: 9; left: 50%; bottom: 4vh; transform: translateX(-50%); font-size: 13px; color: var(--quiet); transition: opacity .6s; will-change: opacity; }
.hint.is-off { opacity: 0; }
.vignette { inset: 0; z-index: 8; pointer-events: none; background: radial-gradient(120% 95% at 50% 46%, transparent 52%, rgba(4, 6, 20, .38) 82%, rgba(2, 3, 12, .62)); }
@keyframes grain { 0% { transform: translate(0, 0); } 20% { transform: translate(-5.17%, 3.45%); } 40% { transform: translate(3.45%, -5.17%); } 60% { transform: translate(-3.45%, -1.72%); } 80% { transform: translate(5.17%, 5.17%); } }
.grain { inset: -8%; z-index: 8; pointer-events: none; opacity: .085; mix-blend-mode: overlay; animation: grain .6s steps(1) infinite; animation-play-state: paused;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.xp-stage.moving .grain { animation-play-state: running; }
@media (prefers-reduced-motion: reduce) { .grain { animation: none; } }
html.xp-paused { overflow: hidden; }

/* after the film: the reel and the method */
.reel.xp-endown { background: var(--ground); position: relative; padding: 12vh 5vw 4vh; } /* the slides: one row the visitor scrolls sideways on their own; page scroll never moves it */
.xp-endown .reel-grid { display: flex; align-items: flex-start; gap: 2.4vw; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scroll-padding: 0 5vw; margin: 0 -5vw; padding: 10px 5vw 22px; scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--brass) 40%, transparent) transparent; }
.xp-endown .reel-grid > .fr { flex: 0 0 min(58vw, 96vh); scroll-snap-align: start; }
@media (max-width: 700px) { .xp-endown .reel-grid { gap: 4vw; margin: 0 -6vw; padding: 10px 6vw 18px; scroll-padding: 0 6vw; } .xp-endown .reel-grid > .fr { flex-basis: 84vw; } }
.xp-endown .cap { font-size: 14px; line-height: 1.45; color: var(--faint); max-width: 40ch; }
.reel.xp-endown > .cap { margin: 0 0 30px; }
.reel.xp-endown .fr { position: relative; margin: 0; background: var(--smoke); padding: 5px; box-shadow: 0 0 0 1px color-mix(in srgb, var(--brass) 14%, transparent); }
.reel.xp-endown .fr .pv { display: block; overflow: hidden; }
.reel.xp-endown .fr img { display: block; width: 100%; height: auto; }
.reel.xp-endown .fr::before, .reel.xp-endown .fr::after, .reel.xp-endown .fr > i::before, .reel.xp-endown .fr > i::after { content: ''; position: absolute; width: 9px; height: 9px; border: 0 solid var(--brass); }
.reel.xp-endown .fr::before { left: -6px; top: -6px; border-left-width: 1px; border-top-width: 1px; }
.reel.xp-endown .fr::after { right: -6px; top: -6px; border-right-width: 1px; border-top-width: 1px; }
.reel.xp-endown .fr > i::before { left: -6px; bottom: -6px; border-left-width: 1px; border-bottom-width: 1px; }
.reel.xp-endown .fr > i::after { right: -6px; bottom: -6px; border-right-width: 1px; border-bottom-width: 1px; }
@media (prefers-reduced-motion: reduce) { .reel.xp-endown .fr img { transform: none; will-change: auto; } }
.mend.xp-endown { background: var(--ground); color: var(--chrome); padding: 0 0 10vh; }
.xp-endown .mfull { margin: 4vh 5vw 0; }
.xp-endown .mfull .cap { margin: 0 0 12px; }
.xp-endown .mfull .mhead { font-size: clamp(32px, 3.6vw, 56px); line-height: .95; margin: 0 0 4.5vh; font-weight: 800; font-stretch: 64%; letter-spacing: -.01em; }
.xp-endown .mcols { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); gap: 0 2.4vw; }
.xp-endown .mcols li { position: relative; padding-top: 16px; }
.xp-endown .mcols li::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: currentColor; opacity: .28; }
.xp-endown .mcols b { display: block; font-weight: 500; font-size: 16px; margin-bottom: 8px; }
.xp-endown .mcols p { margin: 0; font-size: 15px; line-height: 1.5; opacity: .74; max-width: 34ch; }
.xp-endown .reel-end { margin-top: 8vh; }
.xp-endown .endcta { display: inline-block; font-size: 16px; padding: 12px 0; color: var(--chrome); text-decoration: none; border-bottom: 1px solid var(--brass); }
.xp-endown .endcta:hover { color: var(--brass); }
@media (max-width: 1000px) { .xp-endown .mcols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4.5vh 5vw; } }
@media (max-width: 700px) {
  .nb .body { font-size: 16px; } .nb .statement { font-size: 9.5vw; } .st .statement { font-size: 13vw; } .nb.hero .statement { font-size: 16vw; }
  .nb.l .statement, .nb.r .statement { left: 6vw; top: 9vh; } .nb.l .body, .nb.r .body { left: 6vw; right: 6vw; bottom: auto; top: 27vh; }
  .nb.l .num, .nb.r .num { display: none; }
  .nb .spec { width: 90vw; right: 5vw; bottom: 6vh; font-size: 14px; } .nb .spec th, .nb .spec td { padding: 7px 10px 7px 0; }
  .rail { right: 8px; }
}
@media (max-width: 600px) { .xp-endown .mfull { margin-top: 8vh; } .xp-endown .mcols { grid-template-columns: 1fr; gap: 3.2vh; } }
.xp-stage { inset: auto; left: 0; right: 0; top: 0; }
.fr-rail .rail__t { pointer-events: auto; }

/* hold the frame loader until the film is ready */
html.xp-wait { overflow: hidden; }
html.xp-wait body > :not(.ldr) { visibility: hidden !important; }
html.xp-wait .ldr { opacity: 1 !important; visibility: visible !important; }
html .mark.fr-mark { color: var(--chrome); }
html .xe-end { --xe-ground: var(--ground); --xe-ink: var(--chrome); }


/* warm-up under the loader: every built part shown at full opacity once, so each layer is rasterised before the
   reader reaches it (the builds start from opacity 0, which would otherwise leave them unrasterised) */
html.warm .xs .it, html.warm .xs .it * { opacity: 1 !important; visibility: visible !important; }
html .xs.is-warm .it, html .xs.is-warm .it * { opacity: 1 !important; visibility: visible !important; }

/* the motion theme's backdrop motif (themes/<id>.js): above the dot grid and spiral, below statements and slides */
.xp-motif { inset: 0; z-index: 2; pointer-events: none; overflow: hidden; opacity: .45; }   /* the theme motif stays a quiet backdrop */
/* statements that arrive with a transform (motion.statement rise / stamp / slide): their own transform layer, so a
   moving block is composited, never re-rasterised (at rest the transform is none: crisp) */
.nb.is-mo { will-change: transform, opacity; }

/* =====================================================================================================
   layout 'figma' (FIGMA-LAYOUT.md): the Figma frame rebuilt in frame px inside one container, scaled down only.
   layout 'html': the designed board in a shadow root (htmlslide.js), on the same box.
   ===================================================================================================== */
.fg { position: absolute; left: 0; top: 0; transform-origin: 0 0; overflow: hidden; font-size: 16px; line-height: normal; }
.fg.is-pan, .fh-pos.is-pan { will-change: transform; }
.fw { position: absolute; }
.fw > .it { position: absolute; inset: 0; margin: 0; }
.xs .it.is-static { will-change: auto; }
.fx-text { white-space: normal; overflow-wrap: break-word; font-kerning: normal; color: var(--fg); }
.fx-text.is-nw { white-space: nowrap; }
.fx-text .w { display: inline-block; overflow: clip; overflow-clip-margin: .12em; padding-bottom: .1em; margin-bottom: -.1em; vertical-align: top; }
.fx-text .wi { display: inline-block; }
.fx-text .em { color: var(--fx-em, var(--hi)); }
.fx-text .n { font-variant-numeric: tabular-nums; }
.fx-img { overflow: hidden; }
.fx-img > img, .fx-svg > img { display: block; width: 100%; height: 100%; }
.fx-svg > img { object-fit: contain; }
.fx-svg > svg { display: block; width: 100%; height: 100%; overflow: visible; }
/* a UI screen: whole, on a window (browser: a thin bar with three dots; device: a dark bezel; none: bare) */
.fx-scr { display: flex; flex-direction: column; overflow: hidden; background: #fff; }
.fx-scr.is-none { background: transparent; }
.fx-scr.is-device { background: #0e0f13; }
.fx-scr__v { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; }
.fx-scr__v img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: 50% 0%; }
.fx-scr.is-scroll .fx-scr__v img { height: auto; will-change: transform; }
.xbar { flex: none; display: flex; align-items: center; gap: calc(var(--bh, 24px) * .26); height: var(--bh, 24px); padding: 0 calc(var(--bh, 24px) * .5);
  background: color-mix(in oklab, var(--sbg) 55%, #fff); box-shadow: inset 0 calc(-1 * var(--px)) 0 var(--ring); }
.is-dark .xbar { background: color-mix(in oklab, var(--sbg) 82%, #fff); }
.xbar i { width: calc(var(--bh, 24px) * .27); height: calc(var(--bh, 24px) * .27); border-radius: 50%; background: color-mix(in oklab, var(--fg) 20%, transparent); }
/* the reveal: a cover of the slide ground slides off (its own layer; never a clip-path) */
.fx-cov { position: absolute; inset: 0; background: var(--sbg); transform-origin: 100% 50%; will-change: transform; pointer-events: none; z-index: 2; }
.fh-pos { position: absolute; left: 0; top: 0; overflow: hidden; }
.fh { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.fh-park { position: fixed; left: -30000px; top: 0; visibility: hidden; pointer-events: none; }
.sc.is-missing::after { content: ''; position: absolute; inset: 0; background: repeating-linear-gradient(45deg, transparent 0 14px, var(--ring) 14px 15px); }
.fx-dash { position: absolute; inset: 0; overflow: visible; pointer-events: none; }
.fx-text .run { white-space: inherit; }

/* =====================================================================================================
   touch, tablets, phones. Desktop is untouched: every rule below is gated on a class engine.js measure() sets
   (html.xp-port: upright, vw/vh < .9; .xp-phone: upright and under 600 wide; .xp-tab: upright and wider;
   .xp-short: a phone on its side) or on a width / pointer query that a desktop window does not meet.
   ===================================================================================================== */
/* the text column never runs under the slide beside it (a 1024-1279 wide stage: 38ch of body passed 37vw) */
@media (min-width: 701px) { .nb.l .body, .nb.r .body { max-width: min(38ch, 31vw); } }
/* the page's own scroll cue (js/scroll-cue.js) speaks for touch; one cue, not two */
@media (pointer: coarse) { .hint { display: none; } }

/* upright: one idea per screen. The beat's text stacks from the top (the opening's from the foot), in flow, so a
   long headline pushes its line down instead of running into it; the slide takes the room left (portArea) */
html.xp-port .nb:not(.st) { display: flex; flex-direction: column; align-items: flex-start; gap: 1.6vh; gap: 1.6svh; box-sizing: border-box;
  padding: calc(max(74px, 9vh) + env(safe-area-inset-top, 0px)) 6vw 0; padding-top: calc(max(74px, 9svh) + env(safe-area-inset-top, 0px)); }
html.xp-port .nb:not(.st) .statement, html.xp-port .nb:not(.st) .body, html.xp-port .nb:not(.st) .num { position: relative; inset: auto; transform: none; text-align: left; margin: 0; }
html.xp-port .nb:not(.st) .statement { font-size: min(7.4vw, 5.6vh); max-width: 16ch; }
html.xp-port .nb:not(.st) .body { font-size: clamp(16px, 2.3vw, 20px); line-height: 1.5; max-width: 40ch;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; line-clamp: 4; overflow: hidden; }
html.xp-port .nb:not(.st) .slot { display: none; }
html.xp-port .nb:not(.st) .num { order: 3; max-width: none; }
html.xp-port .nb:not(.st) .num .lead { width: 12vw; margin-bottom: 10px; }
html.xp-port .nb:not(.st) .num b { font-size: min(11vw, 7.5vh); }
html.xp-port .nb.hero { justify-content: flex-end; padding-top: 0; padding-bottom: calc(max(84px, 10vh) + env(safe-area-inset-bottom, 0px)); padding-bottom: calc(max(84px, 10svh) + env(safe-area-inset-bottom, 0px)); }
html.xp-port .nb.hero .statement { font-size: min(10.5vw, 8vh); max-width: 11ch; }
/* chapter statements: centred in the visible screen, not the one under the browser's bar */
html.xp-port .st--center:not(.is-last) .statement { top: 50svh; }
/* upright phones: big and minimal. A large headline, at most three lines of copy, no numeral, no callouts */
html.xp-phone .nb:not(.st) .statement { font-size: clamp(32px, 10.4vw, 46px); max-width: none; }
html.xp-phone .nb.hero .statement { font-size: clamp(44px, 14.5vw, 64px); max-width: none; }
html.xp-phone .nb:not(.st) .body { font-size: 16px; line-height: 1.45; -webkit-line-clamp: 3; line-clamp: 3; }
html.xp-phone .nb:not(.st) .num { display: none; }
html.xp-phone .st .statement { max-width: 88vw; }
html.xp-phone .mq__row { font-size: 17vw; }
/* a device's callouts are 9px labels at a phone or tablet's portrait slide size: the screen speaks for itself */
.sc.is-portrait .co-layer, html.xp-short .co-layer { visibility: hidden; }

/* a phone on its side: the side-by-side stage, tightened to 390-ish px of height */
html.xp-short .nb .statement { font-size: min(5vw, 11vh); }
html.xp-short .nb.l .statement, html.xp-short .nb.r .statement { top: 16vh; }
html.xp-short .nb .body { font-size: 14px; line-height: 1.45; bottom: 7vh; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; }
html.xp-short .nb.l .body, html.xp-short .nb.r .body { max-width: 31vw; }
html.xp-short .nb .num { display: none; }
html.xp-short .nb.hero .statement { font-size: min(7.5vw, 16vh); bottom: calc(7vh + 72px); }
html.xp-short .nb.hero .body { max-width: 36vw; bottom: 7vh; }
html.xp-short .nb.c .statement { top: 5vh; font-size: min(4.2vw, 9vh); }
html.xp-short .nb.c .body { bottom: 3vh; -webkit-line-clamp: 2; line-clamp: 2; }
