/* ==========================================================================
   asl-scene: reusable scroll-scene module. Assistly, revision 8.
   Contract: markup carries [data-scene], [data-scene-stage], [data-scene-step].
   The single rAF driver in assets/scroll-scene.js writes, per frame:
     --asl-p  on the scene   0..1  progress through the track
     --asl-o  on each step   0..1  opacity
     --asl-y  on each step   vh    vertical offset
     --asl-z  on each step   px    depth offset
     --asl-r  on each step   deg   rotateX
     --asl-k  on each step         scale
     data-asl-state on each step: "in" | "active" | "out"
   Nothing in here reads layout. Transforms and opacity, nothing else.
   BASE STATE = every step in normal document flow, fully visible.
   The pinned state applies under html.asl-scene-on and nowhere else, which the driver adds
   after it confirms it can run. No JS, or reduced motion, leaves the readable
   stacked version in place.
   ========================================================================== */

.asl-scene            { position: relative; }
.asl-scene-stage      { position: relative; }
.asl-scene-step       { position: relative; }

/* ---------- pinned mode ---------- */
html.asl-scene-on .asl-scene {
  height: calc(var(--asl-len, 4.6) * 100vh);
  height: calc(var(--asl-len, 4.6) * 100svh);
}
html.asl-scene-on .asl-scene-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  perspective: 1500px;
  perspective-origin: 50% 46%;
}
html.asl-scene-on .asl-scene-step {
  position: absolute;
  left: 0; right: 0; top: 0; bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  backface-visibility: hidden;
  will-change: transform, opacity;
  opacity: var(--asl-o, 0);
  transform:
    translate3d(0, calc(var(--asl-y, 7) * 1vh), calc(var(--asl-z, -280) * 1px))
    rotateX(calc(var(--asl-r, 7) * 1deg))
    scale(var(--asl-k, 0.93));
}
html.asl-scene-on .asl-scene-step[data-asl-state="active"] { pointer-events: auto; }
/* In the read band the driver writes identity values. Saying so explicitly
   takes the step off its composited layer, so its text is rasterised at native
   resolution instead of being resampled from a scaled layer. This is the
   difference between "opaque" and "readable". */
html.asl-scene-on .asl-scene-step[data-asl-hold="1"] {
  transform: none;
  will-change: auto;
}

/* ---------- reduced motion: no pin, no transform, every step readable ------ */
@media (prefers-reduced-motion: reduce) {
  html.asl-scene-on .asl-scene       { height: auto; }
  html.asl-scene-on .asl-scene-stage { position: static; height: auto; overflow: visible; perspective: none; }
  html.asl-scene-on .asl-scene-step  {
    position: relative; left: auto; right: auto; top: auto; bottom: auto;
    opacity: 1; transform: none; will-change: auto; pointer-events: auto;
  }
}
