/*
Theme Name: Warn
Description: A quiet, minimal WordPress theme for long-form writing. Single narrow column, left vertical navigation with a hairline divider, self-hosted variable fonts, zero JavaScript.
Version: 1.3.4
Requires at least: 6.0
Tested up to: 6.8
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: warn
Tags: blog, one-column, custom-menu, minimal
*/

/* ---------------------------------------------------------------------------
 * Fonts (self-hosted, variable where possible)
 *
 * Loading strategy — a Next.js/next/font recipe with Google-Fonts-style
 * unicode-range slicing on top:
 *  1. each font is split into a small "latin" slice (the characters every
 *     page needs, incl. arrows) and an "ext" slice (everything else the
 *     font ships). The browser downloads a slice only when the page
 *     actually renders a character from its unicode-range, so a typical
 *     page pays ~107 KB for text instead of the full ~337 KB — and never
 *     touches the big ext slices. CJK is unaffected: it has always come
 *     from system fonts further down the stacks. Slices are cut from the
 *     original files with harfbuzz subsetting (tools-fonts/slice.js);
 *     their codepoint sets are disjoint and union back to the full fonts.
 *  2. the latin slices are preloaded in <head> (see functions.php), so
 *     the download starts with the HTML, not after this stylesheet;
 *  3. font-display: block holds text invisible for a short block period —
 *     with the preload the font almost always wins that race, so the first
 *     paint is already the real font (no mid-read swap, no system-font
 *     flash);
 *  4. if the font still loses, the "Fallback" families below step in:
 *     locally installed Arial, metrically reshaped with size-adjust and
 *     ascent/descent/line-gap overrides so it occupies the exact same
 *     space as the real font — the eventual swap is invisible, zero
 *     layout shift. Metric values are computed from these font files.
 * ------------------------------------------------------------------------ */

@font-face {
	font-family: 'Warn Sans';
	src: url('fonts/InterVariable-latin.woff2') format('woff2');
	font-weight: 100 900;
	font-style: normal;
	font-display: block;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
		U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC,
		U+2122, U+2190-21FF, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Warn Sans';
	src: url('fonts/InterVariable-ext.woff2') format('woff2');
	font-weight: 100 900;
	font-style: normal;
	font-display: block;
	unicode-range: U+0100-0130, U+0132-0151, U+0154-02BA, U+02BD-02C5,
		U+02C7-02D9, U+02DB, U+02DD-0303, U+0305-0307, U+0309-0328,
		U+032A-1FFF, U+2070-20AB, U+20AD-2121, U+2123-218F, U+2200-2211,
		U+2213-2214, U+2216-FEFE, U+FF00-FFFC, U+FFFE-10FFFF;
}

@font-face {
	font-family: 'Warn Sans Fallback';
	src: local('Arial');
	ascent-override: 89.79%;
	descent-override: 22.36%;
	line-gap-override: 0%;
	size-adjust: 107.89%;
}

@font-face {
	font-family: 'Warn Serif';
	src: url('fonts/LoraItalicVariable-latin.woff2') format('woff2');
	font-weight: 400 700;
	font-style: normal; /* the file itself is the italic design */
	font-display: block;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
		U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC,
		U+2122, U+2190-21FF, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Warn Serif';
	src: url('fonts/LoraItalicVariable-ext.woff2') format('woff2');
	font-weight: 400 700;
	font-style: normal; /* the file itself is the italic design */
	font-display: block;
	unicode-range: U+0100-0130, U+0132-0151, U+0154-02BA, U+02BD-02C5,
		U+02C7-02D9, U+02DB, U+02DD-0303, U+0305-0307, U+0309-0328,
		U+032A-1FFF, U+2070-20AB, U+20AD-2121, U+2123-218F, U+2200-2211,
		U+2213-2214, U+2216-FEFE, U+FF00-FFFC, U+FFFE-10FFFF;
}

@font-face {
	font-family: 'Warn Serif Fallback';
	src: local('Arial');
	ascent-override: 98.68%;
	descent-override: 26.88%;
	line-gap-override: 0%;
	size-adjust: 101.95%;
}

@font-face {
	font-family: 'Warn Mono';
	src: url('fonts/IosevkaFixedCurly-ExtendedMedium-latin.woff2') format('woff2');
	font-weight: 400; /* file is Medium; mapped to 400 so regular code picks it */
	font-style: normal;
	font-display: block;
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
		U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC,
		U+2122, U+2190-21FF, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Warn Mono';
	src: url('fonts/IosevkaFixedCurly-ExtendedMedium-ext.woff2') format('woff2');
	font-weight: 400; /* file is Medium; mapped to 400 so regular code picks it */
	font-style: normal;
	font-display: block;
	unicode-range: U+0100-0130, U+0132-0151, U+0154-02BA, U+02BD-02C5,
		U+02C7-02D9, U+02DB, U+02DD-0303, U+0305-0307, U+0309-0328,
		U+032A-1FFF, U+2070-20AB, U+20AD-2121, U+2123-218F, U+2200-2211,
		U+2213-2214, U+2216-FEFE, U+FF00-FFFC, U+FFFE-10FFFF;
}

@font-face {
	font-family: 'Warn Mono Fallback';
	src: local('Arial');
	ascent-override: 73.39%;
	descent-override: 16.35%;
	line-gap-override: 5.32%;
	size-adjust: 131.49%;
}

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

:root {
	--bg: #fcfcfc;
	--bg-rgb: 252 252 252; /* same color, for alpha-mixed fades */

	--ink-100: #d8dbdf;
	--ink-200: #b3b9c1;
	--ink-300: #8c95a1;
	--ink-400: #697381;
	--ink-500: #4a515b;
	--ink-600: #3b4149;
	--ink-700: #2b3035;
	--ink-800: #1e2125;

	--border: rgba(216, 219, 223, 0.7);
	--code-bg: #f7f7f7;
	--selection-bg: rgba(149, 165, 172, 0.25);
	--selection-ink: #485a74;

	--sans: 'Warn Sans', 'Warn Sans Fallback', -apple-system,
		ui-sans-serif, system-ui, 'PingFang SC', 'Hiragino Sans GB',
		'Source Han Sans SC', 'Microsoft YaHei', sans-serif;
	--serif: 'Warn Serif', 'Warn Serif Fallback', Baskerville, Georgia,
		'Songti SC', 'SimSun', serif;
	--mono: 'Warn Mono', 'Warn Mono Fallback', ui-monospace,
		SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
		monospace;

	--pad: 1.5rem; /* body padding: 24 / 40 / 56 */

	color-scheme: light dark;
}

/*
 * Dark mode: same gray ramp, mirrored. ink-500 stays the body text color,
 * so flipping the ramp is all it takes. Framed images and iframes keep
 * their white backgrounds on purpose (photos and embeds expect white).
 */
@media (prefers-color-scheme: dark) {
	:root {
		--bg: #101112;
		--bg-rgb: 16 17 18;

		--ink-100: #3a4048;
		--ink-200: #4a515b;
		--ink-300: #697381;
		--ink-400: #8c95a1;
		--ink-500: #b3b9c1;
		--ink-600: #c9ced4;
		--ink-700: #dde1e5;
		--ink-800: #f0f2f4;

		--border: rgba(74, 81, 91, 0.6);
		--code-bg: #16181b;
		--selection-bg: rgba(149, 165, 172, 0.35);
		--selection-ink: #d6e2ee;
	}

	/* multiply() on a dark page would sink the hairline to black. */
	.site-main::before {
		mix-blend-mode: normal;
	}
}

@media screen and (min-width: 640px) {
	:root { --pad: 2.5rem; }
}

@media screen and (min-width: 768px) {
	:root { --pad: 3.5rem; }
}

/* ---------------------------------------------------------------------------
 * Base
 * ------------------------------------------------------------------------ */

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

html {
	overflow-x: hidden;
	-webkit-text-size-adjust: 100%;
	/*
	 * The canvas behind the page: without this, iOS shows the UA default
	 * (white) when rubber-banding past the top/bottom of the page.
	 */
	background: var(--bg);
}

body {
	margin: 0;
	padding: var(--pad);
	background: var(--bg);
	color: var(--ink-500);
	font-family: var(--sans);
	font-size: 0.875rem;
	line-height: 1.5rem;
	font-variation-settings: 'wght' 440, 'opsz' 32;
	font-feature-settings: 'cv01', 'cv03', 'cv04', 'calt', 'ss03',
		'liga', 'ordn';
	font-variant: common-ligatures contextual;
	letter-spacing: 0.0085em;
	word-spacing: -0.04em;
	font-optical-sizing: auto;
	font-synthesis: none;
	text-decoration-skip-ink: auto;
	text-spacing-trim: space-first;
	text-rendering: geometricPrecision;
	-webkit-font-smoothing: antialiased;
	-webkit-tap-highlight-color: transparent;
	touch-action: manipulation;
	/*
	 * The full shud.in feature stack minus 'cpsp': Inter's character
	 * variants (cv01/cv03/cv04 — digit and letter shapes) stay, but
	 * 'cpsp' capital spacing makes Safari mangle mixed-case text
	 * (gaps after capitals, shrunken lowercase), so it is excluded.
	 */
}

@media screen and (min-width: 640px) {
	body {
		font-size: 0.9375rem;
		line-height: 1.75rem;
	}
}

@media screen and (min-width: 768px) {
	body {
		font-size: 1rem;
		line-height: 1.75rem;
	}
}

::selection {
	background: var(--selection-bg);
	color: var(--selection-ink);
}

/* Italic-ish elements use the serif (Lora italic) face. */
i,
em,
cite,
blockquote,
figcaption,
.site-nav,
.sidenote {
	font-family: var(--serif);
	font-style: normal;
	font-weight: 480;
	font-variation-settings: 'wght' 480, 'opsz' 32;
	font-variant-ligatures: contextual;
	letter-spacing: -0.006em;
	word-spacing: normal;
}

a {
	color: inherit;
	text-decoration-line: underline;
	text-underline-offset: 2px;
	text-decoration-thickness: from-font;
	text-decoration-color: var(--ink-300);
	overflow-wrap: break-word;
	transition: text-decoration-color 0.15s, color 0.15s;
}

a:hover {
	text-decoration-color: var(--ink-600);
}

a:focus-visible {
	outline: 1px dotted var(--ink-400);
	outline-offset: 1px;
	border-radius: 0.125rem;
	color: var(--ink-600);
}

img,
video,
iframe {
	max-width: 100%;
	height: auto;
}

iframe {
	width: 100%;
	border: 1px solid var(--border);
	background: #fff;
}

del { text-decoration-thickness: 1px; }

/* Short horizontal rule: 96px wide, 56px above and below. */
.article hr {
	width: 6rem;
	height: 0;
	margin: 3.5rem 0;
	border: 0;
	border-top: 1px solid var(--border);
	background: none;
}

table {
	width: 100%;
	margin-top: 1.75rem;
	border-collapse: collapse;
	font-variant-numeric: tabular-nums;
}

th,
td {
	padding: 0.25rem 0.5rem;
	border-bottom: 1px solid var(--border);
	text-align: left;
	vertical-align: top;
}

th {
	font-weight: 640;
	font-variation-settings: 'wght' 640, 'opsz' 32;
	color: var(--ink-600);
}

/* ---------------------------------------------------------------------------
 * Top fade (mobile only)
 * ------------------------------------------------------------------------ */

.top-fade {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 30;
	width: 100%;
	height: 1.5rem;
	pointer-events: none;
	/*
	 * Gradient stops derive from --bg itself, so the fade always blends
	 * seamlessly into the page background in both color schemes. (The
	 * previous hardcoded stops — pure white / bluish black — were visible
	 * as a stray light bar against the actual background color.)
	 */
	background: linear-gradient(
		180deg,
		rgb(var(--bg-rgb) / 1) 0%,
		rgb(var(--bg-rgb) / 0.63) 14%,
		rgb(var(--bg-rgb) / 0.36) 29%,
		rgb(var(--bg-rgb) / 0.19) 43%,
		rgb(var(--bg-rgb) / 0.08) 57%,
		rgb(var(--bg-rgb) / 0.02) 71%,
		rgb(var(--bg-rgb) / 0) 86%
	);
}

@media screen and (min-width: 640px) {
	.top-fade { display: none; }
}

/* ---------------------------------------------------------------------------
 * Layout: nav column + main column, split by a hairline
 * ------------------------------------------------------------------------ */

.site {
	display: flex;
	flex-direction: column;
}

.site-main {
	position: relative;
	flex: 1;
	max-width: 42rem;
	contain: inline-size;
}

/* The hairline divider. Horizontal on mobile, vertical from 420px up. */
.site-main::before {
	content: '';
	position: absolute;
	top: 0;
	right: 0;
	width: 100%;
	height: 1px;
	background: var(--border);
	opacity: 0.5;
	mix-blend-mode: multiply;
}

.article {
	padding-top: 1.5rem;
	hanging-punctuation: first allow-end last;
	hyphens: auto;
	hyphenate-limit-chars: 10 6 6;
}

@media screen and (min-width: 420px) {
	.site { flex-direction: row; }

	.site-main::before {
		right: auto;
		left: 0;
		width: 1px;
		height: 100%;
		opacity: 1;
	}

	.article {
		--gutter: 1.5rem;
		padding-top: 0;
		padding-left: var(--gutter);
	}
}

@media screen and (min-width: 640px) {
	.article { --gutter: 2.5rem; }
}

@media screen and (min-width: 768px) {
	.article { --gutter: 3.5rem; }
}

:root { --gutter: 1.5rem; } /* mobile blockquote pull, see below */

/* ---------------------------------------------------------------------------
 * Navigation
 * ------------------------------------------------------------------------ */

.site-nav {
	width: 100%;
}

.site-nav ul {
	display: flex;
	gap: 0.5rem;
	justify-content: flex-end;
	margin: 0 0 1.5rem;
	padding: 0;
	list-style: none;
	text-transform: lowercase;
	text-align: right;
}

.site-nav li {
	margin: 0 -0.5rem;
	transition: color 0.15s;
	color: var(--ink-300);
	white-space: nowrap; /* "thoughts" must never wrap onto two lines */
}

.site-nav li:hover {
	color: var(--ink-600);
}

.site-nav li.is-active,
.site-nav li.current-menu-item,
.site-nav li.current-menu-parent,
.site-nav li.current_page_item,
.site-nav li.current_page_parent,
.site-nav li.current-page-ancestor {
	color: var(--ink-800);
}

.site-nav li a {
	display: inline-block;
	width: 100%;
	padding: 0 0.5rem;
	color: inherit;
	text-decoration: none;
}

@media screen and (min-width: 420px) {
	.site-nav {
		width: 4rem;
		margin-right: 1.5rem;
	}

	.site-nav ul {
		display: block;
		position: sticky;
		top: var(--pad);
		margin-bottom: 0;
	}
}

@media screen and (min-width: 640px) {
	.site-nav { margin-right: 2.5rem; }
}

@media screen and (min-width: 768px) {
	.site-nav { margin-right: 3.5rem; }
}

/* Offset the sticky nav / fade when the admin bar is present. */
@media screen and (min-width: 783px) {
	.admin-bar .top-fade { top: 32px; }
	.admin-bar .site-nav ul { top: calc(var(--pad) + 32px); }
}

@media screen and (max-width: 782px) {
	.admin-bar .top-fade { top: 46px; }
	.admin-bar .site-nav ul { top: calc(var(--pad) + 46px); }
}

/* ---------------------------------------------------------------------------
 * Post list (thoughts-style index: title ····· date)
 * ------------------------------------------------------------------------ */

.post-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.post-list li {
	font-weight: 500;
	font-variation-settings: 'wght' 500, 'opsz' 32;
}

.post-list li a {
	display: flex;
	gap: 0.25rem;
	align-items: center;
	justify-content: space-between;
	margin: 0 -0.5rem;
	padding: 0 0.5rem;
	text-decoration: none;
}

.post-list .post-title {
	display: block;
	color: var(--ink-500);
	transition: color 0.15s;
}

.post-list .dot-leaders {
	flex: 1;
	height: 1em;
	overflow: hidden;
	text-align: end;
	letter-spacing: 6px;
	line-height: 1;
	font-size: 0.875rem;
	font-weight: 400;
	font-variation-settings: 'wght' 400, 'opsz' 32;
	color: var(--ink-100);
	transition: color 0.15s;
	word-spacing: normal;
}

.post-list .dot-leaders::after {
	content: '········································································································';
}

.post-list time {
	display: block;
	align-self: flex-start;
	color: var(--ink-200);
	font-weight: 400;
	font-variation-settings: 'wght' 400, 'opsz' 32;
	font-variant-numeric: tabular-nums;
	letter-spacing: -0.05em;
	transition: color 0.15s;
}

.post-list li a:hover .post-title,
.post-list li a:focus-visible .post-title {
	color: var(--ink-700);
}

.post-list li a:hover .dot-leaders,
.post-list li a:focus-visible .dot-leaders,
.post-list li a:hover time,
.post-list li a:focus-visible time {
	color: var(--ink-500);
	transition: none;
}

/* ---------------------------------------------------------------------------
 * Article typography
 * ------------------------------------------------------------------------ */

.article > * + * {
	margin-top: 1.75rem;
}

/* Trilingual language-order note: quiet metadata, not content. */
.article .lang-note {
	font-size: 0.75rem;
	line-height: 1.25rem;
	color: var(--ink-300);
}

.article h1,
.article h2,
.article h3,
.article h4,
.article h5,
.article h6 {
	margin: 0;
	font-size: inherit;
	line-height: inherit;
	font-weight: 640;
	font-variation-settings: 'wght' 640, 'opsz' 32;
	color: var(--ink-600);
	text-wrap: balance;
}

.article h1 {
	margin-bottom: 1.75rem;
}

.article > * + :is(h2, h3, h4, h5, h6) {
	margin-top: 3.5rem;
}

.article :is(h2, h3, h4, h5, h6) {
	scroll-margin-top: 1.5rem;
}

@media screen and (min-width: 640px) {
	.article :is(h2, h3, h4, h5, h6) {
		scroll-margin-top: 3.5rem;
	}
}

/* h2 hover anchor (“#” fades in from the gutter) */
.article h2 {
	position: relative;
}

.h-anchor {
	position: absolute;
	left: 0;
	width: 1.5rem;
	transform: translateX(calc(-100% + 2px));
	text-align: center;
	color: var(--ink-200);
	text-decoration: none;
	opacity: 0;
	filter: blur(4px);
	user-select: none;
	transition: all 0.5s;
}

@media screen and (min-width: 640px) {
	.h-anchor { width: 2.5rem; }
}

@media screen and (min-width: 768px) {
	.h-anchor { width: 3.5rem; }
}

.article h2:hover .h-anchor,
.article h2:target .h-anchor {
	opacity: 1;
	filter: none;
	transition-delay: 0.3s;
}

.h-anchor:hover {
	color: var(--ink-500);
}

.article p {
	margin: 0;
}

/*
 * ".article p" above beats the generic ".article > * + *" sibling margin
 * on specificity, which would leave paragraphs (and the lang-note gap)
 * with no spacing at all. Same specificity, declared later, so it wins.
 */
.article > * + p {
	margin-top: 1.75rem;
}

/* Chinese-language sites read better justified. */
html[lang^='zh'] .article {
	text-align: justify;
}

.article strong,
.article b {
	font-weight: 640;
	font-variation-settings: 'wght' 640, 'opsz' 32;
	color: var(--ink-600);
}

.article ul,
.article ol {
	margin-top: 1.75rem;
	padding-left: 1.25rem;
	list-style-position: outside;
}

.article ul { list-style-type: disc; }
.article ol { list-style-type: decimal; }

.article li {
	padding-left: 0.375rem;
}

.article li::marker {
	color: var(--ink-200);
}

.article li > ul,
.article li > ol,
.article li > p {
	margin-top: 0;
}

/* The index/comment lists opt back out of the prose list rules above. */
.article ul.post-list,
.article ol.post-list {
	margin-top: 0;
	padding-left: 0;
	list-style: none;
}

.article .post-list li {
	padding-left: 0;
}

.article ol.comment-list,
.article ul.comment-list {
	margin-top: 0;
	padding-left: 0;
	list-style: none;
}

.article .comment-list .children {
	margin-top: 1.75rem;
	padding-left: 1.5rem;
	list-style: none;
}

.article .comment-list li {
	padding-left: 0;
}

.article blockquote {
	margin: 1.75rem 0 0 calc(-1 * var(--gutter));
	padding: 0 0 0 var(--gutter);
	color: var(--ink-500);
	box-shadow: 2px 0 0 var(--ink-300) inset;
}

@media screen and (min-width: 420px) {
	.article blockquote {
		color: var(--ink-400);
		box-shadow: 1px 0 0 var(--ink-500) inset;
	}
}

.article blockquote > * + * {
	margin-top: 1.75rem;
}

.article blockquote + blockquote {
	display: flow-root;
}

/* Code */
code,
kbd,
samp {
	font-family: var(--mono);
	font-size: 0.805rem;
	font-weight: 400;
	word-spacing: -0.15em;
	padding: 0.15em 0.2em;
}

@media screen and (min-width: 640px) {
	code,
	kbd,
	samp {
		font-size: 13.8px;
	}
}

@media screen and (min-width: 768px) {
	code,
	kbd,
	samp {
		font-size: 0.92rem;
	}
}

.article pre {
	margin-top: 1.75rem;
	padding: 0.875rem 1.25rem;
	background: var(--code-bg);
	overflow-x: auto;
	-webkit-font-smoothing: auto;
}

.article pre code {
	display: inline-block;
	min-width: 100%;
	width: max-content;
	padding: 0;
	line-height: 1.45rem;
	white-space: pre;
	word-break: normal;
}

@media screen and (min-width: 768px) {
	.article pre code {
		white-space: pre-wrap;
		width: auto;
		min-width: 0;
	}
}

/* Figures & captions */
.article figure {
	margin: 1.75rem 0 0;
	line-height: 0;
}

.article figure img {
	margin: 0;
}

/*
 * Image grid (the images page): a simple flex wall, one column on mobile
 * and two from 640px up, natural aspect ratios kept. The placeholder
 * background shows while the image loads, like shud.in's gradient tiles.
 */
.article .image-grid {
	display: flex;
	flex-wrap: wrap;
	gap: 0.875rem;
}

.article .image-grid img {
	flex: 1 1 100%;
	margin: 0;
	background: var(--code-bg);
}

@media screen and (min-width: 640px) {
	.article .image-grid img {
		flex: 1 1 calc(50% - 0.875rem);
		max-width: calc(50% - 0.4375rem);
	}
}

/*
 * Captions behave like margin side notes: a small serif note
 * under the figure; on very wide screens it floats into the right margin.
 */
.article figcaption {
	width: 80%;
	margin: 0.875rem auto 0;
	text-align: left;
	text-wrap: pretty;
	font-size: 0.75rem;
	line-height: 1.25rem;
	color: var(--ink-400);
}

@media screen and (min-width: 640px) {
	.article figcaption {
		font-size: 0.875rem;
		line-height: 1.5rem;
	}
}

@media screen and (min-width: 1220px) {
	.article figcaption {
		display: inline;
		float: right;
		clear: right;
		width: 50%;
		margin: 0 -50% 0 0;
		padding-left: 1.75rem;
	}
}

.article p > img:only-child {
	display: block;
}

/* Framed images: [caption] or .framed wrapper */
.article .framed > img,
.article .framed > figure > img {
	padding: 0.875rem;
	background: #fff;
	border: 1px solid var(--border);
}

/* Details / summary */
.article details {
	margin-top: 1.75rem;
	padding: 0.5rem 0;
	border-top: 1px solid var(--border);
	border-bottom: 1px solid var(--border);
}

.article details summary {
	font-weight: 600;
	font-variation-settings: 'wght' 600, 'opsz' 32;
	margin-bottom: 0.25rem;
	cursor: pointer;
}

.article details summary::marker {
	content: '';
}

.article details p:first-of-type {
	margin-top: 0;
}

/* Alignment helpers (block editor) */
.aligncenter {
	margin-left: auto;
	margin-right: auto;
	text-align: center;
}

.alignleft {
	float: left;
	margin-right: 1.75rem;
}

.alignright {
	float: right;
	margin-left: 1.75rem;
}

.wp-caption,
.gallery-caption {
	max-width: 100%;
}

/* Page links (<!--nextpage-->) */
.page-links {
	font-variant-numeric: tabular-nums;
	color: var(--ink-300);
}

.page-links a {
	margin: 0 0.25rem;
}

/* Password form */
.post-password-form input[type='password'] {
	font: inherit;
	border: 0;
	border-bottom: 1px solid var(--ink-200);
	background: transparent;
	padding: 0.25rem 0;
}

.post-password-form input[type='submit'] {
	font: inherit;
	border: 1px solid var(--ink-200);
	background: transparent;
	color: var(--ink-500);
	padding: 0.25rem 0.75rem;
	cursor: pointer;
}

/* ---------------------------------------------------------------------------
 * Comments (only rendered when enabled)
 * ------------------------------------------------------------------------ */

.comments {
	margin-top: 3.5rem;
}

.comments h2 {
	margin: 0 0 1.75rem;
	font-size: inherit;
	font-weight: 640;
	font-variation-settings: 'wght' 640, 'opsz' 32;
	color: var(--ink-600);
}

.comment-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.comment-list .comment {
	margin-top: 1.75rem;
}

.comment-list .children {
	margin: 1.75rem 0 0;
	padding-left: 1.5rem;
	list-style: none;
	border-left: 1px solid var(--border);
}

.comment-respond {
	margin-top: 3.5rem;
}

.comment-meta {
	font-variant-numeric: tabular-nums;
}

.comment-meta > * {
	display: inline;
}

.comment-meta > * + *::before {
	content: ' · ';
	color: var(--ink-200);
}

.comment-list .says {
	display: none;
}

.comment-author {
	font-weight: 640;
	font-variation-settings: 'wght' 640, 'opsz' 32;
	color: var(--ink-600);
}

.comment-metadata,
.comment-metadata a {
	color: var(--ink-200);
	font-size: 0.875rem;
	text-decoration: none;
}

.comment-content p {
	margin-top: 0.5rem;
}

.comment-reply-link {
	color: var(--ink-300);
	text-decoration: none;
}

.comment-reply-link:hover {
	color: var(--ink-600);
}

.comment-form label {
	display: block;
	color: var(--ink-300);
}

.comment-form > * + * {
	margin-top: 1.75rem;
}

.comment-form ::placeholder {
	color: var(--ink-200);
	opacity: 1;
}

/* Name and email share one row on wider screens. */
@media screen and (min-width: 640px) {
	.comment-form-author {
		float: left;
		width: 48%;
	}

	.comment-form-email {
		float: right;
		width: 48%;
		margin-top: 0;
	}

	.comment-form-comment,
	.comment-form .form-submit {
		clear: both;
	}
}

.comment-form input[type='text'],
.comment-form input[type='email'],
.comment-form input[type='url'],
.comment-form textarea {
	width: 100%;
	font: inherit;
	color: var(--ink-600);
	border: 0;
	border-bottom: 1px solid var(--ink-200);
	background: transparent;
	padding: 0.25rem 0;
	border-radius: 0;
}

.comment-form input:focus,
.comment-form textarea:focus {
	outline: none;
	border-bottom-color: var(--ink-500);
}

.comment-form-cookies-consent {
	display: flex;
	gap: 0.5rem;
	align-items: baseline;
}

.comment-form-cookies-consent label {
	display: inline;
}

.comment-form .submit {
	font: inherit;
	border: 1px solid var(--ink-200);
	background: transparent;
	color: var(--ink-500);
	padding: 0.25rem 0.75rem;
	cursor: pointer;
	transition: border-color 0.15s, color 0.15s;
}

.comment-form .submit:hover {
	border-color: var(--ink-500);
	color: var(--ink-700);
}

/* ---------------------------------------------------------------------------
 * Accessibility & misc
 * ------------------------------------------------------------------------ */

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

/* ---------------------------------------------------------------------------
 * Page view transitions (progressive enhancement, no JS)
 * ------------------------------------------------------------------------ */

/*
 * Page view transitions (progressive enhancement, no JS).
 * Scoped to the article column under the name "crossfade".
 *
 * The root group (background, navigation) is frozen: the page chrome
 * stays rock solid while only the article crossfades over it, so the
 * whole screen never shimmers. Alternatives tested and rejected:
 * freezing the old article while the new one fades over it makes
 * old/new body text visibly overlap on wide screens; a sequential
 * out-then-in flashes the bare background between pages.
 * Opacity-only: animating blur() on full-size snapshots forces per-frame
 * filter repaints and feels janky, while opacity is GPU-composited.
 */
@view-transition {
	navigation: auto;
}

.article {
	view-transition-name: crossfade;
}

::view-transition-old(root),
::view-transition-new(root) {
	animation: none;
}

@media (prefers-reduced-motion: no-preference) {
	::view-transition-old(crossfade) {
		animation: warn-hide 0.18s ease-in forwards;
	}

	::view-transition-new(crossfade) {
		opacity: 0;
		animation: warn-appear 0.22s ease-out 0.06s forwards;
	}
}

/* Reduced motion: old/new swap instantly (old frozen, new appears on top). */
@media (prefers-reduced-motion: reduce) {
	::view-transition-old(crossfade),
	::view-transition-new(crossfade) {
		animation: none;
	}
}

@keyframes warn-hide {
	to {
		opacity: 0;
	}
}

@keyframes warn-appear {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}
