/* point.free — overlay on Duckquill.
 * Tighter typography, identity card on landing, smaller epigraph.
 * Keep this file small. If it grows past ~50 lines, reconsider.
 */

/* --- Nav home icon ---
 * We override Duckquill's nav (see templates/partials/nav.html) to drop the
 * redundant "point.free" text after the home icon. Without trailing text the
 * theme's `margin-inline-end: 0.25rem` on the icon causes a visible offset,
 * and the icon itself reads as a bit small standing alone. Bump size + drop
 * the trailing margin so it sits cleanly in the nav row.
 */
#site-nav #home a .icon {
	margin-inline-end: 0;
	width: 1.1em;
	height: 1.1em;
}

/* --- Nav on narrow viewports ---
 *
 * Duckquill's _nav.scss applies this at <=480px:
 *
 *     li:not(:has(.circle)) { flex: 0 0 100%; }
 *
 * The intent is that any nav item which isn't a small circular icon
 * button (search, theme, feed) takes a full row so longer text labels
 * wrap cleanly. With Duckquill's stock nav that's two rows: the home
 * link (icon + site title text) on top, then a row of circles below.
 *
 * Our nav (templates/partials/nav.html) is shaped differently — the
 * home <a> is an icon alone, and we have two short text links ("Blog",
 * "About"). The theme's rule therefore stacks FOUR rows on mobile:
 *
 *     [   home icon (alone, centred)   ]
 *     [          Blog                  ]
 *     [          About                 ]
 *     [   search · theme · feed        ]
 *
 * which produces a tall card that pushes the actual landing content
 * below the fold. The home icon centred alone on its own row is the
 * giveaway.
 *
 * Fix: reverse the full-row rule for our shapes. The home icon is
 * effectively a circle-shaped target so it should sit inline with the
 * circle row. The text links are short enough that "Blog · About" fits
 * comfortably on one line on every viewport down to ~280px. The result
 * is two rows max ("home · Blog · About" wraps to a circles row), and
 * usually one on phones in landscape.
 *
 * We deliberately only target #home, the .divider, and the text-link
 * items by elimination (anything without a .circle that ALSO isn't the
 * home or divider must be a text link). The circle row is already
 * inline in the theme; we don't touch it.
 */
@media only screen and (max-width: 480px) {
	/* Reverse the theme's `flex: 0 0 100%` so items size to content
	 * and let flex-wrap handle overflow. */
	#site-nav nav ul li:not(:has(.circle)) {
		flex: 0 1 auto;
	}

	/* The theme hides the .divider at <=480px (it was needed to
	 * separate the old two-row stack). Bring it back as a quiet
	 * vertical hairline between the home icon and the text links —
	 * now that everything fits on one row, the divider is the visual
	 * grouping we lose otherwise. */
	#site-nav nav ul li.divider {
		display: block;
	}

	/* --- Kill the theme's banner-induced top void ---
	 *
	 * Duckquill's _article.scss has this rule:
	 *
	 *     @media (max-width: 480px) {
	 *         body:has(#banner-container) #site-nav { margin-block-start: calc(50vw + 1rem); }
	 *     }
	 *
	 * The intent: reserve space at the top of the page so a 2:1
	 * banner image shows through above the nav unobscured. The banner
	 * is `position: fixed; z-index: -1` with a fade-to-transparent
	 * mask — drawn behind everything, fading into the page background.
	 *
	 * The result on our setup: the nav gets shoved roughly a third of
	 * the way down the viewport, floating in a field of black with
	 * just a sliver of banner texture visible above it. The reserved
	 * space reads as void, not as "look at the banner". The reviewer
	 * called it: "the bar looks like a standalone content element
	 * parked above your name".
	 *
	 * We don't want the push-down. Banners are decorative, not load-
	 * bearing; the nav sits at the top of the page like every other
	 * site nav and the banner paints behind it (its glass-bg + blur
	 * keep it readable against any banner pixel). Setting
	 * margin-block-start back to the theme's default (1rem, from the
	 * non-mobile rule) restores the expected vertical rhythm.
	 *
	 * Important: this rule must come AFTER any rule that sets
	 * margin-block-start on #site-nav at this breakpoint, and uses
	 * the same selector specificity the theme uses (body:has(...)
	 * #site-nav) so it wins on the cascade.
	 */
	body:has(#banner-container) #site-nav:not(#handle + #site-nav) {
		margin-block-start: 1rem;
	}

	/* --- Nav width matches main content width on mobile ---
	 *
	 * Duckquill sets `max-width: min(var(--container-width), 90%)` on
	 * #site-nav. On any mobile viewport that resolves to 90% — a
	 * ~5%-per-side gutter. That's wider than what `main` uses:
	 *
	 *     main { width: calc(100% - 2rem); }   // 1rem each side
	 *
	 * The mismatch is invisible on pages without a full-width visual
	 * (blog index, about) because nothing in the page bleeds to the
	 * viewport edge for the eye to compare against. But on pages WITH
	 * a banner (landing, posts) the banner is `position: fixed` at
	 * 100vw — so the eye sees a viewport-wide image with a 90%-wide
	 * nav floating below it, and reads the gap as "too much margin on
	 * both sides".
	 *
	 * Fix: match main's gutters. Same 1rem-per-side as the article
	 * body underneath, so the nav and the prose column share a left
	 * and right edge — wherever the banner is also present, the nav
	 * no longer looks stranded inside it.
	 */
	#site-nav {
		max-width: calc(100% - 2rem);
	}
}

/* --- Body type polish --- */

article p {
	line-height: 1.65;
}

/* --- Visually-hidden utility ---
 * For pages that opt into `hide_title = true` in front-matter, page.html
 * applies this class to the auto-rendered <h1>. We keep it in the DOM for
 * accessibility (screen readers, document outline) but remove it visually.
 */
.visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* --- Wider container for the about page ---
 * Duckquill's default --container-width is 45rem, which is right for prose.
 * The about page earns more because it has the two-column projects grid;
 * we widen it via the :has() trick. The landing deliberately keeps the
 * default 45rem column — its job is to read like the front of a written
 * thing, not a poster. A wider frame just leaves the centred copy
 * stranded in air and reads as hollow.
 */
body:has(.about-hero) main {
	max-width: 64rem;
}

/* --- About page: hero + stanzas --- */

.about-hero {
	text-align: center;
	margin: 2rem 0 5rem;
}

.about-hero h1 {
	font-family: monospace;
	font-size: clamp(2.25rem, 5vw, 3.25rem);
	letter-spacing: 0.02em;
	margin: 0 0 1.25rem;
}

.about-tagline {
	font-size: 1.2rem;
	color: var(--fg-muted-5);
	max-width: 40rem;
	margin: 0 auto;
	line-height: 1.5;
}

.about-stanza {
	max-width: 40rem;
	margin: 2.5rem auto;
	font-size: 1rem;
	line-height: 1.75;
}

.about-divider {
	width: 4rem;
	height: 1px;
	margin: 7rem auto;
	background: var(--fg-muted-3);
	border: 0;
}

.projects-heading {
	text-align: center;
	font-family: monospace;
	font-size: 1.1rem;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: var(--fg-muted-5);
	margin: 0 0 5rem;
	font-weight: 400;
}

/* --- Project rows: alternating zig-zag --- */

.project-row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 4rem;
	align-items: center;
	margin: 7rem 0;
}

.project-row.reverse .project-image {
	order: 2;
}

.project-image img {
	width: 100%;
	height: auto;
	display: block;
	border-radius: 0.5rem;
	border: 1px solid var(--fg-muted-2);
}

.project-text h3 {
	font-family: monospace;
	font-size: 1.5rem;
	letter-spacing: 0.02em;
	margin: 0 0 1rem;
}

.project-text p {
	margin: 0 0 1rem;
	font-size: 1rem;
	line-height: 1.65;
	color: var(--fg-color);
}

.project-text .project-link {
	font-family: monospace;
	font-size: 0.9rem;
	margin-top: 1.25rem;
	color: var(--fg-muted-5);
}

.project-text .project-link a {
	text-decoration: none;
	color: var(--accent-color);
}

.project-text .project-link a:hover {
	text-decoration: underline;
}

/* Mobile: stack image above text, no alternation. */
@media (max-width: 48rem) {
	.project-row,
	.project-row.reverse {
		grid-template-columns: 1fr;
		gap: 1.25rem;
		margin: 3rem 0;
	}
	.project-row.reverse .project-image {
		order: 0;
	}
}

/* --- About page footer line --- */

.about-elsewhere {
	text-align: center;
	font-family: monospace;
	font-size: 0.9rem;
	color: var(--fg-muted-5);
	margin: 3rem 0;
}

/* --- As-seen-in carousel ---
 * Auto-scrolling marquee of outlet logos. The track contains two identical
 * copies of the logo list; we translate from 0 to -50% and loop, which makes
 * the seam invisible. Pauses on hover so individual logos remain readable
 * and clickable. Edges are softly faded with a horizontal mask.
 *
 * Logos that haven't been provided yet render as a small text tile so the
 * component degrades gracefully.
 */

.as-seen-in {
	margin: 7rem auto;
	/* Break out of the parent container so the carousel can span the full
	 * page width. The about page container is 64rem; we go wider so logos
	 * have room to breathe and the edge fades sit further from the content. */
	max-width: min(80rem, 100vw - 2rem);
	text-align: center;
}

.as-seen-in-label {
	font-family: monospace;
	font-size: 0.95rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--fg-muted-5);
	margin: 0 0 3rem;
}

.as-seen-in-carousel {
	position: relative;
	width: 100%;
	/* Generous top padding gives rage particles airspace to drift upward
	 * without being clipped; bottom padding accommodates hover lift. */
	padding: 4rem 0 1rem;
	/* `overflow-x: clip` clips the looping track horizontally without forcing
	 * vertical scrolling (unlike `hidden`). This lets the Lunduke rage
	 * particles escape upward beyond the row's bounds. */
	overflow-x: clip;
	overflow-y: visible;
	--edge-fade: 4rem;
}

/* Edge fade implemented as pseudo-element gradient overlays rather than
 * `mask-image` on the carousel. A mask would clip the rage particles when
 * they rise above the carousel's content box; pseudo-overlays only paint
 * over the logos at the left/right edges and leave vertical airspace
 * untouched.
 *
 * The gradients fade from the page background colour at the edges to fully
 * transparent inside the fade zone, producing the same visual "logos
 * dissolve into the page" effect. */
.as-seen-in-carousel::before,
.as-seen-in-carousel::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	width: var(--edge-fade);
	pointer-events: none;
	z-index: 4;
}

.as-seen-in-carousel::before {
	left: 0;
	background: linear-gradient(to right, var(--bg-color) 0%, transparent 100%);
}

.as-seen-in-carousel::after {
	right: 0;
	background: linear-gradient(to left, var(--bg-color) 0%, transparent 100%);
}

.as-seen-in-track {
	display: flex;
	align-items: center;
	gap: 4rem;
	width: max-content;
	animation: as-seen-in-scroll 60s linear infinite;
}

.as-seen-in-carousel:hover .as-seen-in-track,
.as-seen-in-carousel:focus-within .as-seen-in-track {
	animation-play-state: paused;
}

@keyframes as-seen-in-scroll {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
	.as-seen-in-carousel {
		overflow-x: auto;
	}
	.as-seen-in-track {
		animation: none;
	}
}

.as-seen-in-logo {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	height: 5rem;
	flex-shrink: 0;
	color: var(--fg-muted-5);
	text-decoration: none;
	transition: filter 150ms ease, opacity 150ms ease, transform 150ms ease;
	opacity: 1;
	/* Full colour by default. Add the modifier class `.as-seen-in--mono` on the
	 * outer .as-seen-in container to opt into greyscale-with-colour-on-hover. */
}

.as-seen-in-logo:hover,
.as-seen-in-logo:focus-visible {
	color: var(--fg-color);
	opacity: 1;
	transform: translateY(-2px);
	text-decoration: none;
}

/* Monochrome variant: opt-in via <div class="as-seen-in as-seen-in--mono">.
 * Raster logos arrive in arbitrary colours; desaturating them at rest lets
 * the row read as one coherent strip, with brand colour restored on hover. */
.as-seen-in--mono .as-seen-in-logo {
	filter: grayscale(1);
	opacity: 0.85;
}

.as-seen-in--mono .as-seen-in-logo:hover,
.as-seen-in--mono .as-seen-in-logo:focus-visible {
	filter: grayscale(0);
	opacity: 1;
}

.as-seen-in-logo img {
	height: 100%;
	width: auto;
	max-width: 16rem;
	object-fit: contain;
	display: block;
}

.as-seen-in-text {
	font-family: monospace;
	font-size: 0.85rem;
	letter-spacing: 0.04em;
	padding: 0.35rem 0.75rem;
	border: 1px solid var(--fg-muted-2);
	border-radius: 0.25rem;
	white-space: nowrap;
}

/* --- Lunduke easter egg ---
 * On hover the logo shakes and a small cloud of 💢 rage particles spawn
 * around the top, drifting upward and fading out. Bryan didn't write fondly
 * of me; this is a fond reply.
 *
 * Implementation: five absolutely-positioned spans. Each particle's start
 * position (left offset) and animation delay are set via :nth-child so the
 * markup stays a flat list of identical elements. Animation runs from
 * translateY(0) → translateY(-3rem) with opacity 0 → 1 → 0.
 */

.as-seen-in-logo--lunduke {
	position: relative;
	/* Pull above every carousel chrome element so rage particles (children
	 * of this logo) stack above neighbouring logos AND above the edge-fade
	 * pseudo-gradients (z-index 4). The particles' own z-index is capped
	 * inside this stacking context, so the parent must win at the carousel
	 * level. */
	z-index: 5;
}

/* Red rage tint: applied as a CSS filter directly on the <img> so the colour
 * shift is *part of* the image — meaning it shakes in lockstep with the
 * lunduke-shake animation instead of sitting on top as a static rectangle.
 *
 * The recipe: pump saturation, bias the hue toward red, and darken slightly.
 * `sepia(1)` first remaps every colour to a warm monochrome we can then
 * rotate cleanly with `hue-rotate`; without sepia the rotation just smears
 * the original palette. A subtle drop-shadow adds a red "glow" halo that
 * also shakes with the image.
 *
 * The 0%→100% fade is driven by transitioning the `filter` property; the
 * resting filter is `none` so unhovered logos render true-colour. */
.as-seen-in-logo--lunduke img {
	transition: filter 450ms ease-in-out;
}

.as-seen-in-logo--lunduke:hover img,
.as-seen-in-logo--lunduke:focus-visible img {
	filter:
		sepia(1)
		saturate(6)
		hue-rotate(-40deg)
		brightness(0.95)
		contrast(1.15)
		drop-shadow(0 0 0.6rem rgba(220, 20, 20, 0.65));
}

.as-seen-in-rage {
	position: absolute;
	/* Anchor the rage layer directly above the logo so particles spawn from
	 * the top edge and rise into the carousel's reserved airspace. Using
	 * `bottom: 100%` (instead of `inset: 0`) guarantees the layer sits above
	 * the image regardless of intrinsic image dimensions.
	 *
	 * `height` is generous so particles can travel a long way upward without
	 * being clipped — they're z-indexed above every carousel chrome element
	 * (edge fades, neighbouring logos) so they truly float above. */
	left: 0;
	right: 0;
	bottom: 100%;
	height: 8rem;
	pointer-events: none;
	/* Sit above edge-fade gradients (z-index 4) and neighbour logos. */
	z-index: 10;
	/* The container itself never animates; only its child particles do. */
}

.as-seen-in-rage-particle {
	position: absolute;
	/* Sit at the bottom of the rage layer (= top of the logo) and rise from
	 * there into the layer's reserved airspace above. */
	bottom: 0;
	font-size: 1.6rem;
	opacity: 0;
	pointer-events: none;
	/* Centre horizontally as a baseline; :nth-child overrides per-particle. */
	left: 50%;
	transform: translate(-50%, 0) scale(0.4) rotate(0);
	will-change: transform, opacity;
}

/* Five particles fanned out across the top of the logo, each with a unique
 * horizontal start, vertical travel distance, rotation, and timing offset.
 * Numbers chosen by eye to feel scattered without being random. */

.as-seen-in-rage-particle:nth-child(1) { left: 18%; --rage-rotate: -22deg; --rage-rise: -3.2rem; }
.as-seen-in-rage-particle:nth-child(2) { left: 38%; --rage-rotate:  -8deg; --rage-rise: -3.8rem; }
.as-seen-in-rage-particle:nth-child(3) { left: 50%; --rage-rotate:   2deg; --rage-rise: -4.2rem; }
.as-seen-in-rage-particle:nth-child(4) { left: 64%; --rage-rotate:  14deg; --rage-rise: -3.6rem; }
.as-seen-in-rage-particle:nth-child(5) { left: 82%; --rage-rotate:  26deg; --rage-rise: -3.0rem; }

.as-seen-in-logo--lunduke:hover .as-seen-in-rage-particle,
.as-seen-in-logo--lunduke:focus-visible .as-seen-in-rage-particle {
	animation: lunduke-rage-rise 900ms ease-out forwards;
}

/* Staggered start so the cloud puffs rather than fires in unison. */
.as-seen-in-logo--lunduke:hover .as-seen-in-rage-particle:nth-child(1),
.as-seen-in-logo--lunduke:focus-visible .as-seen-in-rage-particle:nth-child(1) { animation-delay: 0ms; }
.as-seen-in-logo--lunduke:hover .as-seen-in-rage-particle:nth-child(2),
.as-seen-in-logo--lunduke:focus-visible .as-seen-in-rage-particle:nth-child(2) { animation-delay: 60ms; }
.as-seen-in-logo--lunduke:hover .as-seen-in-rage-particle:nth-child(3),
.as-seen-in-logo--lunduke:focus-visible .as-seen-in-rage-particle:nth-child(3) { animation-delay: 30ms; }
.as-seen-in-logo--lunduke:hover .as-seen-in-rage-particle:nth-child(4),
.as-seen-in-logo--lunduke:focus-visible .as-seen-in-rage-particle:nth-child(4) { animation-delay: 90ms; }
.as-seen-in-logo--lunduke:hover .as-seen-in-rage-particle:nth-child(5),
.as-seen-in-logo--lunduke:focus-visible .as-seen-in-rage-particle:nth-child(5) { animation-delay: 120ms; }

@keyframes lunduke-rage-rise {
	0%   { opacity: 0; transform: translate(-50%, 0) scale(0.5) rotate(0); }
	20%  { opacity: 1; transform: translate(-50%, -0.8rem) scale(1) rotate(calc(var(--rage-rotate) * 0.5)); }
	100% { opacity: 0; transform: translate(-50%, var(--rage-rise)) scale(1.1) rotate(var(--rage-rotate)); }
}

.as-seen-in-logo--lunduke:hover img,
.as-seen-in-logo--lunduke:focus-visible img {
	animation: lunduke-shake 360ms ease-in-out;
}

@keyframes lunduke-shake {
	0%, 100% { transform: translateX(0) rotate(0); }
	15%      { transform: translateX(-2px) rotate(-1.5deg); }
	35%      { transform: translateX(2px) rotate(1.5deg); }
	55%      { transform: translateX(-2px) rotate(-1deg); }
	75%      { transform: translateX(2px) rotate(1deg); }
}

@media (prefers-reduced-motion: reduce) {
	.as-seen-in-logo--lunduke:hover img,
	.as-seen-in-logo--lunduke:focus-visible img {
		animation: none;
	}
	.as-seen-in-logo--lunduke:hover .as-seen-in-rage-particle,
	.as-seen-in-logo--lunduke:focus-visible .as-seen-in-rage-particle {
		animation: none;
		opacity: 1;
		transform: translate(-50%, -1.5rem) scale(1);
	}
	/* Skip the slow cross-fade; snap the red tint instead. */
	.as-seen-in-logo--lunduke img {
		transition: none;
	}
}

/* ============================================================
 * Landing page
 *
 * Composition mirrors the about page so the two feel like cousins:
 *
 *   hero          — name, tagline, byline (centred, generous)
 *   thesis        — the Ashby passage, typeset like a real book page
 *                   with marginal folios; the only piece of decoration
 *                   on the entire landing, intentionally so
 *   divider       — single hairline, same proportions as about
 *   writing       — one featured post (banner + excerpt) +
 *                   a tight index of the next four
 *   divider
 *   elsewhere
 *
 * No drop shadows, no boxes, no gradients. The drama is typographic:
 * scale contrast, generous whitespace, and the marginal folios on the
 * thesis. If anything needs adding later, it goes in a NEW block below
 * — do not start sprinkling decoration into the existing rules.
 * ============================================================ */

/* --- Hero ---
 * Title is centred — it's an identity mark, treat it like one. Everything
 * underneath is left-aligned within the same prose column so the reader's
 * eye gets a left edge to track down from the very first line of copy.
 * Centred copy under a centred title is what made the previous version
 * read as ceremonial / hollow; this gives the page a spine.
 */

/* The visible <h1> "point . free" was removed in favour of a quieter
 * opening — the byline now leads. The h1 is kept in the DOM but
 * .visually-hidden so the document outline and screen readers still
 * see a page title. Because the hidden h1 takes zero layout space, we
 * compensate here: the top margin absorbs the old title's rendered
 * height + its bottom margin (~4rem + 1.5rem ≈ 5.5rem) so everything
 * below this point stays exactly where it was. The matching .home-title
 * rule below is kept commented in case the visible title is restored.
 */
.home-hero {
	margin: 6.5rem 0 2.5rem;
}

/* Retained for reference / easy restoration of the visible title:
.home-hero .home-title {
	font-family: monospace;
	font-size: clamp(2.75rem, 7vw, 4.5rem);
	letter-spacing: 0.04em;
	margin: 0 0 1.5rem;
	font-weight: 600;
	line-height: 1;
	text-align: center;
}
*/

.home-tagline {
	font-size: 1.2rem;
	line-height: 1.55;
	color: var(--fg-color);
	margin: 0 0 1.25rem;
}

/* Two-line byline. First line names the author (slightly louder, neutral
 * body colour); second line lists credentials (smaller, muted, tracked).
 * They're one breath, not two paragraphs — kept tight with a small top
 * margin on the meta line rather than the paragraph default. */
.home-byline {
	font-family: monospace;
	font-size: 0.9rem;
	letter-spacing: 0.04em;
	color: var(--fg-color);
	margin: 0;
}

.home-byline--meta {
	margin-top: 0.4rem;
	font-size: 0.8rem;
	letter-spacing: 0.06em;
	color: var(--fg-muted-5);
}

.home-byline a {
	color: inherit;
	text-decoration: none;
	border-bottom: 1px solid var(--fg-muted-2);
	transition: color 150ms ease, border-color 150ms ease;
}

.home-byline a:hover,
.home-byline a:focus-visible {
	color: var(--accent-color);
	border-bottom-color: var(--accent-color);
}

/* --- Thesis ---
 * The Ashby passage. Typeset as a centred book page: each clause on its
 * own line, with the page number floated to the right margin as a small
 * monospaced folio — a typographic gesture that frames the passage as
 * *cited material*, not as decoration. A faint accent-coloured rule sits
 * to the left of the whole block, visible only at desktop widths; at
 * narrower viewports it disappears and the lines re-centre. The figcaption
 * underneath is the source. The gloss after that is one sentence in my
 * voice that lands the point. Nothing else lives in here.
 */

.home-thesis {
	margin: 2.5rem 0;
	padding: 0;
	position: relative;
}

.home-thesis-quote {
	/* Override Duckquill's blockquote chrome entirely. */
	margin: 0;
	padding: 0 0 0 2rem;
	border: 0;
	background: none;
	font-family: Georgia, "Iowan Old Style", "Source Serif Pro", "Times New Roman", serif;
	font-size: clamp(1.15rem, 1.6vw, 1.4rem);
	line-height: 1.55;
	color: var(--fg-color);
	border-left: 1px solid var(--accent-color);
}

.home-thesis-line {
	/* Single continuous paragraph — the earlier per-clause grid + folios
	 * fragmented what is one Ashby thought into two competing pull-quotes.
	 * Set it as prose, behind the accent rule, and let the sentence carry
	 * itself. */
	margin: 0;
}

.home-thesis-cite {
	margin: 1.25rem 0 0 2rem;
	font-family: monospace;
	font-size: 0.8rem;
	letter-spacing: 0.06em;
	color: var(--fg-muted-5);
}

.home-thesis-cite cite {
	font-style: italic;
}

.home-thesis-gloss {
	max-width: 38rem;
	margin: 3rem auto 0;
	text-align: center;
	font-size: 1rem;
	line-height: 1.65;
	color: var(--fg-muted-5);
}

.home-thesis-gloss code {
	/* The theme's inline-code default is fine but a touch loud on a quiet
	 * line; calm it to match the surrounding muted text. */
	font-size: 0.92em;
	background: none;
	padding: 0;
	color: var(--fg-color);
	opacity: 0.85;
}

@media (max-width: 36rem) {
	.home-thesis-quote {
		padding-left: 1rem;
	}
	.home-thesis-cite {
		margin-left: 1rem;
	}
}

/* --- Stanzas ---
 * The author's own voice, after the cited thesis and before the post
 * index. Same shape as .about-stanza so the two pages feel related, but
 * defined locally so the landing's rhythm can drift independently. This
 * is the page's editorial middle: without it the landing reads as a
 * quote followed by a list of links. With it, there is somebody home.
 */
.home-stanza {
	margin: 1.5rem 0;
	font-size: 1.05rem;
	line-height: 1.75;
	color: var(--fg-color);
}

.home-stanza + .home-stanza {
	margin-top: 1.5rem;
}

.home-stanza code {
	font-size: 0.92em;
	background: none;
	padding: 0;
	color: var(--fg-color);
	opacity: 0.9;
}

/* --- Divider ---
 * Same proportions as the about page's divider so the two pages share
 * the same punctuation. Defined locally (rather than sharing
 * .about-divider) because the rhythm before/after differs. At the
 * narrower 45rem landing column, the about page's 7rem felt like a
 * chasm; 4rem reads as a real break without splitting the page in two.
 */
.home-divider {
	width: 4rem;
	height: 1px;
	margin: 4rem auto;
	background: var(--fg-muted-3);
	border: 0;
}

/* --- "Writing" section label ---
 * Left-aligned editorial deck head, not a centred banner. Centred all-caps
 * tracking-out above a centred card is what reads as "placeholder website
 * section heading"; left-aligned, it reads as "the writing starts here".
 */

.home-section-label {
	font-family: monospace;
	font-size: 0.85rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--fg-muted-5);
	margin: 2.5rem 0 1.25rem;
	font-weight: 500;
}

/* --- Featured post ---
 * The most recent post gets a project-row-style treatment so the landing
 * feels alive. Whole card is one click target. On hover the title takes
 * the accent colour and the image lifts a hair — the only motion on the
 * page outside the about-page carousel.
 */

/* Stacked lead-story layout: full-width image on top, headline and copy
 * underneath. At a 45rem prose column, side-by-side reduces both halves
 * to something small and polite; stacking lets the image carry weight
 * and lets the title set at display scale. This is the standard
 * editorial layout for a lead story for a reason.
 */
.home-featured {
	margin: 0 0 3rem;
}

.home-featured-link {
	display: block;
	text-decoration: none;
	color: inherit;
}

.home-featured-media {
	overflow: hidden;
	border-radius: 0.5rem;
	border: 1px solid var(--fg-muted-2);
	aspect-ratio: 16 / 9;
	background: var(--fg-muted-1);
	margin: 0 0 1.75rem;
}

/* Reset the theme's global <img> chrome inside our editorial card. The
 * theme applies margin: 1rem auto, a drop shadow, a border-radius, and
 * a zoom-in hover cursor to every <img>; all of those fight with our
 * container, which already provides its own frame and lives inside an
 * <a>. Without these resets, the inner image starts 1rem from the top
 * of the container — that's the "dead space at the top of the image". */
.home-featured-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	margin: 0;
	box-shadow: none;
	border-radius: 0;
	background: none;
	transition: transform 450ms ease;
}

.home-featured-link:hover .home-featured-media img,
.home-featured-link:focus-visible .home-featured-media img {
	transform: scale(1.02);
	/* Override the theme's img:hover treatment (zoom-in cursor, extra
	 * shadow, repositioning). The card handles its own hover; the image
	 * just scales. */
	box-shadow: none;
	border-radius: 0;
	position: static;
}

/* Cancel the theme's zoom-in cursor on the image — the whole card is
 * one click target, the cursor should be pointer. */
.home-featured-link .home-featured-media img {
	cursor: pointer;
}

.home-featured-body {
	min-width: 0;
}

.home-featured-eyebrow {
	font-family: monospace;
	font-size: 0.78rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--accent-color);
	margin: 0 0 0.85rem;
}

.home-featured-dot {
	margin: 0 0.4em;
	color: var(--fg-muted-3);
}

.home-featured-eyebrow time {
	color: var(--fg-muted-5);
	letter-spacing: 0.06em;
	text-transform: none;
}

.home-featured-title {
	font-family: monospace;
	/* Bigger than the old side-by-side version: now that the title gets
	 * a full-width column it has to carry the weight the image and grid
	 * used to share. */
	font-size: clamp(1.75rem, 3.2vw, 2.5rem);
	letter-spacing: 0.01em;
	line-height: 1.15;
	margin: 0 0 1rem;
	color: var(--fg-color);
	transition: color 150ms ease;
}

.home-featured-link:hover .home-featured-title,
.home-featured-link:focus-visible .home-featured-title {
	color: var(--accent-color);
}

.home-featured-desc {
	font-size: 1.05rem;
	line-height: 1.65;
	color: var(--fg-muted-5);
	margin: 0 0 1.25rem;
}

.home-featured-cue {
	font-family: monospace;
	font-size: 0.85rem;
	letter-spacing: 0.04em;
	color: var(--accent-color);
	margin: 0;
}

/* --- Secondary index (next four posts) ---
 * Quiet table-of-contents row. Title left, date right; hairline rules
 * between items; the whole row is the click target. Monospaced dates
 * keep the right edge aligned without us having to set tabular-nums.
 */

.home-index {
	list-style: none;
	padding: 0;
	margin: 0;
	counter-reset: home-index;
}

.home-index-item {
	border-top: 1px solid var(--fg-muted-1);
	counter-increment: home-index;
}

.home-index-item:last-child {
	border-bottom: 1px solid var(--fg-muted-1);
}

.home-index-link {
	display: grid;
	grid-template-columns: auto 1fr auto;
	column-gap: 1.5rem;
	align-items: baseline;
	padding: 1rem 0.5rem;
	text-decoration: none;
	color: var(--fg-color);
	transition: color 120ms ease, background-color 120ms ease;
}

.home-index-link::before {
	content: "0" counter(home-index);
	font-family: monospace;
	font-size: 0.78rem;
	letter-spacing: 0.08em;
	color: var(--fg-muted-3);
}

.home-index-link:hover,
.home-index-link:focus-visible {
	background-color: var(--fg-muted-1);
	color: var(--accent-color);
	text-decoration: none;
}

.home-index-link:hover::before,
.home-index-link:focus-visible::before {
	color: var(--accent-color);
}

.home-index-title {
	font-size: 1rem;
	line-height: 1.4;
	min-width: 0;
}

.home-index-date {
	font-family: monospace;
	font-size: 0.78rem;
	color: var(--fg-muted-5);
	white-space: nowrap;
	letter-spacing: 0.04em;
}

.home-index-more {
	font-family: monospace;
	font-size: 0.9rem;
	letter-spacing: 0.04em;
	margin: 2rem 0 0;
}

.home-index-more a {
	color: var(--accent-color);
	text-decoration: none;
}

.home-index-more a:hover,
.home-index-more a:focus-visible {
	text-decoration: underline;
}

@media (max-width: 36rem) {
	.home-index-link {
		grid-template-columns: auto 1fr;
		row-gap: 0.25rem;
	}
	.home-index-date {
		grid-column: 2;
	}
}

/* --- Elsewhere line --- */

.home-elsewhere {
	text-align: center;
	font-family: monospace;
	font-size: 0.9rem;
	letter-spacing: 0.04em;
	color: var(--fg-muted-5);
	margin: 2rem 0;
}

.home-elsewhere strong {
	letter-spacing: 0.12em;
	text-transform: uppercase;
	font-size: 0.78rem;
	margin-right: 0.5rem;
	font-weight: 500;
}

.home-elsewhere a {
	color: var(--fg-muted-5);
	text-decoration: none;
	border-bottom: 1px solid var(--fg-muted-2);
	transition: color 150ms ease, border-color 150ms ease;
}

.home-elsewhere a:hover,
.home-elsewhere a:focus-visible {
	color: var(--accent-color);
	border-bottom-color: var(--accent-color);
}

/* ============================================================
 * /blog/ — archive page
 *
 * Composed from the same parts as the landing's "Writing" section:
 *
 *   blog-header     — page title + intro stanza (mirrors landing hero)
 *   .home-featured  — lead story of the current paginator page (reused
 *                     verbatim from the landing — same image, eyebrow,
 *                     title, description, "Read →" cue)
 *   blog-index      — thumbnail rows for the rest of the page (NEW —
 *                     deliberately heavier than the landing's text-only
 *                     index because /blog/ is the actual archive and
 *                     earns visible images per row)
 *   blog-paginator  — monospaced row matching the landing's language
 *
 * The landing keeps its quieter text-only index. /blog/ being a bit
 * louder per row is the point: a reader on the landing is being
 * introduced; a reader on /blog/ is browsing.
 * ============================================================ */

/* --- Header: page title + intro stanza ---
 * Title sits as a centred identity mark (same gesture as the landing's
 * .home-title, scaled down a step — this is a section front, not the
 * site front). The intro paragraph sits below, left-aligned, in the
 * same .home-stanza-shaped voice so the two pages rhyme typographically.
 */

.blog-header {
	margin: 1rem 0 2.5rem;
}

.blog-title {
	font-family: monospace;
	font-size: clamp(2rem, 5vw, 3rem);
	letter-spacing: 0.04em;
	margin: 0 0 1.5rem;
	font-weight: 600;
	line-height: 1;
	text-align: center;
}

.blog-intro {
	font-size: 1.05rem;
	line-height: 1.75;
	color: var(--fg-color);
}

.blog-intro p {
	margin: 0;
}

/* --- Thumbnail index ---
 * Grid per row: number · thumbnail · body (title + optional desc) · date.
 * The thumbnail is the editorial gesture that the landing's index
 * deliberately omits. It's small (120×80, 3:2) so the lead card above
 * still unambiguously reads as the lead.
 *
 * Hairline rules between rows (same as the landing's index) keep the
 * archive reading as one continuous list, not a stack of disconnected
 * cards. Whole row is the click target.
 */

.blog-index {
	list-style: none;
	padding: 0;
	margin: 2.5rem 0 0;
	counter-reset: blog-index;
}

.blog-index-item {
	border-top: 1px solid var(--fg-muted-1);
}

.blog-index-item:last-child {
	border-bottom: 1px solid var(--fg-muted-1);
}

.blog-index-link {
	display: grid;
	grid-template-columns: auto 7.5rem 1fr auto;
	column-gap: 1.25rem;
	align-items: center;
	padding: 1rem 0.5rem;
	text-decoration: none;
	color: var(--fg-color);
	transition: color 120ms ease, background-color 120ms ease;
}

.blog-index-link:hover,
.blog-index-link:focus-visible {
	background-color: var(--fg-muted-1);
	text-decoration: none;
}

.blog-index-number {
	font-family: monospace;
	font-size: 0.78rem;
	letter-spacing: 0.08em;
	color: var(--fg-muted-3);
	align-self: center;
	transition: color 120ms ease;
}

.blog-index-link:hover .blog-index-number,
.blog-index-link:focus-visible .blog-index-number {
	color: var(--accent-color);
}

.blog-index-thumb {
	width: 7.5rem;
	aspect-ratio: 3 / 2;
	overflow: hidden;
	border-radius: 0.35rem;
	border: 1px solid var(--fg-muted-2);
	background: var(--fg-muted-1);
}

/* Same reset as .home-featured-media img — see comment there. The
 * theme's global <img> rules (margin, shadow, border-radius, zoom-in
 * cursor on hover) would otherwise push the thumbnail down 1rem inside
 * its container and add visual chrome we don't want. */
.blog-index-thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	margin: 0;
	box-shadow: none;
	border-radius: 0;
	background: none;
	cursor: pointer;
	transition: transform 300ms ease;
}

.blog-index-link:hover .blog-index-thumb img,
.blog-index-link:focus-visible .blog-index-thumb img {
	transform: scale(1.04);
	box-shadow: none;
	border-radius: 0;
	position: static;
}

.blog-index-body {
	min-width: 0;
}

.blog-index-title {
	font-family: monospace;
	font-size: 1.05rem;
	letter-spacing: 0.01em;
	line-height: 1.3;
	margin: 0;
	font-weight: 500;
	color: var(--fg-color);
	transition: color 150ms ease;
}

.blog-index-link:hover .blog-index-title,
.blog-index-link:focus-visible .blog-index-title {
	color: var(--accent-color);
}

.blog-index-desc {
	font-size: 0.9rem;
	line-height: 1.5;
	color: var(--fg-muted-5);
	margin: 0.3rem 0 0;
	/* Two-line clamp keeps row heights even across posts with very
	 * different description lengths. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.blog-index-date {
	font-family: monospace;
	font-size: 0.78rem;
	color: var(--fg-muted-5);
	white-space: nowrap;
	letter-spacing: 0.04em;
	align-self: center;
}

/* Narrow screens: drop the date to a second row, fold the thumbnail to
 * a smaller square so number + thumb + title still fit on one line. The
 * description hides — at this width it would push titles too far down
 * and break the scannability of the list. */
@media (max-width: 36rem) {
	.blog-index-link {
		grid-template-columns: auto 4.5rem 1fr;
		grid-template-rows: auto auto;
		column-gap: 0.85rem;
		row-gap: 0.35rem;
	}
	.blog-index-thumb {
		width: 4.5rem;
		aspect-ratio: 1 / 1;
	}
	.blog-index-desc {
		display: none;
	}
	.blog-index-date {
		grid-column: 3;
		grid-row: 2;
		justify-self: start;
	}
}

/* Paginator styling is owned by the theme (#paginator in _general.scss).
 * We use its markup verbatim. The only thing we contribute is breathing
 * room above it, since our index above is denser than what the theme
 * was originally designed against. */
#paginator {
	margin-block-start: 3rem;
}
