/* site.css — the shared theme for jeremybritton.me (November 2026).
   Load it FIRST on every page, then the page's own stylesheet. Pages and notebooks
   extend or override anything here: tokens are plain custom properties, and base
   rules sit inside :where() so any page rule wins without a fight.

   Theme: light by default, dark when the OS asks, and a toggle (site.js) that sets
   <html data-theme="light|dark">. A notebook that is light-only by design opts out
   with <html data-theme-lock="light">. Preview aid: ?paper=white puts the homepage
   back on pure white for comparison. */

/* ---------- Fonts: Latin subsets, WOFF2 (fonts/2026). ---------- */
@font-face { font-family: Copernicus; font-weight: 400; font-style: normal; font-display: swap; src: url("/fonts/2026/Copernicus-Book.woff2") format("woff2"); }
@font-face { font-family: Copernicus; font-weight: 400; font-style: italic; font-display: swap; src: url("/fonts/2026/Copernicus-BookItalic.woff2") format("woff2"); }
@font-face { font-family: Copernicus; font-weight: 500 700; font-style: normal; font-display: swap; src: url("/fonts/2026/Copernicus-Semibold.woff2") format("woff2"); }
@font-face { font-family: Copernicus; font-weight: 500 700; font-style: italic; font-display: swap; src: url("/fonts/2026/Copernicus-SemiboldItalic.woff2") format("woff2"); }
@font-face { font-family: Sharp; font-weight: 400 700; font-style: normal; font-display: swap; src: url("/fonts/2026/SharpSans-Bold.woff2") format("woff2"); }
@font-face { font-family: Pen; font-weight: 400; font-style: normal; font-display: swap; src: url("/fonts/2026/NanumPen.woff2") format("woff2"); }
@font-face { font-family: Nanum; font-weight: 400; font-style: normal; font-display: swap; src: url("/fonts/2026/NanumPen.woff2") format("woff2"); }
@font-face { font-family: InterVariable; font-weight: 100 900; font-style: normal; font-display: swap; src: url("/fonts/2026/InterVariable.woff2") format("woff2"); }
@font-face { font-family: InterVariable; font-weight: 100 900; font-style: italic; font-display: swap; src: url("/fonts/2026/InterVariable-Italic.woff2") format("woff2"); }

/* ---------- Tokens ---------- */
:root {
	color-scheme: light;
	--paper: #f6f5f1;        /* warm off-white, shared with the notebooks */
	--surface: #ffffff;      /* figures, tooltips, cards that sit on paper */
	--ink: #2b2b2a;
	--soft: #6b6b67;         /* secondary text; passes AA on paper */
	--faint: #9b9b95;        /* markers and hairline-adjacent marks only */
	--rule: #e2e1db;
	--brand: #47dd8e;        /* underline + wash; too light for text */
	--brand-ink: #1c8a52;    /* the green you can set text in */
	--brand-wash: rgb(71 221 142 / 0.25);
	--brand-press: rgb(71 221 142 / 0.42);
	--glow: rgb(71 221 142 / 0.13);
	--pen: #4a4a48;          /* margin notes */
	--hand-ink: #252fd0;         /* blue editor's pen on older pages */
	--hand-ink-wash: rgb(37 47 208 / 0.06);
	--focus: #145abc;
	--shadow: rgb(0 0 0 / 0.28);
	--footer-wash: #d4f6e2;
	--img-backing: transparent;
	--ease-out: cubic-bezier(.2, .7, .2, 1);
}
:root[data-paper="white"] { --paper: #ffffff; }

@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		color-scheme: dark;
		--paper: #141513;
		--surface: #1c1d1b;
		--ink: #e7e5df;
		--soft: #a4a39c;
		--faint: #6f6f69;
		--rule: #2d2e2a;
		--brand-ink: #6fe6a6;
		--brand-wash: rgb(71 221 142 / 0.20);
		--brand-press: rgb(71 221 142 / 0.34);
		--glow: rgb(71 221 142 / 0.09);
		--pen: #cbc8bf;
		--hand-ink: #a3a9ff;
		--hand-ink-wash: rgb(163 169 255 / 0.10);
		--focus: #8fb4ff;
		--shadow: rgb(0 0 0 / 0.6);
		--footer-wash: #10301f;
		--img-backing: #efeee8;
	}
}
:root[data-theme="dark"] {
	color-scheme: dark;
	--paper: #141513;
	--surface: #1c1d1b;
	--ink: #e7e5df;
	--soft: #a4a39c;
	--faint: #6f6f69;
	--rule: #2d2e2a;
	--brand-ink: #6fe6a6;
	--brand-wash: rgb(71 221 142 / 0.20);
	--brand-press: rgb(71 221 142 / 0.34);
	--glow: rgb(71 221 142 / 0.09);
	--pen: #cbc8bf;
	--hand-ink: #a3a9ff;
	--hand-ink-wash: rgb(163 169 255 / 0.10);
	--focus: #8fb4ff;
	--shadow: rgb(0 0 0 / 0.6);
	--footer-wash: #10301f;
	--img-backing: #efeee8;
}

/* ---------- Base (zero specificity: pages win) ---------- */
:where(html) { background: var(--paper); }
:where(body) { background: var(--paper); color: var(--ink); }
:where(::selection) { background: var(--brand-wash); }
:where(a):focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 2px; }

/* At night: transparent ink drawings (the ball cartoons, old article figures) get a
   paper card so black lines stay visible; photos dim a touch. */
:where(article figure img, .published .original img) { background: var(--img-backing); }
:root[data-theme="dark"] :where(.now-figure img) { filter: brightness(.92); }
:root[data-theme="dark"] :where(.portrait) { filter: grayscale(1) brightness(.9); }

/* ---------- Page-to-page: quick crossfade, the JB mark stays put ---------- */
@view-transition { navigation: auto; }

.home-mark:not(footer .home-mark), .jb-home { view-transition-name: jb-mark; }
.theme-toggle { view-transition-name: theme-toggle; }

::view-transition-group(*) { animation-duration: 220ms; animation-timing-function: var(--ease-out); }
::view-transition-old(root) { animation: vt-out 140ms ease-in both; }
::view-transition-new(root) { animation: vt-in 220ms var(--ease-out) both; }
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in { from { opacity: 0; transform: translateY(6px); } }

/* Theme switch: the new light spreads from the toggle (site.js sets the origin). */
html.theme-switching::view-transition-old(root) { animation: none; }
html.theme-switching::view-transition-new(root) {
	animation: theme-reveal 340ms var(--ease-out) both;
}
@keyframes theme-reveal {
	from { clip-path: circle(0 at var(--vt-x, 100%) var(--vt-y, 0)); }
	to { clip-path: circle(var(--vt-r, 150vmax) at var(--vt-x, 100%) var(--vt-y, 0)); }
}

/* ---------- Theme toggle (inserted by site.js) ---------- */
.theme-toggle {
	position: absolute;
	top: 24px;
	right: max(18px, env(safe-area-inset-right, 0px));
	z-index: 20;
	width: 38px;
	height: 38px;
	display: grid;
	place-items: center;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: var(--faint);
	cursor: pointer;
	transition: color 160ms ease-out, background-color 160ms ease-out, transform 120ms ease-out;
	-webkit-tap-highlight-color: transparent;
}
.theme-toggle:hover { color: var(--ink); background: var(--glow); }
/* Pages that style every <button> (the LEGO notebooks) don't reach the toggle. */
html body button.theme-toggle { background: transparent; border: 0; box-shadow: none; padding: 0; min-width: 0; min-height: 0; font: inherit; color: var(--faint); }
html body button.theme-toggle:hover { color: var(--ink); background: var(--glow); }
.theme-toggle:active { transform: scale(.92); }
.theme-toggle:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.theme-toggle svg { width: 18px; height: 18px; display: block; transition: transform 340ms var(--ease-out); }
:root[data-theme="dark"] .theme-toggle svg { transform: rotate(180deg); }
@media (min-width: 760px) { .theme-toggle { top: 24px; right: max(26px, env(safe-area-inset-right, 0px)); } }

/* ---------- Scroll light: margin notes settle in; footers warm as you arrive ---------- */
@supports (animation-timeline: view()) {
	.note, .published .provenance p.handwriting {
		animation: settle linear both;
		animation-timeline: view();
		animation-range: entry 5% entry 70%;
	}
	footer.warm::before {
		animation: warm linear both;
		animation-timeline: view();
		animation-range: entry 0% cover 60%;
	}
}
@keyframes settle { from { opacity: 0; translate: 0 8px; } }
@keyframes warm { from { opacity: .25; } to { opacity: 1; } }

footer.warm { position: relative; isolation: isolate; background: transparent !important; }
footer.warm::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(transparent 40%, var(--footer-wash) 100%);
	pointer-events: none;
}

/* ---------- Pointer light: a soft glow follows the cursor across list rows ---------- */
.glow { position: relative; }
.glow::before {
	content: "";
	position: absolute;
	inset: -0.45em -0.9em;
	border-radius: 10px;
	background: radial-gradient(220px circle at var(--mx, 50%) var(--my, 50%), var(--glow), transparent 70%);
	opacity: 0;
	transition: opacity 220ms ease-out;
	pointer-events: none;
	z-index: -1;
}
.glow:hover::before { opacity: 1; }
.glow-list { isolation: isolate; }

/* ---------- Reduced motion: everything above stands still ---------- */
@media (prefers-reduced-motion: reduce) {
	@view-transition { navigation: none; }
	.note, .published .provenance p.handwriting, footer.warm::before { animation: none !important; }
	.glow::before, .theme-toggle, .theme-toggle svg { transition: none; }
}
.glow:has(.glow:hover)::before { opacity: 0; }
