/**
 * DS Global Effects — frontend overlays
 * Playback controlled via CSS variables + optional JS loop delay.
 */

.dsge-root {
	position: fixed;
	inset: 0;
	pointer-events: none;
	z-index: 9998;
	overflow: hidden;
}

.dsge-layer {
	position: absolute;
	inset: 0;
	pointer-events: none;
	--dsge-i: var(--dsge-intensity, 0.7);
	--dsge-speed: 1;
	--dsge-iteration: infinite;
	--dsge-delay: 0ms;
	--dsge-direction: normal;
	--dsge-easing: linear;
	--dsge-opacity: 1;
	opacity: var(--dsge-opacity, 1);
	animation-duration: calc(var(--dsge-duration, 1s) / var(--dsge-speed, 1));
	animation-timing-function: var(--dsge-easing, linear);
	animation-delay: var(--dsge-delay, 0ms);
	animation-iteration-count: var(--dsge-iteration, infinite);
	animation-direction: var(--dsge-direction, normal);
	animation-fill-mode: both;
}

.dsge-layer.is-paused {
	animation-play-state: paused;
}

.dsge-layer--fade-out {
	animation-fill-mode: forwards;
}

.dsge-layer--fade-out.dsge-is-done {
	transition: opacity 0.6s ease;
	opacity: 0 !important;
}

/* —— Grain —— */
.dsge-layer--grain {
	--dsge-duration: 0.24s;
	--dsge-easing: steps(2, end);
	opacity: calc(0.42 * var(--dsge-i) * var(--dsge-opacity, 1));
	background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
	background-size: 180px 180px;
	mix-blend-mode: overlay;
	animation-name: dsge-grain;
}

@keyframes dsge-grain {
	0% { transform: translate(0, 0); }
	25% { transform: translate(-2%, 1%); }
	50% { transform: translate(1%, -1%); }
	75% { transform: translate(-1%, 2%); }
	100% { transform: translate(0, 0); }
}

/* —— Vignette —— */
.dsge-layer--vignette {
	background: radial-gradient(
		ellipse at center,
		transparent 42%,
		rgba(0, 0, 0, calc(0.72 * var(--dsge-i))) 100%
	);
}

.dsge-layer--vignette-heavy {
	background: radial-gradient(
		ellipse at center,
		transparent 28%,
		rgba(0, 0, 0, calc(0.9 * var(--dsge-i))) 100%
	);
}

/* —— Bloom —— */
.dsge-layer--bloom {
	background: radial-gradient(
		circle at 50% 38%,
		rgba(255, 255, 255, calc(0.3 * var(--dsge-i))),
		transparent 55%
	);
	mix-blend-mode: screen;
}

/* —— Light leak —— */
.dsge-layer--leak {
	--dsge-duration: 7s;
	--dsge-easing: ease-in-out;
	background: linear-gradient(
		115deg,
		transparent 40%,
		rgba(255, 120, 60, calc(0.35 * var(--dsge-i))) 55%,
		rgba(255, 40, 80, calc(0.25 * var(--dsge-i))) 62%,
		transparent 75%
	);
	mix-blend-mode: screen;
	animation-name: dsge-leak;
}

@keyframes dsge-leak {
	0%, 100% { opacity: calc(0.35 * var(--dsge-opacity, 1)); transform: translateX(-8%) rotate(-2deg); }
	50% { opacity: var(--dsge-opacity, 1); transform: translateX(8%) rotate(2deg); }
}

/* —— Aurora —— */
.dsge-layer--aurora {
	--dsge-duration: 12s;
	--dsge-easing: ease-in-out;
	--dsge-direction: alternate;
	background:
		radial-gradient(ellipse 80% 50% at 20% 20%, rgba(80, 255, 180, calc(0.28 * var(--dsge-i))), transparent 60%),
		radial-gradient(ellipse 70% 45% at 80% 30%, rgba(120, 100, 255, calc(0.25 * var(--dsge-i))), transparent 55%),
		radial-gradient(ellipse 60% 40% at 50% 80%, rgba(60, 180, 255, calc(0.2 * var(--dsge-i))), transparent 50%);
	mix-blend-mode: screen;
	animation-name: dsge-aurora;
}

@keyframes dsge-aurora {
	from { transform: translateY(0) scale(1); filter: hue-rotate(0deg); }
	to { transform: translateY(-4%) scale(1.05); filter: hue-rotate(25deg); }
}

/* —— God rays —— */
.dsge-layer--rays {
	--dsge-duration: 10s;
	--dsge-easing: ease-in-out;
	--dsge-direction: alternate;
	background: conic-gradient(
		from 210deg at 70% -10%,
		transparent 0deg,
		rgba(255, 230, 180, calc(0.18 * var(--dsge-i))) 12deg,
		transparent 24deg,
		rgba(255, 220, 160, calc(0.12 * var(--dsge-i))) 36deg,
		transparent 48deg,
		rgba(255, 240, 200, calc(0.15 * var(--dsge-i))) 60deg,
		transparent 80deg
	);
	mix-blend-mode: screen;
	animation-name: dsge-rays;
}

@keyframes dsge-rays {
	from { opacity: calc(0.7 * var(--dsge-opacity, 1)); }
	to { opacity: var(--dsge-opacity, 1); }
}

/* —— Spotlight —— */
.dsge-layer--spotlight {
	background: radial-gradient(
		circle at 50% 35%,
		transparent 18%,
		rgba(0, 0, 0, calc(0.55 * var(--dsge-i))) 70%
	);
}

/* —— Highlight sweep —— */
.dsge-layer--highlight-sweep {
	--dsge-duration: 3.2s;
	--dsge-easing: ease-in-out;
	background: linear-gradient(
		105deg,
		transparent 35%,
		rgba(255, 255, 255, calc(0.22 * var(--dsge-i))) 48%,
		transparent 62%
	);
	mix-blend-mode: soft-light;
	animation-name: dsge-sweep;
}

@keyframes dsge-sweep {
	0% { transform: translateX(-40%); opacity: 0; }
	20% { opacity: var(--dsge-opacity, 1); }
	80% { opacity: var(--dsge-opacity, 1); }
	100% { transform: translateX(40%); opacity: 0; }
}

/* —— Rain —— */
.dsge-layer--rain,
.dsge-layer--rain-heavy {
	--dsge-duration: 0.45s;
	background-image: repeating-linear-gradient(
		-15deg,
		transparent,
		transparent 6px,
		rgba(180, 200, 255, calc(0.18 * var(--dsge-i))) 6px,
		rgba(180, 200, 255, calc(0.18 * var(--dsge-i))) 7px
	);
	background-size: 40px 80px;
	animation-name: dsge-rain;
}

.dsge-layer--rain-heavy {
	--dsge-duration: 0.28s;
	opacity: calc(1.25 * var(--dsge-opacity, 1));
	background-size: 28px 60px;
}

@keyframes dsge-rain {
	from { background-position: 0 0; }
	to { background-position: 20px 80px; }
}

/* —— Snow —— */
.dsge-layer--snow {
	--dsge-duration: 8s;
	background-image:
		radial-gradient(2px 2px at 20% 30%, rgba(255, 255, 255, calc(0.85 * var(--dsge-i))), transparent),
		radial-gradient(3px 3px at 60% 70%, rgba(255, 255, 255, calc(0.7 * var(--dsge-i))), transparent),
		radial-gradient(2px 2px at 80% 10%, rgba(255, 255, 255, calc(0.8 * var(--dsge-i))), transparent),
		radial-gradient(2.5px 2.5px at 40% 50%, rgba(255, 255, 255, calc(0.65 * var(--dsge-i))), transparent),
		radial-gradient(2px 2px at 10% 80%, rgba(255, 255, 255, calc(0.75 * var(--dsge-i))), transparent);
	background-size: 220px 220px;
	animation-name: dsge-snow;
}

@keyframes dsge-snow {
	from { background-position: 0 0, 40px 20px, -20px 60px, 80px 10px, 10px 100px; }
	to { background-position: 40px 220px, 80px 240px, 20px 280px, 120px 230px, 50px 320px; }
}

/* —— Fog —— */
.dsge-layer--fog {
	--dsge-duration: 14s;
	--dsge-easing: ease-in-out;
	--dsge-direction: alternate;
	background:
		radial-gradient(ellipse 90% 40% at 30% 80%, rgba(220, 230, 240, calc(0.45 * var(--dsge-i))), transparent 70%),
		radial-gradient(ellipse 80% 35% at 70% 90%, rgba(200, 210, 220, calc(0.4 * var(--dsge-i))), transparent 65%);
	animation-name: dsge-fog;
}

@keyframes dsge-fog {
	from { transform: translateX(-3%); opacity: calc(0.75 * var(--dsge-opacity, 1)); }
	to { transform: translateX(3%); opacity: var(--dsge-opacity, 1); }
}

/* —— Smoke —— */
.dsge-layer--smoke {
	--dsge-duration: 18s;
	--dsge-easing: ease-in-out;
	--dsge-direction: alternate;
	background:
		radial-gradient(ellipse 50% 40% at 40% 70%, rgba(120, 120, 130, calc(0.35 * var(--dsge-i))), transparent 70%),
		radial-gradient(ellipse 45% 35% at 65% 60%, rgba(90, 90, 100, calc(0.3 * var(--dsge-i))), transparent 65%);
	mix-blend-mode: multiply;
	animation-name: dsge-fog;
}

/* —— Particles —— */
.dsge-layer--particles {
	--dsge-duration: 20s;
	background-image:
		radial-gradient(1.5px 1.5px at 15% 25%, rgba(255, 255, 255, calc(0.7 * var(--dsge-i))), transparent),
		radial-gradient(1.5px 1.5px at 55% 15%, rgba(255, 220, 180, calc(0.6 * var(--dsge-i))), transparent),
		radial-gradient(2px 2px at 75% 45%, rgba(180, 220, 255, calc(0.55 * var(--dsge-i))), transparent),
		radial-gradient(1.5px 1.5px at 35% 65%, rgba(255, 255, 255, calc(0.5 * var(--dsge-i))), transparent),
		radial-gradient(1.5px 1.5px at 85% 80%, rgba(255, 200, 220, calc(0.55 * var(--dsge-i))), transparent);
	background-size: 280px 280px;
	animation-name: dsge-particles;
}

@keyframes dsge-particles {
	from { background-position: 0 0, 30px 50px, 80px 20px, 10px 90px, 60px 40px; }
	to { background-position: 0 -280px, 30px -230px, 80px -260px, 10px -190px, 60px -240px; }
}

/* —— Bokeh —— */
.dsge-layer--bokeh {
	--dsge-duration: 16s;
	--dsge-easing: ease-in-out;
	--dsge-direction: alternate;
	background-image:
		radial-gradient(circle 28px at 20% 30%, rgba(255, 180, 120, calc(0.22 * var(--dsge-i))), transparent 70%),
		radial-gradient(circle 40px at 70% 50%, rgba(120, 180, 255, calc(0.18 * var(--dsge-i))), transparent 70%),
		radial-gradient(circle 22px at 50% 75%, rgba(255, 120, 180, calc(0.16 * var(--dsge-i))), transparent 70%),
		radial-gradient(circle 34px at 85% 20%, rgba(180, 255, 200, calc(0.14 * var(--dsge-i))), transparent 70%);
	mix-blend-mode: screen;
	animation-name: dsge-bokeh;
}

@keyframes dsge-bokeh {
	from { transform: scale(1); opacity: calc(0.8 * var(--dsge-opacity, 1)); }
	to { transform: scale(1.08); opacity: var(--dsge-opacity, 1); }
}

/* —— Scanlines / CRT / VHS —— */
.dsge-layer--scanlines {
	background: repeating-linear-gradient(
		0deg,
		transparent,
		transparent 2px,
		rgba(0, 0, 0, calc(0.22 * var(--dsge-i))) 2px,
		rgba(0, 0, 0, calc(0.22 * var(--dsge-i))) 3px
	);
}

.dsge-layer--crt {
	background:
		repeating-linear-gradient(
			0deg,
			transparent,
			transparent 2px,
			rgba(0, 0, 0, calc(0.18 * var(--dsge-i))) 2px,
			rgba(0, 0, 0, calc(0.18 * var(--dsge-i))) 3px
		),
		radial-gradient(ellipse at center, transparent 55%, rgba(0, 0, 0, calc(0.45 * var(--dsge-i))) 100%);
	box-shadow: inset 0 0 80px rgba(0, 0, 0, calc(0.35 * var(--dsge-i)));
}

.dsge-layer--vhs {
	--dsge-duration: 4s;
	--dsge-easing: steps(2, end);
	background:
		repeating-linear-gradient(
			0deg,
			transparent,
			transparent 3px,
			rgba(0, 0, 0, calc(0.12 * var(--dsge-i))) 3px,
			rgba(0, 0, 0, calc(0.12 * var(--dsge-i))) 4px
		);
	box-shadow:
		inset calc(-2px * var(--dsge-i)) 0 0 rgba(255, 0, 80, 0.25),
		inset calc(2px * var(--dsge-i)) 0 0 rgba(0, 220, 255, 0.25);
	animation-name: dsge-vhs;
}

@keyframes dsge-vhs {
	0%, 100% { transform: translateY(0); }
	50% { transform: translateY(1px); }
}

/* —— Glitch —— */
.dsge-layer--glitch {
	--dsge-duration: 2.4s;
	--dsge-easing: steps(1, end);
	background:
		linear-gradient(90deg, transparent 0%, rgba(0, 255, 255, calc(0.15 * var(--dsge-i))) 2%, transparent 4%),
		linear-gradient(90deg, transparent 40%, rgba(255, 0, 80, calc(0.12 * var(--dsge-i))) 42%, transparent 44%);
	mix-blend-mode: screen;
	animation-name: dsge-glitch;
}

@keyframes dsge-glitch {
	0%, 90%, 100% { opacity: 0; transform: translate(0); }
	91% { opacity: var(--dsge-opacity, 1); transform: translate(-3px, 1px); }
	93% { opacity: var(--dsge-opacity, 1); transform: translate(4px, -1px); }
	95% { opacity: calc(0.6 * var(--dsge-opacity, 1)); transform: translate(-2px, 2px); }
	97% { opacity: var(--dsge-opacity, 1); transform: translate(1px, 0); }
}

/* —— Hologram —— */
.dsge-layer--holo {
	--dsge-duration: 3s;
	background:
		repeating-linear-gradient(
			0deg,
			rgba(0, 255, 200, calc(0.06 * var(--dsge-i))),
			rgba(0, 255, 200, calc(0.06 * var(--dsge-i))) 1px,
			transparent 1px,
			transparent 4px
		),
		linear-gradient(180deg, rgba(80, 255, 220, calc(0.08 * var(--dsge-i))), transparent 40%, rgba(120, 80, 255, calc(0.1 * var(--dsge-i))));
	mix-blend-mode: screen;
	animation-name: dsge-holo;
}

@keyframes dsge-holo {
	from { background-position: 0 0, 0 0; }
	to { background-position: 0 40px, 0 0; }
}

/* —— Neon —— */
.dsge-layer--neon {
	--dsge-duration: 3.5s;
	--dsge-easing: ease-in-out;
	--dsge-direction: alternate;
	box-shadow:
		inset 0 0 60px rgba(255, 0, 128, calc(0.25 * var(--dsge-i))),
		inset 0 0 120px rgba(0, 200, 255, calc(0.2 * var(--dsge-i)));
	animation-name: dsge-neon;
}

@keyframes dsge-neon {
	from { opacity: calc(0.7 * var(--dsge-opacity, 1)); }
	to { opacity: var(--dsge-opacity, 1); }
}

/* —— Letterbox —— */
.dsge-layer--letterbox,
.dsge-layer--letterbox-wide {
	background:
		linear-gradient(#000, #000) top / 100% calc(8% * var(--dsge-i) / 0.7) no-repeat,
		linear-gradient(#000, #000) bottom / 100% calc(8% * var(--dsge-i) / 0.7) no-repeat;
}

.dsge-layer--letterbox-wide {
	background:
		linear-gradient(#000, #000) top / 100% calc(14% * var(--dsge-i) / 0.7) no-repeat,
		linear-gradient(#000, #000) bottom / 100% calc(14% * var(--dsge-i) / 0.7) no-repeat;
}

/* —— Frost —— */
.dsge-layer--frost {
	backdrop-filter: blur(calc(1.2px * var(--dsge-i)));
	-webkit-backdrop-filter: blur(calc(1.2px * var(--dsge-i)));
	background: rgba(255, 255, 255, calc(0.04 * var(--dsge-i)));
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
	.dsge-layer {
		animation: none !important;
	}
}
