/* ==========================================================================
   Latent — supplemental styles
   Layered on top of theme.json. Covers what design tokens can't express:
   automatic dark mode, prose refinements, tables, inline code, anchors,
   focus states, and block-style variations.
   ========================================================================== */

/* ----- 1. Automatic dark mode -------------------------------------------- */
/* theme.json wires every surface to these preset tokens, so remapping the
   seven of them here flips the entire theme — no per-element overrides. */
@media (prefers-color-scheme: dark) {
	:root {
		--wp--preset--color--base: #0E0E11;
		--wp--preset--color--surface: #17171B;
		--wp--preset--color--hairline: #28282F;
		--wp--preset--color--muted: #9A9AA4;
		--wp--preset--color--contrast: #ECECEE;
		--wp--preset--color--primary: #9D94FF;
		--wp--preset--color--accent-soft: #1E1B33;
	}
	/* Slightly soften images so they don't glare on the dark canvas. */
	img:not(.no-dim) { filter: brightness(0.92) contrast(1.02); }
}

/* ----- 2. Global niceties ------------------------------------------------ */
html { -webkit-text-size-adjust: 100%; }
body { text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }

::selection { background: var(--wp--preset--color--primary); color: var(--wp--preset--color--base); }

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	* { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

/* Visible, on-brand focus ring for keyboard users. */
:where(a, button, input, textarea, select, summary, .wp-block-navigation-item__content):focus-visible {
	outline: 2px solid var(--wp--preset--color--primary);
	outline-offset: 3px;
	border-radius: 3px;
}

/* ----- 3. Prose rhythm --------------------------------------------------- */
.wp-block-post-content,
.entry-content {
	overflow-wrap: break-word;
}

/* Breathing room above headings inside the article (tighter for the one that
   immediately follows another heading). */
:where(.wp-block-post-content) :is(h2, h3, h4) {
	margin-top: 2.4em;
}
:where(.wp-block-post-content) :is(h2) {
	padding-top: 0.4rem;
}
:where(.wp-block-post-content) :is(h1, h2, h3, h4) + :is(h2, h3, h4) {
	margin-top: 0.6em;
}

/* Anchored headings (content uses id="" anchors) — offset for sticky header
   and a soft flash when linked to. */
:where(.wp-block-post-content) :is(h2, h3, h4, h5, h6)[id] {
	scroll-margin-top: 6rem;
}
:where(.wp-block-post-content) :target {
	animation: latent-target 1.6s ease;
}
@keyframes latent-target {
	0%, 30% { background: var(--wp--preset--color--accent-soft); box-shadow: 0 0 0 6px var(--wp--preset--color--accent-soft); }
	100% { background: transparent; box-shadow: 0 0 0 6px transparent; }
}

/* Links inside prose: subtle underline that thickens on hover. */
:where(.wp-block-post-content, .entry-content) a {
	text-decoration: underline;
	text-decoration-color: color-mix(in srgb, var(--wp--preset--color--primary) 35%, transparent);
	text-underline-offset: 0.18em;
	text-decoration-thickness: 1px;
	transition: text-decoration-color 0.15s ease, color 0.15s ease;
}
:where(.wp-block-post-content, .entry-content) a:hover {
	text-decoration-color: var(--wp--preset--color--primary);
}

/* Lists: a touch more line spacing between items. */
:where(.wp-block-post-content) :is(ul, ol) > li + li { margin-top: 0.4em; }
:where(.wp-block-post-content) li::marker { color: var(--wp--preset--color--muted); }

/* ----- 4. Inline code ---------------------------------------------------- */
:where(.wp-block-post-content, .entry-content) :not(pre) > code {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.86em;
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--hairline);
	border-radius: 5px;
	padding: 0.12em 0.4em;
	word-break: break-word;
}
/* Don't double-box code that sits inside a link. */
:where(.wp-block-post-content) a > code { color: inherit; }

/* Scrollable code blocks on small screens. */
:where(.wp-block-code, .wp-block-preformatted) {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

/* ----- 5. Tables --------------------------------------------------------- */
/* Comparison tables are core content on this site — make them legible. */
.wp-block-post-content table,
.wp-block-table table,
.entry-content table {
	width: 100%;
	border-collapse: collapse;
	font-variant-numeric: tabular-nums;
}
/* Allow long tables to scroll horizontally rather than overflow the page. */
.wp-block-table,
.wp-block-post-content figure.wp-block-table {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}
.wp-block-post-content table :is(th, td),
.wp-block-table table :is(th, td),
.entry-content table :is(th, td) {
	border: none;
	border-bottom: 1px solid var(--wp--preset--color--hairline);
	padding: 0.7rem 0.9rem;
	text-align: left;
	vertical-align: top;
}
.wp-block-post-content table thead th,
.wp-block-table table thead th,
.entry-content table thead th {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.78rem;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
	border-bottom: 1.5px solid var(--wp--preset--color--contrast);
}
.wp-block-post-content table tbody tr:nth-child(even),
.wp-block-table table tbody tr:nth-child(even),
.entry-content table tbody tr:nth-child(even) {
	background: color-mix(in srgb, var(--wp--preset--color--surface) 55%, transparent);
}
.wp-block-post-content table tbody tr:last-child :is(th, td),
.wp-block-table table tbody tr:last-child :is(th, td) {
	border-bottom: none;
}

/* ----- 6. Media & quotes ------------------------------------------------- */
.wp-block-image img { height: auto; }
figcaption { text-align: center; }

.wp-block-quote { font-style: italic; }
.wp-block-quote cite { display: block; margin-top: 0.6rem; font-style: normal; }

/* ----- 7. Header / footer chrome ----------------------------------------- */
/* BIFF cross-promotion bar (assets/js/biff-bar.js, mounted into #biff-bar by
   the deferred script). The bar renders 37px tall (36px rows + its 1px
   hairline, measured live); reserving exactly that on the empty slot keeps
   the page from shifting when it mounts. It sits
   above .wp-site-blocks, so the sticky header still docks at the viewport top
   once the bar has scrolled away. */
#biff-bar {
	min-height: 37px;
}

.wp-site-blocks > header {
	position: sticky;
	top: 0;
	z-index: 100;
	/* Frosted glass: a translucent base wash + backdrop blur so content softly
	   shows through as it scrolls under the sticky bar. */
	background: color-mix(in srgb, var(--wp--preset--color--base) 86%, transparent);
	-webkit-backdrop-filter: saturate(140%) blur(10px);
	backdrop-filter: saturate(140%) blur(10px);
	border-bottom: 1px solid var(--wp--preset--color--hairline);
}
.wp-site-blocks > footer {
	border-top: 1px solid var(--wp--preset--color--hairline);
}

/* Site title (the "BIFF.ai" wordmark). theme.json styles core/site-title as the
   serif lockup, but WP only prints a block's theme.json CSS on templates where it
   detects that block as rendered. The site-title lives in the header template
   part and got emitted on the blog/home template but NOT on `page`/`single`, so
   the wordmark fell back to the Inter body font on every interior page. Pin it in
   the always-loaded theme stylesheet so the wordmark is the identical serif lockup
   site-wide. Values mirror theme.json's core/site-title (the fluid clamp is WP's
   own compiled output for the 1.5rem size). `.wp-block-site-title` (0,1,0) beats
   theme.json's zero-specificity `:where()` on home too, so home is unchanged. */
.wp-block-site-title {
	font-family: var(--wp--preset--font-family--serif);
	font-size: clamp(0.984rem, 0.7928rem + 0.956vw, 1.5rem);
	font-weight: 500;
	letter-spacing: -0.02em;
}

/* The wordmark is the Biff logo (functions.php swaps the site-title's text for
   assets/brand/biff-logo.svg). The image is dropped by 22.3% of its height —
   where the BIFF letters stand in the plate — so the letters, not the plate's
   bottom edge, sit on the text baseline shared with the tagline and the nav. */
.wp-block-site-title.has-site-logo {
	line-height: 1;
}
.wp-block-site-title .site-logo {
	--logo-height: 2.125rem;
	display: inline-block;
	height: var(--logo-height);
	width: auto;
	max-width: none;
	vertical-align: calc(var(--logo-height) * -0.223);
}
.wp-site-blocks > footer .wp-block-site-title .site-logo {
	--logo-height: 1.5rem;
}

/* Brand lockup: align the tagline to the logo's true text baseline.
   `align-items: baseline` aligns the title and tagline on their shared text
   baseline regardless of their differing font sizes / line-heights. */
.site-brand {
	align-items: baseline;
}
.site-brand .wp-block-site-tagline {
	margin-block: 0;
	line-height: 1;
}

/* Header row: on desktop sit the logo and the nav on one shared text baseline.
   WP's flex layout only offers top/center/bottom, and `center` drops the title
   ~5px below the nav (the title's 1.7 line-height pushes its baseline into the
   lower half of its box). Mobile keeps `center` so the hamburger row — where
   the tagline is hidden and the menu is an icon button, not text — stays put. */
@media (min-width: 600px) {
	header .header-row {
		align-items: baseline;
	}
}

/* Navigation: open menu submenu/overlay surfaces follow the palette. */
.wp-block-navigation .wp-block-navigation__submenu-container,
.wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--wp--preset--color--base) !important;
	color: var(--wp--preset--color--contrast) !important;
	border-color: var(--wp--preset--color--hairline) !important;
}

/* Submenu dropdown ("Projects") — a clean, contained card. */
.wp-block-navigation .has-child .wp-block-navigation__submenu-container {
	min-width: 18.5rem;
	margin-top: 0.6rem;
	padding: 0.4rem;
	border: 1px solid var(--wp--preset--color--hairline) !important;
	border-radius: 12px;
	box-shadow: 0 12px 32px -12px color-mix(in srgb, var(--wp--preset--color--contrast) 22%, transparent);
}
.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	display: block;
	white-space: nowrap;
	padding: 0.5rem 0.7rem;
	border-radius: 8px;
	transition: background-color 0.12s ease, color 0.12s ease;
}
.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover,
.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation-item__content:focus {
	background-color: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--primary);
}
/* The parent toggle keeps the same weight as sibling links. */
.wp-block-navigation .wp-block-navigation-submenu__toggle {
	font-weight: inherit;
}
/* Edge guard: when the masthead is narrow enough that the nav wraps onto its
   own (left-aligned) line, the brand+nav no longer fit on one row — at and
   below 912px. In that state WordPress core still opens the dropdown leftward
   (right:0), which runs its left edge off-screen and clips the "BIF-" prefix.
   Flip it to open rightward while wrapped; at >=913px the nav right-justifies
   and core's default already fits. (Above the mobile overlay breakpoint only.) */
@media (min-width: 600px) and (max-width: 912px) {
	.wp-block-navigation .has-child > .wp-block-navigation__submenu-container {
		left: 0 !important;
		right: auto !important;
	}
}

/* ----- 8. Post-list (archive / search) ----------------------------------- */
.wp-block-post-template .wp-block-post {
	border-bottom: 1px solid var(--wp--preset--color--hairline);
	padding-bottom: var(--wp--preset--spacing--50);
}
.wp-block-post-template li.wp-block-post:last-child {
	border-bottom: none;
}
.wp-block-post-featured-image img {
	transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1), filter 0.3s ease;
}
.wp-block-post:hover .wp-block-post-featured-image img {
	transform: scale(1.02);
}

/* ----- 8b. Home index — masthead, search, hero + grid -------------------- */
/* The home template (index.html) widens the masthead and the post query to
   wide-size and tags them .home-intro / .is-listing. The query stays a
   constrained block (so pagination sits at reading width) while its grid is
   released to the full wide column below. */

/* Masthead: left-align its text to the wide column's edge (so it lines up with
   the grid) but keep the lines at a comfortable reading measure. */
.home-intro > * {
	max-width: 44rem;
	margin-inline: 0;
}

/* Journal search: a slim, editorial underline field — no chrome, on-brand. */
.home-search {
	max-width: 26rem;
	margin-top: 1.5rem;
}
.home-search form {
	display: flex;
	align-items: stretch;
	gap: 0.5rem;
	border-bottom: 1.5px solid var(--wp--preset--color--contrast);
}
.home-search input[type="search"] {
	flex: 1 1 auto;
	min-width: 0;
	border: 0;
	background: transparent;
	padding: 0.5rem 0.1rem;
	color: var(--wp--preset--color--contrast);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0;
}
.home-search input[type="search"]::placeholder { color: var(--wp--preset--color--muted); opacity: 1; }
.home-search input[type="search"]:focus { outline: none; }
.home-search form:focus-within { border-bottom-color: var(--wp--preset--color--primary); }
.home-search button {
	flex: 0 0 auto;
	border: 0;
	background: transparent;
	padding: 0 0.1rem;
	color: var(--wp--preset--color--muted);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--small);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	cursor: pointer;
	transition: color 0.15s ease;
}
.home-search button:hover { color: var(--wp--preset--color--primary); }

/* Release the grid from the query's constrained content-width and lay the
   posts out two-up, with hairline-framed thumbnails and the date demoted
   below the title. */
.is-listing .wp-block-post-template {
	max-width: none;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: var(--wp--preset--spacing--50);
	row-gap: var(--wp--preset--spacing--60);
}
.is-listing .wp-block-post-template .wp-block-post {
	border-bottom: none;
	padding-bottom: 0;
}
.is-listing .wp-block-post-featured-image img {
	border: 1px solid var(--wp--preset--color--hairline);
}
.is-listing .wp-block-post-date {
	margin-top: 0.5rem;
}

/* Lead story: full-width, image beside an enlarged title. */
.is-listing .wp-block-post-template > li.wp-block-post:first-child {
	grid-column: 1 / -1;
	display: grid;
	grid-template-columns: 1.15fr 1fr;
	column-gap: var(--wp--preset--spacing--60);
	align-items: start;
	margin-bottom: var(--wp--preset--spacing--20);
	padding-bottom: var(--wp--preset--spacing--60);
	border-bottom: 1px solid var(--wp--preset--color--hairline);
}
.is-listing .wp-block-post-template > li.wp-block-post:first-child > .wp-block-post-featured-image {
	grid-column: 1;
	grid-row: 1 / span 4;
	margin-bottom: 0;
}
.is-listing .wp-block-post-template > li.wp-block-post:first-child > :not(.wp-block-post-featured-image) {
	grid-column: 2;
}
.is-listing .wp-block-post-template > li.wp-block-post:first-child .wp-block-post-title {
	font-size: var(--wp--preset--font-size--xx-large);
}

/* .no-lead (the /all-posts/ archive, templates/page-all-posts.html): plain
   2-up grid on every page of the archive — no lead-story treatment for
   whichever post happens to be first on page N. */
.is-listing.no-lead .wp-block-post-template > li.wp-block-post:first-child {
	grid-column: auto;
	display: block;
	margin-bottom: 0;
	padding-bottom: 0;
	border-bottom: none;
}
.is-listing.no-lead .wp-block-post-template > li.wp-block-post:first-child > .wp-block-post-featured-image {
	margin-bottom: var(--wp--preset--spacing--40);
}
.is-listing.no-lead .wp-block-post-template > li.wp-block-post:first-child .wp-block-post-title {
	font-size: var(--wp--preset--font-size--x-large);
}

/* Collapse to a single column (and stack the lead story) on small screens. */
@media (max-width: 781.98px) {
	.is-listing .wp-block-post-template {
		grid-template-columns: 1fr;
	}
	.is-listing .wp-block-post-template > li.wp-block-post:first-child {
		display: block;
	}
	.is-listing .wp-block-post-template > li.wp-block-post:first-child > .wp-block-post-featured-image {
		margin-bottom: var(--wp--preset--spacing--40);
	}
}

/* Pagination */
.wp-block-query-pagination {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--small);
}
.wp-block-query-pagination .wp-block-query-pagination-numbers .page-numbers.current {
	color: var(--wp--preset--color--primary);
	font-weight: 700;
}

/* ----- 9. Block-style variations ----------------------------------------- */
/* Card group */
.wp-block-group.is-style-card {
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--hairline);
	border-radius: 14px;
	padding: var(--wp--preset--spacing--50);
}
/* Asterisk separator */
.wp-block-separator.is-style-asterisks {
	border: none;
	max-width: none;
	text-align: center;
	overflow: visible;
	height: auto;
}
.wp-block-separator.is-style-asterisks::before {
	content: "✳   ✳   ✳";
	color: var(--wp--preset--color--muted);
	font-size: 0.9rem;
	letter-spacing: 0.4em;
}
/* Framed image */
.wp-block-image.is-style-frame img {
	border: 1px solid var(--wp--preset--color--hairline);
	padding: 0.5rem;
	background: var(--wp--preset--color--base);
	border-radius: 12px;
}

/* ----- 10. Mobile header & overlay menu ---------------------------------- */
/* Below 600px the navigation collapses to a hamburger + full-screen overlay
   (WP's own breakpoint is min-width:600px). Core only sizes the open panel as
   `position:fixed` and otherwise leaves it as a right-aligned, content-height
   strip with absolutely-positioned submenus that overflow the viewport — so
   labels clipped off the left edge. We override core's own (high-specificity)
   selectors, hence the matching prefixes and !important on layout props. */
@media (max-width: 599.98px) {
	/* Drop the long tagline on phones so the title and menu button share one
	   tidy row instead of the button wrapping to a line of its own. */
	.wp-site-blocks > header .wp-block-site-tagline {
		display: none;
	}
	.wp-site-blocks > header .site-brand {
		min-width: 0;
	}

	/* Hamburger: a clear, finger-sized (≥44px) target aligned with the title. */
	.wp-block-navigation__responsive-container-open {
		display: flex;
		align-items: center;
		justify-content: center;
		min-width: 44px;
		min-height: 44px;
		padding: 0.5rem;
		margin-right: -0.5rem; /* keep the icon optically flush to the edge */
		color: var(--wp--preset--color--contrast);
	}
	.wp-block-navigation__responsive-container-open svg {
		width: 1.6rem;
		height: 1.6rem;
	}

	/* Full-screen overlay panel. */
	.wp-block-navigation__responsive-container.is-menu-open {
		position: fixed !important;
		inset: 0 !important;
		width: 100% !important;
		height: 100dvh !important;
		background-color: var(--wp--preset--color--base) !important;
	}

	/* Inset everything here, on the content wrapper, so top-level rows AND
	   submenus stay within the panel (no edge-clipping). */
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
		display: flex !important;
		flex-direction: column !important;
		align-items: stretch !important;
		justify-content: flex-start !important;
		box-sizing: border-box !important;
		width: 100% !important;
		padding: 4.5rem 1.5rem 2rem !important; /* top clears the close button */
		gap: 0 !important;
		overflow-y: auto !important;
	}
	.is-menu-open .wp-block-navigation__container {
		flex-direction: column !important;
		align-items: stretch !important;
		justify-content: flex-start !important;
		box-sizing: border-box !important;
		width: 100% !important;
		margin: 0 !important;
		padding: 0 !important;
		gap: 0 !important;
	}
	.is-menu-open .wp-block-navigation-item {
		width: 100%;
	}

	/* Each top-level row: large serif label, generous height, hairline divider. */
	.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content,
	.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-submenu__toggle {
		display: flex !important;
		align-items: center;
		gap: 0.5rem;
		box-sizing: border-box;
		width: 100%;
		min-height: 52px;
		padding: 0.5rem 0;
		font-family: var(--wp--preset--font-family--serif);
		font-size: 1.3rem;
		border-bottom: 1px solid var(--wp--preset--color--hairline);
	}
	/* Parent toggle pushes its chevron to the far end. */
	.is-menu-open .wp-block-navigation-submenu__toggle {
		justify-content: space-between;
	}

	/* Close (X): match the hamburger as a clear ≥44px target, top-right. */
	.is-menu-open .wp-block-navigation__responsive-container-close {
		display: flex;
		align-items: center;
		justify-content: center;
		top: 0.6rem;
		right: 1rem;
		min-width: 44px;
		min-height: 44px;
		padding: 0.5rem;
		color: var(--wp--preset--color--contrast);
	}
	.is-menu-open .wp-block-navigation__responsive-container-close svg {
		width: 1.6rem;
		height: 1.6rem;
	}

	/* Submenu ("Projects") inline inside the overlay — neutralise core's
	   absolute positioning AND the desktop floating-card chrome from section 7
	   (whose 3-class selector we must out-specify, hence the longer prefix);
	   just indent the children and keep them readable within the panel. */
	.wp-block-navigation .is-menu-open .has-child .wp-block-navigation__submenu-container {
		position: static !important;
		left: auto !important;
		right: auto !important;
		top: auto !important;
		transform: none !important;
		box-sizing: border-box !important;
		width: 100% !important;
		min-width: 0 !important;
		max-width: 100% !important;
		margin: 0 !important;
		padding: 0 0 0 1rem !important;
		border: none !important;
		border-radius: 0 !important;
		box-shadow: none !important;
		background: transparent !important;
		opacity: 1 !important;
		visibility: visible !important;
	}
	.wp-block-navigation .is-menu-open .has-child .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
		display: flex !important;
		align-items: center;
		box-sizing: border-box;
		width: 100%;
		min-height: 46px;
		padding: 0.4rem 0 !important;
		border-radius: 0 !important;
		font-family: var(--wp--preset--font-family--sans);
		font-size: 1.05rem;
		white-space: normal !important; /* long project names wrap, never clip */
		border-bottom: 1px solid color-mix(in srgb, var(--wp--preset--color--hairline) 60%, transparent);
	}
}

/* ----- 11. Skip link ----------------------------------------------------- */
.skip-link.screen-reader-text {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 999;
}
.skip-link.screen-reader-text:focus {
	left: 1rem;
	top: 1rem;
	width: auto;
	height: auto;
	padding: 0.6rem 1rem;
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	border-radius: 8px;
	font-family: var(--wp--preset--font-family--sans);
	font-size: 0.9rem;
}

/* ----- 12. Single post — meta, contents, footer nav --------------------- */
/* Byline + date on one line: "By {author} · {date} · {N min read}". */
.post-meta {
	align-items: baseline;
	color: var(--wp--preset--color--muted);
}
.post-meta .wp-block-post-author-name {
	color: var(--wp--preset--color--muted);
}
.post-meta .wp-block-post-author-name::before {
	content: "By ";
}
.post-meta .wp-block-post-author-name::after {
	content: " ·";
}
/* Reading-time suffix on the post-date line (server-rendered, see functions.php). */
.reading-time {
	color: var(--wp--preset--color--muted);
}

/* "Contents" box — built from the article's h2/h3 anchors. */
.post-toc {
	margin: 0 0 var(--wp--preset--spacing--50);
	padding: 1.1rem 1.35rem;
	border: 1px solid var(--wp--preset--color--hairline);
	border-radius: 14px;
	background: color-mix(in srgb, var(--wp--preset--color--surface) 50%, transparent);
}
.post-toc > summary {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	list-style: none;
	cursor: pointer;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}
.post-toc > summary::-webkit-details-marker { display: none; }
.post-toc > summary::before {
	content: "§";
	color: var(--wp--preset--color--primary);
	font-size: 1.05em;
}
.post-toc[open] > summary {
	margin-bottom: 0.85rem;
}
.post-toc ol {
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: none;
	/* Keep the contents list visibly subordinate to the article body, which
	   runs at the larger `medium` size — otherwise it reads as a second column
	   of content rather than a quiet wayfinding aid. */
	font-size: var(--wp--preset--font-size--small);
}
.post-toc li {
	margin: 0.45rem 0;
	line-height: 1.35;
}
.post-toc li.h3 {
	padding-left: 0.9rem;
}
.post-toc a {
	text-decoration: none;
	color: var(--wp--preset--color--contrast);
	border-bottom: 1px solid transparent;
	transition: color 0.15s ease, border-color 0.15s ease;
}
.post-toc li.h3 a {
	color: var(--wp--preset--color--muted);
}
.post-toc a:hover {
	color: var(--wp--preset--color--primary);
}
/* Active section while scrolling (added by post.js). */
.post-toc a.is-active {
	color: var(--wp--preset--color--primary);
	border-bottom-color: color-mix(in srgb, var(--wp--preset--color--primary) 45%, transparent);
}

/* End-of-post navigation: previous / next as quiet framed cards. */
.post-nav .wp-block-post-navigation-link {
	flex: 1 1 14rem;
	padding: 1rem 1.15rem;
	border: 1px solid var(--wp--preset--color--hairline);
	border-radius: 12px;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}
.post-nav .wp-block-post-navigation-link:hover {
	border-color: color-mix(in srgb, var(--wp--preset--color--primary) 45%, transparent);
	background: color-mix(in srgb, var(--wp--preset--color--surface) 45%, transparent);
}
/* The small "Previous"/"Next" label core prints before the link. */
.post-nav .post-navigation-link__label {
	display: block;
	margin-bottom: 0.3rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.78rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}
.post-nav .wp-block-post-navigation-link.post-navigation-link-next {
	text-align: right;
}
.post-nav .wp-block-post-navigation-link a {
	font-family: var(--wp--preset--font-family--serif);
	font-size: 1.05rem;
	text-decoration: none;
	color: var(--wp--preset--color--contrast);
}
.post-nav .wp-block-post-navigation-link a:hover {
	color: var(--wp--preset--color--primary);
}

/* "← All writing" return link. */
.back-to-journal a {
	color: var(--wp--preset--color--muted);
	text-decoration: none;
}
.back-to-journal a:hover {
	color: var(--wp--preset--color--primary);
}

/* ----- 13. Single post — reading aids (JS progressive enhancement) ------- */
/* All three elements are injected by assets/js/post.js; with no JS the page
   is unchanged and fully usable. */

/* Thin reading-progress bar pinned to the top of the viewport. */
.latent-progress {
	position: fixed;
	top: 0;
	left: 0;
	height: 3px;
	width: 0;
	z-index: 1000;
	background: var(--wp--preset--color--primary);
	transition: width 0.08s linear;
}

/* Floating "back to top" button — fades in once you're well into the article. */
.latent-top {
	position: fixed;
	right: 1.4rem;
	bottom: 1.4rem;
	z-index: 1000;
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	padding: 0;
	border: 1px solid var(--wp--preset--color--hairline);
	border-radius: 50%;
	background: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--contrast);
	font-size: 1.15rem;
	line-height: 1;
	cursor: pointer;
	opacity: 0;
	transform: translateY(8px);
	pointer-events: none;
	transition: opacity 0.2s ease, transform 0.2s ease, border-color 0.15s ease;
	box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
}
.latent-top.is-visible {
	opacity: 1;
	transform: none;
	pointer-events: auto;
}
.latent-top:hover {
	border-color: color-mix(in srgb, var(--wp--preset--color--primary) 50%, transparent);
	color: var(--wp--preset--color--primary);
}

/* On wide screens the Contents box becomes a sticky sidebar in the left gutter,
   so it tracks you through the article instead of pushing the body down. The
   article keeps its full reading measure; below 1360px it falls back to the
   inline collapsible box. The sidebar is bounded by its containing block
   (the post body), so it never escapes into the footer.

   Engages at 1360px, not 1280: at 1280 the left gutter (~288px) can't hold the
   240px sidebar plus a comfortable edge margin and gap without crushing it
   against the viewport edge. 1360 is the narrowest width where the box clears
   the edge by ≥3rem and still leaves the article its full 44rem measure.

   margin-left MUST be !important: post-content is a constrained-layout group, so
   WP core forces `margin-left:auto !important` on its children — without our own
   !important the gutter pull collapses to 0 and the float jams the body text
   with no gap (the bug that shipped 1.0.10–1.0.11). box-sizing:border-box makes
   `width` the whole box so the negative margin places it precisely.

   Gutter pull = 16.16rem: the masthead wordmark sits 15rem left of the article
   content edge (74rem header vs 44rem body, both centred → (74-44)/2 = 15rem).
   To make the top-level (h2) TOC entries start in the same column as the logo,
   the box's left edge goes a further (1px border + 1.1rem padding ≈ 1.16rem)
   left so the *text*, not the box edge, aligns with the wordmark. Holds at every
   width ≥1360px since logo and TOC share the page centre. (Was -17.5rem, which
   overshot — the h2 entries hung ~1.3rem past the logo into the gutter.) */
@media (min-width: 1360px) {
	.post-toc {
		position: sticky;
		top: 5.5rem;
		float: left;
		box-sizing: border-box;
		width: 15rem;
		margin-left: -16.16rem !important;
		margin-bottom: 0;
		max-height: calc(100vh - 8rem);
		overflow-y: auto;
		padding: 0.15rem 0 0.15rem 1.1rem;
		border: none;
		border-left: 1px solid var(--wp--preset--color--hairline);
		border-radius: 0;
		background: transparent;
	}
	/* Always-visible sidebar: the disclosure summary is just a heading now. */
	.post-toc > summary {
		pointer-events: none;
	}
	.post-toc[open] > summary {
		margin-bottom: 1rem;
	}
}
