/*
 * Shared skin for the audio-sync harness.
 *
 * Restrained on purpose: flat panels, hairline rules, one accent. The Wii U
 * skin proper will replace all of this once the theme pack is wired up — this
 * exists so the sync can be stood up in a room and listened to, and it should
 * not pretend to be the finished article.
 *
 * Sizes are in --unit, which is 1% of a 16:9 scene, so the television page
 * holds its proportions from 720p to 4K and only the pixel count changes. The
 * phone overrides it to something sensible for a hand.
 */

:root {
	--unit: min(1vw, 1.7778vh);
	--ui-scale: 1;
	--text-scale: 1;

	--ink: #e8e9ec;
	--ink-dim: #8b8f98;
	--ink-faint: #5a5e66;
	--ground: #101114;
	--panel: #17181c;
	--line: #24262c;
	--accent: #5ac8fa;
	--good: #63d68b;
	--warn: #e8b84b;
	--bad: #e8695b;

	/*
	 * Control surfaces, as tokens.
	 *
	 * These were literal hex values until the Wii U skin arrived, at which
	 * point every button on the setup guide stayed charcoal on a white page.
	 * A theme that can only repaint the text is not a theme; anything a
	 * component paints itself has to be nameable from outside it.
	 */
	--btn: #1e2026;
	--btn-hover: #262932;
	--btn-edge-hover: #333743;
	--btn-active: #1a1c22;
	--btn-primary: #1d3d4d;
	--btn-primary-edge: #2b5d74;
	--btn-primary-hover: #234a5e;
	--btn-primary-ink: var(--ink);
	--well: #0c0d10;
	--rule: #1c1e24;
	--scrim: rgba(10, 11, 14, 0.94);
}

* { box-sizing: border-box; }

/*
 * `hidden` has to win, everywhere.
 *
 * The browser's own [hidden] rule is the weakest selector on the page, so any
 * element given a display of its own — #gate's display:flex, for one — simply
 * ignores the attribute. The failure is silent: the script sets hidden, nothing
 * throws, and the overlay stays exactly where it was. "Start the television"
 * did nothing but that, and the console had nothing to say about it.
 */
[hidden] { display: none !important; }

html, body {
	margin: 0;
	padding: 0;
	background: var(--ground);
	color: var(--ink);
	font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	font-variant-numeric: tabular-nums;
	-webkit-font-smoothing: antialiased;
}

h1, h2 { font-weight: 600; letter-spacing: -0.01em; margin: 0; }

.panel {
	background: var(--panel);
	border: 1px solid var(--line);
	/* 3px, not 12. A tile with a big radius reads as a bubble; this should
	   read as a panel. */
	border-radius: 3px;
}

.row { display: flex; align-items: center; justify-content: space-between; gap: 1em; }
.muted { color: var(--ink-dim); }
.faint { color: var(--ink-faint); }
.good { color: var(--good); }
.warn { color: var(--warn); }
.bad  { color: var(--bad); }

/*
 * The drifting dust behind a Wii U-style setup overlay (see js/dust.js).
 *
 * The canvas is absolutely positioned and painted first, which — per the CSS
 * painting order — would otherwise land it ON TOP of any plain in-flow
 * sibling. Rather than hand-positioning every overlay's own content, every
 * sibling after the canvas gets lifted into its own stacking context so it
 * always wins regardless of the overlay markup it is dropped into.
 */
.dust-canvas { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.dust-canvas ~ * { position: relative; z-index: 1; }

.dot {
	display: inline-block;
	width: 0.5em; height: 0.5em;
	border-radius: 50%;
	background: var(--ink-faint);
	vertical-align: baseline;
}
.dot.on { background: var(--good); }
.dot.off { background: var(--bad); }
.dot.wait { background: var(--warn); }

/* A number that is being watched rather than read: fixed width so it does not
   shuffle the layout every time it ticks. */
.metric { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }

button {
	font: inherit;
	color: var(--ink);
	background: var(--btn);
	border: 1px solid var(--line);
	border-radius: 3px;
	padding: 0.6em 1.1em;
	cursor: pointer;
	transition: background 120ms linear, border-color 120ms linear;
}
button:hover:not(:disabled) { background: var(--btn-hover); border-color: var(--btn-edge-hover); }
button:active:not(:disabled) { background: var(--btn-active); }
button:disabled { opacity: 0.4; cursor: default; }
button.primary { background: var(--btn-primary); border-color: var(--btn-primary-edge); color: var(--btn-primary-ink); }
button.primary:hover:not(:disabled) { background: var(--btn-primary-hover); }

/* Focus is a first-class state here, not an afterthought: a D-pad and a
   remote have no hover, and this page is a rehearsal for both. */
button:focus-visible, [tabindex]:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

input[type=range] {
	-webkit-appearance: none;
	appearance: none;
	width: 100%;
	height: 2px;
	background: var(--line);
	border-radius: 0;
}
input[type=range]::-webkit-slider-thumb {
	-webkit-appearance: none;
	width: 22px; height: 22px;
	border-radius: 50%;
	background: var(--ink);
	border: 3px solid var(--panel);
	cursor: pointer;
}
input[type=range]::-moz-range-thumb {
	width: 22px; height: 22px;
	border-radius: 50%;
	background: var(--ink);
	border: 3px solid var(--panel);
	cursor: pointer;
}

/* The sync meter: a needle that sits centre when everything is right. It is
   the one piece of chrome here that earns its pixels, because "are we in
   time" is the whole question this page exists to answer. */
.meter {
	position: relative;
	height: 34px;
	background: var(--well);
	border: 1px solid var(--line);
	border-radius: 2px;
	overflow: hidden;
}
.meter .zero {
	position: absolute; left: 50%; top: 0; bottom: 0;
	width: 1px; background: var(--ink-faint);
}
.meter .tick {
	position: absolute; top: 0; bottom: 0; width: 1px;
	background: var(--rule);
}
.meter .needle {
	position: absolute; top: 3px; bottom: 3px;
	width: 3px; margin-left: -1.5px;
	background: var(--good);
	left: 50%;
	transition: left 140ms ease-out, background 200ms linear;
}
.meter .band {
	position: absolute; top: 0; bottom: 0;
	background: rgba(99, 214, 139, 0.10);
}
