/* v9 · the hero moves, all from their own artwork (no new shapes):
   - intro once: the art punches in under a yellow impact flash, the headline words slam in, the sign stamps, the play pops;
   - loop: comic jitter rays on the orange ground (masked to the orange, from the art itself: assets/art/m-orange.webp),
     a light charge running up the yellow arrow (masked to the arrow: assets/art/m-arrow.webp), the sign breathing;
   - pointer depth on desktop: the art, the headline and the sign drift at three speeds.
   The fx box is laid over the image's own cover box (hero-fx.js sizes it), so the masks sit on the art pixel for pixel.
   Off screen or with the clip open everything rests; reduced motion or ?static: no fx at all. */
.fx{position:absolute;z-index:1;pointer-events:none}
.fx>*{position:absolute;inset:0}
.fx-rays{-webkit-mask:url(assets/art/m-orange.webp) 0 0/100% 100% no-repeat;mask:url(assets/art/m-orange.webp) 0 0/100% 100% no-repeat;overflow:hidden}
.fx-rays i{position:absolute;left:29.8%;top:30%;width:260%;aspect-ratio:1;translate:-50% -50%;border-radius:50%;
  background:repeating-conic-gradient(from 0deg,rgba(11,11,11,.0) 0 5.2deg,rgba(11,11,11,.34) 5.6deg 6.4deg,rgba(11,11,11,0) 6.8deg 11deg);
  -webkit-mask:radial-gradient(closest-side,transparent 9%,#000 22%);mask:radial-gradient(closest-side,transparent 9%,#000 22%);
  animation:fxJit .36s steps(1) infinite}
.fx-rays b{position:absolute;inset:0;background:radial-gradient(42% 60% at 29.8% 30%,rgba(255,232,140,.55),rgba(255,232,140,0) 70%);mix-blend-mode:screen;animation:fxGlow 2.4s ease-in-out infinite}
@keyframes fxJit{0%{rotate:0deg;scale:1}33%{rotate:1.3deg;scale:1.012}66%{rotate:-.8deg;scale:.995}}
@keyframes fxGlow{0%,100%{opacity:.15}50%{opacity:.75}}
.fx-arrow{-webkit-mask:url(assets/art/m-arrow.webp) 0 0/100% 100% no-repeat;mask:url(assets/art/m-arrow.webp) 0 0/100% 100% no-repeat;
  background:linear-gradient(56deg,rgba(255,255,255,0) 44%,rgba(255,252,214,.95) 50%,rgba(255,255,255,0) 56%) 0 0/100% 100% no-repeat;
  background-size:260% 260%;mix-blend-mode:screen;animation:fxCharge 3.4s cubic-bezier(.5,0,.3,1) infinite}
@keyframes fxCharge{0%{background-position:100% 100%;opacity:1}38%{background-position:0 0;opacity:1}39%,100%{background-position:0 0;opacity:0}}
.fx-arrow::after{content:"";position:absolute;inset:0;background:#FFF6A8;mix-blend-mode:screen;opacity:0;animation:fxZap 3.4s linear infinite}
@keyframes fxZap{0%,34%{opacity:0}38%{opacity:.55}50%,100%{opacity:0}}
.fx-flash{position:absolute;inset:0;z-index:5;background:var(--yellow);opacity:0;pointer-events:none}

/* the breathing sign and the pointer depth */
.stage-art img{transition:translate .5s cubic-bezier(.16,1,.3,1)}
.hero:not(.vs) .stage.fx-on .stage-art img{scale:1.03;translate:calc(var(--mx,0) * -10px) calc(var(--my,0) * -6px)}
.stage.fx-on .stage-h{translate:calc(var(--mx,0) * 6px) calc(var(--my,0) * 4px);transition:translate .5s cubic-bezier(.16,1,.3,1),opacity .3s}
.stage.fx-on .stage-sign{translate:calc(var(--mx,0) * 14px) calc(var(--my,0) * 9px);animation:fxBreathe 3.6s ease-in-out infinite;transition:translate .5s cubic-bezier(.16,1,.3,1),opacity .3s}
@keyframes fxBreathe{0%,100%{scale:1}50%{scale:1.035}}
.fx-off .fx *,.fx-off .stage-sign,.fx-off .fx-rays i,.stage[data-cm] .fx *{animation-play-state:paused!important}
.stage[data-cm] .fx{display:none}

/* versus: the two boards lean against each other, one up while the other dips */
.vs.fx-on .vs-sign.hi{animation:fxHi 2.8s ease-in-out infinite}
.vs.fx-on .vs-sign.lo{animation:fxLo 2.8s ease-in-out infinite}
@keyframes fxHi{0%,100%{translate:0 0}50%{translate:0 -10px}}
@keyframes fxLo{0%,100%{translate:0 -10px}50%{translate:0 0}}
.vs.fx-on .vs-art img{scale:1.04;translate:calc(var(--mx,0) * -12px) calc(var(--my,0) * -8px);transition:translate .6s cubic-bezier(.16,1,.3,1)}
.vs.fx-off .vs-sign{animation-play-state:paused}

@media (prefers-reduced-motion:reduce){.fx{display:none}.stage-sign,.vs-sign{animation:none!important}}
html.static .fx{display:none}

/* the art loops (art-loops.js): laid over the still, fading in only once they truly play */
.art-loop{position:absolute;inset:0;width:100%;height:100%;display:block;opacity:0;transition:opacity .6s ease;pointer-events:none}
.art-loop.on{opacity:1}
.stage[data-cm] .art-loop{visibility:hidden}
@media (prefers-reduced-motion:reduce){.art-loop{display:none}}
.hero:not(.vs) .stage.fx-on .art-loop{scale:1.03;translate:calc(var(--mx,0) * -10px) calc(var(--my,0) * -6px);transition:opacity .6s ease,translate .5s cubic-bezier(.16,1,.3,1)}
.vs.fx-on .vs-art .art-loop{scale:1.04;translate:calc(var(--mx,0) * -12px) calc(var(--my,0) * -8px);transition:opacity .6s ease,translate .6s cubic-bezier(.16,1,.3,1)}
/* once the art itself moves, the code overlays step back */
.stage:has(.art-loop.on) .fx{display:none}
