/* =========================================================
   Background FX: data-centre photo field + flashlight lens
   + scroll-drawn glowing circuit trace
   Performance: every moving part is moved with transform only
   (GPU-composited); no per-frame mask/filter repaints.
   ========================================================= */
:root{ --p300:#5591ab; --p50:#e2eef4; }

.bg-layer{ position:absolute; top:0; left:0; width:100%; height:0; z-index:1; pointer-events:none; overflow:hidden; }
.bg-field{ position:fixed; inset:0; pointer-events:none; overflow:hidden; contain:strict; }

/* faint full-screen photo (grayscale baked into the file) */
.bg-base{ position:absolute; inset:0; background:url(../img/bg-base.jpg) center/cover no-repeat; opacity:.05; }

/* flashlight lenses: a round window that moves over the screen, while the
   photo inside moves the opposite way, so the photo stays put */
.bg-lens{
  position:absolute; top:0; left:0; border-radius:50%; overflow:hidden;
  will-change:transform; transform:translate3d(-9999px,-9999px,0);
  -webkit-mask-image:radial-gradient(circle closest-side,#000 0%,rgba(0,0,0,.7) 50%,rgba(0,0,0,0) 100%);
          mask-image:radial-gradient(circle closest-side,#000 0%,rgba(0,0,0,.7) 50%,rgba(0,0,0,0) 100%);
  opacity:0; transition:opacity .45s cubic-bezier(.16,1,.3,1);
}
.bg-lens.is-on{ opacity:1; }
.bg-lens-cursor{ width:520px; height:520px; }
.bg-lens-tip{
  width:240px; height:240px;
  -webkit-mask-image:radial-gradient(circle closest-side,#000 0%,rgba(0,0,0,0) 100%);
          mask-image:radial-gradient(circle closest-side,#000 0%,rgba(0,0,0,0) 100%);
}
.bg-lens-img{
  position:absolute; top:0; left:0; width:100vw; height:100vh;
  background:url(../img/bg-lit.jpg?v=2) center/cover no-repeat; opacity:.6;
  will-change:transform;
}
.bg-glow{
  position:absolute; top:0; left:0; width:640px; height:640px; border-radius:50%;
  background:radial-gradient(circle,rgba(85,145,171,.19) 0%,rgba(85,145,171,0) 65%);
  will-change:transform; transform:translate3d(-9999px,-9999px,0);
}

/* circuit trace */
.bg-trace{ position:absolute; top:0; left:0; overflow:visible; }
.tr-base{ fill:none; stroke:rgba(85,145,171,.45); stroke-width:1.4; stroke-dasharray:2 7; stroke-linecap:round; }
.tr-glow, .tr-core{ fill:none; stroke-linecap:round; stroke-linejoin:round; }
.tr-glow{ stroke:rgba(85,145,171,.28); stroke-width:10; }
.tr-core{ stroke:var(--p300); stroke-width:2.4; }
.tr-tip{ opacity:0; transition:opacity .3s ease; }
.tr-tip .halo{ fill:rgba(85,145,171,.3); }
.tr-tip .core{ fill:var(--p50); stroke:var(--primary); stroke-width:2; }
.tr-via{
  position:absolute; width:12px; height:12px; margin:-6px 0 0 -6px; border-radius:50%;
  background:rgba(85,145,171,.15); border:2px solid rgba(85,145,171,.6);
  transition:background .4s cubic-bezier(.16,1,.3,1), box-shadow .4s cubic-bezier(.16,1,.3,1), border-color .4s cubic-bezier(.16,1,.3,1);
}
.tr-label{
  position:absolute; padding:3px 9px; border-radius:6px; white-space:nowrap;
  background:rgba(8,26,56,.82); color:var(--primary-200);
  font-family:var(--font-display); font-weight:600; font-size:13px; line-height:1.5; letter-spacing:.1em; text-transform:uppercase;
  transition:background .4s cubic-bezier(.16,1,.3,1), color .4s cubic-bezier(.16,1,.3,1);
}
.tr-mark.on .tr-via{ background:var(--p300); border-color:var(--p50); box-shadow:0 0 0 5px rgba(85,145,171,.22), 0 0 16px rgba(85,145,171,.6); }
.tr-mark.on .tr-label{ background:var(--primary); color:#fff; }

/* keep page content above the background layer */
main > section > .container, .site-footer > .container{ position:relative; z-index:2; }

@media (max-width:560px){ .tr-label{ display:none; } }
/* phones: a smaller torch that follows the finger */
@media (max-width:640px){ .bg-lens-cursor{ width:300px; height:300px; } .bg-glow{ width:380px; height:380px; } }
@media print{ .bg-layer{ display:none; } }

/* ---------- Ball birth intro + heartbeat ---------- */
.tr-tip .halo{ transform-box:fill-box; transform-origin:center; animation:tipBeat 1.6s cubic-bezier(.45,0,.55,1) infinite; }
@keyframes tipBeat{ 0%,100%{ transform:scale(1); opacity:.9; } 18%{ transform:scale(1.45); opacity:.55; } 36%{ transform:scale(1.1); opacity:.85; } 50%{ transform:scale(1.3); opacity:.6; } }
.tr-tip.is-born .halo{ animation-duration:.8s; }
.tr-tip.is-born .core{ transform-box:fill-box; transform-origin:center; animation:tipBorn .7s cubic-bezier(.16,1,.3,1) .45s both; }
@keyframes tipBorn{ from{ transform:scale(0); } to{ transform:scale(1); } }

.tr-burst{ position:absolute; width:0; height:0; pointer-events:none; z-index:3; }
.tr-burst i{ position:absolute; left:0; top:0; border-radius:50%; transform:translate(-50%,-50%); }
.tr-burst .core{
  width:340px; height:340px;
  background:radial-gradient(circle, rgba(255,255,255,.95) 0%, rgba(198,218,227,.75) 12%, rgba(85,145,171,.35) 35%, rgba(28,108,143,0) 70%);
  mix-blend-mode:screen; animation:burstCore 1.1s cubic-bezier(.16,1,.3,1) forwards;
}
.tr-burst .ring{ width:90px; height:90px; border:2px solid rgba(226,238,244,.9); box-shadow:0 0 24px rgba(142,181,198,.8); animation:burstRing 1.1s cubic-bezier(.16,1,.3,1) forwards; }
.tr-burst .ring.r2{ animation-delay:.15s; opacity:0; }
.tr-burst .rays{
  width:520px; height:520px;
  background:conic-gradient(from 0deg, rgba(226,238,244,0) 0deg, rgba(226,238,244,.35) 6deg, rgba(226,238,244,0) 14deg, rgba(226,238,244,0) 40deg, rgba(226,238,244,.28) 46deg, rgba(226,238,244,0) 54deg, rgba(226,238,244,0) 90deg, rgba(226,238,244,.35) 96deg, rgba(226,238,244,0) 104deg, rgba(226,238,244,0) 140deg, rgba(226,238,244,.28) 146deg, rgba(226,238,244,0) 154deg, rgba(226,238,244,0) 180deg, rgba(226,238,244,.35) 186deg, rgba(226,238,244,0) 194deg, rgba(226,238,244,0) 230deg, rgba(226,238,244,.28) 236deg, rgba(226,238,244,0) 244deg, rgba(226,238,244,0) 270deg, rgba(226,238,244,.35) 276deg, rgba(226,238,244,0) 284deg, rgba(226,238,244,0) 320deg, rgba(226,238,244,.28) 326deg, rgba(226,238,244,0) 334deg);
  -webkit-mask-image:radial-gradient(circle, #000 0%, rgba(0,0,0,.6) 30%, transparent 68%);
          mask-image:radial-gradient(circle, #000 0%, rgba(0,0,0,.6) 30%, transparent 68%);
  mix-blend-mode:screen; animation:burstRays 1.2s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes burstCore{ 0%{ transform:translate(-50%,-50%) scale(.1); opacity:0; } 15%{ opacity:1; } 100%{ transform:translate(-50%,-50%) scale(1.25); opacity:0; } }
@keyframes burstRing{ 0%{ transform:translate(-50%,-50%) scale(.3); opacity:1; } 100%{ transform:translate(-50%,-50%) scale(4.2); opacity:0; } }
@keyframes burstRays{ 0%{ transform:translate(-50%,-50%) scale(.2) rotate(0deg); opacity:0; } 20%{ opacity:1; } 100%{ transform:translate(-50%,-50%) scale(1.1) rotate(35deg); opacity:0; } }
/* the hub itself pulses as the ball leaves it */
.stack-hub.is-birth{ animation:hubBirth .9s cubic-bezier(.16,1,.3,1); }
@keyframes hubBirth{ 0%{ box-shadow:0 0 0 0 rgba(226,238,244,.9), 0 0 0 rgba(142,181,198,0); } 35%{ box-shadow:0 0 0 10px rgba(226,238,244,0), 0 0 60px rgba(142,181,198,.9); } 100%{ box-shadow:0 0 0 0 rgba(226,238,244,0), 0 0 0 rgba(142,181,198,0); } }
@media (prefers-reduced-motion:reduce){ .tr-tip .halo{ animation:none; } .tr-burst{ display:none; } }

/* phones: size the photo layer to the tallest viewport (address bar hidden), so it never
   re-fits — and jumps — while the browser bar slides in and out during scrolling */
.bg-field{ bottom:auto; height:100vh; height:100lvh; }

/* ---------- v5: richer, still natural birth light ----------
   charge (hub gathers light) → flash (white core + soft bloom + horizontal lens flare)
   → rings and sparks spread → the bloom lingers and fades like an afterglow */
.stack-hub.is-charging{ animation:hubCharge .35s cubic-bezier(.5,0,.75,0) forwards; }
@keyframes hubCharge{ from{ box-shadow:0 0 0 0 rgba(226,238,244,0), 0 0 0 rgba(142,181,198,0); filter:brightness(1); }
  to{ box-shadow:0 0 0 6px rgba(226,238,244,.35), 0 0 50px rgba(142,181,198,.8); filter:brightness(1.35); } }
.stack-hub.is-birth{ animation:hubBirth2 1.6s cubic-bezier(.16,1,.3,1); }
@keyframes hubBirth2{
  0%{ box-shadow:0 0 0 0 rgba(255,255,255,.95), 0 0 90px rgba(198,218,227,1); filter:brightness(1.8); }
  30%{ box-shadow:0 0 0 16px rgba(226,238,244,0), 0 0 70px rgba(142,181,198,.75); filter:brightness(1.25); }
  100%{ box-shadow:0 0 0 0 rgba(226,238,244,0), 0 0 0 rgba(142,181,198,0); filter:brightness(1); } }

.tr-burst .core{ width:420px; height:420px; animation-duration:1.3s;
  background:radial-gradient(circle, #fff 0%, rgba(255,255,255,.95) 6%, rgba(198,218,227,.8) 14%, rgba(85,145,171,.38) 34%, rgba(28,108,143,0) 70%); }
.tr-burst .bloom{
  width:900px; height:900px; mix-blend-mode:screen;
  background:radial-gradient(circle, rgba(142,181,198,.45) 0%, rgba(85,145,171,.22) 30%, rgba(28,108,143,0) 65%);
  animation:burstBloom 2.4s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes burstBloom{ 0%{ transform:translate(-50%,-50%) scale(.3); opacity:0; } 12%{ opacity:1; } 45%{ opacity:.75; } 100%{ transform:translate(-50%,-50%) scale(1.1); opacity:0; } }
.tr-burst .flare{
  width:760px; height:6px; border-radius:6px; mix-blend-mode:screen;
  background:linear-gradient(90deg, rgba(226,238,244,0), rgba(226,238,244,.55) 35%, #fff 50%, rgba(226,238,244,.55) 65%, rgba(226,238,244,0));
  filter:blur(1.5px); animation:burstFlare 1.1s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes burstFlare{ 0%{ transform:translate(-50%,-50%) scaleX(.05); opacity:0; } 14%{ opacity:1; } 100%{ transform:translate(-50%,-50%) scaleX(1); opacity:0; } }
.tr-burst .ring.r3{ animation-delay:.32s; animation-duration:1.5s; opacity:0; border-width:1px; }
.tr-burst .spark{
  width:5px; height:5px; background:#fff; box-shadow:0 0 8px 2px rgba(198,218,227,.9);
  animation:burstSpark var(--t,.9s) cubic-bezier(.16,1,.3,1) .05s forwards; opacity:0;
}
@keyframes burstSpark{
  0%{ transform:translate(-50%,-50%) rotate(var(--a)) translateX(10px) scale(1); opacity:1; }
  100%{ transform:translate(-50%,-50%) rotate(var(--a)) translateX(var(--d)) scale(.2); opacity:0; } }
@media (max-width:640px){ .tr-burst .bloom{ width:560px; height:560px; } .tr-burst .flare{ width:440px; } .tr-burst .core{ width:300px; height:300px; } }
/* the front flash is gentler than the old background one, since it now covers the hub itself */
.tr-burst.is-front{ z-index:6; }
.tr-burst.is-front .core{ opacity:.9; }

/* ---------- Light birth scene (phones + desktop) ----------
   every piece animates only transform + opacity; glows are baked into gradients,
   so nothing forces the page to be re-blended or re-painted per frame */
.tr-burst{ contain:layout style; }
.tr-burst i{ mix-blend-mode:normal !important; filter:none !important; will-change:transform, opacity; backface-visibility:hidden; }
.tr-burst .charge{
  width:220px; height:220px; opacity:0;
  background:radial-gradient(circle, rgba(226,238,244,.55) 0%, rgba(142,181,198,.3) 30%, rgba(28,108,143,0) 68%);
  animation:burstCharge .38s cubic-bezier(.5,0,.75,0) forwards;
}
@keyframes burstCharge{ from{ transform:translate(-50%,-50%) scale(.4); opacity:0; } to{ transform:translate(-50%,-50%) scale(1); opacity:1; } }
.tr-burst.flashed .charge{ animation:burstChargeOut .5s ease-out forwards; }
@keyframes burstChargeOut{ from{ transform:translate(-50%,-50%) scale(1); opacity:1; } to{ transform:translate(-50%,-50%) scale(1.6); opacity:0; } }
.tr-burst .flare{
  height:14px; border-radius:50%;
  background:radial-gradient(ellipse at center, #fff 0%, rgba(226,238,244,.75) 18%, rgba(142,181,198,.25) 45%, rgba(142,181,198,0) 70%);
}
.tr-burst .ring{ box-shadow:none; border-color:rgba(226,238,244,.85); }
.tr-burst .spark{
  width:14px; height:14px; box-shadow:none;
  background:radial-gradient(circle, #fff 0%, #fff 22%, rgba(198,218,227,.55) 40%, rgba(198,218,227,0) 70%);
}
/* the hub just swells and settles (transform only) */
.stack-hub.is-charging{ animation:hubChargeLite .38s cubic-bezier(.5,0,.75,0) forwards; }
@keyframes hubChargeLite{ from{ transform:translate(-50%,-50%) scale(1); } to{ transform:translate(-50%,-50%) scale(1.08); } }
.stack-hub.is-birth{ animation:hubBirthLite 1.2s cubic-bezier(.16,1,.3,1); }
@keyframes hubBirthLite{ 0%{ transform:translate(-50%,-50%) scale(1.12); } 100%{ transform:translate(-50%,-50%) scale(1); } }
@media (max-width:640px){
  .tr-burst .bloom{ width:460px; height:460px; }
  .tr-burst .core{ width:260px; height:260px; }
  .tr-burst .flare{ width:360px; }
}
