/* ============================================================
   Nova FX — heroalive.css · "living hero" light layer (.ha-*)
   Living nebula mist + scroll-drift pleasure for index.html.
   Performance contract: transform/opacity ONLY (GPU), every
   loop paused unless .ha-live (hero in view && tab visible),
   mobile = 2 blobs slower, reduced-motion = static soft light.
   ~3 KB — no paint animations, no extra requests.
   ============================================================ */

/* ---- 1 · living nebula mist (behind orbit/h1, above aurora) ---- */
.ha-nebula{position:absolute;inset:-12%;z-index:1;pointer-events:none;
  -webkit-mask-image:radial-gradient(72% 78% at 50% 38%,#000 46%,transparent 88%);
          mask-image:radial-gradient(72% 78% at 50% 38%,#000 46%,transparent 88%)}
.ha-b{position:absolute;border-radius:50%;filter:blur(46px);opacity:0;will-change:transform,opacity;
  transition:opacity 1.4s ease .3s}
.ha-nebula.ha-in .ha-b{opacity:var(--ha-o,.22)}
.ha-b1{width:46vw;height:46vw;left:-6%;top:-8%;
  background:radial-gradient(circle at 50% 50%,rgba(47,107,255,.34),rgba(47,107,255,0) 70%);
  animation:ha-drift1 52s ease-in-out infinite alternate;animation-play-state:paused}
.ha-b2{width:34vw;height:34vw;right:-4%;top:14%;
  background:radial-gradient(circle at 50% 50%,rgba(56,189,248,.30),rgba(56,189,248,0) 70%);
  animation:ha-drift2 44s ease-in-out infinite alternate;animation-play-state:paused}
.ha-b3{width:30vw;height:30vw;left:34%;top:44%;
  background:radial-gradient(circle at 50% 50%,rgba(124,92,255,.26),rgba(124,92,255,0) 70%);
  animation:ha-drift3 64s ease-in-out infinite alternate;animation-play-state:paused}
.ha-nebula.ha-live .ha-b{animation-play-state:running}
@keyframes ha-drift1{from{transform:translate3d(0,0,0) scale(1)}to{transform:translate3d(9vw,7vh,0) scale(1.16)}}
@keyframes ha-drift2{from{transform:translate3d(0,0,0) scale(1.08)}to{transform:translate3d(-8vw,-6vh,0) scale(.94)}}
@keyframes ha-drift3{from{transform:translate3d(0,0,0) scale(.92)}to{transform:translate3d(6vw,-9vh,0) scale(1.2)}}

/* ---- 2 · hero content drift + scroll pleasure ----
   JS (heroalive.js) lerps scrollY in rAF and writes:
     --ha-y (px, negative small drift) on .hero > .container
     --ha-f (0..1 fade-out factor) on .hero content
   Both are consumed by transform/opacity ONLY. Without JS or
   when scrolled past, the map rests at 0 — nothing ever hides. */
.ha-hero .container{will-change:transform}
.ha-hero .ox-tilt{transition:transform .18s linear}
@supports (translate: 0px){     /* compose, never fight existing transforms */
  .ha-hero[data-ha-q] .container{translate:0 var(--ha-y,0px)}
}
.ha-fade{opacity:calc(1 - var(--ha-f,0)*.34)}   /* never below 0.66 */

/* ---- 3 · accent underline draw under the h1 (one-shot) ---- */
.ha-hero h1{position:relative;z-index:2}
.ha-hero h1::after{content:'';position:absolute;left:8%;right:8%;bottom:-.18em;height:2px;
  border-radius:2px;z-index:-1;
  background:linear-gradient(90deg,transparent,var(--acc2) 30%,var(--acc) 60%,transparent);
  box-shadow:0 0 14px rgba(56,189,248,.4);
  transform:scaleX(0);transform-origin:left;
  transition:transform 1.2s var(--e,cubic-bezier(.2,.8,.2,1)) .35s}
.ha-hero.ha-in h1::after{transform:scaleX(1)}

/* ---- 4 · gates ---- */
@media (max-width:860px){
  .ha-b{filter:blur(34px)}
  .ha-b3{display:none}
  .ha-nebula{inset:-8%}
}
@media (max-width:560px){
  .ha-b2{width:52vw;height:52vw;animation-duration:58s}
}
@media (prefers-reduced-motion:reduce){
  .ha-b{animation:none!important;opacity:var(--ha-o,.22)!important}
  .ha-hero .container{translate:0 0!important;transform:none!important}
  .ha-fade{opacity:1!important}
  .ha-hero h1::after{transform:scaleX(1)!important;transition:none}
}