:root {
	--font-mono: Consolas, Inconsolata, Monaco, monospace;

	/* Follow the system light/dark preference. */
	color-scheme: light dark;
}

body {
	font: 100%/1.5 system-ui;
	margin: 0;
	/* Column layout so the fields can flex to fill the viewport below the header. */
	min-height: 100vh;
	display: grid;
	grid-template-columns: minmax(7em, 11em) 1fr;

	> * {
		grid-column: 1 / -1;
	}
}

button, input, select {
	font: inherit;
}

/* Title block and the grid form sit side by side when there's room; the form
   drops below the titles on narrow viewports. run/view-controls always span a
   full row of their own. */
header {
	display: flex;
	flex-wrap: wrap;
	align-items: start;
	gap: 0.5em 2em;
	padding: 1em 1.5em 0;
}

header hgroup {
	flex: 1 1 22em;
	min-width: min(100%, 22em);
	margin: 0;
}

header .run-controls,
header .view-controls {
	flex-basis: 100%;
}

header h1 {
	margin: 0;
	font-size: 1.5rem;
}

.intro {
	color: light-dark(hsl(0 0% 35%), hsl(0 0% 65%));
	font-size: 0.9rem;
}

.run-controls {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75em;
}

.run-controls progress {
	flex: 1;
	height: 1em;
	max-width: 20em;
}

/* Reserve width so the trailing Pause/Resume/Done button doesn't shift as the
   counts and timer change. */
.run-controls #status {
	min-width: 20em;
	font-variant-numeric: tabular-nums;
}

.view-controls {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25em 1.5em;
	margin-top: 0.6em;
	font: 0.85rem var(--font-mono);
}

/* Grid setup. Translucent panel sized to its content so it sits compactly rather
   than spanning the viewport. Each field is a column — a small label over a larger
   value. System font; monospace is reserved for the data (stats etc.). */
.range-form {
	margin: 0.6em 0;
	display: flex;
	flex-wrap: wrap;
	align-items: end;
	gap: 0.5em 1.25em;
	/* Translucent panel around the whole form. */
	padding-block: 0.5em 0.7em;
	padding-inline: 1em;
	border-radius: 0.2em;
	background: light-dark(hsl(220 10% 90% / 0.85), hsl(220 15% 13% / 0.85));

	/* Each fieldset is a bordered group of one axis's fields, labelled by its legend. */
	fieldset {
		display: flex;
		flex-wrap: wrap;
		align-items: baseline;
		gap: 0.25em 0.8em;
		margin: 0;
		padding: 0.15em 0.7em 0.4em;
		border: 1px solid light-dark(hsl(220 10% 78%), hsl(220 12% 34%));
		border-radius: 0.2em;
	}

	legend {
		padding-inline: 0.3em;
		font-weight: bold;
		color: light-dark(hsl(0 0% 40%), hsl(0 0% 62%));
	}

	/* One field: a small label above a larger value. */
	label {
		display: flex;
		flex-flow: column;
		align-items: baseline;
		gap: 0.3em;
		font-size: 80%;
	}

	input {
		min-width: 3em;
		field-sizing: content;
		font-size: 125%;
	}

	/* The grid size lives inside the Go button, under its label. */
	button {
		display: flex;
		flex-flow: column;
		align-items: center;
		gap: 0.1em;
		padding: 0.25em 0.7em;
		line-height: 1.15;
	}

	.colors-count {
		font-size: 75%;
		font-weight: normal;
		color: light-dark(hsl(0 0% 45%), hsl(0 0% 58%));
		font-variant-numeric: tabular-nums;
	}
}

/* ── Inspector: all GMAs for the hovered patch ─────────────────────────────── */

.inspector {
	position: sticky;
	top: 0;
	z-index: 1;
	display: grid;
	grid-template-columns: subgrid;

	align-items: center;
	gap: 0.5em 2em;
	margin-block: 1em;
	padding: 0.5em 1.5em;
	background: light-dark(hsl(0 0% 100% / 0.85), hsl(220 15% 13% / 0.85));
	backdrop-filter: blur(8px);
	border-block: 1px solid light-dark(hsl(0 0% 88%), hsl(0 0% 25%));
	font: 0.8rem var(--font-mono);

	.coords {
		font-weight: bold;

		&:empty {
			opacity: .5;
			font-style: italic;

			&::before {
				content: "Hover a patch to inspect it";
				text-wrap: balance;
			}
		}
	}

	.swatch {
		width: 100%;
		height: 2em;
		border-radius: 3px;
		background: repeating-linear-gradient(-45deg, transparent 0 3px, rgb(0 0 0 / 0.1) 0 5px);
	}
}

.inspect-gmas {
	flex: 1;
	display: flex;
	flex-wrap: wrap;
	gap: 0.4em 0.9em;
}


.inspect-gma {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	flex: 1;
	gap: 0.35em;

	.gname {
		color: light-dark(hsl(0 0% 35%), hsl(0 0% 65%));
	}

	.gerr {
		font-variant-numeric: tabular-nums;
		font-weight: bold;
	}
}

/* ── GMA rows ──────────────────────────────────────────────────────────────── */

/* Fills the viewport below the header (body is a flex column). Rows share the
   height equally (1fr) but never shrink below the gutter's content, so colors
   are as large as the space allows and the page scrolls only when it must. */
.fields {
	grid-column: 1 / -1;
	flex: 1;
	display: grid;
	grid-template-columns: subgrid;
	grid-auto-rows: minmax(min-content, 1fr);
	gap: 0.6em 1em;
	align-items: stretch;
	padding: 0 1.5em 1.5em;
}

.gutter {
	font: 0.78rem/1.3 var(--font-mono);
	border-inline-start: 3px solid transparent;
	padding-inline-start: 0.5em;
}

.gutter h2 {
	margin: 0 0 0.2em;
	font-size: 0.9rem;
}

.gutter .stats {
	display: grid;
	grid-template-columns: auto auto;
	gap: 0 0.6em;
	margin: 0;
}

.gutter .stats div {
	display: contents;
}

.gutter .stats dt {
	color: light-dark(hsl(0 0% 45%), hsl(0 0% 55%));
}

.gutter .stats dd {
	margin: 0;
	text-align: end;
	font-variant-numeric: tabular-nums;
}

/* Best (lowest) / worst (highest) value in each stat column, highlighted
   independently per metric — regardless of the active sort. */
.gutter .stats dd.best {
	color: var(--color-green-50, light-dark(hsl(140 60% 32%), hsl(140 55% 62%)));
	font-weight: bold;
}

.gutter .stats dd.worst {
	color: var(--color-red-40, light-dark(hsl(0 65% 40%), hsl(0 80% 70%)));
	font-weight: bold;
}

/* Slowdown vs the fastest GMA, on its own line so it doesn't crowd the gutter. */
.gutter .slower {
	display: block;
	font-size: 0.85em;
	font-weight: bold;
	color: var(--color-red-40, light-dark(hsl(0 60% 40%), hsl(0 80% 68%)));
}

/* Lowest / highest average Error across GMAs. */
.gutter.best {
	border-inline-start-color: var(--color-green-50, light-dark(hsl(140 55% 35%), hsl(140 55% 60%)));
}

.gutter.worst {
	border-inline-start-color: var(--color-red-40, light-dark(hsl(0 60% 45%), hsl(0 80% 68%)));
}

.field-wrap {
	min-width: 0;
	height: 100%;
}

/* The table fills its row; rows divide that height, so the field grows with the
   available space and densifies (thinner rows) as the sweep adds more. */
.field {
	table-layout: fixed;
	width: 100%;
	height: 100%;
	border-collapse: collapse;
	/* Patches are unit-less colored cells; isolate layout/paint per field. */
	contain: content;
}

.field td {
	padding: 0;
	border: 0;
}

/* NOTE: at full resolution (~36k cells/field) add content-visibility tuning here
   to skip offscreen rows — irrelevant at the coarse MVP grid. */
