/* =========================================================================
   Eye Shape AI — "Aperture" design system
   A dark optical instrument: iris-black ground, amber instrument light.
   ========================================================================= */

/* --- 1. Tokens --------------------------------------------------------- */

:root {
	/* Surfaces: an iris seen in a dark room. Not neutral gray. */
	--pupil: oklch(0.135 0.03 288); /* page ground        #080614 */
	--limbal: oklch(0.185 0.034 288); /* alternate band     #121021 */
	--stroma: oklch(0.235 0.034 288); /* raised panel       #1d1b2d */
	--edge: oklch(0.32 0.032 288); /* decorative hairline #323042 */
	--edge-lit: oklch(0.5 0.038 288); /* functional border   #626078 */

	/* Light: what an ophthalmoscope shines into an eye. */
	--iris: oklch(0.795 0.152 74); /* accent             #f5ab35 */
	--iris-dim: oklch(0.62 0.12 68); /* accent, receded    #b57727 */
	--iris-deep: oklch(0.42 0.09 62); /* accent, structural */

	/* Ink */
	--catch: oklch(0.975 0.006 90); /* headlines  18.7:1 on pupil */
	--sclera: oklch(0.805 0.016 288); /* body       10.9:1 on pupil */
	--haze: oklch(0.68 0.02 288); /* muted       6.9:1 on pupil */
	--alarm: oklch(0.72 0.165 30); /* error       7.6:1 on pupil */

	/* Type */
	--sans: "Archivo", ui-sans-serif, system-ui, -apple-system, sans-serif;
	--mono: "Martian Mono", ui-monospace, "SF Mono", Menlo, monospace;
	--wide: "wdth" 118;
	--narrow: "wdth" 92;

	--step-display: clamp(2.55rem, 1.35rem + 5.2vw, 5.4rem);
	--step-h2: clamp(2rem, 1.32rem + 2.7vw, 3.2rem);
	--step-h3: clamp(1.35rem, 1.14rem + 1.05vw, 1.85rem);
	--step-h4: clamp(1.1rem, 1.03rem + 0.34vw, 1.3rem);
	--step-lead: clamp(1.05rem, 0.98rem + 0.36vw, 1.25rem);
	--step-body: 1.0625rem;
	--step-small: 0.9rem;
	--step-label: 0.72rem;

	/* Space */
	--gap-band: clamp(4rem, 2rem + 8vw, 8.5rem);
	--gap-block: clamp(2rem, 1.2rem + 3vw, 3.75rem);
	--gutter: clamp(1.15rem, 0.6rem + 2.2vw, 2.5rem);
	--measure: 68ch;

	/* Motion */
	--out-quart: cubic-bezier(0.165, 0.84, 0.44, 1);
	--out-expo: cubic-bezier(0.16, 1, 0.3, 1);
	--sine: cubic-bezier(0.45, 0.05, 0.55, 0.95);
	--fast: 160ms;
	--mid: 260ms;

	/* Depth */
	--z-base: 0;
	--z-raised: 10;
	--z-sticky: 100;
	--z-nav: 200;
	--z-backdrop: 300;
	--z-modal: 400;
	--z-toast: 500;

	--radius: 4px;
	--radius-lg: 8px;
}

/* --- 2. Reset ---------------------------------------------------------- */

*,
*::before,
*::after {
	box-sizing: border-box;
}

* {
	margin: 0;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
	scroll-padding-top: 5.5rem;
}

body {
	min-height: 100vh;
	display: flex;
	flex-direction: column;
	background: var(--pupil);
	color: var(--sclera);
	font-family: var(--sans);
	font-size: var(--step-body);
	line-height: 1.65;
	font-variation-settings: "wdth" 100;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
	overflow-x: hidden;
}

img,
svg,
video {
	display: block;
	max-width: 100%;
	height: auto;
}

button,
input,
select,
textarea {
	font: inherit;
	color: inherit;
}

a {
	color: var(--iris);
	text-decoration-color: color-mix(in oklch, var(--iris) 40%, transparent);
	text-underline-offset: 0.22em;
	transition: color var(--fast) var(--out-quart);
}

a:hover {
	color: var(--catch);
	text-decoration-color: currentColor;
}

:focus-visible {
	outline: 2px solid var(--iris);
	outline-offset: 3px;
	border-radius: 2px;
}

::selection {
	background: var(--iris);
	color: var(--pupil);
}

/* --- 3. Typography ----------------------------------------------------- */

h1,
h2,
h3,
h4 {
	color: var(--catch);
	font-weight: 700;
	line-height: 1.04;
	text-wrap: balance;
}

h1,
.display {
	font-size: var(--step-display);
	font-variation-settings: var(--wide);
	font-weight: 800;
	letter-spacing: -0.035em;
}

h2 {
	font-size: var(--step-h2);
	font-variation-settings: "wdth" 110;
	letter-spacing: -0.025em;
	line-height: 1.06;
}

h3 {
	font-size: var(--step-h3);
	letter-spacing: -0.015em;
	line-height: 1.16;
}

h4 {
	font-size: var(--step-h4);
	letter-spacing: -0.005em;
	line-height: 1.25;
}

p,
li {
	text-wrap: pretty;
}

/* A heading and the paragraph under it are always one unit. */
h1 + p,
h2 + p,
h3 + p,
h4 + p {
	margin-top: 0.9rem;
}

.lead {
	font-size: var(--step-lead);
	color: var(--sclera);
	line-height: 1.6;
}

.muted {
	color: var(--haze);
}

.measure {
	max-width: var(--measure);
}

.measure-tight {
	max-width: 52ch;
}

/* Monospace data labels. Used for readouts and units, never as section
   eyebrows — the numbers are the product, the labels name them. */
.label {
	font-family: var(--mono);
	font-size: var(--step-label);
	font-weight: 500;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--haze);
	font-variation-settings: "wdth" 87.5;
}

.label--lit {
	color: var(--iris);
}

.readout {
	font-family: var(--mono);
	font-variation-settings: "wdth" 87.5;
	font-weight: 500;
	font-size: var(--step-small);
	color: var(--catch);
	letter-spacing: 0.01em;
}

/* --- 4. Layout --------------------------------------------------------- */

.wrap {
	width: 100%;
	max-width: 1240px;
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.wrap--narrow {
	max-width: 860px;
}

.band {
	padding-block: var(--gap-band);
	position: relative;
}

.band--tight {
	padding-block: var(--gap-block);
}

.band--limbal {
	background: var(--limbal);
}

.band + .band--limbal,
.band--limbal + .band {
	border-top: 1px solid var(--edge);
}

.stack > * + * {
	margin-top: var(--flow, 1.1rem);
}

main {
	flex: 1;
}

/* A hairline that carries the instrument grammar: a rule with a tick. */
.rule {
	border: 0;
	height: 1px;
	background: var(--edge);
	position: relative;
}

.rule::before {
	content: "";
	position: absolute;
	inset-block-start: -2px;
	inset-inline-start: 0;
	width: 34px;
	height: 5px;
	background: var(--iris);
}

/* --- 5. Navigation ----------------------------------------------------- */

.nav {
	position: sticky;
	top: 0;
	z-index: var(--z-nav);
	background: color-mix(in oklch, var(--pupil) 92%, transparent);
	border-bottom: 1px solid var(--edge);
	backdrop-filter: blur(14px);
	-webkit-backdrop-filter: blur(14px);
}

.nav__bar {
	display: flex;
	align-items: center;
	gap: 1.25rem;
	min-height: 4.25rem;
}

.nav__bar--centered {
	justify-content: center;
}

.brand {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	color: var(--catch);
	text-decoration: none;
	font-variation-settings: "wdth" 112;
	font-weight: 800;
	font-size: 1.0625rem;
	letter-spacing: -0.02em;
	white-space: nowrap;
}

.brand:hover {
	color: var(--catch);
}

.brand__mark {
	width: 26px;
	height: 26px;
	flex: none;
	color: var(--iris);
}

.brand em {
	font-style: normal;
	color: var(--iris);
}

.nav__links {
	display: flex;
	align-items: center;
	gap: 0.35rem;
	list-style: none;
	padding: 0;
	margin-inline-start: auto;
}

.nav__links a {
	display: block;
	padding: 0.5rem 0.75rem;
	color: var(--haze);
	font-size: var(--step-small);
	font-weight: 500;
	text-decoration: none;
	border-radius: var(--radius);
	transition: color var(--fast) var(--out-quart), background var(--fast) var(--out-quart);
}

.nav__links a:hover {
	color: var(--catch);
	background: var(--stroma);
}

.nav__toggle {
	display: none;
	margin-inline-start: auto;
	align-items: center;
	gap: 0.5rem;
	background: none;
	border: 1px solid var(--edge-lit);
	border-radius: var(--radius);
	color: var(--sclera);
	padding: 0.4rem 0.7rem;
	cursor: pointer;
	font-family: var(--mono);
	font-size: var(--step-label);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.nav__toggle:hover {
	color: var(--catch);
	border-color: var(--iris);
}

@media (max-width: 780px) {
	.js .nav__toggle {
		display: inline-flex;
	}

	/* No-JS fallback: the links drop onto their own row instead of wrapping
	   around the wordmark. */
	.nav__bar {
		flex-wrap: wrap;
		row-gap: 0;
	}

	.nav__links {
		flex-wrap: wrap;
		width: 100%;
		margin-inline-start: 0;
		padding-block-end: 0.5rem;
	}

	.js .nav__bar {
		flex-wrap: nowrap;
	}

	.js .nav__links {
		display: none;
		width: auto;
		padding-block-end: 0;
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		padding: 0.5rem var(--gutter) 1rem;
		background: var(--pupil);
		border-bottom: 1px solid var(--edge);
	}

	.js .nav__links[data-open="true"] {
		display: flex;
	}

	.js .nav__links a {
		padding: 0.75rem 0;
		border-bottom: 1px solid var(--edge);
		font-size: 1rem;
	}
}

/* --- 6. Buttons -------------------------------------------------------- */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.55rem;
	padding: 0.85rem 1.5rem;
	border: 1px solid transparent;
	border-radius: var(--radius);
	font-weight: 600;
	font-size: 0.95rem;
	letter-spacing: 0.01em;
	line-height: 1.2;
	max-width: 100%;
	min-width: 0;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: background var(--fast) var(--out-quart), color var(--fast) var(--out-quart),
		border-color var(--fast) var(--out-quart), transform var(--fast) var(--out-quart);
}

.btn:active {
	transform: translateY(1px);
}

.btn[disabled],
.btn[aria-disabled="true"] {
	cursor: not-allowed;
	opacity: 0.45;
	transform: none;
}

.btn--primary {
	background: var(--iris);
	color: var(--pupil);
	font-weight: 700;
}

.btn--primary:hover:not([disabled]) {
	background: var(--catch);
	color: var(--pupil);
}

.btn--ghost {
	background: transparent;
	border-color: var(--edge-lit);
	color: var(--sclera);
}

.btn--ghost:hover {
	border-color: var(--iris);
	color: var(--catch);
	background: var(--stroma);
}

.btn--wide {
	width: 100%;
}

.btn__arrow {
	width: 1em;
	height: 1em;
	flex: none;
	transition: transform var(--mid) var(--out-expo);
}

.btn:hover .btn__arrow {
	transform: translateX(3px);
}

/* --- 7. Hero ----------------------------------------------------------- */

.hero {
	position: relative;
	padding-block: clamp(2.5rem, 1rem + 5vw, 5.5rem) var(--gap-band);
	overflow: hidden;
}

/* Faint landmark constellation behind the hero: the 12 points the
   scanner actually reads. Decorative, never a content dependency. */
.hero::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image: radial-gradient(
		circle at 50% 42%,
		color-mix(in oklch, var(--iris) 9%, transparent),
		transparent 62%
	);
	pointer-events: none;
}

.hero__grid {
	position: relative;
	display: grid;
	gap: clamp(2rem, 1rem + 4vw, 4rem);
	align-items: center;
}

/* Grid and flex children default to min-width:auto, so one long unbroken string
   anywhere below here stretches the whole hero past the viewport. */
.hero__grid > * {
	min-width: 0;
}

@media (min-width: 900px) {
	.hero__grid {
		grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
	}
}

.hero__title {
	margin-bottom: 1.15rem;
}

.hero__sub {
	max-width: 46ch;
	margin-bottom: 2rem;
}

.hero__figure {
	display: flex;
	justify-content: center;
	order: -1;
}

@media (min-width: 900px) {
	.hero__figure {
		order: 0;
	}
}

/* --- 8. The aperture --------------------------------------------------- */

.aperture {
	width: min(132px, 40vw);
	height: auto;
	color: var(--iris);
	filter: drop-shadow(0 0 46px color-mix(in oklch, var(--iris) 22%, transparent));
}

@media (min-width: 900px) {
	.aperture {
		width: min(430px, 34vw);
	}
}

.aperture-slot {
	display: flex;
	justify-content: center;
}

.aperture-slot--compact .aperture {
	width: min(190px, 46vw);
}

.aperture__limbus {
	fill: none;
	stroke: var(--iris-dim);
	stroke-width: 1.5;
}

.aperture__ring {
	fill: none;
	stroke: var(--iris-deep);
	stroke-width: 1;
}

.aperture__fiber {
	stroke: var(--iris);
	stroke-width: 1.1;
	opacity: 0.75;
}

.aperture__blade {
	fill: none;
	stroke: var(--iris);
	stroke-width: 1;
	opacity: 0.28;
}

.aperture__tick {
	stroke: var(--edge-lit);
	stroke-width: 1.5;
}

/* Hippus: a real pupil never holds still, it drifts continuously by a few
   percent. Two layered rhythms on periods that do not divide evenly (13s and
   8s) compose into motion that only repeats every 104s, so it reads as alive
   rather than as a loop. Nothing here ever pauses. */
.aperture__drift,
.aperture__pupil {
	transform-origin: 130px 130px;
}

.aperture__drift {
	animation: pupil-drift 13s var(--sine) infinite;
}

.aperture__pupil {
	fill: var(--pupil);
	animation: pupil-ripple 8s var(--sine) infinite;
}

.aperture__catch {
	fill: var(--catch);
	opacity: 0.6;
	filter: blur(1.2px);
}

/* The slow breath. */
@keyframes pupil-drift {
	0% {
		transform: scale(1);
	}
	21% {
		transform: scale(0.935);
	}
	43% {
		transform: scale(0.878);
	}
	68% {
		transform: scale(0.925);
	}
	85% {
		transform: scale(0.892);
	}
	100% {
		transform: scale(1);
	}
}

/* The small tremor riding on top of it. */
@keyframes pupil-ripple {
	0% {
		transform: scale(1);
	}
	17% {
		transform: scale(0.962);
	}
	34% {
		transform: scale(0.99);
	}
	56% {
		transform: scale(0.944);
	}
	78% {
		transform: scale(0.978);
	}
	100% {
		transform: scale(1);
	}
}

/* The stroma brightens as the pupil narrows, on its own period again so the
   two never lock into a visible beat. */
.aperture__fiber {
	animation: stroma-lift 13s var(--sine) infinite;
}

@keyframes stroma-lift {
	0% {
		opacity: 0.72;
	}
	43% {
		opacity: 0.92;
	}
	68% {
		opacity: 0.78;
	}
	85% {
		opacity: 0.89;
	}
	100% {
		opacity: 0.72;
	}
}

/* Light response: the drift gives way to a hard constriction when a photo
   lands. Both layers have to stop, or the tremor keeps riding on top of it. */
.aperture.is-lit .aperture__drift {
	animation: none;
	transform: scale(1);
}

.aperture.is-lit .aperture__pupil {
	animation: none;
	transform: scale(0.58);
	transition: transform 420ms var(--out-expo);
}

.aperture.is-lit .aperture__blade {
	opacity: 0.6;
}

/* --- 9. The instrument panel (upload) ---------------------------------- */

.panel {
	min-width: 0;
	background: var(--stroma);
	border: 1px solid var(--edge);
	border-radius: var(--radius-lg);
	padding: clamp(1rem, 0.6rem + 1.4vw, 1.5rem);
}

.drop {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.65rem;
	min-width: 0;
	min-height: 168px;
	padding: 1.5rem 1rem;
	border: 1px dashed var(--edge-lit);
	border-radius: var(--radius);
	background: color-mix(in oklch, var(--pupil) 55%, transparent);
	text-align: center;
	cursor: pointer;
	transition: border-color var(--mid) var(--out-quart), background var(--mid) var(--out-quart);
}

.drop:hover,
.drop:focus-within {
	border-color: var(--iris);
	background: color-mix(in oklch, var(--pupil) 30%, transparent);
}

.drop.is-dragging {
	border-color: var(--iris);
	border-style: solid;
	background: color-mix(in oklch, var(--iris) 8%, var(--pupil));
}

.drop input[type="file"] {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	opacity: 0;
	cursor: pointer;
}

/* Corner brackets: the viewfinder framing an instrument uses. */
.drop__corner {
	position: absolute;
	width: 14px;
	height: 14px;
	border: 1px solid var(--iris);
	pointer-events: none;
	opacity: 0.7;
}

.drop__corner--tl {
	top: 8px;
	left: 8px;
	border-right: 0;
	border-bottom: 0;
}

.drop__corner--tr {
	top: 8px;
	right: 8px;
	border-left: 0;
	border-bottom: 0;
}

.drop__corner--bl {
	bottom: 8px;
	left: 8px;
	border-right: 0;
	border-top: 0;
}

.drop__corner--br {
	bottom: 8px;
	right: 8px;
	border-left: 0;
	border-top: 0;
}

.drop__title {
	max-width: 100%;
	color: var(--catch);
	font-weight: 600;
	font-size: 1rem;
	overflow-wrap: anywhere;
}

.drop__hint {
	max-width: 100%;
	color: var(--haze);
	font-size: var(--step-small);
	overflow-wrap: anywhere;
}

.drop__preview {
	display: none;
}

.drop.has-file .drop__preview {
	display: block;
}

.drop__preview img {
	width: 108px;
	height: 108px;
	object-fit: cover;
	border-radius: var(--radius);
	border: 1px solid var(--iris);
}

.drop.has-file .drop__title {
	color: var(--iris);
}

.panel__foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.85rem;
	min-width: 0;
	margin-top: 1rem;
}

.panel__status {
	flex: 1 1 12rem;
	min-width: 0;
	display: flex;
	align-items: center;
	gap: 0.55rem;
	overflow: hidden;
}

.panel__status .label {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.panel__foot .btn {
	flex: 0 0 auto;
}

@media (max-width: 520px) {
	.panel__foot .btn {
		flex: 1 1 100%;
	}
}

/* Status lamp */
.lamp {
	width: 7px;
	height: 7px;
	flex: none;
	border-radius: 50%;
	background: var(--edge-lit);
	transition: background var(--mid) var(--out-quart), box-shadow var(--mid) var(--out-quart);
}

.lamp[data-state="ready"] {
	background: var(--iris);
	box-shadow: 0 0 10px color-mix(in oklch, var(--iris) 70%, transparent);
}

.lamp[data-state="busy"] {
	background: var(--iris);
	animation: blink 1.1s steps(1, end) infinite;
}

.lamp[data-state="error"] {
	background: var(--alarm);
	box-shadow: 0 0 10px color-mix(in oklch, var(--alarm) 70%, transparent);
}

@keyframes blink {
	0%,
	49% {
		opacity: 1;
	}
	50%,
	100% {
		opacity: 0.25;
	}
}

.spinner {
	width: 1em;
	height: 1em;
	border: 2px solid color-mix(in oklch, var(--pupil) 40%, transparent);
	border-top-color: var(--pupil);
	border-radius: 50%;
	animation: spin 700ms linear infinite;
}

@keyframes spin {
	to {
		transform: rotate(360deg);
	}
}

/* --- 10. Notices ------------------------------------------------------- */

.notice {
	display: flex;
	gap: 0.75rem;
	align-items: flex-start;
	padding: 0.85rem 1rem;
	margin-bottom: 1rem;
	border: 1px solid color-mix(in oklch, var(--alarm) 50%, transparent);
	border-radius: var(--radius);
	background: color-mix(in oklch, var(--alarm) 10%, var(--pupil));
	color: var(--catch);
	font-size: var(--step-small);
	line-height: 1.5;
}

.notice svg {
	flex: none;
	width: 1.15rem;
	height: 1.15rem;
	color: var(--alarm);
	margin-top: 0.1rem;
}

/* --- 11. Bipolar axis readout ------------------------------------------ */
/* The measurement is bipolar (round <-> almond), so the instrument is a
   scale with a marker, not a bar that fills from the left. */

.axis {
	padding-block: clamp(1.4rem, 1rem + 1.2vw, 2rem);
	border-top: 1px solid var(--edge);
}

.axis__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 0.5rem 1rem;
	margin-bottom: 1.1rem;
}

.axis__name {
	font-family: var(--sans);
	font-variation-settings: "wdth" 110;
	font-weight: 700;
	font-size: var(--step-h4);
	color: var(--catch);
	letter-spacing: -0.01em;
}

.axis__verdict {
	font-family: var(--mono);
	font-variation-settings: "wdth" 87.5;
	font-size: var(--step-small);
	font-weight: 600;
	color: var(--iris);
	letter-spacing: 0.02em;
}

.axis__strength {
	color: var(--haze);
	font-weight: 400;
}

.axis__strength::before {
	content: "\00b7";
	margin-inline-end: 0.4em;
}

/* `.axis__seek` is track-width and slides by a percentage of itself, so its box
   hangs off the right by up to a full track width. Unclipped that widens the
   document and drags the fixed offer bar out with it. The clip margin keeps the
   marker's glow from being cut at the extremes. */
.axis__scale {
	position: relative;
	height: 46px;
	overflow: clip;
	overflow-clip-margin: 12px;
}

.axis__track {
	position: absolute;
	inset-block-start: 21px;
	inset-inline: 0;
	height: 2px;
	background: var(--edge);
}

/* One tick per tenth of the scale. No background-size here: it would tile the
   repeating gradient inside each tile and multiply the tick count. */
.axis__ticks {
	position: absolute;
	inset-block-start: 14px;
	inset-inline: 0;
	height: 16px;
	background-image: repeating-linear-gradient(to right, var(--edge-lit) 0 1px, transparent 1px 10%);
}

.axis__mid {
	position: absolute;
	inset-block: 6px;
	inset-inline-start: 50%;
	width: 1px;
	background: var(--edge-lit);
}

/* The needle seeks its reading on load. `.axis__seek` spans the full track,
   so a percentage translateX resolves against the track width and the whole
   motion stays on the compositor. */
.axis__seek {
	position: absolute;
	inset: 0;
	transform: translateX(var(--pos, 50%));
	animation: seek 900ms var(--out-expo) both;
	pointer-events: none;
}

.axis__needle {
	position: absolute;
	inset-block: 0;
	inset-inline-start: -1px;
	width: 2px;
	background: var(--iris);
	box-shadow: 0 0 14px color-mix(in oklch, var(--iris) 60%, transparent);
}

.axis__needle::after {
	content: "";
	position: absolute;
	inset-block-start: 15px;
	inset-inline-start: 50%;
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: var(--iris);
	transform: translateX(-50%);
	box-shadow: 0 0 0 4px color-mix(in oklch, var(--iris) 18%, transparent);
}

@keyframes seek {
	from {
		transform: translateX(50%);
	}
}

.axis__poles {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	margin-top: 0.35rem;
}

.axis__pole {
	font-family: var(--mono);
	font-variation-settings: "wdth" 87.5;
	font-size: var(--step-label);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--haze);
}

.axis__pole.is-hit {
	color: var(--catch);
}

.axis__note {
	margin-top: 1rem;
	max-width: 62ch;
	color: var(--haze);
	font-size: var(--step-small);
	line-height: 1.6;
}

/* --- 12. Spec grid (the six shapes) ------------------------------------ */
/* A ruled contact sheet, not a stack of cards. */

/* Six cells, so the column count is pinned to divisors of six. auto-fit would
   land on four at desktop width and leave two dead cells. */
.spec {
	display: grid;
	gap: 1px;
	background: var(--edge);
	border: 1px solid var(--edge);
	border-radius: var(--radius-lg);
	overflow: hidden;
	grid-template-columns: 1fr;
}

@media (min-width: 620px) {
	.spec {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1000px) {
	.spec {
		grid-template-columns: repeat(3, 1fr);
	}
}

.spec__cell {
	background: var(--pupil);
	padding: clamp(1.25rem, 0.9rem + 1.2vw, 1.9rem);
	display: flex;
	flex-direction: column;
	gap: 0.7rem;
	transition: background var(--mid) var(--out-quart);
}

.spec__cell:hover {
	background: var(--limbal);
}

.spec__figure {
	width: 100%;
	max-width: 210px;
	color: var(--sclera);
	margin-bottom: 0.35rem;
}

.spec__cell h3 {
	font-size: var(--step-h4);
	font-variation-settings: "wdth" 110;
}

.spec__cell p {
	font-size: var(--step-small);
	color: var(--haze);
	line-height: 1.6;
	margin: 0;
}

/* Eye diagram internals. Lids and iris in ink, measurement geometry in amber:
   solid caliper = the quantity read, dashed = the reference it is compared to. */
.dia__lid {
	fill: none;
	stroke: currentColor;
	stroke-width: 2.4;
	stroke-linecap: round;
}

.dia__iris {
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	opacity: 0.75;
}

.dia__pupil {
	fill: currentColor;
}

.dia__guide {
	fill: none;
	stroke: var(--iris);
	stroke-width: 1.4;
	stroke-dasharray: 4 4;
}

.dia__caliper {
	fill: none;
	stroke: var(--iris);
	stroke-width: 1.4;
}

.dia__ext {
	fill: none;
	stroke: var(--iris);
	stroke-width: 1;
	stroke-dasharray: 3 4;
	opacity: 0.3;
}

/* --- 13. Measured-axis explainer --------------------------------------- */

.reads {
	display: grid;
	gap: 0;
}

.read {
	display: grid;
	gap: 1rem 2.5rem;
	padding-block: clamp(1.6rem, 1.1rem + 1.6vw, 2.4rem);
	border-top: 1px solid var(--edge);
	align-items: center;
}

@media (min-width: 760px) {
	.read {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	}
}

.read__body p {
	color: var(--haze);
	font-size: var(--step-small);
	max-width: 48ch;
}

/* Three short notes, ruled rather than boxed. */
.uses {
	display: grid;
	gap: 0 clamp(1.5rem, 1rem + 2.5vw, 3.25rem);
	grid-template-columns: 1fr;
}

@media (min-width: 780px) {
	.uses {
		grid-template-columns: repeat(3, 1fr);
	}
}

.use {
	border-block-start: 1px solid var(--edge);
	padding-block: 1.35rem 1.6rem;
}

.use h3 {
	font-size: var(--step-h4);
	margin-bottom: 0.6rem;
}

.use p {
	margin: 0;
	color: var(--haze);
	font-size: var(--step-small);
	line-height: 1.65;
}

/* --- 14. FAQ ----------------------------------------------------------- */

/* Left-aligned inside the wide container so the gutter matches every other
   section, but capped so the rows never stretch to a 1240px accordion. */
.faq {
	max-width: 800px;
	border-block-end: 1px solid var(--edge);
}

.qa {
	border-block-start: 1px solid var(--edge);
}

.qa > summary {
	display: flex;
	align-items: flex-start;
	gap: 1rem;
	padding-block: 1.15rem;
	cursor: pointer;
	list-style: none;
	color: var(--catch);
	font-weight: 600;
	font-size: 1.05rem;
	line-height: 1.4;
	transition: color var(--fast) var(--out-quart);
}

.qa > summary::-webkit-details-marker {
	display: none;
}

.qa > summary:hover {
	color: var(--iris);
}

.qa > summary::after {
	content: "+";
	margin-inline-start: auto;
	flex: none;
	font-family: var(--mono);
	font-size: 1.05rem;
	line-height: 1.3;
	color: var(--iris);
	transition: transform var(--mid) var(--out-expo);
}

.qa[open] > summary::after {
	transform: rotate(135deg);
}

.qa__body {
	padding-block-end: 1.35rem;
	max-width: var(--measure);
	color: var(--haze);
	font-size: var(--step-small);
	line-height: 1.7;
}

/* --- 15. Ruled link list (cross-promotion, blog index) ------------------ */

.links {
	border-block-end: 1px solid var(--edge);
}

.links__item {
	display: flex;
	align-items: center;
	gap: 1rem;
	padding-block: 1rem;
	border-block-start: 1px solid var(--edge);
	color: var(--sclera);
	text-decoration: none;
	transition: color var(--fast) var(--out-quart), transform var(--mid) var(--out-expo);
}

.links__item:hover {
	color: var(--catch);
	transform: translateX(6px);
}

.links__item img,
.links__item .links__glyph {
	width: 30px;
	height: 30px;
	flex: none;
	object-fit: contain;
}

.links__text {
	min-width: 0;
}

.links__text strong {
	display: block;
	font-weight: 600;
	font-size: 1rem;
	color: inherit;
	line-height: 1.3;
}

.links__text span {
	display: block;
	font-size: var(--step-small);
	color: var(--haze);
}

.links__item svg.links__arrow {
	width: 1rem;
	height: 1rem;
	flex: none;
	margin-inline-start: auto;
	color: var(--iris);
	transition: transform var(--mid) var(--out-expo);
}

.links__item:hover svg.links__arrow {
	transform: translateX(4px);
}

/* --- 16. Result page --------------------------------------------------- */

.verdict {
	display: grid;
	gap: clamp(1.75rem, 1rem + 3vw, 3.5rem);
	align-items: center;
}

@media (min-width: 820px) {
	.verdict {
		grid-template-columns: auto minmax(0, 1fr);
	}
}

.plate {
	position: relative;
	justify-self: center;
	padding: 14px;
}

.plate__img {
	width: min(230px, 62vw);
	height: auto;
	aspect-ratio: 1;
	object-fit: cover;
	border-radius: var(--radius);
	filter: saturate(1.02);
}

.plate__corner {
	position: absolute;
	width: 20px;
	height: 20px;
	border: 1.5px solid var(--iris);
}

.plate__corner--tl {
	top: 0;
	left: 0;
	border-right: 0;
	border-bottom: 0;
}

.plate__corner--tr {
	top: 0;
	right: 0;
	border-left: 0;
	border-bottom: 0;
}

.plate__corner--bl {
	bottom: 0;
	left: 0;
	border-right: 0;
	border-top: 0;
}

.plate__corner--br {
	bottom: 0;
	right: 0;
	border-left: 0;
	border-top: 0;
}

.verdict__name {
	font-size: clamp(2.1rem, 1.2rem + 3.6vw, 3.9rem);
	font-variation-settings: var(--wide);
	font-weight: 800;
	letter-spacing: -0.035em;
	line-height: 1;
	color: var(--catch);
	margin-block: 0.5rem 0.7rem;
}

.verdict__modifier {
	color: var(--iris);
}

/* --- 17. Sticky offer bar ---------------------------------------------- */

.offer {
	position: fixed;
	inset-inline: 0;
	inset-block-end: 0;
	z-index: var(--z-sticky);
	background: color-mix(in oklch, var(--limbal) 96%, transparent);
	backdrop-filter: blur(16px);
	-webkit-backdrop-filter: blur(16px);
	border-block-start: 1px solid var(--edge-lit);
	padding: 0.75rem var(--gutter);
	padding-block-end: max(0.75rem, env(safe-area-inset-bottom));
}

.offer__inner {
	max-width: 1240px;
	margin-inline: auto;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1rem;
}

.offer__text {
	margin: 0;
	font-size: var(--step-small);
	color: var(--sclera);
	line-height: 1.4;
}

.offer .btn {
	flex: none;
	padding-block: 0.6rem;
	white-space: nowrap;
}

@media (max-width: 640px) {
	.offer__inner {
		flex-direction: column;
		align-items: stretch;
		gap: 0.6rem;
		text-align: center;
	}

	.offer .btn {
		width: 100%;
	}
}

.has-offer {
	padding-block-end: 8.5rem;
}

/* --- 18. Prose (blog, legal) ------------------------------------------- */

/* Legal and blog copy contains bare URLs, which are single unbreakable words
   wider than a phone. Break them rather than let them widen the document. */
.prose {
	max-width: var(--measure);
	color: var(--sclera);
	overflow-wrap: break-word;
}

.prose a {
	overflow-wrap: anywhere;
}

.prose > * + * {
	margin-top: 1.15rem;
}

.prose h1 {
	font-size: var(--step-h2);
	font-variation-settings: "wdth" 110;
	margin-top: 0;
}

.prose h2 {
	font-size: var(--step-h3);
	margin-top: 2.75rem;
}

.prose h3 {
	font-size: var(--step-h4);
	margin-top: 2rem;
}

.prose ul,
.prose ol {
	padding-inline-start: 1.25rem;
}

.prose li + li {
	margin-top: 0.4rem;
}

.prose li::marker {
	color: var(--iris);
}

.prose img {
	border-radius: var(--radius-lg);
	border: 1px solid var(--edge);
	width: 100%;
}

.prose a {
	font-weight: 500;
}

.prose table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--step-small);
	display: block;
	overflow-x: auto;
}

.prose td,
.prose th {
	border: 1px solid var(--edge);
	padding: 0.5rem 0.7rem;
	text-align: left;
}

.prose .index {
	columns: 2;
	column-gap: 2rem;
	font-size: var(--step-small);
}

@media (max-width: 640px) {
	.prose .index {
		columns: 1;
	}
}

.figure-pair {
	display: grid;
	gap: 1.5rem;
	align-items: start;
}

@media (min-width: 700px) {
	.figure-pair {
		grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
	}
}

/* The prose flow rhythm stops at .prose's direct children, so restore it
   inside the text column of a figure pair. */
.figure-pair > div > * + * {
	margin-top: 1.15rem;
}

.figure-pair .spec__figure {
	max-width: none;
	width: 100%;
	padding: 1rem;
	background: var(--limbal);
	border: 1px solid var(--edge);
	border-radius: var(--radius-lg);
}

/* --- 19. Ad slots ------------------------------------------------------ */
/* Ad creatives are mostly light. Give them a deliberate frame so they read
   as inserts rather than as holes in the page. */

/* An unfilled slot must contribute nothing: the frame and the spacing both
   hang off :not(:empty), so a slot Ezoic never fills leaves no gap behind. */
.ad > div:not(:empty) {
	margin-block: var(--gap-block);
	padding: 0.75rem;
	background: var(--limbal);
	border: 1px solid var(--edge);
	border-radius: var(--radius-lg);
	overflow: hidden;
	display: flex;
	justify-content: center;
}

/* --- 20. Footer -------------------------------------------------------- */

.foot {
	margin-top: auto;
	border-block-start: 1px solid var(--edge);
	background: var(--limbal);
	padding-block: 2.5rem;
}

.foot__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1.25rem;
}

.foot__links {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem 1.5rem;
	list-style: none;
	padding: 0;
	margin: 0;
}

.foot__links a {
	color: var(--haze);
	font-size: var(--step-small);
	text-decoration: none;
}

.foot__links a:hover {
	color: var(--catch);
}

.foot__note {
	width: 100%;
	color: var(--haze);
	font-size: var(--step-label);
	font-family: var(--mono);
	font-variation-settings: "wdth" 87.5;
	letter-spacing: 0.04em;
	line-height: 1.7;
}

/* --- 21. Cookie banner -------------------------------------------------- */

.cb-backdrop {
	position: fixed;
	inset: 0;
	z-index: var(--z-backdrop);
	background: color-mix(in oklch, var(--pupil) 82%, transparent);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	display: none;
	align-items: center;
	justify-content: center;
	padding: var(--gutter);
	overflow-y: auto;
}

.cb-backdrop.is-open {
	display: flex;
}

.cb-panel {
	position: relative;
	z-index: var(--z-modal);
	width: min(600px, 100%);
	max-height: 88vh;
	overflow-y: auto;
	background: var(--stroma);
	border: 1px solid var(--edge-lit);
	border-radius: var(--radius-lg);
	padding: clamp(1.25rem, 1rem + 1.4vw, 2rem);
}

.cb-group {
	border-block-start: 1px solid var(--edge);
	padding-block: 1rem;
}

.cb-group h4 {
	font-size: 1rem;
	margin: 0;
}

.cb-group p {
	font-size: var(--step-small);
	color: var(--haze);
	margin: 0.3rem 0 0;
}

.cb-switch {
	display: flex;
	align-items: center;
	gap: 0.7rem;
}

.cb-switch input {
	appearance: none;
	width: 38px;
	height: 21px;
	flex: none;
	border-radius: 999px;
	background: var(--edge-lit);
	position: relative;
	cursor: pointer;
	transition: background var(--fast) var(--out-quart);
}

.cb-switch input::after {
	content: "";
	position: absolute;
	top: 3px;
	left: 3px;
	width: 15px;
	height: 15px;
	border-radius: 50%;
	background: var(--catch);
	transition: transform var(--mid) var(--out-expo);
}

.cb-switch input:checked {
	background: var(--iris);
}

.cb-switch input:checked::after {
	transform: translateX(17px);
}

.cb-switch input:disabled {
	cursor: not-allowed;
	opacity: 0.65;
}

.cb-detail {
	font-size: var(--step-label);
	font-family: var(--mono);
	color: var(--haze);
	margin-top: 0.5rem;
}

.cb-detail td {
	padding: 0.2rem 0.5rem 0.2rem 0;
	vertical-align: top;
	line-height: 1.6;
}

.cb-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin-top: 1.5rem;
}

.cb-actions .btn {
	flex: 1 1 12rem;
}

/* --- 22. Utility ------------------------------------------------------- */

.center {
	text-align: center;
}

.mx-auto {
	margin-inline: auto;
}

.hidden {
	display: none !important;
}

.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.cluster {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
}

/* --- 23. Reduced motion ------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}

	.aperture__drift {
		animation: none;
		transform: scale(1);
	}

	.aperture__pupil {
		animation: none;
		transform: scale(0.9);
	}

	.aperture__fiber {
		animation: none;
		opacity: 0.8;
	}

	.axis__seek {
		animation: none;
	}

	.spinner {
		animation: none;
		border-top-color: transparent;
		border-right-color: var(--pupil);
	}

	.lamp[data-state="busy"] {
		animation: none;
	}
}
