/* ============================================================================
   VECREAL — FIELD COMPOSITIONS
   Named stages built from the Field system. Each block owns one idea; nothing
   here redefines a token or a base component.
   ========================================================================== */

/* ==========================================================================
   HERO — the era
   ========================================================================== */
.hero{position:relative;min-height:100svh;padding-top:clamp(72px,8vw,104px);padding-bottom:clamp(28px,3.5vw,44px);
  display:flex;align-items:stretch}
.hero .frame{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;flex:1;min-height:0}
/* the stage holds a focused pool of light behind the spine so the field reads
   as one lit instrument, not chips floating in the dark (the V6 hero pool
   renders at its authored strength — no dimming) */
.hero .ground .halo{position:absolute;left:50%;top:72%;width:min(1100px,92vw);aspect-ratio:2.6/1;
  transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;
  background:radial-gradient(closest-side,rgba(184,73,50,.12),rgba(184,73,50,.045) 46%,transparent 72%)}
/* the authored line break owns the wrap; no measure cap fighting it */
.hero h1{max-width:none;margin-top:20px;text-wrap:initial}
.hero h1 .c{color:var(--clay-display)}
.hero .lead{margin-top:24px;max-width:52ch;text-align:center}
.hero .actions{margin-top:34px;justify-content:center}
.hero .facts{display:inline-flex;margin-top:30px;border:var(--hair) solid var(--line);border-radius:var(--r-2);
  background:rgba(255,255,255,.02);overflow:hidden}
.hero .facts span{font-family:var(--mono);font-size:var(--mono-m3-size);letter-spacing:var(--mono-m3-track); /* M3 */
  color:var(--mute);padding:8px 14px;border-left:var(--hair) solid var(--line-2);white-space:nowrap}
.hero .facts span:first-child{border-left:0}
@media(max-width:640px){
  .hero .facts{display:grid;grid-template-columns:1fr;width:100%}
  .hero .facts span{border-left:0;border-top:var(--hair) solid var(--line-2);text-align:center}
  .hero .facts span:first-child{border-top:0}
}

/* ---- the field: the whole job as one measured instrument ----
   The resting state is complete and legible. Motion is an entrance plus a slow
   read-pulse travelling the threads; the field is never blank on first paint,
   which is what sank the earlier fog/constellation attempt. */
.hero-field{position:relative;user-select:none;-webkit-user-select:none;width:min(1240px,100%);flex:0 0 auto;max-width:1240px;margin:clamp(34px,4vw,54px) auto 0;
  height:clamp(300px,32svh,380px);min-height:300px;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 6%,#000 94%,transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 6%,#000 94%,transparent 100%)}
/* far layer: fainter, slightly soft — the record has depth beyond the surface */
.hf-t.ghost{opacity:.28;height:4px;filter:none}
}

.threads{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none;z-index:2}
.threads path{fill:none;stroke:rgba(242,241,237,.16);stroke-width:1;stroke-linecap:round}
.threads circle{fill:var(--clay-lit);opacity:.85}
/* the read-pulse: a short dash running each thread into the node */
.threads .pulse{stroke:#D8A89D;stroke-width:1.6;opacity:.9;
  stroke-dasharray:18 var(--len,600);stroke-dashoffset:var(--len,600);
animation-delay:calc(var(--k,0)*.42s)}
@keyframes hf-run{from{stroke-dashoffset:var(--len,600)}to{stroke-dashoffset:0}}
.spine-node{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:34px;height:34px;
  border-radius:9px;background:var(--clay-display);color:#fff;display:flex;align-items:center;justify-content:center;
  box-shadow:0 0 0 10px rgba(184,73,50,.08),0 0 30px rgba(184,73,50,.35)}
.spine-node svg{width:58%;height:58%}
@keyframes hf-answer{
  0%,20%,100%{border-color:var(--line);background:rgba(255,255,255,.03);transform:none}
  5%,15%{border-color:rgba(198,128,112,.55);background:rgba(198,128,112,.08);transform:translateY(-2px)}}
@media(prefers-reduced-motion:reduce){
  .hero-field.built .hf-o,}

@media(max-width:860px){
  .threads{display:none}
}
@media (prefers-reduced-motion:reduce){
  .threads .pulse{animation:none;stroke-dashoffset:0;stroke-dasharray:none;opacity:.35}
}

/* ==========================================================================
   THE CONDITION — the open loop (antagonist stage)
   ========================================================================== */
.loop-figure{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:clamp(16px,3vw,44px);
  padding:clamp(26px,3.4vw,48px) clamp(20px,3vw,40px);border-radius:var(--r-3);
  border:var(--hair) solid var(--line);background:var(--bg-1);box-shadow:var(--inner),var(--lift-sm)}
.loop-cell{text-align:center}
.loop-cell .hd{display:flex;align-items:baseline;justify-content:center;gap:10px;margin-bottom:6px}
.loop-cell .hd b{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute)}
.loop-cell .hd b.c{color:var(--accent)}
.loop-cell .hd span{font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:var(--mute)}
.loop-cell iframe{display:block;width:100%;max-width:266px;margin:0 auto;aspect-ratio:318.4/253.8;border:0;
  background:transparent;color-scheme:light}
.loop-cell p{font-size:var(--t-cap);line-height:1.5;color:var(--mute);max-width:32ch;margin:2px auto 0}
.loop-cell p b{color:var(--ink);font-weight:580}
.loop-arrow{color:var(--accent);opacity:.85}
.loop-arrow svg{width:34px;height:16px;stroke:currentColor;fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.loop-close{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,3vw,44px);margin-top:clamp(30px,3.6vw,50px)}
.loop-close .br{font-size:var(--t-body);line-height:1.6;color:var(--mute);padding-left:17px;
  border-left:2px solid var(--accent)}
.loop-close .br b{display:block;font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--accent);margin-bottom:8px}
@media(max-width:860px){
  .loop-figure{grid-template-columns:1fr;gap:22px}
  .loop-arrow{transform:rotate(90deg);justify-self:center}
  .loop-close{grid-template-columns:1fr;gap:20px}
}
/* the loop dial embeds are authored light; keep them readable on night */
.night .loop-cell .dialwrap{background:var(--day-1);border-radius:var(--r-2);padding:6px;
  border:var(--hair) solid var(--line)}

/* ==========================================================================
   THE LAYER — the record exhibit with computed leaders
   ========================================================================== */
.layer-fig{border-radius:var(--r-3);border:var(--hair) solid var(--line);background:var(--bg-1);
  box-shadow:var(--inner),var(--lift)}
.layer-fig .hd{border-radius:var(--r-3) var(--r-3) 0 0}
.layer-fig .layer-body{border-radius:0 0 var(--r-3) var(--r-3)}
.layer-fig .hd{display:flex;align-items:center;justify-content:center;gap:9px;padding:13px 18px;
  border-bottom:var(--hair) solid var(--line)}
.layer-fig .hd b{font-size:var(--t-ui);font-weight:600;letter-spacing:-.014em;color:var(--ink)}
.layer-fig .hd b i{font-style:normal;color:var(--accent)}
.layer-body{padding:clamp(20px,2.6vw,30px);position:relative}
.ledger{border-radius:var(--r-2);border:var(--hair) solid var(--line);overflow:hidden;background:var(--bg-1);
  box-shadow:0 1px 2px rgba(25,24,23,.04);user-select:none}
.ledger .lh{display:flex;justify-content:space-between;padding:9px 16px;border-bottom:var(--hair) solid var(--line-2);
  background:var(--bg-2)}
.ledger .lh span{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute)}
.lrow{display:grid;grid-template-columns:88px 1fr 108px 76px 104px;gap:16px;align-items:center;padding:11px 16px;
  font-family:var(--mono);font-size:var(--mono-m3-size);letter-spacing:var(--mono-m3-track); /* M3 */
  color:var(--mute);position:relative}
/* .4 dimmed a --mute row to about 2.4:1. .62 still reads as receded
   and clears 4.5:1, which is what a dimmed row of real numbers needs. */
.lrow.dim{opacity:.89}
.lrow.hot{color:var(--ink);background:var(--bg-1)}
.lrow.hot::before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--accent);
  transform:scaleY(0);transform-origin:top;transition:transform var(--m-4) var(--e-out) 240ms}
.callouts.in ~ .ledger .lrow.hot::before,.layer-body.in .lrow.hot::before{transform:scaleY(1)}
.lrow .r{text-align:right}
.anch{border-bottom:1px dotted var(--clay-line);padding-bottom:1px;transition:color var(--m-2) var(--e-fast),
  border-color var(--m-2) var(--e-fast)}
.anch.hot{color:var(--ink);border-bottom:1px solid var(--accent)}
.layer-notes{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(18px,2.4vw,34px);
  margin-top:clamp(70px,8vw,104px)}
.lnote{position:relative}
.lnote .k{display:block;font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--accent);margin-bottom:7px}
.lnote .t{display:block;font-size:var(--t-ui);font-weight:580;color:var(--ink);line-height:1.45}
.lnote .s{display:block;font-size:var(--t-cap);color:var(--mute);line-height:1.5;margin-top:5px}
.lnote .src{display:block;margin-top:10px;padding-top:10px;border-top:var(--hair) solid var(--line-2);
  font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;line-height:1.6;color:var(--mute)}
.lnote .src b{color:var(--ink);font-weight:var(--mono-m2-weight)}
.layer-leads{position:absolute;inset:0;pointer-events:none;z-index:4}
.layer-leads svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.layer-leads path{fill:none;stroke:var(--clay);stroke-width:1;stroke-linecap:round;opacity:.55;
  transition:stroke-dashoffset var(--m-5) var(--e-out)}
.layer-leads.in path{stroke-dashoffset:0!important}
.layer-leads circle{fill:var(--clay);opacity:0;transition:opacity var(--m-3) var(--e-fast) 420ms}
.layer-leads.in circle{opacity:.9}
@media(max-width:900px){
  .lrow{grid-template-columns:64px 1fr 80px;gap:10px;padding:9px 12px}
  .lrow span:nth-child(4),.lrow span:nth-child(5){display:none}
  .layer-notes{grid-template-columns:1fr;gap:20px;margin-top:30px}
  .layer-leads{display:none}
}

/* ==========================================================================
   EXHIBIT — composed product moments (recut walkthrough ranges)
   ========================================================================== */
.exhibit{display:grid;grid-template-columns:minmax(0,300px) minmax(0,1fr);gap:clamp(20px,3vw,48px);
  align-items:start}
.ex-rail{display:flex;flex-direction:column;border-top:var(--hair) solid var(--line)}
.ex-item{display:block;width:100%;text-align:left;padding:19px 2px 19px 18px;position:relative;
  border-bottom:var(--hair) solid var(--line);transition:padding-left var(--m-2) var(--e-out)}
.ex-item::before{content:"";position:absolute;left:0;top:-1px;bottom:-1px;width:2px;background:var(--accent);
  transform:scaleY(0);transform-origin:center;transition:transform var(--m-2) var(--e-out)}
.ex-item.on::before{transform:scaleY(1)}
.ex-item .k{display:block;font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute);
  margin-bottom:7px}
.ex-item .t{display:block;font-size:16px;font-weight:560;letter-spacing:-.018em;color:var(--mute);line-height:1.3;
  transition:color var(--m-2) var(--e-fast)}
.ex-item .d{display:block;font-size:var(--t-cap);line-height:1.5;color:var(--faint);margin-top:6px;max-width:34ch;
  transition:color var(--m-2) var(--e-fast)}
.ex-item:hover .t{color:var(--ink)}
.ex-item.on .k{color:var(--accent)}
.ex-item.on .t{color:var(--ink)}
.ex-item.on .d{color:var(--mute)}
.ex-stage{position:relative;border-radius:var(--r-3);overflow:hidden;border:var(--hair) solid var(--line);
  background:var(--bg-2);box-shadow:var(--lift)}
.ex-stage .port{position:relative;width:100%;aspect-ratio:16/9;overflow:hidden;background:#ECEEF1}
.ex-stage .port video,.ex-stage .port img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:var(--fx,50%) var(--fy,50%);transform:scale(var(--fk,1));transform-origin:var(--fx,50%) var(--fy,50%);
  transition:transform var(--m-5) var(--e-out)}
.ex-stage .band-label{position:absolute;left:0;right:0;bottom:0;z-index:3;display:flex;align-items:center;gap:10px;
  padding:13px 16px;background:linear-gradient(180deg,transparent,rgba(8,9,11,.82) 62%);color:#F2F1ED}
.ex-stage .band-label .m{font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:#C68070}
.ex-stage .band-label .n{font-size:var(--t-cap);color:rgba(242,241,237,.86)}
.ex-note{margin-top:16px;font-size:var(--t-cap);color:var(--mute);display:flex;align-items:center;gap:9px}
.ex-note svg{width:13px;height:13px;stroke:var(--accent);fill:none;stroke-width:1.9;flex:none}
@media(max-width:900px){
  .exhibit{grid-template-columns:1fr;gap:22px}
  .ex-rail{flex-direction:row;overflow-x:auto;border-top:0;border-bottom:var(--hair) solid var(--line);
    scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .ex-rail::-webkit-scrollbar{display:none}
  .ex-item{flex:0 0 auto;min-width:190px;border-bottom:0;padding:12px 16px 14px}
  .ex-item::before{top:auto;bottom:-1px;left:0;right:0;width:auto;height:2px;transform:scaleX(0)}
  .ex-item.on::before{transform:scaleX(1)}
  .ex-item .d{display:none}
}

/* ==========================================================================
   CURRENCIES — the four things a GC actually runs on
   Each stage is one currency, proven by one custom loop. The stages are
   deliberately identical in structure; the variety lives in the evidence.
   ========================================================================== */
.cur-index{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border-top:var(--hair) solid var(--line);
  margin-top:clamp(34px,4vw,54px)}
.cur-index a{position:relative;padding:20px 22px 22px 0;border-left:var(--hair) solid var(--line);
  padding-left:22px;transition:background var(--m-2) var(--e-fast)}
.cur-index a:first-child{border-left:0;padding-left:0}
.cur-index a::before{content:"";position:absolute;left:0;top:-1px;height:2px;width:0;background:var(--accent);
  transition:width var(--m-3) var(--e-out)}
.cur-index a.on::before{width:100%}
.cur-index a:first-child::before{left:0}
.cur-index .n{display:block;font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute);
  margin-bottom:9px}
.cur-index .t{display:block;font-size:17px;font-weight:560;letter-spacing:-.02em;color:var(--mute);
  transition:color var(--m-2) var(--e-fast)}
.cur-index .d{display:block;font-size:var(--t-cap);line-height:1.5;color:var(--faint);margin-top:6px}
.cur-index a:hover .t,.cur-index a.on .t{color:var(--ink)}
.cur-index a.on .n{color:var(--accent)}
@media(max-width:820px){
  .cur-index{grid-template-columns:1fr 1fr}
  .cur-index a{padding:16px 14px;border-left:var(--hair) solid var(--line);border-top:var(--hair) solid var(--line)}
  .cur-index a:nth-child(odd){border-left:0;padding-left:0}
  .cur-index a:nth-child(-n+2){border-top:0}
  .cur-index .d{display:none}
}

.currency{padding:var(--stage-y-sm) 0}
.currency+.currency{border-top:var(--hair) solid var(--line)}
.cur-head{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:clamp(24px,4vw,72px);
  align-items:end;margin-bottom:clamp(30px,3.6vw,48px)}
.cur-head .n{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute);
  display:block;margin-bottom:14px}
.cur-head .n b{color:var(--accent);font-weight:var(--mono-m1-weight)}
.cur-head .outcome{display:inline-flex;align-items:center;gap:9px;margin-top:18px;font-family:var(--mono);
  font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:var(--accent);
  border:var(--hair) solid var(--clay-line);background:var(--clay-soft);border-radius:100px;padding:6px 13px}
@media(max-width:880px){.cur-head{grid-template-columns:1fr;gap:18px;align-items:start}}

/* the loop plate — the asset is the evidence, so it gets the whole width */
.loop{position:relative;border-radius:var(--r-3);overflow:hidden;border:var(--hair) solid var(--line);
  background:var(--bg-2);box-shadow:var(--lift)}
.loop video,.loop img{display:block;width:100%;height:auto;aspect-ratio:1600/780;object-fit:cover;background:#F6F7F9}
.loop .cnr{position:absolute;width:11px;height:11px;border:1.4px solid var(--clay);opacity:.55;z-index:3}
.loop .cnr.tl{top:12px;left:12px;border-right:0;border-bottom:0}
.loop .cnr.br{bottom:12px;right:12px;border-left:0;border-top:0}
/* the control only surfaces when the loop is not running — reduced motion,
   a blocked autoplay, or a deliberate pause */
.playbtn{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) scale(.9);z-index:5;
  width:66px;height:66px;border-radius:50%;background:rgba(184,73,50,.94);color:#fff;
  display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;
  box-shadow:0 1px 0 rgba(255,255,255,.2) inset,0 18px 40px -14px rgba(25,24,23,.55);
  transition:opacity var(--m-2) var(--e-fast),transform var(--m-2) var(--e-out),background var(--m-1) var(--e-fast)}
.lm.img{-webkit-mask-image:none!important;mask-image:none!important;background-color:transparent!important;
  background-size:contain;background-position:center;background-repeat:no-repeat;
  filter:grayscale(1) contrast(.85);opacity:.8}
.playbtn svg{width:26px;height:26px;fill:currentColor;margin-left:3px}
.playbtn .ic-pause{display:none;margin-left:0;stroke:currentColor}
.loop.is-paused .playbtn{opacity:1;pointer-events:auto;transform:translate(-50%,-50%) scale(1)}
.playbtn:hover{background:var(--clay-display-hover);transform:translate(-50%,-50%) scale(1.05)}
/* while the loop is running, the same control waits quietly in the corner as
   a pause affordance (WCAG 2.2.2), surfacing on hover or keyboard focus */
.loop:not(.is-paused) .playbtn{left:auto;right:14px;top:auto;bottom:14px;transform:none;
  width:38px;height:38px;background:rgba(25,24,23,.55);backdrop-filter:blur(4px);
  box-shadow:0 4px 14px -6px rgba(25,24,23,.5)}
.loop:not(.is-paused) .playbtn .ic-play{display:none}
.loop:not(.is-paused) .playbtn .ic-pause{display:block;width:17px;height:17px}
.loop:not(.is-paused):hover .playbtn,.loop:not(.is-paused) .playbtn:focus-visible{opacity:1;pointer-events:auto}
.loop:not(.is-paused) .playbtn:hover{background:rgba(25,24,23,.75);transform:none}
.loop.is-paused::after{content:"";position:absolute;inset:0;z-index:4;pointer-events:none;
  background:rgba(246,247,249,.26)}
.loop-note{display:flex;align-items:center;gap:10px;margin-top:16px;font-family:var(--mono);
  font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:var(--mute)}
.loop-note i{width:5px;height:5px;border-radius:50%;background:var(--accent);flex:none}

/* ==========================================================================
   PRODUCT PLATES — PI / FI
   ========================================================================== */
.products{display:grid;grid-template-columns:minmax(0,1.32fr) minmax(0,1fr);gap:clamp(16px,1.8vw,24px)}
/* believable chrome: the surface presents as the deployed app, status honest */
.pbar{display:flex;align-items:center;gap:6px;padding:9px 14px;border-bottom:var(--hair) solid var(--line-2);
  background:var(--bg-2);flex:none}
.pbar .d{width:9px;height:9px;border-radius:50%;background:var(--line);flex:none}
.pbar .url{margin-left:8px;font-family:var(--mono);font-size:var(--mono-m3-size);letter-spacing:var(--mono-m3-track); /* M3 */
  color:var(--mute);
  background:var(--bg-1);border:var(--hair) solid var(--line-2);border-radius:5px;padding:3px 12px;
  flex:1;min-width:0;max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}
.pbar .st{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);
  font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:var(--mute);white-space:nowrap}
.pbar .st i{width:6px;height:6px;border-radius:50%;flex:none}
.pbar .st .ok{background:var(--ok,#5DA17D)}
.pplate{display:flex;flex-direction:column;border-radius:var(--r-3);border:var(--hair) solid var(--line);
  background:var(--bg-1);box-shadow:var(--inner),var(--lift-sm);overflow:hidden;
  transition:transform var(--m-2) var(--e-out),border-color var(--m-2) var(--e-fast),box-shadow var(--m-3) var(--e-fast)}
.pplate:hover{transform:translateY(-3px);border-color:var(--clay-line);box-shadow:var(--inner),var(--lift)}
.pplate .pv{position:relative;height:clamp(190px,20vw,246px);overflow:hidden;flex:none}
.pplate .pv .glyph{position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:11px;transition:opacity var(--m-3) var(--e-fast)}
.pplate:hover .pv .glyph{opacity:0}
.pplate .pv .glyph svg{width:44px;height:36px;color:var(--accent)}
.pplate[data-fi] .pv .glyph svg{color:var(--ink)}
.pplate .pv .glyph .g1{font-size:19px;font-weight:580;letter-spacing:-.022em;color:var(--ink)}
.pplate .pv .glyph .g2{font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:var(--mute)}
.pplate .pv .real{position:absolute;inset:0;opacity:.24;filter:grayscale(.4) contrast(.96);
  background:#F6F7F9;transition:opacity var(--m-4) var(--e-fast),filter var(--m-4) var(--e-fast)}
.pplate:hover .pv .real{opacity:1;filter:none}
.pplate .pv .real iframe{position:absolute;left:0;top:0;width:1280px;height:1000px;border:0;pointer-events:none;
  transform-origin:0 0;background:#F6F7F9}
.pplate .pb{padding:22px 24px 24px;display:flex;flex-direction:column;flex:1}
.pplate .ph{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.pplate .ph .mk{width:26px;height:26px;border-radius:7px;background:var(--clay);color:#fff;display:flex;
  align-items:center;justify-content:center;flex:none}
.pplate[data-fi] .ph .mk{background:var(--ink);color:var(--bg-1)}
.pplate .ph .mk svg{width:60%;height:60%}
.pplate .ph b{font-size:16px;font-weight:600;letter-spacing:-.018em;color:var(--ink)}
.pplate .ph .pill{margin-left:auto}
.pplate .rows{border-top:var(--hair) solid var(--line-2);margin-top:2px}
.pplate .rows .r{display:flex;gap:12px;padding:9px 0;border-bottom:var(--hair) solid var(--line-2);font-size:12.5px}
.pplate .rows .r .k{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;
  color:var(--accent);width:88px;flex:none;padding-top:3px}
.pplate .rows .r .v{color:var(--mute);line-height:1.45}
.pplate .go{margin-top:16px;display:inline-flex;align-items:center;gap:7px;font-family:var(--mono);
  font-size:var(--mono-m3-size);letter-spacing:var(--mono-m3-track); /* M3 */
  font-weight:600;color:var(--accent)}
.pplate .go svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2;
  transition:transform var(--m-2) var(--e-out)}
.pplate:hover .go svg{transform:translateX(3px)}
@media(max-width:900px){.products{grid-template-columns:1fr}}

/* ==========================================================================
   OUTCOMES
   ========================================================================== */
.outcomes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(14px,1.6vw,22px)}
.ocard{border-radius:var(--r-3);border:var(--hair) solid var(--line);background:var(--bg-1);overflow:hidden;
  box-shadow:var(--inner),var(--lift-sm);display:flex;flex-direction:column;
  transition:transform var(--m-2) var(--e-out),border-color var(--m-2) var(--e-fast),box-shadow var(--m-3) var(--e-fast)}
.ocard:hover{transform:translateY(-3px);border-color:var(--clay-line);box-shadow:var(--inner),var(--lift)}
.ocard .fig{padding:20px 20px 16px;border-bottom:var(--hair) solid var(--line-2)}
.ocard .fig svg{display:block;width:100%;max-width:280px;height:auto;margin:0 auto}
.ocard .bd{padding:18px 22px 22px}
.ocard h3{font-size:16.5px;font-weight:580;letter-spacing:-.02em;line-height:1.28;color:var(--ink);margin-bottom:8px}
.ocard p{font-size:var(--t-cap);line-height:1.55;color:var(--mute)}
@media(max-width:720px){.outcomes{grid-template-columns:1fr}}

/* ==========================================================================
   STACK BAND — models + infrastructure
   ========================================================================== */
.stack{display:grid;grid-template-columns:minmax(0,300px) minmax(0,1fr);align-items:stretch;
  border:var(--hair) solid var(--line);border-radius:var(--r-3);overflow:hidden;background:var(--bg-1);
  box-shadow:var(--inner),var(--lift-sm)}
.stack .srow{display:contents}
.stack .sk{padding:26px 28px;border-top:var(--hair) solid var(--line-2);display:flex;flex-direction:column;
  justify-content:center}
.stack .sv{padding:24px 30px;border-top:var(--hair) solid var(--line-2);border-left:var(--hair) solid var(--line-2);
  display:flex;align-items:center}
.stack .srow:first-child .sk,.stack .srow:first-child .sv{border-top:0}
.stack .sk .k{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;
  color:var(--accent);margin-bottom:10px}
.stack .sk .v{font-size:var(--t-cap);line-height:1.5;color:var(--mute)}
.stack .sk .v b{color:var(--ink);font-weight:580}
.stack .logo{color:var(--ink)}
/* the row centres in its cell: left-aligned, the plate's right half sat empty
   at desktop widths and the rows read as stopping short rather than composed */
.stack .sv .logos{justify-content:center}
@media(max-width:820px){
  .stack{grid-template-columns:1fr}
  .stack .sv{border-left:0;border-top:0;padding-top:0}
  .stack .srow:first-child .sv{border-top:0}
  .stack .sk{padding-bottom:14px}
}
.trust{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(12px,1.4vw,18px)}
.tcard{border-radius:var(--r-3);border:var(--hair) solid var(--line);background:var(--bg-1);
  box-shadow:var(--inner),var(--lift-sm);padding:22px 22px 24px;
  transition:border-color var(--m-2) var(--e-fast),box-shadow var(--m-3) var(--e-fast)}
.tcard:hover{border-color:var(--clay-line)}
.tcard .th{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;
  color:var(--accent);padding-bottom:14px;margin-bottom:16px;border-bottom:var(--hair) solid var(--line-2)}
@media(max-width:980px){.trust{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:560px){.trust{grid-template-columns:1fr}}

/* ==========================================================================
   PRODUCT SURFACE — a live screen shown as a plate, never in browser chrome
   ========================================================================== */
.surface{position:relative;border-radius:var(--r-3);overflow:hidden;border:var(--hair) solid var(--line);
  background:var(--bg-2);box-shadow:var(--lift)}
.surface .port{position:relative;width:100%;aspect-ratio:1280/760;overflow:hidden;background:#F6F7F9}
.surface .port iframe{position:absolute;left:0;top:0;width:1280px;height:760px;border:0;transform-origin:0 0;
  background:#F6F7F9}
.surface .stamp{position:absolute;right:14px;top:14px;z-index:4;display:inline-flex;align-items:center;gap:7px;
  font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:var(--day-mute);
  background:rgba(251,252,254,.92);border:var(--hair) solid var(--day-line);border-radius:100px;padding:5px 11px}
.surface .stamp i{width:6px;height:6px;border-radius:50%;background:var(--good);flex:none}
.surface .cnr{position:absolute;width:11px;height:11px;border:1.4px solid var(--clay);opacity:.5;z-index:3}
.surface .cnr.tl{top:12px;left:12px;border-right:0;border-bottom:0}
.surface .cnr.br{bottom:12px;right:12px;border-left:0;border-top:0}

/* ==========================================================================
   ASK VEC — the same model, only one of them has the project
   ========================================================================== */
.compare{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(14px,1.6vw,22px)}
.cpane{display:flex;flex-direction:column;border-radius:var(--r-3);border:var(--hair) solid var(--line);
  background:var(--bg-1);box-shadow:var(--inner),var(--lift-sm);overflow:hidden;min-height:330px}
.cpane.vec{border-color:var(--clay-line);box-shadow:var(--inner),var(--lift)}
.cpane .ch{display:flex;align-items:center;gap:9px;padding:13px 18px;border-bottom:var(--hair) solid var(--line-2);
  background:var(--bg-2)}
.cpane .ch b{font-size:var(--t-ui);font-weight:580;letter-spacing:-.014em;color:var(--ink)}
.cpane .ch .tagx{margin-left:auto;font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:var(--mute)}
.cpane.vec .ch .tagx{color:var(--accent)}
.cpane .ch .mk{width:22px;height:22px;border-radius:6px;background:var(--clay);color:#fff;display:flex;
  align-items:center;justify-content:center;flex:none}
.cpane .ch .mk svg{width:60%;height:60%}
.cpane .ch .mk.grey{background:var(--bg-2);color:var(--faint);border:var(--hair) solid var(--line)}
.cpane .cb{padding:18px 20px 20px;flex:1;font-size:var(--t-cap);line-height:1.62;color:var(--mute)}
.cpane .cb b{color:var(--ink);font-weight:560}
.cpane .cb .q{display:block;font-size:var(--t-ui);font-weight:540;color:var(--ink);margin-bottom:14px;
  padding-bottom:14px;border-bottom:var(--hair) solid var(--line-2)}
/* depicted citation chip: record-id content keeps data casing at micro size */
.cpane .cite{display:inline-block;font-family:var(--mono);font-size:var(--mono-m2-size);
  letter-spacing:var(--mono-m3-track);color:var(--accent);
  border:var(--hair) solid var(--clay-line);background:var(--clay-soft);border-radius:4px;padding:0 5px;
  margin-left:3px;vertical-align:1px}
.cpane .empty{color:var(--faint);font-style:normal}
.compare-note{display:flex;align-items:center;justify-content:center;gap:10px;margin-top:20px;font-family:var(--mono);
  font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:var(--mute);text-align:center}
.compare-note b{color:var(--accent);font-weight:600}
@media(max-width:820px){.compare{grid-template-columns:1fr}}

/* ==========================================================================
   CAPABILITY ROWS — alternating claim / evidence
   ========================================================================== */
.cap-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);gap:clamp(26px,4vw,68px);
  align-items:center;padding:clamp(34px,4vw,58px) 0;border-top:var(--hair) solid var(--line)}
.cap-row:first-child{border-top:0}
.cap-row.flip>.cap-copy{order:2}
.cap-row .n{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute);display:block;
  margin-bottom:14px}
.cap-row .n b{color:var(--accent);font-weight:var(--mono-m1-weight)}
.cap-row .cap-copy h3{font-size:var(--t-sub);font-weight:var(--w-display);letter-spacing:var(--ls-sub);line-height:1.18;
  color:var(--ink);margin-bottom:14px}
.cap-row .cap-copy p{font-size:var(--t-body);line-height:1.62;color:var(--mute);max-width:46ch}
.cap-row .cap-copy p b{color:var(--ink);font-weight:560}
.cap-fig{position:relative;border-radius:var(--r-3);overflow:hidden;border:var(--hair) solid var(--line);
  background:var(--bg-2);box-shadow:var(--lift-sm)}
/* a crop is a deliberate detail, so its cut edges feather rather than
   ending in a hard line the eye reads as a broken screenshot */
.cap-fig::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:2;
  background:linear-gradient(90deg,transparent 82%,var(--bg-2) 100%),
             linear-gradient(180deg,transparent 84%,var(--bg-2) 100%)}
.cap-fig .port{position:relative;width:100%;aspect-ratio:16/10;overflow:hidden;background:#F6F7F9}
.cap-fig .port iframe{position:absolute;left:0;top:0;width:1280px;height:800px;border:0;transform-origin:0 0;
  background:#F6F7F9;pointer-events:none}
@media(max-width:880px){
  .cap-row{grid-template-columns:1fr;gap:22px}
  .cap-row.flip>.cap-copy{order:0}
}

/* ==========================================================================
   FIRM LAYER — projects in, one layer, insights out
   The left column shows projects as live sheets (record-lines, one hot);
   the hub is the one night-material element on the day ground; computed
   wires (field.js ioWire) carry the sheets into it and out to the insights.
   ========================================================================== */
/* the columns stretch to one height and distribute; the labels sit outside
   the flow so a column's box is its cards and nothing else, which is what lets
   the hub and the wires centre on the same line */
.io{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1.18fr);
  gap:clamp(48px,6.5vw,104px);align-items:stretch;padding-top:30px}
.iowires{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none;z-index:0}
.iowires path{fill:none;stroke:var(--clay-line);stroke-width:var(--hair)}
.iowires circle{fill:var(--accent)}
.io-col{display:flex;flex-direction:column;gap:12px;justify-content:space-between;
  position:relative;z-index:1}
.io-col .h{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute);
  position:absolute;left:0;bottom:100%;margin:0 0 10px;white-space:nowrap}
/* a project is the thing being built: an isometric massing of it, the contract
   value, the stage it is in, and how much of it is standing */
.io-sheet{display:grid;grid-template-columns:80px minmax(0,1fr);align-items:stretch;
  border-radius:var(--r-2);border:var(--hair) solid var(--line);background:var(--bg-1);
  box-shadow:var(--lift-sm);overflow:hidden;
  transition:transform var(--m-2) var(--e-out),border-color var(--m-2) var(--e-fast),
             box-shadow var(--m-2) var(--e-fast)}
.io-sheet:hover{transform:translateY(-2px);border-color:var(--clay-line);box-shadow:var(--lift)}
.io-sheet .gl{display:grid;place-items:center;border-right:var(--hair) solid var(--line-2);
  background:linear-gradient(180deg,rgba(25,24,23,.012),transparent 62%)}
.io-sheet .gl svg{display:block;width:58px;height:52px}
/* opaque faces: a volume in front must occlude the one behind it, so the
   shading is solid tone rather than a tint that stacks */
.io-sheet .gl path{stroke:#9A9C9F;stroke-width:.8;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.io-sheet .gl .f-top{fill:#F5F5F6}
.io-sheet .gl .f-right{fill:#E9EAEC}
.io-sheet .gl .f-left{fill:#DEDFE2}
.io-sheet .bd{display:block;min-width:0;padding:14px 16px 15px}
.io-sheet .ln{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.io-sheet .nm{font-size:14.5px;font-weight:560;letter-spacing:-.014em;color:var(--ink)}
/* off-scale on purpose: the completion figure is sized to sit on the
   project name's baseline, between M3 and body */
.io-sheet .pc{font-family:var(--mono);font-size:15px;letter-spacing:-.01em;
  font-variant-numeric:tabular-nums;color:var(--ink);line-height:1}
.io-sheet .pc i{font-style:normal;font-size:10px;color:var(--faint);margin-left:1px;vertical-align:1px}
.io-sheet .mt{display:block;margin-top:5px;font-family:var(--mono);font-size:var(--mono-m2-size);
  color:var(--mute);
  font-weight:var(--mono-m2-weight);letter-spacing:var(--mono-m2-track);text-transform:uppercase;
  color:var(--faint)}
/* a machined channel, not a pill: the fill sits in a recess with a lit crown */
.io-sheet .pg{display:block;position:relative;margin-top:12px;height:5px;border-radius:3px;
  background:var(--bg-2);
  box-shadow:inset 0 1px 2px rgba(25,24,23,.14),inset 0 0 0 var(--hair) rgba(25,24,23,.06)}
.io-sheet .pg i{display:block;height:100%;width:var(--p,50%);border-radius:3px;
  background:linear-gradient(180deg,var(--clay-lit),var(--clay-brand));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.30);transform:scaleX(0);transform-origin:left center}
html.field-ready .io.in .io-sheet .pg i{transform:scaleX(1);transition:transform .9s var(--e-out) .35s}
@media(prefers-reduced-motion:reduce){html.field-ready .io-sheet .pg i{transform:scaleX(1);transition:none}}
/* the hub: night material on day ground — elevation and edge, never tint */
.io-hub{position:relative;z-index:1;align-self:center;display:flex;flex-direction:column;
  align-items:center;gap:12px;
  padding:26px 26px 24px;border-radius:var(--r-3);background:#0D0F12;border:1px solid #22262C;
  min-width:196px;box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 22px 44px -20px rgba(13,16,20,.5)}
/* the same spec as the product tiles (.amk): measured, this mark's glyph
   filled 55% of a 38px tile against the reference's 58% of 36 -- close enough
   to pass a diff, far enough to read as a slightly different mark. One spec. */
.io-hub .mk{width:36px;height:36px;border-radius:10px;background:#F7F8F8;color:#15161A;display:flex;
  align-items:center;justify-content:center}
.io-hub .mk svg{width:60%;height:60%}
.io-hub .t{font-size:var(--t-ui);font-weight:580;letter-spacing:-.016em;color:#F7F8F8;text-align:center}
.io-hub .s{font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:#C68070;text-align:center}
.io-item.out{display:flex;align-items:flex-start;padding:13px 16px;border-radius:var(--r-2);
  border:var(--hair) solid var(--line);background:var(--bg-1);box-shadow:var(--lift-sm)}
.io-item.out .nm{font-size:14px;line-height:1.5;color:var(--mute)}
.io-item.out .nm b{display:block;font-size:14.5px;font-weight:580;letter-spacing:-.012em;color:var(--ink);
  margin-bottom:2px}
@media(max-width:880px){
  .io{grid-template-columns:1fr;gap:18px;padding-top:26px}
  .iowires{display:none}.io-hub{min-width:0}
  .io-col{justify-content:flex-start;gap:10px}
  .io-col.out .h{position:static;margin:14px 0 4px}
}
@media(max-width:520px){
  .io-sheet{grid-template-columns:64px minmax(0,1fr)}
  .io-sheet .gl svg{width:46px;height:41px}
}

/* the ledger trace — one insight, followed to firm policy */
/* the ledger line as a pipeline: four cells on one plate, each stage more
   committed than the last; the material progression carries the argument */
/* four set plates on the band ground, chained by a clay hairline. The recessed
   tray they used to sit in is the only recess in the build and belongs to none
   of the figures around it. */
.trace{position:relative;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  grid-template-rows:auto auto 1fr auto;column-gap:clamp(12px,1.4vw,20px);row-gap:0}
/* the cells share the parent's rows, so a two-line title in one cell drops the
   body of every cell to the same line */
.tstep{position:relative;display:grid;grid-row:span 4;grid-template-rows:subgrid;
  padding:16px 16px 14px;border-radius:var(--r-2);
  background:var(--bg-1);border:var(--hair) solid var(--line);box-shadow:var(--lift-sm)}
.tstep:not(:first-child)::after{content:"";position:absolute;right:calc(100% + 1px);top:50%;
  width:clamp(12px,1.4vw,20px);height:var(--hair);background:var(--clay-line)}
.tstep .k{display:inline-flex;align-self:start;justify-self:start;font-family:var(--mono);
  font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;border-radius:100px;padding:4px 10px;margin-bottom:10px;
  color:var(--mute);border:var(--hair) solid var(--line);background:var(--bg-2)}
.tstep:nth-child(3) .k{color:var(--accent);border-color:var(--clay-line);background:rgba(156,74,51,.06)}
.tstep:nth-child(4) .k{color:#FBFCFE;border-color:var(--accent);background:var(--accent)}
.tstep:nth-child(4){border-color:var(--clay-line);background:linear-gradient(180deg,rgba(156,74,51,.05),rgba(156,74,51,.02))}
.trace .tstep:nth-child(4) h4{color:var(--accent);font-size:20px;font-weight:620;letter-spacing:-.026em}
.tstep h4{font-size:16px;font-weight:560;letter-spacing:-.018em;line-height:1.3;color:var(--ink);margin-bottom:7px}
.tstep p{font-size:var(--t-cap);line-height:1.55;color:var(--mute)}
/* entrance: cells commit left to right */
html.field-ready .trace .tstep{opacity:0;transform:translateY(10px);
  transition:opacity 480ms var(--e-out),transform 480ms var(--e-out);transition-delay:calc(var(--s,0)*140ms)}
html.field-ready .trace.in .tstep,html.field-ready .rv.in .tstep{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){html.field-ready .trace .tstep{opacity:1;transform:none;transition:none}}
@media(max-width:900px){.trace{grid-template-columns:1fr 1fr}
  .tstep:nth-child(3)::after{display:none}}
@media(max-width:560px){.trace{grid-template-columns:1fr}
  .tstep:not(:first-child)::after{display:none}}
.tstep .src{display:block;align-self:end;margin-top:11px;padding-top:10px;border-top:var(--hair) solid var(--line-2);
  font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:var(--mute)}
/* These once described a single divided plate, where a cell dropped its outer
   border and padding so the four read as one surface. Each .tstep is its own
   card now (own background, own border, own lift), so stripping the left edge
   left steps 1 and 3 with their content against the card wall and no rule down
   the side. The grid still collapses; the card no longer comes apart. */
@media(max-width:900px){
  .trace{grid-template-columns:1fr 1fr}
  .tstep{padding:22px 18px 24px}
}
@media(max-width:560px){
  .trace{grid-template-columns:1fr}
}

/* ==========================================================================
   ENGAGEMENT SCHEDULE — about
   ========================================================================== */
.wbs{border-top:var(--hair) solid var(--line)}
.wbs-row{display:grid;grid-template-columns:52px minmax(0,220px) 74px minmax(0,1fr);gap:clamp(14px,2vw,30px);
  padding:22px 0;border-bottom:var(--hair) solid var(--line-2);align-items:start}
.wbs-row .no{font-family:var(--mono);font-size:var(--mono-m3-size);letter-spacing:var(--mono-m3-track); /* M3 */
  font-weight:700;color:var(--accent)}
.wbs-row .nm{font-size:17px;font-weight:560;letter-spacing:-.018em;color:var(--ink)}
.wbs-row .du{font-family:var(--mono);font-size:var(--mono-m3-size);letter-spacing:var(--mono-m3-track); /* M3 */
  color:var(--mute);padding-top:3px}
.wbs-row .de{font-size:var(--t-cap);line-height:1.6;color:var(--mute)}
.wbs-head{display:grid;grid-template-columns:52px minmax(0,220px) 74px minmax(0,1fr);gap:clamp(14px,2vw,30px);
  padding:0 0 12px;font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;
  color:var(--mute)}
@media(max-width:760px){
  .wbs-row,.wbs-head{grid-template-columns:44px 1fr;gap:12px}
  .wbs-row .du{grid-column:2;padding-top:0}
  .wbs-row .de{grid-column:2}
  .wbs-head span:nth-child(3),.wbs-head span:nth-child(4){display:none}
}

/* principles */
.principles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0;border-top:var(--hair) solid var(--line)}
.principle{padding:26px 24px 28px;border-left:var(--hair) solid var(--line)}
.principle:first-child{border-left:0;padding-left:0}
.principle .no{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--accent);
  display:block;margin-bottom:14px}
.principle h4{font-size:17px;font-weight:560;letter-spacing:-.018em;line-height:1.3;color:var(--ink);margin-bottom:9px}
.principle p{font-size:var(--t-cap);line-height:1.55;color:var(--mute)}
@media(max-width:900px){
  .principles{grid-template-columns:1fr 1fr}
  .principle:nth-child(odd){border-left:0;padding-left:0}
  .principle:nth-child(n+3){border-top:var(--hair) solid var(--line)}
}
@media(max-width:560px){
  .principles{grid-template-columns:1fr}
  .principle{border-left:0;padding-left:0;border-top:var(--hair) solid var(--line)}
  .principle:first-child{border-top:0}
}

/* founder */
.founder{display:grid;grid-template-columns:minmax(0,300px) minmax(0,1fr);gap:clamp(28px,4vw,64px);
  align-items:start}
.founder .por{border-radius:var(--r-3);overflow:hidden;border:var(--hair) solid var(--line);
  box-shadow:var(--lift-sm);background:var(--bg-2)}
.founder .por img{width:100%;height:auto;display:block}
.founder .who{margin-top:18px}
.founder .who b{display:block;font-size:17px;font-weight:580;letter-spacing:-.018em;color:var(--ink)}
.founder .who span{display:block;font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;
  color:var(--mute);margin-top:6px}
.founder .who a{display:inline-block;margin-top:12px;font-size:var(--t-cap);color:var(--accent)}
.founder .say p{font-size:17px;line-height:1.66;color:var(--mute);max-width:60ch;margin-bottom:18px}
.founder .say p b{color:var(--ink);font-weight:560}
@media(max-width:820px){.founder{grid-template-columns:1fr;gap:26px}.founder .por{max-width:260px}}

/* ==========================================================================
   CLOSE
   ========================================================================== */
.close-stage .claim{max-width:22ch}
/* a closer that asks for its whole beat on one line gets the width for it:
   .claim.full loads earlier (field.css) and loses to the 22ch above on order
   alone, so the pairing is stated here where it can win */
.close-stage .claim.full{max-width:none}
.close-stage .note{margin-top:clamp(34px,4vw,52px);max-width:none}
.close-stage .actions{margin-top:clamp(30px,3.4vw,44px)}

/* ==========================================================================
   OPERATOR POLISH ROUND
   ========================================================================== */

/* product-page heroes are compact and centered; the 100svh flex stage is the
   home hero design, not a default */
.hero.hero-compact{min-height:0;display:block;padding-top:clamp(140px,16vw,190px);padding-bottom:clamp(64px,7vw,96px)}
.hero.hero-compact .frame{min-height:0}

/* --- the layer exhibit regains its production interactions --- */
.lnote{position:relative}
.lnote .cite{font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);line-height:1.6;color:var(--mute);
  border:var(--hair) solid var(--line);background:var(--bg-1);border-radius:4px;padding:0 4px;margin-left:6px;
  cursor:help;vertical-align:baseline;position:relative;top:-1px;
  transition:color var(--m-1) var(--e-fast),border-color var(--m-1) var(--e-fast),background var(--m-1) var(--e-fast)}
.lnote .cite:hover,.lnote .cite:focus-visible{color:var(--accent);border-color:var(--clay-line);background:rgba(156,74,51,.07)}
.lnote .pop{position:absolute;top:calc(100% + 10px);left:50%;transform:translateX(-50%) translateY(-5px);
  width:min(300px,88vw);background:var(--bg-1);border:var(--hair) solid var(--line);border-radius:var(--r-2);
  box-shadow:var(--lift);opacity:0;visibility:hidden;z-index:30;text-align:left;
  transition:opacity var(--m-2) var(--e-fast) 40ms,transform var(--m-2) var(--e-out) 40ms,visibility var(--m-2) 40ms}
.lnote.show-pop .pop{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0)}
.lnote .pop .ph{display:flex;justify-content:space-between;gap:10px;padding:8px 14px;
  background:var(--bg-2);border-bottom:var(--hair) solid var(--line);border-radius:var(--r-2) var(--r-2) 0 0;
  font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:var(--mute)}
.lnote .pop .ph b{color:var(--accent);font-weight:600}
.lnote .pop .pb{display:block;padding:12px 14px;font-size:12.5px;line-height:1.6;color:var(--mute)}
.lnote .pop .pb b{color:var(--ink);font-weight:600}
.anch{border-bottom:1px dotted var(--clay-line);padding-bottom:1px;cursor:help;
  transition:color var(--m-1) var(--e-fast),border-color var(--m-1) var(--e-fast)}
.anch.hl{color:var(--ink);border-bottom:1px solid var(--accent)}
.layer-leads path{transition:stroke var(--m-1) var(--e-fast),stroke-width var(--m-1) var(--e-fast)}
.layer-leads path.hl{stroke:var(--accent);stroke-width:1.5}
/* draw-in choreography, production grammar: plate, hot tick, leads, dots, notes */
html.field-ready .layer-fig .ledger{opacity:0;transform:translateY(8px);
  transition:opacity 520ms var(--e-out),transform 520ms var(--e-out)}
html.field-ready .layer-fig.in .ledger{opacity:1;transform:none;transition-delay:60ms}
html.field-ready .layer-fig .lrow.hot::before{transform:scaleY(0);transform-origin:top;
  transition:transform 420ms var(--e-out) 340ms}
html.field-ready .layer-fig.in .lrow.hot::before{transform:scaleY(1)}
html.field-ready .layer-fig .lnote{opacity:0;transform:translateY(10px);
  transition:opacity 520ms var(--e-out),transform 520ms var(--e-out)}
html.field-ready .layer-fig.in .lnote{opacity:1;transform:none}
html.field-ready .layer-fig.in .lnote:nth-child(1){transition-delay:300ms}
html.field-ready .layer-fig.in .lnote:nth-child(2){transition-delay:390ms}
html.field-ready .layer-fig.in .lnote:nth-child(3){transition-delay:480ms}
html.field-ready .layer-fig .layer-leads path{stroke-dasharray:var(--len,300);stroke-dashoffset:var(--len,300)}
html.field-ready .layer-fig.in .layer-leads path{stroke-dashoffset:0;
  transition:stroke-dashoffset 640ms var(--e-out),stroke var(--m-1) var(--e-fast),stroke-width var(--m-1) var(--e-fast)}
html.field-ready .layer-fig.in .layer-leads .ld1{transition-delay:520ms,0s,0s}
html.field-ready .layer-fig.in .layer-leads .ld2{transition-delay:610ms,0s,0s}
html.field-ready .layer-fig.in .layer-leads .ld3{transition-delay:700ms,0s,0s}
html.field-ready .layer-fig .layer-leads circle{opacity:0;transform:scale(.4);transform-origin:center;transform-box:fill-box;
  transition:opacity 260ms var(--e-fast),transform 260ms var(--e-out)}
html.field-ready .layer-fig.in .layer-leads circle{opacity:1;transform:scale(1)}
html.field-ready .layer-fig.in .layer-leads .cd1{transition-delay:500ms}
html.field-ready .layer-fig.in .layer-leads .cd2{transition-delay:590ms}
html.field-ready .layer-fig.in .layer-leads .cd3{transition-delay:680ms}
@media(prefers-reduced-motion:reduce){
  html.field-ready .layer-fig .ledger,html.field-ready .layer-fig .lnote{opacity:1;transform:none;transition:none}
  html.field-ready .layer-fig .lrow.hot::before{transform:none;transition:none}
  html.field-ready .layer-fig .layer-leads path{stroke-dasharray:none;stroke-dashoffset:0;transition:none}
  html.field-ready .layer-fig .layer-leads circle{opacity:1;transform:none;transition:none}}

/* --- wide exhibit: horizontal rail with progress, full-width stage --- */
.exhibit.wide{display:block}
.exhibit.wide .ex-rail{flex-direction:row;border-top:0;gap:clamp(6px,1vw,14px);margin-bottom:14px;align-items:stretch}
.exhibit.wide .ex-item{flex:1;min-width:0;padding:12px 14px 13px;border:var(--hair) solid var(--line);
  border-radius:var(--r-2);background:var(--bg-1);overflow:hidden}
.exhibit.wide .ex-item::before{display:none}
.exhibit.wide .ex-item .prog{position:absolute;left:0;bottom:0;height:2px;width:100%;
  background:var(--accent);transform:scaleX(var(--p,0));transform-origin:left center;opacity:0}
.exhibit.wide .ex-item.on{border-color:var(--clay-line);background:rgba(156,74,51,.05)}
.exhibit.wide .ex-item.on .prog{opacity:1}
.exhibit.wide .ex-item .d{max-width:none}
.exhibit.wide .ex-stage .port{aspect-ratio:16/9}
/* ══ THE STEPS ON A PHONE ═══════════════════════════════════════════════════
   The five workshop moments (three for meetings) used to stack as full-width
   rows below 860: 288px of column at 390, against a 370px stage. The steps
   cost nearly as much height as the film they introduce, and the exhibits are
   being recut portrait (1120x1802), where that column is the scarce thing.

   They become one horizontal run of chips, in the language the home chapter
   carousel settled: full-bleed track, the neighbouring item peeking past the
   screen edge as the swipe cue, snap to rest, 44px targets, and the live step
   separated on several channels rather than on hue alone.

   PEEK, NOT DOTS. NN/g names the half-visible neighbour the "illusion of
   continuity" and rates it a strong carousel cue, against dots, which it
   calls generally weak signifiers (nngroup.com/articles/mobile-carousels).
   Apple says the same of a scroll view: partial content at an edge is what
   indicates there is more (HIG, Scroll views), and adds that a horizontal
   scroll view inside a vertical one is fine, which is this exact structure.

   Material 3's UNCONTAINED carousel is the layout followed here: the one it
   designates for text-heavy items, where every item keeps ONE size and flows
   past the screen edge. Its multi-browse and hero layouts resize items as
   they approach the edge, which would squeeze a step's label at exactly the
   point the eye needs to read it. M3 offsets the first scrollable tab by
   52dp for the same reason this track starts its run on the page gutter.

   Not the .hcards numbers, though: that track carries ONE card at a time and
   buys its peek with a fixed 50px reserve. Several chips are on screen here,
   so the peek is whatever the next label measures, always well past a sliver.

   IT CENTRES ITSELF. The film drives the step, so a step that goes live
   off-screen leaves the banner showing the wrong thing. field.js writes the
   RAIL's own scrollLeft to bring it to the middle -- never scrollIntoView,
   which walks every ancestor scroll container and will move the PAGE under a
   reader whose rail is only half in view. See `centre()` there.
   ========================================================================== */
@media(max-width:860px){
  /* ── the track ────────────────────────────────────────────────────────────
     Full-bleed so a chip runs out under the screen edge, which is the cue; an
     inset track stops its content 20px early and reads as a finished row. The
     page gutter is cancelled with a negative margin and re-spent as padding,
     so the first chip still starts on the gutter and lines up with the claim
     above it. Same construction as .hcards. */
  .exhibit.wide .ex-rail{
    display:flex;flex-direction:row;flex-wrap:nowrap;align-items:stretch;
    gap:8px;margin-inline:calc(var(--gut) * -1);margin-bottom:12px;
    padding:2px var(--gut) 4px;scroll-padding-inline:var(--gut);
    overflow-x:auto;overflow-y:hidden;
    /* proximity, not mandatory. .hcards shows ONE card at a time, where a
       mandatory rest is the whole interaction; this row shows two and a bit
       chips, and mandatory turns every flick into an argument. Proximity
       still rests on a chip centre, which is exactly where centre() lands. */
    scroll-snap-type:x proximity;
    overscroll-behavior-inline:contain;-webkit-overflow-scrolling:touch;
    scrollbar-width:none;-ms-overflow-style:none;
    /* The fade says the row continues past the edge it fades into. Both sides
       are driven from field.js so an end the reader has already reached is not
       fogged: a fade over the last chip promises content that never arrives. */
    --fadeL:0px;--fadeR:26px;
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 var(--fadeL),
      #000 calc(100% - var(--fadeR)),transparent 100%);
    mask-image:linear-gradient(90deg,transparent 0,#000 var(--fadeL),
      #000 calc(100% - var(--fadeR)),transparent 100%);
  }
  .exhibit.wide .ex-rail::-webkit-scrollbar{display:none;width:0;height:0}
  .exhibit.wide .ex-rail:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}

  /* ── the chip ─────────────────────────────────────────────────────────────
     Sized by its own words, not an even share: an even five-way split at 390
     leaves each step 62px and "Export to Word or PDF" needs 165 of type
     alone. At its own width the run holds about two and a bit chips, which is
     what puts a neighbour under the fade on both sides of the live one. */
  .exhibit.wide .ex-item{
    /* width:auto is load-bearing. The base .ex-item is a block at width:100%,
       and flex-basis:auto reads that width, so every chip came out the full
       track and the run was five 350px slabs laid end to end. */
    flex:0 0 auto;width:auto;min-width:0;
    /* the chip's own type and padding come to 42; 2.5.5 asks 44, so the floor
       is stated here rather than left to depend on a font-size. 44 and not
       Material's 48: it is the WCAG AAA floor, it is Apple's default control
       size on iOS, and it is what the home picker's buttons were set to, so
       the two controls answer a thumb the same way. */
    min-height:44px;
    display:flex;align-items:center;gap:7px;padding:11px 13px 12px;
    scroll-snap-align:center;white-space:nowrap}
  /* the sentence under each step is a phone's worth of prose on its own and
     would set the chip width; the film and the note under it carry that copy */
  .exhibit.wide .ex-item .d{display:none}
  /* the index is the position readout and the row's one clay object when it
     is live -- the channel the home picker spends on its mark. Kept at M1, as
     on the desktop rail, so the two read as one component at two sizes. */
  .exhibit.wide .ex-item .k{display:block;flex:none;margin:0;color:var(--faint)}
  /* one step down from the desktop rail's 16px. At 16 the run showed a chip
     and a half at 390 and the peek stopped being legible AS a chip. */
  .exhibit.wide .ex-item .t{display:block;flex:none;font-size:14.5px;line-height:1.25}
  .exhibit.wide .ex-item.on .k{color:var(--accent)}
  /* the progress rule survives the move: same mechanism, same clay, one px
     thicker, because 2px under a thumb-height chip is the hairline the home
     picker's rest mark was rewritten to stop being */
  .exhibit.wide .ex-item .prog{height:3px}
  /* inset ring: the track clips on both axes, so the global 3px offset draws
     the ring outside the chip where the scroller cuts it off */
  .exhibit.wide .ex-item:focus-visible{outline:2px solid var(--accent);outline-offset:-3px}
}
/* asked for less motion: the run still centres itself, it just arrives */
@media(max-width:860px) and (prefers-reduced-motion:reduce){
  .exhibit.wide .ex-rail{scroll-behavior:auto;scroll-snap-type:none}
}

/* --- micro-slices: the product moving inside a caption row --- */
.cap-fig .port video.mslice{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* --- hotspot callouts over the embedded surface --- */
.hspots{position:absolute;inset:0;z-index:4;pointer-events:none}
.hspot{position:absolute;left:var(--hx);top:var(--hy);pointer-events:auto;width:26px;height:26px;
  border-radius:50%;background:rgba(156,74,51,.14);border:1.5px solid var(--accent);cursor:default;
  display:flex;align-items:center;justify-content:center;
  transition:background var(--m-1) var(--e-fast),transform var(--m-1) var(--e-fast)}
.hspot i{width:6px;height:6px;border-radius:50%;background:var(--accent)}
.hspot::after{content:attr(data-tip);position:absolute;left:50%;bottom:calc(100% + 10px);transform:translateX(-50%) translateY(3px);
  width:max-content;max-width:240px;font-family:var(--font);font-size:12px;line-height:1.45;font-weight:520;
  color:var(--ink);background:var(--bg-1);border:var(--hair) solid var(--line);border-radius:var(--r-2);
  box-shadow:var(--lift);padding:9px 12px;opacity:0;visibility:hidden;text-align:left;
  transition:opacity var(--m-2) var(--e-fast),transform var(--m-2) var(--e-out),visibility var(--m-2)}
.hspot:hover{background:rgba(156,74,51,.24);transform:scale(1.08)}
.hspot:hover::after{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0)}
.hspot:nth-child(3)::after,.hspot:nth-child(4)::after{bottom:auto;top:calc(100% + 10px)}
@media(max-width:860px){.hspots{display:none}}

/* --- PI systems row spacing --- */
.syslogos{margin-top:clamp(18px,2vw,26px)}

/* --- FI institutional-memory chart (ported from production) --- */
/* video elements paint paper, never black, while loading */
.cap-fig .port video,.ex-stage .port video,video[data-slice],.loop video{background:#F6F7F9}

/* --- the firm ledger + trace, one composition --- */
.ledgerfig{position:relative;border:var(--hair) solid var(--line);border-radius:var(--r-3);background:var(--bg-1);
  box-shadow:var(--lift-sm);overflow:hidden}
/* titled the way the figure beside it is titled: a plain mono label on the band
   ground, not a filled chrome strip across the plate */
.lf-lbl{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  margin-bottom:clamp(10px,1.1vw,14px)}
.lf-lbl .l{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute)}
/* demoted meta (clause rule): sentence-case mono at M2 size, data tracking */
.lf-lbl .r{font-family:var(--mono);font-size:var(--mono-m2-size);letter-spacing:var(--mono-m3-track);
  color:var(--faint);text-align:right}
/* The ledger body sits on the plate face, not in a recess. One number reads the
   window; a vertical rule marks where the reading crosses into the lines that
   account for it, with a clay node on the crossing. The flagged line takes the
   canon hot treatment -- clay bar, clay wash, clay chip -- and hands off down. */
.lf-body{display:grid;grid-template-columns:minmax(0,.84fr) minmax(0,1.6fr);align-items:stretch;
  padding:clamp(8px,1vw,14px) clamp(20px,2.4vw,30px)}
.lf-big{position:relative;display:flex;flex-direction:column;justify-content:center;
  padding-right:clamp(26px,3.2vw,50px);border-right:var(--hair) solid var(--line)}
.lf-big::after{content:"";position:absolute;right:0;top:50%;width:7px;height:7px;border-radius:50%;
  background:var(--bg-1);border:1.4px solid var(--accent);transform:translate(50%,-50%)}
.lf-big>b{display:block;font-size:clamp(38px,4.2vw,54px);font-weight:520;letter-spacing:-.032em;
  color:var(--ink);font-variant-numeric:tabular-nums;line-height:1}
.lf-big>span{display:block;margin-top:13px;text-wrap:pretty;font-family:var(--mono);
  font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight);letter-spacing:var(--mono-m2-track);
  text-transform:uppercase;color:var(--faint);line-height:1.8}
.lf-big>span b{display:inline;font-size:inherit;letter-spacing:inherit;color:var(--mute);font-weight:700}
.lf-rows{padding-left:clamp(26px,3.2vw,50px)}
.lf-row{position:relative;display:grid;grid-template-columns:84px minmax(0,1fr) auto;gap:16px;
  align-items:center;padding:13px 0}
.lf-row+.lf-row{border-top:var(--hair) solid var(--line-2)}
.lf-row .n{text-align:right;font-size:clamp(20px,2vw,26px);font-weight:520;letter-spacing:-.024em;
  color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap;line-height:1}
.lf-row.money .n{color:var(--accent)}
.lf-row .w .t{display:block;font-style:normal;font-size:14.5px;font-weight:560;letter-spacing:-.012em;
  color:var(--ink);line-height:1.3}
.lf-row .w .s{display:block;font-style:normal;margin-top:3px;font-size:var(--t-cap);line-height:1.5;
  color:var(--mute)}
.lf-row .m{font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight);
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:var(--mute);
  border:var(--hair) solid var(--line);border-radius:100px;padding:4px 10px;white-space:nowrap}
.lf-row .m.clay{color:var(--accent);border-color:var(--clay-line);background:rgba(156,74,51,.06)}
.lf-row.hot{margin-left:-18px;padding-left:18px;
  background:linear-gradient(90deg,rgba(156,74,51,.055),transparent 62%)}
.lf-row.hot::before{content:"";position:absolute;left:0;top:0;bottom:0;width:2.5px;background:var(--accent)}
/* the rows commit one at a time, as the layer reads them */
html.field-ready .ledgerfig .lf-row{opacity:0;transform:translateY(9px)}
html.field-ready .ledgerfig.in .lf-row{opacity:1;transform:none;
  transition:opacity .58s var(--e-out) calc(var(--i,0)*.13s + .18s),
             transform .58s var(--e-out) calc(var(--i,0)*.13s + .18s)}
html.field-ready .ledgerfig .lf-big::after{opacity:0}
html.field-ready .ledgerfig.in .lf-big::after{opacity:1;transition:opacity .5s var(--e-fast) .38s}
@media(prefers-reduced-motion:reduce){
  html.field-ready .ledgerfig .lf-row{opacity:1;transform:none;transition:none}
  html.field-ready .ledgerfig .lf-big::after{opacity:1}
}
.lf-join{display:flex;align-items:center;gap:14px;margin:16px 0;justify-content:center}
.lf-join i{flex:1;max-width:220px;height:var(--hair);background:var(--clay-line)}
/* demoted (clause rule, 6 words): sentence-case mono at M2 size, data tracking */
.lf-join span{font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight);
  letter-spacing:var(--mono-m3-track);color:var(--accent);white-space:nowrap}
@media(max-width:900px){
  .lf-body{grid-template-columns:1fr}
  .lf-big{padding:0 0 20px;border-right:0;border-bottom:var(--hair) solid var(--line)}
  .lf-big::after{right:auto;left:50%;top:auto;bottom:0;transform:translate(-50%,50%)}
  .lf-rows{padding:16px 0 0}
}
@media(max-width:640px){
  .lf-row{grid-template-columns:62px minmax(0,1fr);gap:12px}
  .lf-row .m{display:none}
}

/* --- the composed surface stack: three live crops, one composition --- */
.sstack{position:relative;height:clamp(440px,44vw,600px)}
.splate{position:absolute;border:var(--hair) solid var(--line);border-radius:var(--r-3);background:#FFFFFF;
  overflow:hidden;box-shadow:0 1px 0 rgba(255,255,255,.6) inset,0 24px 56px -24px rgba(25,24,23,.28),0 4px 14px -6px rgba(25,24,23,.12);
  transition:transform var(--m-2) var(--e-out),box-shadow var(--m-2) var(--e-fast)}
.splate .port{position:relative;width:100%;overflow:hidden;background:#F6F7F9}
.splate .port iframe{position:absolute;top:0;left:0;border:0;transform-origin:0 0;pointer-events:none}
.splate.main{left:0;top:0;width:70%;z-index:1}
.splate.sat{z-index:2}
.splate.sat:hover{transform:translateY(-4px);box-shadow:0 1px 0 rgba(255,255,255,.6) inset,0 32px 64px -24px rgba(25,24,23,.34),0 6px 18px -6px rgba(25,24,23,.16)}
.splate.s1{right:0;top:5%;width:32%}
.sstack.fi .splate.s1{width:30%}
.splate.s2{left:6%;bottom:0;width:58%;z-index:3}
.slabel{position:absolute;left:12px;bottom:12px;z-index:5;display:inline-flex;align-items:center;gap:8px;
  font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;
  color:var(--ink);background:rgba(251,252,254,.92);backdrop-filter:blur(4px);
  border:var(--hair) solid var(--line);border-radius:100px;padding:6px 12px;box-shadow:0 4px 12px -6px rgba(25,24,23,.2)}
.slabel i{width:5px;height:5px;border-radius:50%;background:var(--accent);flex:none}
/* the main plate's label rides its top edge: both satellites dock over the
   bottom corners and were burying a bottom-anchored label mid-word */
.sstack .main .slabel{top:12px;bottom:auto}
/* entrance: the main plate rises, then the satellites float in over it */
html.field-ready .sstack .splate{opacity:0;transform:translateY(16px);
  transition:opacity var(--m-4) var(--e-out),transform var(--m-4) var(--e-out)}
html.field-ready .sstack.in .splate{opacity:1;transform:none}
html.field-ready .sstack.in .splate.main{transition-delay:40ms}
html.field-ready .sstack.in .splate.s1{transition-delay:220ms}
html.field-ready .sstack.in .splate.s2{transition-delay:360ms}
@media(prefers-reduced-motion:reduce){html.field-ready .sstack .splate{opacity:1;transform:none;transition:none}}
@media(max-width:860px){
  .sstack{height:auto;display:flex;flex-direction:column;gap:12px}
  .splate{position:static;width:100%!important}
  .splate.s1 .port{aspect-ratio:345/300!important}
}

/* --- hero field, elevated: columns are stacks of record cards --- */
.hf-col{gap:6px}
.spine-node{width:58px;height:58px;border-radius:14px;
  box-shadow:0 6px 22px -6px rgba(0,0,0,.6),0 0 34px rgba(184,73,50,.28)}
/* --- the radial, machined: recess panel, record-card headers, lit event --- */
.radial{user-select:none;padding:clamp(20px,2.6vw,34px);border-radius:var(--r-3);
  background:radial-gradient(130% 110% at 50% 24%,rgba(255,255,255,.03),rgba(255,255,255,.008) 58%,transparent 80%);
  box-shadow:inset 0 0 0 var(--hair) rgba(255,255,255,.06),inset 0 2px 12px -6px rgba(0,0,0,.6)}
.ra-card .k{padding-bottom:6px;border-bottom:var(--hair) solid rgba(255,255,255,.07);margin-bottom:8px}
.ra-event{background:linear-gradient(180deg,rgba(184,73,50,.13),rgba(184,73,50,.05));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 0 0 9px rgba(184,73,50,.06),0 0 48px rgba(184,73,50,.2)}
/* --- the four consequences, visually contained under their head --- */
.cur-strip{display:flex;gap:10px;margin-top:22px;padding-bottom:16px;position:relative}

/* ==========================================================================
   TWO ALTITUDES — PI grounded and large, FI raised and lighter; the wire
   between them is the emergence mechanism, labeled.
   ========================================================================== */
.alt{position:relative;display:grid;grid-template-columns:minmax(0,1.42fr) minmax(0,1fr);
  gap:clamp(76px,9vw,150px);align-items:start}
.acard{position:relative;display:flex;flex-direction:column;text-decoration:none;color:inherit;
  border-radius:var(--r-3);padding:clamp(22px,2.4vw,30px);
  transition:transform var(--m-2) var(--e-out),box-shadow var(--m-2) var(--e-fast),border-color var(--m-2) var(--e-fast)}
.acard.pi{background:var(--plate-face);border:var(--hair) solid var(--line);box-shadow:var(--lift-sm)}
.acard.pi:hover{transform:translateY(-3px);border-color:var(--clay-line)}
/* the firm card is real but lighter material: direction, not shipped product */
.acard.fi{background:var(--bg-1);border:var(--hair) solid var(--line);box-shadow:0 1px 0 rgba(255,255,255,.85) inset;margin-top:clamp(-14px,-1vw,-8px)}
.acard.fi:hover{transform:translateY(-3px);border-color:var(--clay-line)}
.astat{display:inline-flex;align-items:center;gap:7px;align-self:flex-start;font-family:var(--mono);
  font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;margin-bottom:clamp(18px,2vw,26px)}
.astat i{width:7px;height:7px;border-radius:50%;flex:none}
.astat.live{color:var(--accent)}
.astat.live i{background:var(--accent);animation:astat-live 2.6s ease-out infinite}
@keyframes astat-live{
  0%{box-shadow:0 0 0 0 rgba(184,73,50,.45)}
  62%{box-shadow:0 0 0 7px rgba(184,73,50,0)}
  100%{box-shadow:0 0 0 0 rgba(184,73,50,0)}
}
@media(prefers-reduced-motion:reduce){.astat.live i{animation:none}}
.astat.em{color:var(--mute)}.astat.em i{background:transparent;border:1.5px solid var(--accent)}
.ak{display:block;font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;
  color:var(--mute);margin-bottom:10px}
.acard h3{font-size:clamp(26px,2.4vw,34px);font-weight:620;letter-spacing:-.028em;line-height:1.1;color:var(--ink)}
.asub{font-size:var(--t-body);line-height:1.55;color:var(--mute);margin-top:12px}
.apts{list-style:none;margin:clamp(16px,1.8vw,22px) 0 0;padding:0}
.apts li{position:relative;padding:7px 0 7px 18px;font-size:var(--t-ui);color:var(--mute)}
.apts li::before{content:"";position:absolute;left:2px;top:50%;width:5px;height:5px;border-radius:50%;
  transform:translateY(-50%);background:var(--clay-line)}
.areg{display:block;font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;
  color:var(--mute);margin-top:clamp(16px,1.8vw,22px)}
.asurf{display:block;margin-top:clamp(16px,1.8vw,22px);border:var(--hair) solid var(--line);
  border-radius:var(--r-2);overflow:hidden;background:var(--bg-2)}
.abar{display:flex;align-items:center;gap:5px;padding:7px 11px;border-bottom:var(--hair) solid var(--line-2);
  background:var(--bg-2)}
.abar .d{width:7px;height:7px;border-radius:50%;background:var(--line)}
.abar .url{margin-left:7px;font-family:var(--mono);font-size:var(--mono-m3-size);letter-spacing:var(--mono-m3-track); /* M3 */
  color:var(--mute);
  background:var(--bg-1);border:var(--hair) solid var(--line-2);border-radius:4px;padding:2px 9px}
.aport{position:relative;display:block;width:100%;aspect-ratio:1120/430;overflow:hidden;background:#F6F7F9}
.aport iframe{position:absolute;top:0;left:0;border:0;transform-origin:0 0;pointer-events:none}
.ago{display:inline-flex;align-items:center;gap:9px;align-self:flex-start;margin-top:clamp(20px,2.2vw,26px);
  font-size:var(--t-ui);font-weight:600;border-radius:100px;padding:11px 20px;
  transition:background var(--m-1) var(--e-fast),color var(--m-1) var(--e-fast),
    border-color var(--m-1) var(--e-fast),transform var(--m-1) var(--e-fast)}
.acard.pi .ago{color:#FCFBF9;background:var(--clay-display,#B84932);border:var(--hair) solid var(--clay-display,#B84932)}
.acard.pi:hover .ago{background:var(--clay-display-hover,#C85136);transform:translateY(-1px)}
.acard.fi .ago{color:var(--mute);background:transparent;border:var(--hair) solid var(--line)}
.acard.fi:hover .ago{color:var(--accent);border-color:var(--clay-line)}
.ago svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;transition:transform var(--m-1) var(--e-fast)}
.acard:hover .ago svg{transform:translateX(3px)}
/* the emergence wire is drawn from live card geometry (field.js altWire) */
.acard.pi{margin-top:0}
.acard.fi{margin-top:clamp(74px,7.7vw,111px)}
.awires{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none;z-index:1}
.awires path.w{fill:none;stroke:var(--clay-line);stroke-width:var(--hair)}
.awires path.ah2{fill:none;stroke:var(--accent);stroke-width:1.5}
.awires circle.j{fill:var(--accent)}
.alt .wlab{position:absolute;font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight); /* M2 */
  letter-spacing:var(--mono-m2-track);
  text-transform:uppercase;color:var(--accent);text-align:center;line-height:1.75;white-space:nowrap;
  background:#F6F7F9;padding:2px 8px;z-index:2;transform:translateX(-50%)}
@media(max-width:960px){
  .alt{grid-template-columns:1fr;gap:18px}
  .awires,.alt .wlab{display:none}
  .acard.pi{margin-top:0}
}

/* ==========================================================================
   CONTROL — the authority chain: sources, the layer, the PM
   ========================================================================== */
.chain{display:grid;grid-template-columns:1fr auto 1fr auto 1fr;gap:clamp(10px,1.4vw,20px);align-items:stretch}
.cpanel{border:var(--hair) solid var(--line);border-radius:var(--r-2);background:var(--bg-1);
  padding:clamp(18px,2vw,26px);display:flex;flex-direction:column}
.cpanel.mid{background:#0D0F12;border-color:#22262C;
  box-shadow:0 14px 34px -16px rgba(8,9,11,.5)}
.cpanel.mid .cn{color:rgba(244,241,237,.55)}
.cpanel.mid .ck{color:#C68070}
.cpanel.mid h3{color:#F4F1ED}
.cpanel.mid .cm{color:rgba(244,241,237,.6)}
.chain .cn{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute);margin-bottom:14px}
.chain .ck{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;
  color:var(--accent);margin-bottom:10px}
.cpanel h3{font-size:clamp(18px,1.7vw,23px);font-weight:600;letter-spacing:-.02em;line-height:1.22;color:var(--ink);flex:1}
.chain .cm{font-family:var(--mono);font-size:var(--mono-m3-size);letter-spacing:var(--mono-m3-track); /* M3 */
  line-height:1.7;color:var(--mute);
  margin-top:clamp(14px,1.6vw,20px)}
.chain .carr{display:flex;align-items:center;justify-content:center}
.chain .carr svg{width:20px;height:20px;stroke:var(--accent);fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
@media(max-width:860px){
  .chain{grid-template-columns:1fr}
  .carr{transform:rotate(90deg);padding:2px 0}
}

/* --- the four consequences as one descending run: a shared rail, each step
   inset and pinned to it --- */
.curgroup{position:relative;padding-left:clamp(26px,3.4vw,52px)}
.curgroup::before{content:"";position:absolute;left:0;top:6px;bottom:0;width:var(--hair);
  background:linear-gradient(180deg,var(--accent) 0 16px,var(--line) 16px calc(100% - 90px),transparent)}
.curgroup .currency{position:relative}
.curgroup .currency::before{content:"";position:absolute;left:calc(clamp(26px,3.4vw,52px)*-1 - 3.5px);top:8px;
  width:8px;height:8px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 3px #F6F7F9,0 0 0 3.8px var(--clay-line)}
@media(max-width:860px){
  .curgroup{padding-left:18px}
  .curgroup .currency::before{left:-21.5px}
}

/* one-line diagram grammar: hot columns carry a clay trace, junctions tap the bus */
.threads path.hot{stroke:rgba(198,128,112,.5)}
.threads circle{fill:#C68070;opacity:.85}
.threads .pulse{stroke:#C68070;stroke-width:1.4;opacity:.5;stroke-dasharray:10 var(--len,600);
  stroke-dashoffset:var(--len,600);animation-name:hf-run;animation-timing-function:linear;animation-iteration-count:infinite}
.threads .pulse.busL,.threads .pulse.busR{stroke-width:1.2;opacity:.4;stroke-dasharray:16 var(--len,600)}
/* the node keeps the only glow on the stage */
.spine-node{box-shadow:0 6px 22px -6px rgba(0,0,0,.6),0 0 26px rgba(184,73,50,.26)}

/* the marks: PI wears the clay tile, FI the ink tile */
.amk{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;
  margin-bottom:clamp(14px,1.6vw,20px)}
.amk svg{width:60%;height:60%}
.acard.pi .amk{background:var(--clay-display,#B84932);color:#fff}
.acard.fi .amk{background:#15161A;color:#F7F8F8}

.ah{display:flex;align-items:center;gap:13px}
.ah .amk{margin-bottom:0;width:33px;height:33px;border-radius:9px}

/* the outcome name rides the index line as taxonomy, not a pill */
.cur-head .n em{font-style:normal}

/* the film earns a wider stage: break out of the frame, keep the rail on it */
.exhibit.wide .ex-stage{position:relative;left:50%;translate:-50% 0;
  width:min(1380px,calc(100vw - 48px))}
.exhibit.wide .ex-note{text-align:center}
@media(max-width:860px){.exhibit.wide .ex-stage{width:100%;left:auto;translate:none}}

/* the category, said once, plainly, between the thesis and the close read */
.statement{padding:clamp(64px,7.5vw,104px) 0}
.stmt{font-size:clamp(23px,2.4vw,33px);font-weight:540;letter-spacing:-.022em;line-height:1.4;
  color:var(--mute);max-width:34ch;margin:0 auto;text-align:center}
.stmt b{color:var(--ink);font-weight:620}

/* the memory pair, numbered like the rest of the system */
.card .ck2{display:block;font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute);margin-bottom:10px}
.card .ck2 b{color:var(--accent);font-weight:var(--mono-m1-weight)}

/* ==========================================================================
   THE COMBINATION — chain figure: records -> one changed condition ->
   consequences. Rail names the topology; port-to-port wires are drawn
   from live geometry (field.js combinationChain); hover lights the path.
   ========================================================================== */
.chain-figure{
  position:relative;
  overflow:hidden;
  margin:0;
  border:var(--hair) solid rgba(255,255,255,.1);
  border-radius:calc(var(--r-4) + .25rem);
  background:linear-gradient(180deg,rgba(255,255,255,.026),rgba(255,255,255,.009));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.05),
    inset 0 -1px 0 rgba(0,0,0,.26),
    0 3.25rem 7rem -4.75rem rgba(0,0,0,.92);
}

.chain-orientation{
  display:grid;
  grid-template-columns:minmax(0,1fr) auto minmax(0,1fr) auto minmax(0,1fr);
  align-items:center;
  gap:1rem;
  padding:1.65rem clamp(2rem,2.8vw,2.5rem) .25rem;
  font-family:var(--mono);
  font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight);letter-spacing:var(--mono-m1-track);
  line-height:1.2;
  text-transform:uppercase;
  color:var(--mute);
}

.chain-orientation span{
  text-align:center;
}

.chain-orientation span:nth-of-type(2){
  color:var(--clay-lit);
}

.chain-orientation i{
  font-family:var(--sans);
  font-size:1rem;
  font-style:normal;
  font-weight:400;
  letter-spacing:0;
  color:rgba(198,128,112,.48);
}

.chain-canvas{
  position:relative;
  display:grid;
  grid-template-columns:minmax(17rem,18.5rem) minmax(18rem,1fr) minmax(18.5rem,20rem);
  gap:clamp(3.25rem,5vw,5rem);
  align-items:center;
  min-height:32rem;
  padding:1.75rem clamp(2rem,2.8vw,2.5rem);
}

.chain-column{
  position:relative;
  z-index:2;
  display:flex;
  flex-direction:column;
  gap:1rem;
}

.chain-card{
  position:relative;
  display:flex;
  flex-direction:column;
  justify-content:center;
  min-height:6.5rem;
  padding:1rem 1.25rem;
  border:var(--hair) solid rgba(255,255,255,.12);
  border-radius:var(--r-2);
  background:linear-gradient(145deg,rgba(255,255,255,.038),rgba(255,255,255,.018));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.035);
  transition:
    border-color var(--m-2) var(--e-fast),
    background var(--m-2) var(--e-fast),
    box-shadow var(--m-3) var(--e-fast);
}

.chain-record{
  padding-inline-end:1.5rem;
}

.chain-consequence{
  padding-inline-end:2.75rem;
  border-color:rgba(255,255,255,.145);
  background:linear-gradient(145deg,rgba(255,255,255,.052),rgba(255,255,255,.021));
}

.chain-card:hover,
.chain-card:focus-visible,
.chain-card.is-lit{
  border-color:rgba(198,128,112,.52);
  background:linear-gradient(145deg,rgba(198,128,112,.085),rgba(255,255,255,.025));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.055),0 1.25rem 2.75rem -2rem rgba(0,0,0,.85);
}

.chain-kind{
  display:block;
  margin-bottom:.5rem;
  font-family:var(--mono);
  font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight);letter-spacing:var(--mono-m1-track);
  line-height:1.2;
  text-transform:uppercase;
  color:var(--mute);
}

.chain-consequence .chain-kind{
  color:var(--clay-lit);
}

.chain-card strong{
  display:block;
  margin-top:0;
  font-size:clamp(.95rem,1.25vw,1.0625rem);
  font-weight:610;
  line-height:1.25;
  letter-spacing:-.018em;
  color:var(--ink);
  text-wrap:balance;
}

.chain-consequence svg{
  position:absolute;
  inset-inline-end:1.125rem;
  top:50%;
  width:1rem;
  height:1rem;
  fill:none;
  stroke:var(--faint);
  stroke-width:1.8;
  stroke-linecap:round;
  stroke-linejoin:round;
  transform:translateY(-50%);
  transition:stroke var(--m-1) var(--e-fast),transform var(--m-1) var(--e-out);
}

.chain-consequence:hover svg,
.chain-consequence:focus-visible svg,
.chain-consequence.is-lit svg{
  stroke:var(--clay-lit);
  transform:translate(.2rem,-50%);
}

.chain-port,
.event-port{
  position:absolute;
  z-index:4;
  display:block;
  width:.5rem;
  height:.5rem;
  border:var(--hair) solid rgba(13,15,18,.9);
  border-radius:50%;
  background:var(--clay-lit);
}

.chain-record .chain-port{
  inset-inline-end:-.27rem;
  top:50%;
  transform:translateY(-50%);
}

.chain-consequence .chain-port{
  inset-inline-start:-.27rem;
  top:50%;
  transform:translateY(-50%);
}

.chain-center{
  position:relative;
  z-index:2;
  display:flex;
  align-items:center;
  justify-content:center;
  min-width:0;
}

.chain-event{
  position:relative;
  width:min(100%,21.5rem);
  min-height:16.5rem;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  padding:2.5rem 2.25rem;
  border:var(--hair) solid rgba(198,128,112,.56);
  border-radius:var(--r-3);
  background:linear-gradient(180deg,rgba(184,73,50,.085),rgba(255,255,255,.018));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.075),
    inset 0 -1px 0 rgba(0,0,0,.32),
    0 1.75rem 3.5rem -2.5rem rgba(0,0,0,.92);
  text-align:center;
}

.chain-event h3{
  margin-top:0;
  font-size:clamp(1.55rem,1.8vw,1.75rem);
  font-weight:630;
  line-height:1.06;
  letter-spacing:-.038em;
  color:var(--ink);
}

.chain-event-meta{
  margin-top:1rem;
  font-size:.8125rem;
  line-height:1.4;
  text-wrap:balance;
  color:var(--mute);
}

.event-port-left{
  inset-inline-start:-.27rem;
}

.event-port-right{
  inset-inline-end:-.27rem;
}

.event-port.p1{top:27%}
.event-port.p2{top:42%}
.event-port.p3{top:58%}
.event-port.p4{top:73%}

.chain-wires{
  position:absolute;
  inset:0;
  z-index:1;
  width:100%;
  height:100%;
  overflow:visible;
  pointer-events:none;
}

.chain-wires path{
  fill:none;
  stroke-linecap:round;
}

.chain-wires .wire-base path{
  stroke:rgba(198,128,112,.17);
  stroke-width:1;
}

.chain-wires .wire-flow path{
  stroke:var(--clay-lit);
  stroke-width:1.4;
  opacity:.12;
  transition:opacity var(--m-2) var(--e-fast),stroke-width var(--m-2) var(--e-fast);
}

.chain-wires .wire-flow path.is-lit{
  stroke-width:1.6;
  opacity:.88;
}

html.field-ready .chain-figure:not(.in) .wire-flow path{
  stroke-dasharray:var(--wire-length,30rem);
  stroke-dashoffset:var(--wire-length,30rem);
}

html.field-ready .chain-figure.in .wire-flow path{
  stroke-dasharray:var(--wire-length,30rem);
  stroke-dashoffset:0;
  transition:
    stroke-dashoffset var(--m-5) var(--e-out),
    opacity var(--m-2) var(--e-fast),
    stroke-width var(--m-2) var(--e-fast);
}

/* mobile: stacked fallback */
@media(max-width:64rem){
  .chain-orientation{
    grid-template-columns:1fr;
    gap:.4rem;
  }

  .chain-orientation i{
    justify-self:center;
    transform:rotate(90deg);
  }

  .chain-canvas{
    grid-template-columns:1fr;
    gap:1.5rem;
    min-height:0;
  }

  .chain-center{
    order:-1;
  }

  .chain-event{
    width:100%;
    min-height:0;
  }

  .chain-column{
    display:grid;
    grid-template-columns:repeat(2,minmax(0,1fr));
  }

  .chain-wires,
  .chain-port,
  .event-port{
    display:none;
  }
}

@media(max-width:38rem){
  .chain-column{
    grid-template-columns:1fr;
  }
}

@media(prefers-reduced-motion:reduce){
  .chain-card,
  .chain-consequence svg,
  .chain-wires path{
    transition:none!important;
  }

  html.field-ready .chain-figure .wire-flow path{
    stroke-dasharray:none;
    stroke-dashoffset:0;
  }
}

/* merged reframe: the evidence lines and the numbered pre-echo */
.chain-sub{display:block;margin-top:6px;font-family:var(--mono);
  font-size:var(--mono-m3-size);letter-spacing:var(--mono-m3-track);color:var(--faint)}
.chain-kind b{color:var(--accent);font-weight:inherit}
.chain-record .chain-sub{color:var(--mute)}

/* the whole-job rows ride the same step rail as the home currencies */
.curgroup .cap-row.stacked{position:relative}
.curgroup .cap-row.stacked::before{content:"";position:absolute;left:calc(clamp(26px,3.4vw,52px)*-1 - 3.5px);top:8px;
  width:8px;height:8px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 3px #F6F7F9,0 0 0 3.8px var(--clay-line)}
@media(max-width:860px){.curgroup .cap-row.stacked::before{left:-21.5px}}

/* privacy in plain terms: the boundary strip under the authority chain.
   Three claims a GC's IT lead actually asks about, in the plain-language
   register: what enters, what leaves, who can see it. */
.pbound{margin-top:clamp(34px,4vw,54px)}
.pbound .pb-k{display:block;font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--accent);margin-bottom:14px}
.pbound .pb-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  border-top:var(--hair) solid var(--line);border-bottom:var(--hair) solid var(--line)}
.pbound .pb-row p{margin:0;padding:clamp(18px,2.2vw,26px) clamp(18px,2.6vw,32px);
  border-left:var(--hair) solid var(--line);font-size:var(--t-body);line-height:1.6;color:var(--mute)}
.pbound .pb-row p:first-child{border-left:0;padding-left:0}
.pbound .pb-row p:last-child{padding-right:0}
.pbound .pb-row p b{color:var(--ink);font-weight:560}
@media(max-width:880px){
  .pbound .pb-row{grid-template-columns:1fr}
  .pbound .pb-row p{border-left:0;border-top:var(--hair) solid var(--line);padding-left:0;padding-right:0}
  .pbound .pb-row p:first-child{border-top:0}
}

/* ==========================================================================
   HELD CHAPTERS — the linked-chapter stepper: native sticky pin, tab strip
   with two clocks (top: the scroll cursor riding toward each boundary;
   bottom: the active film's own clock), swap head, full-width stage.
   Mobile and reduced motion fall back to a flowing stack.
   ========================================================================== */
/* Held chapters v2: stacked composition so the plate keeps full frame width.
   Tab strip (chapter map) -> fixed swap head (claim | lead) -> full-width stage.
   Native sticky only. Mobile + reduced motion fall back to a flowing stack. */


/* the chapter map: four tabs on the chapters-strip geometry */


/* the scroll cursor: your position along the held section, 1:1 with scroll.
   Rides the top hairline; separators and the strip's end are the boundaries. */
.hcursor{position:absolute;top:-4px;left:0;width:2px;height:calc(8px + 6px*var(--e,0));border-radius:1px;
  background:var(--accent);z-index:3;pointer-events:none;
  transition:transform 90ms linear,height 140ms var(--e-fast)}
.hcursor::after{content:"";position:absolute;inset:-4px -3px;border-radius:3px;
  background:radial-gradient(closest-side,rgba(184,73,50,.5),transparent);
  opacity:var(--e,0);transition:opacity 140ms var(--e-fast)}


/* the swap head: all pairs stacked in one grid cell; tallest pair sets height */


.hclaim{font-size:clamp(24px,2.3vw,34px);font-weight:var(--w-display);line-height:1.14;
  letter-spacing:-.024em;color:var(--mute);margin:0;max-width:22ch}
.hclaim b{color:var(--ink)}
.hlead{font-size:var(--t-body);line-height:1.6;color:var(--mute);margin:0;max-width:52ch}
.hlead b{color:var(--ink);font-weight:560}

/* the plate: full frame width, shrinking only when viewport height demands */


/* The labels are set on one nowrap line, which is the authored strip and holds
   down to 1220. Measured below that, the longest label runs out of its own tab:
   "04 - Increased productivity" is 223px and the tab's padding box gives it 220
   at 1200, 197 at 1180 and 175 at 1024, so it crossed the separator and ran
   over its neighbour. From 1220 down the labels wrap. The strip is a grid, so
   every tab already stretches to the tallest and the row stays square. */
@media(max-width:1220px){
  /* plain wrap, not balance: balance split "02 -" onto a line of its own,
     which reads as a rendering fault. Filled lines keep the number with the
     words it numbers. */

}

/* flowing fallback */
/* the section head rides inside the pin, compacted: identity stays on screen
   through the whole held run */


/* ==========================================================================
   PI CHAPTERS — kickers, film-exhibit compaction and landing snap, the
   rail-language Ask compare, the memory figure, the week figure.
   ========================================================================== */
.chapk{display:block;font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight); /* M1 */
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute);margin-bottom:16px}
.chapk b{color:var(--accent);font-weight:var(--mono-m1-weight)}
.chapcoda{margin-top:clamp(44px,5vw,68px)}
.chapcoda .cur-head{margin-bottom:clamp(22px,2.6vw,34px)}

/* film exhibits: number folds into the title line; the rail stops competing
   with the stage for height */
.ex-item{padding:9px 2px 10px 16px}
.ex-item .k{display:inline;margin-right:9px}
.ex-item .t{display:inline}
.ex-item .d{margin-top:3px}

/* the big film sections land like a magnet: browser-native proximity snap,
   only when the scroll settles near them */

/* the film stages land like a magnet: native proximity snap on the stage,
   assisted only within a small radius by filmMagnet (both directions) */
/* the magnet is a pointer affordance: on touch it fights momentum scrolling,
   and under reduced-motion it is an unrequested movement */
@media(min-width:961px) and (pointer:fine){
  html{scroll-snap-type:y proximity}
  #workshops .ex-stage,#meetings .ex-stage{scroll-snap-align:center}
}
@media(prefers-reduced-motion:reduce){html{scroll-snap-type:none}}

/* the film stages fit the viewport: rail and stage visible together */
#workshops .ex-stage,#meetings .ex-stage{
  width:min(1380px,calc(100vw - 48px),calc((100svh - 300px)*1.7778));
}

/* =================== capacity: the week figure =================== */
.weekfig{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:clamp(28px,4vw,64px);
  align-items:center;border:var(--hair) solid var(--line);border-radius:var(--r-3);background:var(--bg-1);
  box-shadow:var(--lift);padding:clamp(26px,3vw,40px)}
.wf-h{display:flex;justify-content:space-between;font-family:var(--mono);font-size:var(--mono-m2-size);
  font-weight:var(--mono-m2-weight);letter-spacing:var(--mono-m2-track);text-transform:uppercase;
  color:var(--mute);margin-bottom:12px}
.wf-grid{display:grid;grid-template-columns:repeat(8,1fr);gap:7px}
.wc{aspect-ratio:10/7;border-radius:5px;background:linear-gradient(180deg,#FCFCFD,#ECEDEF);
  border:1px solid #DCDEE1}
.wc.c{background:linear-gradient(180deg,#CB5640,#A84232);border-color:#973D2B}
html.field-ready .weekfig.rv .wc{opacity:0;transform:scale(.7)}
html.field-ready .weekfig.rv.in .wc{opacity:1;transform:none;
  transition:opacity .4s var(--e-out) calc(var(--i)*14ms),transform .4s var(--e-out) calc(var(--i)*14ms)}
.wf-key{display:flex;gap:22px;margin-top:14px}
.wf-key .key{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--mute)}
.wf-key .key i{width:13px;height:13px;border-radius:4px;background:linear-gradient(180deg,#FCFCFD,#ECEDEF);
  border:1px solid #DCDEE1}
.wf-key .key.c i{background:linear-gradient(180deg,#CB5640,#A84232);border-color:#973D2B}
.wf-shift{display:flex;align-items:baseline;gap:16px}
.wf-shift .was{font-size:clamp(38px,3.6vw,54px);font-weight:480;letter-spacing:-.04em;color:var(--faint);line-height:1}
.wf-shift .ar{color:var(--accent)}
.wf-shift .ar svg{width:40px;height:20px}
.wf-shift .now{font-size:clamp(64px,6vw,92px);font-weight:520;letter-spacing:-.05em;color:var(--clay-display);line-height:1}
.wf-cap{font-size:clamp(16px,1.5vw,19px);line-height:1.5;color:var(--mute);margin:14px 0 0;max-width:30ch}
.wf-cap b{color:var(--ink);font-weight:600}
.wf-sub{font-size:var(--t-cap);line-height:1.55;color:var(--faint);margin:10px 0 0;max-width:40ch}
@media(max-width:880px){.weekfig{grid-template-columns:1fr}}

/* Vec introduces himself: the product mark, as the agent's own identity */
/* Vec's mark hangs in the left margin: the claim keeps the page's flush-left
   edge, and the mark reads as a marginal identity marker, not a second logo */
.vechead{position:relative}
/* the mark carries the claim's own type scale, so it stays optically centred
   on the cap band of the first line at every clamp step */
.vecmk{position:absolute;font-size:var(--t-stage);width:.72em;height:.72em;
  left:-1em;top:.285em;border-radius:.16em}
@media(max-width:1180px){
  .vecmk{position:static;display:block;width:38px;height:38px;font-size:inherit;margin-bottom:16px}
}

/* =================== project memory: the graph, assembling ===================
   Records are nodes, the links Vecreal draws are edges, and both arrive in
   project order. Density is the point: the links outnumber the documents. */
.memgraph{margin:0;border:var(--hair) solid var(--line);border-radius:var(--r-3);
  background:linear-gradient(180deg,#FFFFFF,var(--bg-1));box-shadow:var(--lift);overflow:hidden}

/* the assembly: records land in project order, links follow them */
html.field-ready .memgraph .mg2-nodes circle,
html.field-ready .memgraph .mg2-edges line,
html.field-ready .memgraph .mg2-al text{opacity:0}

/* what the record means, kept off the plate */
.mg2-inherit{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,4vw,72px);
  margin-top:clamp(26px,3vw,40px);padding-top:clamp(20px,2.2vw,28px);
  border-top:var(--hair) solid var(--line)}
.mg2-inherit .k{display:block;font-family:var(--mono);font-size:var(--mono-m2-size);
  font-weight:var(--mono-m2-weight);letter-spacing:var(--mono-m2-track);text-transform:uppercase;
  color:var(--accent);margin-bottom:8px}
.mg2-inherit p{margin:0;font-size:clamp(16px,1.4vw,19px);font-weight:560;letter-spacing:-.014em;
  color:var(--ink)}

@media(max-width:880px){
  .mg2-inherit{grid-template-columns:1fr;gap:20px}
}
/* =================== capacity: the week figure =================== */
.weekfig{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:clamp(28px,4vw,64px);
  align-items:center;border:var(--hair) solid var(--line);border-radius:var(--r-3);background:var(--bg-1);
  box-shadow:var(--lift);padding:clamp(26px,3vw,40px)}
.wf-h{display:flex;justify-content:space-between;font-family:var(--mono);font-size:var(--mono-m2-size);
  font-weight:var(--mono-m2-weight);letter-spacing:var(--mono-m2-track);text-transform:uppercase;
  color:var(--mute);margin-bottom:12px}
.wf-grid{display:grid;grid-template-columns:repeat(8,1fr);gap:7px}
.wc{aspect-ratio:10/7;border-radius:5px;background:linear-gradient(180deg,#FCFCFD,#ECEDEF);
  border:1px solid #DCDEE1}
.wc.c{background:linear-gradient(180deg,#CB5640,#A84232);border-color:#973D2B}
html.field-ready .weekfig.rv .wc{opacity:0;transform:scale(.7)}
html.field-ready .weekfig.rv.in .wc{opacity:1;transform:none;
  transition:opacity .4s var(--e-out) calc(var(--i)*14ms),transform .4s var(--e-out) calc(var(--i)*14ms)}
.wf-key{display:flex;gap:22px;margin-top:14px}
.wf-key .key{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--mute)}
.wf-key .key i{width:13px;height:13px;border-radius:4px;background:linear-gradient(180deg,#FCFCFD,#ECEDEF);
  border:1px solid #DCDEE1}
.wf-key .key.c i{background:linear-gradient(180deg,#CB5640,#A84232);border-color:#973D2B}
.wf-shift{display:flex;align-items:baseline;gap:16px}
.wf-shift .was{font-size:clamp(38px,3.6vw,54px);font-weight:480;letter-spacing:-.04em;color:var(--faint);line-height:1}
.wf-shift .ar{color:var(--accent)}
.wf-shift .ar svg{width:40px;height:20px}
.wf-shift .now{font-size:clamp(64px,6vw,92px);font-weight:520;letter-spacing:-.05em;color:var(--clay-display);line-height:1}
.wf-cap{font-size:clamp(16px,1.5vw,19px);line-height:1.5;color:var(--mute);margin:14px 0 0;max-width:30ch}
.wf-cap b{color:var(--ink);font-weight:600}
.wf-sub{font-size:var(--t-cap);line-height:1.55;color:var(--faint);margin:10px 0 0;max-width:40ch}
@media(max-width:880px){.weekfig{grid-template-columns:1fr}}

/* Vec introduces himself: the product mark, as the agent's own identity */
/* Vec's mark hangs in the left margin: the claim keeps the page's flush-left
   edge, and the mark reads as a marginal identity marker, not a second logo */
.vechead{position:relative}
/* the mark carries the claim's own type scale, so it stays optically centred
   on the cap band of the first line at every clamp step */
.vecmk{position:absolute;font-size:var(--t-stage);width:.72em;height:.72em;
  left:-1em;top:.285em;border-radius:.16em}
@media(max-width:1180px){
  .vecmk{position:static;display:block;width:38px;height:38px;font-size:inherit;margin-bottom:16px}
}

/* =================== project memory: the graph, assembling ===================
   Records are nodes, the links Vecreal draws are edges, and both arrive in
   project order. Density is the point: the links outnumber the documents. */
.memgraph{margin:0;border:var(--hair) solid var(--line);border-radius:var(--r-3);
  background:linear-gradient(180deg,#FFFFFF,var(--bg-1));box-shadow:var(--lift);overflow:hidden}

/* the assembly: records land in project order, links follow them */
html.field-ready .memgraph .mg2-nodes circle,
html.field-ready .memgraph .mg2-edges line,
html.field-ready .memgraph .mg2-al text{opacity:0}

/* what the record means, kept off the plate */
.mg2-inherit{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,4vw,72px);
  margin-top:clamp(26px,3vw,40px);padding-top:clamp(20px,2.2vw,28px);
  border-top:var(--hair) solid var(--line)}
.mg2-inherit .k{display:block;font-family:var(--mono);font-size:var(--mono-m2-size);
  font-weight:var(--mono-m2-weight);letter-spacing:var(--mono-m2-track);text-transform:uppercase;
  color:var(--accent);margin-bottom:8px}
.mg2-inherit p{margin:0;font-size:clamp(16px,1.4vw,19px);font-weight:560;letter-spacing:-.014em;
  color:var(--ink)}

@media(max-width:880px){
  .mg2-inherit{grid-template-columns:1fr;gap:20px}
}
/* =================== capacity: the week figure =================== */
.weekfig{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:clamp(28px,4vw,64px);
  align-items:center;border:var(--hair) solid var(--line);border-radius:var(--r-3);background:var(--bg-1);
  box-shadow:var(--lift);padding:clamp(26px,3vw,40px)}
.wf-h{display:flex;justify-content:space-between;font-family:var(--mono);font-size:var(--mono-m2-size);
  font-weight:var(--mono-m2-weight);letter-spacing:var(--mono-m2-track);text-transform:uppercase;
  color:var(--mute);margin-bottom:12px}
.wf-grid{display:grid;grid-template-columns:repeat(8,1fr);gap:7px}
.wc{aspect-ratio:10/7;border-radius:5px;background:linear-gradient(180deg,#FCFCFD,#ECEDEF);
  border:1px solid #DCDEE1}
.wc.c{background:linear-gradient(180deg,#CB5640,#A84232);border-color:#973D2B}
html.field-ready .weekfig.rv .wc{opacity:0;transform:scale(.7)}
html.field-ready .weekfig.rv.in .wc{opacity:1;transform:none;
  transition:opacity .4s var(--e-out) calc(var(--i)*14ms),transform .4s var(--e-out) calc(var(--i)*14ms)}
.wf-key{display:flex;gap:22px;margin-top:14px}
.wf-key .key{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--mute)}
.wf-key .key i{width:13px;height:13px;border-radius:4px;background:linear-gradient(180deg,#FCFCFD,#ECEDEF);
  border:1px solid #DCDEE1}
.wf-key .key.c i{background:linear-gradient(180deg,#CB5640,#A84232);border-color:#973D2B}
.wf-shift{display:flex;align-items:baseline;gap:16px}
.wf-shift .was{font-size:clamp(38px,3.6vw,54px);font-weight:480;letter-spacing:-.04em;color:var(--faint);line-height:1}
.wf-shift .ar{color:var(--accent)}
.wf-shift .ar svg{width:40px;height:20px}
.wf-shift .now{font-size:clamp(64px,6vw,92px);font-weight:520;letter-spacing:-.05em;color:var(--clay-display);line-height:1}
.wf-cap{font-size:clamp(16px,1.5vw,19px);line-height:1.5;color:var(--mute);margin:14px 0 0;max-width:30ch}
.wf-cap b{color:var(--ink);font-weight:600}
.wf-sub{font-size:var(--t-cap);line-height:1.55;color:var(--faint);margin:10px 0 0;max-width:40ch}
@media(max-width:880px){.weekfig{grid-template-columns:1fr}}

/* Vec introduces himself: the product mark, as the agent's own identity */
/* Vec's mark hangs in the left margin: the claim keeps the page's flush-left
   edge, and the mark reads as a marginal identity marker, not a second logo */
.vechead{position:relative}
/* the mark carries the claim's own type scale, so it stays optically centred
   on the cap band of the first line at every clamp step */
.vecmk{position:absolute;font-size:var(--t-stage);width:.72em;height:.72em;
  left:-1em;top:.285em;border-radius:.16em}
@media(max-width:1180px){
  .vecmk{position:static;display:block;width:38px;height:38px;font-size:inherit;margin-bottom:16px}
}

/* =================== the memory growth figure ===================
   Records accumulate week over week; the depth Vecreal can answer from
   compounds; the PM changes and the record does not. */
.memgrow{margin:0;border:var(--hair) solid var(--line);border-radius:var(--r-3);background:var(--bg-1);
  box-shadow:var(--lift);overflow:hidden}
/* what the accumulated record means, attached to the graph it came from */
.mgw-inherit{display:grid;grid-template-columns:1fr 1fr;border-top:var(--hair) solid var(--line-2)}

/* the accumulation performs: dots settle week by week, the curve draws through */
html.field-ready .memgrow .md{opacity:0}
html.field-ready .memgrow.in .md{opacity:.55;transition:opacity .45s var(--e-fast) calc(var(--w)*40ms)}
/* the playhead: one pass, left to right, as the record accumulates */
html.field-ready .memgrow.in .mgw-sweep{animation:mgw-run 1.75s var(--e-out) .1s 1 both}
@keyframes mgw-run{
  0%{opacity:0;transform:translateX(0)}
  9%{opacity:.5}
  88%{opacity:.3}
  100%{opacity:0;transform:translateX(1080px)}
}
@media(prefers-reduced-motion:reduce){
  html.field-ready .memgrow .md{opacity:.5}
}

/* the week figure on night: the record-heavy cells recede into the dark and
   the reclaimed hours carry the clay */
.band.night .weekfig .wc,.band.night .weekfig .wf-key .key i{
  background:linear-gradient(180deg,rgba(255,255,255,.075),rgba(255,255,255,.03));
  border-color:rgba(255,255,255,.17)}
.band.night .weekfig .wc.c,.band.night .weekfig .wf-key .key.c i{
  background:linear-gradient(180deg,#CB5640,#A84232);border-color:#B04A34}

/* ==========================================================================
   THE THESIS — the clay statement band, the two acts and the conclusion.
   ========================================================================== */
/* Thesis E.
   Clay is the header: Built for the GC organizes the section.
   The locked claim is the outcome under it. The lead is cut.
   01 and 02 support at reading scale, each with one instrument figure. */

/* -------------------------------------------------------------------------- */
/* Clay header                                                                */
/* -------------------------------------------------------------------------- */
.band.clay.thesise-head{
  position:relative;
  min-height:68svh;
  display:flex;
  align-items:center;
  padding:clamp(72px,10vh,120px) 0;
  background:linear-gradient(178deg,#BE5540 0%,#A64530 56%,#963E2B 100%);
  color:#FFF7F4;
}
.band.night + .band.clay.thesise-head::before{
  content:"";
  position:absolute;left:0;right:0;top:0;height:1px;
  background:rgba(255,255,255,.2);
}
.band.clay.thesise-head + .band.night::before{
  content:"";
  position:absolute;left:-240px;right:-240px;top:-200px;height:200px;
  pointer-events:none;z-index:1;
  box-shadow:0 8px 16px -2px rgba(96,32,18,.42),0 28px 52px -6px rgba(96,32,18,.5);
  clip-path:inset(200px 0 -120px 0);
}

.te-head{
  display:grid;
  grid-template-columns:minmax(0,1.15fr) minmax(260px,.8fr);
  grid-template-areas:
    "title copy"
    "outcome copy";
  column-gap:clamp(40px,6vw,96px);
  row-gap:32px;
  align-items:start;
}
.te-title{
  grid-area:title;
  margin:0;
  font-size:clamp(56px,7.6vw,112px);
  font-weight:var(--w-display);
  letter-spacing:-.044em;
  line-height:.94;
  color:#FFF7F4;
  text-wrap:balance;
  font-variation-settings:"opsz" 32;
}
.te-outcome{
  grid-area:outcome;
  margin:0;
  max-width:16em;
  font-size:clamp(22px,2.2vw,32px);
  font-weight:var(--w-display);
  letter-spacing:-.028em;
  line-height:1.12;
  color:rgba(255,247,244,.5);
}
.te-outcome b{
  display:block;
  color:#FFF7F4;
  font-weight:inherit;
}
.te-head .te-copy{
  grid-area:copy;
  padding-top:14px;
}
.te-am{
  font-size:clamp(16.5px,1.35vw,19px);
  font-weight:600;
  letter-spacing:-.014em;
  line-height:1.42;
  color:rgba(255,247,244,.94);
  margin:0 0 12px;
  max-width:32ch;
}
.te-ab{
  font-size:var(--t-body);
  line-height:1.62;
  color:rgba(255,247,244,.74);
  margin:0;
  max-width:40ch;
}

/* -------------------------------------------------------------------------- */
/* Support acts                                                               */
/* -------------------------------------------------------------------------- */
.band.thesise-act{
  padding:clamp(72px,10vh,128px) 0;
}
.te-grid{
  display:grid;
  grid-template-columns:minmax(260px,.78fr) minmax(0,1.22fr);
  gap:clamp(36px,5.5vw,96px);
  align-items:center;
}
.te-grid.flip{
  grid-template-columns:minmax(0,1.22fr) minmax(260px,.78fr);
}
.te-grid.flip .te-side{order:2}
.te-grid.flip .te-fig{order:1}

.te-i{
  display:block;
  font-family:var(--mono);
  font-size:var(--mono-m1-size);
  font-weight:var(--mono-m1-weight);
  letter-spacing:var(--mono-m1-track);
  text-transform:uppercase;
  color:rgba(235,233,229,.38);
  margin-bottom:16px;
}
.te-i b{color:var(--clay-lit);font-weight:var(--mono-m1-weight)}
.te-n{
  margin:0 0 16px;
  font-size:clamp(30px,3.2vw,44px);
  font-weight:var(--w-display);
  letter-spacing:-.032em;
  line-height:1.04;
  color:#F4F1ED;
  text-wrap:balance;
  font-variation-settings:"opsz" 32;
}
.te-side .te-am{
  color:rgba(244,241,237,.92);
}
.te-side .te-ab{
  color:rgba(235,233,229,.58);
}

/* -------------------------------------------------------------------------- */
/* 01 · section through the job                                               */
/* -------------------------------------------------------------------------- */
.te-fig{
  position:relative;
  padding:4px 4px 56px 0;
}
.te-cut{
  position:relative;
  z-index:1;
  border-top:var(--hair) solid rgba(255,255,255,.14);
  border-bottom:var(--hair) solid rgba(255,255,255,.14);
}
.te-row{
  display:grid;
  grid-template-columns:92px minmax(0,1fr);
  gap:18px;
  align-items:center;
  min-height:76px;
  padding:0 4px 0 2px;
}
.te-row + .te-row{border-top:var(--hair) solid rgba(255,255,255,.1)}
.te-sys{
  font-family:var(--mono);
  font-size:var(--mono-m1-size);
  font-weight:var(--mono-m1-weight);
  letter-spacing:var(--mono-m1-track);
  text-transform:uppercase;
  color:rgba(235,233,229,.46);
  line-height:1;
}
.te-track{
  display:flex;
  align-items:center;
  gap:10px;
  min-width:0;
  overflow:hidden;
}
.te-t{
  display:block;
  flex:none;
  height:4px;
  width:calc(20px + var(--w,.5)*64px);
  border-radius:2px;
  background:rgba(242,241,237,.22);
  font-style:normal;
}
.te-t.ghost{opacity:.32}
.te-t[data-thread]{
  background:var(--clay-lit);
  height:5px;
  border-radius:2.5px;
}

.te-thru{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  overflow:visible;
  pointer-events:none;
  z-index:2;
}
.te-thru .wv{
  fill:none;
  stroke:var(--clay-lit);
  stroke-width:2.2;
  stroke-linecap:round;
  stroke-linejoin:round;
}
.te-thru .pulse{
  fill:none;
  stroke:#D8A89D;
  stroke-width:1.7;
  stroke-linecap:round;
  opacity:.9;
  stroke-dasharray:16 var(--len,700);
  stroke-dashoffset:var(--len,700);
}
.te-thru .tdot{fill:var(--clay-lit)}
.te-node{
  position:absolute;
  z-index:3;
  width:30px;height:30px;
  margin:0;
  border-radius:8px;
  background:var(--clay-display);
  color:#fff;
  display:flex;
  align-items:center;
  justify-content:center;
  transform:translate(-50%,-50%);
  box-shadow:0 0 0 8px rgba(184,73,50,.1),0 0 24px rgba(184,73,50,.32);
  pointer-events:none;
}
.te-node svg{width:58%;height:58%}

@keyframes te-run{
  from{stroke-dashoffset:var(--len,700)}
  to{stroke-dashoffset:0}
}
.te-fig.built .te-thru .pulse{
  animation:te-run 5.6s linear 1.2s infinite;
}

/* -------------------------------------------------------------------------- */
/* 02 · fork                                                                  */
/* -------------------------------------------------------------------------- */
.te-fork{padding:0}
.te-fork svg{width:100%;height:auto;display:block;overflow:visible}
.te-fork .axis,.te-fork .tick{
  stroke:rgba(255,255,255,.16);
  stroke-width:1;
}
.te-fork .avoid{fill:rgba(198,128,112,.07)}
.te-fork .c0{
  stroke:rgba(235,233,229,.42);
  stroke-width:2;
  stroke-linecap:round;
}
.te-fork .c1{
  stroke:rgba(235,233,229,.28);
  stroke-width:1.7;
  stroke-dasharray:6 8;
  stroke-linecap:round;
}
.te-fork .c2{
  stroke:var(--clay-lit);
  stroke-width:2.6;
  stroke-linecap:round;
}
.te-fork .pin{
  stroke:var(--clay-lit);
  stroke-width:1.4;
}
.te-fork .fd,.te-fork .fe{fill:var(--clay-lit)}
.te-fork .chip rect{
  fill:#101216;
  stroke:rgba(198,128,112,.5);
  stroke-width:1.2;
}
.te-fork .ck{
  font-family:var(--mono);
  font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight);letter-spacing:var(--mono-m1-track);
  fill:var(--clay-lit);
}
.te-fork .cv{
  font-family:var(--mono);
  font-size:var(--mono-m3-size);letter-spacing:var(--mono-m3-track);
  fill:rgba(235,233,229,.7);
}
.te-fork .ax{
  font-family:var(--mono);
  font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight);letter-spacing:var(--mono-m1-track);
  fill:rgba(235,233,229,.34);
}

/* -------------------------------------------------------------------------- */
/* Reveals                                                                    */
/* -------------------------------------------------------------------------- */
html.field-ready .te-head,
html.field-ready .te-side,
html.field-ready .te-fig{
  opacity:0;
  transform:translateY(16px);
}
html.field-ready .te-head.in,
html.field-ready .te-side.in,
html.field-ready .te-fig.in{
  opacity:1;
  transform:none;
  transition:opacity var(--m-4) var(--e-out),transform var(--m-4) var(--e-out);
}

html.field-ready .te-thru .wv{
  stroke-dasharray:var(--len,1400);
  stroke-dashoffset:var(--len,1400);
}
html.field-ready .te-fig.built .te-thru .wv{
  stroke-dashoffset:0;
  /* the read is laid, not switched on: --e-out is ~70% done in its first
     15%, which reads as an instant line. A gentler curve over a longer
     run, a beat later, lets the trace travel. */
  transition:stroke-dashoffset 1.15s cubic-bezier(.42,.02,.38,1) .32s;
}
html.field-ready .te-thru .tdot,
html.field-ready .te-node{
  opacity:0;
}
/* The trace draws from .15s on a front-loaded ease and reads complete by about
   .6s. The mark is what it points at, so it lands under the arriving line
   rather than a second behind it, and the label follows the mark. */
html.field-ready .te-fig.built .te-thru .tdot{
  opacity:1;
  transition:opacity .3s var(--e-fast) .42s;
}
html.field-ready .te-fig.built .te-node{
  opacity:1;
  transition:opacity .30s var(--e-out) 1.30s;
}

html.field-ready .te-fork .c0{stroke-dasharray:360;stroke-dashoffset:360}
/* The trunk and the branch are one gesture, not two.
   They ran .15-.85 and 1.00-1.80, which left 150ms in which no line moved, and
   both used --e-out, whose long tail parks each stroke before the next starts.
   Read together that is exactly what it looked like: a quick draw, a pause, a
   second quick draw. The branch now leaves the fork on the frame the trunk
   reaches it, both run the same .68s, and both take --e-fast, which decelerates
   without stopping -- so the hand-off at (320,248) happens mid-motion. */
html.field-ready .te-fork.in .c0{
  stroke-dashoffset:0;
  transition:stroke-dashoffset .68s var(--e-fast) .15s;
}
/* the fork dot marks the junction, so it lands as the trunk arrives at it
   rather than a beat afterwards */
html.field-ready .te-fork .fd,
html.field-ready .te-fork .pin,
html.field-ready .te-fork .chip{
  opacity:0;
  transition:opacity .3s var(--e-fast) .66s;
}
html.field-ready .te-fork.in .fd,
html.field-ready .te-fork.in .pin,
html.field-ready .te-fork.in .chip{opacity:1}
html.field-ready .te-fork .c2{stroke-dasharray:380;stroke-dashoffset:380}
html.field-ready .te-fork.in .c2{
  stroke-dashoffset:0;
  transition:stroke-dashoffset .68s var(--e-fast) .83s;
}
html.field-ready .te-fork .fe{opacity:0;transition:opacity .3s var(--e-fast) 1.42s}
html.field-ready .te-fork.in .fe{opacity:1}
/* the drift path and its shaded gap arrive once the safe branch has landed:
   the point of the figure is the difference between them, which cannot be read
   until there are two lines to compare */
html.field-ready .te-fork .c1,
html.field-ready .te-fork .avoid{
  opacity:0;
  transition:opacity .5s var(--e-fast) 1.46s;
}
html.field-ready .te-fork.in .c1{opacity:.9}
html.field-ready .te-fork.in .avoid{opacity:1}

@media (prefers-reduced-motion:reduce){
  html.field-ready .te-head,
  html.field-ready .te-side,
  html.field-ready .te-fig,
  html.field-ready .te-thru .tdot,
  html.field-ready .te-node,
  html.field-ready .te-fork .fd,
  html.field-ready .te-fork .pin,
  html.field-ready .te-fork .chip,
  html.field-ready .te-fork .fe,
  html.field-ready .te-fork .c1,
  html.field-ready .te-fork .avoid{
    opacity:1;transform:none;transition:none;
  }
  html.field-ready .te-thru .wv,
  html.field-ready .te-fork .c0,
  html.field-ready .te-fork .c2{stroke-dashoffset:0;transition:none}
  .te-fig.built .te-thru .pulse{animation:none;opacity:0}
}

@media (max-width:960px){
  .band.clay.thesise-head{min-height:0;padding:72px 0}
  .te-head{
    grid-template-columns:1fr;
    grid-template-areas:"title" "outcome" "copy";
    row-gap:20px;
  }
  .te-title{font-size:clamp(48px,14vw,72px)}
  .te-title br{display:none}
  .te-outcome{font-size:clamp(20px,5.6vw,26px);max-width:none}
  .te-grid,
  .te-grid.flip{
    grid-template-columns:1fr;
    min-height:0;
    gap:28px;
  }
  .te-grid.flip .te-side{order:1}
  .te-grid.flip .te-fig{order:2}
  .te-n{font-size:clamp(28px,8vw,36px)}
  .te-fig{min-height:0;padding:0 0 52px}
  .te-row{grid-template-columns:78px 1fr;min-height:56px;gap:12px}
  .te-t{width:calc(12px + var(--w,.5)*28px)}
}

/* ═══════════ E2 ═══════════
   The outcome reads as a promise, the clay band tightens, act 01 declares
   itself continuous, and act 02 names the two costs. */

/* the clay band stays big on purpose; with the promise moved out, the two
   remaining blocks centre on each other so the scale reads as intent */
.band.clay.thesise-head{min-height:72svh}
.te-head{grid-template-areas:"title copy";row-gap:0;align-items:center}
.te-head .te-copy{padding-top:0;align-self:center}

/* the conclusion: the promise alone, closing the intro before the outcomes */
.te-close{padding:clamp(84px,12vh,150px) 0}
.te-conclude{margin:0 auto;text-align:center;max-width:22ch;
  font-size:clamp(38px,4.6vw,68px);font-weight:var(--w-display);letter-spacing:-.034em;
  line-height:1.04;color:rgba(244,241,237,.42)}
.te-conclude b{color:#F4F1ED;font-weight:inherit}

/* 3. act 01 declares the continuous read */

/* 4. act 02 names the two costs */
.te-fork .cst{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight);letter-spacing:var(--mono-m1-track);
  fill:rgba(235,233,229,.42)}
.te-fork .cst.on{fill:var(--clay-lit)}

@media(max-width:900px){
  .te-conclude{font-size:clamp(30px,8vw,42px)}
  .te-head{grid-template-areas:"title" "copy";row-gap:22px}
}
@media(prefers-reduced-motion:reduce){.te-live i{animation:none}}

/* ═══════════ E2 polish ═══════════ */

/* 1. the clay title settles as the band arrives, rather than fading in */
.te-title{letter-spacing:-.028em;transition:letter-spacing .9s var(--e-out),
  transform .8s var(--e-out),opacity .7s var(--e-fast)}
html.field-ready .te-head:not(.in) .te-title{opacity:0;transform:translateY(14px)}
html.field-ready .te-head.in .te-title{opacity:1;transform:none;letter-spacing:-.044em}

/* 2. the clay band is lit from within: the cut above it bleeds warm, matching
      the treatment already on its lower edge */
.band.night + .band.clay.thesise-head::before{
  height:auto;bottom:auto;left:-240px;right:-240px;top:0;height:170px;
  background:linear-gradient(180deg,rgba(255,255,255,.22) 0 1px,
    rgba(190,85,64,.55) 1px,rgba(190,85,64,0) 100%);
  pointer-events:none;z-index:0}
.thesise-head .frame{position:relative;z-index:1}

/* the two blocks sit closer: the title and what it means read as one lockup */
/* the title and its meaning: close enough to lock up, apart enough to breathe */
.te-head{column-gap:clamp(52px,6vw,92px);justify-content:start;
  grid-template-columns:max-content minmax(280px,.56fr)}

@media(max-width:900px){
  .te-head{grid-template-columns:1fr;justify-content:stretch}
}

/* the clay band's lede carries more weight against a 112px title */
.te-am{font-size:clamp(19px,1.75vw,25px);line-height:1.34;margin-bottom:14px}
.thesise-act .te-am{font-size:clamp(18px,1.55vw,22px)}

/* the rails end where the record ends, and the cut sits to the right */
.te-cut{width:max-content;max-width:100%;margin-left:auto}
.te-fig{padding-bottom:0}

/* ═══════════ the acts: title, rule, then what it means ═══════════
   The title sits in the copy block above a hairline. The brightness ladder is
   deliberate but slight; the rule does the separating. */
.thesise-act .te-grid{align-items:center}
.thesise-act .te-n{margin:0 0 clamp(18px,2vw,24px);padding-bottom:clamp(16px,1.8vw,22px);
  border-bottom:var(--hair) solid rgba(255,255,255,.14);
  font-size:clamp(34px,3.5vw,50px);line-height:1.04;letter-spacing:-.03em;color:#F4F1ED}
.thesise-act .te-am{font-size:clamp(19px,1.7vw,24px);font-weight:560;line-height:1.36;
  color:rgba(244,241,237,.92);margin:0 0 13px;max-width:32ch}
.thesise-act .te-ab{font-size:clamp(15.5px,1.2vw,17.5px);line-height:1.62;
  color:rgba(235,233,229,.62);margin:0;max-width:44ch}
.thesise-act .te-ab b{color:rgba(244,241,237,.88);font-weight:560}

/* the mark clears the last hairline and carries a touch more presence */
.te-node{width:36px;height:36px;border-radius:10px}
.te-fig{position:relative;padding-bottom:74px}
.te-fork{padding-bottom:8px}
@media(max-width:900px){
  .thesise-act .te-grid,.thesise-act .te-grid.flip{grid-template-columns:1fr}
}

/* the clay band centres: one column, the statement stacked and centred */
.te-head{grid-template-columns:minmax(0,min(760px,100%));grid-template-areas:"title" "copy";
  justify-content:center;justify-items:center;text-align:center;row-gap:clamp(22px,2.6vw,34px)}
.te-title{text-align:center}
.te-head .te-copy{padding-top:0;max-width:60ch}
.te-am,.te-ab{margin-left:auto;margin-right:auto}
.band.clay .te-am{max-width:34ch}
.band.clay .te-ab{max-width:62ch}

/* the read travels the trace and lights each record as it passes: one legible
   gesture instead of bars sliding inside the rails */
.te-thru .wv{stroke-width:2.6}
.te-thru .pulse{stroke:#F3CBBE;stroke-width:2.8;opacity:1;stroke-dasharray:26 var(--len,700)}
.te-thru .glow{fill:none;stroke:rgba(243,203,190,.30);stroke-width:9;stroke-linecap:round;
  stroke-dasharray:26 var(--len,700);stroke-dashoffset:var(--len,700)}
/* the halo rides the pulse. Given its own 2.1s delay it sat 0.9s behind, and
   at 16% of a 5.6s loop that is far past the point where the eye fuses two
   marks into one object: it stopped reading as a bloom and became a second,
   fatter, dimmer runner chasing the first. */
.te-fig.built .te-thru .glow{animation:te-run 5.6s linear 1.2s infinite}
@media(prefers-reduced-motion:reduce){
    .te-fig.built .te-thru .glow{animation:none;opacity:0}
}

/* the read is quieter than the words it travels under */
.te-thru .wv{stroke:rgba(198,128,112,.72);stroke-width:2.2}
.te-thru .pulse{stroke:#E0AFA2;stroke-width:2.4;opacity:.92;stroke-dasharray:24 var(--len,700)}
.te-thru .glow{stroke:rgba(224,175,162,.18);stroke-width:8;stroke-dasharray:24 var(--len,700)}

/* each record lights as the read reaches it, timed from the path itself */
.te-fig.built .te-cut [data-thread]{animation:te-lit 5.6s linear infinite;animation-delay:var(--d,1.2s)}
.te-fig.built .te-cut .te-row:nth-child(1) [data-thread],
.te-fig.built .te-cut .te-row:nth-child(2) [data-thread],
.te-fig.built .te-cut .te-row:nth-child(3) [data-thread],
.te-fig.built .te-cut .te-row:nth-child(4) [data-thread],
.te-fig.built .te-cut .te-row:nth-child(5) [data-thread]{animation-delay:var(--d,1.2s)}
@keyframes te-lit{
  0%{background:#F7D8CD;box-shadow:0 0 12px rgba(224,175,162,.6);height:6px}
  14%{background:var(--clay-lit);box-shadow:none;height:5px}
  100%{background:var(--clay-lit);box-shadow:none;height:5px}
}

/* the mark takes the same blip when the read arrives */
@keyframes te-blip{
  0%{box-shadow:0 0 0 0 rgba(224,175,162,.55),0 10px 26px -10px rgba(0,0,0,.7);
     transform:translate(-50%,-50%) scale(1.08)}
  16%{box-shadow:0 0 0 13px rgba(224,175,162,0),0 10px 26px -10px rgba(0,0,0,.7);
     transform:translate(-50%,-50%) scale(1)}
  100%{box-shadow:0 0 0 0 rgba(224,175,162,0),0 10px 26px -10px rgba(0,0,0,.7);
     transform:translate(-50%,-50%) scale(1)}
}
.te-fig.built .te-node{animation:te-blip 5.6s linear infinite;animation-delay:var(--d,6.8s)}
/* the mark says who is doing the reading; the label sits outside it so the
   arrival blip scales the mark alone */
.te-nlab{position:absolute;z-index:3;transform:translate(-100%,-50%);
  font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight);
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--clay-lit);
  white-space:nowrap;pointer-events:none}
html.field-ready .te-nlab{opacity:0}
html.field-ready .te-fig.built .te-nlab{opacity:1;transition:opacity .30s var(--e-fast) 1.54s}

/* the system names read a step brighter */
.te-sys{color:rgba(235,233,229,.62)}

@media(prefers-reduced-motion:reduce){
  .te-fig.built .te-cut [data-thread],.te-fig.built .te-node{animation:none}
}

/* the intelligence figure sits closer to the record it reads, and its callouts
   ride a shorter leader: a modest densening, not a redesign */
.layer-fig .lrow{margin-top:clamp(18px,2vw,26px)}
.layer-fig .lead-note{margin-top:clamp(-6px,-.4vw,-2px)}
.layer-fig .ld{--ld-h:clamp(26px,2.6vw,34px)}
.layer-fig .leads path{stroke-dasharray:none}

/* a card on a night ground is a night plate: the light sheet and its grey copy
   belong to day grounds only */
.band.night .card{
  background:linear-gradient(180deg,rgba(255,255,255,.038),rgba(255,255,255,.014));
  border-color:rgba(255,255,255,.13);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05)}
.band.night .card h3,.band.night .card .ck2{color:#F4F1ED}
.band.night .card .ck2 b{color:var(--clay-lit)}
.band.night .card p{color:rgba(235,233,229,.62)}
.band.night .card p b{color:rgba(244,241,237,.9)}
.band.night a.card:hover,.band.night .card.hover:hover{
  border-color:var(--clay-line);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 18px 40px -30px rgba(0,0,0,.9)}

/* ══ THE HERO AND THE STATEMENT ═════════════════════════════════════════════
   The hero states the category and nothing else, held in a deliberate viewport.
   The statement band then says what Vecreal is and, beside the definition,
   shows the outcome it produces. Night runs unbroken from one into the other. */
#era{min-height:100svh;display:flex;align-items:center;padding-block:0}
/* ── THE HERO BACKDROP: the drawing sheet, lit ────────────────────────────
   The shared ground carries no pattern by system rule, so this is a hero-only
   pair of layers between the ground and the type. A modular field rings the
   headline and clears out behind it; a soft box lights the middle, the corners
   close down, and one measured datum gives the composition a floor. */
#era{isolation:isolate}
#era>.frame{position:relative;z-index:3}
#era .hb{position:absolute;inset:0;pointer-events:none;overflow:hidden}
#era .hb-lit{z-index:1}
/* The field terminates ON the datum. That is the whole idea of a datum: the
   sheet has a floor and the ruling stops there. Fading it through the floor was
   tried and is wrong -- it turns a measured edge into a smudge. */
#era .hb-sheet{z-index:2;bottom:auto;height:calc(var(--datum,86%) + 1px)}
#era .ground::before{background:
  radial-gradient(ellipse 60% 48% at 50% 34%,rgba(255,255,255,.062),rgba(255,255,255,.022) 44%,transparent 74%)}
/* .hb-sheen was a 96deg hatch at a 10px pitch: a second ruling, six degrees off
   vertical, inside a field whose whole premise is one 120px orthogonal module.
   Two rulings in one space is noise rather than drafting. It also measured a
   maximum of 2 luma levels against a render without it, so it was not carrying
   the texture it was there for -- while still being enough of a step to show on
   an OLED, where near-black separates. The grain layer already gives the ground
   its surface. Retired; the element stays in the markup as an inert hook. */
#era .hb-sheen{display:none}
#era .hb-floor{position:absolute;left:0;right:0;bottom:0;height:44%;
  background:radial-gradient(ellipse 52% 100% at 50% 100%,rgba(255,255,255,.030),transparent 70%)}
#era .hb-vig{position:absolute;inset:0;
  background:radial-gradient(ellipse 116% 102% at 50% 44%,transparent 40%,rgba(0,0,0,.46) 80%,rgba(0,0,0,.66))}
/* the field is anchored at the top so its rows land on a known module, and it
   stops on the datum rather than fading out somewhere below it */
#era .hb-grid{position:absolute;left:0;right:0;top:0;height:100svh;
  background:
    repeating-linear-gradient(90deg,rgba(255,255,255,.16) 0 1px,transparent 1px 120px),
    repeating-linear-gradient(180deg,rgba(255,255,255,.10) 0 1px,transparent 1px 120px);
  /* columns offset to put one on the centre, rows offset to put one on the
     datum: the field is registered to the composition, not to the origin */
  background-position:var(--gx,0) 0,0 var(--gy,0);
  -webkit-mask-image:radial-gradient(ellipse 56% 44% at 50% 46%,transparent 8%,rgba(0,0,0,.9) 60%,rgba(0,0,0,.22) 94%);
  mask-image:radial-gradient(ellipse 56% 44% at 50% 46%,transparent 8%,rgba(0,0,0,.9) 60%,rgba(0,0,0,.22) 94%)}
/* the datum hangs a set distance below the centred content, and never comes
   closer than its own margin to the bottom edge */
#era .hb-datum{position:absolute;left:0;right:0;height:26px;top:var(--datum,86%);z-index:2}
#era .hb-rule{position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.16) 12%,rgba(255,255,255,.16) 88%,transparent)}
#era .hb-ticks{position:absolute;left:0;right:0;top:0;height:13px;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,.16) 0 1px,transparent 1px 120px);
  background-position:var(--gx,0) 0}
#era .hb-ticks::after{content:"";position:absolute;left:0;right:0;top:0;height:6px;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,.13) 0 1px,transparent 1px 30px)}
#era .hb-c0{position:absolute;top:0;left:var(--dx,50%);width:1.4px;height:20px;
  background:var(--clay-lit);opacity:.75}
/* the second action was the one element the sheet showed through: on a hero
   with a ground behind it, it takes a solid night plate */
#era .btn.ghost{background:#15171C;border-color:rgba(255,255,255,.16);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 10px 22px -14px rgba(0,0,0,.8)}
#era .btn.ghost:hover{background:#1A1D22;border-color:var(--accent)}
@media(max-width:820px){
  #era .hb-grid{background-size:auto;
    -webkit-mask-image:radial-gradient(ellipse 96% 42% at 50% 50%,transparent 10%,rgba(0,0,0,.8) 72%,transparent);
    mask-image:radial-gradient(ellipse 96% 42% at 50% 50%,transparent 10%,rgba(0,0,0,.8) 72%,transparent)}
  /* No datum override here. --datum is the last full 120px row of the sheet,
     computed in field.js, and .hb-sheet ends on it. Pinning the datum to a
     viewport offset instead put the line somewhere the grid does not end, which
     is the band between the two. The module governs at every width. */
}
#era .frame{width:100%}
#era h1{max-width:17ch;font-size:clamp(52px,7.4vw,104px);line-height:.99;letter-spacing:-.042em}
#era .lead{max-width:44ch;margin-top:clamp(24px,2.6vw,34px);font-size:clamp(18px,1.6vw,23px)}
#era .actions{margin-top:clamp(32px,3.4vw,46px)}

/* the definition gets its own section: a kicker, a claim, a lead, and the
   outcome beneath it with room to land before the clay wall arrives */
.statement{padding-block:clamp(96px,12vh,168px) clamp(104px,13vh,180px)}
.statement .stage-head{margin-bottom:clamp(48px,5.6vw,84px)}
.stmt-k{display:block;margin-bottom:16px;font-family:var(--mono);
  font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight);
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--clay-lit)}
.statement .stmt{margin:0;text-align:left;max-width:20ch;
  font-size:clamp(30px,3.2vw,46px);font-weight:var(--w-display);line-height:1.08;
  letter-spacing:-.03em;color:#F4F1ED}
.statement .lead{max-width:46ch}

.stmt-out{position:relative}
.so-k2{display:block;margin-bottom:clamp(18px,2vw,26px);padding-bottom:14px;
  border-bottom:var(--hair) solid rgba(255,255,255,.12);
  font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight);
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:rgba(235,233,229,.52)}
.so-rows{position:relative;display:flex;flex-direction:column;gap:clamp(18px,2vw,26px);
  padding-bottom:32px}
.so-row{display:grid;grid-template-columns:132px minmax(0,1fr);gap:16px;align-items:center}
.so-k{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight);
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:rgba(235,233,229,.60)}
.so-row.on .so-k{color:var(--clay-lit)}
.so-bar{position:relative;height:16px;border-radius:8px;background:rgba(255,255,255,.05);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.45),inset 0 0 0 1px rgba(255,255,255,.05)}
.so-fill{position:absolute;left:0;top:0;bottom:0;width:76%;border-radius:8px;
  background:linear-gradient(180deg,rgba(198,128,112,.9),rgba(156,74,51,.92));
  transform:scaleX(0);transform-origin:left center}
/* the drifting bar runs into the overrun, so it must not round off at the
   seam: it terminates square on the contract mark */
.so-fill.drift{border-radius:8px 0 0 8px;
  background:linear-gradient(180deg,rgba(235,233,229,.40),rgba(235,233,229,.24))}
.so-over{position:absolute;left:76%;top:0;bottom:0;width:22%;border-radius:0 8px 8px 0;
  background-color:#241a17;
  background-image:repeating-linear-gradient(-45deg,rgba(198,128,112,.72) 0 5px,rgba(198,128,112,.26) 5px 10px);
  box-shadow:inset 0 0 0 1px rgba(198,128,112,.28);transform:scaleX(0);transform-origin:left center}
/* off-scale on purpose: the outcome value sits between M3 and body so it
   reads as a result rather than a label */
.so-v{grid-column:2;font-family:var(--mono);font-size:13px;letter-spacing:.01em;
  font-variant-numeric:tabular-nums;color:var(--clay-lit);margin-top:-8px}
.so-v.drift{color:rgba(235,233,229,.66)}
.so-mark{position:absolute;left:calc(132px + 16px + (100% - 132px - 16px)*0.76);
  top:-4px;bottom:22px;pointer-events:none}
.so-mark i{position:absolute;left:0;top:0;bottom:0;width:1px;
  background:repeating-linear-gradient(to bottom,rgba(255,255,255,.34) 0 4px,transparent 4px 9px)}
.so-mark span{position:absolute;left:0;bottom:-20px;transform:translateX(-50%);white-space:nowrap;
  font-family:var(--mono);font-size:var(--mono-m2-size);font-weight:var(--mono-m2-weight);
  letter-spacing:var(--mono-m2-track);text-transform:uppercase;color:rgba(235,233,229,.56)}
html.field-ready .stmt-out.in .so-fill{transform:scaleX(1);transition:transform 1s var(--e-out) .2s}
html.field-ready .stmt-out.in .so-row.on .so-fill{transition-delay:.45s}
html.field-ready .stmt-out.in .so-over{transform:scaleX(1);transition:transform .6s var(--e-out) 1.1s}
/* Stacked, the bar takes the whole row, so the contract mark is 76% of the
   rows box rather than 76% of the track that sat beside a 132px label. It is
   the point the whole figure is about and it stays on the phone: the line
   crosses both bars at the same x, and the label keeps the M2 mono floor. */
@media(max-width:960px){
  .so-row{grid-template-columns:1fr;gap:7px}
  .so-v{grid-column:1}
  .so-rows{padding-bottom:34px}
  .so-mark{left:76%;top:-2px;bottom:24px}
  .so-mark span{bottom:-19px}
}
/* below ~360 the centred label runs past the right edge, so it hangs from the
   mark instead of straddling it. It still reads as the line's caption. */
@media(max-width:360px){
  .so-mark span{left:auto;right:0;transform:none}
}
@media(prefers-reduced-motion:reduce){
  html.field-ready .stmt-out .so-fill,html.field-ready .stmt-out .so-over{transform:scaleX(1);transition:none}
}

/* ══ PROJECT MEMORY ═════════════════════════════════════════════════════════
   The chapter closes light. One line, drawn with care and given room; the
   density lives in the sections above this one. The mark sits at the end of
   the line, in the same material it carries everywhere else on the site. */
/* ── the memory line ──────────────────────────────────────────────────────
   The plot is geometry only. Every mark and every label sits in HTML over it,
   because anything inside the SVG inherits the viewBox scale -- 0.292 on a
   phone, which rendered the handover dot 2.6px across and the dashed line at
   0.29px. Out in HTML they are CSS pixels on every screen.

   That also frees the plot to stretch: preserveAspectRatio="none" plus
   non-scaling strokes means a phone can have a taller box showing more of the
   climb, without a distorted line weight or a squashed glyph anywhere. */
.memline{margin:clamp(40px,3vw,40px) 0 0;padding:0}
.ml-plot{--ml-axis-h:clamp(46px,4vw,52px);position:relative;padding-bottom:var(--ml-axis-h)}
.ml-svg{display:block;width:100%;aspect-ratio:1200/306}
.ml-base{stroke:var(--line);stroke-width:1;vector-effect:non-scaling-stroke}
.ml-curve{stroke:var(--clay-display);stroke-width:2.6;stroke-linecap:round;fill:none;
  vector-effect:non-scaling-stroke}

/* the handover mark, on the home statement's own grammar: a 4/5 dashed rule
   with the label beneath it. The old one used --line-2, which is 6% ink -- a
   0.06 alpha hairline is not a quiet mark, it is an absent one. */
.ml-mark{position:absolute;left:62.225%;top:0;bottom:var(--ml-axis-h);
  width:0;pointer-events:none}
.ml-mark-line{position:absolute;left:-.5px;top:61.99%;bottom:1.96%;width:1px;
  background:repeating-linear-gradient(to bottom,rgba(25,24,23,.34) 0 4px,transparent 4px 9px)}
/* solid, and sized in CSS so it is the same dot at every width. As an SVG
   circle under a non-uniform scale it would have rendered an ellipse. */
.ml-mark-dot{position:absolute;left:50%;top:61.99%;transform:translate(-50%,-50%);
  width:11px;height:11px;border-radius:50%;background:var(--clay-display);
  box-shadow:0 0 0 3px var(--bg),0 1px 3px rgba(25,24,23,.28)}

.ml-axis{position:absolute;left:0;right:0;bottom:0;height:var(--ml-axis-h)}
.ml-ax{position:absolute;top:6px;font-family:var(--mono);font-size:var(--mono-m2-size);
  font-weight:var(--mono-m2-weight);letter-spacing:var(--mono-m2-track);
  text-transform:uppercase;color:var(--faint);white-space:nowrap}
.ml-ax-a{left:6.667%}
.ml-ax-b{left:93.333%;transform:translateX(-100%)}
.ml-hand-lab{position:absolute;left:62.225%;top:4px;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:2px;
  white-space:nowrap;text-align:center}
.ml-hand-lab b{font-family:var(--mono);font-size:var(--mono-m2-size);
  font-weight:var(--mono-m2-weight);letter-spacing:var(--mono-m2-track);
  text-transform:uppercase;color:var(--ink)}
.ml-hand-lab em{font-style:normal;font-size:12px;line-height:1.2;color:var(--mute)}
/* off-scale on purpose: the axis sits below every label on the page so it
   recedes behind the curve it measures */
/* the terminus is the mark itself, positioned off the plot's own coordinates */
/* ── the phone gets a taller plot ────────────────────────────────────────
   At 1200/306 a 350px-wide phone rendered the whole climb inside 89px, so the
   curve read as a nearly flat line with a kink at the end -- the one thing the
   figure exists to show was the thing it could not show. The box goes to 5:4,
   and because the strokes do not scale and no text lives inside it, the only
   thing that stretches is the curve itself. */
@media(max-width:700px){
  .ml-svg{aspect-ratio:1200/560}
  .ml-mark-dot{width:13px;height:13px}
  .ml-hand-lab em{font-size:11.5px}
}
@media(max-width:430px){
  .ml-svg{aspect-ratio:1200/620}
  .memline{margin-top:44px}
}
/* The handover annotation is centred at 62% of the plot and "WEEK 40" is
   anchored to its right end, so on a narrow screen they converge: measured, the
   sub-line overran WEEK 40 by 19px at 320, 6px at 360 and cleared it by 3px at
   390. Below 460 the annotation takes its own row underneath the week marks
   instead, which is unambiguous at every width rather than nearly clear at
   some of them. */
@media(max-width:460px){
  .ml-plot{--ml-axis-h:76px}
  .ml-hand-lab{top:32px}
}

.ml-mk{position:absolute;left:93.333%;top:13.889%;transform:translate(-50%,-50%);
  width:30px;height:30px;border-radius:8px;background:var(--clay-display);color:#fff;
  display:flex;align-items:center;justify-content:center;pointer-events:none;
  box-shadow:0 0 0 7px rgba(184,73,50,.09),0 8px 22px -10px rgba(184,73,50,.5)}
.ml-mk svg{width:58%;height:58%}

.ml-foot{display:flex;align-items:baseline;gap:clamp(34px,4.6vw,72px);
  margin-top:clamp(20px,2.4vw,30px);padding-top:clamp(18px,2vw,26px);
  border-top:var(--hair) solid var(--line)}
.ml-n{display:flex;align-items:baseline;gap:12px}
.ml-n b{font-size:clamp(30px,3.4vw,46px);font-weight:520;letter-spacing:-.03em;color:var(--ink);
  font-variant-numeric:tabular-nums;line-height:1}
.ml-n em{font-style:normal;font-family:var(--mono);font-size:var(--mono-m3-size);
  letter-spacing:var(--mono-m3-track);color:var(--mute);max-width:17ch;line-height:1.45}
.ml-note{margin-left:auto;font-family:var(--mono);font-size:var(--mono-m3-size);
  letter-spacing:var(--mono-m3-track);color:var(--faint)}

/* the line draws once, the handover resolves after it passes, the mark lands last */
/* the draw was set to a guessed 1500 against a path that is longer, so it
   started part-drawn and finished early: the length is measured now, and the
   curve runs at an even pace rather than easing out of a wrong start */
html.field-ready .memline .ml-curve{stroke-dasharray:var(--mlen,1500);stroke-dashoffset:var(--mlen,1500)}
html.field-ready .memline.in .ml-curve{stroke-dashoffset:0;
  transition:stroke-dashoffset 1.55s cubic-bezier(.33,.06,.28,1) .12s}
html.field-ready .memline .ml-area{opacity:0}
html.field-ready .memline.in .ml-area{opacity:1;transition:opacity .8s var(--e-fast) .75s}
html.field-ready .memline .ml-mark,
html.field-ready .memline .ml-hand-lab{opacity:0}
html.field-ready .memline.in .ml-mark,
html.field-ready .memline.in .ml-hand-lab{opacity:1;transition:opacity .5s var(--e-fast) 1.05s}
html.field-ready .memline .ml-mk{opacity:0;transform:translate(-50%,-50%) scale(.8)}
html.field-ready .memline.in .ml-mk{opacity:1;transform:translate(-50%,-50%) scale(1);
  transition:opacity .45s var(--e-fast) 1.95s,transform .5s var(--e-out) 1.95s}
@media(max-width:880px){
  .ml-foot{flex-direction:column;gap:14px;align-items:flex-start}
  .ml-note{margin-left:0}
  .ml-mk{width:24px;height:24px;border-radius:7px}
}
@media(prefers-reduced-motion:reduce){
  html.field-ready .memline .ml-curve{stroke-dashoffset:0}
  html.field-ready .memline .ml-area,html.field-ready .memline .ml-hand{opacity:1;transition:none}
  html.field-ready .memline .ml-mk{opacity:1;transform:translate(-50%,-50%);transition:none}
}

/* the product name reads as a name */
.vecn{color:var(--accent)}
.night .vecn{color:var(--clay-lit)}

/* the chart states the compounding; the bridge says what it changes; the two
   plates below say who it changes it for */
.ml-bridge{display:block;
  gap:clamp(18px,3vw,52px);align-items:baseline;
  margin-top:clamp(28px,3.2vw,44px);padding-top:clamp(20px,2.2vw,28px);
  border-top:var(--hair) solid var(--line)}
.ml-bridge .k{font-family:var(--mono);font-size:var(--mono-m1-size);font-weight:var(--mono-m1-weight);
  letter-spacing:var(--mono-m1-track);text-transform:uppercase;color:var(--mute);white-space:nowrap}
.ml-bridge p{margin:0;max-width:none;font-size:clamp(19px,1.7vw,24px);font-weight:560;
  letter-spacing:-.018em;line-height:1.32;color:var(--ink)}
.mg2-inherit{margin-top:clamp(16px,1.8vw,24px);padding-top:0;border-top:0;
  gap:clamp(14px,1.5vw,20px)}
.mg2-inherit>div{padding:18px 20px 20px;border-radius:var(--r-2);background:var(--bg-1);
  border:var(--hair) solid var(--line);box-shadow:var(--lift-sm)}
@media(max-width:760px){
  .ml-bridge{grid-template-columns:1fr;gap:10px}
}

/* ── the held run, unstacked ────────────────────────────────────────────────
   On a phone the pin is meaningless and only the active film is on screen, so
   the run becomes a linear chapter list: label, claim, lead, film. Each film
   loads and plays only while it is in view. */


.hflow{position:relative;margin-top:16px;border-radius:var(--r-2);overflow:hidden;
  border:var(--hair) solid var(--line);background:#F6F7F9;aspect-ratio:1380/672;
  box-shadow:var(--lift-sm)}
.night .hflow{border-color:rgba(255,255,255,.12);background:#0C0E11}
.hflow video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:1;display:block}

/* ── the held run on a phone: one chapter per card, swiped ──────────────────
   Three passes to get here. The linear list solved reachability by putting all
   four chapters on the page at once: four portrait films in a column, four
   files fetched to show one. The scrolling tab strip that replaced it fixed
   the fetching and broke three other things on a real phone -- the tabs did
   not read as controls, nothing announced that the strip ran off the right
   edge, and the film sat a screen below the control that changed it, so every
   chapter change was a round trip down and back up.

   A chapter is a CARD now. Film and claim live in the same box and travel
   together, so the control and the thing it controls are never a screen apart
   -- measured at 390x640, the whole film is on screen with the picker still
   in view (it was 72-79 per cent under the strip). Four passes in, the card
   carries the graphic and one line of caption: the kicker repeated the
   chapter name that the film's own header and the picker label both already
   print, and the body paragraph put a dense block of prose under a figure
   that is dense reading on its own. Both come off the phone. The desktop path
   still renders every word.

   The control sits UNDER the figure it drives, at the foot of the card, in
   the thumb's reach -- where Apple puts a page control and where the eye
   arrives after the graphic. The four abbreviated labels are the whole
   position story: which chapter (mark filled, mark widened, label darkened)
   and how many there are (four marks). The 2px scroll rule that used to run
   beneath them was a second readout of exactly that state, so it is gone.

   What advertises the swipe is the peek, not the marks: a half-visible next
   card is the one carousel cue with both usability research (NN/g's illusion
   of continuity) and a platform spec behind it (Material 3 sizes its small
   item 40-56dp), while dots are documented as weak signifiers and weaker
   controls. The peek is held at 40px on every phone width for that reason.

   Written against the class, not a width, so a rotation past 960 cannot bring
   the pinned stepper back under a script that is no longer driving it. */


/* the control belongs to the card, so it sits closer to it than the section
   claim does: 16px under the card (12 + the track's own 4 of bottom pad)
   against 24 under the claim. Written at three classes so a reorder in this
   file cannot flip it back. */


/* the held column is a .frame nested inside a .frame. The pinned desktop
   layout wants that second gutter; a phone does not, and it cost twice. The
   section's claim sat 40px in while every other section on the page starts at
   20, and the track -- which cancels ONE gutter to bleed -- was left inset by
   the other, so the neighbouring cards stopped 20px short of the screen on
   both sides and the active card paid for the margin it could not use.
   Zeroing it here aligns the claim with the rest of the page and leaves the
   track exactly one gutter to cancel, which is what its margin already does.
   Worth 40px of card at 390 and 40px at 320. */

/* the original desktop tablist and the stacked stage are removed by the
   script on this path; the hhead is left empty and must not hold space */


/* ── the picker ─────────────────────────────────────────────────────────────
   A row of marks with their names under them. The mark carries the carousel
   reading and the name carries the scent, which is why they are one control
   and not two rows: a labelled strip already encodes both variables a page
   control carries -- which one, and how many -- so a second row of dots under
   it would repeat the scroll rule's mistake in a different shape.

   The segmented box that used to hold this is gone. It read as a form control
   sitting on the page rather than as chrome belonging to the figure, and at
   320 its own content overran it: 273px of segments in a 240px box, so the
   active chip hung past the container's right edge.

   Equal segments cannot hold PRODUCTIVITY inside their own column: at the M2
   floor (9.5px / .12em) the word measures 82px and an even quarter of a 390
   phone is 75. That used to be answered with minmax(max-content,1fr), which
   gave the long label the width it asked for and split what was left between
   the other three -- correct for a SEGMENTED control, where a label crossing
   its segment's edge would be visible. The segments are gone; these are bare
   labels on the page, and the cost of that rule was paid by the marks: an
   unequal column is an unequal mark pitch, and at 320 the four marks sat
   65.97 / 65.97 / 77.86 apart. Marks that are meant to read as one run of
   steps cannot be unevenly spaced.

   So the columns are even (minmax(0,1fr)) and the one long label is allowed
   to overhang its column into the gap, which is empty. Measured at the floor
   -- 320, home, the widest pair: RISK and PRODUCTIVITY need 54.7px of pitch
   between their centres and have 64.6, so 9.9px of clear air remains, and
   PRODUCTIVITY's overhang stops 22px short of the screen edge. Every mark is
   now exactly one pitch from the next at every width.

   ── the inset ──
   Full width put the outer marks against the page gutters, which reads as
   four separate items rather than one connected run. The row is pulled in
   from both edges so the group holds together. It stays proportional (4.6vw)
   and capped, and it is spent on the GAPS, not the targets: the buttons are
   still 56.9px wide at 320 and 71.5 at 390, well clear of the 44px floor. */
.hctl{display:block}
.hpick{display:grid;grid-template-columns:repeat(var(--hn,4),minmax(0,1fr));
  gap:clamp(6px,2.4vw,14px);padding-inline:clamp(8px,4.6vw,22px)}
/* 44px tall and a full grid column wide: the mark is a few px of paint inside
   a target that clears the AAA floor on both axes, which is the whole reason a
   mark-sized control is allowed to be mark-sized */
.hpick button{position:relative;min-width:0;min-height:44px;padding:0;
  display:grid;grid-auto-rows:min-content;align-content:center;justify-items:center;
  gap:9px;background:transparent;
  font-family:var(--mono);font-size:var(--mono-m2-size);
  letter-spacing:var(--mono-m2-track);font-weight:var(--mono-m2-weight);
  text-transform:uppercase;color:var(--mute);white-space:nowrap;
  transition:color var(--m-2) var(--e-fast)}
/* the mark: a short rest pill that stretches into a clay bar when its chapter
   is the live one. One shape at two lengths -- 12x7 at rest, 26x7 live -- so
   the row reads as one family of steps rather than as three dots and a bar.
   The rest mark was a 7px circle, which was a different shape from the state
   it was announcing and, at 7px square, too little paint to find at arm's
   length; 12 gives it the same silhouette as the live mark and nearly twice
   the area, which is what makes the row legible as a run before it is legible
   as a position. Solid, not a hairline ring -- at this height a ring is two
   0.5px arcs and a hole, a shape that disappears at arm's length.

   Three channels still separate the live mark, which is the point: it is
   2.2x the width, it is the only clay object in the row, and its label is the
   only one set in --ink. Width alone was carrying 3.1x before and can afford
   the trade; hue and ink are the two a thumb resolves first anyway.

   The rest pill is --faint, one step lighter than the --mute its own label is
   set in, so mark and name read as one object at one weight. It was --line-2
   (6 per cent ink), which is a hairline token doing a mark's job: 1.1:1 on
   this ground, invisible at arm's length. --faint is the page's own
   3:1-or-better step and is themed, so night follows without an override. */
.hpick button::before{content:"";display:block;width:12px;height:7px;
  border-radius:99px;background:var(--faint);
  transition:width var(--m-2) var(--e-out),background var(--m-2) var(--e-fast)}
.hpick button[aria-current="true"]{color:var(--ink)}
.hpick button[aria-current="true"]::before{width:26px;background:var(--accent)}
.hpick button:hover{color:var(--ink)}
.hpick button:hover::before{background:var(--mute)}
.hpick button[aria-current="true"]:hover::before{background:var(--accent)}
.hpick button:focus-visible{outline:2px solid var(--accent);outline-offset:1px;
  border-radius:var(--r-1)}

/* ── the track ──────────────────────────────────────────────────────────────
   Full-bleed so a card can peek past the screen edge and so the portrait cut
   keeps every pixel it can get -- its labels are 11px inside the film.
   100% inside a padded scroller is the CONTENT box, so the card width is
   content + pad - peek, not content - pad - peek.

   --peek is not what you see: the track's own right pad and the column gap
   also sit in that band, so 38 showed a 28px sliver. 50 lands the visible
   next card on 40px at 390 AND at 320 (the gutter and the pad both scale
   with it), which is the floor of Material 3's 40-56dp small item. */
.hcards{--peek:50px;
  display:grid;grid-auto-flow:column;
  /* capped so a tablet does not get a 1200px-tall portrait film: past ~460
     the extra width buys nothing the 39/58 cut can use, and a second card
     coming into view reads better than one enormous one */
  grid-auto-columns:min(calc(100% + var(--gut) - var(--peek)),460px);
  gap:10px;
  margin-inline:calc(var(--gut) * -1);
  padding:2px var(--gut) 4px;
  /* the snapport is inset by the page gutter on BOTH sides now. It was start
     only, which put the snapport's centre 10px right of the screen's, so a
     centred card could not come out even; symmetric padding is what makes the
     middle cards' two peeks equal, and it leaves the first and last cards
     exactly where they already rested (the end inset and the track's own
     right pad are the same 20). */
  scroll-padding-inline:var(--gut);
  overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;overscroll-behavior-inline:contain;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;-ms-overflow-style:none}
.hcards::-webkit-scrollbar{display:none;width:0;height:0}
.hcards:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-3)}

/* ── where each card rests ──────────────────────────────────────────────────
   Alignment is per item, because one rule cannot serve three positions. Every
   card snapping to `start` bought the first card its correct rest -- left edge
   on the page gutter, aligned to the section headline above it -- and then
   forced that same rest on every other card, so a middle card showed 10px of
   the card behind it and 40px of the card ahead: a lopsided frame that reads
   as a mistake rather than as a peek, and points the wrong way about which
   direction has more to see.

   First card keeps `start` (the headline alignment is the point of it). Last
   card takes `end`, which is where the scroll already clamped it, so it is now
   stated rather than incidental. The cards between take `center`: with the
   snapport inset evenly (above), a centred card sits 35px off each edge, and
   with the 10px column gap inside that band both neighbours show 25px. Even,
   and symmetric at every width, because the card is always the viewport less
   70 (gutter + peek). */
.hcard{scroll-snap-align:center;min-width:0;display:flex;flex-direction:column;
  border:var(--hair) solid var(--line);border-radius:var(--r-3);
  background:var(--bg-1);overflow:hidden;box-shadow:var(--lift-sm)}
.hcard:first-child{scroll-snap-align:start}
.hcard:last-child{scroll-snap-align:end}
/* NOT .foot: field.css owns .foot for the page footer (night ground, night
   ink), and a card foot picked it up and rendered black inside a day card */
.hcard .hc-pad.hc-foot{padding:15px 16px 18px}
/* the claim captions the film it sits under, so it steps down from the
   section claim above the figure and reads as one short block, not a heading */
.held-swipe .hcard .hclaim{margin-top:0;font-size:19px;line-height:1.24;
  letter-spacing:-.02em;max-width:none}
/* the film opens the card: the card's own rounded border draws the top edge,
   so a second hairline there would double it */
.hc-film{position:relative;aspect-ratio:39/58;background:var(--bg-2);
  border-bottom:var(--hair) solid var(--line)}
.hc-film video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  display:block;opacity:1;background:var(--bg-2)}

@media(prefers-reduced-motion:reduce){
  .hcards{scroll-behavior:auto}
  .hpick button,.hpick button::before{transition:none}
}

/* the clay band went from three elements to two, so the body steps up: it is
   now the only copy under the claim and has to carry that weight */
.te-copy>.te-ab:only-child{font-size:clamp(16px,1.45vw,20px);line-height:1.55;
  max-width:52ch;margin-inline:auto;color:rgba(255,247,244,.88)}

/* ══ THE CLAY RULE ══════════════════════════════════════════════════════════
   Audited across seven pages: 110 clay mono labels in 40 places, doing five
   different jobs. A colour that means five things means nothing, and the
   distribution proved it -- five clay labels in one screen on the trust band,
   sixteen in the article, none on the figure with a two-sided argument to mark.

   In a drafting system colour on an annotation encodes STATE, not hierarchy.
   Hierarchy is what tier, weight and position are for. So:

     clay  = identity, state, index, position, and callout numerals
     ink   = the title of a card or figure (structure, but load-bearing)
     mute  = subordinate meta inside a figure

   Demoted labels go to INK, not mute: they are card titles and must keep their
   presence. They lose the accent, not their weight.

   ── AMENDMENT, 2026-08-16, after reviewing the demotion in place ───────────
   The rule above holds where a label sits among siblings: the home trust band
   puts four card titles in one screen, and four clay marks there is the noise
   the audit was called to fix. It over-reached on a second shape.

   Where a mono label is the ONLY label in its block and titles a single
   key/value or label/body pair, it takes CLAY. At ink weight an uppercase mono
   label reads as a heading competing with the sentence beneath it, which is the
   one thing it is not; in clay it reads as a marker on the pair, which is what
   it is. The distinguishing test is siblings, not importance:

     one label, one block, no siblings  -> clay   (.stack .sk .k, .ck2, .mg2 .k)
     several labels sharing one screen  -> ink    (.tcard .th)

   Sans titles are unaffected. This is about mono labels only. */

/* ── demote: card titles that appear several to a screen ─────────────────── */
.tcard .th{color:var(--ink)}
.night .tcard .th{color:var(--night-ink)}
/* ── promote: the sole mono label titling its own pair (see amendment) ────── */
.stack .sk .k,.mg2-inherit .k,.mgw-inherit .k,.card .ck2{color:var(--accent)}
.night .stack .sk .k,.night .card .ck2,
.band.night .stack .sk .k,.band.night .card .ck2,
.band.night .mg2-inherit .k,.band.night .mgw-inherit .k{color:var(--clay-lit)}
/* ── demote: subordinate meta, genuinely secondary ───────────────────────── */
.alt .wlab,.pplate .rows .r .k{color:var(--mute)}

/* ── promote: one clay label per figure, at its top ──────────────────────── */
.io-col .h{color:var(--accent)}
.chapk{color:var(--accent)}
.chapk b{color:var(--accent)}
.lf-lbl .l{color:var(--accent)}

/* ── the executive questions keep the accent and lose the italic: the voice
      is carried by the quotation and the colour, not by a slant ──────────── */
#kinds .card p em,#kinds .card .q,.kinds .q{font-style:normal}

/* ══ MOBILE COMPOSITION ═════════════════════════════════════════════════════
   Appended at the end of the cascade on purpose. This file carries ~10.5KB of
   duplicated .te-* rules (92 selectors appear more than once), so a rule placed
   mid-file can be silently overridden by its own later copy. Everything here is
   phone composition, not scaled-down desktop.
   ========================================================================== */
@media(max-width:860px){
  /* The embedded figure was right-aligned by .te-cut{margin-left:auto}, which
     is correct in the two-column desktop grid and shoves it 36px off centre in
     the single-column phone stack. Centre the block instead. */
  .te-cut{margin-inline:auto}

  /* The chain cards spent a whole line on a bare index. Fold the number into
     the eyebrow so each card loses a line and the three read as one ladder. */
  .cpanel{display:grid;grid-template-columns:auto minmax(0,1fr);
    grid-template-areas:"n k" "h h" "m m";align-items:baseline;
    column-gap:9px;row-gap:0}
  .chain .cn{grid-area:n;margin-bottom:0;color:var(--accent)}
  .cpanel.mid .cn{color:#C68070}
  .chain .cn::after{content:"·";margin-left:9px;opacity:.55}
  .chain .ck{grid-area:k;margin-bottom:12px}
  .cpanel h3{grid-area:h;flex:none}
  .chain .cm{grid-area:m}
  /* ── The chapter films ────────────────────────────────────────────────
     Full-bleed only. The scenes are authored on a 1600x780 canvas and every
     one of them is a SIDE-BY-SIDE PAIR spanning ~91% of that width: the RFI
     log beside the schedule, the change-order log beside the drawing register,
     the clause beside the notice window. The pair is the argument. A zoom-and
     -crop made the type legible and cut one panel off, which reads as a
     product screenshot with a bug rather than a comparison.

     Full-bleed buys the 40px of frame padding back. It does not make an 11px
     mono label readable at a 24% scale, and no CSS here can: these need
     portrait scene variants where the two panels stack. Tracked separately.
     Do not reintroduce a transform zoom on these. */
  .held-flow .hflow{margin-inline:calc(var(--gut) * -1);border-radius:0;
    border-left:0;border-right:0}

  /* Small inline controls need a thumb-sized target on a phone. The bare
     button takes padding, which suits it: no border, so growing the box shows
     nothing.

     The citation chip cannot. `.cpane .cite` sets a `padding` SHORTHAND at two
     classes of specificity, so the one-class `.cite{padding-block}` that stood
     here never applied -- it measured 31x17 with zero block padding the whole
     time it was supposed to be fixing that. And the chip carries a border and
     a fill, so padding would have grown something the reader can see.

     The target is grown instead of the chip: a transparent 44px overlay,
     centred on the mark, taking the press on its behalf. The chip renders
     identically and a thumb gets the whole square. */
  .cite{position:relative}
  .cite::after{content:"";position:absolute;left:50%;top:50%;
    transform:translate(-50%,-50%);width:44px;height:44px}
  .btn.bare{padding-block:8px}
}

/* ══ STACK ROWS, PHONE ORDER ════════════════════════════════════════════════
   Stacked, the row read: label, claim, then the logos the claim is about. The
   claim is the conclusion, so it belongs after its evidence. .sk goes to
   display:contents so its two children become grid items alongside .sv and can
   be ordered: label, logos, claim.
   ========================================================================== */
@media(max-width:820px){
  .stack .sk{display:contents}
  .stack .sk .k{order:1;padding:26px 28px 12px}
  .stack .sv{order:2;padding:0 28px}
  /* the claim needs air from the logos it follows, and at 580 weight it read
     as another row of marks rather than the sentence about them */
  .stack .sk .v{order:3;padding:22px 28px 26px}
  .stack .sk .v b{font-weight:400;color:var(--mute)}
  .stack .srow+.srow .k{border-top:var(--hair) solid var(--line-2);padding-top:26px}
}

/* ══ FI LEDGER + TRACE, PHONE ═══════════════════════════════════════════════
   The big number sat hard against the top-left of a wide empty plate: one
   figure in a large container reads better centred, with room around it. The
   traced steps lost their inline padding when .lf-rows dropped its own, so the
   cards ran to the container edge.
   ========================================================================== */
@media(max-width:820px){
  .lf-big{align-items:center;text-align:center;padding:clamp(20px,5vw,28px) clamp(16px,4vw,22px)}
  .lf-big>span{max-width:26ch;margin-inline:auto}
  .lf-big::after{display:none}
  .lf-rows{padding-left:clamp(16px,4vw,22px);padding-right:clamp(16px,4vw,22px)}
}
@media(max-width:720px){
  /* the trace stacks; restore the inline padding the grid used to supply */
  .trace{grid-template-columns:1fr;row-gap:12px}
  .tstep{grid-row:auto;grid-template-rows:auto;padding:16px 18px 15px}
  .tstep:not(:first-child)::after{right:auto;left:50%;top:auto;bottom:calc(100% + 1px);
    transform:translateX(-50%) rotate(90deg)}
}

/* ══ FI IN AND OUT, PHONE ═══════════════════════════════════════════════════
   Eight full-width rows plus a hub sprawled to nearly three screens. Two up
   holds the same content in half the height and keeps the in-set and out-set
   legible as sets rather than a list. The wires are a desktop device; stacked,
   an arrow between the three groups carries the same flow.

   Above that, one squeeze band: between 881 and 930 the three-column wire
   layout is still on but the sheet body is down to 112px, which is less than
   "Recreational" plus the gap plus the completion figure, so the percentage was
   pushed 9px out of its row and lost its flush right edge. The icon rail and
   the body inset give the row back the 30px it needs. It has to sit ahead of
   the 880 block, which stacks the rail away entirely.
   ========================================================================== */
@media(max-width:940px){
  .io-sheet{grid-template-columns:58px minmax(0,1fr)}
  .io-sheet .gl svg{width:42px;height:38px}
  .io-sheet .bd{padding-left:12px;padding-right:12px}
}
@media(max-width:880px){
  .io-col{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;align-content:start}
  .io-col .h{grid-column:1/-1}
  /* half width cannot hold an 80px icon rail beside the text: stack it */
  .io-sheet{grid-template-columns:1fr;gap:0}
  .io-sheet .gl{padding:14px 14px 0}
  .io-sheet .gl svg{width:38px;height:34px}
  .io-sheet .bd{padding:8px 14px 14px}
  .io-item.out{height:100%}
  /* the hub is centred content, so it does not need the full measure: inset it
     and it reads as a plate the flow passes through rather than a band */
  .io-hub{margin-inline:clamp(22px,9vw,44px)}

  /* the flow, drawn where the wires used to be */
  /* both arrows sit between the groups, not inside them: the second was
     rendering within the hub plate and read as a control on the card */
  .io-col.in::after,.io-col.out::before{
    content:"";display:block;grid-column:1/-1;justify-self:center;
    width:9px;height:9px;margin:14px 0 2px;
    border-right:1.6px solid var(--accent);border-bottom:1.6px solid var(--accent);
    transform:rotate(45deg)}
  .io-col.out::before{margin:2px 0 14px}
}
@media(max-width:520px){
  .io-sheet .gl svg{width:34px;height:30px}
}

/* ══ PORTRAIT SCENE VARIANTS ════════════════════════════════════════════════
   The chapter films now have portrait cuts (assets/loops/*-m.mp4, 1560x2320)
   where the side-by-side pairs stack instead of shrinking. The page picks them
   with a media-scoped <source>, so a phone never fetches the landscape file.

   The box has to change shape with the source or object-fit:cover crops the
   stacked panels straight back off. 39/58 is the authored ratio.
   ========================================================================== */
@media(max-width:960px){
  .held-flow .hflow{aspect-ratio:39/58}
  /* the landscape poster would letterbox inside a portrait box */
  .held-flow .hflow video{object-fit:cover}
}

/* ══ PI EXHIBITS, PHONE ═════════════════════════════════════════════════════
   This MUST use the same breakpoint field.js uses to choose the source (960).
   It previously sat inside the 860 query while the script switched at 960, so
   between 861 and 960 the portrait file played inside a 16/9 box with
   object-fit:cover and had its sides cropped away. One decision, one number.

   The phone framing is BAKED INTO THE ASSET: assets/walkthrough/*-m.mp4 are
   portrait exhibit films, reframed and re-edited for this box. Nothing here
   transforms the picture. A runtime crop used to and could not: the recording
   moves its own content, so a second camera on top either lagged it, fought
   it, or double-cropped a shot that had already pushed in. Do not reintroduce
   a transform on these.

   THE RATIO BELOW IS THE ASSET'S OWN. object-fit:cover fills this box, so a
   ratio that disagrees with the film silently crops it, and what it crops
   first is the top and bottom -- where these films caption every beat. It read
   780/844 for the cut that shipped at 780x844; the current portrait films are
   1120x1802, which is much taller, and leaving the old ratio would have taken
   the caption cards off the bottom of every shot. Re-measure it whenever the
   films are recut: `ffprobe -show_entries stream=width,height`.
   ========================================================================== */
@media(max-width:960px){
  .exhibit.wide .ex-stage .port,.ex-stage .port{aspect-ratio:1120/1802}
  .ex-stage .port video,.ex-stage .port img{transform:none;transition:none}
}

/* ══ MEMORY LINE, PHONE ═════════════════════════════════════════════════════
   This block used to restate the figure's labels at 26, 28 and 23 user units,
   because they were SVG <text> inside viewBox="0 0 1200 360" and a phone's 29%
   scale delivered them at roughly 3px. That was a compensation for where the
   text lived, not a decision about how big it should be, and it had to be kept
   in step with the viewBox by hand.

   The labels are HTML now and size themselves in CSS pixels like everything
   else on the page, so the compensation is not merely unnecessary -- left in
   place it rendered a 26px axis label on a 350px-wide plot. Removed with the
   cause. The phone's plot height is set alongside the other .ml- rules.
   ========================================================================== */

/* ══ CONTRAST CLOSE-OUT ═════════════════════════════════════════════════════
   Appended at the end because this file duplicates rules: editing the first
   copy of .lrow.dim or .io-sheet .mt is silently undone by the later one.

   Two causes, one principle. --faint is the MARK tier and measures 3.2:1 on a
   day plate; anything carrying text belongs on --mute at 5.6:1. And opacity is
   contrast: .4 on a mute row lands near 2.4:1.
   ========================================================================== */
.lrow.dim{opacity:.89}

/* ══ TAP THE FILM ═══════════════════════════════════════════════════════════
   The control is the frame. A transparent button fills the film, so the target
   is the whole picture at every width and there is no chrome to place, no bar
   to fade, no scrubber to mis-hit. The only paint it adds is one centred mark.

   THREE STATES, THREE AMOUNTS OF PAINT.
   Running, pointer away: nothing. A persistent badge over a product recording
   covers the thing the recording exists to show, and it would sit there for
   the whole minute the film runs.
   Running, hovered or focused: the stop mark at .5, which is the disclosure --
   on a pointer, the frame gives no other sign that it is a control, and a mark
   that only appears once you have already pressed is a mark that arrives late.
   Held: the go mark, solid, ringed in clay. Held is the state that has to read
   from across a room and has to survive whatever frame it landed on.

   THE DISC is near-black at .58 with a blurred backdrop, not a clay plate. The
   mark lands on an arbitrary video frame -- a white register table, a dark
   drawing, a photograph -- and a translucent brand-coloured plate reads
   differently on each. A dark disc with a paper-white glyph reads the same on
   all of them, which is what a state indicator has to do. Clay enters as the
   RING, the one channel that is unambiguously ours and does not have to carry
   legibility on its own.

   MULTI-CHANNEL, as the rail chips are: held changes the glyph (bars to
   triangle), the ring (hairline paper to clay), and the opacity (.5 to 1).
   Shape, hue and weight, so the state survives greyscale and survives a busy
   frame under it.

   The disc is 60px inside a target that is the whole film, so the 44px floor
   is met by the button and the mark is free to be mark-sized.
   ========================================================================== */
.filmtap{position:absolute;inset:0;z-index:2;width:100%;height:100%;
  margin:0;padding:0;border:0;background:transparent;cursor:pointer;
  display:grid;place-items:center;-webkit-tap-highlight-color:transparent;
  color:inherit;font:inherit}
/* The mark sits in the bottom-right corner, 14px in -- the same seat the
   .loop films give their control -- not over the middle of the picture. A
   reader hovers a film to read it; a disc over the register table it is
   showing is the one place the control must not be. 44px keeps a finger
   target even though the whole film is the button. */
.filmtap .ft-mark{position:absolute;right:14px;bottom:14px;
  display:grid;place-items:center;width:44px;height:44px;
  border-radius:50%;background:rgba(10,11,13,.78);
  border:1px solid rgba(242,241,237,.16);
  box-shadow:0 2px 12px rgba(8,9,11,.26);
  -webkit-backdrop-filter:blur(3px) saturate(.9);backdrop-filter:blur(3px) saturate(.9);
  opacity:0;transform:scale(.92);
  transition:opacity var(--m-2) var(--e-fast),transform var(--m-3) var(--e-out),
             border-color var(--m-2) var(--e-fast)}
.filmtap .ft-mark svg{width:20px;height:20px;fill:#F2F1ED;stroke:none;display:block}
/* the go mark's mass sits left of its own box, so it is nudged onto the
   optical centre of the disc rather than the geometric one */
.filmtap .ft-go{opacity:0;transform:translateX(1.1px)}
.filmtap .ft-stop{opacity:1}
.filmtap .ft-go,.filmtap .ft-stop{transition:opacity var(--m-1) var(--e-fast)}

/* Running, and the pointer is on the film: the quiet disclosure. In the
   corner the disc covers no reading matter, so it can afford .6 -- findable
   at a glance, still a hint that the frame is a control rather than a state
   that has to survive one. */
@media(hover:hover) and (pointer:fine){
  .filmtap:hover .ft-mark{opacity:.6;transform:none}
}
/* Keyboard focus takes the page's own clay ring, inset because both frames
   clip their overflow and an outward ring would be cut off.

   The mark goes to FULL here, not to the hover .4. The ring alone rests on one
   colour against whatever the film is showing under it, and clay on a dark
   frame is a weaker separation than clay on the page's paper; a required
   indicator should not depend on which frame the film happened to stop on. The
   solid disc is the second channel, and it cannot be mistaken for the held
   state because the glyph inside it still says which way the next press goes:
   bars while it is running, triangle once it is held. Hover stays quiet, at
   .4 -- a hint and an indicator are not the same job. */
.filmtap:focus-visible{outline:2px solid var(--accent);outline-offset:-3px}
.filmtap:focus-visible .ft-mark{opacity:1;transform:none}

/* held by the viewer. The ring is clay at .6, not the solid --clay-lit it
   started as: full strength on a dark disc reads as an alert ring rather than
   as a state, and it is louder than either clay the page already uses (the
   .34 hairline on an active rail chip, the solid mark under an active picker
   label). Held is already carried by shape and by weight; the ring is the
   third channel and only has to be present. */
.is-held>.filmtap .ft-mark{opacity:1;transform:none;border-color:rgba(198,128,112,.6)}
.is-held>.filmtap .ft-go{opacity:1}
.is-held>.filmtap .ft-stop{opacity:0}
.is-held>.filmtap:hover .ft-mark,
.is-held>.filmtap:focus-visible .ft-mark{opacity:1}

@media(prefers-reduced-motion:reduce){
  .filmtap .ft-mark{transition:none;transform:none}
}


/* ══════════════════════════════════════════════════════════════════════════
   #currencies · the four outcomes
   Home and pi both run this. It replaced a pinned stepper that has since been
   deleted outright, so there is no second implementation to keep in step with
   and nothing here defers to one.
   ══════════════════════════════════════════════════════════════════════════ */
/* Scoped to the COMPONENT, not to one section id. These were written against
   #currencies while it was the only instance; pi.html runs the same component
   for its attention surfaces and was inheriting the default 1160 frame, which
   left its film at 904px on a 1920 screen -- narrower than the same film at
   1366. Anything carrying a .dwrap gets the wider frame. */
.band:has(.dwrap){padding:0}

/* ── the chapter title ────────────────────────────────────────────────────
   Outside the pin, and deliberately so. Held inside it, the section title sat
   above a card that has its own title, so every pinned screen carried two
   headings and a paragraph stacked before the film even started. It reads as a
   chapter heading now: state the section, rule off, then begin. That also
   hands the pinned screen back the ~150px it was spending on a heading that
   never changed, which is what lets the rest move up. */
/* The chapter head reads at the STANDARD frame, not the widened one. Only the
   pinned stage below earns extra width, and it earns it for the film; a title
   at 1600 sat disconnected from every other section head on the page. */
.dchapter{padding-top:clamp(64px,8vw,116px);padding-bottom:clamp(22px,2.6vw,36px);
  max-width:var(--frame)}
.dchapter .stage-head{margin:0}
.dchapter-rule{height:var(--hair);background:var(--line);
  max-width:calc(min(var(--frame),100%) - var(--gut) * 2);margin:0 auto clamp(10px,1.4vw,20px)}

/* ── scroll length ────────────────────────────────────────────────────────
   68svh per card. The first pass ran 80svh, which is most of a screen of wheel
   per step and read as stuck; 62 overcorrected and the cards flipped faster
   than they could be read. 68 is the settled figure, roughly six wheel notches.
   One number, and the section's height follows from the count, so both
   instances -- four outcomes on home, three surfaces on pi -- move together. */
.dwrap{--dstep:68svh;--dcount:4;position:relative;height:calc(100svh + (var(--dstep) * var(--dcount)))}
.dpin{position:sticky;top:0;height:100svh;display:flex;align-items:center;overflow:hidden}
.dpin .frame{width:100%;max-width:min(1600px,calc(100vw - 48px))}

/* ── the grid ─────────────────────────────────────────────────────────────
   The heading sits in the CONTENT column, not across the top. Spanning it
   left-aligned it to the rail while the paragraph beneath started 250px
   further right, so the title did not agree with the text it introduced.
   Each column now owns its own left edge: the rail has a label, the content
   has the heading, and everything inside a column lines up with itself. */
.dgrid{
  display:grid;
  grid-template-columns:minmax(0,198px) minmax(0,1fr);
  gap:0 clamp(30px,3.4vw,58px);
  align-items:start;
}
.drail{grid-column:1;align-self:stretch}
.dbody{grid-column:2;min-width:0}

@media(max-width:1400px){
  .dgrid{grid-template-columns:minmax(0,182px) minmax(0,1fr);gap:0 clamp(22px,2.4vw,34px)}
}

/* ── the rail ─────────────────────────────────────────────────────────────
   One vertical rule, on the boundary where the rail's own hairline used to
   sit. Previously there were two lines down this edge -- a border on every
   item and a border on the rail -- competing to be the thing you follow. */
.drail{position:relative;display:flex;flex-direction:column;justify-content:center;
  padding-right:clamp(18px,1.8vw,26px)}
.drail-in{width:100%}

/* No title and no counter on this rail, deliberately.
   The chapter heading directly above already names the section, so a second
   "Four outcomes" was the reader being told twice in the space of one screen.
   And position-in-the-set was being reported three ways at once: four visible
   labels, a fill whose height IS the position, and a numeric counter. The fill
   is the most precise of the three and the only one that moves, so it keeps
   the job and the other two stop competing with it. The rule under the header
   went with them -- there is nothing left above the list to rule off. */
.drail-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.drail-item{
  position:relative;display:flex;align-items:center;width:100%;text-align:left;cursor:pointer;
  background:none;padding:0 0 0 2px;
  /* equal heights, so scroll distance per card is equal and the fill's
     position maps linearly to the reader's own sense of progress. The rail is
     also simply taller than it was: a longer run is easier to follow. */
  min-height:clamp(54px,6.4vh,70px);
}
/* The idle label steps back further than --mute took it: at rgb(101,99,95)
   against a near-black active state the two read as similar weights of the
   same thing rather than as read and unread. */
/* The idle label cannot go lighter than this. At rgba(25,24,23,.42) it sat at
   2.66:1 on the day band, well under the 4.5:1 floor, and axe failed it as a
   serious contrast defect on desktop, mobile and at 320. .62 is 4.83:1, the
   first step with real margin over the floor.

   So the separation between read and unread is carried by WEIGHT, not by
   lightness: 4.83:1 against the active state's 16.54:1, plus 520 -> 640 and a
   tighter track. Lightness had a legal floor; weight does not. */
/* --mute, the system's own mid-tone, at 5.59:1 on the day band. An earlier
   pass hand-rolled this to rgba(25,24,23,.42) chasing more separation from the
   active state, which put it at 2.66:1 and failed the 4.5:1 floor outright.
   The active state is already var(--ink) at 16.54:1 and cannot go darker, so
   the distance between read and unread is carried by weight -- 520 against
   640 -- and not by draining the idle label. */
.drail-item .dr-t{
  display:block;font-size:var(--t-ui);font-weight:var(--w-mid);line-height:1.32;
  letter-spacing:-.011em;color:var(--mute);
  transition:color 200ms var(--e-fast),font-weight 200ms var(--e-fast);
}
.drail-item:hover .dr-t{color:var(--ink)}
.drail-item.on .dr-t{color:var(--ink);font-weight:640;letter-spacing:-.017em}
/* the card about to arrive warms as the fill nears its notch: the change is
   announced before it happens, so nobody overshoots looking for it */
.drail-item.warm .dr-t{color:rgba(25,24,23,.80)}
.drail-item:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:3px}

/* ── the spine ────────────────────────────────────────────────────────────
   Runs the height of the list. The fill's leading edge is the playhead, and
   the notches are the switch points, so the distance between the two is
   literally how much further to scroll. */
/* 3px, not 2. The ticks are 2px deep and 14px wide, so at 2px the travelling
   line -- the thing the eye is actually meant to follow -- read thinner than
   the marks it passes. The track it runs in matches, so the fill sits in a
   groove rather than beside one. */
.dspine{position:absolute;right:0;top:0;bottom:0;width:3px;background:var(--line-2);
  border-radius:3px;overflow:visible}
.dspine-fill{position:absolute;left:0;top:0;width:100%;height:0;background:var(--accent);
  border-radius:3px}
/* A hairline in --line on a near-white ground is invisible at the exact moment
   it matters most, which is while the reader is deciding whether to keep
   scrolling. Ink, 2px, and wider than the spine so it reads as a mark ON the
   track rather than a flaw in it. Clay once passed. */
.dspine-notch{position:absolute;right:-5px;width:15px;height:2px;border-radius:1px;
  transform:translateY(-50%);
  background:rgba(25,24,23,.62);transition:background 200ms var(--e-fast)}
.dspine-notch.passed{background:var(--accent)}

/* ── the cards ────────────────────────────────────────────────────────────
   Discrete, on their own clock, and asymmetric on purpose: the outgoing card
   leaves faster than the incoming arrives, so the overlap is a blink rather
   than a state you can sit in. */
/* Height is measured from the tallest card and written by JS, not guessed at
   with a clamp. The cards are absolutely positioned so they can cross, which
   means they do not push this box open: a guess that came up 14px short simply
   let the film slide over the last line of the longest paragraph. */
.dcopy{position:relative;min-height:clamp(148px,15vh,192px)}
.dpair{
  position:absolute;inset:0;opacity:0;transform:translateY(9px);pointer-events:none;
  transition:opacity 130ms var(--e-fast),transform 130ms var(--e-fast);
}
.dpair.on{
  opacity:1;transform:none;pointer-events:auto;
  transition:opacity 240ms var(--e-out) 90ms,transform 300ms var(--e-out) 90ms;
}
/* Claim beside lead rather than stacked. Stacked, the two of them ran five or
   six lines deep and the film paid for every one of them; side by side they
   run three, and the picture gets the difference. Mirrors .stage-head.split,
   which is the pattern this site already uses for a title and its lead. */
/* Bottom-aligned. The copy box is sized to the TALLEST card, so every shorter
   card was leaving its slack between itself and the film -- the text floated
   with a gap under it instead of sitting on the picture it introduces. Aligned
   to the end, the slack goes above the text where nothing notices it, and each
   card rests the same distance off the graphic whatever its length. */
.dpair{display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);
  gap:0 clamp(24px,2.6vw,44px);align-content:end}
.dpair .hclaim{margin:0;max-width:22ch}
.dpair .hlead{margin:0;max-width:46ch}

/* The whole composition has to fit one pinned screen: heading, card, film.
   At 1366x768 -- an ordinary laptop -- it needed 773px of 768 and the film ran
   off the bottom. Bounding the film by the height left over after the text is
   the same technique the film stages on this site use, and it means the
   section can never need more room than it has. */
.dstage{
  --dchrome:clamp(212px,25vh,296px);
  position:relative;width:100%;
  /* Deliberate, and now constant. Bottom-aligning the card took the gap to
     exactly 0 -- the text sat on the film's edge -- because the slack that
     used to separate them was the leftover space above a short card, which is
     precisely what bottom-aligning removed. Stated here instead, so every card
     stands the same distance off the picture. */
  margin-top:clamp(18px,2vw,30px);
  max-width:calc((100svh - var(--dchrome)) * 2.0513);
  margin-right:auto;
  aspect-ratio:1600/780;
  border-radius:var(--r-3);overflow:hidden;
  border:var(--hair) solid var(--line);
  background:var(--bg-2);
  box-shadow:var(--lift-sm);
}
.dstage video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  opacity:0;transform:scale(1.016);
  transition:opacity 150ms var(--e-fast),transform 150ms var(--e-fast);
}
.dstage video.on{
  opacity:1;transform:none;
  transition:opacity 260ms var(--e-out) 80ms,transform 420ms var(--e-out) 80ms;
}

/* ── narrow: no pin ───────────────────────────────────────────────────────── */
/* -- the phone hands over to the cards -------------------------------------
   Written against the class the script adds, not against a width. That is the
   same rule the old stepper set for itself, and for the same reason: a
   rotation past the breakpoint must not bring a pinned layout back under a
   script that is no longer driving it. The card styles themselves -- .hcards,
   .hcard, .hc-film, .hpick and their peek and snap tuning -- are the ones that
   were already here, reused rather than reinvented. */
/* The SHAPE is a width question and belongs to the stylesheet; only the cards
   themselves wait for the script.

   Hung entirely off the class the script adds, the section was laid out for
   desktop when the page first painted and rearranged a moment later: a 216px
   block collapsed to nothing after the reader already had a settled page. That
   is the whole of home's 0.286 layout-shift score. Stated as a media query it
   is true from the first paint, so there is nothing to undo.

   The script still adds .held-swipe, and the rules that depend on the cards
   existing still hang off it -- a margin between a track and a control that are
   not there yet has nothing to sit between. */
@media(max-width:960px){
  .dwrap{height:auto}
  .dwrap .dpin{position:static;height:auto;overflow:visible;display:block}
  .dwrap .dgrid{display:none}
}
.dwrap.held-swipe .hctl{margin-top:12px}
/* The track spans the viewport, not the frame it happens to sit in.
   .hcards sizes its cards off its own content box -- min(100% + gut - peek,
   460px) -- so anything narrower than the full width shrinks every card. Inside
   .dpin's frame it inherited both a 20px inline padding and a max-width of
   100vw - 48px, and the cards came out 272px against production's 320 at the
   same 390px screen, with the 40px peek measured off a track that was already
   48px short. Stated against the viewport it cannot drift with whatever the
   frame around it is doing. */
.dwrap.held-swipe .hcards{
  width:100vw;
  margin-inline:calc(50% - 50vw);
  padding-inline:var(--gut);
}

/* ── the in-between widths ────────────────────────────────────────────────
   The card grows with the screen until it reaches its 460px cap, which happens
   around 530px wide. Past that the card is fixed and every further pixel goes
   to the peek, so it ran 50, 80, 120, 170, 220 and finally 250 a side by 960.
   A peek is a hint that another card exists; at 250px it is a second column,
   and the card you are meant to be reading no longer holds the eye.

   Above the cap the track stops spanning the viewport and takes the width the
   card actually needs, centred on the page. The peek returns to roughly what
   it is on a phone and stays there.

   Every card centres here too, first and last included. Edge alignment earns
   its place while the card nearly fills the screen -- the first card lines up
   with the headline above it -- but once the track is a centred object in open
   space, an edge-aligned card just sits off to one side with all of its peek
   on the other. */
@media(min-width:540px) and (max-width:960px){
  .dwrap.held-swipe .hcards{
    /* The peek is the affordance -- it tells a viewer there are more cards --
       and it only speaks when it touches the actual screen edge. In this band
       the card caps at 460 while the viewport keeps growing, which broke both
       naive answers: full-bleed exposed half the next card (a second column),
       and a fixed sliver on a centred track floated mid-page with dead space
       outside it (a crop that read as an error).

       So: genuinely full-bleed, with the flanks masked. The neighbour really
       does run to the screen edge, and the mask dissolves it on the way
       there -- solid beside the card, gone at the edge. Near 540 the flank is
       ~50px and it reads like the phone's sliver; at 950 the neighbour
       reaches in ghosted and fades out. Always present, always touching the
       edge, never a competing column, no width at which it collapses. The
       mask is anchored to the card edges, so the resting card itself is
       never faded and mid-swipe cards ghost through the flanks. */
    width:100vw;
    padding-inline:calc((100vw - 460px) / 2);
    margin-inline:0;
    position:relative;
    left:50%;
    translate:-50% 0;
    /* the fade is front-loaded: a steep drop just past the card edge kills
       the second-column read, then a whisper carries the rest of the way to
       the screen edge so there is no dead zone. A plain linear fade left the
       neighbour half-solid across 200px -- still a column. */
    -webkit-mask-image:linear-gradient(to right,
      transparent 0,
      rgba(0,0,0,.26) calc((100vw - 460px) / 2 * 0.55),
      #000 calc((100vw - 460px) / 2 - 8px),
      #000 calc(100% - (100vw - 460px) / 2 + 8px),
      rgba(0,0,0,.26) calc(100% - (100vw - 460px) / 2 * 0.55),
      transparent 100%);
    mask-image:linear-gradient(to right,
      transparent 0,
      rgba(0,0,0,.26) calc((100vw - 460px) / 2 * 0.55),
      #000 calc((100vw - 460px) / 2 - 8px),
      #000 calc(100% - (100vw - 460px) / 2 + 8px),
      rgba(0,0,0,.26) calc(100% - (100vw - 460px) / 2 * 0.55),
      transparent 100%);
  }
  /* the phone's 10px gap suits a track where the neighbour is a 40px sliver;
     with real flank space around the card it reads cramped. The gap breathes
     with the same slack the flanks are built from -- a fifth of it -- so
     narrow band widths stay near the phone's rhythm and wide ones give the
     ghosted neighbour clear separation from the card being read. */
  .dwrap.held-swipe .hcards{grid-auto-columns:460px;
    gap:clamp(12px, calc((100vw - 460px) * 0.2), 56px)}
  .hcard,.hcard:first-child,.hcard:last-child{scroll-snap-align:center}
  /* the control follows the card it drives, not the full-bleed scrollport */
  .dwrap.held-swipe .hctl{max-width:460px;margin-inline:auto}
}
}
@media(max-width:960px){
  .dstage{aspect-ratio:1560/2320}
}

@media(prefers-reduced-motion:reduce){
  /* the spine tracks a scroll run, and there is none in this mode: left
     visible it is a progress mark that never moves */
  .dspine{display:none}
  .drail{padding-right:clamp(10px,1vw,14px)}
  .dwrap{height:auto}
  .dpin{position:static;height:auto;padding:26px 0}
  .dpair,.dstage video{transition:none;transform:none}
}
