/* ============================================================================
   Conor Rice — design system
   Refined-minimal: cool paper, ink, one fountain-pen-blue accent.
   Personality lives in the type (Spectral display / IBM Plex Mono data) and
   restrained detail; everything else stays quiet. Auto light/dark. Prints clean.
   ========================================================================== */

/* ---- Fonts (self-hosted, latin subset) ---------------------------------- */

@font-face {
	font-family: "Spectral"; font-style: normal; font-weight: 400;
	font-display: swap; src: url("/assets/fonts/spectral-400.woff2") format("woff2");
}
@font-face {
	font-family: "Spectral"; font-style: normal; font-weight: 500;
	font-display: swap; src: url("/assets/fonts/spectral-500.woff2") format("woff2");
}
@font-face {
	font-family: "Spectral"; font-style: normal; font-weight: 600;
	font-display: swap; src: url("/assets/fonts/spectral-600.woff2") format("woff2");
}
@font-face {
	font-family: "Spectral"; font-style: italic; font-weight: 400;
	font-display: swap; src: url("/assets/fonts/spectral-italic-400.woff2") format("woff2");
}
@font-face {
	font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400;
	font-display: swap; src: url("/assets/fonts/plex-mono-400.woff2") format("woff2");
}

/* ---- Tokens -------------------------------------------------------------- */

:root {
	/* color — light */
	--paper:        #f0efea;
	--surface:      #faf9f6;
	--ink:          #1a1b1d;
	--ink-soft:     #52545a;
	--ink-faint:    #8b8d93;
	--rule:         #dcdcd4;
	--accent:       #2c5578;
	--accent-strong:#1f3e5a;
	--halo:         rgba(44, 85, 120, 0.07);

	/* type */
	--font-display: "Spectral", Georgia, "Times New Roman", serif;
	--font-body:    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	--font-mono:    "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

	--fs-hero:  clamp(2.6rem, 7vw, 4rem);
	--fs-h1:    clamp(1.85rem, 4vw, 2.4rem);
	--fs-h2:    1.3rem;
	--fs-lede:  1.15rem;
	--fs-body:  1rem;
	--fs-small: 0.875rem;
	--fs-mono:  0.78rem;

	/* space */
	--sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
	--sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 72px;

	--col: 720px;
	--r: 8px;
	--r-sm: 6px;

	--ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

@media (prefers-color-scheme: dark) {
	:root {
		--paper:        #131417;
		--surface:      #1a1c20;
		--ink:          #e8e8e3;
		--ink-soft:     #a5a7ad;
		--ink-faint:    #6c6e74;
		--rule:         #292b30;
		--accent:       #8cb4e6;
		--accent-strong:#aeccf2;
		--halo:         rgba(140, 180, 230, 0.10);
	}
}

/* ---- Reset & base -------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
	margin: 0;
	padding: 0;
	min-height: 100vh;

	background-color: var(--paper);
	color: var(--ink);
	font-family: var(--font-body);
	font-size: var(--fs-body);
	line-height: 1.6;

	display: flex;
	flex-direction: column;
	align-items: center;

	overflow-x: hidden;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

p { margin: 0; }

a {
	color: var(--accent);
	text-decoration: none;
	transition: color 0.18s var(--ease);
}
a:hover { color: var(--accent-strong); }

h1, h2, h3 {
	font-family: var(--font-display);
	font-weight: 500;
	line-height: 1.15;
	margin: 0;
	letter-spacing: -0.01em;
}

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

/* ---- Page frame ---------------------------------------------------------- */

.page {
	width: 100%;
	max-width: var(--col);
	padding: 0 var(--sp-5);
	margin: 0 auto;
}

/* top nav ------------------------------------------------------------------ */

.nav {
	width: 100%;
	max-width: var(--col);
	margin: 0 auto;
	padding: var(--sp-5) var(--sp-5) var(--sp-4);

	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--sp-4);
}

.wordmark {
	font-family: var(--font-display);
	font-size: 1.2rem;
	font-weight: 500;
	letter-spacing: -0.01em;
	color: var(--ink);
	transition: color 0.18s var(--ease);
}
.wordmark:hover { color: var(--accent); }

.nav-links {
	display: flex;
	gap: var(--sp-5);
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}
.nav-links a {
	color: var(--ink-soft);
	position: relative;
	padding-bottom: 2px;
}
.nav-links a::after {
	content: "";
	position: absolute;
	left: 0; bottom: 0;
	width: 100%; height: 1px;
	background: var(--accent);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 0.22s var(--ease);
}
.nav-links a:hover { color: var(--accent); }
.nav-links a:hover::after,
.nav-links a[aria-current="page"]::after { transform: scaleX(1); }
.nav-links a[aria-current="page"] { color: var(--ink); }

/* footer ------------------------------------------------------------------- */

.footer {
	width: 100%;
	max-width: var(--col);
	margin: var(--sp-8) auto 0;
	padding: var(--sp-5);
	border-top: 1px solid var(--rule);

	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: var(--sp-4);
	flex-wrap: wrap;

	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.06em;
	color: var(--ink-faint);
}
.footer a { color: var(--ink-soft); }
.footer a:hover { color: var(--accent); }

/* ---- Shared bits --------------------------------------------------------- */

/* mono eyebrow label above sections */
.eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 0.7ch;
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ink-faint);
}
.eyebrow .idx { color: var(--accent); }

.hairline {
	height: 0;
	border: 0;
	border-top: 1px solid var(--rule);
	margin: var(--sp-6) 0;
}

/* content flow spacing */
.prose > * + * { margin-top: var(--sp-4); }
.prose p { color: var(--ink-soft); }

/* ---- Hero (home) --------------------------------------------------------- */

.hero {
	padding: var(--sp-7) 0 var(--sp-6);
}
.hero .eyebrow { margin-bottom: var(--sp-4); }
.hero-name {
	font-size: var(--fs-hero);
	font-weight: 500;
	letter-spacing: -0.02em;
}
.hero-thesis {
	margin-top: var(--sp-4);
	font-family: var(--font-display);
	font-size: var(--fs-lede);
	font-style: italic;
	color: var(--ink-soft);
	max-width: 34ch;
}
.hero-meta {
	margin-top: var(--sp-5);
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2) var(--sp-4);
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.06em;
	color: var(--ink-faint);
}
.hero-meta a { color: var(--ink-soft); }
.hero-meta a:hover { color: var(--accent); }

/* ---- Card grid (home / projects) ---------------------------------------- */

.card-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
	gap: var(--sp-4);
}

.card {
	display: block;
	background: var(--surface);
	border: 1px solid var(--rule);
	border-radius: var(--r);
	padding: var(--sp-5);
	color: var(--ink);
	transition: transform 0.22s var(--ease),
	            border-color 0.22s var(--ease),
	            box-shadow 0.22s var(--ease);
}
.card:hover {
	color: var(--ink);
	transform: translateY(-3px);
	border-color: var(--accent);
	box-shadow: 0 10px 30px -18px var(--accent);
}
.card .card-idx {
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	color: var(--accent);
	letter-spacing: 0.08em;
}
.card .card-title {
	margin-top: var(--sp-2);
	font-family: var(--font-display);
	font-size: 1.4rem;
	font-weight: 500;
	display: flex;
	align-items: center;
	gap: 0.5ch;
}
.card .card-title .arrow {
	color: var(--accent);
	transition: transform 0.22s var(--ease);
}
.card:hover .card-title .arrow { transform: translateX(4px); }
.card .card-desc {
	margin-top: var(--sp-2);
	color: var(--ink-soft);
	font-size: var(--fs-small);
	line-height: 1.55;
}
.card .card-tag {
	margin-top: var(--sp-3);
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	color: var(--ink-faint);
	letter-spacing: 0.05em;
}

/* ---- Resume -------------------------------------------------------------- */

.resume { padding-top: var(--sp-3); }

.resume-head {
	display: flex;
	justify-content: space-between;
	align-items: flex-end;
	gap: var(--sp-4);
	flex-wrap: wrap;
}
.resume-name {
	font-size: var(--fs-h1);
	font-weight: 600;
	letter-spacing: -0.02em;
}
.resume-contact {
	display: flex;
	flex-direction: column;
	gap: 2px;
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.03em;
	text-align: right;
	color: var(--ink-soft);
}
.resume-contact a { color: var(--ink-soft); }
.resume-contact a:hover { color: var(--accent); }
.resume-contact .row {
	display: inline-flex;
	gap: 0.6ch;
	justify-content: flex-end;
	align-items: center;
}

.resume-summary {
	margin: var(--sp-5) 0;
	font-family: var(--font-display);
	font-size: var(--fs-lede);
	line-height: 1.5;
	color: var(--ink);
}

.section { margin-top: var(--sp-6); }
.section > .eyebrow { margin-bottom: var(--sp-4); }

/* skill chips */
.chips {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2);
}
.chip {
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.02em;
	color: var(--ink-soft);
	background: var(--surface);
	border: 1px solid var(--rule);
	border-radius: var(--r-sm);
	padding: 3px 9px;
	transition: border-color 0.18s var(--ease),
	            color 0.18s var(--ease),
	            background 0.18s var(--ease);
}
.chip:hover {
	color: var(--accent);
	border-color: var(--accent);
	background: var(--halo);
}

.capabilities {
	margin-top: var(--sp-4);
	display: flex;
	flex-direction: column;
	gap: var(--sp-2);
}
.capabilities .cap {
	position: relative;
	padding-left: 1.4ch;
	color: var(--ink-soft);
	font-size: var(--fs-small);
}
.capabilities .cap::before {
	content: "—";
	position: absolute;
	left: 0;
	color: var(--accent);
}

/* work-history entries */
.entries { display: flex; flex-direction: column; gap: var(--sp-5); }

.entry {
	position: relative;
	padding-left: var(--sp-5);
	border-left: 1px solid var(--rule);
	transition: border-color 0.2s var(--ease);
}
.entry::before {
	content: "";
	position: absolute;
	left: -1px; top: 0;
	width: 1px; height: 100%;
	background: var(--accent);
	transform: scaleY(0);
	transform-origin: top;
	transition: transform 0.3s var(--ease);
}
.entry:hover::before { transform: scaleY(1); }
.entry-head {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: var(--sp-3);
	flex-wrap: wrap;
}
.entry-title {
	font-family: var(--font-display);
	font-size: var(--fs-h2);
	font-weight: 500;
}
.entry-date {
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	color: var(--ink-faint);
	letter-spacing: 0.03em;
	white-space: nowrap;
}
.entry-org {
	display: inline-block;
	margin-top: 2px;
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.04em;
	color: var(--ink-soft);
}
.entry-org:hover { color: var(--accent); }
.entry-summary { margin-top: var(--sp-3); color: var(--ink-soft); font-size: var(--fs-small); }
.entry-list {
	margin-top: var(--sp-2);
	display: flex;
	flex-direction: column;
	gap: var(--sp-1);
}
.entry-list .li {
	position: relative;
	padding-left: 1.5ch;
	color: var(--ink-soft);
	font-size: var(--fs-small);
	line-height: 1.5;
}
.entry-list .li::before {
	content: "·";
	position: absolute;
	left: 0.3ch;
	color: var(--accent);
	font-weight: bold;
}

/* toolbar / print button */
.toolbar {
	display: flex;
	justify-content: flex-end;
	gap: var(--sp-3);
	margin-bottom: var(--sp-3);
}
.btn {
	display: inline-flex;
	align-items: center;
	gap: 0.6ch;
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ink-soft);
	background: var(--surface);
	border: 1px solid var(--rule);
	border-radius: var(--r-sm);
	padding: 7px 13px;
	cursor: pointer;
	transition: border-color 0.18s var(--ease),
	            color 0.18s var(--ease),
	            background 0.18s var(--ease);
}
.btn:hover {
	color: var(--accent);
	border-color: var(--accent);
	background: var(--halo);
}
.btn:disabled {
	opacity: 0.4;
	cursor: default;
}
.btn:disabled:hover {
	color: var(--ink-soft);
	border-color: var(--rule);
	background: var(--surface);
}
.btn.primary {
	color: var(--paper);
	background: var(--accent);
	border-color: var(--accent);
}
.btn.primary:hover {
	color: var(--paper);
	background: var(--accent-strong);
	border-color: var(--accent-strong);
}
.btn.lg { font-size: var(--fs-small); padding: 11px 20px; }

/* horizontal scroll wrapper for wide content (tables, boards) */
.scroll-x { width: 100%; overflow-x: auto; }

/* ---- Demo shell (snake / games) ----------------------------------------- */

.demo-frame {
	background: var(--surface);
	border: 1px solid var(--rule);
	border-radius: var(--r);
	padding: var(--sp-5);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-4);
}
.demo-note {
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	color: var(--ink-faint);
	letter-spacing: 0.04em;
	text-align: center;
}

/* Telemetry grid — a footer panel below the controls; a cell per stat, updated live as tiles land. */
.telemetry {
	width: 100%;
	margin-top: 6px;
	padding-top: 18px;
	border-top: 1px solid var(--rule);
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 11px 18px;
}
.tstat-k {
	font-family: var(--font-mono);
	font-size: 0.62rem;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--ink-faint);
}
.tstat-v {
	margin-top: 2px;
	min-height: 1.25em;
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.02em;
	color: var(--ink-soft);
}
.tstat[data-k="composition"] .tstat-v { white-space: pre-line; }

/* Color instrument: palette picker, wrap toggle, density slider. */
.color-controls {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: var(--sp-4);
}
.field {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ink-faint);
	cursor: pointer;
}
.field select {
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--ink-soft);
	background: var(--surface);
	border: 1px solid var(--rule);
	border-radius: var(--r-sm);
	padding: 6px 10px;
	cursor: pointer;
	transition: border-color 0.18s var(--ease), color 0.18s var(--ease);
}
.field select:hover { color: var(--accent); border-color: var(--accent); }
.field input[type="checkbox"] { accent-color: var(--accent); width: 15px; height: 15px; cursor: pointer; }
.field input[type="range"] { accent-color: var(--accent); width: 100px; cursor: pointer; }

/* Collapsible control sections (native <details>/<summary> accordion), grouped by cost:
   coloring = instant recolors, render = re-iterating changes. */
.ctrl-section {
	width: 100%;
	margin-top: var(--sp-3);
	border: 1px solid var(--rule);
	border-radius: var(--r-sm);
	background: var(--surface);
}
.ctrl-section > summary {
	list-style: none;
	cursor: pointer;
	padding: var(--sp-3) var(--sp-4);
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--ink-soft);
	user-select: none;
}
.ctrl-section > summary::-webkit-details-marker { display: none; }
.ctrl-section > summary::before {
	content: "▸";
	display: inline-block;
	margin-right: var(--sp-2);
	color: var(--ink-faint);
	transition: transform 0.15s var(--ease);
}
.ctrl-section[open] > summary::before { transform: rotate(90deg); }
.ctrl-section > summary:hover { color: var(--accent); }
.ctrl-body {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--sp-3) var(--sp-4);
	padding: var(--sp-1) var(--sp-4) var(--sp-4);
}
/* Contextual: filter params appear only with a filter selected; escape-time coloring dims when a filter is active. */
.filter-param.hidden { display: none; }
.ctrl-body.inactive { opacity: 0.4; pointer-events: none; }
.escape-only.is-dimmed { opacity: 0.4; pointer-events: none; }
.field.is-dimmed { opacity: 0.4; pointer-events: none; }   /* a disabled advanced control (e.g. perturbation on the general kernel) */

/* Custom-palette gradient editor: a full-width block under the coloring controls, shown
   for palette = custom. Native color swatches, squared off to read as gradient stops. */
.palette-editor { flex-basis: 100%; display: flex; flex-direction: column; gap: var(--sp-3); margin-top: var(--sp-1); }
.palette-editor.hidden { display: none; }
.pal-bar {
	height: 22px; border-radius: var(--r-sm); border: 1px solid var(--rule);
	background: linear-gradient(90deg, #000, #fff);   /* replaced live from the stops */
}
.pal-stops { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; justify-content: center; }
.pal-stops input[type="color"], .pal-inset {
	width: 30px; height: 26px; padding: 0; border: 1px solid var(--rule); border-radius: var(--r-sm);
	background: none; cursor: pointer;
}
.pal-stops input[type="color"]::-webkit-color-swatch-wrapper { padding: 2px; }
.pal-stops input[type="color"]::-webkit-color-swatch { border: none; border-radius: 3px; }
.pal-inset { width: 26px; }
.pal-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--sp-2) var(--sp-4); }

/* Custom-formula text field: shown only for the "custom" formula option. Monospace, wider than a select. */
.formula-custom.hidden { display: none; }
.formula-input {
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	text-transform: none;
	letter-spacing: 0.04em;
	color: var(--ink-soft);
	background: var(--surface);
	border: 1px solid var(--rule);
	border-radius: var(--r-sm);
	padding: 6px 10px;
	width: 190px;
	transition: border-color 0.18s var(--ease), color 0.18s var(--ease);
}
.formula-input:hover { border-color: var(--accent); }
.formula-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Parse error / note for the custom formula. Empty => collapsed. Warm tone so it reads as "fix this". */
.formula-error {
	font-family: var(--font-mono);
	font-size: var(--fs-small);
	text-transform: none;
	color: #cf6a43;
	max-width: 30ch;
}
.formula-error:empty { display: none; }

/* ---- Analysis / data tables (blackjack writeup) ------------------------- */

.data-table {
	width: 100%;
	border-collapse: collapse;
	font-family: var(--font-mono);
	font-size: var(--fs-small);
}
.data-table th, .data-table td {
	text-align: left;
	padding: var(--sp-2) var(--sp-3);
	border-bottom: 1px solid var(--rule);
}
.data-table th {
	color: var(--ink-faint);
	font-weight: 400;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	font-size: var(--fs-mono);
}
.data-table td { color: var(--ink-soft); }
.data-table td.num { text-align: right; color: var(--ink); }
.data-table td.a { text-align: center; color: var(--ink); }
.data-table td.a.dd { color: var(--accent); font-weight: 500; }

/* ---- Sub-page header + back link ---------------------------------------- */

.page-header { padding: var(--sp-6) 0 var(--sp-5); }
.page-header .eyebrow { margin-bottom: var(--sp-3); }
.page-header h1 { font-size: var(--fs-h1); font-weight: 500; }
.page-header .lead { margin-top: var(--sp-3); color: var(--ink-soft); max-width: 58ch; }

.backlink {
	display: inline-flex;
	align-items: center;
	gap: 0.5ch;
	margin-top: var(--sp-6);
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.06em;
	color: var(--ink-faint);
}
.backlink:hover { color: var(--accent); }
.backlink .arrow { transition: transform 0.2s var(--ease); }
.backlink:hover .arrow { transform: translateX(-3px); }

/* ---- Snake --------------------------------------------------------------- */

.snake-wrap {
	width: 100%;
	overflow-x: auto;
	display: flex;
	justify-content: center;
}
#snake-box {
	display: grid;
	grid-template-rows: repeat(50, 12px);
	grid-template-columns: repeat(50, 12px);
	border: 1px solid var(--rule);
	background: #fff;
	flex: none;
}
.snake-square { border: 1px solid #ececec; }

/* ---- Fractal ------------------------------------------------------------- */

/* Canvas row spans the frame's inner width (reclaiming its horizontal padding) so the
   responsive canvas gets the full column; the engine (ui/viewport) sizes the easel from
   this container's width + the requested aspect, and the buffer from the device's
   resolution setting. */
.fractal-stage {
	display: flex;
	justify-content: center;
	width: calc(100% + 2 * var(--sp-5));
	margin-left: calc(-1 * var(--sp-5));
	margin-right: calc(-1 * var(--sp-5));
}

.easel {
	position: relative;
	max-width: 100%;
	flex: none;
	background: #000;
}
.easel > canvas { position: absolute; top: 0; left: 0; }

/* Action row (zoom / back / out / reset). On narrow screens it becomes a sticky,
   thumb-reachable bar — see the fractal mobile block below. */
.fractal-actions {
	width: 100%;
	display: flex;
	gap: var(--sp-3);
	justify-content: center;
}

/* Progressive-sharpening readout over the canvas: the undetermined-point count,
   which appears with the first frame and counts down as the idle passes resolve
   it. Empty text (set by JS between views) fades it out. The leading dot pulses
   while workers are still refining and turns solid green once the view settles. */
.sharpen-status {
	position: absolute;
	left: 10px;
	bottom: 10px;
	z-index: 2;
	pointer-events: none;
	font-family: var(--font-mono);
	font-size: 0.72rem;
	letter-spacing: 0.03em;
	color: var(--ink-soft);
	background: var(--surface);
	border: 1px solid var(--rule);
	border-radius: var(--r-sm);
	padding: 5px 8px 5px 7px;
	opacity: 0;
	transition: opacity 0.25s var(--ease);
}
.sharpen-status:not(:empty) { opacity: 0.92; }
.sharpen-status::before {
	content: "";
	display: inline-block;
	width: 6px; height: 6px;
	margin-right: 6px;
	border-radius: 50%;
	background: var(--accent);
	vertical-align: middle;
}
.sharpen-status.is-active::before { animation: sharpen-pulse 1s ease-in-out infinite; }
.sharpen-status.is-done::before { background: #3ba55d; animation: none; }
@keyframes sharpen-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.2; } }
@media (prefers-reduced-motion: reduce) { .sharpen-status.is-active::before { animation: none; } }

/* Heuristic-map flag: shown (JS sets the text) only when a "Mandelbrot" is really a z₀=c parameter
   map — a formula with no z₀=0 set. Amber, top-left; hidden for true Mandelbrot and Julia sets. */
.map-note {
	position: absolute;
	left: 10px;
	top: 10px;
	z-index: 2;
	cursor: help;
	font-family: var(--font-mono);
	font-size: 0.72rem;
	letter-spacing: 0.04em;
	color: #bd8630;
	background: var(--surface);
	border: 1px solid #7a5a2a;
	border-radius: var(--r-sm);
	padding: 5px 8px;
	opacity: 0;
	transition: opacity 0.25s var(--ease);
}
.map-note.is-shown { opacity: 0.94; }
.map-note::before { content: "≈ "; opacity: 0.7; }

/* High-precision (double-double) indicator — mirrors .sharpen-status but bottom-right,
   with an amber dot to flag that deep views trade render speed for accuracy. */
.precision-status {
	position: absolute;
	right: 10px;
	bottom: 10px;
	z-index: 2;
	pointer-events: none;
	font-family: var(--font-mono);
	font-size: 0.72rem;
	letter-spacing: 0.03em;
	color: var(--ink-soft);
	background: var(--surface);
	border: 1px solid var(--rule);
	border-radius: var(--r-sm);
	padding: 5px 8px 5px 7px;
	opacity: 0;
	transition: opacity 0.25s var(--ease);
}
.precision-status:not(:empty) { opacity: 0.55; }          /* always shown, but quiet at 64-bit */
.precision-status.is-elevated { opacity: 0.92; }          /* prominent once past f64 */
.precision-status::before {
	content: "";
	display: inline-block;
	width: 6px; height: 6px;
	margin-right: 6px;
	border-radius: 50%;
	background: var(--ink-soft);                           /* neutral dot at f64 */
	vertical-align: middle;
}
.precision-status.is-elevated::before { background: #d9a441; }   /* amber once precision is elevated */

/* Fractal on narrow screens (phones): the canvas + a thumb-reachable action bar ARE the
   interface (the engine collapses the control sections on coarse pointers); every target
   grows to a comfortable touch size. Scoped to the demo frame so the rest of the site is
   untouched. */
@media (max-width: 700px) {
	.fractal-actions {
		position: sticky;
		bottom: calc(8px + env(safe-area-inset-bottom));
		z-index: 5;
		gap: var(--sp-2);
		padding: var(--sp-2);
		background: var(--surface);
		border: 1px solid var(--rule);
		border-radius: var(--r-sm);
	}
	.fractal-actions .btn { flex: 1; min-height: 44px; }
	.demo-frame .field { min-height: 40px; }
	.demo-frame .field select { padding: 10px 12px; min-height: 40px; }
	.demo-frame .field input[type="checkbox"] { width: 20px; height: 20px; }
	.demo-frame .field input[type="range"] { width: 140px; height: 28px; }
	.demo-frame .formula-input { width: 100%; }
	.demo-frame .formula-custom { flex-basis: 100%; }
	.demo-frame .telemetry { grid-template-columns: repeat(2, 1fr); gap: 9px 12px; }
}

/* ---- Mandelbrot-boundary background (home) ------------------------------ */

.mandel-bg {
	position: fixed;
	inset: 0;
	width: 100vw;
	height: 100vh;
	z-index: -1;
	pointer-events: none;
	opacity: 0;
	transition: opacity 0.8s var(--ease);
}
.mandel-bg.ready { opacity: 1; }
@media print { .mandel-bg { display: none; } }

/* ---- Julia widget (home-page mouse-follow fractal) ---------------------- */

.julia-widget {
	position: fixed;
	right: 16px;
	bottom: 16px;
	z-index: 50;
	pointer-events: none;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 5px;
}
.julia-widget canvas {
	width: 160px;
	height: 160px;
	display: block;
	image-rendering: pixelated;
}
.julia-widget .jw-label {
	font-family: var(--font-mono);
	font-size: var(--fs-mono);
	letter-spacing: 0.02em;
	color: var(--ink-faint);
}
@media (max-width: 700px) { .julia-widget { display: none; } }
@media print { .julia-widget { display: none; } }

/* ---- Motion -------------------------------------------------------------- */

@keyframes rise {
	from { opacity: 0; transform: translateY(10px); }
	to   { opacity: 1; transform: translateY(0); }
}
.rise { animation: rise 0.6s var(--ease) both; }
.rise-1 { animation-delay: 0.05s; }
.rise-2 { animation-delay: 0.13s; }
.rise-3 { animation-delay: 0.21s; }

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
	}
}

/* ---- Responsive ---------------------------------------------------------- */

@media (max-width: 560px) {
	.page, .nav, .footer { padding-left: var(--sp-4); padding-right: var(--sp-4); }
	.resume-head { align-items: flex-start; }
	.resume-contact { text-align: left; }
	.resume-contact .row { justify-content: flex-start; }
	.nav-links { gap: var(--sp-4); }
}

/* ---- Print --------------------------------------------------------------- */

@media print {
	:root {
		--paper: #fff; --surface: #fff;
		--ink: #000; --ink-soft: #1a1a1a; --ink-faint: #444;
		--rule: #bbb; --accent: #000; --accent-strong: #000; --halo: transparent;
	}
	@page { margin: 14mm; }

	body { background: #fff; color: #000; font-size: 10.5pt; line-height: 1.4; }

	.nav, .footer, .toolbar, .hero-meta .no-print { display: none !important; }

	.page { max-width: 100%; padding: 0; }

	a { color: #000; }

	/* flatten all the interactive flourishes */
	.entry::before, .nav-links a::after, .card .card-title .arrow { display: none; }
	.card, .chip, .demo-frame { box-shadow: none; border-color: #ccc; }

	.section { margin-top: 14pt; }
	.resume-summary { margin: 10pt 0; font-size: 11pt; }
	.entry { break-inside: avoid; page-break-inside: avoid; }
	.chips { gap: 4pt; }
	.chip { padding: 1pt 5pt; }
	h1, h2, h3 { break-after: avoid; page-break-after: avoid; }
}
