/* ==========================================================================
   Sovereign Terminal v5 — light paper finance newsroom
   --------------------------------------------------------------------------
   A high-contrast LIGHT-ONLY theme: a cool white paper ground, near-black
   indigo ink, and one electric blue-violet accent that carries every CTA and
   feature panel. Condensed heavy uppercase display type and letterspaced
   micro-caps for kickers and bylines.

   The token NAMES are inherited from the previous dark build and are kept
   deliberately — every one of the ~3800 rules below refers to them, so
   renaming would touch the whole file for no visual gain. Their MEANING is
   inverted:

     --navy-*  is no longer a descending navy ramp but an ASCENDING surface
               ramp. --navy-800 is the page (pure white); each step away from
               it is a progressively more tinted panel. So the -900 / -850
               "deep" steps are now the most saturated wells, and code that
               reached for a deeper navy to sink a panel still sinks it.
     --ink-*   runs dark-to-light exactly as before: -100 is the strongest
               headline ink, -500 the quietest meta. Every `color: var(--ink-…)`
               therefore keeps its intended hierarchy with no edits.

   Only the two ends needed real care. --ink-100 was #FFFFFF (a headline on
   navy) and is now near-black; --line-* were white-alpha hairlines and are now
   ink-alpha. Both are commented in place below.

   Sections in order:
     1  Tokens
     2  Reset / base
     3  Typography primitives
     4  Buttons, chips, badges
     5  Header / navigation
     6  Cards (the shared article-card vocabulary)
     7  Front page sections
     8  Newsletter band
     9  Footer
    10  Archive / category
    11  Single post
    12  Static page
    13  404
    14  Utilities, motion, print
   ========================================================================== */

/* ── 1. Tokens ───────────────────────────────────────────────────────────── */
:root {
	/* Ground — an ASCENDING surface ramp (see the header note). -800 is the
	   page itself; the steps either side are tinted panels. The tint is a cool
	   indigo-grey rather than neutral grey, so every surface stays related to
	   the violet accent and the page never looks like unstyled white.

	   -800 → the page. Pure white, so photographs and the violet read at full
	          strength against it.
	   -850 → raised bands (.is-raised), the step that separates a section.
	   -900 → the most tinted well (.is-deep, code blocks, form fields).
	   -750 → inset media placeholders, sitting just off the page.
	   -700 / -600 → progressively firmer fills for chips and avatars. */
	--navy-800: #FFFFFF;
	--navy-850: #F4F5FB;
	--navy-900: #EBEDF7;
	--navy-750: #E4E7F4;
	--navy-700: #D8DCEF;
	--navy-600: #C6CBE6;

	/* The single accent. Everything that must be pressed, or must read as a
	   feature panel, is this violet. Deepened from the dark build's #4A47F5:
	   on white that original hit only ~4.9:1 and looked hazy, where this
	   passes AA for body text and still reads as electric rather than navy.
	   -300 is no longer a light tint for dark grounds but a DEEPER shade, so
	   every `color: var(--violet-300)` hover state stays legible on paper. */
	--violet-500: #2B7FFF;
	--violet-400: #4A93FF;
	--violet-600: #1C63D6;
	--violet-300: #1C63D6;

	/* Semantic aliases. New components reference these rather than the legacy
	   --violet-* names, which are kept only so existing rules keep working. */
	--brand: #2B7FFF;
	--brand-dark: #1C63D6;
	--brand-light: #EAF2FF;

	/* The page sits on a soft grey; cards and panels are the white above it.
	   This is the figure/ground relationship the reference layout uses. */
	--page-bg: #F1F3F7;
	--card-bg: #FFFFFF;

	/* Ink on paper. Same dark-to-light hierarchy the dark build had, so the
	   existing rules keep their meaning — only the absolute values moved.
	   -100 is a near-black indigo rather than pure black: pure #000 on white
	   vibrates at display weight, and the blue cast ties the type to the
	   accent. Every step is AA or better on the -800/-850 grounds. */
	--ink-100: #0A0722;
	--ink-200: #1E1A3C;
	--ink-300: #3D3866;
	--ink-400: #5A5480;
	/* The quietest step, used for timestamps, counts and footer legal links.
	   Darkened from #736D96, which cleared AA on the white page (4.82) but fell
	   to 4.13 on the --navy-900 footer ground where much of this text actually
	   sits. This value clears 4.5 on every surface in the ramp. */
	--ink-500: #6A6490;

	/* Hairlines. Inverted from white-alpha to INK-alpha, keeping the same two
	   weights: a whisper for card divisions, a firmer one for section rules
	   that need to hold a heading. Alphas are higher than the dark build's
	   0.09/0.17 because a dark line on white at 9% is invisible, where a white
	   line on navy at 9% still glows. */
	--line-soft: rgba(10, 7, 34, 0.13);
	--line-firm: rgba(10, 7, 34, 0.26);

	/* Category accents. Re-tuned from the dark build: each swatch is darkened
	   and saturated so it holds its identity as a fill behind WHITE text on a
	   white page. The originals were chosen to glow against navy — amber, sky
	   and rose in particular washed out completely on paper. */
	--amber: #A05F00;
	--red: #C2261A;
	--green: #1F7346;
	--sky: #2E63BE;
	--rose: #C43A61;
	--teal: #0F7F76;

	/* Type. Archivo carries display at 800 with tight tracking; Inter takes
	   body copy where Archivo's apertures would cost readability. */
	--font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
	--font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

	/* Fluid display scale. Every headline size is a clamp so the layout never
	   needs a breakpoint purely to resize type. */
	--fs-display: clamp(2.6rem, 6.4vw, 5.4rem);
	--fs-h1: clamp(2rem, 4.4vw, 3.4rem);
	--fs-h2: clamp(1.6rem, 3vw, 2.5rem);
	--fs-h3: clamp(1.15rem, 1.8vw, 1.55rem);
	--fs-lead: clamp(1.02rem, 1.4vw, 1.2rem);
	--fs-body: 1rem;
	--fs-sm: 0.875rem;
	--fs-xs: 0.75rem;
	--fs-micro: 0.6875rem;

	/* Rhythm */
	--gap: clamp(1.1rem, 2.2vw, 1.75rem);
	--gap-lg: clamp(1.75rem, 3.5vw, 3rem);
	--pad-section: clamp(3rem, 6.5vw, 5.5rem);
	--container: 1320px;
	--container-narrow: 760px;
	--radius: 6px;
	--radius-lg: 14px;
	--radius-pill: 999px;

	--logo-h: 40px;

	--ease: cubic-bezier(0.22, 0.61, 0.36, 1);
	--dur: 0.32s;
}

/* ── 2. Reset / base ─────────────────────────────────────────────────────── */
*,
*::before,
*::after {
	box-sizing: border-box;
}

* {
	margin: 0;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
	/* Light-only, declared in CSS as well as the <meta> in header.php so native
	   UI — scrollbars, form controls, autofill, spellcheck underlines — follows
	   the theme even if the document is served from cache. */
	color-scheme: light;
	/* Fixed header height plus breathing room, so an in-page anchor never
	   lands with its heading tucked under the masthead. */
	scroll-padding-top: 120px;
}

body {
	background: var(--navy-800);
	color: var(--ink-200);
	font-family: var(--font-body);
	font-size: var(--fs-body);
	line-height: 1.65;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	overflow-x: hidden;
}

img,
picture,
svg,
video {
	display: block;
	max-width: 100%;
}

img {
	height: auto;
}

a {
	color: inherit;
	text-decoration: none;
}

button,
input,
select,
textarea {
	font: inherit;
	color: inherit;
}

button {
	background: none;
	border: 0;
	cursor: pointer;
}

ul,
ol {
	list-style: none;
	padding: 0;
}

:focus-visible {
	/* -500 rather than the dark build's -300: the focus ring must be the
	   loudest thing on a pale surface, and -300 is now a deeper shade used for
	   text rather than the bright tint it was on navy. */
	outline: 2px solid var(--violet-500);
	outline-offset: 3px;
	border-radius: 2px;
}

::selection {
	background: var(--violet-500);
	color: #fff;
}

.container {
	width: 100%;
	max-width: var(--container);
	margin-inline: auto;
	padding-inline: clamp(1rem, 3.5vw, 2.5rem);
}

.container--narrow {
	max-width: var(--container-narrow);
}

.section-pad {
	padding-block: var(--pad-section);
}

.section-pad--tight {
	padding-block: clamp(2rem, 4vw, 3.25rem);
}

/* Raised band: one step lighter than the page, used to separate a section
   without introducing a second hue. */
.is-raised {
	background: var(--navy-850);
}

.is-deep {
	background: var(--navy-900);
}

.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 999;
	background: var(--violet-500);
	color: #fff;
	padding: 0.75rem 1.25rem;
	font-weight: 600;
}

.skip-link:focus {
	left: 1rem;
	top: 1rem;
}

/* ── 3. Typography primitives ────────────────────────────────────────────── */

/* The reference's signature: heavy condensed uppercase, tracked tight, with
   a line-height under 1 so multi-line headlines lock into a block. */
.display,
.sec-head__title,
.pulse-head__title,
.error-page__title {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.015em;
	line-height: 0.96;
	color: var(--ink-100);
}

/* Kicker: the small letterspaced label above a headline. Reads as the desk
   or story angle — "RACE TO REDUCE", "GAME GUIDE" in the reference. */
.kicker {
	display: inline-block;
	font-family: var(--font-body);
	font-size: var(--fs-micro);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--ink-400);
	margin-bottom: 0.55rem;
}

.kicker--accent {
	color: var(--violet-300);
}

/* Byline: uppercase, tracked, quiet. Never competes with the headline. */
.byline {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-size: var(--fs-micro);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--ink-400);
	line-height: 1.4;
}

.byline__avatar {
	width: 26px;
	height: 26px;
	border-radius: 50%;
	object-fit: cover;
	flex-shrink: 0;
	background: var(--navy-700);
}

.byline--lg .byline__avatar {
	width: 44px;
	height: 44px;
}

.byline--plain .byline__avatar {
	display: none;
}

.byline__stack {
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
}

.byline__name {
	color: var(--ink-300);
}

.byline--lg .byline__name {
	font-size: var(--fs-xs);
	color: var(--ink-200);
}

.byline__role,
.byline__sep,
.byline time {
	font-weight: 500;
	letter-spacing: 0.1em;
	color: var(--ink-500);
	text-transform: none;
}

.byline__role {
	text-transform: uppercase;
	letter-spacing: 0.14em;
}

/* Meta row: reading time and date, hairline separated. */
.metarow {
	display: inline-flex;
	align-items: center;
	gap: 0.85rem;
	font-size: var(--fs-micro);
	font-weight: 500;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ink-500);
}

.metarow__item {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
}

.metarow svg {
	width: 12px;
	height: 12px;
	flex-shrink: 0;
	opacity: 0.75;
}

/* Section heading: the rule-and-title pattern that opens every band. */
.sec-head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--gap);
	flex-wrap: wrap;
	padding-bottom: 1.1rem;
	margin-bottom: var(--gap-lg);
	border-bottom: 1px solid var(--line-firm);
}

.sec-head__title {
	font-size: var(--fs-h2);
}

.sec-head__kicker {
	font-size: var(--fs-sm);
	color: var(--ink-400);
	max-width: 44ch;
}

/* Centred variant — the reference's "ON THE PULSE" band. */
.sec-head--center {
	flex-direction: column;
	align-items: center;
	text-align: center;
	border-bottom: 0;
	gap: 0.5rem;
	margin-bottom: var(--gap-lg);
}

.sec-head--center .sec-head__title {
	font-size: var(--fs-h1);
}

/* ── 4. Buttons, chips, badges ───────────────────────────────────────────── */
.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 0.7rem 1.4rem;
	border-radius: var(--radius-pill);
	font-size: var(--fs-xs);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	line-height: 1;
	white-space: nowrap;
	border: 1px solid transparent;
	transition: background var(--dur) var(--ease), color var(--dur) var(--ease),
		border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.btn:hover {
	transform: translateY(-1px);
}

.btn:active {
	transform: translateY(0);
}

.btn--primary {
	background: var(--violet-500);
	color: #fff;
}

.btn--primary:hover {
	background: var(--violet-400);
}

.btn--ghost {
	border-color: var(--line-firm);
	color: var(--ink-200);
}

.btn--ghost:hover {
	border-color: var(--violet-500);
	/* Was white-on-violet-tint. On paper the fill stays a pale violet wash and
	   the label goes to the accent, which is the higher-contrast pairing. */
	color: var(--violet-600);
	background: rgba(58, 50, 224, 0.09);
}

/* The inverse button: on the old dark ground this was white-on-navy. It is
   still the "solid, non-accent" CTA, so on paper it inverts to ink-on-white.
   Used inside violet bands where a violet button would disappear. */
.btn--light {
	background: var(--ink-100);
	color: #fff;
}

.btn--light:hover {
	background: var(--ink-200);
	color: #fff;
}

/* Inside a violet band the ghost button's ink border and label would vanish,
   so it reverts to the white-on-dark treatment there. .brief is excluded on
   purpose: its only button sits inside the white card, not on the band. */
.showcase .btn--ghost,
.statband .btn--ghost {
	border-color: rgba(255, 255, 255, 0.45);
	color: #fff;
}

.showcase .btn--ghost:hover,
.statband .btn--ghost:hover {
	border-color: #fff;
	background: rgba(255, 255, 255, 0.14);
	color: #fff;
}

/* A white solid button reads best inside those same bands.
   NOT .brief: its button lives inside the white card on the violet band, not
   on the band itself, so white-on-white would erase it. The card's button
   keeps the default ink/violet .btn--light treatment. */
.showcase .btn--light,
.statband .btn--light {
	background: #fff;
	color: var(--violet-600);
}

.showcase .btn--light:hover,
.statband .btn--light:hover {
	background: var(--ink-200);
	color: #fff;
}

/* The brief panel's submit sits on white inside the form card, so it stays the
   loudest thing there: solid accent, white label. The button carries
   .btn--primary already — this keeps the pairing explicit and survives the
   button class being swapped again. */
.brief__field .newsletter-form__btn {
	background: var(--violet-500);
	color: #fff;
}

.brief__field .newsletter-form__btn:hover {
	background: var(--violet-600);
	color: #fff;
}

.btn--sm {
	padding: 0.55rem 1.05rem;
	font-size: var(--fs-micro);
}

.btn--lg {
	padding: 0.95rem 1.9rem;
	font-size: var(--fs-sm);
}

.btn[disabled] {
	opacity: 0.55;
	cursor: not-allowed;
	transform: none;
}

/* The circular chevron affordance that trails "Read now" / "View all". */
.arrow-badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: currentColor;
	flex-shrink: 0;
	transition: transform var(--dur) var(--ease);
}

.arrow-badge svg {
	width: 11px;
	height: 11px;
	/* The glyph is knocked out of the filled circle by painting it the colour
	   of the surface behind the badge — now white rather than navy. */
	color: var(--navy-800);
}

.btn--ghost .arrow-badge svg,
a:hover > .arrow-badge svg {
	color: var(--navy-800);
}

/* On a violet or otherwise dark fill the badge itself is white (it uses
   currentColor), so the knocked-out glyph must go dark instead of white-on-
   white. Covers the showcase card, stat band and every filled CTA. */
.showcase__cue .arrow-badge svg,
.statband .arrow-badge svg,
.btn--primary .arrow-badge svg,
.deskcard .arrow-badge svg {
	color: var(--violet-600);
}

a:hover > .arrow-badge,
.btn:hover .arrow-badge {
	transform: translateX(2px);
}

.arrow-badge--violet {
	background: var(--violet-500);
}

.arrow-badge--violet svg {
	color: #fff;
}

.arrow-badge--lg {
	width: 30px;
	height: 30px;
}

.arrow-badge--lg svg {
	width: 15px;
	height: 15px;
}

/* Category chip. Colour arrives on inline custom properties from
   st_term_color(), because the palette is assigned per install. */
.chip {
	display: inline-flex;
	align-items: center;
	padding: 0.3rem 0.65rem;
	border-radius: var(--radius);
	background: var(--chip-bg, var(--violet-500));
	color: var(--chip-fg, #fff);
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.11em;
	line-height: 1.2;
	transition: opacity var(--dur) var(--ease);
}

.chip:hover {
	opacity: 0.85;
}

.card__chips {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
}

/* Eyebrow with a pulsing dot — used on archive and 404 heroes. */
.eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: var(--violet-300);
}

.badge-dot {
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--violet-500);
	box-shadow: 0 0 0 0 rgba(58, 50, 224, 0.6);
	animation: st-pulse 2.4s infinite;
}

/* The ring fades to fully transparent, so the colour it fades FROM only has to
   match whatever set the dot's own shadow — the footer status dot overrides
   both. Left as a transparent-violet ramp for that reason. */
@keyframes st-pulse {
	70% {
		box-shadow: 0 0 0 8px rgba(58, 50, 224, 0);
	}
	100% {
		box-shadow: 0 0 0 0 rgba(58, 50, 224, 0);
	}
}

/* ── 5. Header / navigation ──────────────────────────────────────────────── */
.site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--navy-800);
	border-bottom: 1px solid var(--line-soft);
	transition: box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
}

.site-header--scrolled {
	/* Translucent white rather than translucent navy, and a far lighter
	   shadow: on paper the 0.42 black shadow of the dark build read as a
	   smudge. The hairline border does most of the separating work now. */
	background: rgba(255, 255, 255, 0.88);
	backdrop-filter: blur(14px);
	border-bottom-color: var(--line-firm);
	box-shadow: 0 6px 24px rgba(10, 7, 34, 0.09);
}

.masthead {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap);
	min-height: 74px;
}

/* Brand. The customizer logo is inherited untouched — only its height is
   ours, driven by --logo-h from st_customizer_css(). */
.masthead__brand .custom-logo-link,
.masthead__brand .custom-logo {
	display: block;
}

.masthead__brand img {
	max-height: var(--logo-h);
	width: auto;
	object-fit: contain;
}

.site-logo {
	font-family: var(--font-display);
	font-weight: 800;
	font-size: 1.35rem;
	text-transform: uppercase;
	letter-spacing: -0.02em;
	color: var(--ink-100);
}

/* Desktop nav sits inline in the masthead, as in the reference: wordmark
   left, the desk list immediately beside it, utilities right. */
.nav-primary {
	flex: 1;
	min-width: 0;
}

.nav-list {
	display: flex;
	align-items: center;
	gap: clamp(0.9rem, 1.8vw, 1.9rem);
	flex-wrap: wrap;
}

.nav-list a {
	display: inline-block;
	font-size: var(--fs-micro);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.13em;
	color: var(--ink-300);
	padding-block: 0.35rem;
	position: relative;
	transition: color var(--dur) var(--ease);
}

.nav-list a::after {
	content: "";
	position: absolute;
	left: 0;
	bottom: 0;
	width: 100%;
	height: 2px;
	background: var(--violet-400);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform var(--dur) var(--ease);
}

.nav-list a:hover,
.nav-list .current-menu-item > a,
.nav-list .current-cat > a {
	color: var(--ink-100);
}

.nav-list a:hover::after,
.nav-list .current-menu-item > a::after,
.nav-list .current-cat > a::after {
	transform: scaleX(1);
}

.masthead__util {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	flex-shrink: 0;
}

/* Mobile menu toggle — hidden until the desk row can no longer fit. */
.menu-pill {
	display: none;
	align-items: center;
	gap: 0.5rem;
	padding: 0.5rem 0.95rem;
	border: 1px solid var(--line-firm);
	border-radius: var(--radius-pill);
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--ink-200);
}

.menu-pill__bars {
	display: flex;
	flex-direction: column;
	gap: 3px;
	width: 14px;
}

.menu-pill__bars span {
	display: block;
	height: 1.5px;
	background: currentColor;
	/* Quick, so the bars-to-X morph keeps pace with the drawer, which opens
	   instantly. At the full --dur the icon visibly trailed the panel. */
	transition: transform 0.12s var(--ease), opacity 0.12s var(--ease);
}

.menu-pill[aria-expanded="true"] .menu-pill__bars span:nth-child(1) {
	transform: translateY(4.5px) rotate(45deg);
}

.menu-pill[aria-expanded="true"] .menu-pill__bars span:nth-child(2) {
	opacity: 0;
}

.menu-pill[aria-expanded="true"] .menu-pill__bars span:nth-child(3) {
	transform: translateY(-4.5px) rotate(-45deg);
}

/* Drawer-only subscribe link. Hidden by default; the 1080px block below
   turns it on, where the masthead pill is hidden. */
.nav-subscribe {
	display: none;
}

@media (max-width: 1080px) {
	.menu-pill {
		display: inline-flex;
	}

	/* Hidden below the desktop breakpoint, so the masthead carries only the
	   wordmark and the MENU toggle. The newsletter is still reachable — the
	   drawer sits over the page and the footer band is a scroll away — and the
	   pill was competing with the toggle for the same corner. */
	.masthead__util .btn {
		display: none;
	}

	/* Below this width the desk row becomes a drawer. */
	.nav-primary {
		position: absolute;
		left: 0;
		right: 0;
		top: 100%;
		background: var(--navy-850);
		border-bottom: 1px solid var(--line-soft);
		flex: none;
	}

	/* Opens instantly. This was previously a grid-template-rows 0fr→1fr
	   transition, which made the whole list unfurl over ~0.3s and read as lag
	   on a tap. Navigation should respond immediately, so the drawer is simply
	   shown or hidden with no animation. */
	.nav-menu {
		display: none;
	}

	.nav-menu.is-open {
		display: block;
		width: 100%;
		padding-block: 0.5rem 1rem;
		text-align: center;
	}

	/* The desktop rule makes this a right-aligned flex row; in the drawer it is
	   a full-width block. */
	.nav-primary {
		display: block;
		flex: 0 0 auto;
		width: 100%;
	}

	/* The desktop rule right-aligns the row; in the drawer each item is a full
	   width band, so the text is centred instead. */
	.nav-list {
		flex-direction: column;
		align-items: stretch;
		justify-content: flex-start;
		gap: 0;
		padding-inline: clamp(1rem, 3.5vw, 2.5rem);
	}

	.nav-list li {
		border-bottom: 1px solid var(--line-soft);
		width: 100%;
	}

	.nav-list li:last-child {
		border-bottom: 1px solid var(--line-soft);
	}

	.nav-list a {
		display: block;
		width: 100%;
		padding-block: 0.95rem;
		font-size: 0.95rem;
		letter-spacing: 0.06em;
		text-transform: uppercase;
		text-align: center;
	}

	.nav-list a::after {
		display: none;
	}

	.nav-subscribe {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 0.6rem;
		margin: 1.1rem clamp(1rem, 3.5vw, 2.5rem) 0.5rem;
		padding: 0.8rem 1.1rem;
		background: var(--violet-500);
		border-radius: var(--radius-pill);
		color: #fff;
		font-size: var(--fs-micro);
		font-weight: 700;
		text-transform: uppercase;
		letter-spacing: 0.12em;
	}

	.nav-subscribe .arrow-badge {
		background: #fff;
	}

	.nav-subscribe .arrow-badge svg {
		color: var(--violet-500);
	}
}

@media (max-width: 640px) {
	.masthead {
		min-height: 62px;
	}
}

/* Reading progress bar on single posts */
.read-progress {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	height: 3px;
	z-index: 200;
	background: transparent;
	pointer-events: none;
}

.read-progress__fill {
	height: 100%;
	width: 0;
	background: var(--violet-400);
}

/* ── 6. Cards ────────────────────────────────────────────────────────────── */

/* The shared vertical card: media over a body of kicker, headline, byline.
   Every grid on the site composes from this. */
.card {
	display: flex;
	flex-direction: column;
	gap: 0.85rem;
	min-width: 0;
}

.card__media {
	display: block;
	overflow: hidden;
	border-radius: var(--radius);
	background: var(--navy-750);
}

.card__media-clip {
	display: block;
	aspect-ratio: 4 / 3;
	overflow: hidden;
}

.card__img,
.hcard__img,
.spot__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s var(--ease);
}

.card:hover .card__img,
.hcard:hover .hcard__img,
.spot:hover .spot__img {
	transform: scale(1.045);
}

/* No-thumbnail fallback: a tinted well with a diagonal hatch, so a missing
   image reads as deliberate rather than as a hole. */
.card__media--empty {
	background:
		repeating-linear-gradient(
			135deg,
			/* Ink-alpha hatch: the dark build's 3.5% white was invisible here. */
			rgba(10, 7, 34, 0.055) 0 10px,
			transparent 10px 20px
		),
		var(--navy-750);
}

.card__body {
	display: flex;
	flex-direction: column;
	gap: 0.55rem;
	min-width: 0;
}

.card__title {
	font-size: var(--fs-h3);
	font-weight: 700;
	line-height: 1.22;
	letter-spacing: -0.01em;
	color: var(--ink-100);
}

.card__title a {
	background-image: linear-gradient(var(--violet-300), var(--violet-300));
	background-size: 0% 1px;
	background-position: 0 100%;
	background-repeat: no-repeat;
	transition: background-size var(--dur) var(--ease), color var(--dur) var(--ease);
}

.card__title a:hover {
	color: var(--violet-300);
	background-size: 100% 1px;
}

.card__excerpt {
	font-size: var(--fs-sm);
	color: var(--ink-400);
	display: -webkit-box;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.card__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	flex-wrap: wrap;
	margin-top: auto;
	padding-top: 0.15rem;
}

/* Compact card: the reference's "ON THE PULSE" row — a short landscape
   image, a kicker, a two-line headline, a byline. Nothing else. */
.card--compact .card__media-clip {
	aspect-ratio: 16 / 10;
}

.card--compact .card__title {
	font-size: 1.05rem;
	line-height: 1.28;
}

/* Horizontal card: thumbnail left, copy right. The reference's right-hand
   headline column and the Latest rail both use it. */
.hcard {
	display: grid;
	grid-template-columns: 1fr 96px;
	gap: 0.9rem;
	align-items: start;
	padding-bottom: 1.05rem;
	border-bottom: 1px solid var(--line-soft);
	min-width: 0;
}

.hcard:last-child {
	border-bottom: 0;
	padding-bottom: 0;
}

.hcard__media {
	display: block;
	overflow: hidden;
	border-radius: var(--radius);
	aspect-ratio: 1 / 1;
	background: var(--navy-750);
	order: 2;
}

.hcard__body {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	min-width: 0;
}

.hcard__title {
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.3;
	color: var(--ink-100);
}

.hcard__title a:hover {
	color: var(--violet-300);
}

/* Grids */
.grid-2,
.grid-3,
.grid-4 {
	display: grid;
	gap: var(--gap);
}

.grid-2 {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.grid-3 {
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

.grid-4 {
	grid-template-columns: repeat(4, minmax(0, 1fr));
}

@media (max-width: 1080px) {
	.grid-4 {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 860px) {
	.grid-3 {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 560px) {
	.grid-2,
	.grid-3,
	.grid-4 {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* ── 7. Front page sections ──────────────────────────────────────────────── */

/* 7.1 Hero — a cinematic stage with an overlapping "next up" rail.

   Replaces the newspaper split (big lead beside a stacked headline column).
   The composition is now vertical and layered: one full-bleed photograph with
   the headline set OVER it, and the follow-up stories in a single row of cards
   that overlap the image's bottom edge so the two tiers read as one object.

   The stage is the only full-bleed element on the page and the only place the
   light theme goes dark, which is what gives the top of the site its weight. */
.hero {
	position: relative;
	/* Bottom padding is carried by the rail's negative offset below, not here —
	   see .hero-rail. */
	padding-bottom: clamp(1.5rem, 3vw, 2.5rem);
}

/* ── The stage */
.stage {
	position: relative;
	display: flex;
	align-items: flex-end;
	isolation: isolate;
	/* Full-bleed comes free: .hero is already a full-width section (the
	   container lives INSIDE the stage, around the copy only). No 100vw trick —
	   100vw counts the scrollbar gutter, which shifted the stage ~7px left of
	   the viewport and bled it under the scrollbar. */
	width: 100%;
	/* A tall, wide frame. min() keeps it from eating a short laptop screen, and
	   the vh term stops a very wide monitor from making it letterbox-thin. */
	min-height: min(78vh, 720px);
	/* The bottom value must clear the rail's negative offset PLUS a gap, or the
	   cards land flush against the byline row. Rail pulls up by at most 5rem,
	   so this is that plus ~2.5rem of air. */
	padding-block: clamp(2.5rem, 6vw, 5rem) clamp(5.5rem, 9vw, 7.5rem);
	background: var(--ink-100);
	overflow: hidden;
}

.stage__media {
	position: absolute;
	inset: 0;
	z-index: -1;
}

.stage__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* A slow drift on load, so the stage has life without asking the reader to
	   wait for anything. Held off for reduced-motion users in section 14. */
	animation: st-stage-drift 18s var(--ease) forwards;
}

.stage__img--empty {
	display: block;
	background:
		repeating-linear-gradient(
			135deg,
			rgba(255, 255, 255, 0.05) 0 14px,
			transparent 14px 28px
		),
		var(--ink-200);
	animation: none;
}

@keyframes st-stage-drift {
	from {
		transform: scale(1.06);
	}
	to {
		transform: scale(1);
	}
}

/* Three-layer scrim. A single flat overlay either greys the photograph or
   leaves the type unreadable; these separate the jobs:
     1  a strong foot, where the copy sits
     2  a lateral wash from the left, so the headline's measure is covered
        without dimming the right of the frame
     3  a soft vignette, which keeps the eye in the middle of the image */
.stage__scrim {
	position: absolute;
	inset: 0;
	background:
		linear-gradient(to top, rgba(10, 7, 34, 0.94) 0%, rgba(10, 7, 34, 0.62) 34%, rgba(10, 7, 34, 0.12) 68%),
		linear-gradient(to right, rgba(10, 7, 34, 0.78), rgba(10, 7, 34, 0.1) 62%, transparent),
		radial-gradient(120% 100% at 50% 40%, transparent 42%, rgba(10, 7, 34, 0.45));
}

.stage__inner {
	position: relative;
	width: 100%;
}

.stage__copy {
	max-width: 46rem;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.9rem;
}

/* Eyebrow: a live dot, the slot label, then the desk. Small, tracked, and the
   first thing that tells you what you are looking at. */
.stage__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: #fff;
}

.stage__live {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--violet-400);
	box-shadow: 0 0 0 0 rgba(95, 92, 255, 0.75);
	animation: st-pulse 2.4s infinite;
}

.stage__sep {
	width: 14px;
	height: 1px;
	background: rgba(255, 255, 255, 0.45);
}

.stage__desk {
	color: #A5A1FF;
}

.stage__title {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.025em;
	line-height: 0.92;
	font-size: clamp(2.1rem, 5.6vw, 4.4rem);
	color: #fff;
	text-wrap: balance;
	/* Lifts the headline off a busy photograph without a plate behind it. */
	text-shadow: 0 2px 30px rgba(6, 2, 28, 0.6);
}

/* An animated underline that draws in on hover. Keyed to the LINK, not the
   stage: the headline is the hit area, so the affordance has to appear when the
   pointer is actually over something clickable. Underlining on stage-hover
   implied the whole panel was a link, which it deliberately is not. */
.stage__title a {
	background-image: linear-gradient(#fff, #fff);
	background-size: 0% 2px;
	background-position: 0 100%;
	background-repeat: no-repeat;
	transition: background-size 0.45s var(--ease);
}

.stage__title a:hover,
.stage__title a:focus-visible {
	background-size: 100% 2px;
}

.stage__excerpt {
	font-size: var(--fs-lead);
	color: rgba(255, 255, 255, 0.82);
	max-width: 54ch;
	text-shadow: 0 1px 14px rgba(6, 2, 28, 0.55);
}

.stage__foot {
	display: flex;
	align-items: center;
	gap: 1.25rem;
	flex-wrap: wrap;
	margin-top: 0.35rem;
}

/* The byline helper's $on_dark flag does not change its markup, so the dark
   treatment is applied here by descent instead. */
.stage .byline,
.stage .byline__name,
.stage .metarow,
.stage .byline time,
.stage .byline__sep {
	color: rgba(255, 255, 255, 0.82);
}

.stage .byline__avatar {
	box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.28);
}

/* ── The rail */

/* Pulled up onto the stage so the cards break its bottom edge. The stage's own
   bottom padding leaves room for this, so the overlap never covers the copy. */
.hero-rail {
	position: relative;
	z-index: 2;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: clamp(0.5rem, 1vw, 0.85rem);
	list-style: none;
	margin: clamp(-5rem, -6vw, -3rem) 0 0;
	padding: 0;
}

.railcard {
	min-width: 0;
}

/* Two rows: copy on top, then a foot holding the timestamp and the thumbnail
   side by side.

   The thumbnail was absolutely positioned in the bottom-right corner, which
   forced the body to reserve 3.5rem of right padding for the WHOLE card height
   to stop the clamped headline running under it. That cut the headline measure
   from ~300px to 266px and pushed titles to 3–4 wrapped lines, truncating more
   words. In flow it only takes space on the row it actually occupies. */
.railcard__link {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	height: 100%;
	padding: 1rem 1rem 0.9rem;
	background: #fff;
	border: 1px solid var(--line-soft);
	border-radius: var(--radius);
	overflow: hidden;
	box-shadow: 0 18px 40px rgba(10, 7, 34, 0.16);
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
		border-color var(--dur) var(--ease);
}

.railcard__link:hover {
	transform: translateY(-4px);
	border-color: var(--cat-bg, var(--violet-500));
	box-shadow: 0 24px 52px rgba(10, 7, 34, 0.22);
}

/* A tick in the desk colour along the card's top edge, drawn in on hover. It
   is what ties each card to its section without a coloured chip. */
.railcard__tick {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 3px;
	background: var(--cat-bg, var(--violet-500));
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 0.4s var(--ease);
}

.railcard__link:hover .railcard__tick {
	transform: scaleX(1);
}

/* Outline numeral, top-right, quiet. Reads as a position marker rather than
   as content to be read. */
.railcard__index {
	position: absolute;
	top: 0.75rem;
	right: 0.9rem;
	font-family: var(--font-display);
	font-weight: 800;
	font-size: 1.15rem;
	line-height: 1;
	color: transparent;
	-webkit-text-stroke: 1px var(--line-firm);
	font-variant-numeric: tabular-nums;
	transition: color var(--dur) var(--ease),
		-webkit-text-stroke-color var(--dur) var(--ease);
}

.railcard__link:hover .railcard__index {
	color: var(--cat-bg, var(--violet-500));
	-webkit-text-stroke-color: transparent;
}

.railcard__body {
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
	min-width: 0;
	/* Only the index in the top-right corner needs clearing now — the thumbnail
	   lives in the foot row and no longer overlaps the headline. */
	padding-right: 1.75rem;
}

/* The foot row: timestamp left, thumbnail right, pushed to the card's bottom so
   every card in the row aligns on the same baseline whatever its headline. */
.railcard__foot {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 0.75rem;
	margin-top: auto;
	padding-top: 0.5rem;
}

.railcard__desk {
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--cat-bg, var(--violet-500));
}

.railcard__title {
	font-size: 0.95rem;
	font-weight: 600;
	line-height: 1.3;
	color: var(--ink-100);
	/* Two lines: an unusually long headline must not stretch one card and knock
	   the row out of alignment. */
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	overflow: hidden;
}

.railcard__time {
	font-size: var(--fs-micro);
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--ink-500);
	white-space: nowrap;
}

/* The story's art as a real thumbnail, pinned bottom-right.

   This was a 4px-tall full-width strip — the idea was "a hint of the photo
   without a row of thumbnails", but 4px of a photograph carries no image
   information at all: it rendered as a smear that read like a broken progress
   bar. A small square actually identifies the story, which is the only reason
   to show art here. */
.railcard__thumb {
	flex-shrink: 0;
	width: 44px;
	height: 44px;
	border-radius: var(--radius);
	overflow: hidden;
	background: var(--navy-750);
}

.railcard__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s var(--ease);
}

.railcard__link:hover .railcard__thumb img {
	transform: scale(1.08);
}

/* ── Responsive */

/* Below the desktop width four cards cannot hold a two-line headline, so the
   rail goes to two columns and stops overlapping as far. */
@media (max-width: 1080px) {
	.hero-rail {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 0.75rem;
		margin-top: clamp(-3.5rem, -4vw, -2rem);
	}

	/* Two rows of cards overlap further up than one, so the stage needs more
	   bottom clearance here than at full width, not less. */
	.stage {
		padding-block: clamp(2.5rem, 6vw, 5rem) clamp(4.5rem, 8vw, 6rem);
	}
}

@media (max-width: 860px) {
	.stage {
		min-height: min(72vh, 600px);
	}

	.stage__copy {
		max-width: none;
	}
}

@media (max-width: 620px) {
	/* The stage keeps a real minimum height rather than a vh share: on a short
	   phone in landscape a vh-only frame collapses to a letterbox. */
	.stage {
		min-height: 460px;
		/* Bottom clears the rail's smaller 1.5rem lift plus air, matching the
		   desktop rule's logic at this scale. */
		padding-block: 2rem clamp(2.75rem, 9vw, 3.5rem);
		align-items: flex-end;
	}

	/* The lateral wash is dropped — at this width the copy spans the full frame,
	   so a left-weighted gradient just darkens one edge unevenly. */
	.stage__scrim {
		background:
			linear-gradient(to top, rgba(10, 7, 34, 0.95) 0%, rgba(10, 7, 34, 0.7) 42%, rgba(10, 7, 34, 0.2) 78%),
			radial-gradient(120% 100% at 50% 40%, transparent 40%, rgba(10, 7, 34, 0.4));
	}

	.stage__excerpt {
		/* Two lines on a phone: the headline and the byline are what matter at
		   this size, and a four-line summary pushes both off the first screen. */
		display: -webkit-box;
		-webkit-line-clamp: 2;
		line-clamp: 2;
		-webkit-box-orient: vertical;
		overflow: hidden;
	}

	.stage__foot {
		gap: 0.85rem;
	}

	/* The byline (~146px) and the full meta row (~211px) overrun a 343px
	   column by a hair and wrap to two lines, costing 40px of stage height for
	   nothing. Dropping the DATE — the second .metarow__item — keeps reading
	   time, which is the more useful of the two here, and fits one line.
	   The date is still on the article itself. */
	.stage .metarow__item:nth-child(2) {
		display: none;
	}

	/* One column, and the overlap shrinks to a small lift: a full-width card
	   pulled far up would cover the headline it sits under. */
	.hero-rail {
		grid-template-columns: minmax(0, 1fr);
		gap: 0.6rem;
		margin-top: -1.5rem;
	}

	/* Horizontal rows on a phone — a stack of four vertical cards is a lot of
	   scrolling before the rest of the page. */
	.railcard__link {
		flex-direction: row;
		align-items: center;
		gap: 0.85rem;
		padding: 0.85rem 0.9rem;
	}

	.railcard__index {
		position: static;
		flex-shrink: 0;
		font-size: 1rem;
		/* Filled rather than outlined at this size: a 1px stroke on a 16px
		   numeral reads as a smudge on a phone screen. */
		color: var(--cat-bg, var(--violet-500));
		-webkit-text-stroke: 0;
	}

	.railcard__body {
		padding-right: 0;
	}

	.railcard__title {
		-webkit-line-clamp: 2;
		line-clamp: 2;
	}

	/* An explicit 3-column grid rather than a flex row. Flex needed
	   `display:contents` + wrapping + order juggling to put the timestamp under
	   the headline while keeping the thumb on its right, and that combination
	   broke each part onto its own line. The grid just names the geometry:

	     index | copy      | thumb
	     index | timestamp | thumb   */
	.railcard__link {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr) 46px;
		grid-template-rows: auto auto;
		align-items: start;
		column-gap: 0.8rem;
		row-gap: 0.2rem;
	}

	.railcard__index {
		grid-column: 1;
		grid-row: 1 / span 2;
		align-self: center;
	}

	.railcard__body {
		grid-column: 2;
		grid-row: 1;
		padding-right: 0;
	}

	/* Contents are placed directly, so the wrapper must not form a row of its
	   own — its two children take the grid cells instead. */
	.railcard__foot {
		display: contents;
	}

	.railcard__time {
		grid-column: 2;
		grid-row: 2;
	}

	.railcard__thumb {
		grid-column: 3;
		grid-row: 1 / span 2;
		align-self: center;
		width: 46px;
		height: 46px;
	}
}

/* 7.2 Ticker strip — a marquee of desk names under the hero. Editorial
   furniture that advertises breadth at a glance. */
.tickerbar {
	border-block: 1px solid var(--line-soft);
	background: var(--navy-850);
	overflow: hidden;
	padding-block: 0.7rem;
	display: flex;
	align-items: center;
	gap: 1rem;
}

.tickerbar__label {
	flex-shrink: 0;
	margin-left: clamp(1rem, 3.5vw, 2.5rem);
	padding: 0.28rem 0.7rem;
	border-radius: var(--radius);
	background: var(--violet-500);
	color: #fff;
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.14em;
}

.tickerbar__viewport {
	flex: 1;
	overflow: hidden;
	mask-image: linear-gradient(90deg, transparent, #000 3%, #000 92%, transparent);
}

.tickerbar__track {
	display: flex;
	align-items: center;
	gap: 2.5rem;
	width: max-content;
	animation: st-marquee 46s linear infinite;
}

.tickerbar:hover .tickerbar__track,
.tickerbar:focus-within .tickerbar__track {
	animation-play-state: paused;
}

.tickerbar__item {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	font-size: var(--fs-micro);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--ink-400);
	white-space: nowrap;
	transition: color var(--dur) var(--ease);
}

.tickerbar__item:hover {
	color: var(--ink-100);
}

.tickerbar__dot {
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background: var(--cat-bg, var(--violet-400));
	flex-shrink: 0;
}

/* Translating by -25% moves the track by exactly one copy of the list, which
   the template prints four times — so the wrap lands on a point visually
   identical to the start and the loop is seamless.
   The fraction and the copy count in front-page.php must stay in step: at two
   copies and -50% the travel was narrower than the viewport on a 1440 screen
   and a gap opened at the right edge before the wrap. */
@keyframes st-marquee {
	to {
		transform: translateX(-25%);
	}
}

/* 7.25 On the Pulse — a briefing block: one lead story with large art, and a
   numbered rail of follow-ups beside it.

   Replaces the old three-equal-cards grid under a centred heading. Two things
   make it read differently: the heading is left-aligned against a rule with a
   pulsing tick (so the section opens like a wire feed rather than a titled
   card row), and the content is deliberately ASYMMETRIC — a 1.35fr lead beside
   a 1fr rail, where the rail items are numbered rows rather than cards. */
.pulse-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--gap);
	flex-wrap: wrap;
	padding-bottom: 1rem;
	margin-bottom: var(--gap-lg);
	border-bottom: 2px solid var(--ink-100);
}

.pulse-head__id {
	display: inline-flex;
	align-items: center;
	gap: 0.7rem;
	min-width: 0;
}

/* The live tick. Reuses the badge-dot pulse keyframes so the section reads as
   a running feed without a second animation. */
.pulse-head__tick {
	width: 9px;
	height: 9px;
	flex-shrink: 0;
	border-radius: 50%;
	background: var(--violet-500);
	box-shadow: 0 0 0 0 rgba(58, 50, 224, 0.6);
	animation: st-pulse 2.4s infinite;
}

.pulse-head__title {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.02em;
	line-height: 0.95;
	font-size: var(--fs-h2);
	color: var(--ink-100);
}

.pulse-head__kicker {
	font-size: var(--fs-sm);
	color: var(--ink-400);
	max-width: 42ch;
}

.pulse {
	display: grid;
	grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
	gap: clamp(1.5rem, 3.2vw, 2.75rem);
	/* stretch, not start: the rail is a flex column that distributes its rows
	   over the full track height, so it finishes level with the lead instead of
	   stopping short and leaving a hole in the right-hand column. */
	align-items: stretch;
}

/* ── Lead story */
.pulse-lead {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	min-width: 0;
}

.pulse-lead__media {
	position: relative;
	display: block;
	overflow: hidden;
	border-radius: var(--radius);
	background: var(--navy-750);
}

.pulse-lead__clip {
	display: block;
	aspect-ratio: 16 / 10;
	overflow: hidden;
}

.pulse-lead__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.7s var(--ease);
}

.pulse-lead:hover .pulse-lead__img {
	transform: scale(1.035);
}

/* Corner flag rather than an inline kicker, so the lead's desk reads at a
   glance and the copy below opens straight on the headline. */
.pulse-lead__flag {
	position: absolute;
	top: 0;
	left: 0;
	padding: 0.4rem 0.85rem;
	background: var(--violet-500);
	color: #fff;
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	border-bottom-right-radius: var(--radius);
}

.pulse-lead__body {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.6rem;
	min-width: 0;
}

.pulse-lead__title {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.015em;
	line-height: 1.02;
	font-size: clamp(1.4rem, 2.5vw, 2.1rem);
	color: var(--ink-100);
	text-wrap: balance;
}

.pulse-lead__title a:hover {
	color: var(--violet-500);
}

.pulse-lead__excerpt {
	font-size: var(--fs-sm);
	color: var(--ink-400);
	max-width: 54ch;
}

/* ── Numbered rail */
.pulse-rail {
	display: flex;
	flex-direction: column;
	/* Rows share out any height left over once their content is laid out, so
	   the rail always reaches the foot of the lead column. With a fixed
	   padding the rail's height depended entirely on how long the headlines
	   happened to be, which is what left the gap. */
	justify-content: space-between;
	list-style: none;
	margin: 0;
	padding: 0;
	min-width: 0;
}

.pulse-item {
	display: grid;
	grid-template-columns: 2.25rem minmax(0, 1fr) 68px;
	gap: 0.9rem;
	align-items: start;
	/* Vertical padding is a floor; justify-content above adds the slack. */
	padding-block: 0.95rem;
	border-bottom: 1px solid var(--line-soft);
}

.pulse-item:first-child {
	padding-top: 0;
}

.pulse-item:last-child {
	border-bottom: 0;
	padding-bottom: 0;
}

/* Outline numerals: the rank labels the row without competing with the
   headline. Fills in on hover, which is the row's only affordance. */
.pulse-item__num {
	font-family: var(--font-display);
	font-weight: 800;
	font-size: 1.3rem;
	line-height: 1.1;
	color: transparent;
	-webkit-text-stroke: 1px var(--ink-400);
	font-variant-numeric: tabular-nums;
	transition: color var(--dur) var(--ease),
		-webkit-text-stroke-color var(--dur) var(--ease);
}

.pulse-item:hover .pulse-item__num {
	color: var(--violet-500);
	-webkit-text-stroke-color: transparent;
}

.pulse-item__body {
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
	min-width: 0;
}

.pulse-item__desk {
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--violet-500);
}

.pulse-item__title {
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.3;
	color: var(--ink-100);
}

.pulse-item__title a:hover {
	color: var(--violet-500);
}

.pulse-item__time {
	font-size: var(--fs-micro);
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--ink-500);
}

.pulse-item__media {
	display: block;
	overflow: hidden;
	border-radius: var(--radius);
	aspect-ratio: 1 / 1;
	background: var(--navy-750);
}

.pulse-item__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s var(--ease);
}

.pulse-item:hover .pulse-item__media img {
	transform: scale(1.07);
}

/* Tablet: the rail drops under the lead and becomes a two-up row, which keeps
   the section from turning into one very tall column. */
@media (max-width: 900px) {
	.pulse {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--gap-lg);
	}

	.pulse-rail {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	/* As a grid the first-child padding reset no longer applies per column, so
	   every item in the top row needs it. */
	.pulse-item {
		padding-top: 0;
	}

	/* Two columns turns the item rule into a per-cell border, which reads badly
	   at the end of the list: with three items the rule under item 02 points
	   straight at the empty fourth cell.

	   So at this breakpoint the row rule is dropped entirely and the items are
	   separated by grid gap instead. Cheaper than trying to detect the last row
	   in CSS, and honest — a two-up grid does not need horizontal rules to be
	   readable the way a single vertical column does. */
	.pulse-item {
		border-bottom: 0;
		padding-bottom: 0;
	}

	.pulse-rail {
		gap: clamp(1.1rem, 2.4vw, 1.6rem) var(--gap);
	}
}

@media (max-width: 620px) {
	.pulse-rail {
		grid-template-columns: minmax(0, 1fr);
	}

	.pulse-item {
		/* The thumbnail shrinks and the number narrows; at this width three
		   full-size tracks left the headline in a ~120px gutter. */
		grid-template-columns: 1.75rem minmax(0, 1fr) 56px;
		gap: 0.7rem;
		padding-block: 0.95rem;
	}

	.pulse-item:first-child {
		padding-top: 0;
	}

	.pulse-item:last-child {
		border-bottom: 0;
		padding-bottom: 0;
	}

	.pulse-item__num {
		font-size: 1.05rem;
	}
}

/* 7.3 Showcase — a wide photographic plate with a violet copy card lifted
   over its lower-right corner.

   Replaces the old 50/50 split-with-a-diagonal-wedge panel. The overlap is the
   whole idea: the card breaks the plate's edge so the two elements read as
   layered objects rather than as two halves of one box, and the headline gets
   a solid ground instead of competing with the photograph behind it.

   Built as a grid with a deliberately overlapping second track rather than an
   absolutely-positioned card — the card's own height then drives the section's
   height, so a long headline can never spill outside the plate. */
.showcase {
	position: relative;
	display: grid;
	/* Plate and card share ONE grid cell, stacked. That is what lets the card
	   be positioned against the plate's edges with auto margins and keeps the
	   section's height equal to the plate's — no overhang, so no empty band
	   below the image. Both children name the same row/column. */
	grid-template-columns: minmax(0, 1fr);
	grid-template-rows: auto;
}

.showcase__plate,
.showcase__card {
	grid-area: 1 / 1;
}

.showcase__plate {
	position: relative;
	overflow: hidden;
	border-radius: var(--radius-lg);
	background: var(--navy-750);
	/* 16/9 rather than a wider 21/9: the copy card overlaps the plate's lower
	   portion, and on a very letterboxed plate the card hung far below the
	   image and left dead space beside it. A taller plate gives the overlap
	   something to sit against. */
	aspect-ratio: 16 / 9;
}

.showcase__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.9s var(--ease);
}

.showcase:hover .showcase__img {
	transform: scale(1.04);
}

/* A scrim rising from the plate's bottom-right, under the copy card. The card
   is opaque violet so it does not need this for its own legibility — the scrim
   stops the card looking pasted onto an unrelated bright photo by darkening
   the corner it sits in, and it gives the FEATURED label something to read
   against on a pale image. */
.showcase__plate::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background:
		linear-gradient(to top, rgba(10, 7, 34, 0.5), transparent 55%),
		linear-gradient(to left, rgba(10, 7, 34, 0.34), transparent 62%);
}

/* No artwork: the same hatched well the cards use, so a thumbnail-less
   feature still reads as deliberate. */
.showcase__img--empty {
	background:
		repeating-linear-gradient(
			135deg,
			rgba(10, 7, 34, 0.055) 0 12px,
			transparent 12px 24px
		),
		var(--navy-750);
}

/* Vertical rotated label running up the plate's left edge — the piece of
   editorial furniture that replaces the old wedge as the section's signature. */
.showcase__label {
	position: absolute;
	top: clamp(1rem, 2vw, 1.75rem);
	left: clamp(1rem, 2vw, 1.75rem);
	display: inline-block;
	padding: 0.4rem 0.8rem;
	background: var(--violet-500);
	color: #fff;
	border-radius: var(--radius);
	font-family: var(--font-body);
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	line-height: 1;
}

/* The copy card. Sits in the grid's only column, then shifts to overlap the
   plate. `margin-top` is negative so it rises onto the image. */
.showcase__card {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	gap: 0.7rem;
	padding: clamp(1.25rem, 2.6vw, 2.25rem);
	background: var(--violet-500);
	border-radius: var(--radius-lg);
	color: #fff;
	/* Sits fully INSIDE the plate, inset from its bottom-right corner. The card
	   used to hang ~180px below the image, which left an empty white strip
	   across the section's whole left half. Pulling it entirely within the
	   plate means the plate's own bottom edge is the section's bottom edge and
	   there is no leftover band to fill.

	   `margin-bottom` is the inset from the plate's foot; `margin-top: auto`
	   pushes the card down the grid area to get there, so the card's height
	   never has to be known in advance. */
	width: min(520px, 100%);
	margin-top: auto;
	margin-bottom: clamp(1rem, 2.4vw, 2rem);
	margin-left: auto;
	margin-right: clamp(1rem, 3vw, 3rem);
	box-shadow: 0 24px 60px rgba(10, 7, 34, 0.34);
}

.showcase__desk {
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: rgba(255, 255, 255, 0.78);
}

.showcase__title {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.015em;
	line-height: 1;
	font-size: clamp(1.5rem, 2.8vw, 2.35rem);
	/* Explicit, because the shared .display group is not applied here and the
	   card's own colour must win over any inherited ink. */
	color: #fff;
	text-wrap: balance;
}

.showcase__title a:hover {
	text-decoration: underline;
	text-underline-offset: 5px;
	text-decoration-thickness: 2px;
}

.showcase__excerpt {
	font-size: var(--fs-sm);
	color: rgba(255, 255, 255, 0.86);
}

.showcase__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
	margin-top: 0.25rem;
	padding-top: 0.9rem;
	border-top: 1px solid rgba(255, 255, 255, 0.22);
}

.showcase__cue {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	flex-shrink: 0;
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: #fff;
}

.showcase:hover .showcase__cue .arrow-badge {
	transform: translateX(3px);
}

.showcase .byline,
.showcase .byline__name,
.showcase .metarow,
.showcase .byline time,
.showcase .byline__sep {
	color: rgba(255, 255, 255, 0.82);
}

/* Tablet: the card widens and centres, still inset inside the plate. */
@media (max-width: 900px) {
	/* The card is nearly as wide as the plate here, so the plate needs a taller
	   photo for the card to sit inside without covering all of it. Expressed as
	   `height` with the ratio OFF — `aspect-ratio` + `min-height` makes the
	   browser satisfy the floor by widening the plate, which overflowed the
	   viewport at 768px. Same trap as the mobile block below. */
	.showcase__plate {
		aspect-ratio: auto;
		height: 62vw;
		min-height: 400px;
		max-height: 520px;
	}

	.showcase__card {
		width: min(620px, calc(100% - 2rem));
		margin-inline: auto;
		margin-bottom: 1rem;
	}
}

@media (max-width: 620px) {
	/* Stacked. The card is nearly full width here and its text wraps to a tall
	   block, so the desktop overlap is abandoned: the card only tucks under the
	   plate's bottom edge by a fixed amount. Keeping a proportional (vw-based)
	   lift instead made the card cover most of a short plate on small phones.

	   Here the two children leave the shared cell and become real rows: at this
	   width a card inset inside the plate would cover the entire photograph.
	   They still touch — the card overlaps the plate's bottom edge slightly —
	   so stacking does not reintroduce a gap.

	   The plate needs a height FLOOR: on a pure ratio it shrank with the
	   viewport while the card GREW (its text wraps to more lines), so on a
	   390px screen the photo became a 229px strip under a 298px card.

	   The floor is set with `height` + `min-height`, NOT `aspect-ratio` plus
	   `min-height`. With a ratio still in force the browser satisfied the floor
	   by resolving the ratio from the height and blowing the plate's WIDTH out
	   to 450px inside a 390px viewport — a real horizontal overflow. Dropping
	   the ratio here keeps width bound to the container and lets height be the
	   free dimension, which is what a floor needs. */
	.showcase {
		grid-template-rows: auto auto;
	}

	.showcase__plate {
		grid-area: 1 / 1;
		aspect-ratio: auto;
		height: 46vw;
		min-height: 260px;
	}

	.showcase__card {
		grid-area: 2 / 1;
		width: calc(100% - 1.5rem);
		margin-inline: auto;
		/* Lifts onto the plate's foot so the two read as joined. */
		margin-top: -1.5rem;
		margin-bottom: 0;
		/* Tighter type so the card stays proportionate to the plate above it
		   instead of dominating the section. */
		gap: 0.55rem;
		padding: 1.15rem 1.1rem;
	}

	.showcase__title {
		font-size: clamp(1.3rem, 6.4vw, 1.65rem);
	}

	.showcase__foot {
		/* The cue would otherwise wrap under a two-line byline and strand
		   itself against the left edge. */
		justify-content: flex-start;
		gap: 0.75rem;
	}
}

/* Very small phones: the excerpt is the first thing to go. Three lines of
   summary plus a headline plus a byline is more card than a 360px screen can
   hold without the photo above it becoming a sliver. */
@media (max-width: 400px) {
	.showcase__excerpt {
		display: -webkit-box;
		-webkit-line-clamp: 2;
		line-clamp: 2;
		-webkit-box-orient: vertical;
		overflow: hidden;
	}
}

/* 7.4 Spotlight — a wide photo with the headline set alongside it rather
   than over it, as in the reference. */
.spot {
	display: grid;
	grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
	gap: clamp(1.25rem, 2.6vw, 2.25rem);
	align-items: center;
}

.spot__media {
	display: block;
	position: relative;
	overflow: hidden;
	border-radius: var(--radius);
	aspect-ratio: 16 / 10;
	background: var(--navy-750);
}

/* A translucent violet corner wash, echoing the colour-blocked photo
   treatment throughout the reference. */
.spot__media::after {
	content: "";
	position: absolute;
	inset: 0;
	/* Lighter than the dark build's 0.55 — the photograph now sits on white
	   with nothing to recover its midtones, so a heavy violet cast just
	   dirtied it. Enough to colour-block the corner, not enough to tint. */
	background: linear-gradient(215deg, rgba(58, 50, 224, 0.34), transparent 46%);
	pointer-events: none;
}

.spot__body {
	display: flex;
	flex-direction: column;
	gap: 0.9rem;
	min-width: 0;
}

.spot__title {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.015em;
	line-height: 0.98;
	font-size: clamp(1.6rem, 2.9vw, 2.6rem);
	color: var(--ink-100);
}

.spot__title a:hover {
	color: var(--violet-300);
}

.spot__excerpt {
	font-size: var(--fs-sm);
	color: var(--ink-400);
	max-width: 46ch;
}

/* Byline and meta on one row. Was .hero-lead__foot, borrowed from the old hero
   split; that hero is gone, so the spotlight owns this rule now. */
.spot__foot {
	display: flex;
	align-items: center;
	gap: 1rem;
	flex-wrap: wrap;
}

@media (max-width: 860px) {
	.spot {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* 7.5 Desk board — a static directory, not a carousel.
   A 3x2 board where the first panel spans both rows and keeps a photograph,
   and the remaining five are flat plates in their own desk colour. Each panel
   carries the desk's newest headline, so the section is navigation into live
   coverage rather than a strip of labels. */
.deskboard {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	grid-auto-rows: minmax(178px, auto);
	gap: var(--gap);
}

.deskcard {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 1.25rem;
	overflow: hidden;
	border-radius: var(--radius);
	padding: 1.15rem;
	isolation: isolate;
	background: var(--navy-800);
	border: 1px solid var(--line-soft);
	transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

/* The desk's own colour arrives as a full-bleed wash that rises on hover,
   so the board reads as a set of coloured plates without nine hard-coded
   background rules. */
.deskcard::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: var(--cat-bg, var(--violet-500));
	/* Lower than the dark build's 0.16. A desk colour at 16% over white is
	   already a mid tint that fights the ink type sitting on it; 9% keeps the
	   plate identifiably coloured while leaving the headline crisp. */
	opacity: 0.09;
	transition: opacity var(--dur) var(--ease);
}

.deskcard:hover {
	transform: translateY(-3px);
	border-color: var(--cat-bg, var(--violet-500));
}

.deskcard:hover::before {
	opacity: 1;
}

/* Lead panel: spans two rows in the first column and reveals its cover art.
   Which card holds this class rotates on an interval (see main.js), so every
   desk takes a turn as the photographed panel.

   The grid position is NOT animated — moving a grid item between tracks
   cannot tween, and trying produces a jump. Only the artwork cross-fades; the
   panel geometry changes instantly underneath it, which reads as the photo
   moving rather than the box resizing. */
.deskcard--lead {
	grid-row: span 2;
	justify-content: flex-end;
	min-height: 380px;
	padding: 1.4rem;
	border-color: transparent;
}

/* Every card carries its image; only the lead shows it. Fading opacity rather
   than toggling display keeps the swap smooth and lets the browser decode the
   next photo before it is needed. */
.deskcard__img,
.deskcard__scrim {
	position: absolute;
	inset: 0;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.55s var(--ease);
}

.deskcard__img {
	z-index: -2;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Stays DARK deliberately: this scrim sits over a photograph and carries white
   type. It is the one place in the light theme that keeps a near-navy fill,
   and it is now slightly heavier than the dark build's — with a white page
   around it there is no ambient darkness helping the type. */
.deskcard__scrim {
	z-index: -1;
	background: linear-gradient(to top, rgba(10, 7, 34, 0.96) 8%, rgba(10, 7, 34, 0.55) 55%, rgba(10, 7, 34, 0.25));
}

.deskcard--lead .deskcard__img,
.deskcard--lead .deskcard__scrim {
	opacity: 1;
}

.deskcard--lead:hover .deskcard__img {
	transform: scale(1.05);
	transition: opacity 0.55s var(--ease), transform 0.7s var(--ease);
}

/* On the photographed panel the colour wash would drown the image, so the
   scrim does the legibility work and the wash is held back. */
.deskcard--lead::before {
	opacity: 0;
}

.deskcard--lead:hover::before {
	opacity: 0.34;
}

.deskcard__top {
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
}

.deskcard--lead .deskcard__top {
	order: -1;
	margin-bottom: auto;
}

/* On paper the plate begins as a PALE wash of the desk colour, so its type
   must be ink — the dark build's white would be white-on-near-white. On hover
   the wash rises to full opacity and every label flips to white together
   (see the .deskcard:hover block below). */
.deskcard__name {
	font-family: var(--font-display);
	font-weight: 800;
	font-size: clamp(1.1rem, 1.9vw, 1.5rem);
	text-transform: uppercase;
	letter-spacing: -0.01em;
	line-height: 1.05;
	color: var(--ink-100);
	transition: color var(--dur) var(--ease);
}

.deskcard--lead .deskcard__name {
	font-size: clamp(1.5rem, 2.6vw, 2.1rem);
}

.deskcard__count {
	font-size: var(--fs-micro);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--ink-400);
	transition: color var(--dur) var(--ease);
}

.deskcard:hover .deskcard__count {
	color: rgba(255, 255, 255, 0.82);
}

.deskcard__foot {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 0.85rem;
}

.deskcard__latest {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	min-width: 0;
}

.deskcard__latest-label {
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--ink-500);
	transition: color var(--dur) var(--ease);
}

.deskcard__latest-title {
	font-size: var(--fs-sm);
	font-weight: 600;
	line-height: 1.3;
	color: var(--ink-200);
	transition: color var(--dur) var(--ease);
	/* Two lines, so an unusually long headline cannot stretch one plate and
	   knock the whole row out of alignment. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.deskcard--lead .deskcard__latest-title {
	font-size: var(--fs-body);
	-webkit-line-clamp: 3;
	line-clamp: 3;
}

.deskcard__go {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	flex-shrink: 0;
	border-radius: 50%;
	border: 1px solid var(--line-firm);
	color: var(--ink-200);
	transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
		color var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.deskcard__go svg {
	width: 15px;
	height: 15px;
}

.deskcard:hover .deskcard__go {
	background: #fff;
	border-color: #fff;
	/* The desk colour, so the glyph is knocked out of the white disc against
	   whatever plate colour has just risen behind it. */
	color: var(--cat-bg, var(--violet-500));
	transform: translateX(3px);
}

/* Hover state: the plate fills with its solid desk colour, so all of the ink
   type above flips to white in one move. Kept as a single block so the flip is
   obviously coordinated rather than scattered across the section. */
.deskcard:hover .deskcard__name,
.deskcard:hover .deskcard__latest-title {
	color: #fff;
}

.deskcard:hover .deskcard__latest-label {
	color: rgba(255, 255, 255, 0.72);
}

/* The photographed lead panel is the exception: it carries a dark scrim over
   its image from the start, so its type is white at rest, hover or not. */
.deskcard--lead .deskcard__name,
.deskcard--lead .deskcard__latest-title {
	color: #fff;
}

.deskcard--lead .deskcard__count,
.deskcard--lead .deskcard__latest-label {
	color: rgba(255, 255, 255, 0.72);
}

.deskcard--lead .deskcard__go {
	border-color: rgba(255, 255, 255, 0.45);
	color: #fff;
}

@media (max-width: 900px) {
	.deskboard {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	/* The lead stops spanning rows here: at two columns a double-height panel
	   leaves a hole beside it on an odd count. */
	.deskcard--lead {
		grid-row: auto;
		grid-column: span 2;
		min-height: 300px;
	}
}

@media (max-width: 560px) {
	.deskboard {
		grid-template-columns: minmax(0, 1fr);
	}

	.deskcard--lead {
		grid-column: auto;
		min-height: 260px;
	}
}

/* 7.65 The Wire — a dated timeline.
   Stories hang off a vertical spine, grouped under the day they were filed.
   The only section on the page with a sense of time passing, which is what
   keeps it distinct from the desk board above and the ranked list below. */
.wire {
	position: relative;
	list-style: none;
	padding: 0;
	margin: 0;
}

/* The spine. Drawn as a pseudo-element on the list rather than a border on
   each row, so it runs continuously through the date marks too. */
.wire::before {
	content: "";
	position: absolute;
	top: 0.6rem;
	bottom: 0.6rem;
	left: 7px;
	width: 1px;
	background: linear-gradient(
		to bottom,
		transparent,
		var(--line-firm) 6%,
		var(--line-firm) 94%,
		transparent
	);
}

/* Date rule — "Today", "Yesterday", then real dates. */
.wire__daymark {
	position: relative;
	padding-left: 2.75rem;
	margin-block: 1.5rem 0.85rem;
}

.wire__daymark:first-child {
	margin-top: 0;
}

.wire__day {
	display: inline-block;
	padding: 0.28rem 0.7rem;
	border-radius: var(--radius);
	background: var(--navy-750);
	border: 1px solid var(--line-soft);
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--ink-300);
}

.wire__item {
	position: relative;
	padding-left: 2.75rem;
}

/* The node sitting on the spine, in the story's desk colour. A ring rather
   than a filled dot so it reads against the line at any colour. */
.wire__node {
	position: absolute;
	left: 0;
	top: 1.5rem;
	width: 15px;
	height: 15px;
	border-radius: 50%;
	background: var(--navy-800);
	border: 3px solid var(--cat-bg, var(--violet-500));
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.wire__item:hover .wire__node {
	transform: scale(1.25);
	box-shadow: 0 0 0 5px rgba(10, 7, 34, 0.07);
}

.wire__card {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 132px;
	gap: 1.25rem;
	align-items: center;
	padding-block: 1.15rem;
	border-bottom: 1px solid var(--line-soft);
}

.wire__item:last-child .wire__card {
	border-bottom: 0;
}

.wire__body {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	min-width: 0;
}

.wire__meta {
	display: flex;
	align-items: center;
	gap: 0.65rem;
	font-size: var(--fs-micro);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.14em;
}

/* Monospaced-feel timestamp: tabular figures keep the column aligned down
   the feed even though the times differ. */
.wire__time {
	color: var(--ink-200);
	font-variant-numeric: tabular-nums;
}

.wire__desk {
	position: relative;
	padding-left: 0.75rem;
	color: var(--cat-bg, var(--violet-300));
}

.wire__desk::before {
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	width: 3px;
	height: 3px;
	margin-top: -1.5px;
	border-radius: 50%;
	background: currentColor;
}

.wire__title {
	font-size: clamp(1.05rem, 1.6vw, 1.3rem);
	font-weight: 700;
	line-height: 1.25;
	letter-spacing: -0.01em;
	color: var(--ink-100);
}

.wire__title a:hover {
	color: var(--violet-300);
}

.wire__excerpt {
	font-size: var(--fs-sm);
	color: var(--ink-400);
	max-width: 62ch;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.wire__media {
	display: block;
	overflow: hidden;
	border-radius: var(--radius);
	aspect-ratio: 4 / 3;
	background: var(--navy-750);
}

.wire__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s var(--ease);
}

.wire__item:hover .wire__img {
	transform: scale(1.06);
}

@media (max-width: 700px) {
	.wire__daymark,
	.wire__item {
		padding-left: 1.9rem;
	}

	.wire::before {
		left: 5px;
	}

	.wire__node {
		width: 11px;
		height: 11px;
		border-width: 2px;
		top: 1.35rem;
	}

	/* The thumbnail leads on narrow screens rather than being squeezed into a
	   sliver beside the copy. */
	.wire__card {
		grid-template-columns: minmax(0, 1fr);
		gap: 0.85rem;
	}

	.wire__media {
		order: -1;
		aspect-ratio: 16 / 9;
	}

	.wire__excerpt {
		display: none;
	}
}

/* 7.7 Stat band — a full-width violet strip breaking the grid, giving the
   long homepage a change of pace between card sections. */
.statband {
	background: var(--violet-500);
	color: #fff;
}

.statband__grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--gap);
	padding-block: clamp(1.75rem, 3.5vw, 2.75rem);
}

.statband__item {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
}

.statband__num {
	font-family: var(--font-display);
	font-weight: 800;
	font-size: clamp(1.75rem, 3.4vw, 2.75rem);
	line-height: 1;
	letter-spacing: -0.02em;
}

.statband__label {
	font-size: var(--fs-micro);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.15em;
	color: rgba(255, 255, 255, 0.76);
}

@media (max-width: 720px) {
	.statband__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* 7.8 Closing block — latest stories beside a desk index, so the page ends
   on navigation rather than yet another card grid. */
.closing {
	display: grid;
	grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
	gap: clamp(1.5rem, 3.5vw, 3rem);
	align-items: start;
}

@media (max-width: 900px) {
	.closing {
		grid-template-columns: minmax(0, 1fr);
	}
}

.ranklist {
	display: flex;
	flex-direction: column;
}

.rank {
	display: grid;
	grid-template-columns: 3.25rem 1fr;
	gap: 1rem;
	align-items: start;
	padding-block: 1.05rem;
	border-bottom: 1px solid var(--line-soft);
}

.rank:first-child {
	padding-top: 0;
}

.rank:last-child {
	border-bottom: 0;
}

.rank__num {
	font-family: var(--font-display);
	font-weight: 800;
	font-size: 1.6rem;
	line-height: 1;
	color: var(--violet-500);
	letter-spacing: -0.03em;
}

.rank__title {
	font-size: 1.05rem;
	font-weight: 600;
	line-height: 1.3;
	color: var(--ink-100);
	margin-bottom: 0.3rem;
}

.rank__title a:hover {
	color: var(--violet-300);
}

/* Desk index — a compact list of every category with a hover sweep in that
   desk's own colour. Shared by the closing block and the single sidebar. */
.cat-list {
	display: flex;
	flex-direction: column;
}

.cat-list a {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	padding: 0.8rem 0.9rem;
	border-bottom: 1px solid var(--line-soft);
	overflow: hidden;
	isolation: isolate;
	transition: color var(--dur) var(--ease);
}

.cat-list a:last-child {
	border-bottom: 0;
}

.cat-list__name {
	position: relative;
	z-index: 1;
	font-size: var(--fs-xs);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--ink-200);
	transition: color var(--dur) var(--ease);
}

.cat-list__count {
	position: relative;
	z-index: 1;
	font-size: var(--fs-micro);
	font-weight: 600;
	color: var(--ink-500);
	transition: color var(--dur) var(--ease);
}

.cat-list__fill {
	position: absolute;
	inset: 0;
	z-index: 0;
	background: var(--cat-bg, var(--violet-500));
	transform: scaleX(0);
	transform-origin: left;
	transition: transform var(--dur) var(--ease);
}

.cat-list a:hover .cat-list__fill {
	transform: scaleX(1);
}

.cat-list a:hover .cat-list__name,
.cat-list a:hover .cat-list__count {
	color: var(--cat-fg, #fff);
}

/* ── 8. Newsletter ───────────────────────────────────────────────────────── */

/* The retired dark newsletter band lived here. The subscribe section is now a
   white card styled in the redesign layer near the end of this file. */

/* ── 9. Footer ───────────────────────────────────────────────────────────── */

/* Asymmetric two-track footer: a tall brand rail on the left, the desk index
   beside it, and a thin base bar. Deliberately not the stacked full-width
   bands used elsewhere. */
.site-footer {
	position: relative;
	background: var(--navy-900);
	padding-bottom: 1.75rem;
}

/* Spectrum rule — one band per desk in its own colour, spanning the full
   width. Doubles as a legend for the colour coding used across the site. */
.footer-spectrum {
	display: flex;
	height: 4px;
	width: 100%;
}

.footer-spectrum span {
	flex: 1;
	background: var(--cat-bg, var(--violet-500));
}

.footer-grid {
	display: grid;
	/* The brand rail is fixed-ish and the index takes the rest, rather than
	   the two sharing equal tracks — the asymmetry is the point. */
	grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.35fr);
	gap: clamp(2rem, 5vw, 5rem);
	padding-block: clamp(2.5rem, 5vw, 4rem);
}

@media (max-width: 900px) {
	.footer-grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 2.5rem;
	}
}

/* ── Brand rail */
.footer-id {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1.1rem;
	/* A hairline down the inner edge separates the two tracks without a box. */
	position: relative;
}

@media (min-width: 901px) {
	.footer-id::after {
		content: "";
		position: absolute;
		top: 0;
		bottom: 0;
		right: clamp(-2.5rem, -2.5vw, -1rem);
		width: 1px;
		background: var(--line-soft);
	}
}

.footer-id__logo img {
	max-height: 46px;
	width: auto;
}

.footer-id__name {
	font-family: var(--font-display);
	font-weight: 800;
	font-size: 1.6rem;
	text-transform: uppercase;
	letter-spacing: -0.02em;
	color: var(--ink-100);
}

.footer-id__desc {
	font-size: var(--fs-sm);
	color: var(--ink-400);
	max-width: 38ch;
}

/* Live status stamp — shows when the wire last moved, so the footer reads as
   a running newsroom rather than a static sitemap. */
.footer-status {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.4rem 0.8rem;
	border: 1px solid var(--line-soft);
	border-radius: var(--radius-pill);
	font-size: var(--fs-micro);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--ink-300);
}

.footer-status__dot {
	width: 6px;
	height: 6px;
	border-radius: 50%;
	/* Darkened from #3ED598: a mint dot on white read as a pale smudge, and
	   this is the theme's only "live" signal — it has to look lit. */
	background: #12A66B;
	box-shadow: 0 0 0 0 rgba(18, 166, 107, 0.6);
	animation: st-pulse 2.4s infinite;
}

.footer-contact {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	font-size: var(--fs-sm);
	color: var(--ink-300);
}

.footer-contact a {
	transition: color var(--dur) var(--ease);
}

.footer-contact a:hover {
	color: var(--violet-500);
}

/* ── Desk index */
.footer-heading {
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: var(--ink-500);
	margin-bottom: 1.1rem;
}

/* Tag cloud sized by output: the busiest desks set larger, so the shape of
   the coverage is legible at a glance. --scale is set per link in PHP. */
.deskcloud {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.deskcloud__link {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.45rem 0.85rem;
	border-radius: var(--radius-pill);
	border: 1px solid var(--line-soft);
	background: var(--navy-850);
	/* Scaled with calc rather than transform: transform would leave the
	   original box in flow and the chips would overlap. */
	font-size: calc(var(--fs-xs) * var(--scale, 1));
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	line-height: 1.2;
	color: var(--ink-200);
	transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
		color var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.deskcloud__link:hover {
	background: var(--cat-bg, var(--violet-500));
	border-color: var(--cat-bg, var(--violet-500));
	color: var(--cat-fg, #fff);
	transform: translateY(-2px);
}

.deskcloud__count {
	font-size: 0.72em;
	font-weight: 600;
	opacity: 0.6;
	font-variant-numeric: tabular-nums;
}

/* ── Base bar */
.footer-base {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap);
	flex-wrap: wrap;
	padding-top: 1.5rem;
	border-top: 1px solid var(--line-soft);
}

.footer-copy {
	font-size: var(--fs-xs);
	color: var(--ink-500);
}

.footer-legal {
	display: flex;
	align-items: center;
	gap: 1.25rem;
	flex-wrap: wrap;
	font-size: var(--fs-xs);
	color: var(--ink-500);
	/* Pushed to sit beside the copyright, leaving the Top link at the far
	   right regardless of how many legal links there are. */
	margin-right: auto;
	margin-left: 1.25rem;
}

.footer-legal a {
	transition: color var(--dur) var(--ease);
}

.footer-legal a:hover {
	color: var(--ink-200);
}

.footer-legal__menu {
	display: flex;
	gap: 1.25rem;
	flex-wrap: wrap;
}

.footer-top {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.5rem 0.9rem;
	border: 1px solid var(--line-soft);
	border-radius: var(--radius-pill);
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--ink-300);
	transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
		color var(--dur) var(--ease);
}

.footer-top svg {
	width: 13px;
	height: 13px;
	transition: transform var(--dur) var(--ease);
}

.footer-top:hover {
	background: var(--violet-500);
	border-color: var(--violet-500);
	color: #fff;
}

.footer-top:hover svg {
	transform: translateY(-2px);
}

@media (max-width: 640px) {
	.footer-base {
		justify-content: flex-start;
	}

	.footer-legal {
		margin-left: 0;
		margin-right: 0;
		width: 100%;
		order: 3;
	}

	.footer-top {
		order: 2;
		margin-left: auto;
	}
}

/* ── 10. Archive / category ──────────────────────────────────────────────── */

/* Hero: the term name on the left, its stats on the right, over a band
   washed in the term's own colour. */
.deskhero {
	position: relative;
	background: var(--navy-850);
	border-bottom: 1px solid var(--line-soft);
	padding-block: clamp(2.25rem, 5vw, 3.75rem);
	overflow: hidden;
}

/* A broad diagonal wash in the desk colour, anchored to the left edge so it
   sits behind the name rather than across the stats. */
.deskhero::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		100deg,
		var(--chip-bg, var(--violet-500)) -20%,
		transparent 52%
	);
	/* Lowered from 0.2: the desk colours are darker in this theme and the band
	   beneath is now pale, so 0.2 put a mid-tone behind the display-size title
	   and cost it contrast. */
	opacity: 0.12;
	pointer-events: none;
}

/* A thick bar of the desk colour down the leading edge — the strongest
   colour cue on the page, and the thing that makes each desk feel distinct. */
.deskhero::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	width: 6px;
	background: var(--chip-bg, var(--violet-500));
}

.deskhero__grid {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: clamp(1.5rem, 4vw, 3.5rem);
	align-items: end;
}

@media (max-width: 780px) {
	.deskhero__grid {
		grid-template-columns: minmax(0, 1fr);
		align-items: start;
		gap: 1.5rem;
	}
}

.deskhero__lede {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.85rem;
	min-width: 0;
}

.deskhero__title {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.02em;
	line-height: 0.9;
	font-size: var(--fs-display);
	color: var(--ink-100);
	/* Long search queries and tag names must not push the stats off-screen. */
	overflow-wrap: anywhere;
}

.deskhero__desc {
	font-size: var(--fs-lead);
	color: var(--ink-300);
	max-width: 60ch;
}

/* Stat block — count and freshness, rules between them. */
.deskstats {
	display: flex;
	gap: clamp(1.25rem, 3vw, 2.5rem);
	margin: 0;
	flex-shrink: 0;
}

.deskstats__item {
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
	padding-left: clamp(1.25rem, 3vw, 2.5rem);
	border-left: 1px solid var(--line-firm);
}

.deskstats__item:first-child {
	padding-left: 0;
	border-left: 0;
}

.deskstats dt {
	font-size: var(--fs-micro);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--ink-500);
	order: 2;
}

.deskstats dd {
	margin: 0;
	font-family: var(--font-display);
	font-weight: 800;
	font-size: clamp(1.5rem, 2.6vw, 2.1rem);
	line-height: 1;
	letter-spacing: -0.02em;
	color: var(--ink-100);
	white-space: nowrap;
}

/* ── Two-column spread */
.archive-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 320px;
	gap: clamp(1.75rem, 4vw, 3.5rem);
	align-items: start;
}

@media (max-width: 1000px) {
	.archive-layout {
		grid-template-columns: minmax(0, 1fr);
	}
}

.archive-side {
	display: flex;
	flex-direction: column;
	gap: var(--gap);
	position: sticky;
	top: 100px;
}

@media (max-width: 1000px) {
	.archive-side {
		position: static;
	}
}

/* ── Lead story: picture first, copy beneath. */
.deskled {
	display: flex;
	flex-direction: column;
	gap: 1.1rem;
	padding-bottom: var(--gap-lg);
	margin-bottom: 0.5rem;
	border-bottom: 1px solid var(--line-firm);
}

.deskled__media {
	position: relative;
	display: block;
	overflow: hidden;
	border-radius: var(--radius);
	background: var(--navy-750);
}

.deskled__clip {
	display: block;
	aspect-ratio: 16 / 9;
	overflow: hidden;
}

.deskled__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.7s var(--ease);
}

.deskled:hover .deskled__img {
	transform: scale(1.03);
}

/* Corner flag in the desk colour, inherited from the hero's --chip-bg. */
.deskled__tag {
	position: absolute;
	top: 0;
	left: 0;
	padding: 0.4rem 0.85rem;
	background: var(--chip-bg, var(--violet-500));
	/* Paired with the background rather than fixed white: the light swatches
	   (sand, amber, sky, rose) carry dark text, and white would vanish. */
	color: var(--chip-fg, #fff);
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	border-bottom-right-radius: var(--radius);
}

.deskled__body {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	align-items: flex-start;
}

.deskled__title {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.018em;
	line-height: 0.98;
	font-size: clamp(1.6rem, 3.2vw, 2.6rem);
	color: var(--ink-100);
}

.deskled__title a:hover {
	color: var(--violet-300);
}

.deskled__excerpt {
	font-size: var(--fs-lead);
	color: var(--ink-300);
	max-width: 60ch;
}

/* ── Numbered story rows */
.deskrow {
	display: grid;
	grid-template-columns: 3rem minmax(0, 1fr) 148px;
	gap: 1.25rem;
	align-items: start;
	padding-block: 1.5rem;
	border-bottom: 1px solid var(--line-soft);
}

.deskrow:last-of-type {
	border-bottom: 0;
}

.deskrow__num {
	font-family: var(--font-display);
	font-weight: 800;
	font-size: 1.35rem;
	line-height: 1.2;
	letter-spacing: -0.03em;
	/* Numbers in the desk colour, tying the list to the hero band. */
	color: var(--chip-bg, var(--violet-400));
	font-variant-numeric: tabular-nums;
}

.deskrow__body {
	display: flex;
	flex-direction: column;
	gap: 0.45rem;
	min-width: 0;
}

.deskrow__meta {
	display: flex;
	align-items: center;
	gap: 0.65rem;
	font-size: var(--fs-micro);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--ink-500);
}

.deskrow__desk {
	position: relative;
	padding-left: 0.75rem;
	color: var(--violet-300);
}

.deskrow__desk::before {
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	width: 3px;
	height: 3px;
	margin-top: -1.5px;
	border-radius: 50%;
	background: currentColor;
}

.deskrow__title {
	font-size: clamp(1.1rem, 1.7vw, 1.35rem);
	font-weight: 700;
	line-height: 1.25;
	letter-spacing: -0.01em;
	color: var(--ink-100);
}

.deskrow__title a:hover {
	color: var(--violet-300);
}

.deskrow__excerpt {
	font-size: var(--fs-sm);
	color: var(--ink-400);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.deskrow__media {
	display: block;
	overflow: hidden;
	border-radius: var(--radius);
	aspect-ratio: 4 / 3;
	background: var(--navy-750);
}

.deskrow__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s var(--ease);
}

.deskrow:hover .deskrow__img {
	transform: scale(1.06);
}

@media (max-width: 640px) {
	/* The number moves inline with the meta row and the thumbnail leads, so a
	   narrow screen is not trying to hold three columns. */
	.deskrow {
		grid-template-columns: minmax(0, 1fr);
		gap: 0.85rem;
	}

	.deskrow__num {
		display: none;
	}

	.deskrow__media {
		order: -1;
		aspect-ratio: 16 / 9;
	}
}

/* Pagination */
.pagination {
	margin-top: var(--gap-lg);
	padding-top: var(--gap-lg);
	border-top: 1px solid var(--line-soft);
}

.pagination .nav-links {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.45rem;
	flex-wrap: wrap;
}

.pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 40px;
	height: 40px;
	padding-inline: 0.75rem;
	border-radius: var(--radius);
	border: 1px solid var(--line-soft);
	font-size: var(--fs-xs);
	font-weight: 600;
	color: var(--ink-300);
	transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
		color var(--dur) var(--ease);
}

.pagination .page-numbers:hover {
	border-color: var(--violet-500);
	color: var(--violet-600);
	background: rgba(58, 50, 224, 0.07);
}

.pagination .page-numbers.current {
	background: var(--violet-500);
	border-color: var(--violet-500);
	color: #fff;
}

.pagination .dots {
	border: 0;
}

.no-results {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1.25rem;
	padding-block: clamp(2.5rem, 6vw, 5rem);
	max-width: 50ch;
}

.no-results p {
	font-size: var(--fs-lead);
	color: var(--ink-300);
}

/* ── 11. Single post ─────────────────────────────────────────────────────── */
.single-main {
	padding-bottom: var(--pad-section);
}

/* 11.1 Hero — the article opens on its photograph, headline set over it. */
.phero {
	position: relative;
	display: flex;
	align-items: flex-end;
	isolation: isolate;
	margin-bottom: clamp(1.75rem, 4vw, 3rem);
}

.phero--art {
	min-height: clamp(360px, 56vh, 620px);
	padding-block: clamp(2rem, 5vw, 4rem);
}

/* No artwork: a banded header instead, so the page still opens deliberately
   rather than dropping the reader straight into body copy. */
.phero--plain {
	padding-block: clamp(2.25rem, 5vw, 4rem) clamp(1.5rem, 3vw, 2.25rem);
	background: var(--navy-850);
	border-bottom: 1px solid var(--line-soft);
}

.phero__media {
	position: absolute;
	inset: 0;
	z-index: -1;
	overflow: hidden;
}

.phero__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Two-stop scrim: heavy at the foot where the type sits, light at the head so
   the photograph is still legible as an image. */
/* Kept DARK: the headline is set over the photograph in white, so the scrim
   still has to sink the image. It no longer fades into the page ground at the
   foot (that only worked when the page was navy) — instead it holds a strong
   ink wash the whole way down, and the article body below starts on white with
   a clean edge. */
.phero__scrim {
	position: absolute;
	inset: 0;
	background:
		linear-gradient(to top, rgba(10, 7, 34, 0.94) 2%, rgba(10, 7, 34, 0.8) 34%, rgba(10, 7, 34, 0.5) 70%, rgba(10, 7, 34, 0.5)),
		linear-gradient(to right, rgba(10, 7, 34, 0.55), transparent 60%);
}

.phero__inner {
	position: relative;
	max-width: 60rem;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1rem;
}

.phero__title {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.02em;
	line-height: 0.94;
	font-size: clamp(2rem, 5.2vw, 4rem);
	color: var(--ink-100);
	text-wrap: balance;
}

/* The art hero is the theme's one inverted region: white type over a scrimmed
   photograph. --ink-100 is now near-black, so the title, standfirst and every
   meta element inside must be forced back to white here. Scoped to --art only;
   .phero--plain keeps the normal ink treatment on its pale band. */
.phero--art .phero__title {
	color: #fff;
	/* Lifts the headline off a busy photograph without a solid plate behind it. */
	text-shadow: 0 2px 24px rgba(6, 2, 28, 0.55);
}

.phero--art .byline,
.phero--art .byline__name,
.phero--art .metarow,
.phero--art .kicker {
	color: rgba(255, 255, 255, 0.82);
}

.phero__standfirst {
	font-size: var(--fs-lead);
	color: var(--ink-200);
	max-width: 62ch;
}

/* Declared after the base .phero__standfirst so this wins the cascade — the
   base rule sets --ink-200, which would be near-black over the dark scrim. */
.phero--art .phero__standfirst {
	color: rgba(255, 255, 255, 0.92);
	text-shadow: 0 1px 12px rgba(6, 2, 28, 0.6);
}

.phero__caption {
	margin-top: -1rem;
	margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
	padding-left: 0.85rem;
	border-left: 2px solid var(--chip-bg, var(--violet-500));
	font-size: var(--fs-xs);
	color: var(--ink-500);
}

/* 11.2 Body — three tracks: detail rail, article, sidebar. */
.single-layout {
	display: grid;
	grid-template-columns: 190px minmax(0, 1fr) 320px;
	gap: clamp(1.5rem, 3.5vw, 3rem);
	align-items: start;
}

@media (max-width: 1180px) {
	/* Sidebar drops under the article first; the detail rail is narrow enough
	   to keep its column a while longer. */
	.single-layout {
		grid-template-columns: 180px minmax(0, 1fr);
	}

	.single-sidebar {
		grid-column: 1 / -1;
	}
}

@media (max-width: 860px) {
	.single-layout {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Detail rail */
.postrail {
	display: flex;
	flex-direction: column;
	gap: 1.35rem;
	position: sticky;
	top: 100px;
	padding-right: 1.25rem;
	border-right: 1px solid var(--line-soft);
}

@media (max-width: 860px) {
	/* Folds into a single row above the copy, so it reads as a byline strip
	   rather than a stranded column. */
	.postrail {
		position: static;
		flex-direction: row;
		flex-wrap: wrap;
		gap: 1.5rem;
		padding-right: 0;
		padding-bottom: 1.25rem;
		border-right: 0;
		border-bottom: 1px solid var(--line-soft);
	}
}

.postrail__block {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
}

.postrail__label {
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--ink-500);
}

.postrail__value {
	font-size: var(--fs-sm);
	font-weight: 600;
	color: var(--ink-200);
}

.postrail__author {
	display: flex;
	align-items: center;
	gap: 0.6rem;
}

.postrail__avatar {
	width: 40px;
	height: 40px;
	border-radius: 50%;
	object-fit: cover;
	flex-shrink: 0;
}

.postrail__name {
	display: block;
	font-size: var(--fs-sm);
	font-weight: 700;
	color: var(--ink-100);
	line-height: 1.2;
}

.postrail__role {
	display: block;
	font-size: var(--fs-micro);
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--ink-500);
}

/* Article body. Long-form copy is the one place the page steps back from
   uppercase display and lets Inter run at a comfortable measure. */
.article-content,
.page-content {
	font-size: 1.0625rem;
	line-height: 1.78;
	color: var(--ink-200);
	max-width: 68ch;
}

/* Drop cap in the desk colour, opening the article the way print does. */
.article-content > p:first-of-type::first-letter {
	float: left;
	font-family: var(--font-display);
	font-weight: 800;
	font-size: 3.4em;
	line-height: 0.82;
	margin: 0.06em 0.12em 0 0;
	color: var(--chip-bg, var(--violet-400));
}

.article-content > * + *,
.page-content > * + * {
	margin-top: 1.4em;
}

.article-content h2,
.page-content h2 {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.01em;
	line-height: 1.08;
	font-size: clamp(1.4rem, 2.4vw, 1.95rem);
	color: var(--ink-100);
	margin-top: 2.2em;
}

.article-content h3,
.page-content h3 {
	font-size: clamp(1.15rem, 1.8vw, 1.4rem);
	font-weight: 700;
	line-height: 1.25;
	color: var(--ink-100);
	margin-top: 1.9em;
}

.article-content h4,
.page-content h4 {
	font-size: 1.05rem;
	font-weight: 700;
	color: var(--ink-100);
	margin-top: 1.7em;
}

.article-content a,
.page-content a {
	color: var(--violet-300);
	text-decoration: underline;
	text-underline-offset: 3px;
	text-decoration-thickness: 1px;
	transition: color var(--dur) var(--ease);
}

/* Was #fff — on paper an in-copy link must DARKEN on hover, not disappear. */
.article-content a:hover,
.page-content a:hover {
	color: var(--ink-100);
}

.article-content strong,
.page-content strong {
	color: var(--ink-100);
	font-weight: 700;
}

.article-content ul,
.article-content ol,
.page-content ul,
.page-content ol {
	padding-left: 1.4rem;
	list-style: revert;
}

.article-content li,
.page-content li {
	margin-block: 0.45em;
}

.article-content li::marker,
.page-content li::marker {
	color: var(--chip-bg, var(--violet-400));
}

.article-content blockquote,
.page-content blockquote {
	padding: 1.25rem 1.5rem;
	border-left: 3px solid var(--chip-bg, var(--violet-500));
	background: var(--navy-850);
	border-radius: 0 var(--radius) var(--radius) 0;
	font-size: 1.12rem;
	line-height: 1.55;
	color: var(--ink-100);
}

.article-content blockquote p + p,
.page-content blockquote p + p {
	margin-top: 0.8em;
}

.article-content blockquote cite,
.page-content blockquote cite {
	display: block;
	margin-top: 0.75rem;
	font-size: var(--fs-micro);
	font-style: normal;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--ink-500);
}

.article-content img,
.page-content img {
	border-radius: var(--radius);
}

.article-content figure,
.page-content figure {
	margin-inline: 0;
}

.article-content figcaption,
.page-content figcaption {
	margin-top: 0.55rem;
	font-size: var(--fs-xs);
	color: var(--ink-500);
}

.article-content code,
.page-content code {
	background: var(--navy-900);
	border: 1px solid var(--line-soft);
	border-radius: 3px;
	padding: 0.1em 0.4em;
	font-size: 0.9em;
}

.article-content pre,
.page-content pre {
	background: var(--navy-900);
	border: 1px solid var(--line-soft);
	border-radius: var(--radius);
	padding: 1.15rem;
	overflow-x: auto;
}

.article-content pre code,
.page-content pre code {
	background: none;
	border: 0;
	padding: 0;
}

.article-content table,
.page-content table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--fs-sm);
	/* Wide tables must scroll inside their own box rather than pushing the
	   page sideways. */
	display: block;
	overflow-x: auto;
}

.article-content th,
.article-content td,
.page-content th,
.page-content td {
	padding: 0.65rem 0.85rem;
	border-bottom: 1px solid var(--line-soft);
	text-align: left;
}

.article-content th,
.page-content th {
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--ink-300);
}

.article-content hr,
.page-content hr {
	border: 0;
	border-top: 1px solid var(--line-soft);
	margin-block: 2.4em;
}

/* End-of-article mark, in the post's desk colour. */
.article-end {
	margin-top: 2.25rem;
}

.article-end__mark {
	display: block;
	width: 34px;
	height: 5px;
	border-radius: 3px;
	background: var(--chip-bg, var(--violet-500));
}

.article-tags {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	flex-wrap: wrap;
	margin-top: 1.75rem;
	padding-top: 1.5rem;
	border-top: 1px solid var(--line-soft);
}

.article-tags__label {
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--ink-500);
	margin-right: 0.25rem;
}

.article-tags .chip {
	background: var(--navy-750);
	color: var(--ink-300);
}

.article-tags .chip:hover {
	background: var(--chip-bg, var(--violet-500));
	color: var(--chip-fg, #fff);
	opacity: 1;
}

/* Prev / next */
.article-nav {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--gap);
	margin-top: 1.75rem;
	padding-top: 1.75rem;
	border-top: 1px solid var(--line-soft);
}

@media (max-width: 560px) {
	.article-nav {
		grid-template-columns: minmax(0, 1fr);
	}
}

.article-nav__item {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	padding: 1rem 1.15rem;
	border: 1px solid var(--line-soft);
	border-radius: var(--radius);
	transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}

.article-nav__item:hover {
	border-color: var(--chip-bg, var(--violet-400));
	background: var(--navy-850);
}

.article-nav__item--next {
	text-align: right;
	align-items: flex-end;
}

.article-nav__label {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--violet-300);
}

.article-nav__title {
	font-size: var(--fs-sm);
	font-weight: 600;
	line-height: 1.35;
	color: var(--ink-200);
}

.related {
	margin-top: var(--gap-lg);
	padding-top: var(--gap-lg);
	border-top: 1px solid var(--line-firm);
}

/* 11.3 Sidebar */
.single-sidebar {
	display: flex;
	flex-direction: column;
	gap: var(--gap);
	position: sticky;
	top: 100px;
}

@media (max-width: 1180px) {
	.single-sidebar {
		position: static;
		/* Below the article the panels read better side by side than as one
		   tall stack. */
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		align-items: start;
		margin-top: var(--gap-lg);
		padding-top: var(--gap-lg);
		border-top: 1px solid var(--line-firm);
	}
}

@media (max-width: 700px) {
	.single-sidebar {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Sidebar newsletter — a bordered brief card echoing the footer band, rather
   than the old filled violet block. */
.sidebrief {
	position: relative;
	padding: 1.5rem 1.35rem;
	background: var(--navy-850);
	border: 1px solid var(--line-firm);
	border-radius: var(--radius-lg);
	overflow: hidden;
	text-align: center;
}

/* Accent hairline across the top, in the post's desk colour. */
.sidebrief::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 3px;
	background: var(--chip-bg, var(--violet-500));
}

/* A soft bloom behind the copy, the same device the footer card uses. */
.sidebrief::after {
	content: "";
	position: absolute;
	top: 0;
	left: 50%;
	transform: translate(-50%, -60%);
	width: 120%;
	aspect-ratio: 2 / 1;
	background: radial-gradient(ellipse, rgba(58, 50, 224, 0.12), transparent 70%);
	pointer-events: none;
}

.sidebrief > * {
	position: relative;
	z-index: 1;
}

.sidebrief__kicker {
	display: inline-block;
	margin-bottom: 0.6rem;
	font-size: var(--fs-micro);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.18em;
	color: var(--violet-300);
}

.sidebrief__title {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.01em;
	line-height: 1.04;
	font-size: 1.25rem;
	color: var(--ink-100);
	margin-bottom: 0.5rem;
}

.sidebrief__sub {
	font-size: var(--fs-xs);
	color: var(--ink-400);
	margin-bottom: 1.1rem;
}

/* Stacked field and button: the column is too narrow for a row. Overrides the
   shared .newsletter-form__input, which is sized for the footer pill. */
.sidebrief__input {
	width: 100%;
	margin-bottom: 0.55rem;
	padding: 0.7rem 1rem;
	background: var(--navy-900);
	border: 1px solid var(--line-firm);
	border-radius: var(--radius-pill);
	color: var(--ink-100);
	font-size: var(--fs-sm);
	text-align: center;
}

.sidebrief__input::placeholder {
	color: var(--ink-500);
}

.sidebrief__input:focus {
	outline: none;
	background: #fff;
	border-color: var(--violet-500);
	box-shadow: 0 0 0 3px rgba(58, 50, 224, 0.18);
}

.sidebrief__btn {
	width: 100%;
}

.sidebrief .newsletter-form__msg {
	margin-top: 0.75rem;
	font-size: var(--fs-xs);
}

.sidebrief .newsletter-form__msg--success {
	color: #0F7040;
}

.sidebrief .newsletter-form__msg--error {
	color: #C2261A;
}

/* Sidebar panels are white cards; see the redesign layer at the end of this
   file. The old flush/top-ruled treatment is retired. */

/* The old absolutely-positioned "tab" heading is retired; the redesign layer
   near the end of this file styles .panel__heading as a plain flow heading. */

.panel .cat-list a {
	padding-inline: 0;
}

/* ── Ranked story list */
.side-list {
	display: flex;
	flex-direction: column;
	padding-top: 0.35rem;
}

.side-item {
	display: grid;
	grid-template-columns: 1.6rem minmax(0, 1fr);
	gap: 0.8rem;
	align-items: start;
	padding-block: 0.9rem;
	border-bottom: 1px solid var(--line-soft);
}

.side-item:last-child {
	border-bottom: 0;
	padding-bottom: 0;
}

/* The lead item carries artwork, so it takes a third track. Keyed off
   :first-child rather than :has(), which Safari below 15.4 does not support —
   and only the first item is ever given a thumbnail. */
.side-item:first-child {
	grid-template-columns: 1.6rem minmax(0, 1fr) 64px;
}

/* Outline numerals — the rank reads as a marker rather than as content, and
   stays quiet next to the headline it labels. */
.side-item__rank {
	font-family: var(--font-display);
	font-weight: 800;
	font-size: 1.5rem;
	line-height: 1;
	color: transparent;
	-webkit-text-stroke: 1px var(--ink-500);
	font-variant-numeric: tabular-nums;
	transition: -webkit-text-stroke-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

/* The top rank fills in, in the desk colour. */
.side-item:first-child .side-item__rank {
	color: var(--chip-bg, var(--violet-400));
	-webkit-text-stroke: 0;
}

.side-item:hover .side-item__rank {
	-webkit-text-stroke-color: var(--chip-bg, var(--violet-400));
}

.side-item__body {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	min-width: 0;
}

.side-item__title {
	font-size: 0.92rem;
	font-weight: 600;
	line-height: 1.32;
	color: var(--ink-100);
}

.side-item__title a:hover {
	color: var(--violet-300);
}

.side-item__time {
	font-size: var(--fs-micro);
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--ink-500);
}

.side-item__media {
	display: block;
	overflow: hidden;
	border-radius: var(--radius);
	aspect-ratio: 1 / 1;
	background: var(--navy-750);
}

.side-item__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s var(--ease);
}

.side-item:hover .side-item__media img {
	transform: scale(1.07);
}

/* Widget-area defaults, so an added widget inherits the panel treatment. */
.widget {
	padding: 1.4rem 0 0;
	border-top: 2px solid var(--line-firm);
}

.widget ul li {
	padding-block: 0.45rem;
	border-bottom: 1px solid var(--line-soft);
	font-size: var(--fs-sm);
}

.widget ul li:last-child {
	border-bottom: 0;
}

/* ── 12. Static page ─────────────────────────────────────────────────────── */
.page-main {
	padding-block: clamp(2rem, 5vw, 3.5rem) var(--pad-section);
}

.page-header {
	padding-bottom: 1.5rem;
	margin-bottom: 1.75rem;
	border-bottom: 1px solid var(--line-firm);
}

.page-header__title {
	font-family: var(--font-display);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: -0.018em;
	line-height: 0.98;
	font-size: clamp(2rem, 4.4vw, 3.2rem);
	color: var(--ink-100);
}

.page-header__updated {
	display: inline-block;
	margin-top: 0.75rem;
	font-size: var(--fs-micro);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--ink-500);
}

.page-hero {
	margin-bottom: 1.75rem;
}

.page-hero__img {
	width: 100%;
	border-radius: var(--radius);
}

/* ── 13. 404 ─────────────────────────────────────────────────────────────── */
.error-main {
	padding-block: clamp(2.5rem, 6vw, 4.5rem) var(--pad-section);
}

.error-page {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1.1rem;
	max-width: 62ch;
	padding-bottom: var(--pad-section);
}

/* The oversized ghost numeral behind the copy. Pushed off the right edge and
   clipped, so it reads as a graphic rather than as text to be read. */
.error-page__code {
	position: absolute;
	top: -0.28em;
	right: -0.08em;
	z-index: -1;
	font-family: var(--font-display);
	font-weight: 800;
	font-size: clamp(9rem, 26vw, 20rem);
	line-height: 0.8;
	letter-spacing: -0.05em;
	color: var(--violet-500);
	/* Lowered from 0.16: a dark violet numeral on white at that opacity read as
	   solid grey text competing with the headline, where on navy it was a faint
	   ghost. This keeps it as background texture. */
	opacity: 0.1;
	pointer-events: none;
	user-select: none;
}

.error-page__title {
	font-size: var(--fs-h1);
}

.error-page__desc {
	font-size: var(--fs-lead);
	color: var(--ink-300);
}

.error-page__actions {
	display: flex;
	gap: 0.75rem;
	flex-wrap: wrap;
	margin-top: 0.4rem;
}

.error-recent {
	padding-top: var(--gap-lg);
	border-top: 1px solid var(--line-firm);
}

/* ── 14. Utilities, motion, print ────────────────────────────────────────── */
.u-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* Stretches a link over its whole card. Used where the card cannot be an
   <a> because it already contains links (chips, bylines). */
.stretch-hit::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

/* Scroll reveal. The hidden initial state is gated on .js so a visitor
   without JavaScript never sees permanently invisible content. */
.js [data-reveal] {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}

.js [data-reveal].is-visible {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}

	.js [data-reveal] {
		opacity: 1;
		transform: none;
	}

	.tickerbar__track {
		animation: none;
	}
}

@media print {
	.site-header,
	.site-footer,
	.brief,
	.single-sidebar,
	.postrail,
	.related,
	.article-nav,
	.read-progress,
	.tickerbar {
		display: none !important;
	}

	body {
		background: #fff;
		color: #000;
	}

	.single-layout {
		grid-template-columns: 1fr;
	}

	/* The scrim and its artwork do not print, so the headline needs its ink
	   back. .phero--art .phero__title is more specific than a bare
	   .phero__title, so the light-theme white would otherwise win here and
	   print an invisible headline. */
	.phero__title,
	.phero--art .phero__title,
	.phero--art .phero__standfirst,
	.article-content {
		color: #000;
		text-shadow: none;
	}

	.phero__media,
	.phero__scrim {
		display: none !important;
	}
}

/* ═══════════════════════════════════════════════════════════════════════════
   REDESIGN LAYER
   Card-on-grey blog layout: ticker, hero slider, two-column list + sidebar,
   and the "You May Have Missed" row. Declared after the original rules so it
   wins on equal specificity without needing !important.
   ══════════════════════════════════════════════════════════════════════════ */

/* The ground colour goes on <html> as well: on a short page (a 404, an empty
   archive) the body box stops before the viewport does, and the browser would
   paint its own white canvas below it. */
html {
	background: var(--page-bg);
}

body {
	background: var(--page-bg);
	color: var(--ink-200);
	font-family: var(--font-body);
	/* Keeps the footer at the bottom of the viewport on short pages. */
	min-height: 100vh;
	display: flex;
	flex-direction: column;
}

body > .site-main,
body > main {
	flex: 1 0 auto;
}

/* The gutter scales with the viewport rather than taking a fixed 2rem bite:
   on a 390px phone that fixed inset cost ~8% of the usable width, which made
   cards and headlines feel cramped. padding-inline (not width) also keeps the
   box intact when a child sets its own width. */
.container {
	width: 100%;
	max-width: var(--container);
	padding-inline: clamp(0.75rem, 3vw, 1.5rem);
	margin-inline: auto;
}

/* Re-stated after the rule above, which would otherwise reset the narrow
   variant's max-width back to the full container. */
.container--narrow {
	max-width: var(--container-narrow);
}

/* ── Header ──────────────────────────────────────────────────────────────── */

.site-header {
	background: var(--card-bg);
	border-bottom: 1px solid var(--line-soft);
}

.masthead {
	display: flex;
	align-items: center;
	gap: 1.25rem;
	min-height: 62px;
}

.masthead__brand {
	flex: 0 0 auto;
	/* The nav takes the free space instead, which pushes it and the utilities
	   to the right of the wordmark. */
}

.masthead__brand img {
	height: var(--logo-h);
	width: auto;
	display: block;
}

.site-logo {
	font-family: var(--font-display);
	font-size: 1.15rem;
	font-weight: 800;
	letter-spacing: -0.01em;
	color: var(--ink-100);
	text-decoration: none;
}

/* The nav absorbs the free space and right-aligns its contents, so the menu
   sits against the utilities rather than beside the wordmark. */
.nav-primary {
	flex: 1 1 auto;
	display: flex;
	justify-content: flex-end;
}

.nav-list {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 1.6rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.nav-list a {
	font-size: 0.9rem;
	font-weight: 700;
	letter-spacing: 0.01em;
	color: var(--ink-200);
	text-decoration: none;
	white-space: nowrap;
	transition: color 0.18s ease;
}

.nav-list a:hover,
.nav-list .current-menu-item > a,
.nav-list .current_page_item > a {
	color: var(--brand);
}

.masthead__util {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	flex: 0 0 auto;
}

.masthead__search {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	color: var(--brand);
	background: var(--brand-light);
	text-decoration: none;
}

.masthead__search:hover {
	background: var(--brand);
	color: #fff;
}

.btn {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	font-size: 0.9rem;
	font-weight: 700;
	text-decoration: none;
	border-radius: var(--radius-pill);
	padding: 0.72rem 1.5rem;
	transition: background 0.18s ease, transform 0.18s ease;
}

.btn--primary:active {
	transform: translateY(1px);
}

.btn__bell {
	width: 16px;
	height: 16px;
	flex: 0 0 auto;
	display: block;
}

.btn--primary {
	background: var(--brand);
	color: #fff;
}

.btn--primary:hover {
	background: var(--brand-dark);
}

/* ── Top stories ticker ──────────────────────────────────────────────────── */

.ticker {
	background: var(--card-bg);
	border-bottom: 1px solid var(--line-soft);
	padding: 0.5rem 0;
}

.ticker__inner {
	display: flex;
	align-items: center;
	gap: 0.85rem;
}

.ticker__label {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	flex: 0 0 auto;
	font-size: 0.72rem;
	font-weight: 700;
	color: #fff;
	background: var(--brand);
	border-radius: var(--radius-pill);
	padding: 0.3rem 0.75rem;
	white-space: nowrap;
}

.ticker__pip {
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: #fff;
}

.ticker__viewport {
	flex: 1 1 auto;
	overflow: hidden;
	position: relative;
}

.ticker__track {
	display: flex;
	align-items: center;
	gap: 1.75rem;
	width: max-content;
	animation: ticker-scroll 46s linear infinite;
}

.ticker.is-paused .ticker__track {
	animation-play-state: paused;
}

/* Reduced motion / no JS: a plain scrollable strip instead of a marquee. */
.ticker.is-static .ticker__viewport {
	overflow-x: auto;
}

.ticker.is-static .ticker__track {
	animation: none;
}

@keyframes ticker-scroll {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

.ticker__item {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	text-decoration: none;
	white-space: nowrap;
}

.ticker__img {
	width: 30px;
	height: 30px;
	object-fit: cover;
	border-radius: var(--radius);
	flex: 0 0 auto;
}

.ticker__text {
	display: flex;
	flex-direction: column;
	line-height: 1.25;
}

.ticker__headline {
	font-size: 0.78rem;
	font-weight: 600;
	color: var(--ink-200);
}

.ticker__item:hover .ticker__headline {
	color: var(--brand);
}

.ticker__date {
	font-size: 0.65rem;
	color: var(--ink-500);
}

.ticker__toggle {
	flex: 0 0 auto;
	width: 28px;
	height: 28px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--ink-100);
	border: 0;
	border-radius: var(--radius);
	cursor: pointer;
}

.ticker__bars {
	display: flex;
	gap: 3px;
}

.ticker__bars span {
	width: 3px;
	height: 11px;
	background: #fff;
	display: block;
}

/* Paused state swaps the two bars for a single play triangle. */
.ticker.is-paused .ticker__bars {
	gap: 0;
}

.ticker.is-paused .ticker__bars span:first-child {
	width: 0;
	height: 0;
	border-left: 9px solid #fff;
	border-top: 6px solid transparent;
	border-bottom: 6px solid transparent;
	background: none;
}

.ticker.is-paused .ticker__bars span:last-child {
	display: none;
}

/* ── Hero slider ─────────────────────────────────────────────────────────── */

/* The first-pass hero rules were replaced by the refined block at the end of
   this file. */

/* ── Two-column layout ───────────────────────────────────────────────────── */

.layout {
	padding: 1.5rem 0 2.5rem;
}

.layout__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 300px;
	gap: 1.5rem;
	align-items: start;
}

.layout__main {
	min-width: 0;
}

/* ── Post cards ──────────────────────────────────────────────────────────── */

.card-list {
	display: flex;
	flex-direction: column;
	gap: 1rem;
}

.card {
	display: grid;
	/* Proportional rather than a fixed pixel width, so the image keeps its
	   share of the row as the column resizes. */
	grid-template-columns: 30% minmax(0, 1fr);
	gap: 1.15rem;
	background: var(--card-bg);
	border-radius: var(--radius-lg);
	padding: 0.85rem;
	align-items: start;
}

.card__media {
	display: block;
	border-radius: var(--radius);
	overflow: hidden;
	aspect-ratio: 4 / 3;
}

.card__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 0.4s var(--ease);
}

.card:hover .card__img {
	transform: scale(1.04);
}

.card__body {
	padding: 0.2rem 0.3rem 0.2rem 0;
}

.card__title {
	font-family: var(--font-display);
	font-size: 1.08rem;
	line-height: 1.3;
	margin: 0.45rem 0 0.4rem;
}

.card__title a {
	color: var(--ink-100);
	text-decoration: none;
}

.card__title a:hover {
	color: var(--brand);
}

.card__excerpt {
	font-size: 0.83rem;
	line-height: 1.6;
	color: var(--ink-400);
	margin: 0 0 0.6rem;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.card__meta {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	font-size: 0.72rem;
	color: var(--ink-500);
}

.card__edit {
	color: var(--brand);
	text-decoration: none;
}

/* Category chips. Colour arrives as inline custom properties per term. */
.chip {
	display: inline-block;
	font-size: 0.68rem;
	font-weight: 600;
	line-height: 1;
	padding: 0.3rem 0.6rem;
	border-radius: var(--radius-pill);
	background: var(--chip-bg, var(--brand));
	color: var(--chip-fg, #fff);
	text-decoration: none;
}

.chip--sm {
	font-size: 0.63rem;
	padding: 0.25rem 0.5rem;
}

/* ── Sidebar ─────────────────────────────────────────────────────────────── */

.sidebar {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	position: sticky;
	/* Clears the sticky masthead (62px) plus a little breathing room, so the
	   panels are never tucked underneath it when the column pins. */
	top: 5rem;
	align-self: start;
}

.panel,
.sidebar .widget {
	background: var(--card-bg);
	border-radius: var(--radius-lg);
	padding: 1.15rem;
}

.panel__heading {
	display: flex;
	align-items: center;
	gap: 0.45rem;
	font-family: var(--font-display);
	font-size: 1rem;
	color: var(--ink-100);
	margin: 0 0 0.75rem;
}

.panel__dot {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--brand);
}

.panel__intro {
	font-size: 0.8rem;
	line-height: 1.55;
	color: var(--ink-400);
	margin: 0 0 0.9rem;
}

.cat-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.cat-list__item + .cat-list__item {
	border-top: 1px solid var(--line-soft);
}

.cat-list__link {
	display: block;
	padding: 0.65rem 0;
	font-size: 0.9rem;
	font-weight: 700;
	color: var(--ink-200);
	text-decoration: none;
	transition: color 0.18s ease;
}

.cat-list__link:hover {
	color: var(--brand);
}

/* ── Pagination ──────────────────────────────────────────────────────────── */

.pagination {
	margin-top: 1.5rem;
}

.pagination__list {
	display: flex;
	justify-content: center;
	gap: 0.4rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.pagination__list .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 32px;
	height: 32px;
	padding: 0 0.5rem;
	font-size: 0.82rem;
	font-weight: 600;
	color: var(--ink-300);
	background: var(--card-bg);
	border-radius: 50%;
	text-decoration: none;
}

.pagination__list .page-numbers:hover,
.pagination__list .page-numbers.current {
	background: var(--brand);
	color: #fff;
}

/* ── You May Have Missed / Related ───────────────────────────────────────── */

.missed {
	padding: 0 0 2.5rem;
}

.missed__card {
	background: var(--card-bg);
	border-radius: var(--radius-lg);
	padding: 1.25rem;
}

.missed__heading {
	display: flex;
	align-items: center;
	gap: 0.45rem;
	font-family: var(--font-display);
	font-size: 1.05rem;
	margin: 0 0 1rem;
	color: var(--ink-100);
}

.missed__grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 0.85rem;
}

/* The article carries the aspect box, the rounding and the clipping, and is the
   positioning context for the caption — so the caption overlays the photograph
   rather than stacking beneath it, and nothing spills past the rounded corner. */
.tile {
	position: relative;
	aspect-ratio: 4 / 3;
	border-radius: var(--radius);
	overflow: hidden;
	isolation: isolate;
}

/* Invisible cover link: makes the whole tile clickable while sitting BELOW the
   caption, so the chip and title keep their own links. */
.tile__link {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: block;
	text-decoration: none;
}

.tile__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.tile__shade {
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(to top, rgba(10, 7, 34, 0.92) 10%, rgba(10, 7, 34, 0.55) 45%, rgba(10, 7, 34, 0.05) 78%);
}

.tile__body {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 3;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.35rem;
	padding: 0.7rem;
}

.tile__chips {
	display: block;
}

.tile__title {
	font-family: var(--font-display);
	font-size: 0.85rem;
	font-weight: 700;
	line-height: 1.32;
	color: #fff;
	text-decoration: none;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	overflow: hidden;
	text-shadow: 0 1px 3px rgba(10, 7, 34, 0.55);
}

.tile__title:hover {
	text-decoration: underline;
}

.tile__date {
	display: block;
	font-size: 0.65rem;
	color: rgba(255, 255, 255, 0.8);
	text-shadow: 0 1px 3px rgba(10, 7, 34, 0.5);
}

/* ── Archive header ──────────────────────────────────────────────────────── */

.archive-head {
	padding: 1.5rem 0 0.5rem;
}

.archive-head__kicker {
	font-size: 0.7rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--brand);
	margin: 0 0 0.3rem;
}

.archive-head__title {
	font-family: var(--font-display);
	font-size: clamp(1.5rem, 3vw, 2.1rem);
	color: var(--ink-100);
	margin: 0;
}

.archive-head__desc {
	font-size: 0.9rem;
	line-height: 1.6;
	color: var(--ink-400);
	margin-top: 0.4rem;
}

/* ── Single post ─────────────────────────────────────────────────────────── */

.single-article {
	background: var(--card-bg);
	border-radius: var(--radius-lg);
	padding: 1.5rem;
}

.single-head__title {
	font-family: var(--font-display);
	font-size: clamp(1.6rem, 3.4vw, 2.3rem);
	line-height: 1.2;
	color: var(--ink-100);
	margin: 0.6rem 0 0.6rem;
}

.single-head__standfirst {
	font-size: 1rem;
	line-height: 1.6;
	color: var(--ink-400);
	margin: 0 0 0.75rem;
}

.single-head__meta {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	font-size: 0.75rem;
	color: var(--ink-500);
	padding-bottom: 1rem;
	border-bottom: 1px solid var(--line-soft);
}

.single-hero {
	margin: 1.25rem 0;
	border-radius: var(--radius);
	overflow: hidden;
}

.single-hero__img {
	width: 100%;
	height: auto;
	display: block;
}

.single-content {
	font-size: 1rem;
	line-height: 1.75;
	color: var(--ink-200);
}

.single-content > * + * {
	margin-top: 1.1rem;
}

.single-content h2,
.single-content h3 {
	font-family: var(--font-display);
	color: var(--ink-100);
	line-height: 1.3;
	margin-top: 1.8rem;
}

.single-content img {
	max-width: 100%;
	height: auto;
	border-radius: var(--radius);
}

.single-content a {
	color: var(--brand);
}

.single-content blockquote {
	border-left: 3px solid var(--brand);
	padding-left: 1rem;
	color: var(--ink-300);
	font-style: italic;
}

.single-tags {
	margin-top: 1.5rem;
	padding-top: 1rem;
	border-top: 1px solid var(--line-soft);
	font-size: 0.8rem;
}

.single-tags__label {
	font-weight: 700;
	color: var(--ink-300);
	margin-right: 0.4rem;
}

.single-tags a {
	color: var(--brand);
	text-decoration: none;
	margin-right: 0.5rem;
}

/* ── Static pages ────────────────────────────────────────────────────────── */

.page-main {
	padding: 2rem 0 3rem;
}

.static-page {
	background: var(--card-bg);
	border-radius: var(--radius-lg);
	padding: 1.75rem;
}

.page-header__title {
	font-family: var(--font-display);
	font-size: clamp(1.6rem, 3.4vw, 2.3rem);
	color: var(--ink-100);
	margin: 0 0 0.5rem;
}

.page-content {
	font-size: 1rem;
	line-height: 1.75;
}

.page-content > * + * {
	margin-top: 1.1rem;
}

.page-content a {
	color: var(--brand);
}

/* ── Subscribe band (footer) ─────────────────────────────────────────────── */

/* Subscribe band: a white card on the page ground, matching the cards used
   everywhere else rather than the old full-bleed dark panel. */
.brief {
	padding: 0 0 2.5rem;
}

.brief__inner {
	display: grid;
	grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
	gap: clamp(1.5rem, 3vw, 3rem);
	align-items: center;
	background: var(--card-bg);
	border-radius: var(--radius-lg);
	padding: clamp(1.5rem, 3vw, 2.5rem);
}

.brief__kicker {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	font-size: 0.7rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--brand);
	margin: 0 0 0.6rem;
}

.brief__pip {
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--brand);
}

.brief__title {
	font-family: var(--font-display);
	font-size: clamp(1.45rem, 2.8vw, 2.05rem);
	line-height: 1.2;
	color: var(--ink-100);
	margin: 0 0 0.65rem;
}

.brief__sub {
	font-size: 0.92rem;
	line-height: 1.65;
	color: var(--ink-400);
	margin: 0;
}

.brief__points {
	list-style: none;
	margin: 1.1rem 0 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.45rem;
}

.brief__points li {
	position: relative;
	padding-left: 1.4rem;
	font-size: 0.85rem;
	line-height: 1.5;
	color: var(--ink-300);
}

/* Accent check mark, drawn in CSS so it recolours with the theme. */
.brief__points li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.28em;
	width: 0.42rem;
	height: 0.72rem;
	border: solid var(--brand);
	border-width: 0 2px 2px 0;
	transform: rotate(45deg);
}

.brief__card {
	background: var(--page-bg);
	border: 1px solid var(--line-soft);
	border-radius: var(--radius-lg);
	padding: clamp(1.15rem, 2vw, 1.5rem);
}

/* ── Empty state ─────────────────────────────────────────────────────────── */

.empty {
	background: var(--card-bg);
	border-radius: var(--radius-lg);
	padding: 2rem;
	text-align: center;
	color: var(--ink-400);
}

.empty__title {
	font-family: var(--font-display);
	color: var(--ink-100);
	margin: 0 0 0.5rem;
}

/* ── Responsive ──────────────────────────────────────────────────────────── */

@media (max-width: 1080px) {
	.layout__grid {
		grid-template-columns: minmax(0, 1fr);
	}

	.sidebar {
		position: static;
	}

	.missed__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.brief__inner {
		grid-template-columns: minmax(0, 1fr);
	}
}

@media (max-width: 780px) {
	.card {
		grid-template-columns: 34% minmax(0, 1fr);
		gap: 0.85rem;
	}

	.card__excerpt {
		display: none;
	}
}

@media (max-width: 520px) {
	.missed__grid {
		grid-template-columns: minmax(0, 1fr);
	}

	.card {
		grid-template-columns: minmax(0, 1fr);
	}

	.card__media {
		aspect-ratio: 16 / 9;
	}

	.ticker__label span:not(.ticker__pip) {
		display: none;
	}
}

/* ── Footer ──────────────────────────────────────────────────────────────── */

.site-footer {
	background: var(--page-bg);
	border-top: 1px solid var(--line-soft);
	padding: 1.75rem 0 2rem;
	text-align: center;
}

.footer-legal {
	display: flex;
	justify-content: center;
}

.footer-legal__menu {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.5rem 2rem;
	list-style: none;
	margin: 0 0 1.1rem;
	padding: 0;
}

.footer-legal__menu a {
	font-size: 0.85rem;
	font-weight: 700;
	color: var(--ink-200);
	text-decoration: none;
	transition: color 0.18s ease;
}

.footer-legal__menu a:hover {
	color: var(--brand);
}

.footer-copy {
	font-size: 0.78rem;
	color: var(--ink-500);
	margin: 0;
}

.footer-copy a {
	color: var(--ink-400);
	text-decoration: none;
}

.footer-copy a:hover {
	color: var(--brand);
}

/* ── 404 ─────────────────────────────────────────────────────────────────── */

.error404 {
	position: relative;
	background: var(--card-bg);
	border-radius: var(--radius-lg);
	padding: clamp(2rem, 5vw, 3.5rem);
	margin: 1.5rem 0;
	overflow: hidden;
}

/* Oversized ghost numeral behind the copy. Decorative, so it is hidden from
   assistive tech and never intercepts a click. */
.error404__code {
	position: absolute;
	top: 50%;
	right: clamp(1rem, 4vw, 3rem);
	transform: translateY(-50%);
	margin: 0;
	font-family: var(--font-display);
	font-size: clamp(7rem, 22vw, 16rem);
	font-weight: 800;
	line-height: 0.8;
	letter-spacing: -0.04em;
	color: var(--brand);
	opacity: 0.08;
	pointer-events: none;
	user-select: none;
}

.error404__body {
	position: relative;
	z-index: 1;
	max-width: 40rem;
}

.error404__kicker {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	font-size: 0.7rem;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--brand);
	margin: 0 0 0.6rem;
}

.error404__title {
	font-family: var(--font-display);
	font-size: clamp(1.6rem, 3.6vw, 2.5rem);
	line-height: 1.18;
	color: var(--ink-100);
	margin: 0 0 0.7rem;
}

.error404__desc {
	font-size: 0.95rem;
	line-height: 1.65;
	color: var(--ink-400);
	margin: 0 0 1.5rem;
}

.error404__search {
	display: flex;
	gap: 0.6rem;
	max-width: 30rem;
}

.error404__input {
	flex: 1 1 auto;
	min-width: 0;
	font-family: var(--font-body);
	font-size: 0.95rem;
	color: var(--ink-100);
	background: #fff;
	border: 1px solid var(--line-firm);
	border-radius: var(--radius);
	padding: 0.72rem 0.9rem;
	-webkit-appearance: none;
	appearance: none;
}

.error404__input:focus {
	outline: none;
	border-color: var(--brand);
	box-shadow: 0 0 0 3px var(--brand-light);
}

.error404__search .btn {
	flex: 0 0 auto;
}

.error404__back {
	margin: 1.25rem 0 0;
}

.error404__back a {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	font-size: 0.9rem;
	font-weight: 700;
	color: var(--brand);
	text-decoration: none;
}

.error404__back a:hover {
	text-decoration: underline;
}

@media (max-width: 560px) {
	.error404__search {
		flex-direction: column;
	}

	.error404__search .btn {
		justify-content: center;
	}
}

/* ── Hero slider (refined) ───────────────────────────────────────────────────
   Replaces the first-pass hero rules above: the photograph now leads at a
   wider ratio, the arrows sit inside the card so nothing overhangs the
   rounded corner, and dots give the reader a sense of position. */

.hero {
	padding: 1.5rem 0 0;
}

.hero__slider {
	position: relative;
	background: var(--card-bg);
	border-radius: var(--radius-lg);
	padding: 1rem;
	outline: none;
}

/* A visible ring when the slider itself is focused, so keyboard users can see
   that the arrow keys will act here. */
.hero__slider:focus-visible {
	outline: 2px solid var(--brand);
	outline-offset: 3px;
}

.hero-slide {
	display: grid;
	grid-template-columns: var(--hero-media) minmax(0, 1fr);
	gap: clamp(1.25rem, 2.5vw, 2.25rem);
	align-items: center;
}

.hero-slide[hidden] {
	display: none;
}

/* Cross-fade the incoming slide. Purely additive: with reduced motion, or
   without JS, the slide simply appears. */
.hero-slide.is-active {
	animation: hero-fade 0.4s var(--ease) both;
}

@keyframes hero-fade {
	from { opacity: 0; transform: translateY(6px); }
	to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
	.hero-slide.is-active { animation: none; }
}

.hero-slide__media {
	display: block;
	position: relative;
	border-radius: var(--radius);
	overflow: hidden;
	/* Wider than the old 4:3 — a lead image reads better landscape, and it
	   balances the copy column at this ratio. */
	aspect-ratio: 3 / 2;
	background: var(--navy-850);
}

.hero-slide__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 0.6s var(--ease);
}

.hero__slider:hover .hero-slide.is-active .hero-slide__img {
	transform: scale(1.03);
}

@media (prefers-reduced-motion: reduce) {
	.hero-slide__img { transition: none; }
	.hero__slider:hover .hero-slide.is-active .hero-slide__img { transform: none; }
}

.hero-slide__chips {
	margin-bottom: 0.15rem;
}

.hero-slide__title {
	font-family: var(--font-display);
	font-size: clamp(1.35rem, 2.4vw, 2rem);
	line-height: 1.18;
	margin: 0.5rem 0 0.6rem;
}

.hero-slide__title a {
	color: var(--ink-100);
	text-decoration: none;
}

.hero-slide__title a:hover {
	color: var(--brand);
}

.hero-slide__excerpt {
	font-size: 0.92rem;
	line-height: 1.65;
	color: var(--ink-400);
	margin: 0 0 0.9rem;
	/* Three lines keeps every slide the same height regardless of how long the
	   excerpt runs, so the card does not jump as slides change. */
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	overflow: hidden;
}

.hero-slide__more {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	font-size: 0.88rem;
	font-weight: 700;
	color: var(--brand);
	text-decoration: none;
}

.hero-slide__more:hover {
	text-decoration: underline;
}

.hero-slide__meta {
	margin-top: 0.85rem;
	font-size: 0.75rem;
	color: var(--ink-500);
}

/* The controls are siblings of the slides (a <button> cannot live inside the
   media's <a>), so a single --hero-media custom property defines the media
   column's share and both the grid and the controls read from it. Change the
   ratio in one place and the arrows and dots follow. */
.hero__slider {
	--hero-media: 51.2%;
	/* Lets the dots centre themselves with auto margins once they go static. */
	display: flex;
	flex-direction: column;
}

.hero-slide__stage {
	position: relative;
	grid-column: 1;
}

.hero__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 38px;
	height: 38px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	color: var(--ink-200);
	background: rgba(255, 255, 255, 0.94);
	border: 1px solid var(--line-soft);
	border-radius: 50%;
	cursor: pointer;
	box-shadow: 0 2px 12px rgba(10, 7, 34, 0.16);
	z-index: 3;
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease;
}

.hero__nav svg {
	width: 18px;
	height: 18px;
	display: block;
}

.hero__nav:hover {
	background: var(--brand);
	border-color: var(--brand);
	color: #fff;
}

.hero__nav:active {
	transform: translateY(-50%) scale(0.94);
}

.hero__nav:focus-visible {
	outline: 2px solid var(--brand);
	outline-offset: 2px;
}

/* --stage-l / --stage-r are written by main.js from the measured stage box, so
   the controls land exactly on the photograph at any width. The fallbacks keep
   them sensible before the script runs and if it never does. */
.hero__nav--prev {
	left: calc(var(--stage-l, 1rem) + 0.6rem);
}

.hero__nav--next {
	left: auto;
	right: calc(var(--stage-r, 50%) + 0.6rem);
}

/* Dots: position indicator and direct jumps. */
/* Dots sit on the photograph itself, bottom-centre, on a translucent pill so
   they stay legible over any image. */
.hero__dots {
	position: absolute;
	/* Centre of the measured stage. */
	left: var(--stage-c, 25%);
	bottom: 1.6rem;
	transform: translateX(-50%);
	display: flex;
	gap: 0.4rem;
	padding: 0.4rem 0.6rem;
	background: rgba(255, 255, 255, 0.92);
	border-radius: var(--radius-pill);
	box-shadow: 0 2px 10px rgba(10, 7, 34, 0.16);
	z-index: 4;
}

.hero__dot {
	width: 8px;
	height: 8px;
	padding: 0;
	border: 0;
	border-radius: var(--radius-pill);
	background: var(--navy-600);
	cursor: pointer;
	transition: width 0.22s var(--ease), background 0.22s ease;
}

.hero__dot:hover {
	background: var(--ink-400);
}

.hero__dot.is-active {
	width: 22px;
	background: var(--brand);
}

.hero__dot:focus-visible {
	outline: 2px solid var(--brand);
	outline-offset: 2px;
}

@media (max-width: 780px) {
	.hero-slide {
		grid-template-columns: minmax(0, 1fr);
		gap: 1rem;
	}

	.hero-slide__media {
		aspect-ratio: 16 / 9;
	}

	/* Stacked, the arrows centre on the image rather than the whole card. */
	.hero__nav {
		top: 28%;
	}

	.hero__nav--prev { left: 1.35rem; }
	.hero__nav--next { left: auto; right: 1.35rem; }

	.hero__slider {
		--hero-media: 100%;
	}

	/* Static below the image, the pill would stretch the full row; keeping it
	   inline-flex and auto-margined shrinks it back to its contents. */
	.hero__dots {
		position: static;
		transform: none;
		display: inline-flex;
		justify-content: center;
		margin: 0.9rem auto 0;
		box-shadow: none;
		background: none;
		padding: 0;
	}

	.hero-slide {
		text-align: initial;
	}

	.hero-slide__body {
		display: flex;
		flex-direction: column;
	}
}

/* ── Market widget ───────────────────────────────────────────────────────────
   Sidebar panel of live quotes. Green/red are reserved for direction here —
   the only place on the site where colour carries meaning rather than brand,
   so both also change the sparkline and are backed by a + / − sign for anyone
   who cannot separate the two hues. */

.market-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.market-row {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 52px auto;
	align-items: center;
	gap: 0.6rem;
	padding: 0.6rem 0;
	border-radius: var(--radius);
}

.market-row + .market-row {
	border-top: 1px solid var(--line-soft);
}

.market-row__id {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

.market-row__label {
	font-size: 0.85rem;
	font-weight: 700;
	color: var(--ink-200);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.market-row__sym {
	font-size: 0.65rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ink-500);
}

.market-row__spark {
	display: block;
	width: 52px;
	height: 22px;
	/* The sparkline paints in currentColor, which the direction rules below set. */
	color: var(--ink-400);
}

.market-row__spark svg {
	display: block;
	width: 100%;
	height: 100%;
	overflow: visible;
}

.market-row__figures {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	white-space: nowrap;
}

.market-row__price {
	font-size: 0.88rem;
	font-weight: 700;
	color: var(--ink-100);
	font-variant-numeric: tabular-nums;
}

.market-row__change {
	font-size: 0.7rem;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

/* Direction. --up/--down are defined here rather than in the token block
   because they are semantic (gain/loss), not part of the brand palette, and
   must not be recoloured by the accent control. */
.market-row {
	--up: #12885A;
	--down: #C2261A;
}

.market-row.is-up .market-row__change,
.market-row.is-up .market-row__spark {
	color: var(--up);
}

.market-row.is-down .market-row__change,
.market-row.is-down .market-row__spark {
	color: var(--down);
}

.market-row.is-flat .market-row__change {
	color: var(--ink-500);
}

/* A quote that actually moved flashes once. */
@keyframes market-tick {
	0%   { background: var(--brand-light, rgba(43, 127, 255, 0.1)); }
	100% { background: transparent; }
}

.market-row.is-tick {
	animation: market-tick 1.1s ease-out;
}

@media (prefers-reduced-motion: reduce) {
	.market-row.is-tick { animation: none; }
}

.market-foot {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	margin: 0.85rem 0 0;
	padding-top: 0.7rem;
	border-top: 1px solid var(--line-soft);
	font-size: 0.68rem;
	color: var(--ink-500);
}

.market-foot__pulse {
	width: 6px;
	height: 6px;
	flex: 0 0 auto;
	border-radius: 50%;
	background: #12885A;
	box-shadow: 0 0 0 0 rgba(18, 136, 90, 0.55);
	animation: market-pulse 2.4s ease-out infinite;
}

@keyframes market-pulse {
	0%   { box-shadow: 0 0 0 0 rgba(18, 136, 90, 0.5); }
	70%  { box-shadow: 0 0 0 6px rgba(18, 136, 90, 0); }
	100% { box-shadow: 0 0 0 0 rgba(18, 136, 90, 0); }
}

@media (prefers-reduced-motion: reduce) {
	.market-foot__pulse { animation: none; }
}

/* ── Static pages (legal, about, contact) ────────────────────────────────────
   These are read top to bottom rather than scanned, so the card is capped at a
   comfortable measure instead of spanning the full grid — which previously left
   a wide empty gutter beside the text. The newsletter band below keeps the full
   container width. */

.page-main .container--narrow {
	/* A little wider than the 760px reading measure: legal pages carry long
	   nested lists that read badly when the indent eats the line. */
	max-width: 860px;
}

.static-page {
	padding: clamp(1.5rem, 4vw, 2.75rem);
}

.page-header__title {
	/* Legal headings are set in caps by the editor; letting them run at display
	   size makes the page shout. */
	font-size: clamp(1.5rem, 3vw, 2.1rem);
	letter-spacing: -0.01em;
}

.page-header {
	padding-bottom: 1.1rem;
	margin-bottom: 1.5rem;
	border-bottom: 1px solid var(--line-soft);
}

.page-header__updated {
	display: block;
	margin-top: 0.4rem;
	font-size: 0.78rem;
	color: var(--ink-500);
}

.page-content {
	font-size: 0.98rem;
	line-height: 1.75;
	color: var(--ink-300);
	/* An earlier rule caps this at 68ch. The card itself is now sized to a
	   reading measure, so the inner cap only produced a gutter inside it. */
	max-width: none;
}

/* Section headings inside the editor content. Legal pages often use plain
   paragraphs as pseudo-headings, so bold text gets a little breathing room. */
.page-content h2,
.page-content h3,
.page-content h4 {
	font-family: var(--font-display);
	color: var(--ink-100);
	line-height: 1.3;
	margin-top: 2rem;
	margin-bottom: 0.6rem;
}

.page-content h2 { font-size: 1.25rem; }
.page-content h3 { font-size: 1.08rem; }
.page-content h4 { font-size: 1rem; }

.page-content > p > strong:only-child {
	display: inline-block;
	margin-top: 0.75rem;
	color: var(--ink-100);
}

.page-content ul,
.page-content ol {
	margin-block: 1rem;
	padding-left: 1.35rem;
}

.page-content li {
	margin-bottom: 0.5rem;
}

.page-content li::marker {
	color: var(--brand);
}

.page-content a {
	color: var(--brand);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.page-content a:hover {
	text-decoration: none;
}

.page-content table {
	width: 100%;
	border-collapse: collapse;
	margin-block: 1.25rem;
	font-size: 0.9rem;
}

.page-content th,
.page-content td {
	padding: 0.6rem 0.75rem;
	border: 1px solid var(--line-soft);
	text-align: left;
	vertical-align: top;
}

.page-content th {
	background: var(--page-bg);
	color: var(--ink-100);
	font-weight: 700;
}

/* Long legal tables should scroll inside the card rather than widen the page. */
.page-content .wp-block-table,
.page-content figure.wp-block-table {
	overflow-x: auto;
}
