/* ============================================================
   effects.css — living background system + ambient motion
   Layer order (back→front): base gradient · grid · aurora ·
   conic sweep · scanline · particles · fine noise.
   All purely decorative, pointer-events:none, behind z-index:2.
   ============================================================ */
.bg{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  background:radial-gradient(120% 80% at 50% -10%,var(--bg-2),var(--bg) 60%)}

/* perspective grid that fades upward */
.bg-grid{position:absolute;inset:-2px;
  background-image:linear-gradient(var(--grid) 1px,transparent 1px),
                   linear-gradient(90deg,var(--grid) 1px,transparent 1px);
  background-size:48px 48px;
  -webkit-mask-image:radial-gradient(ellipse 100% 78% at 50% 0%,#000 22%,transparent 90%);
          mask-image:radial-gradient(ellipse 100% 78% at 50% 0%,#000 22%,transparent 90%);
  animation:gridfloat 40s ease-in-out infinite}
@keyframes gridfloat{0%,100%{transform:translateY(0)}50%{transform:translateY(6px)}}

/* aurora blooms — react to pointer via --mx/--my */
.au{position:absolute;border-radius:50%;filter:blur(72px);mix-blend-mode:screen}
html[data-theme="light"] .au{mix-blend-mode:multiply;filter:blur(64px)}
.au1{width:50vw;height:50vw;max-width:680px;max-height:680px;top:-14%;left:4%;
  background:radial-gradient(circle,var(--au1),transparent 68%);
  transform:translate(var(--mx),var(--my));transition:transform 1.2s var(--ease-out);
  animation:au1 46s ease-in-out infinite}
.au2{width:46vw;height:46vw;max-width:620px;max-height:620px;top:2%;right:2%;
  background:radial-gradient(circle,var(--au2),transparent 68%);animation:au2 58s ease-in-out infinite}
.au3{width:40vw;height:40vw;max-width:560px;max-height:560px;bottom:-12%;left:32%;
  background:radial-gradient(circle,var(--au3),transparent 70%);animation:au3 70s ease-in-out infinite}
@keyframes au1{0%,100%{transform:translate(var(--mx),var(--my)) scale(1)}
  50%{transform:translate(calc(var(--mx) + 30px),calc(var(--my) + 22px)) scale(1.08)}}
@keyframes au2{0%,100%{transform:translate(0,0) scale(1.04)}50%{transform:translate(-28px,20px) scale(.94)}}
@keyframes au3{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(24px,-18px) scale(1.06)}}

/* slow conic sweep — a faint "radar" pass, kept subtle */
.sweep{position:absolute;top:-40%;left:50%;width:160vw;height:160vw;translate:-50% 0;
  background:conic-gradient(from 0deg,transparent 0deg,var(--glow-soft) 16deg,transparent 38deg);
  opacity:.3;animation:sweep 64s linear infinite}
@keyframes sweep{to{rotate:360deg}}

/* descending scanline — slow + faint */
.scan{position:absolute;left:0;right:0;height:220px;
  background:linear-gradient(180deg,transparent,var(--glow),transparent);
  opacity:.22;animation:scan 22s linear infinite}
@keyframes scan{0%{transform:translateY(-280px)}100%{transform:translateY(110vh)}}

/* global particle constellation — field.js paints into this canvas.
   One continuous field behind the whole page (fixed full-viewport).
   NOTE: class is .bgfield (NOT .field) to avoid colliding with form .field rows. */
.bgfield{position:absolute;inset:0;width:100%;height:100%;opacity:.62}
html[data-theme="light"] .bgfield{opacity:.85}

/* fine film grain for texture (SVG fractal noise data-uri) */
.noise{position:absolute;inset:0;opacity:.04;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

@media (prefers-reduced-motion:reduce){
  .bg-grid,.au1,.au2,.au3,.sweep,.scan,.pt{animation:none!important}
  .au1{transition:none}
}
