/* Hallmark · pre-emit critique: P5 H5 E5 S5 R5 V5 · macrostructure: Ecosystem Index · theme: studied-DNA (source: supplied WisLens screenshots) · nav: N7 contextual · rail: bounded to HD-3 ad band · footer: preserved · contrast: pass (40–41) · slop: pass (42–45) · honest: pass (46) · chrome: pass (47) · tokens: pass (48) · responsive: pass (49) · icons: pass (30) · mobile: pass (34, 49, 50–57) */
/**
 * NEWSTOOM STARTER — COMPONENTS
 * All values reference tokens.css. Rebrand there, not here.
 */

/* ---------------------------------------------------------------- base */
*,
*::before,
*::after { box-sizing: border-box; }

html {
	-webkit-text-size-adjust: 100%;
	overflow-x: clip;
}

body {
	margin: 0;
	font-family: var(--nr-font-body);
	font-size: var(--nr-text-md);
	line-height: var(--nr-leading-body);
	color: var(--nr-color-ink);
	background: var(--nr-color-paper);
	/* Nudge system fonts toward editorial neutrals */
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
	overflow-x: clip;
}

/* Display faces get optical kerning + hung punctuation feel */
h1, h2, h3, h4, .nr-brand__link {
	font-kerning: normal;
}

img,
video { max-width: 100%; height: auto; }

a { color: var(--nr-color-accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--nr-color-ink); }

:focus-visible { outline: 2px solid var(--nr-color-accent); outline-offset: 2px; }

/* OPS-28: long unbreakable tokens (URLs, model names) wrap inside their
   container instead of pushing the viewport horizontally. */
body { overflow-wrap: break-word; }

.screen-reader-text {
	border: 0; clip-path: inset(50%); height: 1px; width: 1px;
	margin: -1px; overflow: hidden; padding: 0; position: absolute; word-wrap: normal !important;
}

.nr-skip-link {
	position: absolute; left: var(--nr-space-4); top: -48px; z-index: 100;
	background: var(--nr-color-ink); color: var(--nr-color-paper);
	padding: var(--nr-space-2) var(--nr-space-4); border-radius: var(--nr-radius-s);
	transition: top var(--nr-transition);
}
.nr-skip-link:focus { top: var(--nr-space-3); color: var(--nr-color-paper); }

/* ------------------------------------------------------------ containers */
/* --------------------------------------------------------- container measure */
.nr-container {
	max-width: var(--nr-container-max);
	margin-inline: auto;
	padding-inline: var(--nr-gutter);
}
.nr-container--narrow { max-width: var(--nr-container-narrow); }

/* Prose measure override: the article column reads at ~66ch regardless of the
   wider narrow container (which also hosts meta rows). Breadcrumbs are scoped
   to the same centered article column on article/page templates only — on
   archive/search they must share the section header's left edge instead. */
/* Single-article axis: breadcrumb, title, standfirst and meta all share the
   prose column (same max-width AND same centering), so every left edge lines
   up on one axis. The lead media frame and its caption stay on the container
   axis (wider, centered) by design. */
.nr-prose,
.nr-single__title,
.nr-single__standfirst,
.nr-single__meta,
.nr-single__kicker,
.nr-single .nr-breadcrumbs,
.nr-page .nr-breadcrumbs {
	width: 100%;
	max-width: var(--nr-prose-measure);
	margin-left: auto;
	margin-right: auto;
}

.nr-main { min-height: 55vh; padding-bottom: var(--nr-section-gap); }

/* ---------------------------------------------------------------- header */
.nr-header {
	background: var(--nr-color-paper);
	border-bottom: 1px solid var(--nr-color-line);
	position: sticky;
	top: 0;
	z-index: 90;
}

.nr-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--nr-space-4);
	min-height: var(--nr-header-height);
	padding-block: 12px;
}

.wl-header__identity {
	display: flex;
	align-items: center;
	min-width: 0;
}

/* WisLens Brand & Wordmark */
.wl-brand {
	display: flex;
	flex-direction: column;
	gap: 2px;
	flex-shrink: 0;
}

.wl-brand__link {
	text-decoration: none;
	display: inline-block;
	line-height: 1;
}

.wl-wordmark {
	font-family: var(--nr-font-display);
	font-size: 1.85rem;
	line-height: 1;
	letter-spacing: -0.025em;
	color: var(--wl-color-primary, #0B0F14);
	display: inline-flex;
	align-items: baseline;
}

.wl-wordmark__wis {
	font-weight: 700;
}

.wl-wordmark__lens {
	font-weight: 300;
}

.wl-wordmark__i {
	position: relative;
	display: inline-block;
}

.wl-wordmark__dot {
	position: absolute;
	top: -0.15em;
	left: 50%;
	transform: translateX(-50%);
	width: 0.22em;
	height: 0.22em;
	background-color: var(--wl-color-accent, #3B82F6);
	border-radius: 50%;
}

.wl-brand__tag {
	font-size: 0.625rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--nr-color-ink-soft, #64748B);
	margin-top: 3px;
	line-height: 1.2;
}

/* Header Navigation & Actions */
.wl-header__nav {
	display: none;
}

.wl-header__actions {
	display: flex;
	align-items: center;
	gap: 12px;
	flex-shrink: 0;
}

.wl-header__search {
	display: flex;
	align-items: center;
	position: relative;
}

.wl-header__search-input {
	width: 148px;
	padding: 7px 14px;
	border: 1px solid var(--nr-color-line);
	border-radius: var(--nr-radius-pill);
	background: var(--nr-color-surface);
	font-size: var(--nr-text-sm);
	font-family: var(--nr-font-body);
	color: var(--nr-color-ink);
	outline: 2px solid transparent;
	outline-offset: 1px;
	transition: background-color var(--nr-transition), border-color var(--nr-transition);
}

.wl-header__search-input:focus {
	border-color: var(--nr-color-line-strong);
	background: var(--nr-color-paper);
	outline-color: var(--nr-color-accent);
}

.wl-header__search-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border: none;
	background: transparent;
	color: var(--nr-color-ink);
	cursor: pointer;
	border-radius: 50%;
	margin-left: -48px;
	z-index: 2;
	transition: color var(--nr-transition);
}

.wl-header__search-btn:hover {
	color: var(--nr-color-accent);
}

.wl-header__search-toggle {
	display: none;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border: 1px solid var(--nr-color-line);
	border-radius: var(--nr-radius-s);
	background: var(--nr-color-surface);
	color: var(--nr-color-ink);
	cursor: pointer;
	padding: 0;
	transition: border-color var(--nr-transition), color var(--nr-transition);
}

.wl-header__search-toggle:hover {
	border-color: var(--nr-color-line-strong);
	color: var(--wl-color-accent, #3B82F6);
}

/* Buttons */
.wl-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	font-family: var(--nr-font-body);
	font-size: 0.875rem;
	font-weight: 600;
	text-decoration: none;
	cursor: pointer;
	border-radius: var(--nr-radius-pill);
	transition: background var(--nr-transition), color var(--nr-transition), transform var(--nr-transition);
	border: none;
	line-height: 1.2;
}

.wl-btn--header-subscribe,
.wl-btn--primary {
	background: var(--wl-color-primary, #0B0F14);
	color: #FFFFFF;
	padding: 9px 20px;
}

.wl-btn--header-subscribe:hover,
.wl-btn--primary:hover {
	background: #1E293B;
	color: #FFFFFF;
}

.wl-btn--block {
	width: 100%;
	padding: 12px 20px;
}

/* Nav toggle button — 44x44 touch target (OPS-180) */
.nr-nav-toggle {
	display: inline-flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	width: 44px;
	height: 44px;
	padding: 0 10px;
	cursor: pointer;
	background: var(--nr-color-surface);
	border: 1px solid var(--nr-color-line);
	border-radius: var(--nr-radius-s);
}

.nr-nav-toggle__bars,
.nr-nav-toggle__bars::before,
.nr-nav-toggle__bars::after {
	content: "";
	display: block;
	width: 22px;
	height: 2px;
	background: var(--nr-color-ink);
	border-radius: 1px;
}

.nr-nav-toggle__bars {
	position: relative;
}

.nr-nav-toggle__bars::before {
	position: absolute;
	top: -6px;
}

.nr-nav-toggle__bars::after {
	position: absolute;
	top: 6px;
}

/* ------------------------------------------------------------ desktop nav */
.nr-nav { display: none; }

/* ------------------------------------------------------------ mobile nav */
.nr-mobile-nav { display: none; background: var(--nr-color-paper); border-bottom: var(--nr-border); }
.nr-mobile-nav:not([hidden]) { display: block; }

.nr-mobile-nav__search {
	display: flex;
	gap: var(--nr-space-2);
	padding: var(--nr-space-4) var(--nr-gutter);
	border-bottom: 1px solid var(--nr-color-line);
}
.nr-mobile-nav__search input {
	flex: 1;
	padding: 10px 14px;
	border: 1px solid var(--nr-color-line);
	border-radius: var(--nr-radius-pill);
	background: var(--nr-color-surface);
	font-size: var(--nr-text-sm);
	font-family: var(--nr-font-body);
	color: var(--nr-color-ink);
	outline: none;
}
.nr-mobile-nav__search input:focus {
	border-color: var(--nr-color-accent);
}
.nr-mobile-nav__search button {
	padding: 10px 18px;
	min-height: 44px;
	border: none;
	border-radius: var(--nr-radius-pill);
	background: var(--wl-color-primary, #0B0F14);
	color: #FFFFFF;
	font-family: var(--nr-font-body);
	font-size: var(--nr-text-sm);
	font-weight: 600;
	cursor: pointer;
	transition: background var(--nr-transition);
}
.nr-mobile-nav__search button:hover {
	background: #1E293B;
}

.wl-mobile-nav__cta {
	padding: var(--nr-space-4) var(--nr-gutter);
	border-top: 1px solid var(--nr-color-line);
}

.nr-mobile-nav__list { list-style: none; margin: 0; padding: var(--nr-space-2) var(--nr-gutter) var(--nr-space-4); }
.nr-mobile-nav__item { border-bottom: var(--nr-border); }
.nr-mobile-nav__row { display: flex; align-items: center; }
.nr-mobile-nav__link {
	flex: 1; display: block; padding: var(--nr-space-3) 0;
	color: var(--nr-color-ink); text-decoration: none; font-size: var(--nr-text-lg); font-family: var(--nr-font-display); font-weight: 700;
}
.nr-mobile-nav__expand {
	width: 44px;
	height: 44px;
	padding: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: none;
	border: 0;
	font-size: var(--nr-text-lg);
	cursor: pointer;
	color: var(--nr-color-ink-soft);
	transition: transform var(--nr-transition);
}
.nr-has-children.is-open > .nr-mobile-nav__row .nr-mobile-nav__expand { transform: rotate(180deg); }
.nr-mobile-nav__sub { display: none; list-style: none; margin: 0 0 var(--nr-space-3); padding: 0 0 0 var(--nr-space-4); }
.nr-has-children.is-open > .nr-mobile-nav__sub { display: block; }
.nr-mobile-nav__sub a {
	display: block; padding: 7px 0; color: var(--nr-color-ink-soft); text-decoration: none; font-size: var(--nr-text-md);
}
.nr-mobile-nav__sub a:hover { color: var(--nr-color-accent); }

/* --------------------------------------------------------------- sections */
.nr-section { padding-top: var(--nr-section-gap); }

.nr-section__header {
	display: flex; align-items: baseline; justify-content: space-between; gap: var(--nr-space-4);
	border-bottom: var(--nr-rule-strong); padding-bottom: var(--nr-space-2); margin-bottom: var(--nr-space-5);
}
.nr-section__title {
	margin: 0; font-family: var(--nr-font-display); font-size: var(--nr-text-h2); line-height: var(--nr-leading-tight);
}
/* Short ink rule above each section title: quiet editorial rhythm without
   adding markup (headings stay h2 for the document outline). */
.nr-section__title::before {
	content: "";
	display: block;
	width: 3.5rem;
	border-top: 3px solid var(--nr-color-ink);
	margin-bottom: var(--nr-space-2);
}
.nr-section__more {
	font-size: var(--nr-text-sm); text-transform: uppercase; letter-spacing: 0.06em;
	text-decoration: none; color: var(--nr-color-ink-soft); white-space: nowrap;
}
.nr-section__more:hover { color: var(--nr-color-accent); }

/* ------------------------------------------------------------------ grids */
.nr-grid { display: grid; gap: var(--nr-space-5) var(--nr-space-4); }
.nr-grid--3 { grid-template-columns: 1fr; }

/* ------------------------------------------------------------------ cards */
.nr-card { display: flex; flex-direction: column; min-width: 0; }
.nr-card__media { display: block; overflow: hidden; border-radius: var(--nr-radius-s); background: var(--nr-color-surface-deep); }
.nr-card__img { display: block; width: 100%; height: 100%; object-fit: cover; aspect-ratio: 16 / 9; transition: transform var(--nr-transition); }
.nr-card__media:hover .nr-card__img { transform: scale(1.02); }

/* Fallback media slot: posts without a featured image keep the same 16:9
   media box as their siblings — a quiet editorial placeholder, not a ghost
   gap and not stock imagery. Purely decorative; the link is aria-hidden
   exactly like a thumbnail link. */
.nr-card__media--fallback { aspect-ratio: 16 / 9; }
.nr-card__fallback {
	display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-end;
	gap: var(--nr-space-1);
	width: 100%; height: 100%;
	padding: var(--nr-space-3);
	background: var(--nr-color-surface-deep);
}
.nr-card__fallback-mark {
	font-family: var(--nr-font-display); font-weight: 700;
	font-size: 1.6rem; line-height: 1; color: var(--nr-color-line-strong);
}
.nr-card__fallback-label {
	font-size: var(--nr-text-xs); font-weight: 700; text-transform: uppercase;
	letter-spacing: 0.08em; color: var(--nr-color-ink-faint);
}

.nr-card__body { display: flex; flex-direction: column; gap: var(--nr-space-2); padding-top: var(--nr-space-3); }

.nr-card__kicker,
.nr-listitem__kicker {
	font-size: var(--nr-text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
	color: var(--nr-color-accent);
}

.nr-card__title { margin: 0; font-family: var(--nr-font-display); font-size: var(--nr-text-card); line-height: 1.28; }

/* Title links underline on hover only — cleaner grid rhythm */
.nr-card__title a { color: var(--nr-color-ink); text-decoration: none; }
.nr-card__title a:hover { color: var(--nr-color-accent); text-decoration: underline; }

.nr-card__excerpt { margin: 0; color: var(--nr-color-ink-soft); font-size: var(--nr-text-sm); line-height: 1.55; }
/* Bounded sapo always ends in a visible affordance, never a bare ellipsis
   (OPS-28): PHP trims the excerpt and appends the "Xem tiếp" link. */
.nr-continue {
	margin-left: 4px;
	color: var(--nr-color-accent);
	font-weight: 700;
	text-decoration: none;
	white-space: nowrap;
}
.nr-continue:hover { text-decoration: underline; }
/* Sapo is a deliberately bounded excerpt: the PHP side trims to the pattern's
   word budget and always follows it with a visible "Xem tiếp" link, so the
   two-line box below is an intentional dek, never the only path to the story
   and never an ambiguous ellipsis (OPS-28 full-title rule). */
.nr-card__excerpt {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Editorial hierarchy: kicker sits under a hairline when it leads a card body */
.nr-card__kicker {
	display: inline-block;
	padding-bottom: 2px;
	border-bottom: 1px solid var(--nr-color-line-strong);
}

/* ---- Shared grid-card rhythm --------------------------------------------
 * Every card in a .nr-grid is one top-aligned column: media slot (featured
 * image or the neutral fallback) → kicker → title (full, natural wrap) →
 * bounded sapo + "Xem tiếp" → meta. The media slot still equalizes card
 * heights; titles no longer contribute a fixed height — a card with a longer
 * stored title grows and its neighbours top-align under it (OPS-28: the
 * complete stored title is always visible; no line clamp, no fixed-height
 * crop, no ellipsis on titles anywhere).
 */
.nr-grid .nr-card__kicker { height: 23px; }
.nr-grid .nr-card__title {
	/* Full title: natural wrapping, no height bound (OPS-28). Long
	   unbreakable tokens stay contained via the global overflow-wrap rule. */
	height: auto; overflow: visible;
	display: block;
}

/* ---- Text-only state (hero/horizontal only) -----------------------------
 * The nr-card--no-media text-only geometry now appears only where a card
 * variant is explicitly designed without a media slot — horizontal rows in
 * text-only layouts. Grid cards always render the fallback media slot instead.
 */
.nr-card--no-media .nr-card__kicker { font-size: var(--nr-text-sm); }
.nr-card--no-media .nr-card__title { font-size: var(--nr-text-h3); }

/* --------------------------------------------------- WisLens Hero Module */
.wl-hero-container {
	padding-top: var(--nr-space-5);
}

.wl-hero {
	width: 100%;
}

.wl-hero__surface {
	position: relative;
	overflow: hidden;
	border-radius: var(--nr-radius-xl, 24px);
	background: #0b0f14;
	min-height: 480px;
	display: flex;
	align-items: stretch;
}

.wl-hero__media-link {
	position: absolute;
	inset: 0;
	z-index: 1;
	text-decoration: none;
}

.wl-hero__media {
	position: absolute;
	inset: 0;
	overflow: hidden;
	display: block;
}

.wl-hero__media img,
.nr-hero-story__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.wl-hero__fallback {
	width: 100%;
	height: 100%;
	background: #141a23;
	display: flex;
	align-items: center;
	justify-content: center;
}

.wl-hero__fallback-mark {
	font-family: var(--nr-font-display);
	font-size: 5rem;
	font-weight: 700;
	color: rgba(255, 255, 255, 0.15);
}

.wl-hero__veil {
	position: absolute;
	inset: 0;
	z-index: 2;
	background: linear-gradient(
		90deg,
		rgba(11, 15, 20, 0.94) 0%,
		rgba(11, 15, 20, 0.82) 42%,
		rgba(11, 15, 20, 0.3) 72%,
		rgba(11, 15, 20, 0) 100%
	);
	pointer-events: none;
}

.wl-hero__content {
	position: relative;
	z-index: 3;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: flex-start;
	gap: 16px;
	padding: 48px 56px;
	max-width: 580px;
	pointer-events: none;
}

.wl-hero__content a,
.wl-hero__content button,
.wl-hero__cta {
	pointer-events: auto;
}

.wl-hero__kicker {
	font-size: 0.75rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: rgba(255, 255, 255, 0.85);
	border: none;
	padding: 0;
	display: inline-block;
}

.wl-hero__title {
	margin: 0;
	font-family: var(--nr-font-display);
	font-size: clamp(1.85rem, 3.4vw, 2.65rem);
	font-weight: 700;
	line-height: 1.22;
	letter-spacing: -0.02em;
}

.nr-hero-story__title-link,
.nr-hero-story__title-text {
	color: #ffffff;
	text-decoration: none;
	display: block;
}

.nr-hero-story__title-link:hover .nr-hero-story__title-text {
	color: #e2e8f0;
}

/* The hero headline link inherits the global accent color; on the near-black
   hero surface that must be the on-dark accent (OPS-215). */
.wl-hero__title-link {
	color: var(--wl-color-accent-on-dark, #60a5fa);
}

.wl-hero__title-link:hover {
	color: #e2e8f0;
}

.wl-hero__excerpt,
.nr-hero-story__excerpt {
	margin: 0;
	font-size: 1.0625rem;
	line-height: 1.55;
	color: rgba(255, 255, 255, 0.82);
	font-weight: 400;
	max-width: 480px;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.wl-hero__cta {
	margin-top: 6px;
}

.wl-btn--hero {
	background: #ffffff;
	color: #0b0f14;
	padding: 11px 24px;
	border-radius: var(--nr-radius-pill);
	font-weight: 600;
	font-size: 0.9375rem;
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
}

.wl-btn--hero:hover {
	background: #f8fafc;
	color: #0b0f14;
	transform: translateY(-1px);
}

/* Style affordance selector for tests */
.nr-hero-story__continue {
	color: var(--nr-color-accent);
}

@media (max-width: 899px) {
	.wl-hero__surface {
		min-height: 420px;
		border-radius: var(--nr-radius-lg, 16px);
	}
	.wl-hero__veil {
		background: linear-gradient(
			180deg,
			rgba(11, 15, 20, 0.2) 0%,
			rgba(11, 15, 20, 0.8) 50%,
			rgba(11, 15, 20, 0.96) 100%
		);
	}
	.wl-hero__content {
		padding: 24px;
		justify-content: flex-end;
		max-width: 100%;
	}
	.wl-hero__title {
		font-size: 1.5rem;
	}
	.wl-hero__excerpt,
	.nr-hero-story__excerpt {
		font-size: 0.9375rem;
	}
}

/* -------------------------------------------------- WisLens Latest Module */
.wl-latest {
	padding-top: var(--nr-space-7);
	padding-bottom: var(--nr-space-4);
}

.wl-latest__header {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--nr-space-4);
	margin-bottom: var(--nr-space-5);
}

.wl-latest__title {
	margin: 0;
	font-family: var(--nr-font-display);
	font-size: 1.5rem;
	font-weight: 700;
	color: var(--nr-color-ink);
	letter-spacing: -0.01em;
}

.wl-latest__more {
	font-size: 0.9375rem;
	font-weight: 500;
	color: var(--nr-color-ink-soft);
	text-decoration: none;
	display: inline-flex;
	align-items: center;
	gap: 4px;
	transition: color var(--nr-transition);
}

.wl-latest__more:hover {
	color: var(--nr-color-accent);
}

.wl-latest__grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 24px;
}

.wl-latest-card {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

.wl-latest-card__media-link {
	display: block;
	text-decoration: none;
}

.wl-latest-card__media {
	display: block;
	overflow: hidden;
	border-radius: var(--nr-radius, 12px);
	aspect-ratio: 16 / 9;
	background: var(--nr-color-surface-deep);
}

.wl-latest-card__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--nr-transition);
}

.wl-latest-card:hover .wl-latest-card__media img {
	transform: scale(1.03);
}

.wl-latest-card__body {
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding-top: 12px;
}

.wl-latest-card__category {
	font-size: 0.75rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--nr-color-ink-soft);
	border: none;
	padding: 0;
	display: inline-block;
}

.wl-latest-card__title {
	margin: 0;
	font-family: var(--nr-font-display);
	font-size: 1.0625rem;
	font-weight: 600;
	line-height: 1.35;
	letter-spacing: -0.01em;
}

.wl-latest-card__title a {
	color: var(--nr-color-ink);
	text-decoration: none;
	transition: color var(--nr-transition);
}

.wl-latest-card__title a:hover {
	color: var(--nr-color-accent);
}

.wl-latest-card__date {
	font-size: 0.8125rem;
	color: var(--nr-color-ink-faint);
	margin-top: 2px;
}

@media (min-width: 720px) and (max-width: 1019px) {
	.wl-latest__grid {
		grid-template-columns: repeat(2, 1fr);
		gap: 20px;
	}
}

@media (max-width: 719px) {
	.wl-latest__grid {
		display: flex;
		flex-direction: column;
		gap: 0;
	}
	.wl-latest-card {
		display: flex;
		flex-direction: row;
		align-items: center;
		gap: 16px;
		padding-block: 16px;
		border-bottom: 1px solid var(--nr-color-line);
	}
	.wl-latest-card:last-child {
		border-bottom: none;
	}
	.wl-latest-card__media-link {
		flex-shrink: 0;
		width: 96px;
		height: 72px;
	}
	.wl-latest-card__media {
		width: 96px;
		height: 72px;
		border-radius: var(--nr-radius-s, 8px);
		aspect-ratio: auto;
	}
	.wl-latest-card__body {
		flex: 1;
		min-width: 0;
		padding-top: 0;
		gap: 4px;
	}
	.wl-latest-card__category {
		font-size: 0.6875rem;
		font-weight: 700;
	}
	.wl-latest-card__title {
		font-size: 0.9375rem;
		font-weight: 600;
		line-height: 1.35;
	}
	.wl-latest-card__date {
		font-size: 0.75rem;
	}
}

/* ------------------------------------------------ WisLens Spotlight (HD-1=A)
 * ONE module, 1 main story (left, approved cinematic surface) + 3 secondary
 * stories (right cluster). Supersedes the standalone-Hero + Latest-4 top
 * structure; hero surface/veil/overlay rules above carry forward unchanged.
 * Secondary titles use a deliberate 2-line clamp (HD-4=T-B): the FULL title
 * always remains in the DOM as the accessible name — the clamp is visual
 * presentation only.
 */
.wl-spotlight-container {
	padding-top: var(--nr-space-5);
}

.wl-spotlight {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--nr-space-5);
}

.wl-spotlight__main {
	min-width: 0;
}

/* Secondary cluster: 3 compact cards. Deliberate rows: hairline dividers
   apply at base level too (tablet stacks the whole module single-column
   below 1200px, mirroring the utility-rail breakpoint). */
.wl-spotlight__secondary {
	display: grid;
	gap: var(--nr-space-4);
	align-content: start;
	min-width: 0;
}

.wl-spotlight-card + .wl-spotlight-card {
	border-top: 1px solid var(--nr-color-line);
	padding-top: var(--nr-space-4);
}

.wl-spotlight-card {
	display: grid;
	grid-template-columns: 128px minmax(0, 1fr);
	gap: var(--nr-space-4);
	align-items: center;
	min-width: 0;
}

.wl-spotlight-card__media-link {
	display: block;
	width: 128px;
	text-decoration: none;
	min-width: 0;
}

.wl-spotlight-card__media {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
	border-radius: var(--nr-radius-s);
	overflow: hidden;
	background: var(--nr-color-surface-deep);
}

.wl-spotlight-card__media img,
.wl-spotlight-card__media .nr-hero-story__img,
.wl-spotlight-card__media .nr-card__fallback {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	aspect-ratio: auto;
}

.wl-spotlight-card__body {
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding-top: 2px;
	min-width: 0;
}

.wl-spotlight-card__kicker {
	font-size: 0.75rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--nr-color-ink-soft);
}

.wl-spotlight-card__title {
	margin: 0;
	font-family: var(--nr-font-display);
	font-size: 1.0625rem;
	font-weight: 600;
	line-height: 1.35;
	letter-spacing: -0.01em;
	/* HD-1 deliberate rows: reserve the 2-line block so a one-line title
	   never shortens the card (no random heights). */
	min-height: 2.7em;
	/* HD-4=T-B scoped clamp: visual only; full title stays in the DOM. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.wl-spotlight-card__title a {
	color: var(--nr-color-ink);
	text-decoration: none;
}

.wl-spotlight-card__title a:hover {
	color: var(--nr-color-accent);
}

.wl-spotlight-card__date {
	font-size: 0.8125rem;
	color: var(--nr-color-ink-faint);
}

@media (min-width: 1200px) {
	.wl-spotlight {
		/* 2-column image matrix: lead ~63% / secondary ~37%, shared height. */
		grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
		gap: var(--nr-space-4);
		align-items: stretch;
	}
	.wl-spotlight__main {
		height: 100%;
	}
	.wl-spotlight__main .wl-hero__surface {
		min-height: 0;
		height: auto;
		/* The lead grows just enough to pay for the breathing room between
		   secondary stories; each right-hand card keeps its visual measure. */
		aspect-ratio: 5 / 3;
	}
	.wl-spotlight__secondary {
		display: grid;
		grid-template-rows: repeat(3, minmax(0, 1fr));
		align-content: stretch;
		gap: var(--nr-space-3);
		height: 100%;
		padding: 0;
		min-height: 0;
	}
	.wl-spotlight-card {
		position: relative;
		display: block;
		overflow: hidden;
		isolation: isolate;
		height: 100%;
		min-height: 0;
		grid-template-columns: none;
		gap: 0;
		background: #141a23;
		border-radius: var(--nr-radius-md);
	}
	.wl-spotlight-card + .wl-spotlight-card {
		border-top: 0;
		padding-top: 0;
		box-shadow: none;
	}
	.wl-spotlight-card::after {
		content: "";
		position: absolute;
		inset: 0;
		z-index: 2;
		pointer-events: none;
		background: linear-gradient(
			to top,
			rgba(11, 15, 20, 0.88) 0%,
			rgba(11, 15, 20, 0.55) 42%,
			rgba(11, 15, 20, 0.12) 72%,
			rgba(11, 15, 20, 0) 100%
		);
	}
	.wl-spotlight-card__media-link {
		position: absolute;
		inset: 0;
		width: auto;
		height: auto;
		z-index: 1;
	}
	.wl-spotlight-card__media,
	.wl-spotlight-card__media.nr-card__media--fallback {
		position: absolute;
		inset: 0;
		width: 100%;
		height: 100%;
		aspect-ratio: auto;
		border-radius: inherit;
		background: #141a23;
	}
	.wl-spotlight-card__media img,
	.wl-spotlight-card__media .nr-hero-story__img,
	.wl-spotlight-card__media .nr-card__fallback {
		position: absolute;
		inset: 0;
		width: 100%;
		height: 100%;
		object-fit: cover;
	}
	.wl-spotlight-card__media .nr-card__fallback {
		justify-content: flex-start;
		align-items: center;
		padding: 12% 0 0;
		background: #141a23;
	}
	.wl-spotlight-card__media .nr-card__fallback-mark {
		font-size: 2.25rem;
		color: rgba(255, 255, 255, 0.14);
	}
	.wl-spotlight-card__media .nr-card__fallback-label {
		display: none;
	}
	.wl-spotlight-card__body {
		position: absolute;
		inset: 0;
		z-index: 3;
		display: flex;
		flex-direction: column;
		justify-content: flex-end;
		gap: 4px;
		padding: var(--nr-space-4);
		min-height: 0;
		pointer-events: none;
	}
	.wl-spotlight-card__kicker {
		color: rgba(255, 255, 255, 0.82);
	}
	.wl-spotlight-card__title {
		min-height: 0;
		font-size: 1rem;
		line-height: 1.3;
		color: #ffffff;
	}
	.wl-spotlight-card__title a {
		color: #ffffff;
		pointer-events: auto;
	}
	.wl-spotlight-card__title a:hover {
		color: #ffffff;
	}
	.wl-spotlight-card__date {
		font-size: 0.75rem;
		color: rgba(255, 255, 255, 0.72);
	}
}

/* Mobile: main first, then compact secondary rows (full-width thumbs above
   text kept small; matches the approved compact-row pattern). */
@media (max-width: 719px) {
	.wl-spotlight {
		gap: var(--nr-space-5);
	}
	.wl-spotlight-card {
		grid-template-columns: 96px minmax(0, 1fr);
		gap: 12px;
	}
	.wl-spotlight-card__media-link {
		width: 96px;
	}
	.wl-spotlight-card__title {
		font-size: 0.9375rem;
	}
	.wl-spotlight-card + .wl-spotlight-card {
		border-top: 1px solid var(--nr-color-line);
		padding-top: var(--nr-space-4);
	}
}

/* ------------------------------------------------ News mixed (handoff §2)
 * 1 lead card + compact headline rows: high density, mixed hierarchy.
 */
.nr-news-mixed {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--nr-space-5);
}

.nr-news-mixed__lead-title {
	font-size: var(--nr-text-h3);
}

/* Compact rows reuse the nr-list--compact geometry; titles get the T-B
 * scoped clamp (visual only — full titles stay in the DOM). */
.nr-news-mixed__items {
	border-top: var(--nr-border);
}
.nr-news-mixed__item-title {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

@media (min-width: 1020px) {
	.nr-news-mixed {
		grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
		gap: var(--nr-space-6);
	}
}

/* ------------------------------------------------ Reviews mixed (handoff §2)
 * 1 lead review + secondary cluster; the two regions pair baselines via
 * top-aligned rows with bounded text slots.
 */
.nr-reviews-mixed {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--nr-space-5);
}

.nr-reviews-mixed__lead-title {
	font-size: var(--nr-text-h3);
}

.nr-reviews-mixed__secondary {
	display: grid;
	gap: var(--nr-space-4);
	align-content: start;
}

.nr-reviews-mixed__secondary-card {
	display: grid;
	grid-template-columns: 128px 1fr;
	gap: var(--nr-space-4);
	align-items: start;
	padding-top: var(--nr-space-4);
	border-top: var(--nr-border);
	min-width: 0;
}

.nr-reviews-mixed__secondary-card:first-child {
	border-top: 0;
	padding-top: 0;
}

.nr-reviews-mixed__secondary-title {
	/* HD-4=T-B scoped clamp: visual only; full title stays in the DOM. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-size: 1rem;
}

.nr-reviews-mixed__secondary-date {
	font-size: var(--nr-text-xs);
	color: var(--nr-color-ink-faint);
}

.nr-reviews-mixed__secondary-body {
	display: flex;
	flex-direction: column;
	gap: 4px;
	min-width: 0;
}

@media (min-width: 1020px) {
	.nr-reviews-mixed {
		grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
		gap: var(--nr-space-6);
	}
	.nr-reviews-mixed__secondary-card {
		grid-template-columns: 168px 1fr;
	}
}

@media (max-width: 719px) {
	.nr-reviews-mixed__secondary-card {
		grid-template-columns: 96px 1fr;
		gap: 12px;
	}
}

/* ------------------------------------------------ Góc cà phê rhythm (handoff §2)
 * Modestly airier spacing on the compact feed ONLY (no new typography, no
 * separate art direction). Scoped via the section id the engine already
 * emits (data-newsroom-section="goc-ca-phe") — coupling is config-driven.
 */
.nr-section[data-newsroom-section="goc-ca-phe"] .nr-list--compact .nr-listitem__inner {
	padding-block: var(--nr-space-4);
}
.nr-section[data-newsroom-section="goc-ca-phe"] .nr-list--compact .nr-listitem__title {
	font-size: var(--nr-text-md);
}

/* ------------------------------------------------ Homepage bottom ad band (HD-3)
 * Three INDEPENDENT small slots. Only filled slots render (PHP side), so the
 * grid holds exactly the creatives that exist: 3-up wide, stack otherwise.
 */
.nr-ad-row {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--nr-space-3);
	margin-block: var(--nr-space-4) var(--nr-space-5);
}
/* The row owns the band styling: its slot children override the standalone
   nr-ad margins (the :empty collapse still applies to empty creatives, but
   the PHP side only renders filled slots inside the row anyway). */
.nr-ad-row .nr-ad:not(:empty) {
	margin-block: 0;
}
@media (min-width: 720px) {
	.nr-ad-row {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}
@media (min-width: 1020px) {
	.nr-ad-row {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/* ------------------------------------------------ Homepage shell + rail (HD-2=S-B)
 * Main editorial flow + desktop utility rail. The rail is an independent
 * sibling (align-self: start) — main content never depends on rail height.
 * Below 1200px the shell is a pass-through (sections keep their own
 * containers); at >= 1200px the shell BECOMES the container measure and the
 * nested section containers lose their horizontal padding, so every left
 * edge stays on one axis. The rail carries the newsletter on wide desktop;
 * the inline band renders only below — exactly one newsletter per viewport.
 */
.wl-home-shell {
	display: block;
}

.wl-home-main {
	min-width: 0;
}

/* The first category follows the top banner without inheriting a full generic
   section gap. This keeps the homepage cadence compact while later category
   groups retain the standard editorial separation. */
.wl-home-main > .nr-section:first-child {
	padding-top: var(--nr-space-5);
}

.wl-home-rail {
	display: none; /* hidden below the rail breakpoint */
}

.wl-home-rail__sticky {
	min-width: 0;
}

.wl-rail-module {
	background: var(--nr-color-surface);
	border: 1px solid var(--nr-color-line);
	border-radius: var(--nr-radius-lg, 20px);
	padding: var(--nr-space-5);
	margin-bottom: var(--nr-space-5);
}

.wl-rail-module__title {
	margin: 0 0 var(--nr-space-4);
	font-size: 0.75rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--nr-color-ink-soft);
}

/* Popular: compact numbered rows; T-B scoped clamp, full titles in DOM. */
.wl-rail-popular__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--nr-space-3);
	counter-reset: wl-popular;
}

.wl-rail-popular__item {
	counter-increment: wl-popular;
	display: flex;
	gap: var(--nr-space-3);
	align-items: baseline;
	min-width: 0;
}

.wl-rail-popular__item::before {
	content: counter(wl-popular, decimal-leading-zero);
	font-family: var(--nr-font-display);
	font-size: 1rem;
	font-weight: 700;
	color: var(--nr-color-accent);
	flex-shrink: 0;
}

.wl-rail-popular__link {
	color: var(--nr-color-ink);
	text-decoration: none;
	font-weight: 600;
	font-size: var(--nr-text-sm);
	line-height: 1.4;
	/* HD-4=T-B scoped clamp: visual only; full title stays in the DOM. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.wl-rail-popular__link:hover {
	color: var(--nr-color-accent);
}

/* Rail newsletter: compact form reusing the shared input/button styles. */
.wl-rail-newsletter__desc {
	margin: 0 0 var(--nr-space-3);
	font-size: var(--nr-text-sm);
	line-height: 1.5;
	color: var(--nr-color-ink-soft);
}

.wl-rail-newsletter__form {
	display: flex;
	flex-direction: column;
	gap: var(--nr-space-2);
}

/* Rail ad: sits in the module rhythm; the standalone margins collapse. */
.wl-home-rail .nr-ad:not(:empty) {
	margin-block: 0 var(--nr-space-5);
}

/* OPS-168: ONLY homepage-sidebar-1 receives the taller local demo frame —
   a 300×600-style portrait inside the 320px desktop rail column. Scoped to
   the slot attribute + the rail's desktop breakpoint (the rail is display:none
   below it, so no mobile ad band exists). No global .nr-ad min-height is
   imposed; other slots keep the primitive's base rhythm. Empty creatives
   still emit no markup at all (newsroom_ad_slot() fail-closed). */
@media (min-width: 1200px) {
	.wl-home-rail .nr-ad[data-newsroom-ad="homepage-sidebar-1"]:not(:empty) {
		aspect-ratio: 1 / 2;
		min-height: 0;
		width: 100%;
	}
	/* Same fill mechanism as the single rail: the breakpoint-swap wrapper is
	   the flex parent a stretch-filled creative needs. */
	.wl-home-rail .nr-ad[data-newsroom-ad="homepage-sidebar-1"]:not(:empty) .nr-ad__desktop {
		display: flex;
		align-items: stretch;
		height: 100%;
	}
	.wl-home-rail .nr-ad[data-newsroom-ad="homepage-sidebar-1"]:not(:empty) .nr-ad__mobile {
		height: 100%;
	}
}

[data-newsroom-subscribe-target] {
	scroll-margin-top: 96px;
}

@media (min-width: 1200px) {
	.wl-home-shell {
		display: grid;
		grid-template-columns: minmax(0, 1fr) 320px;
		gap: var(--nr-space-6);
		max-width: var(--nr-container-max);
		margin-inline: auto;
		padding-inline: var(--nr-gutter);
	}
	/* The shell owns the gutter on rail viewports: nested section/newsletter
	   containers become pass-through so all left edges share one axis. */
	.wl-home-main .nr-container,
	.wl-newsletter-inline-wrap .nr-container {
		padding-inline: 0;
	}
	/* Keep the list's operational edge inside the main column. The More link
	   and dates therefore keep a deliberate gutter away from the utility rail. */
	.wl-home-main > .nr-section .nr-section__header,
	.wl-home-main > .nr-section .nr-list--media .nr-listitem__inner {
		padding-inline-end: var(--nr-space-5);
	}
	/* The rail's containing shell shares the bottom edge of the actual
	   creatives, not the decorative space that follows them. */
	.wl-ad-band-container .nr-ad-row {
		margin-bottom: 0;
	}
	.wl-home-rail {
		display: block;
		align-self: stretch;
		padding-top: var(--nr-space-5);
	}
	.wl-home-rail__sticky {
		position: sticky;
		top: calc(var(--nr-header-height) + var(--nr-space-4));
	}
	.wl-home-rail__sticky > :last-child {
		margin-bottom: 0;
	}
	/* Exactly one newsletter per viewport: rail carries it on wide
	   desktop; the inline band (and its wrapper) is hidden here. */
	.wl-newsletter-inline-wrap {
		display: none;
	}
}

/* ------------------------------------------------ WisLens Inline Newsletter */
.wl-newsletter-container {
	padding-block: var(--nr-space-7);
}

.wl-newsletter {
	background: var(--nr-color-surface);
	border: 1px solid var(--nr-color-line);
	border-radius: var(--nr-radius-xl, 24px);
	padding: 48px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 40px;
}

.wl-newsletter__body {
	max-width: 520px;
}

.wl-newsletter__kicker {
	font-size: 0.75rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--wl-color-accent, #2563eb);
	display: inline-block;
}

.wl-newsletter__title {
	margin: 6px 0 10px;
	font-family: var(--nr-font-display);
	font-size: 1.65rem;
	font-weight: 700;
	color: var(--nr-color-ink);
	letter-spacing: -0.015em;
}

.wl-newsletter__desc {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.55;
	color: var(--nr-color-ink-soft);
}

.wl-newsletter__form {
	display: flex;
	flex-direction: column;
	gap: 8px;
	width: min(100%, 380px);
	flex-shrink: 0;
}

.wl-newsletter__input-row {
	display: flex;
	gap: 8px;
	/* Small phones: stack input + button so nothing can overflow 320px. */
	flex-wrap: wrap;
}
.wl-newsletter__input-row .wl-newsletter__input {
	min-width: 0;
}
.wl-newsletter__input-row .wl-newsletter__submit {
	flex: 0 0 auto;
}

.wl-newsletter__input {
	flex: 1;
	padding: 11px 16px;
	border: 1px solid var(--nr-color-line);
	border-radius: var(--nr-radius-pill);
	font-size: 0.875rem;
	font-family: var(--nr-font-body);
	background: var(--nr-color-paper);
	color: var(--nr-color-ink);
	outline: none;
}

.wl-newsletter__input:focus {
	border-color: var(--nr-color-accent);
}

.wl-newsletter__submit {
	padding: 11px 22px;
	flex-shrink: 0;
}

.wl-newsletter__notice {
	margin: 0;
	font-size: 0.75rem;
	color: var(--nr-color-ink-faint);
}

@media (max-width: 820px) {
	.wl-newsletter {
		flex-direction: column;
		align-items: flex-start;
		padding: 28px;
		gap: 24px;
		border-radius: var(--nr-radius-lg, 16px);
	}
	.wl-newsletter__form {
		width: 100%;
	}
}

/* horizontal variant: image-left rows. Explicit two-column geometry:
   fixed media column + fluid content column; media keeps its own 16:9 box. */
.nr-card--horizontal {
	display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: var(--nr-space-3);
	padding-block: var(--nr-space-4); border-top: var(--nr-border);
	align-items: start;
}
.nr-hcards { margin-bottom: 0; }
.nr-hcards .nr-card--horizontal:first-child { border-top: 0; padding-top: 0; }
.nr-card--horizontal .nr-card__media { align-self: start; margin-top: 4px; }
.nr-card--horizontal .nr-card__img { aspect-ratio: 16 / 9; height: auto; }
.nr-card--horizontal .nr-card__body { padding-top: 0; }
.nr-card--horizontal .nr-card__title { font-size: var(--nr-text-h3); }
@media (min-width: 720px) {
	.nr-card--horizontal { grid-template-columns: 240px minmax(0, 1fr); gap: var(--nr-space-4); }
}
/* No featured image: text spans the full row, no ghost column */
.nr-card--horizontal.nr-card--no-media { grid-template-columns: 1fr; }

/* ------------------------------------------------------------------ lists */
.nr-list { margin: 0; padding: 0; list-style: none; }
.nr-list--plain .nr-listitem__inner {
	display: flex; justify-content: space-between; gap: var(--nr-space-4);
	padding-block: var(--nr-space-3); border-bottom: var(--nr-border);
}
.nr-listitem__title { margin: 0 0 2px; font-family: var(--nr-font-display); font-size: var(--nr-text-lg); line-height: 1.35; }
.nr-listitem__title a { color: var(--nr-color-ink); text-decoration: none; }
.nr-listitem__title a:hover { color: var(--nr-color-accent); }
.nr-listitem__excerpt { margin: 4px 0 0; color: var(--nr-color-ink-soft); font-size: var(--nr-text-sm); }
.nr-listitem__meta { flex-shrink: 0; font-size: var(--nr-text-xs); color: var(--nr-color-ink-faint); padding-top: 6px; }

.nr-list--compact .nr-listitem__inner {
	display: flex; align-items: baseline; gap: var(--nr-space-3);
	padding-block: var(--nr-space-2); border-bottom: var(--nr-border);
}
/* Explicit three-column geometry: kicker | title | date. The date column is
   fixed-width so timestamps form a stable column regardless of title length. */
.nr-list--compact .nr-listitem__kicker { display: inline-block; flex-shrink: 0; width: 110px; text-align: left; }
.nr-list--compact .nr-listitem__title { font-size: var(--nr-text-md); font-family: var(--nr-font-body); font-weight: 600; }
.nr-list--compact .nr-listitem__meta { padding-top: 0; }
/* Title takes the flexible middle; date is a fixed right-aligned column that
   pins to the row's right edge regardless of title length. */
.nr-list--compact .nr-listitem__main { flex: 1 1 auto; min-width: 0; }
.nr-list--compact .nr-listitem__meta { flex-shrink: 0; width: 96px; text-align: right; white-space: nowrap; }

/* Plain list (guides' sibling layout): same fixed date column so every
   date-bearing list shares one alignment system. */
.nr-list--plain .nr-listitem__meta { flex-shrink: 0; width: 96px; text-align: right; white-space: nowrap; }

/* Narrow screens: the fixed date column would crush the title, so rows
   collapse to a two-line layout — title on top, date under it. */
@media (max-width: 719px) {
	.nr-list--plain .nr-listitem__inner { display: block; }
	.nr-list--plain .nr-listitem__meta { width: auto; text-align: left; padding-top: 4px; }
	.nr-list--compact .nr-listitem__inner { flex-wrap: wrap; }
	.nr-list--compact .nr-listitem__kicker { width: auto; }
	.nr-list--compact .nr-listitem__main { flex: 1 1 100%; order: 3; }
	.nr-list--compact .nr-listitem__meta { width: auto; text-align: left; order: 2; margin-left: auto; }
}

/* ------------------------------------------------ thumbnail-led rows */
/* Hi-Fi (latest-list) and Guides & Explainers (compact-feed) opt into media
   rows via nr-list--media + newsroom_list_item( show_media ). Every row keeps
   the same 16:9 media slot as cards — a real thumbnail from the existing
   newsroom-card crop, or the shared neutral fallback — so a story never
   renders a blank or collapsed media box. Rows stay lists (not grids), so a
   media slot never forces synthetic margins onto text-only siblings
   elsewhere: lists without nr-list--media are untouched. The text column
   stays flexible (min-width: 0) and headlines clamp, so long titles wrap
   predictably instead of pushing the row wider. */
.nr-list--media .nr-listitem__inner {
	display: flex; align-items: flex-start; gap: var(--nr-space-4);
	padding-block: var(--nr-space-3); border-bottom: var(--nr-border);
}
.nr-listitem__media { flex-shrink: 0; width: 112px; }
.nr-listitem__media .nr-card__fallback { padding: var(--nr-space-2); }
.nr-listitem__media .nr-card__fallback-mark { font-size: 1.1rem; }
.nr-list--media .nr-listitem__main { flex: 1 1 0; min-width: 0; }
/* Same fixed 96px date column as the other date-bearing lists. */
.nr-list--media .nr-listitem__meta { flex-shrink: 0; width: 96px; text-align: right; white-space: nowrap; }
/* Full title in media rows (OPS-28): titles wrap naturally with no clamp; the
   sapo stays a bounded two-line dek followed by the visible "Xem tiếp" link
   from the PHP side, so row rhythm survives without hiding any title text. */
.nr-list--media .nr-listitem__title { display: block; }
.nr-list--media .nr-listitem__excerpt {
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
	margin-top: 2px;
}

@media (min-width: 720px) {
	.nr-listitem__media { width: 128px; }
}
@media (min-width: 900px) {
	.nr-listitem__media { width: 168px; }
}
/* Tablet/mobile (OPS-24): the text column (kicker + clamped title + sapo) is
   usually taller than the media slot, so a top-aligned thumb leaves all the
   slack under it and the row reads lopsided. Centering the media against the
   text keeps the row balanced. Desktop keeps its approved top-aligned
   geometry; the date column stays top-right / below the text on narrow
   screens, unchanged. */
@media (max-width: 899px) {
	.nr-list--media .nr-listitem__media { align-self: center; }
}
/* Narrow screens: the thumbnail leads the row at a compact size, the text
   column takes the remaining width, and the date drops under the headline
   (overriding the no-media wrap rules above, which assume no media node). */
@media (max-width: 719px) {
	.nr-list--media .nr-listitem__inner { flex-wrap: wrap; }
	.nr-list--media .nr-listitem__main { flex: 1 1 0; order: 0; }
	.nr-list--media .nr-listitem__meta { order: 0; flex-basis: 100%; width: auto; margin-left: 0; padding-top: 4px; text-align: left; }
}

/* ------------------------------------------------------------------- meta */
.nr-meta {
	display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--nr-space-2);
	font-size: var(--nr-text-xs); color: var(--nr-color-ink-faint);
}
.nr-meta > *:not(:first-child)::before { content: "·"; margin-right: var(--nr-space-2); color: var(--nr-color-line-strong); }
.nr-meta a { color: inherit; text-decoration: none; }
.nr-meta a:hover { color: var(--nr-color-accent); text-decoration: underline; }

/* ------------------------------------------------------------ breadcrumbs */
/* Context line: one step above caption size, still clearly subordinate to the
   archive title and the SECTION kicker (which stays 700/accent/uppercase). */
.nr-breadcrumbs { margin-block: 0 var(--nr-space-4); }
.nr-breadcrumbs ol {
	list-style: none; display: flex; flex-wrap: wrap; gap: var(--nr-space-2);
	margin: 0; padding: 0;
	font-size: var(--nr-text-sm); line-height: 1.5;
	color: var(--nr-color-ink-soft); font-weight: 500;
}
.nr-breadcrumbs li { display: flex; gap: var(--nr-space-2); align-items: baseline; }
.nr-breadcrumbs li + li::before { content: "›"; color: var(--nr-color-line-strong); }
.nr-breadcrumbs li[aria-current="page"] { color: var(--nr-color-ink-faint); font-weight: 400; }
.nr-breadcrumbs a { color: var(--nr-color-ink); text-decoration: none; }
.nr-breadcrumbs a:hover { color: var(--nr-color-accent); text-decoration: underline; }

/* ---------------------------------------------------------------- archives */
.nr-archive__header { margin-bottom: var(--nr-space-6); }
.nr-archive__kicker,
.nr-single__kicker {
	margin: 0 0 var(--nr-space-2); font-size: var(--nr-text-xs); font-weight: 700;
	text-transform: uppercase; letter-spacing: 0.08em; color: var(--nr-color-accent);
}
.nr-archive__title { margin: 0; font-family: var(--nr-font-display); font-size: var(--nr-text-h1); line-height: var(--nr-leading-tight); }
.nr-archive__description { margin-top: var(--nr-space-3); color: var(--nr-color-ink-soft); max-width: 62ch; }
.nr-archive__author { display: flex; gap: var(--nr-space-4); align-items: center; margin-top: var(--nr-space-4); }
.nr-archive__author img { border-radius: 50%; }
.nr-archive__author p { margin: 0; color: var(--nr-color-ink-soft); }
.nr-archive__count { color: var(--nr-color-ink-faint); font-size: var(--nr-text-sm); }

/* ------------------------------------------------------------------ single */
.nr-single { padding-top: var(--nr-space-2); }
.nr-badge {
	display: inline-block; padding: 2px 8px; border-radius: var(--nr-radius-s);
	background: var(--nr-color-accent-soft); color: var(--nr-color-accent);
	font-size: var(--nr-text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; text-decoration: none;
}
/* OPS-168 shared Single contract: the pre-title row carries the content-type
   badge and nothing else (no category/section label beside it — the breadcrumb
   trail is the category context). Breadcrumb → badge keeps the breadcrumb's
   own --nr-space-4 step; the badge → H1 step is one token tighter
   (--nr-space-3) so the row reads as part of the title block. Untyped posts
   emit no row at all, so crumb → H1 collapses to the single 16px step with no
   ghost gap (the row's own margin simply does not exist). */
.nr-single .nr-single__kicker { margin-bottom: var(--nr-space-3); }

.nr-single__title {
	margin: var(--nr-space-2) 0 var(--nr-space-3);
	/* OPS-152 D2 (locked): Newsreader is the controlled editorial emphasis on
	   the Single H1 only; deck, kicker, meta and cards stay Be Vietnam Pro. */
	font-family: var(--nr-font-editorial); font-size: var(--nr-text-h1); line-height: var(--nr-leading-tight); letter-spacing: -0.01em;
	/* OPS-224: the article H1 reads at the article prose measure (42rem) —
	   the same usable measure as the article content/meta rule — instead of
	   the 22ch display-heading cap, and wraps naturally: no text-wrap:
	   balance and no manual <br>, so a long Vietnamese title uses the full
	   article column. */
	max-width: var(--nr-prose-measure);
}
.nr-single__standfirst {
	margin: 0 0 var(--nr-space-4); font-family: var(--nr-font-display);
	font-size: var(--nr-text-lg); line-height: 1.5; color: var(--nr-color-ink-soft);
	max-width: 56ch;
	text-wrap: pretty;
}
.nr-single-bodyhead {
	margin-bottom: var(--nr-space-5);
}
.nr-single__meta {
	display: flex; flex-wrap: wrap; gap: var(--nr-space-3);
	padding-block: var(--nr-space-3); border-top: var(--nr-border); border-bottom: var(--nr-border);
	font-size: var(--nr-text-sm); color: var(--nr-color-ink-soft);
}
.nr-single__byline a { font-weight: 600; color: var(--nr-color-ink); text-decoration: none; }
.nr-single__byline a:hover { color: var(--nr-color-accent); }

/* Lead media: ONE presentation canvas for every article type. The frame is
   the 16:9 rendition contract from the approved baseline; the source image is
   letterboxed with object-fit: contain so no original pixels are cropped.
   Regular single, no-image single and awkward-gallery fixtures all share it. */
.nr-single__hero { margin-block: var(--nr-space-5); }
.nr-single__hero .nr-single__hero-frame {
	position: relative;
	aspect-ratio: 16 / 9;
	background: var(--nr-color-surface-deep);
	border-radius: var(--nr-radius, 12px);
	overflow: hidden;
}
.nr-single__hero .nr-single__hero-frame img {
	width: 100%;
	height: 100%;
	display: block;
	object-fit: contain;
}
.nr-single__hero figcaption {
	font-size: var(--nr-text-xs); color: var(--nr-color-ink-faint);
	padding-top: var(--nr-space-2); padding-bottom: var(--nr-space-2);
	margin-left: var(--nr-gutter);
	margin-right: var(--nr-gutter);
	max-width: none;
}

/* prose (article body incl. block editor output) */
.nr-prose { padding-top: var(--nr-space-2); }
.nr-prose > * + * { margin-top: var(--nr-space-4); }
.nr-prose p { margin: 0; }
.nr-prose a { text-underline-offset: 3px; }
.nr-prose h2, .nr-prose h3, .nr-prose h4 {
	font-family: var(--nr-font-display); line-height: var(--nr-leading-tight); margin: var(--nr-space-6) 0 0;
	/* OPS-224: article headings read at the article prose measure so long
	   Vietnamese section headings wrap on the article column, not inside the
	   narrow 22ch display-heading box. */
	max-width: var(--nr-prose-measure);
}
.nr-prose h2 {
	font-size: 1.5rem;
	/* OPS-224: the compensating padding-top and border-top divider between
	   article sections are removed; section separation is the retained
	   vertical rhythm and the heading itself. */
}
.nr-prose h3 { font-size: 1.25rem; }
.nr-prose ul, .nr-prose ol { padding-left: 1.4em; }
.nr-prose blockquote {
	margin: var(--nr-space-5) 0; padding: 0 0 0 var(--nr-space-5);
	border-left: 3px solid var(--nr-color-accent);
	font-family: var(--nr-font-display); font-size: var(--nr-text-lg); font-style: italic;
}
.nr-prose blockquote p { margin: 0; }
.nr-prose figure { margin: var(--nr-space-5) 0; }
.nr-prose figcaption { font-size: var(--nr-text-xs); color: var(--nr-color-ink-faint); }
.nr-prose .wp-block-image img { border-radius: var(--nr-radius-s); }

/* Media attribution (provenance rendering — moved from style.css, which is
   never enqueued; main.css is the live front-end stylesheet). */
.nr-media-attr {
	display: inline-block;
	margin-top: 0.35rem;
	font-size: 0.8rem;
	line-height: 1.5;
	color: var(--nr-fg-soft, #5a6069);
}
.nr-media-attr__ai {
	display: inline-block;
	padding: 0 0.5rem;
	border: 1px solid currentColor;
	border-radius: 999px;
	font-size: 0.72rem;
	letter-spacing: 0.02em;
}
.nr-media-attr a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}
figcaption .nr-media-attr-caption {
	color: var(--nr-fg-soft, #5a6069);
}
/* End-note attribution: one muted source line at the end of the article.
   No border/divider — separation is whitespace only. */
.nr-media-attr-endnote {
	margin: var(--nr-space-5, 2rem) 0 0;
	font-size: 0.8rem;
	line-height: 1.5;
	color: var(--nr-color-ink-faint, #5a6069);
}
.nr-media-attr-endnote a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}
.nr-prose code { font-family: var(--nr-font-mono); font-size: 0.92em; background: var(--nr-color-surface); padding: 1px 5px; border-radius: var(--nr-radius-s); }
/* OPS-224: a generated <hr> between article sections stays in the markup but
   renders as whitespace only — no visible line. */
.nr-prose hr { border: 0; margin: var(--nr-space-6) 0; }

.nr-pagelinks { padding-top: var(--nr-space-4); font-weight: 600; }

.nr-tags { display: flex; flex-wrap: wrap; gap: var(--nr-space-2); padding-top: var(--nr-space-5); align-items: baseline; }
.nr-tags__label { font-size: var(--nr-text-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--nr-color-ink-faint); margin-right: var(--nr-space-1); }
.nr-tags a {
	display: inline-block; padding: 3px 10px; border: var(--nr-border); border-radius: 999px;
	font-size: var(--nr-text-xs); color: var(--nr-color-ink-soft); text-decoration: none; background: var(--nr-color-paper);
}
.nr-tags a:hover { border-color: var(--nr-color-accent); color: var(--nr-color-accent); }

.nr-related { padding-top: var(--nr-space-6); border-top: var(--nr-rule-strong); margin-top: var(--nr-space-7); }
.nr-related__title { font-family: var(--nr-font-display); font-size: var(--nr-text-h3); margin: 0 0 var(--nr-space-4); }

.nr-postnav {
	display: grid; grid-template-columns: 1fr 1fr; gap: var(--nr-space-4);
	padding-block: var(--nr-space-5) 0; border-top: var(--nr-border); margin-top: var(--nr-space-6);
}
.nr-postnav a { text-decoration: none; color: var(--nr-color-ink); display: block; }
.nr-postnav a:hover .nr-postnav__title { color: var(--nr-color-accent); }
.nr-postnav__label { display: block; font-size: var(--nr-text-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--nr-color-ink-faint); }
.nr-postnav__title { font-family: var(--nr-font-display); font-weight: 700; }
.nr-postnav__next { text-align: right; }

/* --------------------------------------------- OPS-152 Single Article V1 ----
 * Single-only shell + desktop utility rail, inline TOC, share links, read
 * time and visual H2 numbering. New .wl-single-* classes; Homepage-scoped
 * (.wl-home-*) classes are NOT reused. The rail appears only at >=1200px
 * (locked D1): above it the rail carries AD-SINGLE-RAIL-1/2 + the compact
 * newsletter; below it the page is one column, both rail ad slots are hidden
 * with the rail, and the inline newsletter block is the single newsletter.
 */
.wl-single-shell { display: block; }
.wl-single-main { min-width: 0; }
.wl-single-rail { display: none; }
.wl-single-rail .nr-ad:not(:empty) { margin-block: 0; }

@media (min-width: 1200px) {
	.wl-single-shell {
		display: grid;
		grid-template-columns: minmax(0, 1fr) 320px;
		/* OPS-168 final dispatch: the 32px gap stays the COLUMN gutter to the
		   rail. Between the head row and the title row it must not re-apply —
		   the head row already carries the whole crumb→badge→H1 rhythm with its
		   own token steps (16px / 12px). A row gap here stacked a 32px band on
		   top of that rhythm on desktop only (48px crumb→H1 untyped, 44px
		   badge→H1 typed); with row-gap 0 the untouched-single collapse is the
		   single 16px step everywhere and the rail still starts on the H1 top
		   edge (both live in row 2). */
		row-gap: 0;
		column-gap: var(--nr-space-6);
		max-width: var(--nr-container-max);
		margin-inline: auto;
		padding-inline: var(--nr-gutter);
	}
	/* The shell owns the gutter on rail viewports: nested containers become
	   pass-through so all left edges share one axis. */
	.wl-single-main .nr-container { padding-inline: 0; }
	.wl-single-rail { display: block; align-self: start; }
	/* Exactly one newsletter per viewport: the rail module carries it on wide
	   desktop; the inline band after Related is hidden here. */
	.wl-single-newsletter-inline { display: none; }
}

/* Inline TOC (main column, after the cover): light-surface bounded module.
   <details> is natively keyboard-operable, starts open, never persists. */
/* OPS-224 part D: the TOC is theme markup (inc/toc.php → .wl-toc), so its
   separation from the share toolbar is set here directly. The deliberate
   top margin keeps the MỤC LỤC card's rounded border visually independent
   from the share buttons' borders above (spacing + border separation only —
   no extra card treatment, no divider). */
.wl-toc {
	background: var(--nr-color-surface);
	border: 1px solid var(--nr-color-line);
	border-radius: var(--nr-radius-lg, 20px);
	padding: var(--nr-space-5);
	margin: var(--nr-space-7) 0 var(--nr-space-6);
}
.wl-toc summary {
	cursor: pointer;
	font-family: var(--nr-font-display);
	font-size: var(--nr-text-sm);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--nr-color-ink-soft);
}
.wl-toc summary:focus-visible { outline: 2px solid var(--nr-color-accent); outline-offset: 2px; }
.wl-toc ol { margin: var(--nr-space-4) 0 0; padding-left: 1.4em; }
.wl-toc li + li { margin-top: var(--nr-space-2); }
.wl-toc a { color: var(--nr-color-ink); text-decoration: none; }
.wl-toc a:hover { color: var(--nr-color-accent); text-decoration: underline; }

/* TOC anchor landings clear the fixed-height header. */
.nr-single .nr-prose h2 { scroll-margin-top: 96px; }

/* In-body H2 + pull quote join the H1 in the Newsreader emphasis set (D2). */
.nr-single .nr-prose h2 { font-family: var(--nr-font-editorial); }
.nr-single .nr-prose blockquote { font-family: var(--nr-font-editorial); }

/* Visual-only H2 numbering (locked D7): CSS counter, editors write plain
   headings; DOM text is untouched. */
.nr-single .nr-prose { counter-reset: wl-single-h2; }
.nr-single .nr-prose h2::before {
	counter-increment: wl-single-h2;
	content: counter(wl-single-h2, decimal-leading-zero) "  ";
	color: var(--nr-color-accent);
}

/* Article-header share links (D3): plain anchors, no JS. */
.wl-share {
	display: flex; flex-wrap: wrap; gap: var(--nr-space-2); align-items: center;
	padding-block: var(--nr-space-3) 0;
}
.wl-share__label {
	font-size: var(--nr-text-xs); text-transform: uppercase; letter-spacing: 0.08em;
	color: var(--nr-color-ink-faint); margin-right: var(--nr-space-1);
}
.wl-share ul { display: flex; flex-wrap: wrap; gap: var(--nr-space-2); margin: 0; padding: 0; list-style: none; }
.wl-share__link {
	display: inline-block; padding: 3px 12px; border: var(--nr-border); border-radius: var(--nr-radius-pill);
	font-size: var(--nr-text-sm); font-weight: 600; color: var(--nr-color-ink); text-decoration: none;
	background: var(--nr-color-paper);
}
.wl-share__link:hover { border-color: var(--nr-color-accent); color: var(--nr-color-accent); }
.wl-share__link:focus-visible { outline: 2px solid var(--nr-color-accent); outline-offset: 2px; }

/* Inline newsletter placement below 1200px (locked D1): after Related,
   before the footer; the rail newsletter replaces it at >=1200px. */
.wl-single-newsletter-inline { padding-top: var(--nr-space-6); }

/* ------------------------------------------ OPS-153 review corrections ----
 * B: the prose body, TOC, gallery, tags, Related and prev/next share the
 *    cover's main-column width and edges — the nested narrow container and
 *    the 42rem prose axis are removed for the Single template only (pages
 *    keep the shared axis rules).
 * C: the shell splits into a head row (breadcrumb + kicker) above the
 *    main/rail row, so the rail's first visible module starts on the exact
 *    H1 top line; the H1 loses its top margin inside the body head.
 */
.nr-single .nr-prose,
.nr-single .nr-single__title,
.nr-single .nr-single__standfirst,
.nr-single .nr-single__meta,
.nr-single .nr-single__kicker,
.nr-single .nr-breadcrumbs {
	max-width: none;
	margin-left: 0;
	margin-right: 0;
}
.nr-single-bodyhead .nr-single__title { margin-top: 0; }

/* OPS-224: the Single template keeps the OPS-153 full-width body axis, but
   the article H1 rejoins the article prose measure declared in the shared
   .nr-single__title rule above. The head/body left-edge alignment is
   unchanged (margins stay 0); only the H1's usable width stops at the
   measure so long titles wrap on the article column. */
.nr-single .nr-single__title { max-width: var(--nr-prose-measure); }

@media (min-width: 1200px) {
	.wl-single-shell {
		grid-template-rows: auto 1fr;
	}
	.nr-single-head {
		grid-column: 1;
		grid-row: 1;
		/* The inherited .nr-container auto-margins turn this grid item
		   shrink-to-fit and centre it on the breadcrumb text; the head must
		   fill 100% of the main column so its left edge shares the exact
		   H1/body axis (OPS-168 final UI dispatch). */
		width: 100%;
		max-width: none;
		margin-inline: 0;
		padding-inline: 0;
	}
	.wl-single-main {
		grid-column: 1;
		grid-row: 2;
	}
	.wl-single-rail {
		grid-column: 2;
		grid-row: 2;
	}
}

/* OPS-153 review round 2 — Single rail ad rhythm (human NEEDS-CHANGES):
   populated rail ads get portrait 2:3 geometry at the 320px rail instead of
   the shared 90px banner token, and modules are separated by ONE tokenized
   16px gap. Scoped to the Single rail — the Homepage rail and banner
   contexts keep the shared tokens. Empty slots still emit zero markup
   (PHP fail-close), and flex `gap` only applies between rendered children,
   so filled, one-ad and empty states cannot leave a ghost gap. */
@media (min-width: 1200px) {
	.wl-single-rail {
		display: flex;
		flex-direction: column;
		gap: var(--nr-space-4);
	}
	.wl-single-rail .wl-rail-module {
		margin-bottom: 0;
	}
	.wl-single-rail .nr-ad:not(:empty) {
		aspect-ratio: 2 / 3;
		min-height: 0;
		width: 100%;
	}
	/* The breakpoint-swap wrapper is the flex parent a rail creative fills;
	   without it the creative collapses to its content height (48px). */
	.wl-single-rail .nr-ad:not(:empty) .nr-ad__desktop {
		display: flex;
		align-items: stretch;
		height: 100%;
	}
	.wl-single-rail .nr-ad:not(:empty) .nr-ad__mobile {
		height: 100%;
	}
}

/* -------------------------------------------------------------- ad slots ----
 * Theme-level primitives only: no provider binding, no JS. A slot renders
 * whatever markup a campaign/creative system fills it with; empty slots
 * collapse to nothing (markup is not emitted at all — see newsroom_ad_slot()).
 * OPS-168: no global minimum height is imposed on .nr-ad; any taller
 * presentation is per-slot opt-in (e.g. homepage-sidebar-1's desktop rail
 * frame above). Usage: newsroom_ad_slot( 'homepage-top' ).
 */
.nr-ad {
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	max-width: 100%;
}
.nr-ad > * { max-width: 100%; }

/* Filled ads use the creative as their complete visual surface. The frame
   adds only compact rhythm; empty slots still emit no markup and no gap. */
.nr-ad:not(:empty) {
	margin-block: var(--nr-space-4);
	position: relative;
}
.nr-ad__label {
	display: block;
	font-size: var(--nr-text-xs);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--nr-color-ink-faint);
	margin-bottom: var(--nr-space-2);
	text-align: center;
}
.nr-ad--wide { min-height: var(--nr-ad-min-wide); }

/* Textless local-review creatives. Production creatives remain supplied by
   the existing option/filter contract and are not coupled to these classes. */
.wl-ad-demo {
	display: block;
	width: 100%;
	background: var(--nr-color-surface-deep);
	border: 1px solid var(--nr-color-line);
	border-radius: var(--nr-radius-s);
}
.wl-ad-demo--leaderboard { height: 90px; }
.wl-ad-demo--mobile { height: 100px; max-width: 320px; margin-inline: auto; }
.wl-ad-demo--sidebar {
	aspect-ratio: 4 / 5;
	border-radius: var(--nr-radius);
}
.wl-ad-demo--tile {
	aspect-ratio: 16 / 5;
	min-height: 84px;
	max-height: 104px;
}

/* The homepage already ends with a newsletter/ad cadence; do not add the
   generic main + footer gaps a second time. */
body.home .nr-main {
	padding-bottom: var(--nr-space-5);
}
body.home .nr-footer {
	margin-top: 0;
}

/* Full-bleed-ish containment: ads must never cause horizontal overflow */
.nr-ad img, .nr-ad iframe { display: block; max-width: 100%; height: auto; }

/* Breakpoint-swapped creatives: show exactly one node. Both nodes take the
   full slot width so block-level creatives reach the container edges (as
   flex children they would otherwise shrink-wrap their text). */
.nr-ad__mobile { display: block; width: 100%; }
.nr-ad__desktop { display: none; width: 100%; }
@media (min-width: 720px) {
	.nr-ad__mobile { display: none; }
	.nr-ad__desktop { display: block; }
}

/* ------------------------------------------------------------- editorial gallery ----
 * Native core/gallery + core/image, laid out with CSS Grid. No JS, no masonry.
 * The tiny count classifier in inc/template-tags.php sets data-nr-gallery-count
 * (1|2|3|4) so each case gets an intentional composition. Mixed orientations
 * work because every figure keeps its own aspect ratio inside its cell.
 */
.nr-gallery {
	display: grid;
	gap: var(--nr-space-3);
	margin: var(--nr-space-5) 0;
}
.nr-gallery .blocks-gallery-item,
.nr-gallery figure { margin: 0; min-width: 0; }
/* Source aspect ratios are preserved per figure: height:auto + contain means
   awkward fixtures read as intentional letterboxed frames on one shared
   surface, never as random cropped blocks. */
.nr-gallery .blocks-gallery-item,
.nr-gallery figure {
	background: var(--nr-color-surface-deep);
	border-radius: var(--nr-radius-s);
	overflow: hidden;
}
.nr-gallery img { display: block; width: 100%; height: auto; object-fit: contain; border-radius: 0; }
.nr-gallery figcaption {
	font-size: var(--nr-text-xs); color: var(--nr-color-ink-faint);
	padding-top: var(--nr-space-2); text-align: left;
}

/* 1 image: full measure, never cropped */
.nr-gallery[data-nr-gallery-count="1"] { grid-template-columns: 1fr; }
.nr-gallery[data-nr-gallery-count="1"] img { max-height: min(78vh, 780px); width: auto; max-width: 100%; margin-inline: auto; }

/* 2 images: 50/50 */
.nr-gallery[data-nr-gallery-count="2"] { grid-template-columns: 1fr 1fr; }

/* 3 images: one large + two stacked, magazine style */
@media (min-width: 720px) {
	.nr-gallery[data-nr-gallery-count="3"] {
		grid-template-columns: 2fr 1fr;
		grid-template-rows: 1fr 1fr;
	}
	.nr-gallery[data-nr-gallery-count="3"] figure:first-child { grid-row: 1 / 3; }
}

/* 4 images: uniform 2x2; 5+: 3-col desktop */
.nr-gallery[data-nr-gallery-count="4"] { grid-template-columns: 1fr 1fr; }

@media (min-width: 720px) {
	.nr-gallery[data-nr-gallery-count="5"] { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 719px) {
	/* mobile: 2-up for 4+, everything else stacks */
	.nr-gallery { grid-template-columns: 1fr; }
	.nr-gallery[data-nr-gallery-count="2"],
	.nr-gallery[data-nr-gallery-count="4"],
	.nr-gallery[data-nr-gallery-count="5"] { grid-template-columns: 1fr 1fr; }
	.nr-gallery img { height: auto; }
}

/* core/gallery compat: WordPress wraps items in ul.blocks-gallery-grid */
.nr-gallery ul.blocks-gallery-grid,
ul.blocks-gallery-grid.nr-gallery { list-style: none; margin: 0; padding: 0; }

/* -------------------------------------------------------------- pagination */
.nr-pagination { margin-block: var(--nr-space-6); }
.nr-pagination .nav-links { display: flex; flex-wrap: wrap; gap: var(--nr-space-2); align-items: center; }
.nr-pagination .page-numbers {
	display: inline-block; padding: 6px 12px; border: var(--nr-border); border-radius: var(--nr-radius-s);
	color: var(--nr-color-ink); text-decoration: none; font-size: var(--nr-text-sm);
}
.nr-pagination .page-numbers.current { background: var(--nr-color-ink); color: var(--nr-color-paper); border-color: var(--nr-color-ink); }
.nr-pagination .page-numbers:hover:not(.current) { border-color: var(--nr-color-accent); color: var(--nr-color-accent); }
.nr-pagination .dots { border: 0; }
/* WisLens Category V1 (OPS-150): pagination on the Headphone archive is
 * centred and styled through this template-owned wrapper (the core
 * the_posts_pagination() markup only ever emits the single sanitized class
 * token `pagination`, so shared styling is applied by the wrapper element). */
.nr-catv1__pagination { margin-block: var(--nr-space-6); }
.nr-catv1__pagination .nav-links { display: flex; flex-wrap: wrap; gap: var(--nr-space-2); align-items: center; justify-content: center; }
.nr-catv1__pagination .page-numbers {
	display: inline-block; padding: 6px 12px; border: var(--nr-border); border-radius: var(--nr-radius-s);
	color: var(--nr-color-ink); text-decoration: none; font-size: var(--nr-text-sm);
}
.nr-catv1__pagination .page-numbers.current { background: var(--nr-color-ink); color: var(--nr-color-paper); border-color: var(--nr-color-ink); }
.nr-catv1__pagination .page-numbers:hover:not(.current) { border-color: var(--nr-color-accent); color: var(--nr-color-accent); }
.nr-catv1__pagination .dots { border: 0; }

/* ------------------------------------------------- WisLens Category V1 (OPS-150)
 * Headphone archive layout: breadcrumb → intro → one full-width lead →
 * two-column follow-up rows → centred pagination.
 * Grid axis contract: the lead and the follow-up listing are equal-halves
 * grids with the same 24px gap inside the same container, so the lead image's
 * right edge and the text block's left edge sit on the exact gutter axes that
 * separate the two follow-up columns. No sidebar.
 * OPS-168: the child/sibling category row was removed — its markup, helper
 * and every rule made for it are gone; header navigation/submenus are the
 * sole cross-category navigation.
 */

/* Header rhythm without the SECTION eyebrow (OPS-150 correction for
   Headphone, widened to every category archive by OPS-168): the H1 keeps a
   deliberate step below the breadcrumb — no reserved band, no visual hole.
   It fires wherever the kicker is absent (title is the header's first child). */
.nr-catv1__header .nr-archive__title,
.nr-archive__header > .nr-archive__title:first-child { margin-top: var(--nr-space-2); }

.nr-catv1__lead { margin-bottom: var(--nr-space-6); }
.nr-card--lead { display: flex; flex-direction: column; gap: var(--nr-space-4); }
.nr-card--lead .nr-card__media { border-radius: var(--nr-radius); }
.nr-card--lead .nr-card__body { padding-top: 0; gap: var(--nr-space-3); }
.nr-card--lead__title { font-size: var(--nr-text-h2); }

.nr-catv1__followups { display: grid; grid-template-columns: 1fr; gap: var(--nr-space-5); }
.nr-catv1__followups .nr-card--horizontal { border-top: 0; padding-block: 0; }

@media (min-width: 1020px) {
	/* Lead: 16:9 media left, text right, sharing the follow-up grid axis.
	   The media's 16:9 frame owns the row height; the text panel stretches to
	   exactly that height (shared top/bottom edges, OPS-150 correction) with
	   the meta row anchored to the panel's bottom edge. Content-safe: an
	   unusually tall text body grows the row instead of cropping the image. */
	.nr-card--lead {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--nr-space-5);
		align-items: start;
	}
	.nr-card--lead .nr-card__body { align-self: stretch; }
	.nr-card--lead .nr-meta { margin-top: auto; }
	.nr-card--lead .nr-card__title { font-size: var(--nr-text-h1); }
	.nr-catv1__followups { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ------------------------------------------------------------ search + 404 */
.nr-searchbar { max-width: 460px; margin-bottom: var(--nr-space-5); }
.nr-searchform { display: flex; gap: var(--nr-space-2); }
.nr-searchform input {
	flex: 1; padding: 10px 12px; border: var(--nr-border); border-radius: var(--nr-radius-s); background: var(--nr-color-surface);
}
.nr-searchform button {
	padding: 10px 18px; border: 0; border-radius: var(--nr-radius-s);
	background: var(--nr-color-ink); color: var(--nr-color-paper); cursor: pointer; font-size: var(--nr-text-sm);
}
.nr-searchform button:hover { background: var(--nr-color-accent); }

.nr-empty { padding-block: var(--nr-space-5); }
.nr-empty__sections { list-style: none; display: flex; flex-wrap: wrap; gap: var(--nr-space-2); margin: var(--nr-space-4) 0 0; padding: 0; }
.nr-empty__sections a {
	display: inline-block; padding: 6px 14px; border: var(--nr-border); border-radius: 999px;
	text-decoration: none; color: var(--nr-color-ink); font-size: var(--nr-text-sm);
}
.nr-empty__sections a:hover { border-color: var(--nr-color-accent); color: var(--nr-color-accent); }

.nr-404 { padding-block: var(--nr-space-8); }
.nr-404__code {
	margin: 0; font-family: var(--nr-font-display); font-size: clamp(4rem, 12vw, 7rem);
	line-height: 1; color: var(--nr-color-line-strong);
}
.nr-404__title { font-family: var(--nr-font-display); font-size: var(--nr-text-h2); margin: var(--nr-space-2) 0 var(--nr-space-3); }
.nr-404__heading { font-family: var(--nr-font-display); font-size: var(--nr-text-h3); margin-top: var(--nr-space-6); }

/* ------------------------------------------------------------------ footer */
/* Layout-framework footer (O3 primary + O1 fallback): bounded groups only.
   The grid self-balances by the number of rendered groups — brand column
   slightly wider for the wordmark + description, link columns equal. */
.nr-footer { border-top: var(--nr-rule-strong); background: var(--nr-color-surface); margin-top: var(--nr-section-gap); }
.nr-footer__grid {
	display: grid; gap: var(--nr-space-6); padding-block: var(--nr-space-7);
	grid-template-columns: 1fr;
}
.nr-footer__brand { margin: 0; font-family: var(--nr-font-display); font-weight: 700; font-size: var(--nr-text-lg); }
.nr-footer__desc { margin: var(--nr-space-2) 0 0; color: var(--nr-color-ink-soft); font-size: var(--nr-text-sm); max-width: 40ch; }
.nr-footer__heading { font-size: var(--nr-text-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--nr-color-ink-faint); margin: 0 0 var(--nr-space-3); }
.nr-footer__sections { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--nr-space-2); font-size: var(--nr-text-sm); }
.nr-footer__sections a { color: var(--nr-color-ink); text-decoration: none; font-weight: 600; }
.nr-footer__sections a:hover { color: var(--nr-color-accent); }
.nr-footer__legal { border-top: var(--nr-border); padding-block: var(--nr-space-4); font-size: var(--nr-text-xs); color: var(--nr-color-ink-faint); }
.nr-footer__legal p { margin: 0; }
.nr-footer__trust { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--nr-space-2); font-size: var(--nr-text-sm); }
.nr-footer__trust a { color: var(--nr-color-ink-soft); text-decoration: none; }
.nr-footer__trust a:hover { color: var(--nr-color-accent); }
.nr-trust-notice {
	border: 1px solid var(--nr-color-accent);
	border-left-width: 4px;
	background: var(--nr-color-surface);
	padding: var(--nr-space-3) var(--nr-space-4);
	margin: 0 0 var(--nr-space-4);
	font-size: var(--nr-text-sm);
	border-radius: 4px;
}

/* ------------------------------------------------------------- responsive */
@media (min-width: 720px) {
	.nr-grid--3 { grid-template-columns: repeat(2, 1fr); }
	/* 3 rendered groups (default): brand + 2 balanced link columns.
	   4 rendered groups (--four modifier): brand + 3 balanced link columns. */
	.nr-footer__grid { grid-template-columns: 1.2fr 1fr 1fr; }
	.nr-footer__grid--four { grid-template-columns: 1.2fr 1fr 1fr 1fr; }
}

@media (min-width: 1020px) {
	.nr-footer__grid { grid-template-columns: 1.4fr 1fr 1fr; }
	.nr-footer__grid--four { grid-template-columns: 1.4fr 1fr 1fr 1fr; }
	.nr-grid--3 { grid-template-columns: repeat(3, 1fr); }

	.nr-nav-toggle { display: none; }
	.nr-nav { display: block; }
	.nr-mobile-nav { display: none !important; }

	.nr-header__search { display: flex; }

	.nr-nav__list { display: flex; flex-wrap: wrap; gap: 0; margin: 0; padding: 0; list-style: none; }
	.nr-nav__item { position: relative; }
	.nr-nav__link {
		display: block; padding: var(--nr-space-3) var(--nr-space-4);
		color: var(--nr-color-ink); text-decoration: none;
		font-size: var(--nr-text-sm); font-weight: 600; letter-spacing: 0.01em;
		border-bottom: 2px solid transparent;
	}
	.nr-nav__link:hover { color: var(--nr-color-accent); border-bottom-color: var(--nr-color-accent); }
	.nr-nav__expand { display: none; }

	.nr-nav__sub {
		display: none; position: absolute; top: 100%; left: 0; z-index: 50;
		min-width: 210px; margin: 0; padding: var(--nr-space-2) 0;
		list-style: none; background: var(--nr-color-paper);
		border: var(--nr-border); border-radius: var(--nr-radius-s); box-shadow: var(--nr-shadow-pop);
	}
	.nr-has-children:hover > .nr-nav__sub,
	.nr-has-children:focus-within > .nr-nav__sub { display: block; }
	.nr-nav__sub a {
		display: block; padding: 7px 14px; color: var(--nr-color-ink-soft); text-decoration: none; font-size: var(--nr-text-sm);
	}
	.nr-nav__sub a:hover { background: var(--nr-color-surface); color: var(--nr-color-accent); }

	/* WisLens Desktop Header Navigation (>= 1020px / 1024px) */
	.wl-header__inner {
		flex-wrap: nowrap;
		gap: var(--nr-space-4);
	}

	.wl-header__nav {
		display: flex;
		align-items: center;
		justify-content: center;
		flex: 1;
		margin-inline: var(--nr-space-4);
		min-width: 0;
	}

	.wl-header__nav .nr-nav {
		display: block;
	}

	.wl-header__nav .nr-nav__list {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 4px;
		margin: 0;
		padding: 0;
		list-style: none;
		flex-wrap: wrap;
		/* Full taxonomy nav (21+ items at depth 0) must wrap inside the header
		   instead of overflowing the page horizontally. */
		max-width: 100%;
		overflow-wrap: normal;
	}
	.wl-header__nav .nr-nav__item {
		flex-shrink: 1;
	}

	.wl-header__nav .nr-nav__item {
		position: relative;
	}

	/* Compact band (≈1020–1219px): keep the five curated sections on ONE
	   header row — slightly tighter links before anything wraps. */
	@media (max-width: 1219px) {
		.wl-header__nav {
			margin-inline: var(--nr-space-2);
		}
		.wl-header__nav .nr-nav__link {
			padding: 8px 9px;
			font-size: 0.875rem;
		}
	}

	.wl-header__nav .nr-nav__link {
		display: inline-flex;
		align-items: center;
		padding: 8px 12px;
		font-family: var(--nr-font-body);
		font-size: 0.9375rem;
		font-weight: 500;
		color: var(--nr-color-ink);
		text-decoration: none;
		border-radius: var(--nr-radius-pill);
		border-bottom: none;
		transition: color var(--nr-transition), background-color var(--nr-transition);
		white-space: nowrap;
	}

	.wl-header__nav .nr-nav__link:hover,
	.wl-header__nav .nr-nav__link:focus-visible {
		color: var(--wl-color-accent, #3B82F6);
		background-color: var(--nr-color-surface, #F8FAFC);
	}

	.wl-header__nav .nr-nav__expand {
		display: none;
	}

	.wl-header__nav .nr-nav__sub {
		display: none;
		position: absolute;
		top: calc(100% + 4px);
		left: 0;
		min-width: 200px;
		margin: 0;
		padding: 6px 0;
		list-style: none;
		background: var(--nr-color-paper, #FFFFFF);
		border: 1px solid var(--nr-color-line, #E5E7EB);
		border-radius: var(--nr-radius, 12px);
		box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.08), 0 8px 10px -6px rgba(0, 0, 0, 0.05);
		z-index: 100;
	}

	.wl-header__nav .nr-has-children:hover > .nr-nav__sub,
	.wl-header__nav .nr-has-children:focus-within > .nr-nav__sub {
		display: block;
	}

	.wl-header__nav .nr-nav__sub a {
		display: block;
		padding: 8px 16px;
		font-size: 0.875rem;
		font-weight: 500;
		color: var(--nr-color-ink-soft, #64748B);
		text-decoration: none;
		transition: color var(--nr-transition), background-color var(--nr-transition);
		white-space: nowrap;
	}

	.wl-header__nav .nr-nav__sub a:hover,
	.wl-header__nav .nr-nav__sub a:focus-visible {
		color: var(--wl-color-accent, #3B82F6);
		background-color: var(--nr-color-surface, #F8FAFC);
	}

	.wl-header__search { display: flex; }
	.wl-header__search-toggle { display: none; }
	.wl-btn--header-subscribe { display: inline-flex; }
}

@media (min-width: 1200px) {
	.nr-header__inner {
		display: grid;
		grid-template-columns: minmax(260px, 1fr) auto minmax(260px, 1fr);
		gap: var(--nr-space-4);
	}
	.wl-header__identity {
		justify-self: start;
	}
	.wl-header__nav {
		justify-self: center;
		margin-inline: 0;
	}
	.wl-header__actions {
		justify-self: end;
	}
	.wl-header__nav .nr-nav__list {
		flex-wrap: nowrap;
	}
}

@media (max-width: 1019px) {
	.nr-header__inner { flex-wrap: nowrap; }
	.wl-header__nav { display: none; }
}

@media (min-width: 768px) and (max-width: 1019px) {
	.nr-header__inner {
		padding-block: 14px;
		gap: 16px;
	}
	.wl-header__search { display: flex; }
	.wl-header__search-toggle { display: none; }
	.wl-btn--header-subscribe { display: inline-flex; }
	.nr-nav-toggle { display: inline-flex; }
}

@media (max-width: 767px) {
	.nr-header__inner {
		padding-block: 12px;
		gap: 12px;
	}
	.wl-brand {
		min-width: 0;
	}
	.wl-wordmark {
		font-size: 1.55rem;
	}
	.wl-brand__tag {
		font-size: 0.53125rem;
		letter-spacing: 0.08em;
	}
	.wl-header__nav { display: none; }
	.wl-header__search { display: none; }
	.wl-header__search-toggle { display: inline-flex; }
	.wl-btn--header-subscribe { display: none; }
	.nr-nav-toggle { display: inline-flex; }
}

@media (max-width: 359px) {
	.nr-header__inner {
		padding-inline: 12px;
		gap: 8px;
	}
	.wl-brand {
		flex: 1 1 auto;
		min-width: 0;
	}
	.wl-brand__tag {
		max-width: 100%;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
	.wl-header__actions {
		min-width: 0;
		gap: 6px;
	}
}

@media (prefers-reduced-motion: reduce) {
	* { transition: none !important; }
	.nr-card__media:hover .nr-card__img { transform: none; }
}
