/* Global CSS — reset + CRT atmosphere + prose + house code theme.
   All COMPONENT styling lives in StyleX. This file is atmosphere only. */

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

html {
	color-scheme: dark;
	scroll-behavior: smooth;
}

body {
	margin: 0;
	background:
		radial-gradient(120% 80% at 50% -10%, rgba(255, 123, 0, 0.06), transparent 55%),
		radial-gradient(90% 60% at 100% 110%, rgba(153, 77, 0, 0.1), transparent 60%), #0c0702;
	color: #ece3d0;
	font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 1rem;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
	overflow-x: hidden;
}

/* Graph-paper grid behind everything */
body::before {
	content: "";
	position: fixed;
	inset: 0;
	z-index: -2;
	pointer-events: none;
	background-image:
		linear-gradient(rgba(255, 176, 0, 0.04) 1px, transparent 1px),
		linear-gradient(90deg, rgba(255, 176, 0, 0.04) 1px, transparent 1px);
	background-size: 56px 56px;
	opacity: 0.35;
	mask-image: radial-gradient(closest-side, rgba(0, 0, 0, 0.75), transparent 70%);
}

/* Aperture grille + scanlines + vignette + bezel */
body::after {
	content: "";
	position: fixed;
	inset: 0;
	z-index: 999;
	pointer-events: none;
	mix-blend-mode: multiply;
	opacity: 0.42;
	background-image:
		repeating-linear-gradient(
			90deg,
			rgba(0, 0, 0, 0.1) 0px,
			rgba(0, 0, 0, 0.1) 1px,
			transparent 1px,
			transparent 3px
		),
		repeating-linear-gradient(
			0deg,
			rgba(0, 0, 0, 0.1) 0px,
			rgba(0, 0, 0, 0.1) 1px,
			transparent 1px,
			transparent 3px
		),
		radial-gradient(130% 120% at 50% 50%, transparent 60%, rgba(0, 0, 0, 0.5) 100%);
	box-shadow:
		inset 0 0 110px 32px rgba(0, 0, 0, 0.3),
		inset 0 0 0 2px rgba(255, 123, 0, 0.06);
}

/* Film grain — SVG feTurbulence, soft-light */
.grain {
	position: fixed;
	inset: 0;
	z-index: 998;
	pointer-events: none;
	opacity: 0.06;
	mix-blend-mode: soft-light;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (pointer: coarse), (max-width: 719px) {
	.grain {
		display: none;
	}
}

::selection {
	background: rgba(255, 176, 0, 0.4);
	color: #0a0806;
}

:focus-visible {
	outline: 2px solid #2e8bff;
	outline-offset: 2px;
}

/* Scrollbars — amber, thin */
* {
	scrollbar-width: thin;
	scrollbar-color: rgba(255, 123, 0, 0.35) transparent;
}

a {
	color: #2e8bff;
	text-decoration: none;
	border-bottom: 1px solid rgba(46, 139, 255, 0.35);
	transition:
		color 120ms ease,
		border-color 120ms ease;
}

a:hover {
	color: #7cc2ff;
	border-bottom-color: rgba(124, 194, 255, 0.6);
}

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

/* Projects grid — old dense span system (nth-child can't live in StyleX) */
.projects-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1rem;
}

@media (min-width: 720px) {
	.projects-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 1.2rem;
	}
}

@media (min-width: 1100px) {
	.projects-grid {
		grid-template-columns: repeat(6, minmax(0, 1fr));
		grid-auto-flow: dense;
		gap: 1.25rem;
	}

	.projects-grid > * {
		grid-column: span 2;
	}

	.projects-grid > *:nth-child(1),
	.projects-grid > *:nth-child(2) {
		grid-column: span 3;
	}

	.projects-grid > *:nth-child(6),
	.projects-grid > *:nth-child(7) {
		grid-column: span 3;
	}
}

/* Raw-SVG icons (Icon.tsx) — sized in em off the span's font-size. */ .icon {
	display: inline-flex;
	align-items: center;
	vertical-align: -0.125em;
	line-height: 1;
	flex-shrink: 0;
}

.icon svg {
	width: 1em;
	height: 1em;
	fill: currentColor;
}

.skip-link {
	position: absolute;
	/* inline-start = the non-scrollable side in BOTH directions: an LTR
	   document scrolls rightward only, an RTL one leftward only — parking
	   the link on inline-start keeps it out of the scroll region in both */
	inset-inline-start: -999px;
	top: 0;
	z-index: 1200;
	background: #2e8bff;
	color: #0c0702;
	padding: 0.5rem 1rem;
	font-weight: 600;
}

.skip-link:focus {
	inset-inline-start: 0;
}

/* ---- prose (markdown body) ---- */

.prose {
	line-height: 1.75;
}

.prose h1,
.prose h2,
.prose h3,
.prose h4 {
	font-family: VT323, "IBM Plex Mono", monospace;
	color: #ffce5c;
	letter-spacing: 0.01em;
	font-weight: 400;
	line-height: 1.25;
	margin: 2em 0 1em;
	scroll-margin-top: 5rem;
}

.prose h2 {
	font-size: 1.5rem;
	margin-top: 2em;
	margin-bottom: 1em;
}

/* copy-section buttons — v2 kit, inline right after the heading text,
   quiet until the heading is engaged */
.prose .sec-copy {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.7rem;
	height: 1.7rem;
	margin-left: 0.55rem;
	padding: 0;
	vertical-align: -0.25em;
	border: 1px solid #333;
	background: transparent;
	color: #999;
	cursor: pointer;
	opacity: 0;
	transition:
		opacity 0.15s ease,
		color 0.15s ease,
		border-color 0.15s ease;
}

.prose h2:hover > .sec-copy,
.prose h3:hover > .sec-copy,
.prose h2:focus-within > .sec-copy,
.prose h3:focus-within > .sec-copy,
.prose .sec-copy:focus-visible {
	opacity: 0.85;
}

.prose .sec-copy:hover {
	color: #fff;
	border-color: #ff7b00;
}

.prose .sec-copy.copied {
	color: #ff7b00;
	border-color: #ff7b00;
	opacity: 1;
}

@media (hover: none) {
	.prose .sec-copy {
		opacity: 0.5;
	}
}

.prose h3 {
	font-size: 1.25rem;
	margin-top: 1.6em;
	margin-bottom: 0.6em;
}

.prose p {
	margin: 1.25em 0;
	color: #ece3d0;
}

.prose a {
	color: #2e8bff;
	border-bottom: 1px solid rgba(46, 139, 255, 0.38);
}

.prose a:hover {
	color: #7cc2ff;
	border-bottom-color: rgba(124, 194, 255, 0.6);
}

.prose strong {
	color: #ece3d0;
	font-weight: 600;
}

/* Chat dock — critical LAYOUT. Lives in this document stylesheet on
   purpose: the StyleX dev payload can land after first paint and the bar
   flashed unstyled, inline mid-content (2026-10-08). Plain css cannot lose
   that race, dev or prod. The hide state rides [data-past]. Logical props
   — centered without a transform, RTL-safe. */
.chat-dock {
	position: fixed;
	inset-inline: 0;
	bottom: calc(0.55rem + env(safe-area-inset-bottom));
	margin-inline: auto;
	width: min(680px, calc(100vw - 2rem));
	z-index: 1000;
	display: flex;
	flex-direction: column;
}
.chat-dock[data-past="true"] {
	opacity: 0;
	transform: translateY(140%);
	visibility: hidden;
	pointer-events: none;
}
@media (max-width: 719px) {
	.chat-dock {
		bottom: calc(0.45rem + env(safe-area-inset-bottom));
		width: calc(100vw - 1.4rem);
	}
}

/* Answer cards (plan A5) — <blockquote data-answer> = canonical-fact
   blocks agents cite verbatim; humans see the amber "ANSWER" tag. */
.prose blockquote[data-answer] {
	border-left: 2px solid #ffb000;
	position: relative;
	padding-top: 1.4rem;
}
.prose blockquote[data-answer]::before {
	content: "ANSWER";
	position: absolute;
	top: 0.15rem;
	left: 0.8rem;
	font-family: "IBM Plex Mono", monospace;
	font-size: 0.62rem;
	letter-spacing: 0.18em;
	color: #ffb000;
	opacity: 0.85;
}

.prose blockquote {
	margin: 1.6em 0;
	padding: 0 0 0 1em;
	border-left: 0.25rem solid rgba(255, 176, 0, 0.4);
	color: rgba(236, 227, 208, 0.72);
	font-style: italic;
	font-weight: 500;
}

.prose blockquote p {
	color: inherit;
	margin: 0.35rem 0;
}

.prose ul,
.prose ol {
	margin: 0.9rem 0;
	padding-left: 1.5rem;
	color: rgba(236, 227, 208, 0.88);
}

.prose li {
	margin: 0.3rem 0;
}

.prose li::marker {
	color: #ffb000;
}

.prose code {
	font-family: inherit;
	font-size: 0.88em;
	background: rgba(0, 0, 0, 0.5);
	border: 1px solid rgba(255, 123, 0, 0.2);
	padding: 0.15rem 0.4rem;
	color: #ffce5c;
	font-weight: 600;
}

.prose pre {
	position: relative;
	background: #170d03;
	border: 1px solid rgba(255, 123, 0, 0.2);
	padding: 0.857rem 1.142rem;
	overflow-x: auto;
	margin: 1.3rem 0;
	font-size: 0.95rem;
	line-height: 1.6;
}

.prose pre code {
	background: none;
	border: none;
	padding: 0;
	color: #ece3d0;
	white-space: pre;
}

.prose img {
	border: 1px solid rgba(255, 123, 0, 0.2);
	margin: 1.4rem 0;
}

.prose hr {
	border: none;
	border-top: 1px dashed rgba(255, 123, 0, 0.35);
	margin: 2.5rem auto;
	width: 60%;
}

.prose table {
	border-collapse: collapse;
	width: 100%;
	margin: 1.4rem 0;
	font-size: 0.88rem;
}

.prose th,
.prose td {
	border: 1px solid rgba(255, 123, 0, 0.2);
	padding: 0.5rem 0.8rem;
	text-align: left;
}

.prose th {
	font-family: VT323, monospace;
	letter-spacing: 0.06em;
	color: #ffce5c;
	background: rgba(255, 176, 0, 0.1);
}

.prose tbody tr:nth-child(2n) {
	background: rgba(255, 176, 0, 0.04);
}

/* code-scroll wrappers (applied client-side around each pre) */
.code-scroll {
	position: relative;
}

.code-scroll pre {
	margin: 0;
}

.codebar {
	position: absolute;
	top: 0;
	right: 0;
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.25rem 0.5rem;
	font-size: 0.72rem;
	color: rgba(236, 227, 208, 0.55);
	opacity: 0;
	transition: opacity 120ms ease;
	background: linear-gradient(180deg, rgba(23, 13, 3, 0.95), rgba(23, 13, 3, 0.7));
	border-left: 1px solid rgba(255, 123, 0, 0.2);
	border-bottom: 1px solid rgba(255, 123, 0, 0.2);
}

.code-scroll:hover .codebar,
.code-scroll:focus-within .codebar {
	opacity: 1;
}

.codebar button {
	background: none;
	border: 1px solid rgba(255, 123, 0, 0.35);
	color: #ffb000;
	font: inherit;
	font-size: 0.72rem;
	padding: 0.55rem 0.8rem;
	min-height: 40px;
	cursor: pointer;
}

.codebar button:hover {
	background: rgba(255, 176, 0, 0.1);
}

/* table scroll wrapper */
.table-scroll {
	overflow-x: auto;
	border: 1px solid rgba(255, 123, 0, 0.2);
}

.table-scroll table {
	margin: 0;
}

/* ---- rich-body vocabulary (2026-10-02): TL;DR callout + figures.
   Scoped classes so post bodies carry them through dangerouslySetInnerHTML. */

.prose .tldr {
	margin: 1.4rem 0 1.6rem;
	padding: 0.9rem 1.1rem;
	background: rgba(255, 176, 0, 0.04);
	border: 1px solid rgba(255, 123, 0, 0.2);
	border-left: 3px solid #ffb000;
}

.prose .tldr-tag {
	display: block;
	font-family: VT323, "IBM Plex Mono", monospace;
	font-size: 0.85rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: #ffb000;
	margin: 0 0 0.35rem;
}

.prose .tldr p {
	margin: 0;
}

.prose .tldr ul {
	margin: 0 0 0.5rem;
	padding-left: 1.1rem;
}

.prose .tldr li {
	margin: 0.3rem 0;
}

.prose figure.fig {
	margin: 1.6rem 0;
	padding: 1rem 0.8rem 0.6rem;
	background: rgba(0, 0, 0, 0.3);
	border: 1px solid rgba(255, 123, 0, 0.2);
}

.prose .fig svg {
	display: block;
	width: 100%;
	height: auto;
}

.prose .fig text {
	font-family: "IBM Plex Mono", monospace;
	fill: #ece3d0;
}

.prose .fig .node rect {
	fill: rgba(23, 13, 3, 0.92);
	stroke: #ffb000;
	stroke-width: 1.2;
}

.prose .fig .node.dim rect {
	stroke: rgba(255, 176, 0, 0.4);
}

.prose .fig .edge {
	fill: none;
	stroke: rgba(255, 176, 0, 0.55);
	stroke-width: 1.2;
}

.prose .fig .edge.anim {
	stroke-dasharray: 5 5;
	animation: fig-dash 1.2s linear infinite;
}

.prose .fig .lbl {
	font-size: 12px;
	fill: #ffce5c;
}

.prose .fig .lbl-body {
	font-size: 11px;
}

.prose .fig .lbl-cmd {
	font-size: 0.65rem;
	fill: #ffce5c;
}

.prose .fig .lbl-dim {
	font-size: 0.65rem;
	fill: rgba(236, 227, 208, 0.55);
}

.prose .fig a {
	cursor: pointer;
}

/* biome-ignore lint/style/noDescendingSpecificity: prose theme is hand-ordered */
.prose .fig a:hover rect {
	stroke: #ffce5c;
	stroke-width: 2;
}

@keyframes fig-dash {
	to {
		stroke-dashoffset: -20;
	}
}

@media (prefers-reduced-motion: reduce) {
	.prose .fig .edge.anim {
		animation: none;
	}
}

/* ---- v2 body kit: icons, sortable tables, checklists, reveals ---- */

.prose h2 .icon {
	font-size: 1.25rem;
	color: #ffb000;
	margin-right: 0.5rem;
	vertical-align: -0.18em;
}

.prose p .icon,
.prose li .icon,
.prose td .icon,
.prose summary .icon {
	font-size: 1em;
	color: #ffb000;
	vertical-align: -0.12em;
	margin-right: 0.3em;
}

.prose table[data-sortable] th[data-sort] {
	cursor: pointer;
	user-select: none;
}

.prose table[data-sortable] th[data-sort]::after {
	content: " ↕";
	opacity: 0.45;
	font-size: 0.85em;
}

.prose table[data-sortable] th[data-sort].sort-asc::after {
	content: " ↑";
	opacity: 1;
}

.prose table[data-sortable] th[data-sort].sort-desc::after {
	content: " ↓";
	opacity: 1;
}

.prose ul.checklist {
	list-style: none;
	padding-left: 0;
}

.prose ul.checklist li {
	margin: 0.45rem 0;
}

.prose ul.checklist label {
	/* block flow — flex split each inline segment (text/code/text) into its
	   own item and scattered long lines across the row */
	display: block;
	cursor: pointer;
}

.prose ul.checklist input[type="checkbox"] {
	accent-color: #ffb000;
	width: 1rem;
	height: 1rem;
	margin-right: 0.6rem;
	transform: translateY(2px);
}

.prose ul.checklist li.done label {
	color: rgba(236, 227, 208, 0.55);
	text-decoration: line-through;
}

.prose .check-progress {
	font-family: "IBM Plex Mono", monospace;
	font-size: 0.75rem;
	letter-spacing: 0.1em;
	color: #ffb000;
	margin: 0 0 0.4rem;
}

.prose details.note {
	margin: 1.2rem 0;
	border: 1px dashed rgba(255, 123, 0, 0.35);
	background: rgba(0, 0, 0, 0.3);
}

.prose details.note summary {
	cursor: pointer;
	padding: 0.5rem 0.9rem;
	color: #ffce5c;
	font-family: "IBM Plex Mono", monospace;
	font-size: 0.85rem;
	list-style: none;
}

.prose details.note summary::-webkit-details-marker {
	display: none;
}

.prose details.note summary::before {
	content: "▸ ";
}

.prose details.note[open] summary::before {
	content: "▾ ";
}

.prose details.note > p {
	padding: 0 0.9rem;
	margin: 0.4rem 0 0.7rem;
}

/* ---- v2 instrument kit: filter chips, verify lines, stack strip ---- */

.prose .chiprow {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	margin: 0.9rem 0 0.4rem;
}

.prose .chip {
	font-family: "IBM Plex Mono", monospace;
	font-size: 0.75rem;
	letter-spacing: 0.04em;
	padding: 0.22rem 0.65rem;
	border: 1px solid rgba(255, 123, 0, 0.35);
	color: rgba(236, 227, 208, 0.72);
	cursor: pointer;
	user-select: none;
}

.prose .chip .icon {
	font-size: 0.9em;
	vertical-align: -0.1em;
	margin-right: 0.3em;
	color: #ffb000;
}

.prose .chip.on {
	background: #ffb000;
	border-color: #ffb000;
	color: #170d03;
}

.prose .chip.on .icon {
	color: #170d03;
}

.prose .verify {
	font-family: "IBM Plex Mono", monospace;
	font-size: 0.82rem;
	color: rgba(236, 227, 208, 0.72);
	border-left: 2px solid rgba(255, 176, 0, 0.4);
	padding: 0.3rem 0.7rem;
	margin: 1rem 0;
}

/* biome-ignore lint/style/noDescendingSpecificity: prose theme is hand-ordered */
.prose .verify .icon {
	color: #ffb000;
}

.prose .stack {
	font-family: "IBM Plex Mono", monospace;
	font-size: 0.75rem;
	letter-spacing: 0.03em;
	color: rgba(236, 227, 208, 0.55);
	border-top: 1px dashed rgba(255, 123, 0, 0.2);
	padding-top: 0.6rem;
	margin: 0.8rem 0 0;
}

/* biome-ignore lint/style/noDescendingSpecificity: prose theme is hand-ordered */
.prose .stack .icon {
	color: #ffb000;
	margin-right: 0.2em;
}

/* glossary popovers */
.prose abbr[data-term] {
	text-decoration: underline dotted rgba(255, 176, 0, 0.55);
	cursor: help;
}

.termpop {
	position: fixed;
	z-index: 60;
	display: none;
	max-width: 270px;
	background: #170d03;
	border: 1px solid #ffb000;
	padding: 0.5rem 0.7rem;
	font-family: "IBM Plex Mono", monospace;
	font-size: 0.75rem;
	line-height: 1.5;
	color: #ece3d0;
	pointer-events: none;
}

/* figures wake on scroll — gated by .figready so no-JS stays visible */
.prose .fig.figready .edge.anim {
	animation-play-state: paused;
}

.prose .fig.figready.inview .edge.anim {
	animation-play-state: running;
}

.prose .fig.figready .node,
.prose .fig.figready .edge,
/* biome-ignore lint/style/noDescendingSpecificity: prose theme is hand-ordered */
	.prose
	.fig.figready
	> svg
	> rect {
	opacity: 0;
	transition: opacity 500ms ease;
}

.prose .fig.figready.inview .node,
.prose .fig.figready.inview .edge,
.prose .fig.figready.inview > svg > rect {
	opacity: 1;
}

/* print runbook — chrome off, reveals open, dark ink on white */
@media print {
	header,
	nav,
	aside,
	.grain,
	.chiprow,
	.sec-copy {
		/* biome-ignore lint/complexity/noImportantStyles: print runbook must beat runtime stylex styles */
		display: none !important;
	}

	.prose,
	.prose p,
	.prose li,
	.prose h1,
	.prose h2,
	.prose h3,
	.prose strong {
		/* biome-ignore lint/complexity/noImportantStyles: print runbook must beat runtime stylex styles */
		color: #111 !important;
	}

	.prose a {
		/* biome-ignore lint/complexity/noImportantStyles: print runbook must beat runtime stylex styles */
		color: #111 !important;
		text-decoration: underline;
	}

	.prose pre,
	.prose code,
	.prose td,
	.prose th,
	.prose .tldr,
	.prose .fig {
		/* biome-ignore lint/complexity/noImportantStyles: print runbook must beat runtime stylex styles */
		background: #fff !important;
		/* biome-ignore lint/complexity/noImportantStyles: print runbook must beat runtime stylex styles */
		border-color: #999 !important;
		/* biome-ignore lint/complexity/noImportantStyles: print runbook must beat runtime stylex styles */
		color: #111 !important;
	}

	.prose details:not([open]) > *:not(summary) {
		/* biome-ignore lint/complexity/noImportantStyles: print runbook must beat runtime stylex styles */
		display: block !important;
	}

	.prose details.note summary {
		color: #111;
	}

	figure.fig,
	.prose pre,
	.prose table {
		break-inside: avoid;
	}
}

/* ---- house syntax-highlight theme (hljs classes) ---- */

.hljs-comment,
.hljs-quote {
	color: #8a6d45;
	font-style: italic;
}

.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-doctag {
	color: #ff7b00;
}

.hljs-string,
.hljs-regexp,
.hljs-addition {
	color: #f6c177;
}

.hljs-number,
.hljs-symbol,
.hljs-bullet,
.hljs-meta {
	color: #ffce5c;
}

.hljs-title,
.hljs-section,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
	color: #2e8bff;
}

.hljs-attr,
.hljs-attribute,
.hljs-variable,
.hljs-template-variable,
.hljs-type {
	color: #ffce5c;
}

.hljs-built_in,
.hljs-builtin-name {
	color: #7cc2ff;
}

.hljs-deletion {
	color: #ff4d4d;
}

.hljs-emphasis {
	font-style: italic;
}

.hljs-strong {
	font-weight: 600;
}

/* ---- tanstack/highlight class bridge (th-* spans) ----
   chat renderer + post code fallback share @tanstack/highlight; same house
   palette as the hljs theme above. */

.th-token.th-comment {
	color: #8a6d45;
	font-style: italic;
}

.th-token.th-keyword,
.th-token.th-literal {
	color: #ff7b00;
}

.th-token.th-string,
.th-token.th-inserted {
	color: #f6c177;
}

.th-token.th-number,
.th-token.th-meta,
.th-token.th-attr,
.th-token.th-variable,
.th-token.th-property,
.th-token.th-type {
	color: #ffce5c;
}

.th-token.th-function,
.th-token.th-heading,
.th-token.th-selector,
.th-token.th-tag,
.th-token.th-link {
	color: #2e8bff;
}

.th-token.th-command {
	color: #7cc2ff;
}

.th-token.th-deleted {
	color: #ff4d4d;
}

/* ---- toasts ---- */

.toast-region {
	position: fixed;
	bottom: 1rem;
	left: 50%;
	transform: translateX(-50%);
	z-index: 1100;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	align-items: center;
	/* toasts must never eat mouse events — they hover over the article and
	   intercepted selection drags, which read as "copy is flaky" */
	pointer-events: none;
}

.toast {
	background: #120902;
	border: 1px solid rgba(255, 123, 0, 0.35);
	color: #ffce5c;
	padding: 0.55rem 1rem;
	font-size: 0.82rem;
	box-shadow: 0 0 24px rgba(255, 123, 0, 0.2);
	animation: toast-in 0.35s ease-out;
	pointer-events: none;
}

@keyframes toast-in {
	from {
		opacity: 0;
		transform: translateY(0.4rem);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

/* blinking terminal cursor */
.cursor {
	display: inline-block;
	width: 0.55em;
	background: #ffb000;
	animation: blink 1.1s steps(1) infinite;
	color: transparent;
	user-select: none;
}

/* nav shell framing: '>' prompt (in JSX) + animated underline bar;
   current page keeps a persistent azure bar */
.nav-link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: -0.1rem;
	height: 1px;
	background: currentColor;
	opacity: 0;
	transform: translateY(3px);
	transition:
		opacity 0.18s,
		transform 0.18s;
}
.nav-link:hover::after {
	opacity: 0.85;
	transform: translateY(0);
}
/* persistent current-page bar removed (owner, 2026-10-08) — active state is
   color only (navLinkActive azure); underline stays a hover affordance */

/* page-termbar cursor ticks at the CRT refresh rate (1.4s), footer at 1.1s */
.termbar .cursor {
	animation-duration: 1.4s;
}

/* ---------- opt-in CRT refresh mode (localStorage crt=1) ---------- */
.crt-flicker {
	position: fixed;
	inset: 0;
	z-index: 251;
	pointer-events: none;
	background: rgba(255, 176, 0, 0.04);
	mix-blend-mode: screen;
	animation: crt-flicker 0.085s steps(2, end) infinite;
}
@keyframes crt-flicker {
	0% {
		opacity: 0.2;
	}
	100% {
		opacity: 1;
	}
}
.crt-roll {
	position: fixed;
	left: 0;
	right: 0;
	height: 60px;
	z-index: 55;
	pointer-events: none;
	mix-blend-mode: screen;
	background: linear-gradient(
		to bottom,
		transparent,
		rgba(255, 176, 0, 0.04) 45%,
		rgba(255, 206, 92, 0.09) 50%,
		rgba(255, 176, 0, 0.04) 55%,
		transparent
	);
	animation: crt-roll 11s linear infinite;
	transform: translateY(-15vh);
}
@keyframes crt-roll {
	0% {
		transform: translateY(-15vh);
	}
	68% {
		transform: translateY(115vh);
	}
	100% {
		transform: translateY(115vh);
	}
}
@media (prefers-reduced-motion: reduce) {
	.crt-flicker,
	.crt-roll {
		display: none;
	}
}

/* ---------- 404 "no signal" glitch bars ---------- */
.nosync {
	position: fixed;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	display: grid;
	place-items: center;
}
.nosync__bar {
	grid-area: 1 / 1;
	width: 100%;
	height: 2px;
	background: rgba(255, 123, 0, 0.6);
	box-shadow: 0 0 12px rgba(255, 123, 0, 0.6);
	transform: translateY(-1px);
}
.nosync__bar--ghost {
	background: rgba(255, 176, 0, 0.4);
	transform: translateY(1px) translateX(2px);
	filter: blur(0.5px);
	animation: nosync-glitch 1.2s steps(8, end) 1 both;
}
@keyframes nosync-glitch {
	0% {
		opacity: 0;
		transform: translateY(1px) translateX(0);
	}
	10% {
		opacity: 1;
		transform: translateY(1px) translateX(-6px);
	}
	25% {
		transform: translateY(1px) translateX(5px);
	}
	40% {
		opacity: 0.4;
		transform: translateY(1px) translateX(-3px);
	}
	60% {
		opacity: 1;
		transform: translateY(1px) translateX(2px);
	}
	100% {
		opacity: 0.35;
		transform: translateY(1px) translateX(2px);
	}
}
@media (prefers-reduced-motion: reduce) {
	.nosync__bar--ghost {
		animation: none;
	}
}

/* ---------- neofetch boot sequence (old component CSS, verbatim) ---------- */
.neofetch {
	padding: 0;
	margin-top: 0;
	overflow: hidden;
}
.nf-prompt {
	margin: 0 0 1rem;
	font-family: var(--font-mono, "IBM Plex Mono", monospace);
	font-size: clamp(0.85rem, 1.6vw, 1rem);
	line-height: 1.7;
	white-space: pre;
}
.nf-dollar {
	color: rgba(255, 176, 0, 0.55);
}
.nf-typed {
	color: #ffce5c;
}
.nf-cursor {
	color: #ffce5c;
	animation: nf-blink 0.9s steps(1) infinite;
}
@keyframes nf-blink {
	50% {
		opacity: 0;
	}
}
.nf-body {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: clamp(1.4rem, 3vw, 2.6rem);
	align-items: center;
}
.nf-logo {
	margin: 0;
	font-family: var(--font-mono, "IBM Plex Mono", monospace);
	font-size: clamp(0.5rem, 1.4vw, 0.95rem);
	line-height: 0.92;
	letter-spacing: 0;
	color: #ffce5c;
	white-space: pre;
	overflow: hidden;
	text-shadow:
		0 0 1px #ffce5c,
		0 0 4px rgba(255, 123, 0, 0.35),
		0 0 10px rgba(255, 123, 0, 0.2);
	user-select: none;
}
.nf-logo-line {
	display: block;
}
.nf-shh {
	font-size: 2em;
	letter-spacing: 0.12em;
	padding-left: 0.25ch;
	padding-top: 0.5em;
	margin-bottom: -1.17em;
}
.nf-info {
	font-family: var(--font-mono, "IBM Plex Mono", monospace);
	font-size: clamp(0.9rem, 1.65vw, 1.08rem);
	line-height: 1.7;
	min-width: 0;
}
.nf-host {
	margin: 0;
	font-family: var(--font-mono, "IBM Plex Mono", monospace);
	font-weight: 700;
	font-size: clamp(1.1rem, 2.2vw, 1.35rem);
	line-height: 1.3;
	color: #ffce5c;
	text-shadow:
		0 0 1px #ffce5c,
		0 0 8px rgba(255, 123, 0, 0.35);
}
.nf-at {
	color: rgba(255, 176, 0, 0.55);
	margin: 0 0.05em;
}
.nf-sep {
	height: 0;
	border-top: 1px dashed rgba(255, 176, 0, 0.55);
	width: clamp(8rem, 22vw, 16rem);
	margin: 0.3rem 0 0.4rem;
}
.nf-row {
	display: grid;
	grid-template-columns: auto max-content max-content 1fr;
	column-gap: 0.45em;
	align-items: baseline;
	word-break: break-word;
}
.nf-row__icons {
	display: inline-flex;
	gap: 0.3em;
	color: #ffce5c;
	align-self: center;
}
.nf-key {
	color: #ffce5c;
}
.nf-colon {
	color: rgba(255, 176, 0, 0.55);
}
.nf-val {
	color: #ece3d0;
}
.nf-hint {
	color: rgba(236, 227, 208, 0.55);
	margin-left: 0.4em;
	opacity: 0.5;
	font-size: 0.85em;
	display: inline-flex;
	vertical-align: -0.08em;
}
.nf-stackstrip {
	display: inline-flex;
	gap: 0.45em;
	color: #ffce5c;
	text-shadow:
		0 0 1px #ffce5c,
		0 0 6px rgba(255, 123, 0, 0.35);
}
.neofetch .nf-logo-line,
.neofetch .nf-host,
.neofetch .nf-sep,
.neofetch .nf-row {
	opacity: 0;
}
.neofetch.nf-printed .nf-logo-line {
	animation: nf-print-line 0.12s ease both;
	animation-delay: calc(var(--l) * 18ms);
}
.neofetch.nf-printed .nf-host,
.neofetch.nf-printed .nf-sep,
.neofetch.nf-printed .nf-row {
	animation: nf-in 0.3s ease both;
	animation-delay: calc(450ms + var(--i) * 30ms);
}
@keyframes nf-in {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}
@keyframes nf-print-line {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}
.nf-row.clickable {
	cursor: pointer;
	transition: background 0.15s;
}
.nf-row.clickable:hover,
.nf-row.clickable:focus-visible {
	background: rgba(255, 176, 0, 0.1);
	outline: none;
}
.nf-row.clickable:focus-visible {
	box-shadow: 0 0 0 1px rgba(255, 176, 0, 0.55);
}
.nf-row.copied .nf-val {
	color: #7cc2ff;
}
@media (max-width: 600px) {
	.nf-body {
		grid-template-columns: 1fr;
		gap: 1rem;
	}
	.nf-logo {
		font-size: clamp(0.3rem, 1.45vw, 0.5rem);
		line-height: 0.9;
	}
	.nf-prompt {
		margin: 0 0 0.5rem;
	}
	.nf-info {
		font-size: 0.85rem;
		line-height: 1.55;
	}
	.nf-host {
		font-size: 1rem;
	}
	.nf-sep {
		width: 100%;
		margin: 0.15rem 0 0.25rem;
	}
	.nf-stackstrip {
		gap: 0.4em;
	}
}
@media (prefers-reduced-motion: reduce) {
	.neofetch * {
		/* biome-ignore lint/complexity/noImportantStyles: reduced-motion a11y kill-switch must win specificity wars */
		animation: none !important;
	}
	.neofetch .nf-logo-line,
	.neofetch .nf-host,
	.neofetch .nf-sep,
	.neofetch .nf-row {
		opacity: 1;
	}
}

@keyframes blink {
	50% {
		opacity: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		/* biome-ignore lint/complexity/noImportantStyles: reduced-motion a11y kill-switch must win specificity wars */
		animation-duration: 0.01ms !important;
		/* biome-ignore lint/complexity/noImportantStyles: reduced-motion a11y kill-switch must win specificity wars */
		animation-iteration-count: 1 !important;
		/* biome-ignore lint/complexity/noImportantStyles: reduced-motion a11y kill-switch must win specificity wars */
		transition-duration: 0.01ms !important;
	}

	html {
		scroll-behavior: auto;
	}
}

/* ---- reading rail + chat dock glue ---- */

/* the composer owns the bottom on posts — toasts stack above it instead of
   under it, and the page gets foot room so nothing is unreachable.
   (Spacer on main, NOT on article — `article` also matches blog list rows
   and poured 8rem of dead space between every row.) */
.has-chatdock .toast-region {
	bottom: 6.4rem;
}

.has-chatdock main::after {
	content: "";
	display: block;
	height: 2.5rem;
}

/* the dock hides itself past the outro — the foot room goes with it */
.has-chatdock.chatdock-past main::after {
	display: none;
}

/* fix strip hangs off the TL;DR card — skin matched in the route (stylex).
   When joined, the TL;DR drops its bottom border: one card, no seam. */
.tldr-join .tldr {
	border-bottom: none;
}

/* assistant panel typing dots (StyleX cannot reach @keyframes) */
@keyframes chatpulse {
	0%,
	100% {
		opacity: 0.25;
		transform: translateY(0);
	}
	50% {
		opacity: 1;
		transform: translateY(-2px);
	}
}
.chat-dot {
	animation: chatpulse 1.1s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
	.chat-dot {
		animation: none;
	}
}

/* chat composer placeholders — StyleX silently drops ::placeholder
   (pseudo-ELEMENT) keys, so these live here as plain classes.
   .chat-bar-input also pins the input's own visual: the bar rides the
   document css (see .chat-dock) — if the StyleX dev payload ever degrades,
   the input must not fall back to UA chrome (grey bg, inset border). */
.chat-input {
	flex: 1;
	min-width: 0;
	max-height: 7rem;
	overflow-y: auto;
	padding-block: 0.7rem;
	background-color: transparent;
	border-width: 0;
	outline-width: 0;
	outline-style: none;
	color: #ece3d0;
	caret-color: #ffb000;
	resize: none;
	font-family: "IBM Plex Mono", ui-monospace, monospace;
	font-size: 0.92rem;
	line-height: 1.45;
}
.chat-input::placeholder {
	color: rgba(255, 176, 0, 0.4);
}
.chat-bar-input {
	flex: 1;
	min-width: 0;
	max-height: 6rem;
	overflow-y: auto;
	padding-block: 0.25rem;
	background-color: transparent;
	border-width: 0;
	outline-width: 0;
	outline-style: none;
	color: #ece3d0;
	caret-color: #ffb000;
	resize: none;
	font-family: "IBM Plex Mono", ui-monospace, monospace;
	font-size: 0.92rem;
	line-height: 1.45;
}
.chat-bar-input::placeholder {
	color: rgba(255, 176, 0, 0.4);
}

/* ---- assistant panel markdown (.chat-md) — house mono, amber-tinted ---- */
.chat-md > :first-child {
	margin-top: 0;
}
.chat-md > :last-child {
	margin-bottom: 0;
}
/* biome-ignore lint/style/noDescendingSpecificity: chat-md is a panel-scoped namespace — no .prose collision */
.chat-md p {
	margin: 0.45rem 0;
}
.chat-md .chat-head {
	display: block;
	margin: 0.7rem 0 0.25rem;
	font-size: 0.92rem;
	color: #ffce5c;
}
.chat-md .chat-hr {
	border: none;
	border-top: 1px solid rgba(255, 123, 0, 0.2);
	margin: 0.7rem 0;
}
.chat-md .chat-quote {
	margin: 0.45rem 0;
	padding: 0.1rem 0 0.1rem 0.8rem;
	border-left: 2px solid rgba(255, 123, 0, 0.35);
	color: rgba(236, 227, 208, 0.72);
}
/* biome-ignore lint/style/noDescendingSpecificity: chat-md is a panel-scoped namespace — no .prose collision */
.chat-md ul,
.chat-md ol {
	margin: 0.45rem 0;
	padding-left: 1.25rem;
}
/* biome-ignore lint/style/noDescendingSpecificity: chat-md is a panel-scoped namespace — no .prose collision */
.chat-md li {
	margin: 0.2rem 0;
}
/* biome-ignore lint/style/noDescendingSpecificity: chat-md is a panel-scoped namespace — no .prose collision */
.chat-md a {
	color: #ffb000;
	text-decoration: underline;
	text-underline-offset: 2px;
}
.chat-md strong {
	color: #ffce5c;
}
.chat-md .chat-inline {
	background-color: rgba(255, 176, 0, 0.1);
	border: 1px solid rgba(255, 123, 0, 0.2);
	padding: 0.05rem 0.35rem;
	font-size: 0.84em;
	color: #ffce5c;
	white-space: nowrap;
}
.chat-md .chat-code {
	margin: 0.55rem 0;
	padding: 0.65rem 0.8rem;
	background-color: #0d0702;
	border: 1px solid rgba(255, 123, 0, 0.2);
	overflow-x: auto;
	font-size: 0.82rem;
	line-height: 1.55;
}
/* titled fences — the chat codebar */
.chat-md .chat-code-frame {
	margin: 0.75rem 0;
	border: 1px solid rgba(255, 123, 0, 0.2);
}

.chat-md .chat-code-frame figcaption {
	padding: 0.3rem 0.65rem;
	font-size: 0.72rem;
	color: #ffce5c;
	letter-spacing: 0.08em;
	border-bottom-width: 1px;
	border-bottom-style: solid;
	border-bottom-color: rgba(255, 123, 0, 0.2);
	background-color: rgba(255, 123, 0, 0.06);
}

.chat-md .chat-code {
	counter-reset: mrsn-line;
}

.chat-md .chat-code-frame .chat-code {
	margin: 0;
	border-width: 0;
}

/* numbered lines + highlighted lines (tanstack highlight th-line spans) */
.chat-md .chat-code .th-line::before {
	counter-increment: mrsn-line;
	content: counter(mrsn-line);
	display: inline-block;
	width: 1.6em;
	margin-right: 0.75em;
	color: rgba(255, 206, 92, 0.35);
	text-align: right;
	user-select: none;
}

.chat-md .chat-code .th-line--highlighted {
	background-color: rgba(255, 123, 0, 0.2);
}

.chat-md .chat-code code {
	font-family: inherit;
	background-color: transparent;
	padding: 0;
	border: none;
}

/* View Transitions — house cross-fade (router defaultViewTransition).
   Opacity only: RTL-safe, no translate. Reduced-motion: instant swap. */
::view-transition-old(root) {
	animation: vt-fade-out 160ms cubic-bezier(0.2, 0, 0, 1) both;
}
::view-transition-new(root) {
	animation: vt-fade-in 160ms cubic-bezier(0.2, 0, 0, 1) both;
}
@keyframes vt-fade-out {
	to {
		opacity: 0;
	}
}
@keyframes vt-fade-in {
	from {
		opacity: 0;
	}
}
@media (prefers-reduced-motion: reduce) {
	::view-transition-old(root),
	::view-transition-new(root) {
		animation: none;
	}
}

/* CRT power-on — once per session (html.boot set pre-hydration).
   A phosphor line blooms across the dark, then the cover lifts.
   Whole block disabled under reduced-motion (no cover can stick). */
@media (prefers-reduced-motion: no-preference) {
	html.boot::before {
		content: "";
		position: fixed;
		inset: 0;
		z-index: 9998;
		pointer-events: none;
		background: #0c0702;
		animation: boot-cover 320ms cubic-bezier(0.2, 0, 0, 1) forwards;
	}
	html.boot::after {
		content: "";
		position: fixed;
		inset-inline: 0;
		top: 50%;
		height: 2px;
		z-index: 9999;
		pointer-events: none;
		background: #ffb000;
		box-shadow: 0 0 24px 4px rgba(255, 176, 0, 0.55);
		animation: boot-line 320ms cubic-bezier(0.2, 0, 0, 1) forwards;
	}
}
@keyframes boot-cover {
	0%,
	55% {
		opacity: 1;
	}
	100% {
		opacity: 0;
	}
}
@keyframes boot-line {
	0% {
		transform: scaleX(0);
		opacity: 1;
	}
	55% {
		transform: scaleX(1);
		opacity: 1;
	}
	100% {
		transform: scaleX(1);
		opacity: 0;
	}
}

/* § section anchor — appears beside the copy button on heading hover */
.prose .sec-anchor {
	position: absolute;
	inset-inline-end: -1.4rem;
	color: rgba(255, 176, 0, 0.4);
	text-decoration: none;
	font-size: 0.85em;
	opacity: 0;
	transition:
		opacity 120ms cubic-bezier(0.2, 0, 0, 1),
		color 120ms cubic-bezier(0.2, 0, 0, 1);
}
.prose h2,
.prose h3 {
	position: relative;
}
.prose h2:hover > .sec-anchor,
.prose h3:hover > .sec-anchor,
.prose .sec-anchor:focus-visible {
	opacity: 1;
}
.prose .sec-anchor:hover,
.prose .sec-anchor.copied {
	color: #ffce5c;
}

/* neofetch clickable rows — hit-area expansion, wins the cascade by order */
.neofetch .nf-row.clickable {
	padding-block: 0.7rem;
	margin-block: -0.7rem;
}

/* § anchors are hover-only affordances — touch has no hover, and the
   inset-inline-end offset pokes past the viewport (2px h-overflow) */
@media (max-width: 719px) {
	.prose .sec-anchor {
		display: none;
	}
}

/* prose kit — heading deep links + selection ask (sharp, house colors) */
.prose .h-anchor {
	margin-inline-start: 0.4rem;
	color: rgba(255, 176, 0, 0.55);
	text-decoration: none;
	opacity: 0;
	transition: opacity 0.15s;
	font-size: 0.8em;
}
.prose .h-anchor::after {
	content: "#";
}
.prose h2:hover .h-anchor,
.prose h3:hover .h-anchor {
	opacity: 1;
}
.sel-ask {
	position: absolute;
	z-index: 1200;
	font-family: "IBM Plex Mono", monospace;
	font-size: 0.7rem;
	color: #ffb000;
	background-color: #14100a;
	border: 1px solid rgba(255, 176, 0, 0.4);
	padding: 0.2rem 0.55rem;
	cursor: pointer;
}
.sel-ask:hover {
	background-color: rgba(255, 176, 0, 0.1);
}

/* print — the fix sheet: TL;DR, prose, commands; chrome stays home.
   body-prefix specificity beats component classes without !important. */
@media print {
	body header,
	body footer#site-footer,
	body nav[aria-label="contents"],
	body nav[aria-label="Main menu"],
	body section[aria-label="Assistant"],
	body .toast-region,
	body #post-extras,
	body .grain,
	body canvas {
		display: none;
	}
	body {
		background: #fff;
	}
	body .prose,
	body .prose * {
		color: #111;
		background: transparent;
		border-color: #bbb;
		text-shadow: none;
	}
	body .prose pre,
	body .prose code {
		background: #f4f4f4;
		border: 1px solid #ccc;
	}
	body .prose a {
		text-decoration: underline;
	}
}
