/* normaliz.ar edge stylesheet.
 *
 * The real semantic token system (ADR-0006 §5, DESIGN.md §§1–3): all color,
 * type, and spacing are CSS custom properties defined once in :root, so
 * re-theming is editing variables — never refactoring component rules. Every
 * visual value below goes through a token; no hardcoded hex lives in a
 * component rule.
 *
 * Values are TENTATIVE (no final palette, no embedded font yet); the ROLES are
 * the contract. The muted dark base, large/light text, and mono typography are
 * shared and fixed across themes; only the highlight (--accent) swaps between
 * the green/amber/white phosphor candidates via [data-theme=...] (D2/D3).
 */

:root {
	color-scheme: dark;

	/* Surfaces — the "engamado" scale (ADR-0006 §4): a deep blue-green base and
	   three tonally-adjacent steps up. Elevation is expressed by tone, not by
	   shadow; sections are contiguous planes that touch. */
	--surface-base: #0a1419;
	--surface-1: #0f1c23;
	--surface-2: #15262e;
	--surface-3: #1d3540;

	/* Ink. */
	--ink-primary: #e7f1ee;
	--ink-muted: #7f9aa0;

	/* Highlight / phosphor — the ONE token that swaps per theme (D3). It does
	   double duty: the input-cue affordance and the clean formatted output, so
	   selección→formato reads in a single color. Default candidate: green. */
	--accent: #5ef2b3;

	/* Dimmed accent — the SAME hue at lower intensity (ADR-0006 §6 / DESIGN.md
	   §6 refinement, prompt DD3). It colors the dirty source/context in the
	   chaos→order animation and its static fallback; the bright --accent is the
	   ignited candidate and the formatted result. One hue, two intensities — so
	   the whole tableau reads as a single color deepening, not a palette. Each
	   theme override below carries its own dim+bright pair. Default: green. */
	--accent-dim: #2f7a5c;

	/* The door/temple gradient (green → blue). Fixed across themes. Kept defined
	   even though the wordmark no longer uses it (reserved for future doors,
	   ADR-0006 §2). */
	--brand-gradient: linear-gradient(135deg, #2fe6a0, #2f8fe6);

	/* The wordmark letters: the solid terminal-blue of --brand-gradient (the
	   "celeste" of the .ar). Fixed across themes, like the gradient. */
	--brand-celeste: #2f8fe6;

	/* Typography. Mono is the protagonist (DESIGN.md §2); the door headline and
	   the tableau numbers are mono (D4). System mono stack placeholder — the real
	   family is embedded later. */
	--mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
	--sans-ui: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	--display: var(--mono);

	/* Spacing — base 4 / 8 unit (DESIGN.md §3). */
	--space-1: 0.25rem;
	--space-2: 0.5rem;
	--space-3: 1rem;
	--space-4: 1.5rem;
	--space-5: 2rem;
	--space-6: 3rem;

	/* Tableau line scale (D4): three depth steps for the static chaos/order
	   fallback. Each chaos↔order pair shares one step, so the two strips read as
	   aligned rows across the machine. The live canvas gets its depth from
	   parallax instead. */
	--line-far: 0.85rem;
	--line-mid: 1rem;
	--line-near: 1.2rem;
}

/* Theme overrides — only the highlight token group swaps (D2). The base, type,
   and layout are inherited from :root unchanged. */
[data-theme="amber"] {
	--accent: #ffb000;
	--accent-dim: #8a5e0c;
}
[data-theme="white"] {
	--accent: #eaf6f2;
	--accent-dim: #7c948f;
}

* {
	box-sizing: border-box;
}

body {
	margin: 0;
	background: var(--surface-base);
	color: var(--ink-primary);
	font-family: var(--sans-ui);
	line-height: 1.5;
}

/* The shell fills the viewport; the apex grid owns its own layout (no centered
   max-width column — the strips run full-bleed and touch). */
.shell {
	min-height: 100vh;
}

/* ── Three-strip grid (ADR-0006 §3, login weighting) ────────────────────────
   chaos | machine + access | order. Contiguous planes, no gap: each strip is
   its own tonal plane and they touch. */
.apex {
	display: grid;
	grid-template-columns: 1fr minmax(20rem, 30rem) 1fr;
	min-height: 100vh;
	position: relative;
}

.strip {
	padding: var(--space-6) var(--space-5);
	overflow: hidden;
}

/* Left: chaos — dirty AR free-text with embedded dirty numbers. The dirty
   source/context is the DIM accent (DD3); the candidate run inside it is bright.
   Same vertical rhythm as the order strip (gap/justify/padding) so the pairs
   read as aligned rows (D4). */
.strip--chaos {
	background: var(--surface-1);
	color: var(--accent-dim);
	font-family: var(--mono);
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: var(--space-4);
}

.chaos-line {
	margin: 0;
}

/* The detected candidate inside a dirty line is bright (D3/D5): the static
   counterpart of the canvas "ignite". The ▮ rides inside it and inherits this
   bright color. */
.candidate {
	color: var(--accent);
}

/* Right: order — clean dialable digit-only numbers in the bright highlight. */
.strip--order {
	background: var(--surface-2);
	color: var(--accent);
	font-family: var(--mono);
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: var(--space-4);
	text-align: right;
}

.order-line {
	margin: 0;
	letter-spacing: 0.02em;
}

/* Per-pair depth sizing (D4): each chaos↔order pair shares one step. */
.line--far {
	font-size: var(--line-far);
}
.line--mid {
	font-size: var(--line-mid);
}
.line--near {
	font-size: var(--line-near);
}

/* The redaction glyph rides inside both chaos and order numbers (D6). It tracks
   its number's current color (DD3): dim where the surrounding number is dim,
   bright where ignited — so it is born dim and ignites together with its digits
   rather than rendering as a fixed muted glyph. */
.redaction {
	color: currentColor;
}

/* Center: the machine — the brand wordmark + the four access buttons. Door
   register: generous spacing, large type, gradient foregrounded. */
.strip--machine {
	background: var(--surface-base);
	display: flex;
	align-items: center;
	justify-content: center;
}

.machine {
	width: 100%;
	max-width: 24rem;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-5);
	text-align: center;
}

/* Brand identity (DD-A): the wordmark letters are fixed celeste; the dot is the
   animation accent (--accent), so "the dot is the animation's color" holds in
   every theme. This is NOT a semantic split of the data. */
.wordmark {
	margin: 0;
	font-family: var(--display);
	font-size: clamp(2.2rem, 6vw, 3rem);
	font-weight: 700;
	letter-spacing: -0.01em;
	color: var(--brand-celeste);
}

.wordmark-dot {
	color: var(--accent);
}

.access {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}

.access-btn {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	padding: var(--space-3) var(--space-4);
	border: 1px solid var(--surface-3);
	border-radius: var(--space-2);
	background: var(--surface-1);
	color: var(--ink-primary);
	font-family: var(--sans-ui);
	font-size: 0.95rem;
	text-decoration: none;
	transition: border-color 120ms ease, background 120ms ease;
}

.access-btn-icon {
	width: 1.25rem;
	height: 1.25rem;
	flex-shrink: 0;
	display: block;
}

.access-btn:hover {
	border-color: var(--accent);
	background: var(--surface-2);
}

/* ── Canvas animation (DD1, progressive enhancement) ─────────────────────────
   The canvas is hidden by default and revealed by apex-anim.js only when motion
   is allowed and JS runs. It spans the whole apex (chaos + order regions) behind
   the machine; the machine strip stays opaque and above it (z-index) so the
   wordmark and access buttons remain legible. With JS off OR
   prefers-reduced-motion, .anim-on is never set and the static strips render
   exactly as the server emitted them. */
.apex-canvas {
	display: none;
}

.apex.anim-on .apex-canvas {
	display: block;
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	z-index: 0;
}

/* When the canvas takes over, the static fallback text is hidden (still in the
   DOM for no-JS / SSR), and the machine floats above the canvas. */
.apex.anim-on .strip--chaos,
.apex.anim-on .strip--order {
	visibility: hidden;
}

/* DD6 — frosted machine: in the animated state ONLY, the center strip becomes a
   lighter, translucent surface with a backdrop blur of the canvas beneath it. The
   canvas spans full width behind it, so the dirty→clean crossfade reads as
   happening INSIDE the machine and the left↔right gap disappears. The wordmark and
   buttons stay opaque above the blur and fully legible. The static (non-anim)
   machine keeps its opaque --surface-base from .strip--machine. The deeper blur
   (12px, iteration 3) softens the seam so the crossfade band reads as one frosted
   transform rather than two adjacent regions. */
.apex.anim-on .strip--machine {
	position: relative;
	z-index: 1;
	background: color-mix(in srgb, var(--surface-3) 60%, transparent);
	-webkit-backdrop-filter: blur(12px);
	backdrop-filter: blur(12px);
}

/* ── Mobile: collapse to the single center column (machine + access), with the
   chaos/order strips behind it as a muted static backdrop (no animation yet). */
@media (max-width: 48rem) {
	.apex {
		grid-template-columns: 1fr;
		position: relative;
	}

	.strip--chaos,
	.strip--order {
		position: absolute;
		inset: 0;
		justify-content: flex-start;
		opacity: 0.12;
		pointer-events: none;
		z-index: 0;
	}

	.strip--order {
		justify-content: flex-end;
	}

	.strip--machine {
		position: relative;
		z-index: 1;
		min-height: 100vh;
		background: transparent;
	}
}
