/* Página de obra de Luis (/luis).
   Mismo sistema que la portada: tinta sobre fondo, reglas de 2px, radio 0,
   Archivo, un solo acento, y la misma clave de tema ('ap-theme') — el tema
   elegido en la portada llega hasta aquí.

   CÓMO SE HIZO ESTA PÁGINA, porque el orden importa y ya se hizo mal una vez:
   1. Primero se cerró el TEXTO de los seis bloques (nombre, qué es, para qué,
      cómo, impacto). Sin animación de por medio.
   2. Después, de cada bloque cerrado se extrajo UNA frase y de ahí salió la
      idea de su animación.
   3. Y solo entonces se construyó.
   La versión anterior invirtió ese orden: las animaciones dibujaban la
   arquitectura del sistema y el texto se había reducido a dos palabras. Quien
   ya conocía los proyectos lo entendía; nadie más.

   Regla de las escenas: el CSS base describe el ESTADO FINAL. `is-playing`
   añade las animaciones y, como usan `animation-fill-mode:both`, el fotograma
   0% manda durante el retardo — o sea que el "antes" vive dentro de la
   animación, no en el CSS base. Consecuencia: sin JS, con el JS caído o con
   movimiento reducido, la escena se ve terminada y el bloque se entiende.
   Se reproducen UNA vez al entrar en pantalla: son una ilustración, no un
   salvapantallas. */

@font-face{font-family:'Archivo';src:url('../fonts/Archivo-latin-ext.woff2') format('woff2');
  font-weight:100 900;font-stretch:100%;font-display:swap;
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Archivo';src:url('../fonts/Archivo-latin.woff2') format('woff2');
  font-weight:100 900;font-stretch:100%;font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

:root{
  --ground:#ffffff; --panel:#f3f2f2;
  --ink:#201e1d; --body:#3d3a38; --muted:#6b6866;
  --rule:#201e1d; --hair:#d6d3d0; --faint-page:#e2dfdc;
  --accent:#ec3013; --on-accent:#ffffff;
  --font:'Archivo',system-ui,-apple-system,sans-serif;
  --measure:74rem;
  --gutter:clamp(1.25rem,4vw,3rem);
  /* el gris de dentro de una escena: 30% de tinta sobre el fondo, no un gris
     fijo — --hair vale como filete de página pero desaparece en tema oscuro */
  --faint:color-mix(in oklab,var(--ink) 30%,var(--ground));
}
:root[data-theme="dark"]{
  --ground:#201e1d; --panel:#2a2725;
  --ink:#ffffff; --body:#c9c5c2; --muted:#9d9996;
  --rule:#ffffff; --hair:#3d3a38; --faint-page:#332f2d;
  --accent:#ff6a52; --on-accent:#201e1d;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--ground);color:var(--body);font-family:var(--font);
  font-size:clamp(1rem,.96rem + .2vw,1.08rem);line-height:1.62;
  -webkit-font-smoothing:antialiased;overflow-x:hidden}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
::selection{background:color-mix(in oklab,var(--accent) 22%,transparent)}
[hidden]{display:none !important}

/* ---------- barra ---------- */
.bar{position:sticky;top:0;z-index:30;background:var(--ground);
  border-bottom:2px solid var(--rule);display:flex;align-items:center;
  gap:1rem;padding:0 var(--gutter);height:64px}
.scroll-progress{position:absolute;left:0;bottom:-2px;width:100%;height:2px;
  background:var(--accent);transform:scaleX(0);transform-origin:left center;
  will-change:transform;pointer-events:none}
.brand{font-weight:700;font-size:1.05rem;letter-spacing:.02em;color:var(--ink);
  text-transform:uppercase;white-space:nowrap;text-decoration:none}
.bar nav{display:flex;align-items:center;gap:1.4rem;margin-left:auto;
  font-size:.66rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase}
.bar nav a{color:var(--muted);text-decoration:none;padding-block:.4rem;
  border-bottom:2px solid transparent;transition:color .15s,border-color .15s}
.bar nav a:hover{color:var(--ink);border-bottom-color:var(--accent)}
.bar nav a[aria-current]{color:var(--ink);border-bottom-color:var(--accent)}
.ctrl{font-family:inherit;font-size:.66rem;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);background:none;border:0;
  border-left:1px solid var(--hair);border-radius:0;padding:.5rem .85rem;
  margin-left:.6rem;cursor:pointer;transition:color .15s,background .15s}
.ctrl:hover{color:var(--ink);background:var(--panel)}
@media (max-width:52rem){.bar nav a{display:none}}

.wrap{max-width:var(--measure);margin:0 auto;padding:0 var(--gutter)}
.prose{max-width:63ch}

/* ---------- portada ---------- */
.hero{padding:clamp(3rem,9vw,6rem) 0 clamp(1.8rem,4vw,3rem)}
.hero .eyebrow{font-size:.66rem;font-weight:700;letter-spacing:.2em;
  text-transform:uppercase;color:var(--accent);margin:0 0 1.1rem}
h1{font-size:clamp(2.3rem,1.2rem + 4.6vw,4.4rem);line-height:1;letter-spacing:-.035em;
  font-weight:700;color:var(--ink);margin:0 0 1rem;text-wrap:balance}
.claim{font-size:clamp(1.15rem,1rem + 1vw,1.6rem);font-weight:700;color:var(--ink);
  letter-spacing:-.02em;line-height:1.24;margin:0;max-width:34ch}
.claim span{color:var(--accent)}
.motion-ready .hero > *{animation:page-rise .65s cubic-bezier(.2,.75,.25,1) both}
.motion-ready .hero > :nth-child(2){animation-delay:.07s}
.motion-ready .hero > :nth-child(3){animation-delay:.14s}
.motion-ready .hero > :nth-child(4){animation-delay:.21s}
.motion-ready .hero > :nth-child(5){animation-delay:.28s}
@keyframes page-rise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:translateY(0)}}
.stamp{display:flex;flex-wrap:wrap;gap:.5rem 1.5rem;font-size:.68rem;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:1.8rem 0 0}
.stamp a{color:var(--muted);text-decoration:underline;text-decoration-color:var(--hair);
  text-underline-offset:3px;text-decoration-thickness:1px}
.stamp a:hover{color:var(--accent);text-decoration-color:var(--accent)}

.actions{display:flex;flex-wrap:wrap;gap:.8rem;margin:1.6rem 0 0}
.btn{display:inline-flex;align-items:center;gap:.6rem;font-family:inherit;
  font-size:.78rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;
  text-decoration:none;border-radius:0;padding:.85rem 1.4rem;cursor:pointer;
  transition:background .15s,color .15s,border-color .15s}
.btn-primary{background:var(--accent);color:var(--on-accent);border:2px solid var(--accent)}
.btn-primary:hover{background:color-mix(in oklab,var(--accent) 82%,#000);
  border-color:color-mix(in oklab,var(--accent) 82%,#000);color:var(--on-accent)}
.btn-secondary{background:none;color:var(--ink);border:2px solid var(--rule)}
.btn-secondary:hover{background:var(--ink);color:var(--ground)}

.legend{border-top:2px solid var(--rule);border-bottom:1px solid var(--hair);
  padding:1.1rem 0;font-size:.84rem;color:var(--muted)}
.legend span{display:block;max-width:66ch}
.legend b{color:var(--ink)}

/* ---------- índice ---------- */
.idx{list-style:none;margin:2.2rem 0 0;padding:0;border-top:1px solid var(--hair)}
.idx li{margin:0;border-bottom:1px solid var(--hair)}
.idx a{display:flex;align-items:baseline;gap:1rem;padding:.8rem .7rem .8rem 0;
  text-decoration:none;color:var(--muted);transition:color .2s,padding .25s,background .25s}
.idx a:hover{color:var(--accent)}
.idx a:hover,.idx a:focus-visible{padding-left:.7rem;background:var(--panel)}
.idx b{color:var(--accent);font-variant-numeric:tabular-nums;font-size:.7rem;
  letter-spacing:.12em;flex:none;min-width:2rem}
.idx .t{font-weight:700;color:var(--ink);text-transform:uppercase;letter-spacing:.04em;
  flex:none}
.idx a:hover .t{color:var(--accent)}
.idx .d{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.idx .s{margin-left:auto;font-size:.62rem;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;flex:none;color:var(--muted)}
.idx .s.live{color:var(--accent)}
.idx .s.done{color:var(--ink)}
@media (max-width:44rem){.idx .d{display:none}}

/* ---------- un bloque ---------- */
.act{border-top:2px solid var(--rule);padding:clamp(2.2rem,5vw,3.4rem) 0 clamp(2.4rem,6vw,4rem);
  scroll-margin-top:5rem}
.act-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:.6rem 1.1rem;margin:0 0 1.4rem}
.act-num{font-size:.72rem;font-weight:700;letter-spacing:.16em;color:var(--accent);
  font-variant-numeric:tabular-nums}
.act-name{font-size:clamp(1.7rem,1.2rem + 2vw,2.6rem);font-weight:700;color:var(--ink);
  letter-spacing:-.03em;line-height:1;margin:0}
.status{font-size:.62rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  padding:.34rem .6rem;border:1px solid var(--hair);color:var(--muted);white-space:nowrap;
  margin-left:auto}
.status.live{border-color:var(--accent);color:var(--accent)}
.status.done{border-color:var(--rule);color:var(--ink)}
@media (max-width:44rem){.status{margin-left:0;order:9}}

/* ---------- las dos columnas ----------
   La escena va FIJA mientras se lee el texto de al lado: el bloque es largo y
   la animación dura cinco segundos, así que anclarla es lo que hace que siga
   sirviendo de ilustración en vez de quedarse atrás. En el móvil las columnas
   se mantienen y la escena pasa a miniatura. */
.act-body{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(1rem,2.6vw,2.6rem);align-items:start}
.col-scene{position:sticky;top:5rem}
.col-text{min-width:0}
@media (max-width:60rem){
  .act-body{grid-template-columns:minmax(0,.62fr) minmax(0,1fr);gap:1rem}
}

/* La estructura entra una sola vez; la lectura queda quieta después. */
.motion-ready .act .act-head,.motion-ready .act .col-text{
  opacity:0;transform:translateY(18px);transition:opacity .6s ease,transform .6s cubic-bezier(.2,.75,.25,1)}
.motion-ready .act.is-visible .act-head,.motion-ready .act.is-visible .col-text{
  opacity:1;transform:translateY(0)}
.motion-ready .act.is-visible .col-text{transition-delay:.1s}
@media (max-width:44rem){
  .act-body{grid-template-columns:minmax(0,.42fr) minmax(0,1fr);gap:.7rem}
  .col-scene{top:4.6rem}
}

/* ---------- campos del bloque ---------- */
.fld{margin:0 0 1.5rem;max-width:none}
.fld:last-child{margin-bottom:0}
.fld > .lab{display:block;font-size:.62rem;font-weight:700;letter-spacing:.18em;
  text-transform:uppercase;color:var(--muted);margin-bottom:.35rem}
.fld p{margin:0 0 .8rem}
.fld p:last-child{margin:0}
.fld.lede p{font-size:clamp(1rem,.94rem + .45vw,1.24rem);line-height:1.44;color:var(--ink);
  font-weight:500;letter-spacing:-.01em}
@media (max-width:44rem){
  .fld.lede p{font-size:1rem;line-height:1.4}
  body{font-size:.94rem;line-height:1.55}
  .fld > .lab{font-size:.58rem;letter-spacing:.14em}
}
strong{color:var(--ink);font-weight:700}
em{font-style:italic}

.stack{border-top:1px solid var(--hair);margin:1.8rem 0 0;padding-top:.9rem;
  font-size:.82rem;color:var(--muted)}
.stack b{color:var(--ink);font-size:.62rem;font-weight:700;letter-spacing:.18em;
  text-transform:uppercase;margin-right:.7rem}

.honest{border-left:2px solid var(--accent);background:var(--panel);
  padding:.9rem 1.1rem;margin:1.2rem 0 0;font-size:.92rem}
.honest p{margin:0}
.honest b{color:var(--ink);text-transform:uppercase;font-size:.6rem;
  letter-spacing:.18em;display:block;margin-bottom:.3rem}

/* ---------- la escena ---------- */
.scene{position:relative;border:1px solid var(--hair);background:var(--ground);margin:0;
  box-shadow:0 0 0 0 color-mix(in oklab,var(--accent) 0%,transparent);
  transition:border-color .25s,box-shadow .25s,transform .3s cubic-bezier(.2,.75,.25,1)}
.scene::before{content:"";position:absolute;z-index:2;left:-1px;right:-1px;top:-1px;height:2px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;transition:transform .45s ease}
.scene:hover,.scene:focus-within{border-color:color-mix(in oklab,var(--accent) 55%,var(--hair));
  box-shadow:0 12px 32px color-mix(in oklab,var(--ink) 9%,transparent);transform:translateY(-2px)}
.scene:hover::before,.scene:focus-within::before{transform:scaleX(1)}
.scene svg{width:100%;height:auto;display:block;overflow:hidden}
.scene [data-num]{font-family:var(--font);font-weight:700;letter-spacing:.06em}
.replay-scene{position:absolute;z-index:3;right:.55rem;bottom:.55rem;border:1px solid var(--hair);
  background:color-mix(in oklab,var(--ground) 90%,transparent);color:var(--ink);font:600 .58rem/1 var(--font);
  letter-spacing:.13em;text-transform:uppercase;padding:.55rem .65rem;cursor:pointer;
  opacity:0;transform:translateY(5px);transition:opacity .2s,transform .2s,border-color .2s,color .2s;
  backdrop-filter:blur(5px)}
.scene:hover .replay-scene,.replay-scene:focus-visible{opacity:1;transform:translateY(0)}
.replay-scene:hover{color:var(--accent);border-color:var(--accent)}
@media (hover:none){.replay-scene{opacity:1;transform:none}}

/* ---------- cierre, carrera y pie ---------- */
.cv{border-top:2px solid var(--rule);padding:clamp(2rem,5vw,3rem) 0}
.cv h2{font-size:.72rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink);margin:0 0 1.2rem;display:flex;gap:.9rem;align-items:baseline}
.cv h2 b{color:var(--accent);font-variant-numeric:tabular-nums}
table{width:100%;border-collapse:collapse;font-size:.9rem}
td{text-align:left;vertical-align:top;padding:.6rem .9rem .6rem 0;border-bottom:1px solid var(--hair)}
td.yr{white-space:nowrap;color:var(--muted);font-size:.82rem;width:1%}
td.ro{font-weight:700;color:var(--ink)}
td.og{color:var(--muted)}
.tw{overflow-x:auto}
.cols{display:grid;grid-template-columns:1fr 1fr;gap:1.2rem 2.4rem;margin-top:1.6rem}
@media (max-width:46rem){.cols{grid-template-columns:1fr}}
.cols h3{font-size:.62rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted);margin:0 0 .5rem}
.cols ul{margin:0;padding-left:1.1rem}
.cols li{margin-bottom:.45rem}
.cols li::marker{color:var(--accent)}
.cols b{color:var(--ink)}

.close{border-top:2px solid var(--rule);padding:clamp(2rem,5vw,3rem) 0}
.close h2{font-size:clamp(1.3rem,1.1rem + 1vw,1.8rem);font-weight:700;color:var(--ink);
  letter-spacing:-.02em;margin:0 0 .8rem}
.close p{max-width:58ch;margin:0 0 1.4rem}

footer{border-top:2px solid var(--rule);padding:1.6rem var(--gutter);
  display:flex;flex-wrap:wrap;gap:.6rem 1.6rem;justify-content:space-between;
  font-size:.72rem;letter-spacing:.06em;color:var(--muted);
  max-width:var(--measure);margin:0 auto}
footer a{color:var(--muted);text-decoration:underline;text-decoration-color:var(--hair);
  text-underline-offset:3px}
footer a:hover{color:var(--accent)}

@media print{.bar,.actions,.close,.idx{display:none}.act{break-inside:avoid}}

/* ═══════════════════════════════════════════════════════════════════════
   LAS SEIS ESCENAS
   Cada una sale de UNA frase de su bloque. Si hay que explicar la animación,
   está mal elegida.
   Ninguna escribe un color literal: todo sale de los tokens, así que claro y
   oscuro salen gratis.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── 01 · "every citation is re-checked against the documents actually used;
      one that cannot be confirmed is flagged, not shipped" ────────────── */
.sc-cite .dbox{fill:none;stroke:var(--faint);stroke-width:2}
.sc-cite .dln{fill:var(--faint)}
.sc-cite .doc.lit .dbox{stroke:var(--ink)}
.sc-cite .sheet{fill:none;stroke:var(--ink);stroke-width:2}
.sc-cite .ln{fill:var(--faint)}
.sc-cite .cbox{fill:none;stroke:var(--accent);stroke-width:2}
.sc-cite .chip.no .cbox{stroke:var(--faint)}
.sc-cite .cmk{fill:none;stroke:var(--accent);stroke-width:3;stroke-linecap:square;
  stroke-dasharray:48;stroke-dashoffset:0}
.sc-cite .chip.no .cmk{stroke:var(--muted);stroke-width:2}
.sc-cite .thr{fill:none;stroke:var(--accent);stroke-width:2;
  stroke-dasharray:340;stroke-dashoffset:0}
.sc-cite .thr.dead{stroke:var(--muted);stroke-dasharray:5 5;stroke-dashoffset:0}

.sc-cite.is-playing .ln,.sc-cite.is-playing .chip{
  animation:ci-row .34s ease-out both;animation-delay:calc(var(--i)*130ms)}
.sc-cite.is-playing .doc.lit .dbox{animation:ci-lit .3s linear both}
.sc-cite.is-playing .doc[style*="--i:1"] .dbox{animation-delay:2.35s}
.sc-cite.is-playing .doc[style*="--i:3"] .dbox{animation-delay:3.15s}
.sc-cite.is-playing .thr{animation:ci-thread .6s ease-out both;
  animation-delay:calc(1.8s + var(--i)*800ms)}
.sc-cite.is-playing .cmk{animation:ci-mark .34s ease-out both;
  animation-delay:calc(2.42s + var(--j)*800ms)}

@keyframes ci-row{from{opacity:0;transform:translateX(14px)}to{opacity:1;transform:translateX(0)}}
@keyframes ci-lit{from{stroke:var(--faint)}to{stroke:var(--ink)}}
@keyframes ci-thread{from{stroke-dashoffset:340}to{stroke-dashoffset:0}}
@keyframes ci-mark{from{stroke-dashoffset:48}to{stroke-dashoffset:0}}

/* ── 02 · "cost locks the moment materials are bought; a price change next
      quarter can no longer rewrite last quarter's profit" ─────────────── */
.sc-price .tag{fill:none;stroke:var(--ink);stroke-width:2}
.sc-price .hole{fill:none;stroke:var(--ink);stroke-width:2}
.sc-price .dg{fill:var(--ink);font-family:var(--font);font-weight:700;font-size:38px}
.sc-price .reel-in{transform:translateY(var(--stop))}
.sc-price .clamp{fill:none;stroke:var(--accent);stroke-width:4;transform:translateX(0)}
.sc-price .pad{transform-box:fill-box;transform-origin:bottom center;transform:scale(1)}
.sc-price .pshk{fill:none;stroke:var(--accent);stroke-width:4}
.sc-price .pbody{fill:var(--accent)}
.sc-price .split{stroke:var(--faint);stroke-width:1;stroke-dasharray:4 6}
.sc-price .rlab{fill:var(--faint)}
.sc-price .rbar{fill:var(--faint);width:var(--w1)}
.sc-price .rtick{fill:var(--accent);opacity:1}

.sc-price.is-playing .reel-in{animation:pr-spin 2.1s cubic-bezier(.2,.6,.2,1) both;
  animation-delay:calc(.5s + var(--i)*130ms)}
.sc-price.is-playing .clamp{animation:pr-clamp .42s cubic-bezier(.3,1.4,.5,1) both;
  animation-delay:2.95s}
.sc-price.is-playing .pad{animation:pr-pad .32s cubic-bezier(.3,1.6,.5,1) both;
  animation-delay:3.25s}
.sc-price.is-playing .rbar{animation:pr-shift .45s cubic-bezier(.5,0,.3,1) both;
  animation-delay:calc(3.7s + var(--i)*380ms)}
.sc-price.is-playing .rtick{animation:pr-tick .35s ease-out both;
  animation-delay:calc(3.75s + var(--i)*380ms)}

@keyframes pr-spin{from{transform:translateY(0)}to{transform:translateY(var(--stop))}}
@keyframes pr-clamp{from{transform:translateX(var(--from))}to{transform:translateX(0)}}
@keyframes pr-pad{from{transform:scale(0)}to{transform:scale(1)}}
@keyframes pr-shift{from{width:var(--w0)}to{width:var(--w1)}}
@keyframes pr-tick{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:translateX(0)}}

/* ── 03 · "every play request is signed and expires, so a copied address is
      dead on arrival" ─────────────────────────────────────────────────── */
.sc-link .sbox{fill:none;stroke:var(--faint);stroke-width:2}
.sc-link .scr.a .sbox{stroke:var(--ink)}
.sc-link .splay{fill:var(--accent)}
.sc-link .splay.dead{fill:none;stroke:var(--faint);stroke-width:2}
.sc-link .strack{fill:var(--faint)}
.sc-link .sfill{fill:var(--ink);width:172px}
.sc-link .sx{fill:none;stroke:var(--accent);stroke-width:4;stroke-linecap:square;
  stroke-dasharray:90;stroke-dashoffset:0}
.sc-link .trail{fill:none;stroke:var(--faint);stroke-width:1;stroke-dasharray:4 7}
.sc-link .tbox{fill:var(--ground);stroke:var(--faint);stroke-width:2;stroke-dasharray:6 4}
.sc-link .turl{fill:var(--faint)}
.sc-link .tlife{fill:var(--accent);width:0}
.sc-link.is-playing .turl{animation:lnk-url 1.5s linear both;animation-delay:2.2s}
.sc-link .token{transform:translateX(460px)}

.sc-link.is-playing .sfill{animation:lnk-play 1.5s linear both;animation-delay:.5s}
.sc-link.is-playing .token{animation:lnk-move 1.5s cubic-bezier(.4,0,.3,1) both;
  animation-delay:2.2s}
.sc-link.is-playing .tlife{animation:lnk-drain 1.5s linear both;animation-delay:2.2s}
.sc-link.is-playing .tbox{animation:lnk-fade 1.5s linear both;animation-delay:2.2s}
.sc-link.is-playing .splay.dead{animation:lnk-try .34s ease-out both;animation-delay:3.85s}
.sc-link.is-playing .sx{animation:lnk-x .38s ease-out both;animation-delay:4.15s}

@keyframes lnk-play{from{width:0}to{width:172px}}
@keyframes lnk-move{from{transform:translateX(0)}to{transform:translateX(460px)}}
@keyframes lnk-drain{from{width:96px}to{width:0}}
@keyframes lnk-fade{from{stroke:var(--accent);stroke-dasharray:200}
  to{stroke:var(--faint);stroke-dasharray:6 4}}
@keyframes lnk-try{from{opacity:0}to{opacity:1}}
@keyframes lnk-x{from{stroke-dashoffset:90}to{stroke-dashoffset:0}}
@keyframes lnk-url{from{fill:var(--ink)}to{fill:var(--faint)}}

/* ── 04 · "cut the page by roughly a third while adding the price list that
      had never existed" ───────────────────────────────────────────────── */
.sc-page .hd{fill:var(--ink)}
.sc-page .ln{fill:var(--faint)}
.sc-page .grp{transform-box:fill-box;transform-origin:top center}
.sc-page .grp.gone{transform:scaleY(0)}
.sc-page .foot{transform:translateY(-118px)}
.sc-page .ghost{stroke:var(--faint);stroke-width:1;stroke-dasharray:6 5}
.sc-page .meas{fill:none;stroke:var(--accent);stroke-width:2}
.sc-page .nbox{fill:none;stroke:var(--accent);stroke-width:2}
.sc-page .nlab,.sc-page .nnum{fill:var(--accent)}
.sc-page .newblk{opacity:1;transform:translateY(0)}
.sc-page .wipe{transform:translateX(1600px)}
.sc-page .inv-bg{fill:var(--ink)}
.sc-page .inv .hd{fill:var(--ground)}
.sc-page .inv .ln{fill:var(--muted)}
.sc-page .inv .ghost{stroke:var(--muted)}

.sc-page.is-playing .grp.gone{animation:pg-cut .75s cubic-bezier(.65,0,.35,1) both;
  animation-delay:calc(.9s + var(--i)*140ms)}
.sc-page.is-playing .foot{animation:pg-up .75s cubic-bezier(.65,0,.35,1) both;
  animation-delay:1s}
.sc-page.is-playing .ghost,.sc-page.is-playing .meas{animation:pg-fade .4s ease-out both;
  animation-delay:1.75s}
.sc-page.is-playing .newblk{animation:pg-add .5s cubic-bezier(.3,1.3,.5,1) both;
  animation-delay:2.1s}
.sc-page.is-playing .wipe{animation:pg-wipe 2.5s cubic-bezier(.6,0,.4,1) both;
  animation-delay:2.85s}

@keyframes pg-cut{from{transform:scaleY(1)}to{transform:scaleY(0)}}
@keyframes pg-up{from{transform:translateY(0)}to{transform:translateY(-118px)}}
@keyframes pg-fade{from{opacity:0}to{opacity:1}}
@keyframes pg-add{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:translateY(0)}}
@keyframes pg-wipe{0%{transform:translateX(0)}32%{transform:translateX(800px)}
  62%{transform:translateX(800px)}100%{transform:translateX(1600px)}}

/* ── 05 · "it cannot find the ruling that every relevant case cites but that
      shares almost no words with what you typed" ──────────────────────── */
.sc-net .nd{fill:var(--faint);transform-box:fill-box;transform-origin:center;transform:scale(1)}
.sc-net .nd.nr{fill:var(--ink)}
.sc-net .nd.fr{fill:var(--accent)}
.sc-net .ring{fill:none;stroke:var(--faint);stroke-width:2;stroke-dasharray:5 6;r:160px}
.sc-net .qx{fill:none;stroke:var(--accent);stroke-width:3}
.sc-net .eg{stroke:var(--accent);stroke-width:2;stroke-dasharray:560;stroke-dashoffset:0}

.sc-net.is-playing .nd{animation:nt-pop .34s cubic-bezier(.3,1.5,.5,1) both;
  animation-delay:calc(var(--i)*24ms)}
.sc-net.is-playing .ring{animation:nt-ring 1.1s cubic-bezier(.25,.9,.3,1) both;
  animation-delay:.95s}
.sc-net.is-playing .nd.nr{animation:nt-pop .34s cubic-bezier(.3,1.5,.5,1) both,
  nt-near .3s linear both;
  animation-delay:calc(var(--i)*24ms),calc(1.1s + (var(--i) - 19)*130ms)}
.sc-net.is-playing .eg{animation:nt-draw .6s ease-out both,nt-taut .3s ease-out both;
  animation-delay:calc(2.45s + var(--i)*170ms),calc(3.05s + var(--i)*170ms)}
.sc-net.is-playing .nd.fr{animation:nt-pop .34s cubic-bezier(.3,1.5,.5,1) both,
  nt-yank .45s cubic-bezier(.3,1.7,.5,1) both;
  animation-delay:calc(var(--i)*24ms),calc(3.35s + (var(--i) - 24)*260ms)}

@keyframes nt-pop{from{transform:scale(0)}to{transform:scale(1)}}
@keyframes nt-ring{from{r:0px}to{r:160px}}
@keyframes nt-near{from{fill:var(--faint)}to{fill:var(--ink)}}
@keyframes nt-draw{from{stroke-dashoffset:560}to{stroke-dashoffset:0}}
@keyframes nt-taut{0%{stroke-width:2}45%{stroke-width:5}100%{stroke-width:2}}
@keyframes nt-yank{0%{fill:var(--faint);transform:scale(1)}
  50%{fill:var(--accent);transform:scale(1.75)}100%{fill:var(--accent);transform:scale(1)}}

/* ── 06 · "not to automate a task, but to remove myself from it" ──────── */
.sc-reach .pbox{fill:none;stroke:var(--ink);stroke-width:2}
.sc-reach .pln{fill:var(--faint)}
.sc-reach .av{fill:var(--faint)}
.sc-reach .cln{fill:var(--faint)}
.sc-reach .per .ph,.sc-reach .per .ps{fill:var(--ink)}
.sc-reach .rep{opacity:1}
.sc-reach .rep rect{fill:var(--accent)}
.sc-reach .ebox{fill:var(--ground);stroke:var(--accent);stroke-width:2}
.sc-reach .eflap{fill:none;stroke:var(--accent);stroke-width:2}
.sc-reach .env{transform:translateX(348px);opacity:1}
.sc-reach .env.ghosted{opacity:0}
.sc-reach .cursor{fill:var(--ink);transform:translate(520px,-232px)}

.sc-reach.is-playing .cmt{animation:rc-in .34s ease-out both;
  animation-delay:calc(.6s + var(--i)*1.15s)}
.sc-reach.is-playing .per{animation:rc-in .34s ease-out both;
  animation-delay:calc(.7s + var(--i)*1.15s)}
/* el primero lo arrastra ella: lento, y el cursor va pegado al sobre */
.sc-reach.is-playing .env.first{animation:rc-fly-first 1.75s cubic-bezier(.45,0,.5,1) both;
  animation-delay:1.55s}
.sc-reach.is-playing .cursor{animation:rc-cursor 3.2s cubic-bezier(.35,0,.5,1) both;
  animation-delay:1.2s}
/* los demás salen solos, más rápido, encabalgados */
.sc-reach.is-playing .env:not(.first):not(.ghosted){
  animation:rc-fly .5s cubic-bezier(.4,0,.3,1) both;
  animation-delay:calc(4.5s + (var(--i) - 1)*400ms)}
.sc-reach.is-playing .env.ghosted{animation:rc-ghost .42s cubic-bezier(.4,0,.3,1) both;
  animation-delay:calc(5.7s + var(--i)*230ms)}
.sc-reach.is-playing .rep{animation:rc-drop .3s cubic-bezier(.3,1.4,.5,1) both}
.sc-reach.is-playing .rep[style*="--i:0"]{animation-delay:3.35s}
.sc-reach.is-playing .rep[style*="--i:1"]{animation-delay:5.05s}
.sc-reach.is-playing .rep[style*="--i:2"]{animation-delay:5.45s}
.sc-reach.is-playing .rep[style*="--i:3"]{animation-delay:5.85s}

@keyframes rc-in{from{opacity:0;transform:translateX(-12px)}to{opacity:1;transform:translateX(0)}}
@keyframes rc-fly{0%{opacity:0;transform:translateX(0)}
  9%{opacity:1;transform:translateX(0)}
  100%{opacity:1;transform:translateX(348px)}}
/* el primero aparece ANTES de moverse: el cursor tiene que poder recogerlo */
@keyframes rc-fly-first{0%{opacity:0;transform:translateX(0)}
  9%{opacity:1;transform:translateX(0)}
  26%{transform:translateX(0)}
  100%{opacity:1;transform:translateX(348px)}}
/* los sobres de relleno solo insinúan volumen: pasan y no se quedan */
@keyframes rc-ghost{0%{opacity:0;transform:translateX(0)}
  18%{opacity:1}82%{opacity:1}100%{opacity:0;transform:translateX(348px)}}
@keyframes rc-drop{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}
/* entra abajo a la derecha, se pone sobre el sobre, lo arrastra, y se va */
@keyframes rc-cursor{
  0%{opacity:0;transform:translate(240px,290px)}
  9%{opacity:1}
  25%{transform:translate(0,0)}          /* llega justo cuando el sobre arranca */
  65.6%{transform:translate(348px,0)}    /* lo suelta justo cuando aterriza */
  72%{opacity:1;transform:translate(362px,-12px)}
  100%{opacity:0;transform:translate(520px,-236px)}}

/* Quien pide menos movimiento ve la escena terminada, que es donde vive la
   información. No es una degradación: es el mismo dibujo sin el camino. */
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important;animation-iteration-count:1 !important;scroll-behavior:auto !important}
  .scene *{transition:none !important}
  html{scroll-behavior:auto}
}
