/* Static grain: one fractal-noise tile, jittered in four steps. */

:root {
	--mf-crt-noise-opacity: 0.035;
	--mf-crt-noise-opacity-peak: 0.09;
	--mf-crt-noise-speed: 0.25s;

	/* The furthest any step moves the tile. The layer is oversized by this much, so
	   the jitter never pulls an edge into view. */
	--mf-crt-noise-travel: 60px;
}

/* The jitter is a transform, not a background-position: this layer covers the whole
   viewport, and a paint-triggering property here repaints all of it four times a
   second, forever. Translating an oversized tile is the same picture on the compositor. */
.mf-crt-noise {
	inset: calc(-1 * var(--mf-crt-noise-travel));
	opacity: var(--mf-crt-noise-opacity);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
	background-repeat: repeat;
	animation: mf-crt-noise var(--mf-crt-noise-speed) steps(4) infinite;
	will-change: transform;
}

@keyframes mf-crt-noise {
	0% {
		transform: translate3d(0, 0, 0);
	}

	25% {
		transform: translate3d(50px, 50px, 0);
	}

	50% {
		transform: translate3d(-50px, 20px, 0);
	}

	75% {
		transform: translate3d(30px, -30px, 0);
	}

	100% {
		transform: translate3d(0, 0, 0);
	}
}

/* The grain stays, its jitter does not. */
@media (prefers-reduced-motion: reduce) {
	.mf-crt-noise {
		animation: none !important;
		will-change: auto;
	}
}
