/* The homepage's scene layer: the canvas, the haze behind the head and the vignette, all fixed to the viewport
   inside the hero stage's stacking context so they show through the hero and the phone and stay behind the copy
   (.hero-grid / .see-stage sit above at z-index 2). Hidden entirely once the page has crossed into the paper. */
canvas.scene{position:fixed;inset:0;width:100%;height:100%;display:block;z-index:0;pointer-events:none;background:#05070d;opacity:1;transition:opacity .6s ease}
.scene-haze{position:fixed;inset:0;z-index:1;pointer-events:none;background:radial-gradient(60% 70% at 28% 45%,rgba(60,110,200,.10),transparent 70%);opacity:1}
.scene-vignette{position:fixed;inset:0;z-index:1;pointer-events:none;background:radial-gradient(120% 90% at 30% 50%,transparent 55%,#05070d 100%)}
@media (max-width:900px){
  .scene-haze{background:radial-gradient(70% 50% at 50% 24%,rgba(60,110,200,.12),transparent 70%)}
  .scene-vignette{background:radial-gradient(100% 70% at 50% 30%,transparent 50%,#05070d 100%)}
}
/* while the scene is live it drives --dissolve on <html> every frame (0 dark, 1 paper): the vignette and the haze go
   out with it, scroll-linked and reversible, with no transition in the way (a transition retargeted every frame lags
   by seconds and leaves a grey corner over the pale wash). Without the scene they simply stay. */
html[data-scene-ready="1"]:not(.scene-static) .scene-haze,html[data-scene-ready="1"]:not(.scene-static) .scene-vignette{opacity:calc(1 - var(--dissolve,0))}
/* the poster: the first paint over the canvas, captured from the same camera, pose and frozen time as the live scene so the
   crossfade does not jump; it fades once the scene is live and stays as the whole scene without WebGL (html.scene-static) */
.scene-poster{position:fixed;inset:0;z-index:1;pointer-events:none;opacity:1;transition:opacity .6s ease}
.scene-poster img{display:block;width:100%;height:100%;object-fit:cover;object-position:30% 45%}
@media (max-width:900px){.scene-poster img{object-position:50% 18%}}
html[data-scene-ready="1"]:not(.scene-static) .scene-poster{opacity:0}
/* the scene became ready with the hero already scrolled: the still of the resting face is cut, not crossfaded into a mid-transit frame */
html.scene-cut .scene-poster{transition:none}
html.scene-static canvas.scene{display:none}
/* without WebGL the still head steps aside once the hero has left the viewport (html.past-hero, from the page), so it never
   bleeds through the dissolve's transparent top; the vignette and the haze follow it */
html.scene-static.past-hero .scene-poster,html.scene-static.past-hero .scene-haze,html.scene-static.past-hero .scene-vignette{opacity:0}
html.scene-past .scene-poster{opacity:0}
/* once the page is past the dissolve the scene is dark behind paper: hide it so nothing bleeds and the GPU rests */
html.scene-past canvas.scene,html.scene-past .scene-haze,html.scene-past .scene-vignette{opacity:0}
/* the stats overlay (?stats=1) */
.scene-stats{position:fixed;left:12px;bottom:12px;z-index:50;font:12px/1.4 ui-monospace,Menlo,monospace;color:#9fb3d9;background:rgba(5,7,13,.7);padding:6px 8px;border-radius:6px;pointer-events:none;white-space:pre}
