/* DEAD AIR chassis: the dial (BRIEF §2.1, D-014..D-016).
   Structure only. Every colour, shadow, texture, radius and easing comes from the --st-*
   tokens, which the generated dial CSS (scripts/partials/dial.mjs) sets on .dial__skin
   per station. Fallback first: a fixed band of links reading 88.7 on the first skin. */

@layer chassis {
	.dial {
		container-name: dial;
		position: fixed;
		inset-inline: 0;
		inset-block-end: 0;
		z-index: var(--z-dial);
		block-size: var(--dial-space);
	}

	.dial__skin {
		block-size: 100%;
		display: grid;
		grid-template-columns: var(--dial-readout-w) minmax(0, 1fr);
		padding-inline-start: var(--sp-4);
		padding-block-end: env(safe-area-inset-bottom, 0px);
		color: var(--st-ink);
		background: var(--st-texture, none), var(--st-bg);
		border-block-start: 1px solid
			color-mix(in oklch, var(--st-ink) 30%, transparent);
		font-family: var(--font-ui);
		line-height: 1;
	}

	/* Readout: frequency, unit and the station's name in its own display face. */
	.dial__readout {
		display: grid;
		grid-template-columns: auto 1fr;
		grid-template-areas:
			"freq unit"
			"now now";
		align-content: center;
		align-items: baseline;
		gap: var(--sp-1) var(--sp-2);
		min-inline-size: 0;
		padding-inline-end: var(--sp-4);
		border-inline-end: 1px solid
			color-mix(in oklch, var(--st-ink) 22%, transparent);
		font-family: var(--font-mono);
	}

	/* Always 5 characters (" 88.7"): the point stays put, like an LCD. */
	.dial__freq {
		grid-area: freq;
		min-inline-size: 5ch;
		white-space: pre;
		font-size: 1.75rem;
		font-weight: 700;
		letter-spacing: -0.03em;
		font-variant-numeric: tabular-nums;
		color: var(--st-accent);
		text-shadow: var(--st-shadow);
	}

	.dial__unit {
		grid-area: unit;
		font-size: 0.6875rem;
		font-weight: 500;
		letter-spacing: 0.08em;
		color: var(--st-dim);
	}

	.dial__now {
		grid-area: now;
		block-size: 1.15em;
		overflow: hidden;
		font-family: var(--st-font-display);
		font-size: 0.9375rem;
		line-height: 1.15;
		white-space: nowrap;
		text-overflow: ellipsis;
	}

	/* The ruler. The track is the size container, so cqi maps 0–100 onto the band. */
	.dial__track {
		position: relative;
		container-type: inline-size;
		/* The end gutter is wider: Sign-Off's label centres on 107.7, near the band's end. */
		margin-inline: var(--dial-gutter) calc(var(--dial-gutter) + var(--sp-8));
	}

	/* Ticks hang below the line, numbers sit above it: they never touch. */
	.dial__scale {
		position: absolute;
		inset-inline-start: 0;
		inset-block-start: calc(50% - 0.5px);
		inline-size: calc(100% + 1px);
		block-size: 0.625rem;
		color: var(--st-dim);
		background:
			linear-gradient(currentColor 0 0) 0 0 / 100% 1px,
			repeating-linear-gradient(
				to right,
				currentColor 0 1px,
				transparent 0 20cqi
			)
			0 0 / 100% 100%,
			repeating-linear-gradient(
				to right,
				currentColor 0 1px,
				transparent 0 5cqi
			)
			0 0 / 100% 50%,
			repeating-linear-gradient(
				to right,
				currentColor 0 1px,
				transparent 0 2.5cqi
			)
			0 0 / 100% 25%;
		background-repeat: no-repeat;
	}

	/* The build puts each number on the side of its tick the needle never stops on. */
	.dial__scale > span {
		position: absolute;
		inset-block-end: 100%;
		inset-inline-start: calc(
			(var(--f) - var(--band-min)) /
			var(--band-span) *
			100cqi +
			4px
		);
		font: 500 0.6875rem / 1 var(--font-mono);
	}

	.dial__scale > [data-end] {
		translate: calc(-100% - 8px) 0;
	}

	.dial__stations {
		position: absolute;
		inset: calc(var(--focus-width) + 2px) 0;
		z-index: 1;
		padding: 0;
		list-style: none;
	}

	/* Each marker sits at its frequency on a zero-width column; the link centres on it.
	   No transforms on markers: anchored labels must follow them in every engine. */
	.dial__stations > li {
		position: absolute;
		inset-block: 0;
		inset-inline-start: calc(
			(var(--f) - var(--band-min)) /
			var(--band-span) *
			100%
		);
		inline-size: 0;
		display: flex;
		justify-content: center;
		align-items: flex-start;
	}

	.dial__stations > li:nth-child(even) {
		align-items: flex-end;
	}

	.dial__marker {
		--lit: 0;
		flex: none;
		display: flex;
		flex-direction: column-reverse;
		align-items: center;
		gap: 2px;
		block-size: 50%;
		min-inline-size: var(--sp-6);
		padding: 2px var(--sp-1) 0;
		color: color-mix(
			in oklch,
			var(--st-ink),
			var(--st-accent) calc(var(--lit) * 100%)
		);
		text-decoration: none;
		white-space: nowrap;
		border-radius: min(var(--st-radius), 0.5rem);
	}

	.dial__stations > li:nth-child(even) .dial__marker {
		flex-direction: column;
		padding-block: 0 2px;
	}

	.dial__marker[aria-current] {
		--lit: 1;
	}

	/* The pointer from the label down (or up) to the scale. */
	.dial__marker::before {
		content: "";
		flex: 1;
		inline-size: 1px;
		background: currentColor;
		scale: calc(1 + var(--lit) * 2) 1;
	}

	@media (prefers-reduced-motion: no-preference) {
		.dial__marker::before {
			transition: scale var(--st-dur) var(--st-ease);
		}
	}

	.dial__marker:hover::before {
		scale: 3 1;
	}

	.dial__marker:focus-visible {
		outline: var(--focus-width) solid var(--st-accent);
		outline-offset: 1px;
	}

	.dial__label {
		display: flex;
		align-items: baseline;
		gap: 0.4em;
		padding-block-end: 4px;
		background:
			linear-gradient(currentColor 0 0) 50% 100% / calc(var(--lit) * 100%) 2px
			no-repeat;
	}

	.dial__name {
		font-size: 0.8125rem;
		font-weight: 600;
		letter-spacing: 0.01em;
	}

	.dial__mhz {
		font-family: var(--font-mono);
		font-size: 0.6875rem;
		font-weight: 500;
		color: var(--st-dim);
	}

	.dial__marker[aria-current] .dial__mhz {
		color: inherit;
	}

	.dial__needle {
		position: absolute;
		inset-block-start: calc(50% - 0.625rem);
		inset-inline-start: -1px;
		inline-size: 2px;
		block-size: 1.25rem;
		background: var(--st-accent);
		box-shadow: var(--st-shadow);
		border-radius: 1px;
		translate: calc((var(--tune) - var(--band-min)) / var(--band-span) * 100cqi)
			0;
		pointer-events: none;
	}

	/* Dead mode (404): the needle rests at the bottom stop, unlit. */
	.dial[data-mode="dead"] .dial__needle {
		opacity: 0.5;
	}

	.dial__keys {
		position: absolute;
		inset-block-end: 100%;
		inset-inline-start: var(--sp-4);
		padding: 2px var(--sp-2);
		font: 500 0.6875rem / 1.4 var(--font-mono);
		color: var(--st-ink);
		background: var(--st-bg);
		border: 1px solid color-mix(in oklch, var(--st-ink) 30%, transparent);
		border-block-end: 0;
		opacity: 0;
		pointer-events: none;

		& kbd {
			padding-inline: 0.35em;
			font: inherit;
			font-weight: 700;
			border: 1px solid color-mix(in oklch, currentColor 45%, transparent);
			border-block-end-width: 2px;
			border-radius: 2px;
		}
	}

	.dial:focus-within .dial__keys {
		opacity: 1;
	}

	@media (hover: hover) {
		.dial:hover .dial__keys {
			opacity: 1;
		}
	}

	/* Station labels, fallback (D-016): the tagline from data-label, shown on hover/focus.
	   Empty alt text: the link's own name already says everything essential. */
	.dial__marker::after {
		content: attr(data-label);
		/* biome-ignore lint/suspicious/noDuplicateProperties: engines without alt text keep the line above */
		content: attr(data-label) / "";
		position: absolute;
		inset-block-end: calc(100% + var(--sp-2));
		inset-inline-start: 50%;
		translate: -50% 0;
		inline-size: max-content;
		max-inline-size: 28ch;
		padding: var(--sp-2) var(--sp-3);
		font: 500 0.8125rem / 1.35 var(--font-ui);
		white-space: normal;
		color: var(--st-ink);
		background: var(--st-bg);
		border: 1px solid color-mix(in oklch, var(--st-ink) 35%, transparent);
		border-radius: min(var(--st-radius), 0.5rem);
		box-shadow: var(--st-shadow);
		opacity: 0;
		visibility: hidden;
		pointer-events: none;
		transition:
			opacity var(--st-dur) var(--st-ease),
			visibility 0s linear var(--st-dur);
	}

	.dial__stations > li:nth-child(-n + 2) .dial__marker::after {
		inset-inline-start: 0;
		translate: none;
	}

	.dial__stations > li:nth-last-child(-n + 2) .dial__marker::after {
		inset-inline: auto 0;
		translate: none;
	}

	.dial__marker:is(:hover, :focus-visible)::after {
		opacity: 1;
		visibility: visible;
		transition-delay: 0s;
	}

	/* Station labels, enhanced (D-016): hint popovers via interest invokers, anchored to the
	   marker's full-height column so the label clears the dial. */
	/* biome-ignore lint/correctness/noUnknownPseudoClass: interest invokers (Chromium 149+), D-016 */
	@supports selector(:interest-source) {
		.dial__marker::after {
			content: none;
		}

		.dial__stations > li {
			anchor-name: --dial-marker;
			anchor-scope: --dial-marker;
		}

		.dial__hint {
			position-anchor: --dial-marker;
			position-area: top;
			position-try-fallbacks: flip-block;
			justify-self: anchor-center;
			inset: auto;
			margin: 0 var(--sp-2) var(--sp-2);
			inline-size: max-content;
			max-inline-size: 28ch;
			padding: var(--sp-2) var(--sp-3);
			font: 500 0.8125rem / 1.35 var(--font-ui);
			color: var(--st-ink);
			background: var(--st-bg);
			border: 1px solid color-mix(in oklch, var(--st-ink) 35%, transparent);
			border-radius: min(var(--st-radius), 0.5rem);
			box-shadow: var(--st-shadow);
		}

		/* Band ends open inward, like the fallback. */
		.dial__stations > li:nth-child(-n + 2) .dial__hint {
			position-area: top span-right;
			justify-self: start;
			margin-inline: 0;
		}

		.dial__stations > li:nth-last-child(-n + 2) .dial__hint {
			position-area: top span-left;
			justify-self: end;
			margin-inline: 0;
		}
	}

	/* Scroll-driven readout (D-014): --freq is a registered <integer> animated by the
	   generated segments; printed as MHz + tenth. Same gate as the generated CSS. */
	@supports (animation-timeline: view()) and
		(timeline-scope: --x) and
		(counter-reset: n round(down, 1.5, 1)) {
		/* MHz prints 3 wide, so 99.9 → 100.0 moves nothing (CLS 0). */
		@counter-style dial-mhz {
			system: extends decimal;
			pad: 3 "\2007";
		}

		@media (prefers-reduced-motion: no-preference) {
			.dial[data-mode="scan"] .dial__freq {
				/* Rounded first: WebKit leaves an animated <integer> fractional (896.36), and
				   mod(899.6, 10) would otherwise print "89.10". */
				--freq-whole: round(var(--freq), 1);
			}

			.dial[data-mode="scan"] .dial__freq::before {
				counter-reset: dial-w round(down, calc(var(--freq-whole) / 10), 1)
					dial-t mod(var(--freq-whole), 10);
				content: counter(dial-w, dial-mhz) "." counter(dial-t);
			}

			.dial[data-mode="scan"] .dial__freq > span {
				display: none;
			}
		}
	}

	/* Narrow: readout becomes a strip on top, markers show their frequency. The name stays in
	   the link's accessible name (visually hidden), and the current one shows in the readout. */
	@media (width < 54rem) {
		.dial__skin {
			grid-template-columns: minmax(0, 1fr);
			grid-template-rows: 1.5rem minmax(0, 1fr);
			padding-inline-start: 0;
		}

		.dial__readout {
			grid-template-columns: auto auto minmax(0, 1fr);
			grid-template-areas: "freq unit now";
			align-content: center;
			gap: var(--sp-2);
			padding-inline: var(--sp-4);
			border-inline-end: 0;
			border-block-end: 1px solid
				color-mix(in oklch, var(--st-ink) 18%, transparent);
		}

		.dial__freq {
			font-size: 1rem;
		}

		.dial__now {
			font-size: 0.875rem;
		}

		.dial__track {
			margin-inline: var(--dial-gutter);
		}

		.dial__scale {
			inset-block-start: 0.125rem;
			block-size: 1rem;
		}

		.dial__scale > span {
			display: none;
		}

		.dial__stations > li,
		.dial__stations > li:nth-child(even) {
			align-items: flex-end;
		}

		.dial__marker,
		.dial__stations > li:nth-child(even) .dial__marker {
			flex-direction: column;
			block-size: calc(100% - 0.375rem);
			padding: 0 2px var(--sp-1);
		}

		.dial__name {
			position: absolute;
			inline-size: 1px;
			block-size: 1px;
			overflow: hidden;
			clip-path: inset(50%);
			white-space: nowrap;
		}

		.dial__mhz {
			color: inherit;
		}

		.dial__needle {
			inset-block-start: 0;
			block-size: 1.25rem;
		}

		.dial__marker::after {
			inset-block-end: calc(100% + 3rem);
		}

		.dial__hint {
			margin-block-end: 3rem;
		}

		/* An open label covers the legend here. */
		.dial:has(:popover-open, .dial__marker:is(:hover, :focus-visible))
			.dial__keys {
			opacity: 0;
		}
	}

	/* 320px (WCAG reflow): Open Water and Small Hours are 2.8 MHz apart; keep their targets apart. */
	@media (width < 22rem) {
		.dial__track {
			margin-inline: var(--sp-4);
		}

		.dial__mhz {
			letter-spacing: -0.04em;
		}
	}

	/* Very short viewports: the dial moves to the top; labels open below it. */
	@media (max-height: 30rem) {
		.dial {
			inset-block: 0 auto;
			block-size: var(--dial-h);
		}

		.dial__skin {
			padding-block-end: 0;
			border-block-start: 0;
			border-block-end: 1px solid
				color-mix(in oklch, var(--st-ink) 30%, transparent);
		}

		.dial__marker::after {
			inset-block: calc(100% + var(--sp-2)) auto;
		}

		.dial__keys {
			inset-block: 100% auto;
			border-block: 0 1px solid
				color-mix(in oklch, var(--st-ink) 30%, transparent);
		}
	}

	/* Home: dial markers are in-page links; tune to them with a sweep (D-019). */
	@media (prefers-reduced-motion: no-preference) {
		html:has(> body[data-page="home"]) {
			scroll-behavior: smooth;
		}
	}
}
