/* Two filters, stacked on a single fixed layer. Cheap: static gradients + opacity/transform animation only.
   BACKROOMS filter = camcorder: yellow cast, vignette, scanlines, grain, fluorescent flicker.
   DREAMCORE filter = soft haze: pastel bloom at the edges, faint cyan/pink fringe. */
.fx{position:fixed;inset:0;pointer-events:none;z-index:var(--z-filter)}
.fx--vignette{background:radial-gradient(ellipse at 50% 45%,transparent 55%,rgba(0,0,0,var(--vignette)) 100%)}
.fx--scan{background:repeating-linear-gradient(to bottom,rgba(255,255,230,var(--scan-alpha)) 0 1px,transparent 1px 3px);mix-blend-mode:overlay}
.fx--grain{opacity:var(--grain-alpha);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='96'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='1' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 .97 0 0 0 0 .8 0 0 0 .9 0'/%3E%3C/filter%3E%3Crect width='96' height='96' filter='url(%23n)'/%3E%3C/svg%3E")}
.fx--dream{background:radial-gradient(60% 40% at 0% 0%,rgba(227,169,207,var(--bloom-alpha)),transparent 70%),radial-gradient(55% 45% at 100% 100%,rgba(159,216,227,var(--bloom-alpha)),transparent 70%)}
.fx--flicker{background:rgba(255,248,200,.035);animation:hum var(--dur-ambient) steps(1,end) infinite}
@keyframes hum{0%,100%{opacity:1}7%{opacity:.2}8%{opacity:1}9%{opacity:.4}10%{opacity:1}58%{opacity:1}59%{opacity:0}60%{opacity:.9}61%{opacity:.1}62%{opacity:1}}
/* Discover only: fog bands that drift slowly */
.fog{position:absolute;inset:0;overflow:hidden;pointer-events:none}
.fog::before,.fog::after{content:"";position:absolute;left:-20%;width:140%;height:40%;background:linear-gradient(to bottom,transparent,rgba(224,207,85,.05),transparent);animation:drift 28s var(--ease-in-out) infinite alternate;will-change:transform}
.fog::before{top:12%}.fog::after{top:55%;animation-duration:36s;background:linear-gradient(to bottom,transparent,rgba(159,216,227,.04),transparent)}
@keyframes drift{from{transform:translate3d(-4%,0,0)}to{transform:translate3d(4%,0,0)}}
@keyframes blink{50%{opacity:.25}}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes skel{0%{opacity:.5}50%{opacity:1}100%{opacity:.5}}
@keyframes pulse-dot{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.5);opacity:.5}}
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition-duration:1ms!important}.fx--flicker{display:none}}

/* v2: horror layer */
.fx--wallpaper{background:repeating-linear-gradient(90deg,rgba(224,207,85,.035) 0 1px,transparent 1px 26px),radial-gradient(120% 80% at 50% -10%,rgba(224,207,85,.06),transparent 60%)}
.fx--track{overflow:hidden}.fx--track::after{content:"";position:absolute;left:0;right:0;top:0;height:64px;background:url("../art/scan-band.svg") 0 0/8000px 64px no-repeat;opacity:.05;animation:track 12s linear infinite,smudge 1.3s steps(1,end) infinite;will-change:transform}
@keyframes smudge{0%{background-position:0 0}22%{background-position:-2000px 0}41%{background-position:-6000px 0}63%{background-position:-4000px 0}81%{background-position:-2000px 0}}
@keyframes track{from{transform:translateY(-20vh)}to{transform:translateY(110vh)}}
.bg-art{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;background:#050403}
.bg-art img{transition:opacity 3s linear;position:absolute;inset:-3%;width:106%;height:106%;object-fit:cover;opacity:.34;filter:sepia(.5) saturate(.85) contrast(1.1);animation:breathe 42s ease-in-out infinite alternate;will-change:transform}
.bg-art::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(227,169,207,.10),transparent 35%,rgba(159,216,227,.09));mix-blend-mode:screen}
@keyframes breathe{from{transform:scale(1)}to{transform:scale(1.07) translate3d(0,-1%,0)}}
.glitch{text-shadow:2px 0 rgba(227,169,207,.55),-2px 0 rgba(159,216,227,.45);animation:glitch 7s steps(1,end) infinite}
@keyframes glitch{0%,92%,100%{transform:none}93%{transform:translate3d(-3px,0,0)}94%{transform:translate3d(4px,0,0)}95%{transform:none}}
.rec{display:inline-flex;gap:8px;align-items:center;font:500 var(--fs-12)/1 var(--font-mono);letter-spacing:.14em;color:var(--text-2)}.rec::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--signal-danger);animation:blink 1.6s steps(1,end) infinite}
.hero-art{position:absolute;inset:0 0 auto 0;height:380px;overflow:hidden;-webkit-mask-image:linear-gradient(to bottom,#000 15%,transparent);mask-image:linear-gradient(to bottom,#000 15%,transparent)}
.hero-art img{width:100%;height:100%;object-fit:cover;opacity:.45;filter:sepia(.4) contrast(1.1)}

/* v3: frame animation + hand-drawn lettering */
.scared{animation:scared 14s step-end infinite;will-change:transform}
/* irregular holds on purpose: no rhythm to settle into. 6-frame strip, 16.667% per frame */
@keyframes scared{0%{transform:translateX(0)}31%{transform:translateX(-16.667%)}33%{transform:translateX(0)}58%{transform:translateX(-33.333%)}60%{transform:translateX(-50%)}81%{transform:translateX(-66.667%)}82%{transform:translateX(-50%)}90%{transform:translateX(-83.333%)}100%{transform:translateX(0)}}
.glitch-img{filter:drop-shadow(2px 0 rgba(227,169,207,.5)) drop-shadow(-2px 0 rgba(159,216,227,.4))}
.hero-art img{width:100%;height:100%}

/* v4: boil. Same drawing redrawn 6x in one strip; steps() jumps between redraws in irregular order. */
.boil{display:block;flex:none;background-repeat:no-repeat;background-size:600% 100%;animation:boil6 1.1s steps(1,end) infinite}
@keyframes boil6{0%{background-position:0 0}14%{background-position:60% 0}29%{background-position:20% 0}43%{background-position:100% 0}57%{background-position:40% 0}72%{background-position:80% 0}86%{background-position:20% 0}}
@media (prefers-reduced-motion:reduce){.boil{animation:none!important}}
