/* DEAD AIR chassis: static bands between stations (BRIEF §2.2).
   Each band knows its neighbours (data-from / data-to, and the --from-* / --to-* palette and
   its own seeded --wave, set by scripts/partials/static.mjs from the dial's skin source), so
   stations can shape their edges later. Band N also names the view timeline --bN the dial
   follows; .static__mid marks its midpoint for dial.js. */

@layer chassis {
	/* Home windows: skipped until they approach, so their fonts and paint wait too (BRIEF §5.2).
	   `auto` remembers the real height once rendered, so Open Water's extra length sticks.
	   The intrinsic size is the content box, so a never-rendered window gets none and the
	   reset layer's 100svh border-box minimum sizes it, whatever its padding (P1-10 N1). */
	#band > [data-station] {
		content-visibility: auto;
		contain-intrinsic-size: auto none;
	}

	.static {
		position: relative;
		isolation: isolate;
		overflow: clip;
		block-size: var(--static-h);
		content-visibility: auto;
		contain-intrinsic-size: auto var(--static-h);
		background: linear-gradient(
			var(--from-bg),
			color-mix(in oklch, var(--from-bg), var(--to-bg)),
			var(--to-bg)
		);
		pointer-events: none;
	}

	.static > *,
	.static__noise > *,
	.static::after {
		position: absolute;
	}

	/* Noise fades in from both edges, so the band starts and ends as the neighbours' paper. */
	.static__noise {
		inset: 0;
		mask: linear-gradient(transparent, #000 30%, #000 70%, transparent);
	}

	/* Light pairs: grain darkens into the paper rather than greying it. */
	.static[data-tone="light"] .static__noise {
		mix-blend-mode: multiply;
	}

	/* The two inks interlaced a pixel apart: outgoing fades out as incoming fades in,
	   over an accent wash that peaks mid-band. */
	.static__smear {
		inset: 0 -8%;
		background:
			repeating-linear-gradient(
				transparent 0 1px,
				color-mix(in oklch, var(--to-ink) 26%, transparent) 1px 2px,
				transparent 2px 4px
			),
			repeating-linear-gradient(
				color-mix(in oklch, var(--from-ink) 26%, transparent) 0 1px,
				transparent 1px 4px
			),
			linear-gradient(
				transparent 20%,
				color-mix(in oklch, var(--from-accent) 28%, transparent) 45%,
				color-mix(in oklch, var(--to-accent) 28%, transparent) 55%,
				transparent 80%
			);
		background-size:
			100% 55%,
			100% 55%,
			100% 100%;
		background-repeat: no-repeat;
		background-position:
			0 100%,
			0 0,
			0 0;
		opacity: 0.6;
	}

	/* Grain (tokens.css); bleed covers the jitter. */
	.static__grain {
		inset: -3rem;
		background: var(--grain);
		opacity: 0.32;
	}

	/* Oscilloscope. The flat trace is a 2.6px line; the jagged --wave (shape(), seeded per
	   band) grows out of it by scaling, so the scrub stays on the compositor. Without shape()
	   the flat line is the trace (§5.1: plain divider). */
	.static::after,
	.static__scope,
	.static__echo {
		inset-inline: 0;
		background: linear-gradient(to right, var(--from-accent), var(--to-accent));
	}

	.static::after {
		content: "";
		inset-block-start: calc(50% - 1.3px);
		block-size: 2.6px;
	}

	.static__scope,
	.static__echo {
		display: none;
		inset-block-start: calc(50% - 4.5rem);
		block-size: 9rem;
	}

	/* A fainter echo: the trace mirrored (so its gradient runs the other way), half a step
	   over, so the line reads as noise, not a chart. */
	.static__echo {
		background-image: linear-gradient(
			to left,
			var(--from-accent),
			var(--to-accent)
		);
		transform: scale(-1, 0.7) translateX(1%);
		opacity: 0.45;
	}

	.static__mid {
		inset: 50% 0 0;
	}

	@supports (clip-path: shape(from 0 0, line to 1px 1px)) {
		.static__scope,
		.static__echo {
			display: block;
			clip-path: var(--wave);
		}

		.static::after {
			opacity: 0;
		}
	}

	/* Scrubbed by the band's own view progress: flat → noisy → flat, grain swells, smear slides. */
	@supports (animation-timeline: view()) {
		@media (prefers-reduced-motion: no-preference) {
			.static__scope,
			.static__echo,
			.static::after,
			.static__smear {
				animation: var(--a) linear both;
				animation-timeline: view();
			}

			.static__scope,
			.static__echo {
				--a: static-scope;
			}

			.static::after {
				--a: static-flat;
			}

			.static__smear {
				--a: static-smear;
			}

			.static__grain {
				animation:
					static-grain linear both,
					static-jitter step-end both;
				animation-timeline: view(), view();
			}
		}

		@keyframes static-scope {
			0%,
			20%,
			80%,
			100% {
				scale: 1 0.02;
			}

			50% {
				scale: 1;
			}
		}

		@keyframes static-flat {
			0%,
			25%,
			75%,
			100% {
				opacity: 1;
			}

			40%,
			60% {
				opacity: 0;
			}
		}

		@keyframes static-grain {
			0%,
			100% {
				opacity: 0.08;
			}

			50% {
				opacity: 0.6;
			}
		}

		@keyframes static-jitter {
			0%,
			100% {
				translate: 0;
			}
			12% {
				translate: -37px 21px;
			}
			25% {
				translate: 33px -12px;
			}
			37% {
				translate: -9px -38px;
			}
			50% {
				translate: 41px 23px;
			}
			62% {
				translate: -34px -27px;
			}
			75% {
				translate: 18px 39px;
			}
			87% {
				translate: -25px 6px;
			}
		}

		@keyframes static-smear {
			from {
				translate: -6% 0;
				opacity: 0.15;
			}

			50% {
				opacity: 0.75;
			}

			to {
				translate: 6% 0;
				opacity: 0.15;
			}
		}
	}

	/* Reduced motion: the static becomes an 8px divider in the two stations' accents. */
	@media (prefers-reduced-motion: reduce) {
		.static {
			block-size: var(--static-rm-h);
			contain-intrinsic-size: auto var(--static-rm-h);
			background: linear-gradient(
				to right,
				var(--from-accent),
				var(--to-accent)
			);
		}

		.static > :not(.static__mid),
		.static::after {
			display: none;
		}
	}
}
