/**
 * Custom Component Styles — Atomicdust Base Theme
 *
 * Styles for base theme patterns and custom blocks.
 * All classes prefixed .nisa- (kebab-case).
 *
 * BASE THEME PATTERNS (ship with every project):
 *   Text Ticker, Section Label, Card Row,
 *   Case Studies (+ case-studies-4), Card Links Image
 *
 * PROJECT-SPECIFIC CSS:
 *   Add below the base theme patterns as new patterns are built.
 *   Never remove base theme pattern CSS — it supports the pattern library.
 */

/* Section spacing is set via block attributes (style.spacing.padding)
   on each pattern's outer group. No CSS fallbacks needed — inline
   styles from block attributes always apply. */

/* -----------------------------------------------
   Text Ticker — Vertical Infinite Scroll
   ----------------------------------------------- */

/* Ticker container — fixed height, vertical mask fade */
.nisa-text-ticker {
	position: relative;
	height: 20rem;
	overflow: hidden;
	-webkit-mask-image: linear-gradient(
		to bottom,
		transparent,
		black clamp(1.5rem, 4vw, 3rem),
		black calc(100% - clamp(1.5rem, 4vw, 3rem)),
		transparent
	);
	mask-image: linear-gradient(
		to bottom,
		transparent,
		black clamp(1.5rem, 4vw, 3rem),
		black calc(100% - clamp(1.5rem, 4vw, 3rem)),
		transparent
	);
}

/* Track — vertical flex column */
.nisa-text-ticker__track {
	flex-direction: column !important;
	flex-wrap: nowrap !important;
}

/* Items — no margin (gap handles spacing) */
.nisa-text-ticker__item {
	margin: 0 !important;
	line-height: 1.3;
}

/* Animated state — JS adds .is-animated after cloning children */
.nisa-text-ticker.is-animated .nisa-text-ticker__track {
	animation: nisa-text-scroll var(--nisa-ticker-duration, 20s) linear infinite;
}

@keyframes nisa-text-scroll {
	from {
		transform: translateY(0);
	}
	to {
		transform: translateY(calc(var(--nisa-ticker-height) * -1));
	}
}

/* Pause/play button — bottom-right of ticker */
.nisa-text-ticker__pause-btn {
	position: absolute;
	bottom: 0.5rem;
	right: 0.5rem;
	z-index: 1;
}

/* Reduced motion — no animation */
@media (prefers-reduced-motion: reduce) {
	.nisa-text-ticker.is-animated .nisa-text-ticker__track {
		animation: none;
	}

	/* WCAG 2.2.2 pause controls exist only for motion that runs. Under
	   reduced motion the ticker, hero words and recognition marquee don't
	   animate, so never show a control with nothing to pause — also covers a
	   preference flipped mid-session. BugHerd #334. The video band is NOT in
	   this list: its video autoplays from the markup either way, so its pause
	   control stays (custom.js builds it in the reduced-motion path too). */
	.nisa-text-ticker__pause-btn,
	.nisa-hero-main__pause-btn,
	.nisa-recognition__pause-btn {
		display: none;
	}
}

/* Mobile — shorter ticker */
@media (max-width: 781px) {
	.nisa-text-ticker {
		height: 14rem;
	}
}

/* -----------------------------------------------
   Section Label
   ----------------------------------------------- */

/* Reusable section label — colored square + text.
   Square color inherits from --wp--preset--color--accent. */
.nisa-section-label {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	font-weight: 500;
	margin-bottom: 0;
}

.nisa-section-label::before {
	content: "";
	display: block;
	width: 0.625rem;
	height: 0.625rem;
	border-radius: 0.125rem;
	background-color: var(--wp--preset--color--accent);
	flex-shrink: 0;
}

.nisa-section-label--center {
	justify-content: center;
}

/* -----------------------------------------------
   Card Row
   ----------------------------------------------- */

/* Card — rounded corners, overflow clip. Background set natively via backgroundColor attribute. */
.nisa-card {
	border-radius: 0.75rem;
	overflow: hidden;
}

/* Card image — flush to edges, consistent aspect ratio */
.nisa-card__image {
	margin: 0;
}

.nisa-card__image img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	display: block;
}

/* -----------------------------------------------
   Project-Specific Styles
   Add below this line. Do not modify base theme patterns above.
   ----------------------------------------------- */

/* -----------------------------------------------
   Hero Main
   ----------------------------------------------- */

/* Gradient on the em applies ONLY while it still holds the raw fallback text
   (pre-rebuild, no-JS, and the block editor, where the rotation JS never
   runs). After the rebuild the em MUST NOT paint: background-clip:text clips
   to the text of the element AND ITS DESCENDANTS, so a gradient left on the
   ready em painted a complete second copy of every rotating word underneath
   the ink's copy. The two copies coincided pixel-perfectly until the inks
   became composited, animated layers — then the em's copy (layout position,
   whole-em gradient geometry) and the ink's copy (animated position, word-box
   gradient geometry) diverged: a doubled word in two slightly different
   blues. Beth's "are there two instances?" — yes: two PAINTERS, one DOM. */
.nisa-hero-main__heading em {
	font-style: italic;
}

.nisa-hero-main__heading em:not(.nisa-rotating--ready) {
	/* Static dark(left) -> light(right) gradient, no animation. Preset defined
	   in theme.json (settings.color.gradients -> hero-word). */
	background: var(--wp--preset--gradient--hero-word);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
}

/* Rotating words — structural */

/* Rotating words — DELIBERATELY NO CLIP on the em.
   An earlier build masked this line (overflow-y: clip + a padding runway) and
   slid words through the mask, relying on fade timing to hide the slicing.
   Position and opacity were separate tweens, and with lagSmoothing(0) (Lenis)
   any dropped frame desynced them — descenders of the active word were cut at
   the mask edge and descender tails of off-position words painted at readable
   opacity. The mask is gone; correctness now comes from a geometric rule in
   custom.js: a word is only visible near its rest position, and its travel is
   small. Nothing here may reintroduce overflow clipping or padding hacks. */
.nisa-hero-main__heading em.nisa-rotating--ready {
	display: inline-flex;
	align-items: baseline;
	position: relative;
	line-height: inherit;
	/* The VIEW AREA — a hard boundary sized so the active word is never cut:
	   top at the line-box top (seated ink starts 15px below it — nothing legit
	   is ever clipped there, and any repaint artifact above the line is
	   guaranteed gone); 0.35em extra below so full descender ink (which runs
	   ~5px past the line box in this font, see the __ink rule) plus the last
	   visible px of the entry rise fit entirely inside; 0.3em side slack for
	   italic overhang while the wrapper width is mid-tween. Words BECOME
	   VISIBLE only once fully inside this window (fade starts at 0.22s, when
	   the rise is ~12px from seated — inside), so unlike the old overflow
	   mask, no visible glyph ever crosses the boundary and nothing gets
	   sliced. clip-path (not overflow) so composited layers are bounded too. */
	clip-path: inset(0 -0.3em -0.35em -0.3em);
}

/* line-height MUST inherit the h1's theme.json value (1.15). A taller value
   here builds a line box bigger than the heading's, which inflates the
   heading (was forcing line 2 to 84px instead of 69px). */
.nisa-rotating__inner {
	display: inline-block;
	line-height: inherit;
	position: relative;
}

/* PURE LAYOUT BOXES — never animated, never layer-promoted, never hidden.
   GSAP targets the __ink child (paint + layer + motion on ONE element; see
   the __ink rule and the history comment in custom.js). Splitting motion
   onto this parent while the ink held the compositor layer rendered TWO
   instances of the incoming word (the ink layer seated while the parent
   transform animated). Visibility of each word is controlled on its ink. */
.nisa-rotating__word {
	display: block;
	white-space: nowrap;
	position: absolute;
	top: 0;
	left: 0;
	line-height: inherit;
}

/* First word is relative (sets the container height + width) — the sentence
   stays readable if the rotation JS never starts. */
.nisa-rotating__word:first-child {
	position: relative;
}

/* Hidden by default so only word 1 shows until JS/GSAP takes over — on the
   INK, the element GSAP actually animates (autoAlpha writes inline
   visibility/opacity there and overrides these). */
.nisa-rotating__word .nisa-rotating__ink {
	visibility: hidden;
}

.nisa-rotating__word:first-child .nisa-rotating__ink {
	visibility: visible;
}

/* Gradient text lives on a STATIC inner span — never on .nisa-rotating__word,
   which is the element GSAP transforms and fades. Chrome keeps painting a stale
   raster of background-clip:text text when that same element's transform AND
   opacity jump in one frame, so the outgoing word stays drawn on top of the
   incoming one (both at the same baseline). gsap.ticker.lagSmoothing(0) — needed
   for Lenis — makes that single-frame jump happen after any dropped frame, tab
   switch, or wake-from-sleep, which is why the overlap looked intermittent.
   The .nisa-rotating__ink box is identical to the word box, so the static
   dark(left) -> light(right) gradient spans each word exactly. */
.nisa-hero-main__heading .nisa-rotating__ink {
	display: block;
	/* Static dark(left)->light(right) per-word gradient (theme.json -> hero-word). */
	background: var(--wp--preset--gradient--hero-word);
	/* lint-allow: C4 — this element IS animated by GSAP, but it is PERMANENTLY composited (will-change + translateZ + force3D:true in custom.js), so transform/opacity changes are compositor updates with no re-raster into shared tiles — the stale-raster failure C4 guards against cannot occur; see the history comment in custom.js before changing this */
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	/* Enlarge the PAINT box so the gradient covers every part of the glyphs.
	   background-clip: text only paints background within the element's box,
	   and ivypresto-headline's metrics are BIGGER than the 1.15 line box:
	   measured at 60px, ascent 65 + descent 15 = 80px in a 69px line box, so
	   the baseline sits at 59.5px and "Strategic"'s g-tail ink reaches 73.9px
	   — 4.9px past the box. That strip got NO gradient → transparent → the
	   descender looked amputated even at rest, with zero overflow clipping
	   involved. Padding extends the painted box below (descenders), above
	   (safety at other sizes), and to the sides (italic overhang); the exactly
	   matching negative margins cancel it out of layout, so line height,
	   wrapper width math, and the word's text position are all unchanged. */
	padding: 0.1em 0.15em 0.25em;
	margin: -0.1em -0.15em -0.25em;
	/* Own compositor layer — THE fix for the "phantom g" artifact (Beth's
	   find: deleting the g from Strategic removed it). When this ink rasters
	   into the shared page tiles, Chromium's background-clip:text rasterizer
	   WRAPS glyph ink that crosses its internal line-box boundary back to the
	   top edge — painting a floating copy of the active word's descender tail
	   over line 1's descenders (only words with descenders showed it; Critical
	   never did). A/B-verified live: artifact present without the layer, gone
	   with it, g still fully painted. no-repeat is hygiene on top: a clipped
	   text gradient must never tile phantom copies above/below the box. */
	transform: translateZ(0);
	will-change: transform;
	background-repeat: no-repeat;
}

/* Same paint-box problem for the no-JS fallback, where the em still holds the
   raw comma-separated text with the gradient on it. The em is inline there, so
   vertical padding paints a taller background without shifting any layout. */
.nisa-hero-main__heading em:not(.nisa-rotating--ready) {
	padding-top: 0.1em;
	padding-bottom: 0.25em;
}

/* When JS will run (html.js is stamped in wp_head before first paint), the
   raw comma-list em must NEVER paint. On cold loads it used to render for a
   few frames before custom.js rebuilt it — gradient ink in a 3-line heading
   layout whose first em line sits exactly over the final layout's line 1
   descenders. Chrome's background-clip:text stale-raster bug could strand a
   sliver of that flash there (the recurring "blue ligament" over the p of
   "Disciplined", reproducible on cold/incognito loads). Hidden ink can't
   paint, so there is nothing to strand. No-JS visitors lack html.js and keep
   the readable fallback. */
/* Scoped to no-preference: custom.js returns early under
   prefers-reduced-motion, so the em never gets --ready there — without this
   media scope the guard would hide the heading's italic text FOREVER for
   reduced-motion users (their designed fallback IS the raw comma list). */
@media (prefers-reduced-motion: no-preference) {
	html.js .nisa-hero-main__heading em:not(.nisa-rotating--ready) {
		visibility: hidden;
	}
}

/* Reduced-motion twin of the guard above. Those visitors get no rotation,
   so they should only ever see the first word ("Strategic", BugHerd #333).
   inc/hero-rotating-words.php wraps words 2+ in .nisa-rotating__rest on the
   server, so this hides them from the very first paint with the heading
   already in its final layout (hiding the whole em instead left four lines
   of empty space that collapsed when custom.js trimmed it). No-JS visitors
   lack html.js and keep the full list. */
@media (prefers-reduced-motion: reduce) {
	html.js .nisa-hero-main__heading .nisa-rotating__rest {
		display: none;
	}
}

/* Second guard: after the rebuild, the word inks stay hidden until the
   WEBFONT is active (JS adds --fonts on document.fonts.ready, 3s fallback).
   On cold loads the words otherwise paint in the fallback serif, whose taller
   glyphs reach up into line 1's descender zone; when ivypresto swaps in,
   Chrome's background-clip:text bug can strand a gradient strip of that
   fallback ink over the "p" of "Disciplined" — the artifact only ever
   reproduced on cold/incognito loads. The rule targets the INK spans (not the
   words): GSAP writes inline visibility on .nisa-rotating__word, so a word
   rule would need !important, while the inks carry all visible paint and JS
   never touches their visibility. */
@media (prefers-reduced-motion: no-preference) {
	html.js .nisa-hero-main__heading em.nisa-rotating--ready:not(.nisa-rotating--fonts) .nisa-rotating__ink {
		visibility: hidden;
	}
}

.nisa-hero-main {
	position: relative;
	box-sizing: border-box;
	/* Target height ~500px (designer spec), down from the previous
	   full-viewport "peek". max() holds a 500px floor on normal laptops (where
	   40vh is smaller) and only grows toward 40vh on unusually tall displays;
	   min-height (not height) still lets tall content expand the hero rather
	   than clip on short viewports. The pattern applies the tall `section`
	   preset as top/bottom padding — and since that padding sits INSIDE this
	   border-box min-height, it's trimmed here so the centred content actually
	   lands within ~500px instead of inflating the hero back toward full-height. */
	min-height: max(500px, 40vh);
	padding-block: clamp(1.5rem, 4vh, 2.5rem) !important;
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.nisa-mobile-br {
	display: none;
}

/* Homepage hero intro: the two sentences sit on their own lines on desktop
   (a manual <br> in the paragraph), but on tablet/phone the first sentence
   already wraps, so the forced break stranded "unique objectives." on a short
   line. Hide it at WP's 781px breakpoint and let the copy flow; the space
   before the <br> keeps the sentences apart. Keyed to the block's className
   (editor-safe), not a class on the <br>. */
@media (max-width: 781px) {
	.nisa-hero-main__lede br {
		display: none;
	}
}

@media (max-width: 1024px) {
	.nisa-mobile-br {
		display: block;
	}
}

@media (max-width: 600px) {
	.nisa-hero-main__heading {
		/* lint-allow: deliberate art-directed shrink below the display preset floor on phones */
		font-size: 1.625rem !important;
	}
}

.nisa-hero-main__pause-btn {
	position: absolute;
	bottom: 1rem;
	right: 1rem;
	z-index: 2;
}

/* -----------------------------------------------
   Capabilities Hero — interior split hero (Figma 24:5002)
   Band on `wash`; text column starts at the root content inset; photo
   bleeds to the right viewport edge at full band height. Level-3 CSS is
   only what native flex/group attrs can't express: the one-sided bleed
   (root padding re-applied on the text side only) and the media sizing.
   ----------------------------------------------- */

.nisa-cap-hero {
	/* 476px at the 1440 comp, scaling down fluidly */
	min-height: clamp(20rem, 33vw, 29.75rem);
	/* Full-bleed section: zero the block's own padding (the root-padding-aware
	   left/right inset alignfull blocks pick up, plus the columns' default
	   block padding) so the photo fills full height and bleeds to the viewport
	   edge. The content column re-adds its own inset via native padding. */
	padding: 0;
}

/* .nisa-cap-hero is a core/columns 52/48 split: the column widths, per-column
   vertical alignment (content center / media stretch), seam gap (blockGap 0),
   and the content column's inset padding are native block attributes now. */

/* Columns render content-box in this theme; keep each column's native padding
   inside its flex basis so the split stays 52/48. */
.nisa-cap-hero > .wp-block-column {
	box-sizing: border-box;
}

/* Intro measure matches the comp's 564px column */
.nisa-cap-hero__intro {
	max-width: 35.25rem;
	line-height: 1.58;
}

/* Hero media columns (Capabilities + Fixed Income) — consolidated (C5). Column
   width + stretch are native block attrs; CSS only anchors the absolutely-
   positioned photo/graphic + overlays (sweep / stat) inside the column. */
.nisa-cap-hero__media,
.nisa-fi-hero__media {
	position: relative;
	min-width: 0;
}

/* Load-in reveal: a static brand-blue gradient shows on load, then the photo
   fades in over it (custom.js). The photo starts hidden ONLY when JS will
   animate it (html.js) and motion is allowed — so no-JS / reduced-motion keep
   the photo visible. overflow:hidden keeps the cover-cropped photo in-column. */
.nisa-cap-hero__media {
	overflow: hidden;
	/* Same gradient as the homepage hero words (theme.json -> hero-word). */
	background: var(--wp--preset--gradient--hero-word);
}

@media (prefers-reduced-motion: no-preference) {
	html.js .nisa-cap-hero__photo {
		opacity: 0;
	}
}

/* Photo figure fills the media column; the img cover-crops to it so its
   intrinsic ratio can't inflate the band (same technique as the FI hero
   graphic + the footer subscribe image). */
.nisa-cap-hero__photo {
	position: absolute;
	inset: 0;
	margin: 0; /* UA reset — defeats browser <figure> margins */
}

.nisa-cap-hero__photo img {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Italic gradient word — same token gradient as the why-nisa heading em.
   Paint box enlarged so background-clip:text can't amputate the g descender
   (ivypresto ink exceeds the line box — see the hero rotating-words saga);
   the negative margins cancel the padding out of layout. no-repeat stops
   phantom tile copies of overflowing glyphs. */
.nisa-cap-hero__heading em {
	font-style: italic;
	/* Blue-safe hero gradient (sits on wash bg — hero's bright end fails AA there). */
	background: var(--wp--preset--gradient--hero-word-onblue);
	background-repeat: no-repeat;
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	padding: 0.1em 0.15em 0.25em;
	margin: -0.1em -0.15em -0.25em; /* lint-allow: cancels the paint-box padding above — no layout spacing created */
}

/* -----------------------------------------------
   Capabilities Card Grids (Figma 24:5009)
   Two 4-up grids under ruled headings. Cards: muted at rest, light-blue on
   hover/focus (the comp's blue Fixed Income card is the captured hover
   state). Whole card is clickable via the CTA link's stretched ::before
   (same pattern as .nisa-insights__card); tags are plain text.
   ----------------------------------------------- */

.nisa-cap-grids__rule,
.nisa-lt-hero__rule,
.nisa-dir__rule {
	border: none;
	border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 12%, transparent);
	width: 100%;
	opacity: 1;
}

/* -----------------------------------------------
   IDEA Team — dark hero + staggered 6-cell values grid
   (patterns/idea-hero.php)
   ----------------------------------------------- */

/* Eyebrow reads light on the navy hero (overrides .nisa-eyebrow accent). */
.nisa-idea-hero__eyebrow {
	color: var(--wp--preset--color--sky-blue);
}

/* Headline is white on navy (headings default to primary via theme.json);
   the highlighted word reads bright blue. */
.nisa-idea-hero__heading {
	color: var(--wp--preset--color--secondary);
}

.nisa-idea-hero__heading em {
	font-style: normal;
	/* bright-blue on navy was 2.82:1 — under the 3:1 AA minimum even for 80px
	   text (WCAG audit S6). bright-blue-2 is 4.55:1. */
	color: var(--wp--preset--color--bright-blue-2);
}

/* Card ↔ image spacing: a flex gap on each column owns the vertical spacing so
   it can't be cancelled by the image figure's margin reset (WP's blockGap uses
   margin-block-start on the 2nd cell, which .nisa-idea-img was zeroing in cols
   1 & 3). 20px on the outer columns, 30px on the offset middle column. */
.nisa-idea-grid > .wp-block-column {
	display: flex;
	flex-direction: column;
	gap: 20px;
}

.nisa-idea-grid > .nisa-idea-grid__col--offset {
	/* lint-allow: gap override for the offset column; display:flex is on the
	   base .nisa-idea-grid > .wp-block-column rule above */
	gap: 30px;
}

.nisa-idea-grid > .wp-block-column > * {
	/* flex-stack container exception: the gap sets the spacing, so zero any WP
	   blockGap margin-block so it can't double up */
	margin-block: 0;
}

/* Middle grid column is offset down for the staggered masonry look. */
.nisa-idea-grid__col--offset {
	/* lint-allow: deliberate vertical offset of one column vs its siblings (the
	   design's stagger) — not inter-block spacing, so blockGap can't express it */
	margin-top: clamp(1.5rem, 3vw, 2.75rem);
}

/* Value card — light-blue tile matching each image cell's proportions. */
.nisa-idea-card {
	aspect-ratio: 3 / 2;
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	padding: clamp(1.5rem, 3vw, 2rem);
	border-radius: 8px;
}

.nisa-idea-card__title {
	margin: 0;
}

.nisa-idea-card__body {
	margin: 0;
	line-height: 1.5;
}

/* Image cells match the card radius. */
.nisa-idea-img {
	margin: 0;
	border-radius: 8px;
	overflow: hidden;
}

.nisa-idea-img img {
	display: block;
	width: 100%;
	border-radius: 8px;
}

/* Mobile: drop the offset and let cards size to their content when stacked. */
@media (max-width: 781px) {
	.nisa-idea-grid__col--offset {
		margin-top: 0;
	}

	/* The middle column is authored image-then-card (it is the staggered one, so
	   the image leads on desktop). Stacked, that puts two images back to back
	   against column 1 and two cards back to back against column 3; reversing it
	   restores the card/image alternation down the whole column. Core has no
	   mobile-order control, so this can't be a block attribute. Specificity has
	   to match `.nisa-idea-grid > .wp-block-column`, which sets the base
	   `flex-direction: column`. Reading order is unaffected — the cells carry no
	   focusable content, so only the visual order changes. */
	.nisa-idea-grid > .nisa-idea-grid__col--offset {
		flex-direction: column-reverse;
	}

	.nisa-idea-card {
		aspect-ratio: auto;
	}
}

/* -----------------------------------------------
   People Grid by Role — nisa/people-grid
   (Leadership Team: Senior Leadership, Client Services, etc.)
   ----------------------------------------------- */

/* Full-bleed section; own root padding + a content-width inner (mirrors the
   person-profile block so the grid lines up with the page content column). */
.nisa-slead {
	padding-inline: var(--wp--style--root--padding-left, clamp(1rem, 4vw, 4rem));
	padding-block: clamp(2.5rem, 6vw, 4.5rem);
}

.nisa-slead__inner {
	max-width: var(--wp--style--global--content-size, 1440px);
	margin-inline: auto;
}

.nisa-slead__heading {
	/* lint-allow: heading→grid gap in the render.php block flow — no blockGap available */
	margin: 0 0 clamp(1.75rem, 3vw, 2.5rem);
}

.nisa-slead__grid {
	display: grid;
	grid-template-columns: repeat(var(--nisa-slead-cols, 4), minmax(0, 1fr));
	gap: clamp(2.25rem, 4vw, 3.25rem) 1rem;
}

.nisa-slead__card {
	display: block;
	text-decoration: none;
	color: inherit;
}

.nisa-slead__photo {
	margin: 0;
	aspect-ratio: 12 / 13;
	overflow: hidden;
	background: var(--wp--preset--color--wash);
}

/* .nisa-slead__img cover rule is consolidated with .nisa-person__photo-img above. */

.nisa-slead__name {
	/* lint-allow: name/title spacing inside the render.php card flow — no blockGap available */
	margin: 0.9rem 0 0.15rem;
}

.nisa-slead__role {
	margin: 0;
	line-height: 1.35;
}

/* a. only: a "No bio page" person renders the card as a plain div (no hover). */
a.nisa-slead__card:hover .nisa-slead__name,
a.nisa-slead__card:focus-visible .nisa-slead__name {
	color: var(--wp--preset--color--accent);
}

@media (max-width: 1024px) {
	.nisa-slead__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 520px) {
	.nisa-slead__grid {
		grid-template-columns: 1fr;
	}
}

/* -----------------------------------------------
   Team Directory — nisa/people-directory + jump nav
   (Leadership Team "Senior Team" section)
   ----------------------------------------------- */

/* Anchor targets clear the fixed header (the theme had no scroll-margin).
   Includes the /insights/ "Jump To" sections (BugHerd #359). */
.nisa-slead[id],
.nisa-dir__bucket {
	scroll-margin-top: var(--nisa-header-h, 7rem);
}

/* /insights/ "Jump To" targets: header height plus a little air so the section
   heading never sits flush under the bar. */
.nisa-ins-sec[id],
.nisa-ins-perspwrap[id] {
	scroll-margin-top: calc(var(--nisa-header-h, 7rem) + 1.5rem);
}

/* Sections that JS focuses after a same-page jump (Team jump nav, header
   same-page links) are reading positions, not controls — no browser ring
   around the whole section. Tab continues from inside it. */
.nisa-focus-target:focus {
	outline: none;
}

/* Jump nav reuses .nisa-ins-jumpnav styling; the group carries .nisa-team-jumpnav
   too as the JS smooth-scroll hook. Left alignment is set on the group in markup. */

/* Full-bleed section; own root padding + a flex-column content-width inner so
   head / rule / buckets are spaced by gap (no sibling margins). */
.nisa-dir {
	padding-inline: var(--wp--style--root--padding-left, clamp(1rem, 4vw, 4rem));
	padding-block: clamp(2rem, 5vw, 4rem);
}

.nisa-dir__inner {
	max-width: var(--wp--style--global--content-size, 1440px);
	margin-inline: auto;
	display: flex;
	flex-direction: column;
	gap: clamp(1.5rem, 3vw, 2.25rem);
}

/* Head: heading left, search + Clear All right. */
.nisa-dir__head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem 2rem;
}

.nisa-dir__heading {
	margin: 0;
}

.nisa-dir__tools {
	display: flex;
	align-items: center;
	gap: 1.25rem;
}

.nisa-dir__search {
	position: relative;
	display: flex;
	align-items: center;
}

.nisa-dir__search-input {
	width: min(30rem, 60vw);
	padding: 0.75rem 3rem 0.75rem 1.25rem;
	font-family: var(--wp--preset--font-family--inter);
	color: var(--wp--preset--color--primary);
	background: var(--wp--preset--color--secondary);
	border: 1px solid var(--wp--preset--color--lighter-blue);
	border-radius: 0.375rem;
}

.nisa-dir__search-input:focus-visible {
	outline: 2px solid var(--wp--preset--color--bright-blue);
	outline-offset: 1px;
}

.nisa-dir__search-icon {
	position: absolute;
	right: 1rem;
	width: 1.125rem;
	height: 1.125rem;
	color: var(--wp--preset--color--bright-blue);
	pointer-events: none;
}

.nisa-dir__clear {
	flex-shrink: 0;
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-style: italic;
	color: var(--wp--preset--color--primary);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.nisa-dir__clear:hover,
.nisa-dir__clear:focus-visible {
	color: var(--wp--preset--color--bright-blue);
}

/* Buckets stack; each bucket = eyebrow + card grid. */
.nisa-dir__buckets {
	display: flex;
	flex-direction: column;
	gap: clamp(2rem, 4vw, 3.25rem);
}

.nisa-dir__bucket {
	display: flex;
	flex-direction: column;
	gap: clamp(0.75rem, 1.5vw, 1.25rem);
}

.nisa-dir__eyebrow {
	color: var(--wp--preset--color--bright-blue);
}

.nisa-dir__grid {
	display: grid;
	grid-template-columns: repeat(var(--nisa-dir-cols, 3), minmax(0, 1fr));
	gap: 0 clamp(1.5rem, 3vw, 3rem);
}

/* Card: avatar + name/title, hover → light-blue + arrow. */
.nisa-dir__card {
	position: relative;
	display: flex;
	align-items: center;
	gap: 0.9rem;
	padding: 0.85rem 1rem;
	text-decoration: none;
	color: inherit;
	border-bottom: 1px solid var(--wp--preset--color--lighter-blue);
	border-radius: 0.375rem;
	transition: background-color 0.2s ease;
}

/* a. only: a "No bio page" person's card is a div — no hover fill or arrow. */
a.nisa-dir__card:hover,
a.nisa-dir__card:focus-visible {
	background: var(--wp--preset--color--light-blue);
	border-bottom-color: transparent;
}

.nisa-dir__avatar {
	flex-shrink: 0;
	width: 3rem;
	height: 3rem;
	border-radius: 50%;
	overflow: hidden;
	background: var(--wp--preset--color--wash);
}

.nisa-dir__text {
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
	min-width: 0;
}

.nisa-dir__name {
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-size: 20px; /* lint-allow: exact size set in design review, no fontSizes slug maps to 20px */
	line-height: 1.25;
	color: var(--wp--preset--color--primary);
}

.nisa-dir__role {
	font-family: var(--wp--preset--font-family--inter);
	font-size: 14px; /* lint-allow: exact size set in design review, no fontSizes slug maps to 14px */
	line-height: 1.3;
	color: var(--wp--preset--color--accent);
}

/* Decorative arrow revealed on hover, pushed to the right. */
.nisa-dir__card::after {
	content: "\2192";
	margin-left: auto;
	padding-left: 0.5rem;
	color: var(--wp--preset--color--primary);
	opacity: 0;
	transition: opacity 0.2s ease;
}

a.nisa-dir__card:hover::after,
a.nisa-dir__card:focus-visible::after {
	opacity: 1;
}

/* Filter hidden states (author rule beats UA [hidden] on flex/grid children). */
.nisa-dir__card[hidden],
.nisa-dir__bucket[hidden] {
	display: none;
}

.nisa-dir__noresults {
	margin: 0;
	color: var(--wp--preset--color--gray);
}

@media (max-width: 1024px) {
	.nisa-dir__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 640px) {
	.nisa-dir__grid {
		grid-template-columns: 1fr;
	}

	.nisa-dir__search-input {
		width: 100%;
	}
}

.nisa-cap-card {
	position: relative;
	height: 100%;
	display: flex;
	flex-direction: column;
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 12%, transparent);
	transition: background-color 0.25s ease;
}

.nisa-cap-card:hover,
.nisa-cap-card:focus-within {
	/* !important required: WP emits .has-muted-background-color with
	   !important, so the resting preset class beats any normal hover rule
	   (same counter as .nisa-btn-pill's hover). */
	background-color: var(--wp--preset--color--light-blue) !important;
}

.nisa-cap-card__tags {
	opacity: 0.8;
	margin-top: auto; /* lint-allow: flex push to the card's bottom edge, not sibling spacing — blockGap still owns gaps between siblings */
}

.nisa-cap-card__cta {
	text-align: right;
	margin-top: auto; /* lint-allow: flex push for cards without a tag list; when tags are present they absorb the slack and this resolves to the parent blockGap */
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 0.625rem; /* co-located with display:flex — bespoke flex container */
}

/* Dark card/strategy link. Consolidated (C5): also serves fi-persp-card title,
   the featured-band title, the Insights jump-nav links, and the Thought
   Leadership + News Mentions list titles. */
.nisa-cap-card__cta a,
.nisa-fi-persp-card__title a,
.nisa-persp-featured__title a,
.nisa-ins-jumpnav__link a,
.nisa-tl__title a,
.nisa-nm__title a {
	color: var(--wp--preset--color--primary);
	text-decoration: none;
}

.nisa-cap-card__cta a:hover,
.nisa-fi-persp-card__title a:hover {
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Whole-card stretched-link cover (skill Variant 2) — shared by every card
   whose single link is stretched over the card. On .nisa-cap-card the CTA uses
   ::before so ::after stays free for the plus circle; the Query-Loop title
   cards use ::after. Card must be position:relative. */
.nisa-cap-card__cta a::before,
.nisa-insights__card-title a::after,
.nisa-insight-card__title a::after,
.nisa-fi-persp-card__title a::after,
.nisa-person__name a::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 1;
}

/* Arrow circle — a right arrow inside a ring (matches the pill button's arrow
   glyph). The ring + arrow are ONE shape carved by a mask; background-color:
   currentColor paints them, so it stays token-colored with no hardcoded hex
   (mask ignores the SVG's own colors). The card bg shows through the unmasked
   interior, so on the card's light-blue hover the interior tracks the card
   automatically — no separate fill rule needed. */
.nisa-cap-card__cta::after {
	content: '';
	width: 1.875rem;
	height: 1.875rem;
	flex-shrink: 0;
	background-color: currentColor;
	color: var(--wp--preset--color--primary);
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='15' cy='15' r='14' stroke-width='1'/%3E%3Cpath d='M10 15H20' stroke-width='1.5'/%3E%3Cpath d='M16 11l4 4-4 4' stroke-width='1.5'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='15' cy='15' r='14' stroke-width='1'/%3E%3Cpath d='M10 15H20' stroke-width='1.5'/%3E%3Cpath d='M16 11l4 4-4 4' stroke-width='1.5'/%3E%3C/svg%3E");
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
	transition: transform 0.2s ease;
}

/* Subtle arrow nudge on hover — the affordance the pill button uses. */
.nisa-cap-card:hover .nisa-cap-card__cta::after,
.nisa-cap-card:focus-within .nisa-cap-card__cta::after {
	transform: translateX(2px);
}


@media (prefers-reduced-motion: reduce) {
	.nisa-cap-card,
	.nisa-cap-card__cta::after {
		transition: none;
	}
}

/* Tablet: 4-up gets too cramped below ~1200px, but core columns only know
   "one row" or "fully stacked" — wrap to a 2×2 grid in between. Row/column
   gaps come from the columns' own blockGap (top 1.5 / left 1.5), which WP
   emits as flex gap, so wrapping inherits correct spacing for free. Below
   782px core's is-stacked-on-mobile takes over (1-up). */
@media (min-width: 782px) and (max-width: 1199px) {
	/* !important required: core forces `flex-wrap: nowrap !important` on
	   .wp-block-columns at >=782px — this is the documented counter, scoped
	   to this grid and breakpoint only. */
	.nisa-cap-grids__row {
		flex-wrap: wrap !important;
	}

	.nisa-cap-grids__row > .wp-block-column {
		flex-basis: calc(50% - 0.75rem) !important;
		flex-grow: 0 !important;
	}
}

/* -----------------------------------------------
   How We Work (Figma 24:4757-4776 + 24:4751)
   Muted band: header + video placeholder card, then the ruled 1-2-3
   process list. The play affordance is DECORATIVE (CSS only) until video
   playback is wired — no button semantics on a control that does nothing.
   ----------------------------------------------- */

.nisa-video-card {
	position: relative;
	overflow: hidden;
	border-radius: 4px;
}

.nisa-video-card__media {
	margin: 0; /* UA reset — defeats browser <figure> margins */
}

.nisa-video-card__media img {
	display: block;
	width: 100%;
	aspect-ratio: 437 / 244;
	object-fit: cover;
}

/* Bottom scrim for caption legibility (comp: transparent -> black) */
.nisa-video-card::before {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.78));
	pointer-events: none;
}

/* Play circle — decorative until playback exists. Figma 127:9607: solid white
   disc, bright-blue triangle, soft drop shadow. */
.nisa-video-card::after {
	content: '\25B6';
	position: absolute;
	top: 41%;
	left: 50%;
	translate: -50% -50%;
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	border-radius: 50%;
	background-color: var(--wp--preset--color--secondary);
	color: var(--wp--preset--color--bright-blue-2);
	box-shadow: 0 8px 24px rgba(1, 46, 82, 0.22);
	font-size: 0.75rem; /* lint-allow: icon glyph inside a pseudo-element, no editor control exists for pseudo content */
	padding-left: 0.15em; /* optical centering of the triangle glyph */
}

.nisa-video-card__caption {
	position: absolute;
	inset: auto 1.5rem 1.25rem 1.5rem;
	margin-block: 0; /* abspos — blockGap margin would shift it off-anchor */
	z-index: 1;
	max-width: 25rem;
}

/* Hidden native embed — the editable Vimeo URL lives in this core/embed
   block; video-dialog.js lifts the URL and removes the iframe (display:none
   + WP's native loading="lazy" means Vimeo assets never load on page view). */
.nisa-video-card__embed {
	display: none;
}

/* Once JS provides the real play button, retire the decorative circle. */
.nisa-video-card--enhanced::after {
	display: none;
}

/* Real play button — same circle visual, whole-card hit area via inset 0.
   The visible circle is the button's ::after. */
.nisa-video-card__play {
	position: absolute;
	inset: 0;
	z-index: 2;
	border: none;
	background: none;
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
}

.nisa-video-card__play::after {
	content: '\25B6';
	position: absolute;
	top: 50%;
	left: 50%;
	translate: -50% -50%;
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	border-radius: 50%;
	background-color: var(--wp--preset--color--secondary);
	color: #d9d9d9; /* lint-allow: exact glyph grey set in design review, no palette token matches */
	box-shadow: 0 8px 24px rgba(1, 46, 82, 0.22);
	font-size: 0.75rem; /* lint-allow: icon glyph inside a pseudo-element, no editor control exists for pseudo content */
	padding-left: 0.15em; /* optical centering of the triangle glyph */
	transition: scale 0.2s ease, box-shadow 0.2s ease;
}

.nisa-video-card__play:hover::after,
.nisa-video-card__play:focus-visible::after {
	scale: 1.08;
	box-shadow: 0 10px 28px rgba(1, 46, 82, 0.28);
}

/* Hero-scale play button (Figma 127:9607 ≈ 68px disc) — featured webinar video
   and the homepage FI video hero. Larger disc + proportionally larger glyph. */
.nisa-webinar-hero__video::after,
.nisa-webinar-hero__video .nisa-video-card__play::after,
.nisa-fi-video__card::after,
.nisa-fi-video__card .nisa-video-card__play::after {
	width: 4.25rem;
	height: 4.25rem;
	font-size: 2.1rem; /* lint-allow: icon glyph inside a pseudo-element, no editor control exists for pseudo content */
}

/* Feature variant — homepage How We Work (2026-09-29 redesign). Radius,
   shadow (preset "card"), caption padding/colours and type are block
   attributes; only what blocks can't express is here: the navy scrim, the
   caption pinned full-width to the bottom edge, and a fluid 3–4.25rem play
   disc (tops out at the site's hero-scale disc) with a navy glyph. The card's own navy background colour is hidden
   behind the poster on the frontend and keeps the white caption readable
   where the editor un-stacks it below the image. */
.nisa-video-card--feature::before {
	background:
		linear-gradient(to right, rgba(1, 20, 38, 0) 45%, rgba(1, 20, 38, 0.55)),
		linear-gradient(to bottom, rgba(1, 20, 38, 0) 40%, rgba(1, 20, 38, 0.85));
}

.nisa-video-card--feature .nisa-video-card__caption {
	inset: auto 0 0 0;
	max-width: none;
}

.nisa-video-card--feature::after,
.nisa-video-card--feature .nisa-video-card__play::after {
	top: 50%;
	width: clamp(3rem, 4.5vw, 4.25rem);
	height: clamp(3rem, 4.5vw, 4.25rem);
	color: var(--wp--preset--color--primary);
	font-size: clamp(0.95rem, 1.5vw, 1.25rem); /* lint-allow: icon glyph inside a pseudo-element, no editor control exists for pseudo content */
}

.nisa-video-card__play:focus-visible {
	/* Two-tone inset ring over the poster: navy band at the edge (inset shadow,
	   0–3px) + white outline inside it (3–6px). Whatever the poster colour, one
	   of the two contrasts with it; the old single light-blue ring measured
	   1.21:1 over a light poster (WCAG 2.4.7 / 1.4.11). */
	outline: 3px solid var(--wp--preset--color--secondary);
	outline-offset: -6px;
	box-shadow: inset 0 0 0 3px var(--wp--preset--color--primary);
}

/* The modal — native <dialog>. Centering is EXPLICIT (fixed + inset 0 +
   margin auto + fit-content height): the UA stylesheet centers dialogs via
   margin:auto, but theme/WP margin resets can strip that, leaving the modal
   pinned to the top-left. This declaration set survives any reset. */
/* Transform-based centering — margin-auto centering proved unreliable here
   (used margins resolved asymmetrically and bottom-pinned the dialog, with
   no attributable CSSOM rule). translate centering has no dependencies. */
dialog.nisa-video-dialog {
	position: fixed;
	top: 50%;
	left: 50%;
	right: auto;
	bottom: auto;
	translate: -50% -50%;
	margin: 0;
}

.nisa-video-dialog {
	width: min(60rem, 92vw);
	height: fit-content;
	max-height: 90vh;
	padding: 0;
	border: none;
	border-radius: 6px;
	background: var(--wp--preset--color--primary);
	overflow: visible;
}

.nisa-video-dialog::backdrop {
	background: rgba(1, 15, 26, 0.82);
}

.nisa-video-dialog__frame {
	aspect-ratio: 16 / 9;
}

.nisa-video-dialog__frame iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: none;
	border-radius: 6px;
}

/* Close button INSIDE the dialog's top-right — always on-screen at every
   viewport (an outside-the-frame X clips on small screens and disappears
   entirely if positioning ever degrades). */
.nisa-video-dialog__close {
	position: absolute;
	top: 0.75rem;
	right: 0.75rem;
	z-index: 2;
	display: grid;
	place-items: center;
	width: 2.75rem;
	height: 2.75rem;
	border: none;
	border-radius: 50%;
	background-color: color-mix(in srgb, var(--wp--preset--color--secondary) 92%, transparent);
	color: var(--wp--preset--color--primary);
	cursor: pointer;
}

.nisa-video-dialog__close svg {
	width: 1rem;
	height: 1rem;
}

.nisa-video-dialog__close:hover {
	background-color: var(--wp--preset--color--light-blue);
}

.nisa-video-dialog__close:focus-visible {
	outline: 2px solid var(--wp--preset--color--light-blue-2);
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	.nisa-video-card__play::after {
		transition: none;
	}
}

/* Process list — hairline rules BETWEEN rows only (no opening rule),
   closing rule after the last */
/* Vertical centering is NATIVE, set per-COLUMN in the pattern (each column's
   is-vertically-aligned-center → align-self). The PARENT-level control is a
   trap: core ships `.wp-block-columns { align-items: normal !important }`,
   which silently defeats are-vertically-aligned-center and any theme
   align-items rule. Per-column align-self is untouchable by it. */
.nisa-process-row {
	/* Divider is the neutral hairline gray used by the component cards on this
	   page (darker/more visible than the pale light-blue-2). rgb() keeps the
	   linter's hex rule satisfied; value = #E1E1E1. */
	border-top: 1px solid rgb(225, 225, 225);
	padding-block: 1.875rem;
	padding-inline: 2rem;
}

/* Stacked variant (BugHerd #353): the process list sits inside the How We Work
   left column under the heading + copy (circle | heading stacked over copy).
   Its gap above the intro paragraph is the group's own block margin. */

.nisa-process-list > .nisa-process-row:first-child {
	border-top: none;
	padding-top: 0.5rem;
}

.nisa-process-list > .nisa-process-row:last-child {
	border-bottom: 1px solid rgb(225, 225, 225);
}

/* Number in a circle. The fill is the block's own Background colour (editor-
   managed; light-blue after BugHerd #355 — white was too faint on the muted
   section). Core pads any paragraph carrying .has-background, which would
   break the fixed 4rem disc, so the padding is reset here. */
.nisa-process-row__num {
	display: grid;
	place-items: center;
	width: 4rem;
	height: 4rem;
	padding: 0;
	border-radius: 50%;
}

/* How We Work steps (homepage) — the number disc. Fill, colour, type and the
   connecting line (a core/separator set to "fill" in the flex row, hidden on
   tablet/mobile via block visibility) are all editor settings; the fixed
   circle is not expressible as block attributes. Core pads any paragraph
   carrying .has-background, so padding is reset for an exact 84px disc. */
.nisa-how-work__num {
	display: grid;
	place-items: center;
	flex-shrink: 0;
	width: 5.25rem;
	height: 5.25rem;
	padding: 0;
	border-radius: 50%;
}

/* -----------------------------------------------
   Who We Serve (Figma 24:4789)
   Photo left (inset off the content edge per comp), eyebrow + heading +
   two bullet-less audience lists right.
   ----------------------------------------------- */

/* Comp floats the photo 88px in from the content edge */
.nisa-who-serve__columns {
	padding-inline-start: 5.5rem;
}

.nisa-who-serve__media {
	margin: 0; /* UA reset — defeats browser <figure> margins */
}

.nisa-who-serve__media img {
	display: block;
	width: 100%;
	aspect-ratio: 304 / 393;
	object-fit: cover;
}

.nisa-who-serve__list {
	list-style: none;
	margin: 0; /* UA reset — defeats browser <ul> margins */
	padding: 0;
}

@media (max-width: 781px) {
	.nisa-who-serve__columns {
		padding-inline-start: 0;
	}
}

/* -----------------------------------------------
   Capabilities Hero — Mobile
   ----------------------------------------------- */

@media (max-width: 781px) {
	/* core/columns stacks natively here (is-stacked-on-mobile). */
	.nisa-cap-hero {
		min-height: 0;
	}

	/* Give the stacked media column height (its photo is absolutely positioned). */
	.nisa-cap-hero__media {
		aspect-ratio: 16 / 10;
	}
}

/* -----------------------------------------------
   Breadcrumb Bar — interior pages (Yoast trail)
   Bar geometry/colors/size are native block attrs on the pattern
   (light-blue bg, primary text, xs size, 1.0625rem padding → 48px bar,
   Figma 24:4666). CSS carries only what blocks can't: weight + link states.
   ----------------------------------------------- */

.nisa-breadcrumb-bar {
	font-weight: 500;
	/* White hairline under the bar (Figma "Line 56"). Interior heroes often use
	   the same light-blue as the bar itself, so without this the two tones merge
	   into one band and the breadcrumb loses its edge. Shared class, so this
	   lands on every template that renders the bar. */
	border-bottom: 1px solid var(--wp--preset--color--secondary);
}

.nisa-breadcrumb-bar a {
	color: inherit;
	text-decoration: none;
	transition: color 0.2s ease;
}

.nisa-breadcrumb-bar a:hover,
.nisa-persp-bio__link a,
.nisa-persp-related__viewall a {
	color: var(--wp--preset--color--accent);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.nisa-breadcrumb-bar a:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* Separator (aria-hidden span injected via wpseo_breadcrumb_separator in
   inc/filters-breadcrumbs.php). Wide comp spacing; margin-inline is the
   sanctioned exception. */
.nisa-breadcrumb-bar__sep {
	margin-inline: 0.5rem;
	color: var(--wp--preset--color--accent);
}

@media (prefers-reduced-motion: reduce) {
	.nisa-breadcrumb-bar a {
		transition: none;
	}
}

/* -----------------------------------------------
   Pill Button — rounded CTA with arrow icon
   ----------------------------------------------- */

:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .wp-block-button__link {
	gap: 0.625rem;
	display: inline-flex;
	align-items: center;
	font-size: var(--wp--preset--font-size--sm);
}

/* Legacy paint for the .nisa-btn-pill class ONLY. The block style takes colour,
   radius and padding from theme.json instead, without !important, so the
   editor's own controls still win per instance — the point of moving variants
   off classes. Delete this rule once all content is on the block style. */
.nisa-btn-pill .wp-block-button__link {
	border-radius: 100vw;
	padding: 0.875rem 2rem;
	background-color: var(--wp--preset--color--accent) !important;
	border-color: var(--wp--preset--color--accent) !important;
}

:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .wp-block-button__link::after,
:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .wp-block-button__link.nisa-btn-swap::before {
	content: "";
	display: inline-block;
	width: 1.25em;
	height: 1.25em;
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E");
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E");
	mask-size: contain;
	-webkit-mask-size: contain;
	mask-repeat: no-repeat;
	-webkit-mask-repeat: no-repeat;
	background-color: currentColor;
	flex-shrink: 0;
	transition: transform 0.25s ease;
}

:is(.nisa-btn-pill, .is-style-nisa-pill-arrow) .wp-block-button__link:hover,
:is(.nisa-fi-hero__cta, .is-style-nisa-anchor-down) .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--primary) !important;
	border-color: var(--wp--preset--color--primary) !important;
	opacity: 1;
}

/* Legacy nudge hover — only when the arrow-swap JS has NOT enhanced the link
   (no-JS / reduced-motion, where custom.js returns early). */
:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .wp-block-button__link:not(.nisa-btn-swap):hover::after {
	transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {
	:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .wp-block-button__link::after {
		transition: none;
	}
}

/* -----------------------------------------------
   Pill + Play (Video) — outline pill: label, then a play triangle that does
   the Pill + Arrow swap on hover (shares every pill/swap rule above and below).
   Border, radius, padding and colours are theme.json (nisa-pill-play), so the
   editor's colour/border controls still win per instance.
   video-dialog.js opens the button's Vimeo URL in the video modal (no-JS
   visitors simply follow the link to Vimeo).
   ----------------------------------------------- */

/* Trailing solid play triangle in place of the arrow — same slot, size and
   swap motion as Pill + Arrow (custom.js opts it into .nisa-btn-swap). Two
   classes so it beats the shared arrow mask on both pseudo-elements. */
.wp-block-button.is-style-nisa-pill-play .wp-block-button__link::after,
.wp-block-button.is-style-nisa-pill-play .wp-block-button__link.nisa-btn-swap::before {
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 4.5v15l12.5-7.5z' fill='black'/%3E%3C/svg%3E");
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 4.5v15l12.5-7.5z' fill='black'/%3E%3C/svg%3E");
}

.is-style-nisa-pill-play .wp-block-button__link:is(:hover, :focus-visible) {
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--secondary);
	opacity: 1;
}

/* -----------------------------------------------
   Pill Button — arrow swap hover (Osmo button-009)
   custom.js wraps the link text in .nisa-btn-swap__text and adds
   .nisa-btn-swap to the link. Rest state: [text][arrow→]. Hover: the text
   slides right into the arrow's slot, the arrow exits right, and an
   identical arrow fades in from the left — the arrow "wraps around" the
   label. Reduced-motion users never get the class (custom.js early-returns),
   so they keep the static layout + legacy hover above. Motion spec from
   osmo.supply button-009; colors/shape/type stay NISA's own.
   ----------------------------------------------- */

:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .wp-block-button__link.nisa-btn-swap {
	position: relative;
	overflow: clip;
	/* Reserve the arrow's slot on the right: base 2rem + arrow 1.25em + the
	   0.625rem visual gap. The absolutely-positioned arrows sit inside it. */
	padding-right: calc(2rem + 1.25em + 0.625rem);
	transition: scale 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}

:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .wp-block-button__link.nisa-btn-swap:active {
	scale: 0.955 0.925;
}

.nisa-btn-swap__text {
	display: inline-block;
	transition: translate 0.5s cubic-bezier(0.32, 0.72, 0, 1);
}

/* Both arrows: out of flow, vertically centered. The vertical -50% rides in
   every translate value below so the motion never loses the centering. */
:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .nisa-btn-swap::before,
:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .nisa-btn-swap::after {
	position: absolute;
	top: 50%;
	transition: translate 0.5s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.15s ease-out;
}

:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .nisa-btn-swap::after {
	right: 2rem;
	translate: 0 -50%;
}

:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .nisa-btn-swap::before {
	left: 2rem;
	translate: -1.5em -50%;
	opacity: 0;
}

/* Hover motion is gated to real hover devices; touch users get the stable
   rest state. Reduced-motion needs no gate here — the class never exists. */
@media (hover: hover) and (pointer: fine) {
	:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .wp-block-button__link.nisa-btn-swap:is(:hover, :focus-visible) .nisa-btn-swap__text {
		translate: calc(1.25em + 0.625rem) 0;
		transition: translate 0.5s 0.075s cubic-bezier(0.32, 0.72, 0, 1);
	}

	:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .wp-block-button__link.nisa-btn-swap:is(:hover, :focus-visible)::after {
		translate: 1.5em -50%;
		opacity: 0;
		transition: translate 0.5s 0.05s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.15s 0.075s ease-out;
	}

	:is(.nisa-btn-pill, .is-style-nisa-pill-arrow, .is-style-nisa-pill-play) .wp-block-button__link.nisa-btn-swap:is(:hover, :focus-visible)::before {
		translate: 0 -50%;
		opacity: 1;
		transition: translate 0.5s 0.075s cubic-bezier(0.32, 0.72, 0, 1), opacity 0.15s 0.075s ease-out;
	}
}

/* -----------------------------------------------
   Image Reveal — clip-path wipe + scale-in
   ----------------------------------------------- */

/* Shimmer for the image-reveal placeholder background. (The hero rotating words
   no longer use this — their gradient is now static.) */
@keyframes nisa-gradient-shift {
	0%, 100% {
		background-position: 0% 50%;
	}
	50% {
		background-position: 100% 50%;
	}
}

.nisa-image-reveal {
	overflow: hidden;
	position: relative;
	background: linear-gradient(135deg, var(--wp--preset--color--primary), var(--wp--preset--color--bright-blue), var(--wp--preset--color--accent), var(--wp--preset--color--bright-blue));
	background-size: 300% 300%;
	animation: nisa-gradient-shift 4s ease-in-out infinite;
}

.nisa-image-reveal__img {
	margin: 0;
	clip-path: inset(0 100% 0 0);
	will-change: clip-path;
}

.nisa-image-reveal__img img {
	display: block;
	width: 100%;
	height: 70vh;
	object-fit: cover;
	transform: scale(1.3);
	will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
	.nisa-image-reveal__img {
		clip-path: none !important;
		will-change: auto;
	}

	.nisa-image-reveal__img img {
		transform: none !important;
		will-change: auto;
	}

	.nisa-image-reveal {
		background: none;
		animation: none;
	}
}

/* -----------------------------------------------
   Video Band — full-bleed ambient background video + parallax
   (poster shows until the video paints; JS drifts the video for parallax)
   ----------------------------------------------- */

.nisa-video-band {
	overflow: hidden;
	position: relative;
	background: var(--wp--preset--color--primary);
}

.nisa-video-band__video {
	margin: 0;
}

.nisa-video-band__video video {
	display: block;
	width: 100%;
	height: 85vh;
	object-fit: cover;
	/* Top-anchored (Beth, 2026-10-07): faces sit in the top third of the
	   footage, so the cover crop AND the parallax overscale both come off the
	   bottom. scale(1.1) from the top edge leaves 10% overflow below; the
	   drift in custom.js runs -8% → 0, so the top edge is flush at its lowest
	   point and the bottom never exposes (8% < 10%). */
	object-position: 50% 0%;
	transform-origin: 50% 0%;
	transform: scale(1.1);
	will-change: transform;
}

/* Phones: the band follows the footage's 16:9 shape (was 45vh — a near-square
   crop that cut off faces at both sides; BugHerd #865 shortened it from 85vh). */
@media (max-width: 781px) {
	.nisa-video-band__video video {
		height: auto;
		aspect-ratio: 16 / 9;
	}
}

/* Tablets: a shorter band than the 85vh desktop view. Kept as a viewport height
   rather than the phones' 16:9 aspect-ratio because at these widths 45vh still
   reads as a landscape band — nothing like the 1.03:1 near-square that made
   45vh wrong on phones (BugHerd #865).

   Ceiling is 1366px to reach tablets in LANDSCAPE as well as portrait (iPad Air
   1180, iPad Pro 12.9 1366); a 1024px ceiling only caught portrait. Note this
   also applies to a desktop window narrowed under 1366px — deliberate, since
   the band's job is to stay proportionate to the viewport, but it is why this
   does not use the theme's narrower 1199px tablet band.

   Classic iPad portrait (768px) is NOT covered here: it sits under the 781px
   phone breakpoint and gets the 16:9 treatment instead. */
@media (min-width: 782px) and (max-width: 1366px) {
	.nisa-video-band__video video {
		height: 45vh;
	}
}

@media (prefers-reduced-motion: reduce) {
	.nisa-video-band__video video {
		transform: none !important;
		will-change: auto;
	}
}

/* Pause/play toggle — bottom-right, raised clear of the insights tab bar that
   overlaps this band's bottom edge (--nisa-insights-tabs-h is written by
   insights-carousel.js; the fallback covers first paint / no-insights pages).
   Shape via .nisa-pause-btn in global.css. */
.nisa-video-band__pause-btn {
	position: absolute;
	right: clamp(1rem, 4vw, 2.5rem);
	bottom: calc(var(--nisa-insights-tabs-h, 3.5rem) + 1rem);
	z-index: 3;
	/* High-contrast over arbitrary (light or dark) video frames: near-solid
	   navy fill + white icon (~12:1), a light hairline + drop shadow so the
	   button's edge stays visible on dark footage too (WCAG 1.4.11). */
	--_pause-bg: color-mix(in srgb, var(--wp--preset--color--primary) 90%, transparent);
	--_pause-bg-hover: var(--wp--preset--color--primary);
	--_pause-color: var(--wp--preset--color--secondary);
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--secondary) 65%, transparent);
	box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
}

/* Stronger, always-visible focus ring over video (white + navy offset). */
.nisa-video-band__pause-btn:focus-visible {
	outline: 3px solid var(--wp--preset--color--secondary);
	outline-offset: 2px;
	box-shadow: 0 0 0 5px var(--wp--preset--color--primary);
}

/* -----------------------------------------------
   Insights Feed — Tabbed Slider
   ----------------------------------------------- */

/* Section — clip overflow (the tab strip's mobile scroller runs edge to edge). */
.nisa-insights {
	overflow: clip;
}

/* The Perspectives carousel's viewport: the content-width query box. Cards
   slide within it and are clipped at the content edges — no bleed past the
   page gutter (client feedback 2026-09-23). */
.nisa-insights__panel--carousel .nisa-insights__query {
	overflow: clip;
	/* Match .nisa-insights__cards / the tab-list: those are capped at the
	   content size AND inset by the page gutter (padding inside a border-box
	   group), while this alignfull query had neither, so it ran wider. Width
	   rather than padding, so the clip still lands on the content edge. */
	width: calc(min(100%, var(--wp--style--global--content-size, 1440px)) - 2 * var(--wp--style--root--padding-right, clamp(1rem, 4vw, 4rem)));
	max-width: none;
	margin-inline: auto;
}

/* ── Tab bar ───────────────────────────────────── */

/* Native core/tabs shell. The wrapper is transparent (the tab-list carries its
   own bg, the muted section bg shows through); insights-carousel.js sets the
   tab-list's margin-top to -tabListHeight so it overlaps the video band above. */
.nisa-insights__tabs {
	position: relative;
	z-index: 2;
}

/* The tab-list is the folder-tab strip. Grid (equal columns) rather than flex:
   core forces `flex: inherit !important` on the buttons, so flex:1 can't make
   them fill evenly — grid columns size them regardless. */
.nisa-insights .wp-block-tab-list {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 1fr;
	align-items: end;
	gap: 0.5rem;
	max-width: var(--wp--style--global--content-size, 1440px);
	margin-inline: auto;
	padding-inline: var(--wp--style--root--padding-right, clamp(1rem, 4vw, 4rem));
	position: relative;
	z-index: 2;
	background: transparent;
	border: 0;
}

/* Each tab — dark folder tab by default, rounded top corners. Native tab
   buttons carry aria-selected, so the active state keys off it. */
.nisa-insights .wp-block-tab-list button {
	/* Fill the grid column: core sets width:max-content + flex:inherit on tab
	   buttons, so reset width to auto and let justify-self stretch it. */
	justify-self: stretch;
	width: auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 1.125rem 1.75rem;
	border: none;
	border-radius: 0.375rem 0.375rem 0 0;
	background-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--light-blue);
	font-family: var(--wp--preset--font-family--inter);
	font-size: 15px; /* lint-allow: exact tab size set in design review, no fontSizes slug maps to 15px */
	font-weight: 500;
	line-height: 1.2;
	cursor: pointer;
	white-space: nowrap;
	transition: background-color 0.2s ease, color 0.2s ease;
}

/* Crowded row (desktop/tablet): if editors add tabs or long labels so the
   one-line folder tabs no longer fit, insights-carousel.js adds .is-crowded —
   columns go equal and labels wrap inside equal-height tabs instead of the
   row overflowing. Never set at today's three labels, so the default look is
   unchanged. (Phones use the pill scroller, which handles any count.) */
@media (min-width: 769px) {
	.nisa-insights .wp-block-tab-list.is-crowded {
		grid-auto-columns: minmax(0, 1fr);
		align-items: stretch;
	}

	.nisa-insights .wp-block-tab-list.is-crowded button {
		white-space: normal;
		text-align: left;
	}
}

.nisa-insights .wp-block-tab-list button:hover:not([aria-selected="true"]) {
	background-color: var(--wp--preset--color--accent);
}

/* Keyboard focus — the site's two-tone ring (see .wp-block-button__link in
   global.css), so it shows on the navy tabs/pills and over the video, not the
   browser's thin default. Fits the phone strip's 4px bottom padding. */
.nisa-insights .wp-block-tab-list button:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
	box-shadow: 0 0 0 4px var(--wp--preset--color--secondary);
}

/* Active tab — muted (beige) bg, dark text, blends into the section below.
   box-shadow covers the sub-pixel gap between tab bottom and section bg. */
.nisa-insights .wp-block-tab-list button[aria-selected="true"] {
	background-color: var(--wp--preset--color--muted);
	color: var(--wp--preset--color--primary);
	box-shadow: 0 1px 0 0 var(--wp--preset--color--muted);
}

/* Dot indicator (::before) — outlined bright blue on dark tabs, filled on active. */
.nisa-insights .wp-block-tab-list button::before {
	content: '';
	display: inline-block;
	width: 0.5rem;
	height: 0.5rem;
	border-radius: 50%;
	border: 1.5px solid var(--wp--preset--color--bright-blue-2);
	background: transparent;
	flex-shrink: 0;
	transition: background-color 0.2s ease, border-color 0.2s ease;
}

.nisa-insights .wp-block-tab-list button[aria-selected="true"]::before {
	/* Core positions the selected tab's ::before as an absolute bottom-left
	   indicator; keep our dot inline (static) so it sits before the label. */
	position: static;
	background-color: var(--wp--preset--color--bright-blue);
	border-color: var(--wp--preset--color--bright-blue);
}

/* ── Panels ────────────────────────────────────── */
/* Native tabs hide inactive panels via the [hidden] attribute (Interactivity
   API); we only add the top spacing. */
.nisa-insights__panel {
	padding-top: 2.5rem;
}

/* ── Track — transform-based slider ────────────── */

.nisa-insights__track {
	--_per-view: 3;
	display: flex !important;
	flex-wrap: nowrap !important;
	gap: 1.25rem;
	overflow: visible;
	margin: 0;
	padding: 0;
	transition: transform 0.5s ease;
	cursor: grab;
	touch-action: pan-y pinch-zoom;
	user-select: none;
}

.nisa-insights__track.is-dragging {
	transition: none;
	cursor: grabbing;
}

/* List items — exactly --_per-view cards fill the track (= content width):
   (track width - the gaps between them) / count. insights-carousel.js reads
   the same count from the rendered widths, so a page is always one full view. */
.nisa-insights__track > li {
	flex-shrink: 0;
	width: calc((100% - (var(--_per-view) - 1) * 1.25rem) / var(--_per-view));
	list-style: none;
}

/* ── Card ──────────────────────────────────────── */

.nisa-insights__card {
	background-color: var(--wp--preset--color--secondary);
	border: 1px solid var(--wp--preset--color--light-blue);
	border-radius: 0.25rem;
	overflow: hidden;
	height: 100%;
	display: flex;
	flex-direction: column;
	transition: box-shadow 0.25s ease, border-color 0.25s ease;
}

.nisa-insights__card-body {
	flex: 1;
	display: flex;
	flex-direction: column;
}

/* Title — serif display font, 24px clamp (lg), light weight */
.nisa-insights__card-title {
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-size: var(--wp--preset--font-size--lg) !important;
	font-weight: 300;
	line-height: 1.3;
	margin: 0;
}

/* Stretched link — makes the entire card clickable via the title anchor */
.nisa-insights__card {
	position: relative;
}

/* Inherit-color card link. Consolidated (C5): also serves the person chip's
   name→bio link + the perspective card's category pill. */
.nisa-insights__card-title a,
.nisa-insight-card__title a,
.nisa-person__name a,
.nisa-fi-persp-card__cat a,
.nisa-persp-author__name a,
.nisa-contact__phone a,
.nisa-contact__address a {
	color: inherit;
	text-decoration: none;
}

/* .nisa-insights__card-title a::after consolidated with
   .nisa-cap-card__cta a::before (stretched-link cover). C5 dedup. */

/* Date — accent blue, uppercase, more breathing room from the title */
.nisa-insights__card-date {
	color: var(--wp--preset--color--accent);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	margin-top: auto;
	padding-top: 1.25rem;
}

/* Increase gap between title and date inside card body */
.nisa-insights__card-body {
	gap: 0 !important;
}

/* Hover — gradient circle with white arrow reveals from bottom-right corner.
   Circle is centered on the card corner; overflow:hidden clips it to a quarter-circle.
   Gradient animates via background-position on an oversized linear-gradient.
   pointer-events:none lets the stretched link underneath still handle clicks. */
.nisa-insights__card::after,
.nisa-insight-card__inner::after {
	content: '';
	position: absolute;
	bottom: -3.5rem;
	right: -3.5rem;
	width: 7rem;
	height: 7rem;
	border-radius: 50%;
	background-image:
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C%2Fsvg%3E"),
		linear-gradient(135deg, var(--wp--preset--color--bright-blue), var(--wp--preset--color--accent), var(--wp--preset--color--primary));
	background-size: 1.125rem 1.125rem, 300% 300%;
	background-position: 25% 25%, 0% 0%;
	background-repeat: no-repeat, no-repeat;
	transform: scale(0);
	transform-origin: bottom right;
	transition: transform 0.25s ease-out;
	pointer-events: none;
	z-index: 2;
}

.nisa-insights__card:hover::after,
.nisa-insights__card:focus-within::after,
.nisa-insight-card__inner:hover::after,
.nisa-insight-card__inner:focus-within::after {
	transform: scale(1);
	animation: nisa-insights-card-gradient 2s linear infinite alternate;
}

@keyframes nisa-insights-card-gradient {
	from { background-position: 25% 25%, 0% 0%; }
	to   { background-position: 25% 25%, 100% 100%; }
}

/* Subtle lift + navy drop shadow on every insights-feed card on hover/focus —
   the curated Insight Cards (tabs 1 & 3) and the Perspectives query cards. */
.nisa-insight-card__inner:hover,
.nisa-insight-card__inner:focus-within,
.nisa-insights__card:hover,
.nisa-insights__card:focus-within {
	border-color: var(--wp--preset--color--lighter-blue);
	box-shadow: 0 10px 28px -8px rgba(1, 46, 82, 0.18);
}

@media (prefers-reduced-motion: reduce) {
	.nisa-insights__card::after,
	.nisa-insight-card__inner::after {
		transition: opacity 0.15s ease;
		transform: scale(1);
		opacity: 0;
		animation: none !important;
	}

	.nisa-insights__card:hover::after,
	.nisa-insights__card:focus-within::after,
	.nisa-insight-card__inner:hover::after,
	.nisa-insight-card__inner:focus-within::after {
		opacity: 1;
	}
}

/* Featured image — fill bottom of card */
.nisa-insights__card-image {
	margin: 0;
}

/* Its img shares the perspective-card image rule (3:2 cover) — see
   `.nisa-fi-persp-card__media img` (BugHerd #974; was 16 / 10). */

/* ── Insight Card (curated report card — tabs 1 & 3) ────────────── */

/* 3-up grid, constrained to the content width. */
.nisa-insights__cards {
	max-width: var(--wp--style--global--content-size, 1440px);
	margin-inline: auto;
	padding-inline: var(--wp--style--root--padding-right, clamp(1rem, 4vw, 4rem));
}

/* Each card = a one-item query loop; make it and its post-template fill the cell. */
.nisa-insight-card,
.nisa-insight-card__template,
.nisa-insight-card__template > li {
	height: 100%;
	margin: 0;
	list-style: none;
}

.nisa-insight-card__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
	background-color: var(--wp--preset--color--secondary);
	border: 1px solid var(--wp--preset--color--light-blue);
	border-radius: 0.25rem;
	overflow: hidden;
	padding: 2rem 2rem 0;
	transition: box-shadow 0.25s ease, border-color 0.25s ease;
}

.nisa-insight-card__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-weight: 300;
	line-height: 1.15;
	color: var(--wp--preset--color--primary);
}

/* Inherit-color link + stretched-link cover are shared rules — see
   .nisa-insights__card-title a (color) and .nisa-cap-card__cta a::before
   (::after cover), both of which now include .nisa-insight-card__title. */

.nisa-insight-card__dek {
	/* lint-allow: card-internal spacing over plugin post-* output (non-uniform) */
	margin: 0.75rem 0 0;
	line-height: 1.5;
	color: var(--wp--preset--color--body);
}

.nisa-insight-card__date {
	/* lint-allow: card-internal spacing over plugin post-* output (non-uniform) */
	margin: 1.25rem 0 0;
	text-transform: uppercase;
	letter-spacing: 0.05em;
}

/* Chart / featured image pinned to the bottom of the card, bleeding to its edges. */
.nisa-insight-card__chart {
	/* lint-allow: negative inline margin bleeds the image to the card edges */
	margin: 1.5rem -2rem 0;
	margin-top: auto;
	padding-top: 1.5rem;
}

.nisa-insight-card__chart img {
	display: block;
	width: 100%;
	height: auto;
	/* Fixed 3:2 like every other card image (BugHerd #974). The sources are
	   mostly 16:9, so cover trims a little off each side. */
	aspect-ratio: 3 / 2;
	object-fit: cover;
}

/* ── Footer — Subscribe (all tabs) + View All / arrows (Perspectives) ── */

.nisa-insights__footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 1.5rem;
	max-width: var(--wp--style--global--content-size, 1440px);
	margin-inline: auto;
	padding-inline: var(--wp--style--root--padding-right, clamp(1rem, 4vw, 4rem));
}

.nisa-insights__nav,
.nisa-insights__subscribe-group {
	display: flex;
	align-items: center;
	gap: 1.5rem;
	flex-wrap: wrap;
}

/* Subscribe CTA is always right-aligned. Perspectives keeps the base
   space-between (View All / arrows sit opposite it); the cards tabs have no nav,
   so their lone Subscribe group is pushed to the right rather than flex-start. */
.nisa-insights__panel--cards .nisa-insights__footer {
	justify-content: flex-end;
}

/* Carousel arrows (injected by insights-carousel.js) sit before View All. */
.nisa-insights__arrows {
	display: flex;
	gap: 0.5rem;
}

/* View All — italic serif underline link (the button-block chrome is stripped). */
.nisa-insights__view-all .wp-block-button__link {
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--wp--preset--color--primary);
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-size: 16px; /* lint-allow: exact size from the comp, no fontSizes slug maps to 16px italic */
	font-style: italic;
	font-weight: 300;
	line-height: 1.3;
	letter-spacing: 0.16px; /* lint-allow: exact tracking from the comp */
	text-decoration-line: underline;
	text-underline-offset: 0.2em;
}

.nisa-insights__view-all .wp-block-button__link:hover {
	color: var(--wp--preset--color--bright-blue);
	background: transparent;
}

.nisa-insights__subscribe-heading {
	margin: 0;
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-size: var(--wp--preset--font-size--xl);
	font-weight: 300;
	line-height: 1.15;
	color: var(--wp--preset--color--primary);
}


/* -----------------------------------------------
   Insights Feed — Mobile
   ----------------------------------------------- */

/* Tablet: 2 cards per view */
@media (max-width: 1024px) {
	.nisa-insights__track {
		--_per-view: 2;
	}
}

/* 2 cards fill content width, card 3 bleeds */
@media (max-width: 768px) {
	/* Tab strip becomes a horizontal scroller that bleeds edge-to-edge.
	   --_edge is the page's content inset; we cancel the section's global
	   padding with a negative margin, then re-apply it as scroll padding so the
	   first/last tab still line up with the content while the strip itself runs
	   to both viewport edges (a partial next tab peeks to signal scrollability). */
	.nisa-insights__tabs {
		--_edge: var(--wp--style--root--padding-left, clamp(1rem, 4vw, 4rem));
		overflow: hidden;
		margin-inline: calc(-1 * var(--_edge));
	}

	.nisa-insights .wp-block-tab-list {
		/* Back to a horizontal flex scroller on mobile (the desktop grid would
		   force-fit all tabs; here they keep intrinsic width and scroll). */
		display: flex;
		flex-wrap: nowrap;
		align-items: center;
		gap: 0.5rem;
		max-width: none;
		margin: 0;
		/* Pills sit on the off-white section, clear of the video (no overlap on
		   phones). The 4px bottom keeps the focus ring inside the scroller. */
		padding: 1.5rem var(--_edge) 0.25rem;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
		scroll-snap-type: x proximity;
		scroll-padding-inline: var(--_edge);
		overscroll-behavior-x: contain;
	}

	.nisa-insights .wp-block-tab-list::-webkit-scrollbar {
		display: none;
	}

	/* Rounded pills (Beth + designer, 2026-10-07). Keyed to whatever buttons
	   core/tabs outputs — any number, any label: the strip scrolls; a label too
	   long for the screen wraps inside its pill instead of overflowing. */
	.nisa-insights .wp-block-tab-list button {
		flex: 0 0 auto;
		justify-self: auto;
		width: max-content;
		max-width: calc(100vw - 2 * var(--_edge) - 2rem);
		padding: 0.7rem 1.15rem;
		border: 1px solid var(--wp--preset--color--lighter-blue);
		border-radius: 999px;
		background-color: var(--wp--preset--color--secondary);
		color: var(--wp--preset--color--primary);
		white-space: normal;
		text-align: center;
		scroll-snap-align: start;
	}

	.nisa-insights .wp-block-tab-list button:hover:not([aria-selected="true"]) {
		background-color: var(--wp--preset--color--wash);
	}

	.nisa-insights .wp-block-tab-list button[aria-selected="true"] {
		border-color: var(--wp--preset--color--primary);
		background-color: var(--wp--preset--color--primary);
		color: var(--wp--preset--color--secondary);
		box-shadow: none;
	}

	/* Pills read as buttons on their own — no folder-tab status dot. */
	.nisa-insights .wp-block-tab-list button::before {
		display: none;
	}

	/* Pills → cards: one 24px gap (4px strip padding + 20px). The desktop
	   values (blockGap 19px + 40px panel padding) suit the folder tabs only. */
	.nisa-insights .wp-block-tab-panels {
		margin-block-start: 0;
	}

	.nisa-insights__panel {
		padding-top: 1.25rem;
	}

	/* The tabs wrapper runs edge to edge here (for the tab-strip scroller), so
	   put the page gutter back on the carousel's viewport — as margin, not
	   padding, so the overflow clip lands on the gutter line. */
	.nisa-insights__panel--carousel .nisa-insights__query {
		width: auto;
		margin-inline: var(--_edge);
	}

	/* Curated cards stack (core's fixed 3-col grid doesn't reflow on its own). */
	.nisa-insights__cards {
		grid-template-columns: 1fr;
	}

	/* Drop the serif label on tighter screens — the Subscribe button carries it. */
	.nisa-insights__subscribe-heading {
		display: none;
	}
}

/* Phone: 1 card per view */
@media (max-width: 600px) {
	.nisa-insights__track {
		--_per-view: 1;
	}
}

@media (max-width: 480px) {
	.nisa-insights__footer {
		flex-wrap: wrap;
		gap: 1.5rem;
	}
}

/* -----------------------------------------------
   Insights Feed — Reduced Motion
   ----------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.nisa-insights__track {
		transition: none;
	}
}

/* -----------------------------------------------
   Why NISA — Headline + Stat
   ----------------------------------------------- */

/* Defined band with content vertically centered, matching the Figma
   (~511px @ 1440). min-height scales with width and is capped; symmetric
   section padding + justify-center keep the heading/stat block in the middle.
   Content taller than the band (mobile stacked) just grows the section. */
.nisa-why-nisa {
	min-height: clamp(22rem, 35.5vw, 32rem);
	display: flex;
	flex-direction: column;
	justify-content: center;
}

/* The section is a COLUMN flex container (above), so its child sits on the
   cross axis, and WP's constrained-layout `margin-inline: auto` defeats the
   stretch default — leaving the row shrink-wrapped to its max-content width and
   centred by those auto margins. That went unnoticed while the content was wide
   enough to fill the line; once the heading took a max-width it fell short and
   the whole row drifted right, off the left edge that "Our Distinguished
   Approach" below shares. width:100% fills the line again, so the auto margins
   resolve to 0 and the row starts on that edge. The child keeps its own
   max-width from the group's constrained layout, so wide viewports still cap
   and centre exactly like the Approach section. */
.nisa-why-nisa > .nisa-why-nisa__columns {
	width: 100%;
}

/* Gradient text on the emphasised words — the static hero dark->light gradient.
   Why NISA sits on WHITE, so it takes the exact hero gradient. Non-italic, like
   the About hero/stats words below; the homepage hero word is the only gradient
   word still italic. */
.nisa-why-nisa__heading em {
	font-style: normal;
	background: var(--wp--preset--gradient--hero-word);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
}

/* About Us hero + stats sit on light-blue, so they take the `-onblue` gradient:
   the standard hero-word ramp ends at #0498D7, which measures ~2.5:1 against
   #D7E9F6 — under the 3:1 large-text floor. `hero-word-onblue` ends at #0378AA
   (~3.4:1) and passes. Non-italic per the comps (only the homepage hero word is
   still italic). NOTE: on About Us #20 one heading carries BOTH
   nisa-why-nisa__heading and nisa-about-stats__heading; both rules now set
   font-style: normal, so the source-order tie between them no longer decides
   anything — but they still differ in gradient, and this one wins. Also serves
   the In Our Community #21 hero — Figma node 4971:10598. */
.nisa-about-hero__heading em,
.nisa-about-stats__heading em {
	font-style: normal;
	background: var(--wp--preset--gradient--hero-word-onblue);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
}

/* Tablet: the four AUM figures are too cramped in one row, so wrap them 2x2.
   Same counter as .nisa-aum-grid — core forces flex-wrap:nowrap at >=782px, so
   both declarations need !important to land. Basis is 50% minus half the
   block's own 2rem blockGap. Below 782px core stacks them 1-up already.
   Ceiling is 1064px, not the 1024px used by the other tablet-band rules: the
   long labels under these figures need the extra room before they sit 4-up. */
@media (min-width: 782px) and (max-width: 1064px) {
	.nisa-about-stats__grid {
		flex-wrap: wrap !important;
	}

	.nisa-about-stats__grid > .wp-block-column {
		flex-basis: calc(50% - 1rem) !important;
		flex-grow: 0 !important;
	}
}

/* Top-aligned column flex. Consolidated (C5): the Why NISA stat column, the
   AUM stat cards, and the boxed Careers CTA's text column. Each stretches to a
   taller sibling (the heading beside it, the AUM row's tallest card / --tall's
   250px floor, the CTA box's image), so the slack falls below the content.
   align-items stays at its stretch default, so children keep full width and
   text stays left-aligned. */
.nisa-why-nisa__right,
.nisa-aum-grid .nisa-aum-card,
.nisa-media-cta__box .nisa-media-cta__text {
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
}

/* Stat number — IvyPresto; inherits its size from the .nisa-stat__value group */
.nisa-stat__number {
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	line-height: 1.25;
	margin: 0;
}

/* Dollar sign — IvyPresto, pulled tight, and always 60% of its figure.
   The stat's size lives on the .nisa-stat__value GROUP (Typography panel);
   the number inherits it and the $ is 0.6em of it, so the ratio can't drift
   per block or per breakpoint (fluid presets bottom out at different ratios,
   which is how the $ ended up 29–75% of its figure). Don't give the $ its own
   font size — a preset class on it wins over this rule. */
.nisa-stat__dollar {
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-size: 0.6em; /* lint-allow: sized relative to the stat group, not a text preset */
	margin: 0;
	margin-right: -0.15em;
	/* Drop the $ so its top meets the figure's top. em, not %: a % margin
	   resolves against the CONTAINER WIDTH, so the old 5% sat the $ 5–14px low
	   in narrow AUM cards and a few px high in wide rows. Measured: with no
	   margin the $ ink sits 15.2% of the figure above the digits' top, i.e.
	   0.152 / 0.6 ≈ 0.25em of the $ — holds at every size/breakpoint.
	   !important beats block-level margin:0 some stats carry inline. */
	margin-top: 0.25em !important; /* lint-allow: client-requested $ top-alignment nudge */
}

/* Stat value row — tighten baseline gap */
.nisa-stat__value {
	gap: 0 !important;
	
}
.nisa-aum-total__row .nisa-stat__value {
	margin-left: 130px !important;
	margin-right: 130px !important;
}

/* Stat label — pull up to compensate for number's line-height whitespace */
.nisa-stat__label {
	margin: 0;
	margin-top: -1.25rem !important;
}

.nisa-stat__label sup,
.nisa-why-nisa__footnote sup {
	font-size: 0.65em; /* lint-allow: superscript sized relative to its parent, not a text preset */
	vertical-align: super;
	line-height: 0;
}

/* Footnote — tighter spacing, light weight */
.nisa-why-nisa__footnote {
	margin-top: auto;
	padding-top: 2rem;
}

/* .nisa-why-nisa__footnote sup consolidated with .nisa-stat__label sup. C5 dedup. */

/* -----------------------------------------------
   Why NISA — Mobile
   ----------------------------------------------- */

@media (max-width: 781px) {
	.nisa-why-nisa__right {
		align-items: flex-start;
	}
}

/* -----------------------------------------------
   Our Distinguished Approach
   ----------------------------------------------- */

/* Section — the blue→transparent wash is a native theme.json gradient preset
   applied on the block ("approach-wash"). Here we only host the decorative
   dot-grid pattern (::before), which has no native equivalent, behind the
   content (z-index -1 inside an isolated context). */
/* .page-id-21 .nisa-ins-resources rides along because the In Our Community
   support band carries the same dot field in the comp (Figma 4857:5862 — the
   same 548x467 vector as this section), and the class is shared with the
   /insights/ resources band, which has no dots. */
.nisa-why-nisa-approach,
.wp-block-group.is-style-nisa-dot-grid,
.page-id-21 .nisa-ins-resources {
	position: relative;
	isolation: isolate;
}

/* Dot Grid — Group block style. These are the section's original Figma dots,
   moved off .nisa-why-nisa-approach so the treatment is CHOSEN in the editor:
   Default renders no dots, "Dot Grid" renders these. (The Insights hero keeps
   its own finer radial-gradient field above — a different visual.) */
.wp-block-group.is-style-nisa-dot-grid::before,
.page-id-21 .nisa-ins-resources::before {
	content: "";
	position: absolute;
	top: 30px; /* lint-allow: exact dot-field inset set in design review */
	right: 30px; /* lint-allow: exact dot-field inset set in design review */
	width: min(46vw, 620px);
	aspect-ratio: 548 / 467;
	/* Exported straight from Figma — the per-dot white→navy gradient/opacity fade
	   is baked into the SVG, so no CSS mask is needed. */
	background: url("../images/approach-dots.svg") no-repeat top right / contain;
	pointer-events: none;
	z-index: -1;
}

/* In Our Community sits on the light-blue band, where white dots vanish into
   the copy. Same dot field, gradient re-based from sky-blue (a branded blue one
   step darker than the band) to navy — see community-dots.svg. BugHerd #381. */
.page-id-21 .nisa-ins-resources::before {
	background-image: url("../images/community-dots.svg");
}

/* Pillars — each column stacks icon → heading → body → divider; flex column so
   the divider pins to the bottom and lines up across columns of unequal copy. */
.nisa-approach__item {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}

/* Icon tiles — the navy fill, light-blue glyph color, and corner radius are
   native block supports (backgroundColor / textColor / border.radius on the
   group). Only the fixed size + glyph centering live here, since core has no
   width/height control for a group. Glyph strokes inherit currentColor. */
/* Selector is deliberately two classes deep. WP's layout reset
   `:root :where(.is-layout-flow) > * { margin-block: 0 }` has the SAME
   specificity as a single class (`:where()` contributes none), so which one
   wins is decided by source order — the theme loads last on the frontend but
   WP's reset is injected last in the editor canvas, which silently flattened
   the gap below the icon tile to 0 there. The extra class wins in both. */
.nisa-approach__item .nisa-approach__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	flex-shrink: 0;
	/* lint-allow: fixed gap below the icon tile (heading has margin-top:0 here) */
	margin-bottom: 1.25rem;
}

.nisa-approach__item .nisa-approach__icon svg {
	display: block;
	width: 100%;
	height: 100%;
}

.nisa-approach__item .wp-block-heading {
	margin-top: 0 !important;
}

.nisa-approach__item .wp-block-heading + p {
	/* lint-allow: overrides the global margin-based vertical rhythm (see global.css) */
	margin-top: 0.75rem !important;
	/* lint-allow: gap between the pillar copy and the bottom divider (the divider
	   is border-top + margin-top:auto, so the gap must sit above it, here). */
	margin-bottom: 2rem !important;
}

/* Divider under each pillar — pushed to the column base, full width, with a
   generous gap above the line. */
.nisa-approach__sep {
	border-color: var(--wp--preset--color--light-blue);
	width: 100%;
	/* lint-allow: pins the divider to the column base within the margin rhythm */
	margin-top: auto !important;
	margin-bottom: 0 !important;
}

/* ============================================================
   CAPABILITIES SECTION
   ============================================================ */

.nisa-capability-row {
	position: relative;
	border-bottom: 1px solid var(--wp--preset--color--light-blue);
	cursor: pointer;
}

/* Swipe background — scales from top on hover, slow ease-out on close for stagger feel */
.nisa-capability-row::after {
	content: '';
	position: absolute;
	inset: 0.3125rem 0;
	border-radius: 0.25rem;
	background-color: var(--wp--preset--color--light-blue);
	transform: scaleY(0);
	transform-origin: center;
	transition: transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1);
	z-index: 0;
}

.nisa-capability-row:hover::after,
.nisa-capability-row.is-active::after {
	transform: scaleY(1);
	transition: transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

/* Name — grows to fill available space, pushing arrow right */
.nisa-capability-row__name {
	flex-grow: 1;
	position: relative;
	z-index: 1;
}

.nisa-capability-row__name a {
	color: var(--wp--preset--color--accent);
	text-decoration: none;
}

.nisa-capability-row__name a::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 2;
}

.nisa-capability-row__arrow {
	flex-shrink: 0;
	position: relative;
	z-index: 1;
}

/* ── Search Across Strategies bar ──────────────────
   Dark label + input + round icon button. NOTE: submit target/behaviour is a
   placeholder (posts to site search) — final search function is TBD. */
.nisa-cap-search {
	display: flex;
	align-items: stretch;
	max-width: 896px;
	/* lint-allow: top gap to the list above (the wp:html form doesn't receive the section blockGap) */
	margin: 3.5rem auto 0;
	background-color: var(--wp--preset--color--secondary);
	border: 1px solid var(--wp--preset--color--mid-blue);
	border-radius: 0.625rem;
	overflow: hidden;
}

.nisa-cap-search__label {
	display: flex;
	align-items: center;
	flex-shrink: 0;
	background-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--secondary);
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 400;
	line-height: 1.15;
	padding: 1.1875rem 1.75rem;
	white-space: nowrap;
}

/* Responsive label: full text on tablet/desktop, short "Search" on mobile. */
.nisa-cap-search__label-short {
	display: none;
}

.nisa-cap-search__input {
	flex: 1 1 auto;
	min-width: 0;
	border: none;
	background: transparent;
	padding: 0 1.5rem;
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--md);
	color: var(--wp--preset--color--body);
}

.nisa-cap-search__input:focus {
	outline: none;
}

.nisa-cap-search__btn {
	flex-shrink: 0;
	align-self: center;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	margin-right: 1rem;
	border: none;
	border-radius: 50%;
	background-color: var(--wp--preset--color--light-blue);
	color: var(--wp--preset--color--accent);
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.nisa-cap-search__btn:hover {
	background-color: var(--wp--preset--color--lighter-blue);
}

.nisa-cap-search__btn svg {
	width: 1.25rem;
	height: 1.25rem;
}

/* -----------------------------------------------
   Capabilities — Mobile
   ----------------------------------------------- */

@media (max-width: 781px) {
	.nisa-capabilities__grid {
		gap: 0 !important;
	}

	.nisa-capabilities__col + .nisa-capabilities__col {
		border-top: none;
	}

	.nisa-cap-search__label-full {
		display: none;
	}

	.nisa-cap-search__label-short {
		display: inline;
	}
}

/* ============================================================
   RECOGNITION SECTION
   ============================================================ */

/* Laurel icon above the heading (Figma node 1:1792, exported SVG) */
.nisa-recognition__laurel {
	color: var(--wp--preset--color--light-blue-2);
	line-height: 0;
}

.nisa-recognition__laurel svg {
	display: block;
	width: 54px;
	height: 40px;
}

/* Right column: capped-height, internally-scrolling disclosure list.
   The viewport is the positioning context for the bottom fade overlay;
   the content is the scroll container (JS adds data-lenis-prevent so the
   inner scroll wins over Lenis page-scroll). */
.nisa-recognition__viewport {
	position: relative;
	height: 32rem;
	overflow: hidden;
}

.nisa-recognition__content {
	will-change: transform;
}

/* Marquee — recognition.js clones the items once and sets --nisa-recog-shift
   (one set's height) + --nisa-recog-duration; the track loops up by that
   distance. Pause via the button (animation-play-state). */
.nisa-recognition__content.is-animated {
	animation: nisa-recog-scroll var(--nisa-recog-duration, 30s) linear infinite;
}

@keyframes nisa-recog-scroll {
	from {
		transform: translateY(0);
	}
	to {
		transform: translateY(calc(var(--nisa-recog-shift, 0px) * -1));
	}
}

/* Award items — hairline separator between entries. Measure is capped
   (matches the comp's ~80% body width) so the text rag and dividers pull in,
   leaving clear space before the scroll indicator + a more readable line
   length. Left-aligns within the flex column; releases on smaller widths. */
.nisa-recognition__item {
	max-width: 41rem;
	border-bottom: 1px solid color-mix(in srgb, var(--wp--preset--color--light-blue-2) 28%, transparent);
}

.nisa-recognition__item:last-child {
	border-bottom: none;
}

/* Top + bottom fades — content dissolves into the navy at both edges as it
   cycles; the top fade is shorter than the bottom. */
.nisa-recognition__viewport::before,
.nisa-recognition__viewport::after {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	pointer-events: none;
	z-index: 1;
}

.nisa-recognition__viewport::before {
	top: 0;
	height: 4rem;
	background: linear-gradient(to bottom, var(--wp--preset--color--primary), rgba(1, 46, 82, 0));
}

.nisa-recognition__viewport::after {
	bottom: 0;
	height: 8rem;
	background: linear-gradient(to top, var(--wp--preset--color--primary), rgba(1, 46, 82, 0));
}

/* Pause/play control — bottom-right, above the fades. Shape via .nisa-pause-btn
   (global.css). */
.nisa-recognition__pause-btn {
	position: absolute;
	bottom: 0.75rem;
	right: 0.75rem;
	z-index: 2;
}

/* -----------------------------------------------
   Recognition — Mobile
   ----------------------------------------------- */

@media (max-width: 781px) {
	.nisa-recognition__left {
		text-align: center;
	}

	.nisa-recognition__laurel svg {
		margin-inline: auto;
	}
	/* Marquee stays active on mobile (same as desktop) — only the reduced-motion
	   block below opts out. */
}

/* Reduced motion — no marquee; the list shows at natural height (JS skips too). */
@media (prefers-reduced-motion: reduce) {
	.nisa-recognition__viewport {
		height: auto;
		overflow: visible;
	}

	.nisa-recognition__viewport::before,
	.nisa-recognition__viewport::after {
		display: none;
	}
}

/* ============================================================
   CTA BAND — "Discuss Your Portfolio" (full-bleed photo + overlay)
   Figma node 18:4220. Photo inset ~24px on the muted section bg
   (square corners); centered heading + pill over a soft scrim.
   ============================================================ */

.nisa-cta-band__frame {
	position: relative;
	overflow: hidden;
	min-height: clamp(26rem, 43vw, 40rem);
}

/* Photo fills the frame (object-fit cover crops to the band ratio) */
.nisa-cta-band__img {
	position: absolute;
	inset: 0;
}

.nisa-cta-band__img img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
}

/* Centered overlay — heading + CTA */
.nisa-cta-band__overlay {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2rem;
	padding: 2rem;
	text-align: center;
}

/* Soft dark scrim behind the text for legibility (Figma 1:1807 —
   rgba(0,0,0,.5), 50px layer blur, 200px radius). Sits behind content. */
.nisa-cta-band__overlay::before {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: min(37.9rem, 82%);
	height: 15.25rem;
	transform: translate(-50%, -50%);
	background: rgba(0, 0, 0, 0.5);
	border-radius: 200px;
	filter: blur(50px);
	z-index: 0;
}

.nisa-cta-band__overlay > *,
.nisa-ins-hero > * {
	position: relative;
	z-index: 1;
}

/* CTA band heading width is now the Max Width block extension
   (atomicMaxWidth:34rem, flush-left OFF) on the heading — editable in the
   panel, set in both the live page and patterns/cta-band.php. Centering is the
   flex parent (.nisa-cta-band__overlay align-items:center), unaffected. Was
   max-width:34rem here. */

/* ===============================================================
   FIXED INCOME — Capability Detail Page (Figma 1:2225)
   Sections: hero (graphic + stat), our approach + expert quote,
   strategies grid (reuses .nisa-cap-card), video feature (reuses
   .nisa-video-card + video-dialog.js), perspectives query loop,
   related capabilities (reuses .nisa-capability-row).
   =============================================================== */

/* ---- Hero ---- */
.nisa-fi-hero {
	position: relative;
	/* z-index lifts the hero (and its overhanging stat box) above the
	   following section so the stat can hang past the panel's bottom edge. */
	z-index: 1;
	min-height: clamp(24rem, 42vw, 32rem);
	/* Full-bleed section: zero the block's own padding (the root-padding-aware
	   left/right inset alignfull blocks pick up, plus the columns' default
	   block padding) so the media panel fills the full height and bleeds to the
	   viewport edge. The content column re-adds its own inset via native padding. */
	padding: 0;
}

/* Columns render content-box in this theme; keep each column's native padding
   inside its 50% flex basis so the split stays exactly even. */
.nisa-fi-hero > .wp-block-column {
	box-sizing: border-box;
}

/* .nisa-fi-hero is a core/columns block: the 50/50 split (column widths), the
   per-column vertical alignment (content center / media stretch), the seam gap
   (blockGap 0) and the content column's inset padding are all native block
   attributes now — no CSS for them. CSS below is only what blocks can't express:
   the panel fill, the stat overhang, and the placeholder image's blend. */

.nisa-fi-hero__heading {
	line-height: 1.05;
}

.nisa-fi-hero__subhead {
	/* max-width moved to the block's Max Width control (editor-max-width.js) */
	line-height: 1.3;
}

/* Down-arrow scroll pill — anchors to #strategies. Not .nisa-btn-pill, so the
   arrow-swap JS (custom.js) leaves it alone; the circle + glyph mirror the
   .nisa-cap-card plus circle recipe (glyph content, token colors, no hex). */
:is(.nisa-fi-hero__cta, .is-style-nisa-anchor-down) .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	transition: background-color 0.25s ease;
}

/* Legacy paint — .nisa-fi-hero__cta only (see the pill note above). */
.nisa-fi-hero__cta .wp-block-button__link {
	border-radius: 100vw;
	padding: 0.4375rem 0.5rem 0.4375rem 1.75rem;
	background-color: var(--wp--preset--color--accent) !important;
	border-color: var(--wp--preset--color--accent) !important;
}

:is(.nisa-fi-hero__cta, .is-style-nisa-anchor-down) .wp-block-button__link::after {
	content: '\2193';
	display: grid;
	place-items: center;
	width: 2.125rem;
	height: 2.125rem;
	flex-shrink: 0;
	border-radius: 50%;
	background-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--secondary);
	font-size: 1rem; /* lint-allow: icon glyph inside a pseudo-element, no editor control exists for pseudo content */
	line-height: 1;
	margin-inline-start: 0.75rem;
	transition: background-color 0.25s ease, color 0.25s ease, transform 0.2s ease;
}

/* .nisa-fi-hero__cta .wp-block-button__link:hover consolidated with
   .nisa-btn-pill .wp-block-button__link:hover. C5 dedup. */

/* The disc is `primary`, and hover fills the PILL with `primary` too (the
   consolidated .nisa-btn-pill hover rule) — so the disc would vanish into the
   button. Invert it on hover: light disc, dark arrow. Both states stay high
   contrast (white on #012E52, and #012E52 on #D7E9F6). */
:is(.nisa-fi-hero__cta, .is-style-nisa-anchor-down) .wp-block-button__link:hover::after {
	transform: translateY(2px);
	background-color: var(--wp--preset--color--light-blue);
	color: var(--wp--preset--color--primary);
}

/* .nisa-fi-hero__media consolidated with .nisa-cap-hero__media (C5 — see the
   "Hero media columns" rule in the Capabilities Hero section). */

/* Light-blue panel that fills the entire right half and bleeds to the right
   viewport edge; the art is cropped to it. overflow:hidden clips the art to the
   panel; the stat lives OUTSIDE this box so it isn't clipped. */
.nisa-fi-hero__graphic {
	margin: 0; /* UA reset — defeats browser <figure> margins */
	position: absolute;
	inset: 0;
	overflow: hidden;
	background-color: var(--wp--preset--color--light-blue);
}

/* Hero line art — inline SVG via the atomic/svg block, so custom.js can reach
   the individual strokes for the draw-on (an <img src> can't be animated, which
   is why this replaced the flattened PNG and its mix-blend-mode hack).
   The stroke colour rides currentColor: the file itself carries no colour, so
   the art is themeable from here and the media-library asset stays neutral.
   preserveAspectRatio="xMidYMid slice" on the SVG is the object-fit:cover
   equivalent — the art bleeds past the panel edges as the mockup intends. */
.nisa-hero-art {
	position: absolute;
	inset: 0;
	color: var(--wp--preset--color--art-blue);
}

/* Stat box overlaps the bottom of the panel — offset from the panel's left
   edge, near the right viewport edge, hanging below the panel's bottom into
   the following section (comp 1:2568). Anchored to the media column. */
.nisa-fi-hero__stat {
	position: absolute;
	left: clamp(1.5rem, 15%, 9rem);
	right: clamp(0.75rem, 1.5vw, 1.5rem);
	bottom: 0;
	transform: translateY(38%);
	z-index: 2;
}


/* ---- Our Approach + expert quote ---- */
.nisa-fi-approach__heading,
.nisa-strategy-stripe__heading {
	line-height: 1.08;
}

/* Strategy stripes (patterns/strategy-stripe.php) — the sub-strategy sections
   that replaced the grandchild pages. Each carries the old page slug as its
   anchor so the mega menu jumps straight to it; clear the fixed header. */
.nisa-strategy-stripe[id],
.nisa-strategy-intro[id] {
	scroll-margin-top: calc(var(--nisa-header-h, 7rem) + 1.5rem);
}

/* Stripe rows mirror the Our Approach row's 24/43/30 columns so title and
   copy edges line up exactly (that row overflows slightly and flex-shrinks,
   so only an identical column set shrinks identically). The 30% column is an
   intentionally empty spacer — drop it once the columns stack. */
@media (max-width: 781px) {
	.nisa-strategy-stripe__aside:empty {
		display: none;
	}
}

/* Stripe "Learn more about …" Details toggle — the full strategy paragraph
   sits behind it. <summary> can't take link styles from the editor, so it
   borrows the theme link look (accent, underlined, primary on hover) and
   swaps the browser triangle for a plus that becomes a minus when open. */
.nisa-strategy-stripe__more > summary {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	cursor: pointer;
	list-style: none;
	color: var(--wp--preset--color--accent);
	text-decoration: underline;
	text-underline-offset: 0.2em;
	transition: color 0.2s ease;
}

.nisa-strategy-stripe__more > summary::-webkit-details-marker {
	display: none;
}

.nisa-strategy-stripe__more > summary::after {
	content: "";
	flex-shrink: 0;
	width: 0.75em;
	height: 0.75em;
	background:
		linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat,
		linear-gradient(currentColor, currentColor) center / 2px 100% no-repeat;
	transition: background-size 0.2s ease;
}

/* Open: the vertical bar collapses, leaving a minus. */
.nisa-strategy-stripe__more[open] > summary::after {
	background-size: 100% 2px, 2px 0;
}

.nisa-strategy-stripe__more > summary:hover {
	color: var(--wp--preset--color--primary);
}

.nisa-strategy-stripe__more > summary:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	.nisa-strategy-stripe__more > summary,
	.nisa-strategy-stripe__more > summary::after {
		transition: none;
	}
}

/* Details block style "Toggle Below" (inc/block-styles.php) — opened content
   renders above the summary. <details> as a flex column lets `order` move the
   summary after the content box; the DOM (and so reading/focus order) is
   unchanged. Where a browser ignores `display` on <details>, this degrades to
   the core layout (content below the toggle). The open summary picks up the
   block gap so it doesn't sit flush under the revealed text. */
.wp-block-details.is-style-nisa-toggle-below {
	display: flex;
	flex-direction: column;
}

.wp-block-details.is-style-nisa-toggle-below > summary {
	order: 1;
}

/* Flow layout gives the first revealed block a top margin because it follows
   <summary> in the DOM — but visually it's now first, directly under the
   Details block's own margin, so the two would stack into a double gap. */
.wp-block-details.is-style-nisa-toggle-below > summary + * {
	margin-block-start: 0; /* lint-allow: reset of the flow-layout sibling margin, which no longer sits between siblings once summary is reordered */
}

.wp-block-details.is-style-nisa-toggle-below[open] > summary {
	margin-block-start: var(--wp--style--block-gap, 1.5rem); /* lint-allow: <summary> is not a block, so blockGap cannot space it once reordered below the content */
}

/* Divider under the intro lede — same colour/weight as the Why NISA pillar
   rules (.nisa-approach__sep), sized to one pillar column and centred. */
.nisa-strategy-intro__sep {
	border-color: var(--wp--preset--color--light-blue);
	width: min(100%, 28rem);
	margin-inline: auto;
}

.nisa-fi-approach__quote {
	position: relative;
	/* Hanging opening quote: indent the body so the ::before mark hangs in the
	   gutter at the column's left edge — flush with the eyebrow / name — while
	   the quote lines stay optically aligned (comp 1:2672). */
	padding-left: 0.7em;
}

/* Opening quote mark — decorative; navy to match the quote; the closing curly
   quote stays inline in the copy. */
.nisa-fi-approach__quote::before {
	content: '\201C';
	position: absolute;
	top: 0;
	left: 0;
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-size: 1.15em; /* lint-allow: decorative glyph in a pseudo-element, no editor control for pseudo content */
	line-height: 1;
	color: inherit;
}

/* "Hear more…" — italic serif link (fontFamily + size are block attrs). */
/* Italic serif links — the FI "Hear more" and the Perspectives "View All". */
.nisa-fi-approach__hear a,
.nisa-fi-perspectives__viewall a {
	font-style: italic;
	color: var(--wp--preset--color--accent);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Person chip (nisa/person block) — photo + name + title, content-driven from
   the People CPT. Used in the FI expert quote and anywhere a person is featured
   (base 60px round avatar + serif name + blue role, matching the FI comp). */
.nisa-person {
	position: relative; /* containing block for the stretched name→bio link */
	display: flex;
	align-items: center;
	gap: 0.875rem;
}

.nisa-person__photo {
	flex-shrink: 0;
	width: 60px;
	height: 60px;
	margin: 0; /* UA reset — defeats browser <figure> margins */
	border-radius: 50%;
	overflow: hidden;
}

.nisa-person__photo-img,
.nisa-slead__img,
.nisa-dir__avatar-img,
.nisa-persp-author__avatar-img,
.nisa-persp-bio__avatar-img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.nisa-person__text {
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
}

.nisa-person__name {
	margin: 0; /* UA reset — defeats browser <p> margins */
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-size: var(--wp--preset--font-size--lg);
	color: var(--wp--preset--color--primary);
}

/* Hover underline on the name -> bio link. The shared inherit-color card-link
   rule above sets text-decoration: none for all four card links; only the
   people block's name gets it back on hover. The name's stretched ::after
   covers the whole chip, so hovering anywhere on it underlines the name. */
.nisa-person__name a:hover {
	text-decoration: underline;
}

.nisa-person__title {
	margin: 0; /* UA reset — defeats browser <p> margins */
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--bright-blue);
}

/* ---- Strategies grid (cards reuse .nisa-cap-card) ---- */
/* Grid columns come from the block's grid layout (columnCount 4). Responsive
   collapse is a media-query-only override — the base grid stays editor-owned. */
@media (max-width: 1199px) {
	.nisa-fi-strategies__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
	}
}

@media (max-width: 600px) {
	.nisa-fi-strategies__grid {
		grid-template-columns: 1fr !important;
	}
}

/* MINIMUM breathing room between a strategy card's description and its CTA.
   `.nisa-cap-card__cta` uses `margin-top: auto`, which distributes only
   LEFTOVER height — so in an equal-height grid row the TALLEST card gets
   nothing. Measured here: 0px on High-Yield (8-line description) vs 77px on
   the 5-line cards, i.e. the description sat flush against the link, and the
   gap differed on all six cards. This padding is the floor `auto` cannot
   provide; `auto` still bottom-aligns every CTA across the row. 4.5rem is
   measured off the comp (~72px minimum on the tallest card).

   Scoped to THIS grid deliberately. `.nisa-cap-card` is shared with
   Capabilities #7 (`.nisa-cap-grids__row`), which is already design-approved:
   applying it there moved its tagged cards to 94-142px and its untagged ones
   to 128-182px. #7 also cannot hit the 0px collision — its untagged cards are
   shorter than the tagged ones in the same row, so they always have slack.

   lint-allow: not authored spacing — a collision floor coupled to the flex
   rule on `.nisa-cap-card__cta`, and deliberately NOT a per-block padding
   attribute: an editor clearing it would silently restore the 0px overlap on
   whichever card happens to be tallest. */
.nisa-fi-strategies__grid .nisa-cap-card__cta {
	padding-top: 4.5rem;
}

/* ---- Video feature (clean variant of .nisa-video-card) ---- */
.nisa-fi-video__card {
	border-radius: 4px;
}

/* No bottom scrim on the FI variant — the comp is a clean poster + play */
.nisa-fi-video__card::before {
	display: none;
}

.nisa-fi-video__card .nisa-video-card__media img {
	aspect-ratio: 1091 / 597;
}

/* Center the play affordance (base sits at 41% under a scrim) */
.nisa-fi-video__card::after,
.nisa-fi-video__card .nisa-video-card__play::after {
	top: 50%;
}

/* Caption is the accessible label source only — visually hidden here */
.nisa-fi-video__card .nisa-video-card__caption {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	inset: auto;
}

/* ---- Fixed Income Perspectives (query loop) ---- */
@media (max-width: 1199px) {
	.nisa-fi-perspectives__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
	}
}

@media (max-width: 600px) {
	.nisa-fi-perspectives__grid {
		grid-template-columns: 1fr !important;
	}
}

/* .nisa-fi-perspectives__viewall a (+ :hover) consolidated into the shared link
   rules — inherit-color base (Insights section) + underline hover (Capabilities
   section). C5 dedup. */

.nisa-fi-persp-card {
	position: relative; /* containing block for the stretched title link */
	height: 100%;
	display: flex;
	flex-direction: column;
	border: 1px solid #e1e1e1; /* comp 1:168 hairline */
	border-radius: 4px;
	overflow: hidden; /* clips the flush image's top corners to the card radius */
	transition: box-shadow 0.25s ease;
}

/* Hover lift — a soft navy shadow, no movement. :focus-within comes along so
   keyboard users tabbing onto the card's stretched title link get the same
   affordance (same pairing as .nisa-cap-card). The card's own overflow:hidden
   clips its children, not this outer shadow. */
.nisa-fi-persp-card:hover,
.nisa-fi-persp-card:focus-within {
	box-shadow: 0 6px 18px color-mix(in srgb, var(--wp--preset--color--primary) 12%, transparent);
}

.nisa-fi-persp-card__media img,
.nisa-insights__card-image img {
	display: block;
	width: 100%;
	aspect-ratio: 3 / 2; /* comp 316×211 */
	object-fit: cover;
}

/* Eyebrow: date + computed read-time (inc/filters-readtime.php) share one line. */
.nisa-fi-persp-card__read {
	margin-left: 0.6em; /* inline-axis separator after the date */
}

/* Category pill (post-terms) — light-blue bg / gray uppercase are block attrs;
   inline-block so it hugs its text, and raised above the stretched title link
   so it stays clickable (skill Variant 2 secondary-link rule). */
.nisa-fi-persp-card__cat {
	position: relative;
	z-index: 2;
	display: inline-block;
}

/* STOPGAP — /perspectives/ card grid. The Post Template block lays this grid
   out itself everywhere else (layout {type:grid, columnCount:3}), and the theme
   file templates/archive-nisa_perspective.html still says so, but the copy of
   that template saved in the database renders the block as is-layout-flow, so
   the cards stack in one column. This restores the comp's 3-up (Figma
   4487:6657). Delete this block once the template customization is cleared and
   core emits its own grid rule again. Breakpoints match the other card grids in
   this file; scoped to the archive body class because .nisa-persp-grid is also
   used at columnCount 4 on the singles' related rows. Topic archives
   (templates/taxonomy-perspective_topics.html) reuse the same grid. */
.post-type-archive-nisa_perspective .nisa-persp-grid,
.tax-perspective_topics .nisa-persp-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 1.5rem;
}

/* The block still renders as is-layout-flow — the same lost grid attribute this
   stopgap exists for — so core's `:where(.is-layout-flow) > * + *` puts a
   block-gap margin on every card EXCEPT the first. A grid keeps that margin:
   it dropped cards 2..n 24px below the first one in their own row, and stacked
   with `gap` it doubled the space between rows. It also made the row track 24px
   taller than its content, so the first card (no margin) stretched to fill and
   looked 24px taller — which is what `align-items: start` here was previously
   working around. Zeroing the margin fixes all three, and lets the cards keep
   their intended equal-height stretch. */
.post-type-archive-nisa_perspective .nisa-persp-grid > li,
.tax-perspective_topics .nisa-persp-grid > li {
	margin-block-start: 0;
}

@media (max-width: 1024px) {
	.post-type-archive-nisa_perspective .nisa-persp-grid,
	.tax-perspective_topics .nisa-persp-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 600px) {
	.post-type-archive-nisa_perspective .nisa-persp-grid,
	.tax-perspective_topics .nisa-persp-grid {
		grid-template-columns: 1fr;
	}
}

/* Post cards in the grids (image on top, date + title below) — body fills the
   card so the topic tag pins to the bottom (tag hugs its text via align-self);
   block-level inline styles (padding / gap / pill styling) moved here off the
   archive markup. No min-height floor (was 250px — left 75–160px of empty card
   under short titles, worst on phones where cards stack): cards in a row still
   match via the grid stretch, and a fixed 72px (4.5rem) bottom padding keeps
   breathing room under the title (Beth, 2026-10-07). */
.nisa-persp-grid .nisa-fi-persp-card__body {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	padding: 1.25rem 1.125rem 4.5rem;
}

.nisa-persp-grid .nisa-fi-persp-card__cat {
	margin-top: auto;
	align-self: flex-start;
	padding: 0.5rem 0.75rem;
	border-radius: 4px;
	font-weight: 500;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

/* Archive query-loop spacing. core/query has NO padding support in WP 7.1, so
   these paddings could only ever live as hand-written inline styles in the
   template HTML — which the Site Editor flagged as out of date and strips on
   the next save (the Perspectives archive, saved in the editor, already lost
   them). Moved here 2026-10-06 with the exact previous values so the News,
   Primers and topic archives render unchanged. /perspectives/ is deliberately
   not included: it has rendered without this padding since its editor save. */
:is(.post-type-archive-nisa_news, .post-type-archive-nisa_primer) .nisa-persp-featwrap {
	padding-top: clamp(2rem, 4vw, 3.5rem);
	padding-bottom: clamp(2rem, 4vw, 3.5rem);
}

:is(.post-type-archive-nisa_news, .post-type-archive-nisa_primer) .nisa-persp-gridwrap {
	padding-top: 0.5rem;
	padding-bottom: var(--wp--preset--spacing--section);
}

.tax-perspective_topics .nisa-persp-gridwrap {
	padding-top: clamp(2rem, 4vw, 3.5rem);
	padding-bottom: 1rem;
}

/* Card date eyebrow — typography moved off the archive block markup. Also
   applies to any .nisa-persp-grid loop reused off-archive (e.g. the Insights
   page's Chief Economist + Perspectives card rows) and to the featured band's
   date, which on the Chief Economist hub sits outside both the .nisa-persp-
   archive and .nisa-persp-grid scopes and so used to render at 400/normal. */
.nisa-persp-archive .nisa-fi-persp-card__date,
.nisa-persp-grid .nisa-fi-persp-card__date,
.nisa-persp-featured__body .nisa-fi-persp-card__date,
.nisa-persp-single__date {
	font-weight: 500;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

/* Title -> date gap on the singles only (the rule above is shared with the card
   grids). Overrides the head column's 1rem blockGap, which WP emits at
   :where() specificity. */
.nisa-persp-single__date {
	margin-top: 50px; /* lint-allow: exact title-to-date gap set in design review */
}

/* Whole-card link (skill Variant 2): the featured image is isLink:false, so the
   post-title anchor is the card's ONE link — stretched over the card by the
   shared cover rule in the Capabilities card section (its text is the
   accessible name; no extra anchor, no ARIA). */

/* .nisa-fi-persp-card__title a (+ :hover) consolidated into the shared dark-link
   rules in the Capabilities card section. C5 dedup. */

/* ---- Explore Related Capabilities (rows reuse .nisa-capability-row) ---- */
/* The shared row carries only a bottom hairline; add a top one to the first
   row in each column so the list is fully ruled (comp 1:2656/2667). */
.nisa-fi-related__grid .nisa-capability-row:first-child {
	border-top: 1px solid var(--wp--preset--color--light-blue);
}

/* ---- Fixed Income — Mobile ---- */
@media (max-width: 781px) {
	/* core/columns stacks natively here (is-stacked-on-mobile) — no
	   flex-direction needed. */
	.nisa-fi-hero {
		min-height: 0;
		/* room for the stat that hangs below the media panel */
		padding-bottom: 2.5rem;
	}

	/* Full-width landscape panel below the content; the image still covers it. */
	.nisa-fi-hero__media {
		height: clamp(15rem, 56vw, 20rem);
	}

	.nisa-fi-hero__stat {
		left: var(--wp--style--root--padding-left);
		right: var(--wp--style--root--padding-right);
		bottom: 0;
		transform: translateY(42%);
	}
}

/* Phones + tablets: figure above its label instead of beside it — side by side,
   the "b" of "$280b" wrapped onto its own line (BugHerd #870; it still wrapped
   at 782–1024px, so the breakpoint covers tablets too). .is-layout-flex lifts
   specificity over core's per-instance layout class (align-items:center). */
@media (max-width: 1024px) {
	.nisa-fi-hero__stat-row.is-layout-flex {
		flex-direction: column;
		align-items: flex-start;
	}
}

/* -----------------------------------------------
   Style Guide  (shortcode: [nisa_styleguide])
   Internal design-token reference, PHP-rendered in
   inc/styleguide.php — reads theme.json live.
   Layout uses bespoke flex/grid containers that own
   their own display + gap (not WP layout gap), and
   preset font-size vars, per the component-CSS rules.
   ----------------------------------------------- */
/* Horizontal insets come from the post-content container's has-global-padding
   (root padding) + constrained content width — do NOT re-pad here or the guide
   double-insets and reads narrower than the full-bleed header/breadcrumb. */
.nisa-styleguide {
	display: flex;
	flex-direction: column;
	gap: clamp(3rem, 6vw, 5rem);
	padding-top: clamp(2rem, 5vw, 4rem);
	padding-bottom: clamp(3rem, 8vw, 6rem);
}

.nisa-styleguide__intro {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	padding-bottom: 1.5rem;
	border-bottom: 2px solid var(--wp--preset--color--primary);
}

.nisa-styleguide__lead {
	max-width: 62ch;
	color: var(--wp--preset--color--gray);
}

.nisa-styleguide__section {
	display: flex;
	flex-direction: column;
	gap: 1.75rem;
}

.nisa-styleguide__title {
	padding-bottom: 0.65rem;
	border-bottom: 1px solid var(--wp--preset--color--light-blue);
}

/* --- Colors + gradients grid --- */
.nisa-styleguide__swatches {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
	gap: 1.5rem;
}

.nisa-styleguide__swatch {
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
}

.nisa-styleguide__chip {
	aspect-ratio: 3 / 2;
	border-radius: 0.4rem;
	border: 1px solid var(--wp--preset--color--light-blue);
}

.nisa-styleguide__chip--wide {
	aspect-ratio: 5 / 2;
}

.nisa-styleguide__swatch-meta,
.nisa-styleguide__row-meta {
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
}

.nisa-styleguide__swatch-name {
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	color: var(--wp--preset--color--primary);
}

.nisa-styleguide__hex {
	font-size: var(--wp--preset--font-size--xs);
	color: var(--wp--preset--color--accent);
	text-transform: uppercase;
}

.nisa-styleguide__token {
	font-size: var(--wp--preset--font-size--xs);
	color: var(--wp--preset--color--gray);
	word-break: break-all;
}

/* --- Stacked rows (fonts, type scale, headings, spacing) --- */
.nisa-styleguide__stack {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

.nisa-styleguide__stack-row {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	padding-bottom: 1.5rem;
	border-bottom: 1px solid var(--wp--preset--color--wash);
}

.nisa-styleguide__row-meta {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.35rem 1.25rem;
}

.nisa-styleguide__font-specimen {
	line-height: 1.15;
	color: var(--wp--preset--color--primary);
}

/* Neutralize browser default margins on rendered specimens so the flex/grid
   gap owns the rhythm.  UA reset — not sibling spacing. */
.nisa-styleguide__stack-row > :is(h1, h2, h3, h4, h5, h6, p),
.nisa-styleguide__type-row > :is(h1, h2, h3, h4, h5, h6) {
	margin-block: 0;
}

/* --- Heading specimens --- */
.nisa-styleguide__type-row {
	display: grid;
	grid-template-columns: 6rem 1fr;
	align-items: baseline;
	gap: 1.5rem;
	padding-bottom: 1.5rem;
	border-bottom: 1px solid var(--wp--preset--color--wash);
}

.nisa-styleguide__type-label {
	font-size: var(--wp--preset--font-size--xs);
	color: var(--wp--preset--color--gray);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	white-space: nowrap;
}

/* --- Body text / prose --- */
.nisa-styleguide__prose {
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
	max-width: 72ch;
}

/* --- Buttons --- */
.nisa-styleguide__buttons {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1rem;
}

/* --- Spacing scale --- */
.nisa-styleguide__space-row {
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
	padding-bottom: 1.25rem;
	border-bottom: 1px solid var(--wp--preset--color--wash);
}

.nisa-styleguide__space-bar {
	height: 1.4rem;
	min-inline-size: 0.25rem;
	border-radius: 0.25rem;
	background-color: var(--wp--preset--color--bright-blue);
}

/* ============================================================
   PERSON PROFILE — single nisa_person (nisa/person-profile block
   + single-nisa_person template). Figma node 4092:3830.
   ============================================================ */

/* Shared geometry for the left "About" gutter and the content measure.
   The custom block's About content column and the template's
   post-content wrapper both read these, so the body copy lines up under
   the quote across the block boundary. */
.nisa-person-profile,
.nisa-person-single {
	--nisa-bio-gutter: clamp(1.5rem, 29vw, 26rem);
	--nisa-bio-measure: 47rem;
}

/* Full-bleed block: a soft top-down wash behind the hero (fades out before
   the body), then re-constrain the content to the site content width. */
.nisa-person-profile {
	background: var(--wp--preset--gradient--approach-wash);
	/* Root padding lives on the full-width wrapper (like has-global-padding),
	   NOT inside __inner's max-width cap — so this block's content box lines up
	   exactly with the constrained post-content body in the template. */
	padding-inline: var(--wp--style--root--padding-left, clamp(1rem, 4vw, 4rem));
}

.nisa-person-profile__inner {
	box-sizing: border-box;
	max-width: var(--wp--style--global--content-size, 1440px);
	margin-inline: auto;
	padding-block: clamp(2.5rem, 6vw, 5rem);
	/* Flex column with gap spaces hero → about (avoids sibling margins). */
	display: flex;
	flex-direction: column;
	gap: clamp(2.5rem, 6vw, 5rem);
}

/* ---- Hero -------------------------------------------------- */
.nisa-person-profile__hero {
	display: grid;
	grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
	gap: clamp(2rem, 5vw, 4.5rem);
	align-items: center;
}

.nisa-person-profile__intro {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1rem;
}

.nisa-person-profile__eyebrow {
	margin: 0;
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--label-blue);
}

.nisa-person-profile__name {
	margin: 0;
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-weight: 300;
	font-size: var(--wp--preset--font-size--xxxl);
	line-height: 1.1;
	color: var(--wp--preset--color--primary);
}

.nisa-person-profile__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--lg);
	font-weight: 400;
	color: var(--wp--preset--color--accent);
}

.nisa-person-profile__linkedin {
	display: inline-flex;
	width: 1.625rem;
	height: 1.625rem;
	color: var(--wp--preset--color--primary);
	transition: color var(--nisa-footer-transition, 0.25s ease);
}

.nisa-person-profile__linkedin:hover {
	color: var(--wp--preset--color--accent);
}

/* Inline SVGs that fill their box — the profile LinkedIn icon and the Fixed
   Income hero line art. One shared body (C4), two components. */
.nisa-person-profile__linkedin svg,
.nisa-hero-art svg {
	display: block;
	width: 100%;
	height: 100%;
}

.nisa-person-profile__photo {
	margin: 0; /* UA reset — defeats browser <figure> margins */
}

/* Full featured image (uncropped), capped at the design width. */
.nisa-person-profile__img {
	display: block;
	width: 100%;
	height: auto;
	max-width: 537px;
}

/* ---- About: gutter label + content column ------------------ */
.nisa-person-profile__about {
	display: grid;
	grid-template-columns: var(--nisa-bio-gutter) minmax(0, 1fr);
}

/* Consolidated: the Thought Leadership heading reuses the About label's gutter
   treatment (right-aligned in the bio gutter, matching type) so the two section
   labels line up down the left column. */
.nisa-person-profile__about-label,
.nisa-person-single__about-label,
.nisa-tl__heading,
.nisa-nm__heading {
	margin: 0;
	padding-right: clamp(1.5rem, 3vw, 3rem);
	text-align: right;
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-weight: 300;
	font-size: var(--wp--preset--font-size--xxl);
	color: var(--wp--preset--color--primary);
}

.nisa-person-profile__content {
	max-width: var(--nisa-bio-measure);
}

/* Top-align the first line of each bio section with its gutter label. The
   boxes already start level; this nudges the content down by the label's
   larger cap offset (a 40px IvyPresto heading carries more space above its
   capitals than the 24px titles / small caps labels beside it). Expressed in
   the label's own size so it holds as the xxl preset scales. Measured
   2026-09-30: 4–5.5px at 1440 before the nudge. */
.nisa-person-profile__content,
.nisa-nm__content,
.nisa-tl__content {
	padding-top: calc(var(--wp--preset--font-size--xxl) * 0.125);
}

/* ---- Field grid (2 × 2, thin rule under each cell) --------- */
.nisa-person-profile__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0 clamp(1.5rem, 3vw, 2.5rem);
}

/* First row sits flush with the top of the "About" label (same rule as the
   News Mentions / Thought Leadership lists), so label and content align. */
.nisa-person-profile__grid > .nisa-person-profile__field:nth-child(-n+2) {
	padding-top: 0;
}

.nisa-person-profile__field {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	padding: 0.5rem 0 0.85rem;
	border-bottom: 1px solid var(--wp--preset--color--lighter-blue);
}

.nisa-person-profile__field-label {
	margin: 0;
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--label-blue);
}

.nisa-person-profile__field-value {
	margin: 0;
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--md);
	color: var(--wp--preset--color--primary);
}

/* ---- Pull quote ------------------------------------------- */
.nisa-person-profile__quote {
	position: relative;
	/* lint-allow: top gap from the field grid inside the render.php block flow — no blockGap available */
	margin: clamp(2.25rem, 4vw, 3.25rem) 0 0;
	padding: 0;
	border: 0;
}

/* Quote-only bios (no field grid): the quote is first, so it aligns with the
   "About" label instead of sitting a gap below it. */
.nisa-person-profile__quote:first-child {
	margin-top: 0; /* lint-allow: removes the render.php grid→quote gap when there is no grid above */
}

/* When About ends with the field grid (no pull quote), the profile's full
   bottom padding + the body's top margin (~116px) leaves the bio copy looking
   detached from a thin row of fields. Trim the padding so the grid → copy gap
   (~16px + the body's clamp(1.75–2.25rem) margin ≈ 52px) matches the
   grid → quote gap. Bios WITH a quote, and bios with no About, keep the full
   padding (Beth 2026-09-30). */
.nisa-person-profile:has(.nisa-person-profile__grid):not(:has(.nisa-person-profile__quote)) .nisa-person-profile__inner {
	padding-bottom: 1rem;
}

.nisa-person-profile__quote p {
	margin: 0;
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-weight: 300;
	font-size: var(--wp--preset--font-size--xxl);
	line-height: 1.3;
	color: var(--wp--preset--color--primary);
}

.nisa-person-profile__quote::before {
	content: "\201C";
	position: absolute;
	top: -0.15em;
	left: -0.62em;
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	/* lint-allow: decorative quotation-mark glyph, client-set size, not a type-scale token */
	font-size: 2.5rem;
	line-height: 1;
	color: var(--wp--preset--color--primary);
}

/* ---- Body copy (core/post-content) aligned under the quote - */
.nisa-person-single__body {
	/* Core's constrained layout forces `margin-inline: auto !important` on
	   non-aligned children (centring them), which would ignore the gutter and
	   leave the copy left of the quote/grid. Reassert the offset with
	   !important so the body column lines up with them.

	   The gutter alone isn't enough above ~1568px: the profile block and the
	   Thought Leadership section cap their inner at content-size (1440px) and
	   center it inside the root-padded area, so their content column shifts
	   right as the viewport grows past content-size. This wrapper fills the
	   full padded width instead, so add the SAME centering offset —
	   max(0, (ownWidth - content-size) / 2) — to keep the body column locked to
	   the grid/quote above and the Thought Leadership list below. Below
	   content-size the offset is 0, so narrower layouts are unchanged. */
	margin-left: calc(max(0px, (100% - var(--wp--style--global--content-size, 1440px)) / 2)) !important;
	margin-right: auto !important;
	max-width: calc(var(--nisa-bio-gutter) + var(--nisa-bio-measure));
	/* Gutter label | copy, the same columns as the profile's About section and
	   the News / Thought Leadership rows. The "About" label here only renders
	   when the profile above has no About section (inc/people.php), so the
	   copy is pinned to column 2 either way. */
	display: grid;
	grid-template-columns: var(--nisa-bio-gutter) minmax(0, 1fr);
	align-items: start;
	/* lint-allow: gap below the profile block; spans the custom-block boundary, so blockGap can't reach it */
	margin-top: clamp(1.75rem, 3vw, 2.25rem);
}

/* WP auto-adds has-global-padding to the body group AND the inner
   post-content; that double root-padding would indent the copy past the
   quote. Cancel it so the paragraphs sit flush-left with the quote + grid
   (the gutter offset is carried by the wrapper's margin above). */
.nisa-person-single__body.has-global-padding,
.nisa-person-single__body .wp-block-post-content {
	padding-inline: 0;
}

.nisa-person-single__body > .wp-block-post-content {
	grid-column: 2;
	/* Cap-top nudge like the other label rows (.nisa-person-profile__content),
	   smaller because body copy's taller line-height already sets its caps
	   lower. Measured: 0.05 → label and first-line caps level at 1440. */
	padding-top: calc(var(--wp--preset--font-size--xxl) * 0.05);
}

.nisa-person-single__body :where(p) {
	color: var(--wp--preset--color--body);
}

/* ---- Responsive: collapse the gutter, stack the hero ------- */
@media (max-width: 1024px) {
	.nisa-person-profile,
	.nisa-person-single {
		--nisa-bio-gutter: 0px;
		--nisa-bio-measure: 100%;
	}

	.nisa-person-profile__hero {
		grid-template-columns: 1fr;
	}

	.nisa-person-profile__about,
	.nisa-tl__inner,
	.nisa-nm__inner {
		grid-template-columns: 1fr;
		gap: 1rem;
	}

	.nisa-person-profile__about-label,
	.nisa-person-single__about-label,
	.nisa-tl__heading,
	.nisa-nm__heading {
		text-align: left;
		padding-right: 0;
	}

	.nisa-person-single__body {
		margin-left: 0 !important;
		max-width: none;
		grid-template-columns: minmax(0, 1fr);
		row-gap: 1rem;
	}

	.nisa-person-single__body > .wp-block-post-content {
		grid-column: 1;
	}

	.nisa-tl__content,
	.nisa-nm__content {
		max-width: none;
	}
}

@media (max-width: 600px) {
	.nisa-person-profile__grid {
		grid-template-columns: 1fr;
	}

	/* One column: only the first field is in the first row. */
	.nisa-person-profile__grid > .nisa-person-profile__field:nth-child(2) {
		padding-top: 0.5rem; /* lint-allow: render.php field markup, no block attribute — restores the row padding the 2-col first-row rule removed */
	}

	/* The opening-quote glyph is an abspos ::before hung outside the quote's
	   left edge (left: -0.62em), which at the mobile gutter leaves it about a
	   pixel off the viewport edge. margin-inline moves the BORDER box, so the
	   glyph travels with the quote — padding would not, because an abspos child
	   is offset from the padding box edge, which padding does not move. Matching
	   inline-end keeps the measure symmetrical rather than leaving the quote
	   running to the gutter on one side. Inline-axis margin, so it is not
	   sibling spacing (C1). */
	.nisa-person-profile__quote {
		margin-inline: 1rem;
	}
}

/* =========================================================
   About Us page (Figma 4092:3110)
   Hero split + two-image row · four-across Trusted Partner
   stat band · muted Our Story with leadership quote · ruled
   AUM section totals + muted stat-card grids · two media CTAs.
   Copy and tokens live in patterns/about-*.php; the gradient
   heading em is grouped with .nisa-why-nisa__heading em above.
   ========================================================= */

/* ---- Hero: two-image row, equal heights via a fixed leaf height ---- */
.nisa-about-hero__media {
	margin: 0; /* UA reset — defeats browser <figure> margins */
}

.nisa-about-hero__media img {
	display: block;
	width: 100%;
	height: clamp(17rem, 30vw, 28rem);
	object-fit: cover;
	border-radius: 4px;
}

/* ---- Stat labels (band + Our Story) ----
   A NEW class (not .nisa-stat__label) so it skips the -1.25rem hero pull;
   the small negative only trims the serif number's line-box whitespace. */
.nisa-about-stat__label {
	margin-top: -0.4rem; /* optical — close the gap under the serif number */
}

/* ---- Our Story ---- */
.nisa-about-story__avatar img {
	border-radius: 50%;
	object-fit: cover;
}

/* ---- What We Manage: ruled section totals ---- */
/* The row spans the full content width so the flanking rules can grow to the
   section edges (matching the comp). */
.nisa-aum-total__row {
	width: 100%;
}

/* Separator styled as a flexible hairline that flanks the big number. flex-basis
   0 makes both rules grow evenly to the edges regardless of core's default 100px
   separator width; the value group keeps its intrinsic width in the middle. */
.nisa-aum-total__rule {
	flex: 1 1 0;
	width: auto;
	max-width: none;
	height: 0;
	margin: 0;
	border: none;
	border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 40%, transparent);
	align-self: center;
}

.nisa-aum-total__label {
	margin-top: -0.75rem; /* optical — pull the sublabel under the tall number */
}

/* ---- Stat-card grids ---- */
.nisa-aum-card {
	height: 100%;
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 10%, transparent);
}

/* .nisa-aum-grid .nisa-aum-card and .nisa-media-cta__box .nisa-media-cta__text
   are top-aligned column flex via the shared rule in the Why NISA section
   above (C5 dedup). */

.nisa-aum-card__label {
	margin-top: -0.3rem; /* optical — trim the serif number's line-box */
}

/* .nisa-aum-card__tags had opacity: 0.85 — gray at 85% on the muted background
   measured 3.96:1, under AA for 12px text (WCAG audit S6). Removed 2026-10-06;
   full gray #666 is 5.45:1. */

/* Tablet: the 4-up rows get cramped below ~1200px; wrap to a 2×2 grid.
   Same counter as .nisa-cap-grids__row — core forces flex-wrap:nowrap at
   >=782px. The three-up physical remainder row is left untouched. */
@media (min-width: 782px) and (max-width: 1199px) {
	.nisa-aum-grid:not(.nisa-aum-grid--three) {
		flex-wrap: wrap !important;
	}

	.nisa-aum-grid:not(.nisa-aum-grid--three) > .wp-block-column {
		flex-basis: calc(50% - 0.75rem) !important;
		flex-grow: 0 !important;
	}
}

/* ---- Media CTAs (Leadership + Careers) ---- */
/* Investment Solutions video CTA (/capabilities/). Native Columns: a
   .nisa-video-card on the left (image + hidden Vimeo embed — video-dialog.js
   adds the play button, and the "Watch the Video" pill links to the card's
   #anchor, so both open the modal) and the copy on the right. Was a
   media-text until 2026-09-23; the image still fills its column edge to edge
   and the box clips its corners. Copy padding matches the old media-text
   (8% inline + 2.5rem block, client review 2026-09-22). */
.nisa-video-cta {
	overflow: hidden;
}

.nisa-video-cta__content {
	/* lint-allow: inner padding of the copy column */
	padding: 2.5rem 8%;
}

.nisa-video-cta__media .nisa-video-card {
	height: 100%;
	border-radius: 0;
}

.nisa-video-cta__media .nisa-video-card__media,
.nisa-video-cta__media .nisa-video-card__media img {
	height: 100%;
}

/* Desktop: the image takes the row's height (set by the copy) instead of
   its own 437:244 card ratio. Stacked (<782px, core's breakpoint) it keeps
   the card ratio. */
@media (min-width: 782px) {
	.nisa-video-cta__media .nisa-video-card__media img {
		aspect-ratio: auto;
		min-height: 16rem;
	}
}

/* "Watch the Video" pill: a play triangle in place of the arrow. Covers both
   swap icons (::after at rest, ::before on hover) and the no-JS ::after. */
.nisa-video-cta__content .wp-block-button__link::after,
.nisa-video-cta__content .wp-block-button__link.nisa-btn-swap::before {
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 4.5v15L19 12z' fill='black' stroke='black' stroke-width='1.5' stroke-linejoin='round'/%3E%3C/svg%3E");
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7 4.5v15L19 12z' fill='black' stroke='black' stroke-width='1.5' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.nisa-media-cta__media {
	margin: 0; /* UA reset — defeats browser <figure> margins */
}

.nisa-media-cta__media img {
	display: block;
	width: 100%;
	height: clamp(18rem, 34vw, 30rem);
	object-fit: cover;
	border-radius: 4px;
}

/* Careers CTA (boxed variant): the image fills the full box height and bleeds to
   its top/right/bottom edges — the box clips the rounded corners — while the text
   column is vertically centered across the whole box. */
.nisa-media-cta__box {
	overflow: hidden;
}

/* .nisa-media-cta__box .nisa-media-cta__text is centered by the shared
   column-flex rule in the stat-card grids section above (C5 dedup). */

/* Definite height (not 100%) so the image PINS the box height instead of
   resolving circularly against it; comp height is 327px at desktop. The image
   column stretches to match and object-fit:cover keeps it full-bleed. */
.nisa-media-cta__box .nisa-media-cta__media img {
	height: clamp(16rem, 23vw, 20.4375rem);
	border-radius: 0;
}

/* ---- About Us page-scoped tweaks (.page-id-20) ---- */

/* Hairline white rule under the interior breadcrumb bar, About Us only. */
.page-id-20 .nisa-breadcrumb-bar {
	border-bottom: 1px solid var(--wp--preset--color--secondary);
}

/* Stat figure sizes are now BLOCK SETTINGS, not page-scoped CSS: the Trusted
   Partner figures carry a custom 5.125rem (82px) on the block, the AUM cards
   carry the `xxl` preset and the ruled totals `stat` — all editable in each
   block's Typography panel, and the editor now matches the front end (the old
   `!important` override made the panel read a different size than rendered). */

/* Taller cards in the first (physical) AUM grid — reuses .nisa-aum-card's
   height:100% so every card in the row matches this floor. */
.nisa-aum-grid--tall .nisa-aum-card {
	min-height: 200px; /* lint-allow: was 250px; trimmed per client (BugHerd #369) */
}

/* Mobile (the columns stack at WP's 781px breakpoint, so each card is full
   width and the desktop floor just leaves dead space under the content). */
@media (max-width: 781px) {
	.nisa-aum-grid--tall .nisa-aum-card {
		min-height: 175px;
	}

	/* The figures in these cards (their value groups) carry the `xxxl` preset, which bottoms out at
	   32px on phones — too small once the card is full width.

	   A plain `font-size` here does NOT work: core prints preset classes as
	   `.has-xxxl-font-size{font-size:var(--wp--preset--font-size--xxxl)
	   !important}`, so it wins on !important. Escalating to !important in reply
	   is the one thing this section deliberately moved away from (see the
	   block-settings note above the rule before this one) — it makes the
	   editor's Typography panel report a size the front end doesn't render.

	   So retarget the VARIABLE core's own rule reads, scoped to these figures.
	   Core's !important rule still wins the cascade; it just resolves to 4rem
	   here. The block keeps its XXXL setting, so the editor stays truthful, and
	   nothing outside this card is touched. rem, not px, so the reader's
	   font-size setting is still respected. Set on the value GROUP (which now
	   carries the size) so the 0.6em $ scales with the figure. */
	/* All AUM card grids, not just --tall: the Overlay cards below the second
	   total were still on the 32px floor (BugHerd #951). */
	.nisa-aum-grid .nisa-stat__value {
		--wp--preset--font-size--xxxl: 4rem;
	}

	/* Section totals ($299b physical, $184b overlay) use the `stat` preset, which
	   floors at 48px — smaller than the 64px cards under them (BugHerd #949/#950).
	   Same variable-retarget technique as above, sized one step up from the cards
	   so the total still leads, as it does on desktop. */
	.nisa-aum-total__row .nisa-stat__value {
		--wp--preset--font-size--stat: 5rem;
		/* The desktop 130px side gutters (rule above, !important) would push an
		   80px figure past a phone screen; keep a short rule either side. */
		margin-left: 1rem !important;
		margin-right: 1rem !important;
	}
}

/* ============================================================
   CONTACT — /contact (page 23). Figma node 4092:3289.
   Dark-navy section: H1 + intro + Gravity Form #1 on the left,
   info rail on the right. The whole left form IS GF #1, so its
   markup is styled here (third-party — no block attributes).
   ============================================================ */

/* Rail: media-inquiries link as a white IvyPresto display figure. */
.nisa-contact__mail a {
	color: var(--wp--preset--color--secondary);
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	/* lint-allow: client-requested exact 20px; no matching fontSizes preset. */
	font-size: 1.25rem;
	letter-spacing: 1px;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.nisa-contact__phone {
	letter-spacing: 1px !important;
}

/* Light text on navy reads optically tighter than the same Inter setting on
   the light pages (measured identical: 16px/400/normal). A hair of tracking
   on body copy and the form's labels/notes restores legibility. BugHerd
   #387/#388. */
.nisa-contact p,
.nisa-contact .gform_wrapper .gfield_label,
.nisa-contact .gform_wrapper legend.gfield_label,
.nisa-contact .gform_wrapper .gform-field-label,
.nisa-contact .gform_wrapper .gfield_html,
.nisa-contact .gform_wrapper .gform_required_legend {
	letter-spacing: 0.01em;
}

/* Click-to-call + directions links (BugHerd #383/#384) inherit colour via the
   shared "inherit-colour link" rule with .nisa-person__name a (search that);
   underline on hover/focus via the shared rule with .nisa-ceu-author. */
/* Hover/focus underline for these links lives in the shared rule with
   .nisa-ceu-author (search "hover-underline") to avoid duplicate declarations. */

/* Columns: left form column caps at 740px, right rail fills the rest, with a
   150px gutter. Below desktop the fixed gutter is too wide for the row (columns
   don't wrap until <782px), so scale it down through the tablet band. */
@media (min-width: 782px) and (max-width: 1199px) {
	.nisa-contact__cols {
		column-gap: clamp(2.5rem, 7vw, 150px) !important;
	}
}

/* Narrow end of that band: side by side, the form column and the info rail are
   both too cramped, so stack them. Core only wraps columns below 782px, hence
   the explicit direction here. The 1025-1199px slice keeps the row and the
   clamped gutter above. Vertical spacing comes from the block's own
   blockGap.top (2.5rem) — column-gap does nothing once the axis flips, so no
   gap rule is needed here. */
@media (min-width: 782px) and (max-width: 1024px) {
	.nisa-contact__cols {
		flex-direction: column;
	}
}

/* Newsletter card Subscribe pill — accent pill with a circular
   arrow chip, matching the site-wide subscribe treatment. */
.nisa-contact__subscribe .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: 0.75rem;
	border-radius: 999px;
	padding: 0.7rem 0.7rem 0.7rem 1.25rem;
	font-weight: 500;
}

.nisa-contact__subscribe .wp-block-button__link::after {
	content: "\2192";
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.75rem;
	height: 1.75rem;
	border-radius: 50%;
	background-color: var(--wp--preset--color--bright-blue);
	color: var(--wp--preset--color--secondary);
	flex: 0 0 auto;
}

/* ---- Gravity Form #1, scoped to the contact section ---- */

.nisa-contact .gform_wrapper {
	margin: 0; /* drop GF's default wrapper spacing — column blockGap owns the gap */
}

/* Field labels + the checkbox group legend. */
.nisa-contact .gform_wrapper .gfield_label,
.nisa-contact .gform_wrapper legend.gfield_label {
	color: var(--wp--preset--color--secondary);
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 500;
	letter-spacing: 0.01em;
}

.nisa-contact .gform_wrapper .gfield_required {
	color: var(--wp--preset--color--bright-blue);
}

/* "Required fields are marked..." legend above the form, on navy. */
#gform_wrapper_1 .gform_required_legend {
	color: var(--wp--preset--color--secondary);
}

/* Required asterisks (legend + field labels) — white, like the legend above. */
#gform_wrapper_1 .gfield_required.gfield_required_asterisk {
	color: var(--wp--preset--color--secondary);
}

/* Column-reverse puts the form itself above the "required fields" legend that
   GF prints first in the source. */
#gform_wrapper_1 {
	display: flex;
	flex-direction: column-reverse;
}

/* Post-submit confirmation replaces the form on the same navy section — white
   like the labels. ID selector to outrank the GF theme framework's colour. */
#gform_confirmation_message_1,
#gform_confirmation_message_1 a {
	color: var(--wp--preset--color--secondary);
}

/* Text / email inputs + the message textarea: white fill on navy. */
.nisa-contact .gform_wrapper input[type="text"],
.nisa-contact .gform_wrapper input[type="email"],
.nisa-contact .gform_wrapper textarea {
	width: 100%;
	background-color: var(--wp--preset--color--secondary);
	color: var(--wp--preset--color--primary);
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--md);
	border: 1px solid transparent;
	border-radius: 6px;
	padding: 0.85rem 1rem;
	line-height: 1.4;
}

.nisa-contact .gform_wrapper input[type="text"],
.nisa-contact .gform_wrapper input[type="email"] {
	min-height: 50px;
}

.nisa-contact .gform_wrapper textarea {
	min-height: 150px;
	resize: vertical;
}

.nisa-contact .gform_wrapper ::placeholder,
.nisa-subscribe-dialog .gform_wrapper .ginput_container_email input::placeholder,
.nisa-subscribe-page .gform_wrapper .ginput_container_email input::placeholder {
	color: var(--wp--preset--color--gray);
	opacity: 1;
}

/* Focus rings on the navy section use bright-blue-2 (#049DDE, 4.55:1 on navy);
   bright-blue (#0378AA) was 2.82:1 — below the 3:1 non-text minimum. */
.nisa-contact .gform_wrapper input[type="text"]:focus,
.nisa-contact .gform_wrapper input[type="email"]:focus,
.nisa-contact .gform_wrapper textarea:focus {
	outline: 2px solid var(--wp--preset--color--bright-blue-2);
	outline-offset: 1px;
	border-color: transparent;
}

/* Checkbox row: white box, bright-blue when checked. */
.nisa-contact .gform_wrapper .gchoice {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.nisa-contact .gform_wrapper .gchoice label {
	color: var(--wp--preset--color--secondary);
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--sm);
}

.nisa-contact .gform_wrapper .gfield-choice-input[type="checkbox"] {
	appearance: none;
	-webkit-appearance: none;
	width: 18px;
	height: 18px;
	margin: 0;
	background-color: var(--wp--preset--color--secondary);
	border: 1px solid var(--wp--preset--color--secondary);
	border-radius: 3px;
	cursor: pointer;
	position: relative;
	flex: 0 0 auto;
}

/* lint-allow: bright-blue :checked fill (pseudo-state, no class to share) */
.nisa-contact .gform_wrapper .gfield-choice-input[type="checkbox"]:checked {
	background-color: var(--wp--preset--color--bright-blue);
	border-color: var(--wp--preset--color--bright-blue);
}

.nisa-contact .gform_wrapper .gfield-choice-input[type="checkbox"]:checked::after {
	content: "";
	position: absolute;
	left: 5px;
	top: 1px;
	width: 5px;
	height: 10px;
	border: solid var(--wp--preset--color--secondary);
	border-width: 0 2px 2px 0;
	transform: rotate(45deg);
}

/* Checkbox / consent-link / Submit focus ring: in the shared bright-blue-2
   focus rule under "Subscribe modal" (the link had the browser default,
   Submit Gravity Forms' 60%-alpha blue — both under 3:1 on navy). */

/* Consent HTML block (field 9) — fine print + Privacy Notice link. */
.nisa-contact .gform_wrapper .gfield_html {
	color: var(--wp--preset--color--secondary);
	font-size: var(--wp--preset--font-size--sm);
	opacity: 0.85;
}

.nisa-contact .gform_wrapper .gfield_html a {
	color: var(--wp--preset--color--secondary);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Submit button — pale-blue fill, navy label + trailing arrow.
   Gravity Forms' orbital/framework theme styles a generic `>button` with a
   high-specificity `:not()`-stacked selector (not our `.gform_button`), so the
   visual properties it sets (background, color, padding, radius) need
   `!important` here to win — GF's rule is NOT !important, so ours takes it. */
.nisa-contact .gform_wrapper .gform_footer button.gform_button.button {
	display: inline-flex !important;
	align-items: center;
	gap: 0.6rem;
	background-color: var(--wp--preset--color--wash) !important;
	color: var(--wp--preset--color--primary) !important;
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	letter-spacing: 0.75px !important;
	border: none !important;
	border-radius: 6px !important;
	padding: 1rem 1.6rem !important;
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.nisa-contact .gform_wrapper .gform_footer button.gform_button.button::after {
	content: "\2192" !important;
	font-family: var(--wp--preset--font-family--inter) !important;
	color: var(--wp--preset--color--primary) !important;
	display: inline-block;
}

.nisa-contact .gform_wrapper .gform_footer button.gform_button.button:hover,
.nisa-contact .gform_wrapper .gform_footer button.gform_button.button:focus-visible {
	background-color: var(--wp--preset--color--light-blue) !important;
}

/* ============================================================
   FIXED INCOME — Intermediate & Core (page 98, /…/intermediate-
   and-core/). Figma node 4092:3581. Only the genuinely new
   sections need CSS: centered hero, Portfolio Fit ruled list,
   and equal-height How-It-Works stat cards. The Implementation
   Process list reuses .nisa-process-row (circled numbers + rules
   already styled), and Perspectives / Related / CTA reuse their
   existing nisa-fi-* / nisa-cta-solid classes.
   ============================================================ */

/* Hero — centered eyebrow / headline / intro. */
.nisa-ic-hero {
	text-align: center;
}

/* Intro width is the Max Width block extension (atomicMaxWidth on the
   paragraph, injected inline at render by inc/filters-max-width.php), NOT a CSS
   cap — so it stays editable in the block's Max Width panel. Centering comes
   from WP constrained-layout's margin-inline:auto (flush-left toggle OFF).
   Was `max-width:640px;margin-inline:auto` here, which silently beat the
   extension. */

/* Portfolio Fit — right-column role list, a rule below each item
   except the last. */
.nisa-ic-fit__item {
	border-bottom: 1px solid var(--wp--preset--color--primary);
}

.nisa-ic-fit__item:last-child {
	border-bottom: none;
}

/* How It Works — centre the section eyebrow (the Implementation
   Process eyebrow below stays left). */
.nisa-ic-hiw__header .nisa-eyebrow {
	text-align: center;
}

/* Stat-card titles read in the sans face, not the serif default. */
.nisa-ic-hiw__stats h3 {
	font-family: var(--wp--preset--font-family--inter);
}

/* 70/30 stat cards share a row height so their coloured panels
   bottom-align regardless of copy length. */
.nisa-ic-hiw__card {
	height: 100%;
}

/* Related list on the capability sub-pages: bottom hairline only (drop the
   shared first-child top rule). Scoped so Fixed Income (#8) keeps its
   fully-ruled look. */
.page-id-98 .nisa-fi-related__grid .nisa-capability-row:first-child,
.page-id-12 .nisa-fi-related__grid .nisa-capability-row:first-child {
	border-top: none;
}

/* ============================================================
   LIABILITY DRIVEN INVESTING (page 12). Figma 4092:3677.
   Reuses nisa-ic-hero / nisa-ic-fit / nisa-process-list /
   nisa-fi-perspectives / nisa-fi-related / nisa-cta-solid.
   New here: ERISA banner, resource cards, chart placeholders.
   ============================================================ */

/* Portfolio Fit here rules below every factor, including the last
   (page 98 drops its last rule; this design keeps it). */
/* LDI uses editable core/separator blocks for the fit dividers instead of the
   CSS border-bottom (Intermediate & Core #98 keeps the CSS version). Turning
   the border off on LDI only avoids doubling the line under each item. */
.nisa-ldi-fit .nisa-ic-fit__item {
	border-bottom: none;
}

/* Match the old 1px hairline. Core keeps a 2px `border-top` on every separator
   even when a background colour is set, so the colored bar (height) and the
   border would stack to 3px — zero the border and let the 1px background bar be
   the line. Thickness has no editor control, so this only pins the weight; the
   colour stays editable in the block's panel. */
.nisa-ldi-fit .wp-block-separator.has-background,
.nisa-how-work__line.wp-block-separator.has-background {
	border: none;
	height: 1px;
}

/* LDI hero fill is now the group's own backgroundColor block attr ("muted"),
   not a page-scoped CSS override — so it's editable and needs no .page-id-12
   hack to avoid page 98 (whose hero carries its own bg attr). */

/* Banner section: a 50/50 muted-over-white split so the (symmetrically
   padded, therefore vertically centred) banner straddles the transition —
   the same look the old hero-overlap gave, without the overlap. */
.nisa-ldi-bannerwrap {
	background: linear-gradient(
		to bottom,
		var(--wp--preset--color--muted) 0,
		var(--wp--preset--color--muted) 50%,
		var(--wp--preset--color--secondary) 50%,
		var(--wp--preset--color--secondary) 100%
	);
}

/* Portfolio-Fit intro width + left-hold are now the Max Width block extension
   (atomicMaxWidth:50rem, flush-left ON) on the paragraph — editable in the
   panel; was max-width:50rem + margin-inline:0 here. */

/* ERISA banner — navy card: text grows, button sits at the right. */
.nisa-ldi-banner__text {
	flex: 1 1 20rem;
}

/* Lead cluster (icon tile + text) grows so the anchor button holds the right
   edge; wraps as a unit below the button on narrow widths (banner is flex-wrap). */
.nisa-ldi-banner__lead {
	flex: 1 1 24rem;
}

/* Navy icon tile — component chrome (fixed decorative square), like the
   circled process numbers. The line glyph is currentColor so the tile owns it;
   light-blue-2 (#D9EDF7) is the stroke from the supplied Upward.svg. */
.nisa-ldi-banner__icon {
	display: grid;
	place-items: center;
	flex-shrink: 0;
	width: 4rem;
	height: 4rem;
	border-radius: 8px;
	background-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--light-blue-2);
}

/* Width only + height:auto so the 46x40 viewBox keeps its aspect (no squash). */
.nisa-ldi-banner__icon svg {
	width: 2.125rem;
	height: auto;
}

/* Phones: icon tile above the heading, both flush left, instead of the tile
   vertically centred beside a tall text block (BugHerd #896). .is-layout-flex
   outranks core's per-instance layout class (align-items:center).
   The text's desktop `flex: 1 1 20rem` basis is a WIDTH in the row layout, but
   once the lead is a column it becomes a 320px minimum HEIGHT — ~200px of empty
   space under the copy that made the whole banner section too tall. Reset it. */
@media (max-width: 781px) {
	.nisa-ldi-banner__lead.is-layout-flex {
		flex-direction: column;
		align-items: flex-start;
	}

	.nisa-ldi-banner__text {
		flex-basis: auto;
	}

	/* Tighter sides on a phone-width card. The desktop padding is the block's
	   own spacing attribute (inline style), so only !important can override it
	   here — desktop keeps the editable 2.5rem/3.5rem. */
	.nisa-ldi-banner {
		padding: 2.5rem 1.5rem !important; /* lint-allow: beats the block's inline padding on phones only */
	}

	/* ERISA resource cards: one per row instead of three squeezed across
	   (BugHerd #897). The grid block's fixed columnCount:3 never collapses on
	   its own; .is-layout-grid outranks core's per-instance layout class. */
	.nisa-ldi-rcards.is-layout-grid {
		grid-template-columns: 1fr;
	}
}

/* Portfolio Components row spans the full content width; its eyebrow and
   the DV01 caption stay centred and narrow. */
.nisa-ldi-components > .nisa-eyebrow {
	text-align: center;
}

.nisa-ldi-components__row {
	max-width: var(--wp--style--global--content-size);
}

/* DV01 caption width is now the Max Width block extension (atomicMaxWidth:31rem
   = 496px, centered) on that paragraph — editable in the panel, and no longer
   needs the .nisa-ldi-components descendant scope to spare the other caption. */

/* Chart placeholders — editable boxes to swap for real chart exports. */
.nisa-ldi-chartph {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 14rem;
	border: 1px dashed color-mix(in srgb, var(--wp--preset--color--primary) 25%, transparent);
}

.nisa-ldi-chartph--bar {
	min-height: 18rem;
}

.nisa-ldi-chartph--card {
	min-height: 8rem;
}

/* Portfolio Components — matched-height stone cards with a hairline
   border. rgb() (not hex) keeps the linter's hex rule satisfied;
   values = #F4F3EE fill / #E1E1E1 border. */
.nisa-ldi-compcard {
	height: 100%;
	background-color: rgb(244, 243, 238);
	border: 1px solid rgb(225, 225, 225);
}

/* ERISA resource cards — flex column so the CTA sits at the base; the
   whole card is a click target via the CTA's stretched link. */
.nisa-ldi-rcard {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
	border: 1px solid var(--wp--preset--color--light-blue-2);
}

.nisa-ldi-rcard__desc {
	flex-grow: 1;
}

/* lint-allow: same accent-link reset as .nisa-capability-row__name a, but a
   distinct component (stretched-link card CTA) — not worth a shared class. */
.nisa-ldi-rcard__cta a {
	color: var(--wp--preset--color--accent);
	text-decoration: none;
}

.nisa-ldi-rcard__cta a::after,
.nisa-tl__title a::after {
	content: "";
	position: absolute;
	inset: 0;
}

/* ============================================================
   PERSPECTIVES ARCHIVE (/perspectives/, archive-nisa_perspective).
   Featured card + search/Category filter bar + numbered pager.
   Grid cards reuse .nisa-fi-persp-card (existing CSS above).
   ============================================================ */

/* Featured card — media column fills the card height beside the copy,
   with the image inset 2rem from the card edges. */
.nisa-persp-featured__mediacol {
	align-self: stretch;
	padding: 2rem;
}

.nisa-persp-featured__mediacol .wp-block-post-featured-image,
.nisa-persp-featured__mediacol .wp-block-post-featured-image a,
.nisa-persp-featured__media img {
	height: 100%;
}

.nisa-persp-featured__media img {
	width: 100%;
	object-fit: cover;
	border-radius: 8px;
}

/* Chief Economist Updates featured card: a fixed 3:2 image, matching the grid
   cards, instead of stretching to the copy column's height (BugHerd #975).
   The /perspectives/ featured card keeps the full-height fill. */
.nisa-ceu-featwrap .nisa-persp-featured__mediacol .wp-block-post-featured-image,
.nisa-ceu-featwrap .nisa-persp-featured__mediacol .wp-block-post-featured-image a,
.nisa-ceu-featwrap .nisa-persp-featured__media img {
	height: auto;
}

.nisa-ceu-featwrap .nisa-persp-featured__media img {
	aspect-ratio: 3 / 2;
}

/* Read More — accent pill link (core/read-more renders a bare <a>). */
.nisa-persp-featured__more {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	width: fit-content;
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--secondary);
	border-radius: 999px;
	padding: 0.7rem 1.4rem;
	font-size: var(--wp--preset--font-size--sm);
	text-decoration: none;
}

.nisa-persp-featured__more::after {
	content: "\2192";
}

/* Hover: the same paint change the hero Subscribe pill makes. That pill has no
   background-COLOUR swap of its own — the archive-scoped rule pins its hover
   background back to accent, and what actually reads as a lighter blue is
   global.css's `.wp-block-button__link:hover { opacity: 0.85 }` over the band.
   This anchor carries .nisa-btn-pill directly (not on a .wp-block-button
   wrapper), so none of those rules reach it. Expressed here as the equivalent
   accent-over-muted colour rather than an opacity fade, because the section's
   scroll-reveal animates this element's opacity and a CSS transition on the
   same property would fight it. */
.nisa-persp-featured-tpl .nisa-persp-featured__more {
	transition: background-color 0.25s ease;
}

.nisa-persp-featured-tpl .nisa-persp-featured__more:hover {
	background-color: color-mix(in srgb, var(--wp--preset--color--accent) 85%, var(--wp--preset--color--muted));
}

/* ---- Filter bar (form injected by inc/perspectives-archive.php) ---- */
/* lint-allow: generic flex row, incidental overlap with another component */
.nisa-persp-filters {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 2rem; /* Figma 127:8415 — ~31px between controls */
}

.nisa-persp-filters__search {
	position: relative;
	display: flex;
	align-items: center;
	flex: 1 1 30rem;
	max-width: 30rem; /* Figma search field 480px */
}

.nisa-persp-filters__search input {
	width: 100%;
	/* border color = #0078AB (client spec); rgb() keeps the linter's hex rule happy */
	border: 1px solid rgb(0, 120, 171);
	border-radius: 6px;
	padding: 1.15rem 3rem 1.15rem 1.75rem; /* Figma field height 56px, left inset 28px */
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--sm);
}

.nisa-persp-filters__submit {
	position: absolute;
	right: 1rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: none;
	background: transparent;
	color: rgb(0, 120, 171);
	cursor: pointer;
	padding: 0.4rem;
	line-height: 1;
}

.nisa-persp-filters__submit svg {
	width: 1.15rem;
	height: 1.15rem;
}

.nisa-persp-filters__cat select {
	/* #0078AB border like the search input, but keep the pill radius */
	appearance: none;
	-webkit-appearance: none;
	border: 1px solid rgb(0, 120, 171);
	border-radius: 999px;
	padding: 1.15rem 3rem 1.15rem 1.75rem; /* Figma pill 56px tall; right room for the chevron */
	min-width: 11.5rem; /* Figma Category pill ≈ 212px */
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--sm);
	background-color: var(--wp--preset--color--secondary);
	color: var(--wp--preset--color--primary);
	/* custom chevron — %23 keeps the linter's hex rule happy; color matches the border */
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='8' viewBox='0 0 14 8' fill='none'%3E%3Cpath d='M1 1l6 6 6-6' stroke='%230078AB' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 1.5rem center;
	background-size: 0.875rem auto;
	cursor: pointer;
}

.nisa-persp-filters__clear {
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-style: italic;
	color: var(--wp--preset--color--accent);
}

/* ---- Numbered pager — circular current page ---- */
.nisa-persp-pager {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	margin-top: 70px; /* lint-allow: core/query-pagination doesn't emit spacing.margin */
}

/* lint-allow: generic flex row, incidental overlap with another component */
.nisa-persp-pager .wp-block-query-pagination-numbers {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.nisa-persp-pager .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.25rem;
	height: 2.25rem;
	border-radius: 50%;
	color: var(--wp--preset--color--accent);
	font-weight: 700;
	text-decoration: none;
}

.nisa-persp-pager .page-numbers.current {
	background-color: var(--wp--preset--color--secondary);
	color: var(--wp--preset--color--accent);
}

/* ---- Perspectives grid promo band (Quarterly Market Webinar) ----
   Injected after the grid, just above the pager (inc/perspectives-archive.php). */
.nisa-persp-promo {
	margin-top: 2rem; /* lint-allow: gap for an injected element, no blockGap to use */
}

.nisa-persp-promo__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem 2.5rem;
	/* Figma node 4741:4210 specifies #007CBB; `bright-blue` (#0378AA) is the
	   theme's established token for that comp blue (same mapping as the
	   perspective single's date, also specced #007cbb) and it measures slightly
	   better against white — 4.92:1 vs 4.56:1. */
	background-color: var(--wp--preset--color--bright-blue);
	border-radius: 8px;
	padding: 2rem clamp(1.5rem, 4vw, 3rem);
}

.nisa-persp-promo__text {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	max-width: 34rem;
}

.nisa-persp-promo__title {
	margin: 0; /* UA reset — injected HTML heading, no blockGap to lean on */
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-weight: 300;
	font-size: var(--wp--preset--font-size--xl);
	line-height: 1.2;
	color: var(--wp--preset--color--secondary);
}

/* White, not light-blue: at 13.7px this is normal-size text, and #D7E9F6 on the
   bright-blue fill measures 3.95:1 — under the 4.5:1 AA floor. The comp specs it
   white anyway (4.92:1). Tied to the fill above — do not revert one alone. */
.nisa-persp-promo__sub {
	margin: 0; /* UA reset — injected HTML paragraph */
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--secondary);
}

.nisa-persp-promo__link {
	width: fit-content;
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-style: italic;
	color: var(--wp--preset--color--secondary);
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Decorative waveform — the real asset from the comp (Figma node 4922:4171),
   88 variable-height bars carrying their own #6EB1E2 -> #049DDE gradient. It
   replaces the CSS repeating-gradient that faked this with uniform bars.
   aspect-ratio (not a fixed height) keeps the asset undistorted at any width;
   `contain` never crops it. No mask: the old one faded both ends because the
   faked bars were all the same height, whereas the real waveform already tapers
   to near-zero amplitude at both edges — masking would clip its outer bars. */
.nisa-persp-promo__wave,
.nisa-ins-webinar__wave {
	flex: 1 1 14rem;
	max-width: 31.1875rem; /* 499px — the asset's natural width; do not upscale */
	aspect-ratio: 499 / 134;
	background: url("../images/webinar-waveform.svg") no-repeat center / contain;
}

/* Perspectives archive title — deep-blue→bright-blue-2 text gradient. The
   padding + equal negative margin keeps the clipped text from cropping
   descenders without changing layout. (No transform here, so it's C4-safe.)
   #035D8F has no palette token; bright-blue-2 is the exact match for #049DDE. */
.nisa-persp-hero__title {
	background: linear-gradient(89deg, #035d8f 15.85%, var(--wp--preset--color--bright-blue-2) 49.45%);
	background-repeat: no-repeat;
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	padding: 0.1em 0.15em 0.25em;
	margin: -0.1em -0.15em -0.25em; /* gradient-clip offset, not sibling spacing */
}

/* Archive breadcrumb bar — white hairline under it (this archive only). */
.post-type-archive-nisa_perspective .nisa-breadcrumb-bar,
.tax-perspective_topics .nisa-breadcrumb-bar,
.post-type-archive-nisa_primer .nisa-breadcrumb-bar,
.post-type-archive-nisa_news .nisa-breadcrumb-bar,
.page-id-17 .nisa-breadcrumb-bar,
.page-id-2471 .nisa-breadcrumb-bar {
	border-bottom: 1px solid var(--wp--preset--color--secondary);
}

/* Perspectives CTAs — match the footer subscribe-bar button (see footer.css):
   a mid-blue circular disc with a white arrow that nudges 2px on hover. This
   supersedes the pill arrow-swap animation — custom.js still adds .nisa-btn-swap,
   but the rules below neutralize the swap and rebuild the disc treatment.
   Scoped to .nisa-persp-archive (Perspectives/Primers/News archives),
   .nisa-ins-hero (Insights page hero) and .nisa-ceu-hero (Chief Economist page
   hero) so only those Subscribe CTAs adopt it. */
:is(.nisa-persp-archive, .nisa-ins-hero, .nisa-ceu-hero) :is(.nisa-btn-pill, .is-style-nisa-pill-arrow) .wp-block-button__link.nisa-btn-swap {
	overflow: visible;
	/* Tighten the right side so the disc sits near the pill edge. */
	padding-right: 0.375rem;
	padding-left: 1.5rem;
	padding-top: 0.4375rem;
	padding-bottom: 0.4375rem;
	text-align: left;
}

/* Keep the body colour on hover — the footer button doesn't darken. */
:is(.nisa-persp-archive, .nisa-ins-hero, .nisa-ceu-hero) :is(.nisa-btn-pill, .is-style-nisa-pill-arrow) .wp-block-button__link.nisa-btn-swap:hover {
	background-color: var(--wp--preset--color--accent) !important;
	border-color: var(--wp--preset--color--accent) !important;
}

/* The label is static — the disc is a plain trailing icon, so cancel the
   swap's text slide in every state. */
:is(.nisa-persp-archive, .nisa-ins-hero, .nisa-ceu-hero) .nisa-btn-swap__text,
:is(.nisa-persp-archive, .nisa-ins-hero, .nisa-ceu-hero) :is(.nisa-btn-pill, .is-style-nisa-pill-arrow) .wp-block-button__link.nisa-btn-swap:is(:hover, :focus-visible) .nisa-btn-swap__text {
	translate: none;
	transition: none;
}

/* Drop the swap's incoming (::before) arrow entirely. */
:is(.nisa-persp-archive, .nisa-ins-hero, .nisa-ceu-hero) :is(.nisa-btn-pill, .is-style-nisa-pill-arrow) .nisa-btn-swap::before {
	display: none;
}

/* Rebuild ::after as the footer's circular disc arrow. */
:is(.nisa-persp-archive, .nisa-ins-hero, .nisa-ceu-hero) :is(.nisa-btn-pill, .is-style-nisa-pill-arrow) .nisa-btn-swap::after {
	content: "";
	position: static;
	right: auto;
	top: auto;
	width: 1.75rem;
	height: 1.75rem;
	border-radius: 50%;
	background-color: #1365A6;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C%2Fsvg%3E");
	background-repeat: no-repeat;
	background-position: center;
	background-size: 0.875rem 0.875rem;
	mask-image: none;
	-webkit-mask-image: none;
	opacity: 1;
	translate: none;
	transition: transform 0.25s ease;
}

:is(.nisa-persp-archive, .nisa-ins-hero, .nisa-ceu-hero) :is(.nisa-btn-pill, .is-style-nisa-pill-arrow) .wp-block-button__link.nisa-btn-swap:is(:hover, :focus-visible)::after {
	transform: translateX(2px);
	translate: none;
	opacity: 1;
	transition: transform 0.25s ease;
}

@media (prefers-reduced-motion: reduce) {
	:is(.nisa-persp-archive, .nisa-ins-hero, .nisa-ceu-hero) :is(.nisa-btn-pill, .is-style-nisa-pill-arrow) .nisa-btn-swap::after {
		transition: none;
	}
}

/* -----------------------------------------------
   Insights hub page (/insights/) — Figma 4533:11363
   Reuses .nisa-fi-persp-card (card rows), .nisa-cta-solid__band (CTA), and the
   Perspectives-hero disc button (.nisa-ins-hero scope above). Sections sit on a
   mint→light-blue gradient wash (.nisa-ins-body).
   ----------------------------------------------- */

/* Hero — solid light-blue with a decorative dot-grid on the right. */
.nisa-ins-hero {
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

/* Shared with the Dot Grid group block style below — one dot field, one rule. */
.nisa-ins-hero::after {
	content: "";
	position: absolute;
	z-index: 0;
	top: 0;
	right: 0;
	width: min(46%, 640px);
	height: 100%;
	background-image: radial-gradient(circle, color-mix(in srgb, var(--wp--preset--color--bright-blue) 32%, transparent) 1.6px, transparent 1.7px);
	background-size: 27px 27px;
	-webkit-mask-image: linear-gradient(to left, #000 45%, transparent), linear-gradient(to bottom, #000 60%, transparent);
	-webkit-mask-composite: source-in;
	mask-image: linear-gradient(to left, #000 45%, transparent), linear-gradient(to bottom, #000 60%, transparent);
	mask-composite: intersect;
	pointer-events: none;
}

/* Hero content is kept above the dot layer by the shared
   `.nisa-cta-band__overlay > *, .nisa-ins-hero > *` rule (C5 dedup). */

.nisa-ins-hero__lead {
	color: var(--wp--preset--color--primary);
}

/* Hero title — explicit 60px (design review). !important is required to beat
   WP's has-stat-font-size utility, which itself uses !important. */
h1.nisa-ins-hero__title {
	font-size: 60px !important; /* lint-allow: exact size set in design review, no matching fontSizes slug */
}

/* Below-hero body — cream wash fading into the light-blue base over ~620px. */
.nisa-ins-body {
	background-color: var(--wp--preset--color--light-blue);
	background-image: linear-gradient(to bottom, color-mix(in srgb, var(--wp--preset--color--muted) 90%, transparent) 0, rgba(250, 249, 245, 0) 620px);
}

/* Jump-to nav — centered serif links. */
.nisa-ins-jumpnav__label {
	color: var(--wp--preset--color--gray);
}

.nisa-ins-jumpnav__link {
	font-family: var(--wp--preset--font-family--ivypresto-headline);
}

.nisa-ins-jumpnav__link a:hover {
	color: var(--wp--preset--color--bright-blue);
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Section heading + subhead. */
/* Section title — explicit 30px (design review). !important is required to beat
   WP's has-xxl-font-size utility, which itself uses !important. */
h2.nisa-ins-sectitle {
	font-size: 30px !important; /* lint-allow: exact size set in design review, no matching fontSizes slug */
}

.nisa-ins-secsub {
	max-width: 46rem;
	color: var(--wp--preset--color--primary);
}

.nisa-ins-sechead__text {
	max-width: 42rem;
}

/* Italic serif "View …" links, shared across sections. */
.nisa-ins-vlink {
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-style: italic;
	color: var(--wp--preset--color--accent);
	text-decoration: underline;
	text-underline-offset: 3px;
}

.nisa-ins-vlink:hover {
	color: var(--wp--preset--color--bright-blue);
}

.nisa-ins-vlink--light {
	color: var(--wp--preset--color--secondary);
}

.nisa-ins-vlink--light:hover {
	color: var(--wp--preset--color--light-blue);
}

/* Resource cards (Market and Economy + Pension Risk Pulse). */
.nisa-ins-card {
	height: 100%;
	display: flex;
	flex-direction: column;
	gap: 0.85rem;
	border: 1px solid #e1e1e1;
	border-radius: 4px;
	padding: clamp(1.5rem, 2.5vw, 2rem);
	transition: box-shadow 0.25s ease;
}

/* Hover lift — same soft navy shadow as .nisa-fi-persp-card, no movement.
   :focus-within carries it to keyboard users on the card's inner link. */
.nisa-ins-card:hover,
.nisa-ins-card:focus-within {
	box-shadow: 0 6px 18px color-mix(in srgb, var(--wp--preset--color--primary) 12%, transparent);
}

.nisa-ins-card__title {
	margin: 0;
	line-height: 1.15;
}

.nisa-ins-card__desc {
	color: var(--wp--preset--color--primary);
	margin-top: auto;
}

/* Chart placeholder (FPO — pending real chart exports). */
.nisa-ins-chartph {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 168px;
	border-radius: 4px;
	background:
		repeating-linear-gradient(to bottom, transparent 0 41px, color-mix(in srgb, var(--wp--preset--color--primary) 9%, transparent) 41px 42px),
		var(--wp--preset--color--pale-blue);
}

.nisa-ins-chartph span {
	font-size: 0.7rem; /* lint-allow: decorative FPO placeholder label inside a wp:html chart box, no editor/block control exists */
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: color-mix(in srgb, var(--wp--preset--color--primary) 35%, transparent);
}

/* Live date + featured image (pinned Insight Card query, BugHerd: Insights cards
   dynamic). core/query has no spacing support in WP 7.1, so the flow-layout
   margin it inherits as a card child is zeroed here — the date then hugs the
   title exactly like the old static date paragraph (margin 0). The date→image
   gap is the inner group's blockGap (block attribute). */
.nisa-ins-card > .nisa-ins-card__live {
	margin-block-start: 0; /* lint-allow: core/query exposes no margin control; restores the static card's title→date spacing */
}

/* Top "Market and Economy" cards — more breathing room under the chart, and the
   copy + link bottom-aligned so the two cards' links line up even when their
   titles/copy differ in length (one wraps to two lines, the other doesn't). The
   desc paragraph carries an inline margin-top:0 (block spacing attribute), so
   the intended margin-top:auto needs !important to win. Scoped to this section. */
.nisa-ins-market :is(.nisa-ins-chartph, .nisa-ins-card__live) {
	margin-bottom: 1.5rem; /* lint-allow: extra space under the chart beyond the card's uniform blockGap; chart is a wp:html block with no block spacing control, and this pairs with the desc's margin-top:auto to bottom-align the copy/link */
}

/* Reserve two lines for the title so a one-line title (Derivatives Market
   Overview) occupies the same height as a two-line one (Economic and Market
   Overview) — this keeps the date and, crucially, the CHART aligned across the
   two cards. line-height is 1.15, so two lines = 2.3em. */
.nisa-ins-market .nisa-ins-card__title {
	min-height: 2.3em;
}

.nisa-ins-market .nisa-ins-card__desc {
	margin-top: auto !important;
}

/* Quarterly Market Webinar band. */
.nisa-ins-webinar__text {
	max-width: 40rem;
}

/* .nisa-ins-webinar__wave shares the waveform asset rule with
   .nisa-persp-promo__wave above. */

/* Resources — icon columns with a bottom-ruled link. */
.nisa-ins-res__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 8px;
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--secondary);
}

.nisa-ins-res__icon svg {
	width: 30px;
	height: 30px;
}

.nisa-ins-res__title {
	margin: 40px 0 0; /* lint-allow: 40px icon→title gap set in design review */
}

.nisa-ins-res__desc {
	color: var(--wp--preset--color--primary);
}

.nisa-ins-res__linkwrap {
	margin-top: auto;
	padding-top: 3.75rem;
	padding-bottom: 2rem;
	border-bottom: 1px solid var(--wp--preset--color--primary);
}

/* CTA band button — inverts on hover (white fill, accent label) instead of the
   navy fill the shared pill hover gives every other pill. !important is forced
   twice over: the shared hover rule uses it for the background, and WP emits
   .has-secondary-color with !important for the resting label colour. The arrow
   is a masked SVG painted with background-color: currentColor, so it recolours
   with the label — no separate rule needed. Written against the link rather
   than .nisa-btn-swap so the no-JS / reduced-motion state inverts too. */
.nisa-ins-cta :is(.nisa-btn-pill, .is-style-nisa-pill-arrow) .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--secondary) !important;
	border-color: var(--wp--preset--color--secondary) !important;
	color: var(--wp--preset--color--accent) !important;
}

/* -----------------------------------------------
   Chief Economist Updates page (/chief-economist-updates/) — Figma 4487:5197
   Light-blue hero (H1 uses the `display` slug → ~60px desktop) with an author
   chip, then a full-bleed navy body holding the featured perspective card
   (reuses .nisa-persp-featured), the recent-perspectives grid (reuses
   .nisa-persp-grid / .nisa-fi-persp-card), and the Stephen Douglass bio band.
   ----------------------------------------------- */

/* Author chip — avatar + name + title, links to the People page. */
.nisa-ceu-author {
	display: inline-flex;
	align-items: center;
	gap: 0.75rem;
	text-decoration: none;
}

.nisa-ceu-author__avatar {
	width: 48px;
	height: 48px;
	border-radius: 50%;
	border: 2px solid var(--wp--preset--color--secondary); /* #FFFFFF ring */
	object-fit: cover;
	flex-shrink: 0;
}

.nisa-ceu-author__text {
	display: flex;
	flex-direction: column;
	line-height: 1.3;
}

.nisa-ceu-author__name {
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-size: var(--wp--preset--font-size--lg);
	color: var(--wp--preset--color--primary);
}

.nisa-ceu-author__title {
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--accent);
}

/* Shared hover-underline: CEU author name + Contact phone/address links. */
.nisa-ceu-author:hover .nisa-ceu-author__name,
.nisa-contact__phone a:hover,
.nisa-contact__phone a:focus-visible,
.nisa-contact__address a:hover,
.nisa-contact__address a:focus-visible {
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Navy body — light-blue continues from the hero for the first 130px (behind
   the featured card's top), then hard-switches to primary navy. */
.nisa-ceu-body {
	background-image: linear-gradient(to bottom, var(--wp--preset--color--light-blue) 0, var(--wp--preset--color--light-blue) 130px, var(--wp--preset--color--primary) 130px);
}

/* The updates pager sits on this navy body (not a light archive grid section),
   so the shared accent-blue page numbers fail contrast badly (accent on primary
   is 1.58:1). Recolor to light tokens on the dark ground — light-blue numbers
   (11:1), white on hover — leaving the current page (white disc) untouched. */
.nisa-ceu-body .nisa-persp-pager .page-numbers:not(.current),
.nisa-ceu-body .nisa-persp-pager .wp-block-query-pagination-previous,
.nisa-ceu-body .nisa-persp-pager .wp-block-query-pagination-next {
	color: var(--wp--preset--color--light-blue);
}

.nisa-ceu-body .nisa-persp-pager .page-numbers:not(.current):hover,
.nisa-ceu-body .nisa-persp-pager .wp-block-query-pagination-previous:hover,
.nisa-ceu-body .nisa-persp-pager .wp-block-query-pagination-next:hover {
	color: var(--wp--preset--color--secondary);
}

/* Tighten the pager rhythm: close to the cards above, clear of the bio CTA
   below. The base .nisa-persp-pager margin-top:70px is tuned for the archives'
   light grid section; here the grid and the CTA share one navy band. */
.nisa-ceu-body .nisa-persp-pager {
	margin-top: 1.25rem; /* lint-allow: core/query-pagination doesn't emit spacing.margin */
	margin-bottom: 2rem; /* lint-allow: core/query-pagination doesn't emit spacing.margin */
}

/* Stephen Douglass bio band — cream card with the photo inset (65px sides,
   20px top/bottom) and capped at 275px tall. Figure padding supplies the inset
   (the "margins"); the flex centers a narrower image. */
.nisa-ceu-bio {
	overflow: hidden;
}

.nisa-ceu-bio__photo {
	margin: 0;
	padding: 20px 65px;
	display: flex;
	justify-content: center;
}

.nisa-ceu-bio__photo img {
	display: block;
	max-height: 275px;
	max-width: 100%;
	height: auto;
}

/* -----------------------------------------------
   Thought Leadership — single-person Perspectives list
   (templates/single-nisa_person.html + inc/person-perspectives.php)
   ----------------------------------------------- */

/* Heading | list, sharing the person-profile bio gutter + measure so the
   "Thought Leadership" label lines up under "About" and the list lines up with
   the bio/About content column. Vars come from .nisa-person-single (ancestor);
   the <=1024 collapse to a single column is inherited from that block too. */
.nisa-tl__inner,
.nisa-nm__inner {
	display: grid;
	grid-template-columns: var(--nisa-bio-gutter) minmax(0, 1fr);
	align-items: start;
}

/* The list sits in the content column but is capped narrower than the bio
   measure, per the design. News Mentions shares the cap (2026-09-30) so the two
   stacked blue modules line up. */
.nisa-tl__content,
.nisa-nm__content {
	max-width: 38rem;
}

/* Each Perspective row: eyebrow + linked title, divided by a hairline, with a
   decorative arrow anchored right (row right-padding reserves its gutter). The
   title link stretches across the row (.nisa-tl__title a::after, consolidated
   above) so the whole row is clickable; the navy title color and the stretch
   rule are also shared above (C5). */
.nisa-tl__item {
	position: relative;
	border-bottom: 1px solid var(--wp--preset--color--lighter-blue);
}

/* Decorative "go to post" arrow — the title link is the real control. */
.nisa-tl__item::after {
	content: "\2192";
	position: absolute;
	top: 50%;
	right: 0;
	transform: translateY(-50%);
	color: var(--wp--preset--color--primary);
	line-height: 1;
}

/* Hover / keyboard focus accent — title links, decorative arrow,
   and the News Mentions title + Read Article links. */
.nisa-tl__item:hover .nisa-tl__title a,
.nisa-tl__title a:focus-visible,
.nisa-tl__item:hover::after,
.nisa-nm__item:hover .nisa-nm__title a,
.nisa-nm__title a:focus-visible,
.nisa-nm__readmore:hover,
.nisa-nm__readmore:focus-visible {
	color: var(--wp--preset--color--accent);
}

/* -----------------------------------------------
   NISA News Mentions — single-person news list
   (templates/single-nisa_person.html + inc/person-news-mentions.php)
   ----------------------------------------------- */

/* Layout grid, heading and list width are all shared with Thought Leadership
   above, so the two modules line up when stacked. Both sit inside one
   light-blue band (.nisa-person-related — its Background colour + section
   padding are block attributes). When a bio has BOTH, a hairline divides them
   so the posts don't run on from the news list. Conditional on both being
   rendered (each drops itself when empty — inc/person-*.php), so it can't be a
   block attribute. */
.nisa-nm-block + .nisa-tl-block {
	padding-top: clamp(2rem, 4vw, 4rem); /* the gap ABOVE the rule is the band's blockGap */
	border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 18%, transparent);
}

/* Each mention: title link + "Read Article", divided by a hairline. */
.nisa-nm__item {
	border-bottom: 1px solid var(--wp--preset--color--lighter-blue);
}

/* "Read Article" — italic serif link beneath each title. */
.nisa-nm__readmore {
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-style: italic;
	color: var(--wp--preset--color--primary);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Mobile stack — the shared <=1024 collapse in the person-profile block is
   re-overridden by the .nisa-tl__inner / .nisa-nm__inner base grid + heading +
   content rules ABOVE (later source order), which left a 0-width gutter column
   and overlapped the heading on top of the list. Re-assert the single-column
   stack here so it wins by source order. */
@media (max-width: 1024px) {
	.nisa-tl__inner,
	.nisa-nm__inner {
		grid-template-columns: 1fr;
	}

	.nisa-nm__heading {
		text-align: left;
		padding-right: 0;
	}

	.nisa-tl__content,
	.nisa-nm__content {
		max-width: none;
	}
}

/* ============================================================
   SINGLE PERSPECTIVE (templates/single-nisa_perspective.html)
   Article title rail + author sidebar (filler), featured-image
   hero + post-content, author-bio boxes (filler), categories/
   AddToAny share row, same-topic Related Perspectives grid,
   disclosure. Figma: Single Perspectives node 4487:6977.
   ============================================================ */

/* Empty spacer column that offsets the title to align with the main
   content column on desktop; collapses away on the mobile stack. */
@media (max-width: 781px) {
	.nisa-persp-single__head-spacer {
		display: none;
	}
}

/* Date eyebrow (date + appended read-time share one line) — uppercase styling
   consolidated into the shared .nisa-fi-persp-card__date rule. */

/* Topic pills — post-terms rendered as a wrapping row of light-blue chips.
   The core separator span is hidden; each term anchor becomes a pill. */
.nisa-persp-single__pills {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem;
}

.nisa-persp-single__pills .wp-block-post-terms__separator {
	display: none;
}

.nisa-persp-single__pills a {
	display: inline-flex;
	align-items: center;
	min-height: 28px; /* Figma node 4971-8881 chip height — padding alone overshot to 31px */
	padding-inline: 0.75rem;
	border-radius: 4px;
	background-color: var(--wp--preset--color--light-blue);
	color: var(--wp--preset--color--gray);
	font-weight: 500;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	text-decoration: none;
}

/* The design alternates chip fills so adjacent terms read as separate tags:
   odd chips take the light-blue token, even chips the warm cream. #EEEDE6 has no
   theme.json token (see the .nisa-news-people note below, which approximates the
   same design colour with `muted`). */
.nisa-persp-single__pills a:nth-of-type(even),
.nisa-persp-single__pills a:nth-of-type(even):hover {
	background-color: #eeede6;
}

.nisa-persp-single__pills a:hover {
	background-color: var(--wp--preset--color--lighter-blue);
}

/* News "people" pills (nisa/news-people block) use the warm cream fill instead
   of the light-blue topic-pill fill — `muted` (#FAF9F5) is the closest theme
   token to the requested #EEEDE6. Hover kept on the same fill so it doesn't
   flash the inherited blue. */
.nisa-persp-single__pills.nisa-news-people a,
.nisa-persp-single__pills.nisa-news-people a:hover {
	background-color: var(--wp--preset--color--muted);
}

/* News + perspective single meta rows — the pills cell and the Share block sit
   in two equal columns, each opened by a top hairline (matches
   .nisa-persp-single__main's divider colour). border+padding co-located as a
   bespoke divider cell. Per the Figma (node 4971-8881) the perspective row uses
   the same two-rule treatment, so both templates share this cell. */
.nisa-news-meta__cell,
.nisa-persp-meta__cell {
	border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 12%, transparent);
	padding-top: 1rem; /* co-located with the divider border — space below the rule */
}

/* Section labels (AUTHOR / CATEGORIES / SHARE). */
.nisa-persp-single__label {
	margin-bottom: 0.25rem; /* lint-allow: label-to-content offset inside a flex-gap-free heading rail */
}

/* Article body leading — 1.75 instead of the theme.json global 1.5, across all
   three singles (perspective, primer, news). The paragraph selector is listed
   explicitly so a paragraph carrying its own preset/class still lands on 1.75;
   an author's inline line-height from the editor still wins over both. */
.single-nisa_perspective .entry-content,
.single-nisa_perspective .entry-content p,
.single-nisa_primer .entry-content,
.single-nisa_primer .entry-content p,
.single-nisa_news .entry-content,
.single-nisa_news .entry-content p {
	line-height: 1.75;
}

/* Space below every article h2. Needs the element in the selector to outweigh
   global.css's `.single .entry-content > * + *`, which zeroes margin-block-end
   for the prose rhythm. */
.single-nisa_perspective .entry-content h2,
.single-nisa_primer .entry-content h2,
.single-nisa_news .entry-content h2 {
	margin-bottom: 20px; /* lint-allow: exact heading-to-body gap set in design review */
}

/* Body section vertical padding — moved off the group's inline block attributes
   so it lives with the rest of the single-perspective layout. Bottom now matches
   the top clamp (was the larger `section` spacing preset). */
.nisa-persp-single__body {
	padding-top: clamp(1.5rem, 3vw, 2.5rem);
	padding-bottom: clamp(1.5rem, 3vw, 2.5rem);
}

/* Two-column split for the single-perspective layout. Widths live here (not as
   inline column flex-basis attributes) so the narrow-rail / wide-body ratio is
   controlled from one place across the head, body, bios, and meta rows. The
   spacer columns match the aside so the title/bios/meta align with the article
   body. Per the Figma (node 4971-8881): ~16% rail + ~62% body, left-aligned
   with the shorter measure leaving intentional whitespace to the right.

   !important + flex-grow:0 are required: with no inline flex-basis on the
   columns, core's own `.wp-block-columns:not(.is-not-stacked-on-mobile) >
   .wp-block-column` rule (specificity 0,3,0) sets flex-basis:0/flex-grow:1 and
   would otherwise beat these class selectors, collapsing the layout to equal
   columns. Core only pins flex-grow:0 for columns that carry an inline
   flex-basis, so we assert both here. Desktop only — below 782px columns stack
   full-width. */
@media (min-width: 782px) {
	.nisa-persp-single__cols > .nisa-persp-single__aside,
	.nisa-persp-single__cols > .nisa-persp-single__head-spacer {
		flex-basis: 17% !important;
		flex-grow: 0 !important;
	}

	.nisa-persp-single__cols > .nisa-persp-single__main,
	.nisa-persp-single__cols > .nisa-persp-single__head-col,
	.nisa-persp-single__cols > .nisa-persp-bios__col,
	.nisa-persp-single__cols > .nisa-persp-meta__col {
		flex-basis: 63% !important;
		flex-grow: 0 !important;
	}

	/* Content columns share the same left gutter so the head title, article
	   body, and bios all line up on one left edge. Only the body's main column
	   also carries the divider rail border. */
	.nisa-persp-single__main,
	.nisa-persp-single__head-col,
	.nisa-persp-bios__col,
	.nisa-persp-meta__col {
		padding-left: clamp(2rem, 4vw, 4.5rem); /* co-located with the rail border — bespoke divider gutter */
	}

	/* Divider rail between the author sidebar and the article body. */
	.nisa-persp-single__main {
		border-left: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 12%, transparent);
	}

	/* Author/tools sidebar pins under the sticky header while the longer
	   article column scrolls past. Desktop only — below 782px the columns
	   stack and the sidebar stays in normal flow. align-self:flex-start stops
	   the flex column from stretching to the full row height, which would
	   otherwise leave no runway for the sticky offset to take effect. */
	.nisa-persp-single__aside {
		position: sticky;
		top: 115px;
		align-self: flex-start;
	}
}

/* Primers on phones: the stacked sidebar (Download + "Get Insights in Your
   Inbox") moves below the primer content instead of above it (BugHerd #946).
   Body row only (the head row shares the class) and primers only, so
   Perspectives and News keep the sidebar first. */
@media (max-width: 781px) {
	.single-nisa_primer .nisa-persp-single__body > .nisa-persp-single__cols {
		flex-direction: column-reverse;
	}
}

/* Contributor author chips — server-rendered by the nisa/perspective-contributors
   block from the ACF contributor_attribution field, so their layout lives here
   rather than in block attributes (non-block markup, CSS-gate allowed). */
.nisa-persp-authors > * + * {
	margin-top: 1rem; /* lint-allow: server-rendered chips (nisa/perspective-contributors render.php) — non-block markup, no blockGap available */
}

.nisa-persp-author {
	display: flex;
	align-items: center;
	gap: 1rem;
}

/* Tablet band: the aside becomes a sidebar at 782px but stays narrow until the
   layout widens, so the avatar and name side by side crowd each other and the
   name wraps badly. Stack the chip and left-align it through that range only —
   below 782px the aside is full width again, above 1024px there is room for the
   row. Scoped to the aside so the same chip keeps its row layout wherever else
   the block is used. */
@media (min-width: 782px) and (max-width: 1024px) {
	.nisa-persp-single__aside .nisa-persp-author {
		flex-direction: column;
		align-items: flex-start;
		gap: 0; /* the 1rem row gap reads as a big vertical step once stacked */
	}
}

/* Circular avatar — initials fallback or a featured-image photo clipped round. */
.nisa-persp-author__avatar {
	width: 3.25rem;
	height: 3.25rem;
	border-radius: 50%;
	display: grid;
	place-items: center;
	flex-shrink: 0;
	line-height: 1;
	overflow: hidden;
}

.nisa-persp-author__name {
	line-height: 1.15;
}

/* Contributor name links to their profile; underline on interaction only
   (base inherit-colour/no-underline is in the shared link group above). */
.nisa-persp-author__name a:hover,
.nisa-persp-author__name a:focus {
	text-decoration: underline;
}

.nisa-persp-author__cred {
	line-height: 1.2;
}

/* Listen / Download tool pills (filler). Not .nisa-btn-pill — that variant
   hardcodes an accent fill + arrow glyph; these stay light-blue with a
   leading play/download glyph. Background comes from the block colour attr. */
:is(.nisa-persp-tool, .is-style-nisa-tool-listen, .is-style-nisa-tool-download) .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	border: none;
}

/* Legacy paint — .nisa-persp-tool only (see the pill note above). */
.nisa-persp-tool .wp-block-button__link {
	border-radius: 100vw;
	padding: 0.75rem 1.5rem;
}

:is(.nisa-persp-tool, .is-style-nisa-tool-listen, .is-style-nisa-tool-download, .is-style-nisa-disc-download) .wp-block-button__link::before {
	content: "";
	display: inline-block;
	width: 1.1em;
	height: 1.1em;
	background-color: currentColor;
	flex-shrink: 0;
	mask-size: contain;
	-webkit-mask-size: contain;
	mask-repeat: no-repeat;
	-webkit-mask-repeat: no-repeat;
	mask-position: center;
	-webkit-mask-position: center;
}

:is(.nisa-persp-tool--listen, .is-style-nisa-tool-listen) .wp-block-button__link::before {
	width: 1.5em;
	height: 1.5em;
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='10.5' fill='none' stroke='black' stroke-width='1.5'/%3E%3Cpath d='M9.5 8v8l7-4z' fill='black'/%3E%3C/svg%3E");
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='10.5' fill='none' stroke='black' stroke-width='1.5'/%3E%3Cpath d='M9.5 8v8l7-4z' fill='black'/%3E%3C/svg%3E");
}

:is(.nisa-persp-tool--download, .is-style-nisa-tool-download, .is-style-nisa-disc-download) .wp-block-button__link::before {
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v12'/%3E%3Cpath d='m7 10 5 5 5-5'/%3E%3Cpath d='M5 21h14'/%3E%3C/svg%3E");
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v12'/%3E%3Cpath d='m7 10 5 5 5-5'/%3E%3Cpath d='M5 21h14'/%3E%3C/svg%3E");
}

/* The "Download Article" pill is rendered by the Post to PDF plugin shortcode
   ([post_pdf_download]) rather than a core button, so restyle its output to
   match the sibling .nisa-persp-tool--listen pill. Higher specificity + the
   .p2pdf-wrap ancestor keep these ahead of the plugin's own button CSS
   regardless of stylesheet load order. */
/* In the sticky aside the Listen pill (core button) and the Download pill
   (p2pdf shortcode <a>) sit in a vertical buttons stack. Force both to fill the
   rail so they render at an identical width regardless of label length — the
   shortcode pill can't take the core button's width attribute, so this is the
   only place the two can be matched. Scoped to the aside so the bios --row
   variant keeps its content-width pills. */
.nisa-persp-single__aside .nisa-persp-tools .wp-block-button,
.nisa-persp-single__aside .nisa-persp-tools .p2pdf-wrap {
	width: 100%;
}

.nisa-persp-single__aside .nisa-persp-tools .wp-block-button__link,
.nisa-persp-single__aside .nisa-persp-tools .p2pdf-download-btn {
	width: 100%;
	/* border-box so the pill's own horizontal padding counts inside the 100%
	   rather than adding to it — the plugin button defaults to content-box, which
	   pushed the Download pill ~48px wider than Listen and past the rail edge. */
	box-sizing: border-box;
	justify-content: center;
}

.nisa-persp-tools .p2pdf-wrap {
	margin: 0;
}

.nisa-persp-tools .p2pdf-wrap .p2pdf-download-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	border-radius: 100vw;
	/* Match the Listen pill's 1.5rem side padding (theme.json nisa-tool-listen).
	   In the sticky aside both pills stretch to width:100% so this is cosmetic,
	   but where they render at content width (inline / report layout) 0.5rem
	   looked visibly pinched next to Listen. */
	padding: 0.75rem 1.5rem;
	border: none;
	box-shadow: none;
	font-family: inherit;
	font-size: inherit;
	font-weight: 500;
	background-color: var(--wp--preset--color--light-blue) !important;
	color: var(--wp--preset--color--primary) !important;
	transition: background-color 0.18s ease;
}

.nisa-persp-tools .p2pdf-wrap .p2pdf-download-btn:hover,
.nisa-persp-tools .p2pdf-wrap .p2pdf-download-btn:focus {
	background-color: var(--wp--preset--color--lighter-blue) !important;
	color: var(--wp--preset--color--primary) !important;
	box-shadow: none;
	transform: none;
}

.nisa-persp-tools .p2pdf-wrap .p2pdf-download-btn::before {
	content: "";
	display: inline-block;
	width: 1.1em;
	height: 1.1em;
	background-color: currentColor;
	flex-shrink: 0;
	mask-size: contain;
	-webkit-mask-size: contain;
	mask-repeat: no-repeat;
	-webkit-mask-repeat: no-repeat;
	mask-position: center;
	-webkit-mask-position: center;
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v12'/%3E%3Cpath d='m7 10 5 5 5-5'/%3E%3Cpath d='M5 21h14'/%3E%3C/svg%3E");
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v12'/%3E%3Cpath d='m7 10 5 5 5-5'/%3E%3Cpath d='M5 21h14'/%3E%3C/svg%3E");
}

/* Featured-image hero. */
.nisa-persp-single__hero-img img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 4px;
}

/* Keep post-content images (and other embedded media) inside the article
   column's gutter — they must never bleed past the divider rail / column edge. */
.nisa-persp-single__main img {
	max-width: 100%;
	height: auto;
}

/* Author-bio cards — server-rendered by the nisa/perspective-contributors
   block (variant "bios") from the ACF contributor_attribution field, so the
   card layout lives here rather than in block attributes (non-block markup,
   CSS-gate allowed). */
.nisa-persp-bio-list > * + * {
	margin-top: 1.25rem; /* lint-allow: server-rendered bio cards (nisa/perspective-contributors render.php) — non-block markup, no blockGap available */
}

.nisa-persp-bio {
	display: flex;
	align-items: flex-start;
	gap: 1.5rem;
	background-color: var(--wp--preset--color--muted);
	border-radius: 4px;
	padding: 1.75rem;
}

/* Square avatar — initials fallback or a featured-image photo clipped square. */
.nisa-persp-bio__avatar {
	width: 6.5rem;
	height: 6.5rem;
	border-radius: 4px;
	display: grid;
	place-items: center;
	flex-shrink: 0;
	line-height: 1;
	overflow: hidden;
}

.nisa-persp-bio__meta {
	flex: 1 1 auto;
}

.nisa-persp-bio__name {
	line-height: 1.2;
}

/* .nisa-persp-bio__link a styling consolidated into the shared accent-underline
   rule in the breadcrumb section. */

@media (max-width: 600px) {
	.nisa-persp-bio {
		flex-wrap: wrap;
	}
}

/* Categories / Share meta band — hairline rules top and bottom. */
/* Categories / Share meta band — aligned with the article column (shares the
   32%/64% spacer grid used by the header + bios). The topic pills sit on one
   row opposite the Share icons. */
.nisa-persp-meta__col {
	padding-block: clamp(1.25rem, 2.5vw, 1.75rem);
}

.nisa-persp-meta__row {
	width: 100%;
}

/* AddToAny share icons. The plugin injects each icon's square background inline
   (client-side, from its own icon-color option, #c7c7c7). We take ownership of
   that colour in the stylesheet — !important supersedes the plugin's inline
   value — so the base and hover states are authored here rather than in the
   plugin settings. The plugin default #c7c7c7 fails WCAG 1.4.11: its white
   glyphs sit at only 1.69:1, and the square itself is barely visible on the
   white page. #767676 lifts the white glyph to 4.54:1 (and the square edge to
   4.54:1 on white) while staying a recognisable neutral that reads distinctly
   lighter than the navy hover. No theme.json token maps to it (the `gray`
   token #666 is darker than the design's understated grey).
   Scoped to the plugin's own .addtoany_list widget rather than a theme wrapper:
   the share row appears in several single templates (perspectives, insights /
   market reports, news) each with a different wrapper class, and .addtoany_list
   is used ONLY for these rows, so this covers every instance in one place. */
.addtoany_list a:not(.addtoany_special_service) > span {
	border-radius: 6px;
	background-color: #767676 !important; /* accessible neutral grey — white glyph 4.54:1; no theme.json token maps */
}

.addtoany_list a:not(.addtoany_special_service):hover > span,
.addtoany_list a:not(.addtoany_special_service):focus > span {
	background-color: var(--wp--preset--color--primary) !important; /* #012E52 */
}

/* Related Perspectives section — vertical padding moved off the group's inline
   block attributes. Bottom pad only; top padding intentionally dropped so the
   section sits tight under the meta band above it. */
.nisa-persp-related {
	padding-bottom: var(--wp--preset--spacing--section);
}

/* Related-grid cards use a fixed 16px rhythm (date → title → topic tag) rather
   than the archive cards' bottom-pinned tag: bump the flex gap to 16px and unpin
   the topic tag so that gap sets the space above it. Scoped to the related
   section so the archive / insights card grids keep their equal-height pin. */
.nisa-persp-related .nisa-fi-persp-card__body {
	display: flex; /* bespoke flex container owns its gap (co-located per lint C2) */
	gap: 1rem;
}

.nisa-persp-related .nisa-fi-persp-card__cat {
	margin-top: 0; /* unpin from the card bottom so the 16px gap governs the offset */
}

/* Related Perspectives header row — title left, view-all link right. The
   view-all + bio "View Bio" link styling is consolidated into the shared
   accent-underline rule in the breadcrumb section. */

@media (max-width: 900px) {
	.nisa-persp-related__query .wp-block-post-template.is-layout-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 600px) {
	.nisa-persp-related__query .wp-block-post-template.is-layout-grid {
		grid-template-columns: 1fr;
	}
}

/* Disclosure small print. */
.nisa-persp-disclosure__title {
	letter-spacing: 0.02em;
}

/* -----------------------------------------------
   Search Results (templates/search.html)
   Single-column list: rounded search box, "N results found" count, then
   image-left rows (3/2 media matching the article/resource cards) divided by
   hairlines, each with title + excerpt + "View more" link.
   ----------------------------------------------- */

/* Rounded search box at the top. */
.nisa-search__box .wp-block-search__inside-wrapper {
	background-color: var(--wp--preset--color--muted);
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 12%, transparent);
	border-radius: 20px;
	padding: 0.4rem 0.5rem 0.4rem 1.25rem;
}

.nisa-search__box .wp-block-search__input {
	background: transparent;
	border: none;
}

.nisa-search__box .wp-block-search__button {
	background: transparent;
	color: var(--wp--preset--color--primary);
}

/* Each result — image left, text right; hairline divider between rows. */
.nisa-search-result {
	border-bottom: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 12%, transparent);
}

.nisa-search-result__media {
	flex-shrink: 0;
}

.nisa-search-result__body {
	flex: 1;
	min-width: 0;
}

/* Title link reads navy (inherits the block's primary textColor). */
.nisa-search-result .wp-block-post-title a {
	color: inherit;
}

/* Excerpt capped to three lines. */
.nisa-search-result__excerpt {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Stack image over text on small screens. */
@media (max-width: 600px) {
	.nisa-search-result {
		flex-direction: column;
	}

	.nisa-search-result__media {
		width: 100% !important;
	}
}

/* Pagination — navy numbers, the current page in a filled circle, arrow links.
   margin-inline (always allowed) spaces the dynamic page-number list. */
.nisa-search__pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.5rem;
	height: 2.5rem;
	margin-inline: 0.15rem;
	border-radius: 50%;
	color: var(--wp--preset--color--primary);
	font-weight: 600;
	text-decoration: none;
}

.nisa-search__pagination .page-numbers.current {
	background-color: var(--wp--preset--color--light-blue);
}

.nisa-search__pagination .wp-block-query-pagination-previous,
.nisa-search__pagination .wp-block-query-pagination-next {
	color: var(--wp--preset--color--primary);
	font-weight: 600;
	text-decoration: none;
}

/* Decorative dot field, selectable from the Group block's Styles panel rather
   than obtainable only by using a particular section class. Drawn here because
   a repeating radial-gradient has no theme.json equivalent; everything else
   about the group (background colour, padding, width) stays with the editor.
   The dots sit in a ::after layer behind the content, are pointer-inert, and
   fade out toward the left/bottom so they never compete with text. */
/* -----------------------------------------------
   Market Report — long-form monthly report template
   (patterns/market-report-*.php; Figma "Market and Report — Long form",
   node 127:7255). Hero = light-blue band, text left + network graphic right,
   scroll cue below; body reuses the .nisa-persp-single two-column layout.
   ----------------------------------------------- */

/* Hero network graphic — caps at its native size, centers in its column. */
.nisa-mr-hero__graphic {
	margin: 0;
}

.nisa-mr-hero__graphic img {
	display: block;
	width: 100%;
	max-width: 567px;
	height: auto;
	margin-inline: auto;
}

/* Scroll cue — a down-chevron inside a soft circle, centered under the hero
   (decorative; the anchor is an in-page jump to the report body). */
.nisa-mr-hero__scroll a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	border-radius: 50%;
	background-color: color-mix(in srgb, var(--wp--preset--color--gray) 12%, var(--wp--preset--color--muted));
	transition: transform 0.2s ease;
}

.nisa-mr-hero__scroll a::after {
	content: "";
	width: 20px;
	height: 20px;
	background-color: var(--wp--preset--color--primary);
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4v16'/%3E%3Cpath d='m6 14 6 6 6-6'/%3E%3C/svg%3E");
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4v16'/%3E%3Cpath d='m6 14 6 6 6-6'/%3E%3C/svg%3E");
	mask-size: contain;
	-webkit-mask-size: contain;
	mask-repeat: no-repeat;
	-webkit-mask-repeat: no-repeat;
	mask-position: center;
	-webkit-mask-position: center;
}

.nisa-mr-hero__scroll a:hover,
.nisa-mr-hero__scroll a:focus-visible {
	transform: translateY(3px);
}

@media (prefers-reduced-motion: reduce) {
	.nisa-mr-hero__scroll a {
		transition: none;
	}
}

/* On stacked mobile the graphic reads first visually if left large — cap it. */
@media (max-width: 781px) {
	.nisa-mr-hero__graphic img {
		max-width: 320px;
	}
}

/* ---- Report body: top row (month + intro), then sticky sidebar + content ---- */

/* Hairline divider under the hero, spanning the content width. */
.nisa-mr-divider.nisa-mr-divider {
	border-bottom-width: 1px;
	color: var(--wp--preset--color--light-blue);
	opacity: 1;
}

.nisa-mr-body__aside {
	position: sticky;
	top: calc(var(--nisa-header-h, 112px) + 1.5rem);
	align-self: start;
}

.nisa-mr-body__month {
	color: var(--wp--preset--color--primary);
}

/* Section headings anchor below the sticky header when reached via a TOC link. */
.nisa-mr-heading {
	color: var(--wp--preset--color--primary);
	scroll-margin-top: calc(var(--nisa-header-h, 112px) + 1.5rem);
	margin-top: 2.5rem; /* lint-allow: section rhythm above each report heading */
}

.nisa-mr-body__main > .nisa-mr-heading:first-child,
.nisa-mr-lead + .nisa-mr-heading {
	margin-top: 0;
}

/* ---- Auto Table of Contents ---- */
.nisa-mr-toc__label {
	margin: 0 0 0.75rem; /* lint-allow: label→list gap inside the custom TOC nav (not a block layout) */
	color: var(--wp--preset--color--label-blue);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 500;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.nisa-mr-toc__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
	border-left: 1px solid var(--wp--preset--color--lighter-blue);
}

.nisa-mr-toc__link {
	display: block;
	padding-left: 1rem;
	margin-left: -1px;
	border-left: 2px solid transparent;
	color: var(--wp--preset--color--primary);
	text-decoration: none;
	line-height: 1.35;
	transition: color 0.2s ease, border-color 0.2s ease;
}

.nisa-mr-toc__link:hover,
.nisa-mr-toc__link:focus-visible {
	color: var(--wp--preset--color--accent);
}

.nisa-mr-toc__link.is-active {
	color: var(--wp--preset--color--accent);
	font-weight: 600;
	border-left-color: var(--wp--preset--color--accent);
}

@media (prefers-reduced-motion: reduce) {
	.nisa-mr-toc__link {
		transition: none;
	}
}

/* ---- Markets data table ---- */
/* PRT Credit Risk Monitor chart (iframe of a Chart.js page, uploads/…/prt-
   timeseries-*.html). The chart keeps Chart.js's default 2:1 shape, but the
   iframe is a fixed 500px tall, so on phones the chart sat on ~320px of white
   (BugHerd #917). Size the frame to the chart instead: half the column width
   (the iframe spans the content column) + the chart page's 8px body margins,
   with 2px of rounding slack so no inner scrollbar appears. Phones only —
   desktop keeps 500px. */
@media (max-width: 781px) {
	iframe.nisa-prt-chart {
		height: calc((100vw - var(--wp--style--root--padding-left) - var(--wp--style--root--padding-right)) / 2 + 10px);
	}
}

.nisa-mr-table {
	margin: 0;
}

.nisa-mr-table table {
	border-collapse: collapse;
	width: 100%;
	font-size: var(--wp--preset--font-size--sm);
}

/* Horizontal hairlines only — drop the core table's default cell side borders. */
.nisa-mr-table th,
.nisa-mr-table td {
	border-left: 0;
	border-right: 0;
	border-top: 0;
}

.nisa-mr-table thead th {
	padding: 0 0 0.6rem;
	border-bottom: 2px solid var(--wp--preset--color--primary);
	color: var(--wp--preset--color--bright-blue);
	font-weight: 600;
	text-align: right;
	white-space: nowrap;
}

.nisa-mr-table tbody td {
	padding: 0.55rem 0;
	border-bottom: 1px dotted rgb(180, 180, 180);
	text-align: right;
	color: var(--wp--preset--color--primary);
	white-space: nowrap;
}

/* First column = row label, left-aligned and free to wrap. */
.nisa-mr-table thead th:first-child,
.nisa-mr-table tbody td:first-child {
	text-align: left;
	white-space: normal;
	padding-right: 1rem;
	width: 40%;
}

/* Heat-map variant (PRT "Average Issuer Spread ELB", BugHerd #1097): long
   multi-word headers wrap and sit on the baseline; numbers centre under them.
   The ELB colour scale is the editor's Highlight format (<mark>, inline
   background) so each cell's colour stays editable — stretched here to fill
   the cell like the source spreadsheet. */
.nisa-mr-table--heat thead th {
	white-space: normal;
	vertical-align: bottom;
	text-align: center;
}

.nisa-mr-table--heat tbody td {
	text-align: center;
}

.nisa-mr-table--heat thead th:first-child,
.nisa-mr-table--heat tbody td:first-child {
	width: 28%;
}

.nisa-mr-table--heat td mark {
	display: block;
	margin: -0.55rem 0; /* lint-allow: pulls the highlight to the cell edges (cell padding is 0.55rem) */
	padding: 0.55rem 0.5rem;
	color: var(--wp--preset--color--primary);
}

/* Banded variant (Derivatives Market Overview summary table, BugHerd #1096):
   a full-width section row splits the table and everything from that row down
   sits on a tint, plus the heavy grey rules top and bottom — matching the
   artwork this replaced. The band keys off the colspan cell rather than
   nth-child, so inserting a row above the split cannot shift it. No neutral
   grey in theme.json is close (muted is warm, wash is blue-tinted), hence the
   literal rgb() values. */
.nisa-mr-table--banded thead th {
	border-top: 3px solid rgb(118, 118, 118);
	padding-top: 0.6rem;
}

.nisa-mr-table--banded tbody tr:last-child td {
	border-bottom: 3px solid rgb(118, 118, 118);
}

.nisa-mr-table--banded tbody tr:has(td[colspan]),
.nisa-mr-table--banded tbody tr:has(td[colspan]) ~ tr {
	background: rgb(242, 242, 242);
}

.nisa-mr-table--banded tbody td[colspan] {
	font-weight: 700;
}

/* Split variant (Inflation Hedging pricing, BugHerd #1099): two narrow tables
   sit side by side, each carrying a blue group title row above its column
   headers. Differs from the base class in three ways measured off the source
   artwork — everything left-aligned (not right), solid hairlines (not the base's
   dotted rule + 2px header rule), and headers that wrap and sit on the baseline.
   The title colour is theme `accent`, which the artwork matches exactly. */
.nisa-mr-table--split thead th,
.nisa-mr-table--split tbody td {
	text-align: left;
	white-space: normal;
}

.nisa-mr-table--split thead th:first-child,
.nisa-mr-table--split tbody td:first-child {
	width: auto;
}

.nisa-mr-table--split thead th {
	color: var(--wp--preset--color--primary);
	vertical-align: bottom;
	border-bottom: 1px solid rgb(216, 223, 228);
	padding: 0.6rem 1rem 0.5rem 0;
}

/* First head row is the group title spanning the table. */
.nisa-mr-table--split thead tr:first-child th {
	color: var(--wp--preset--color--accent);
	font-weight: 700;
	border-top: 1px solid rgb(216, 223, 228);
}

.nisa-mr-table--split tbody td {
	border-bottom: 1px solid rgb(216, 223, 228);
	padding-right: 1rem;
}

/* Stack the pair on phones; WP already stacks the columns, this just closes the
   gap the second table would otherwise inherit from the row above it. */
@media (max-width: 781px) {
	.nisa-mr-split-tables {
		row-gap: 2rem;
	}
}

.nisa-mr-table figcaption {
	margin-top: 0.75rem; /* lint-allow: figcaption offset inside the table figure, no blockGap available */
	color: var(--wp--preset--color--gray);
	font-size: var(--wp--preset--font-size--xs);
	font-style: italic;
	text-align: left;
}

/* ---- Stacked layout: sidebar unpins, sits above content ---- */
@media (max-width: 781px) {
	.nisa-mr-body__aside {
		position: static;
	}
	.nisa-mr-table table {
		font-size: var(--wp--preset--font-size--xs);
	}
}

/* -----------------------------------------------
   Quarterly Market Webinar (patterns/quarterly-webinar.php)
   Video hero + synopsis + video grids. Reuses .nisa-video-card and the
   listen-tool (circled-play) button for "Watch the Full Discussion".
   ----------------------------------------------- */

/* Key-points list — bright-blue markers, comfortable rhythm. */
.nisa-webinar-points {
	margin: 0;
	padding-left: 1.15em;
}

.nisa-webinar-points li {
	margin-block: 0.4rem; /* lint-allow: list-item rhythm; core list has no per-item blockGap */
	line-height: 1.5;
	padding-left: 0.35em;
}

.nisa-webinar-points li::marker {
	color: var(--wp--preset--color--bright-blue);
}

/* Presenter chips sit in a row (the nisa/person chips own their own layout). */
.nisa-webinar-presenters {
	align-items: center;
}

/* Section top spacing, matching the comp's rhythm. (The hairline that used to
   open each of these sections is gone.) */
.nisa-webinar-more,
.nisa-webinar-videos {
	padding-top: clamp(2rem, 4vw, 3rem);
}

/* More Webinars is hidden on the Quarterly Market Webinar page (#19) for now;
   the markup stays in the pattern so it can be switched back on. */
.page-id-19 .nisa-webinar-more {
	display: none;
}

/* More Webinars item — carded, same hairline as the Other Videos grid below.
   The thumbnail bleeds to the card's edge, so the card clips it to the radius
   and only the copy column carries the inset. */
.nisa-webinar-more__card {
	border: 1px solid #e1e1e1;
	border-radius: 4px;
	overflow: hidden;
}

.nisa-webinar-more__card .nisa-video-card {
	border-radius: 0; /* the card above owns the corners now */
}

/* Copy column: its left gutter is the columns blockGap, so only the far side
   needs holding off the frame. */
.nisa-webinar-more__card > .wp-block-column:last-child {
	padding-right: clamp(1.5rem, 3vw, 2.5rem);
}

/* Stacked: the thumbnail spans the card's full width and the copy sits under
   it, so the inset has to come from all three open sides. */
@media (max-width: 781px) {
	.nisa-webinar-more__card > .wp-block-column:last-child {
		padding: 0 clamp(1.25rem, 5vw, 1.5rem) clamp(1.25rem, 5vw, 1.5rem);
	}
}

/* ---- Other Videos grid — Figma node 4537:14809 ----------------------------
   The comp draws each item as a bordered white card: thumbnail flush to the
   top edge, then a play disc + title row set well below it, with open space
   under the title. Each column IS the card (the thumbnail and the <h3> are
   siblings inside it), so the chrome lives on the column and the title owns
   the spacing. */
.nisa-webinar-videos__grid > .wp-block-column {
	display: flex;
	flex-direction: column;
	border: 1px solid #e1e1e1; /* same hairline as .nisa-fi-persp-card */
	border-radius: 4px;
	background-color: var(--wp--preset--color--secondary);
	overflow: hidden; /* clips the flush thumbnail's top corners to the radius */
}

/* Thumbnail: flush to the card edges (the column's radius does the clipping)
   and on the comp's 392x205 crop. */
.nisa-webinar-videos__grid .nisa-video-card {
	border-radius: 0;
}

.nisa-webinar-videos__grid .nisa-video-card__media img {
	aspect-ratio: 392 / 205;
}

/* No scrim and no disc ON the thumbnail here — the comp puts the play
   affordance beside the title instead. .nisa-video-card__play keeps its
   inset-0 hit area, so the whole thumbnail still opens the video. */
.nisa-webinar-videos__grid .nisa-video-card::before,
.nisa-webinar-videos__grid .nisa-video-card::after,
.nisa-webinar-videos__grid .nisa-video-card__play::after {
	display: none;
}

/* Title row: disc + title, indented from the card's left edge. The padding is
   the comp's own whitespace (79px above the row, 133px below it at the 1440
   artboard), which is also what levels the three cards to one height. */
.nisa-webinar-videos__title {
	display: flex;
	align-items: center;
	gap: 1rem;
	margin-top: 0;
	padding: clamp(2rem, 5.5vw, 4.9375rem) 1.25rem clamp(2.5rem, 9.2vw, 8.3125rem);
}

/* Play disc beside the title — outlined, unlike the filled disc on the video
   hero. Decorative: the thumbnail above is the control. */
.nisa-webinar-videos__title::before {
	content: '\25B6';
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 38px;
	height: 38px;
	border: 1px solid var(--wp--preset--color--accent);
	border-radius: 50%;
	color: var(--wp--preset--color--accent);
	font-family: var(--wp--preset--font-family--inter);
	font-size: 0.6875rem; /* lint-allow: icon glyph inside a pseudo-element, no editor control exists for pseudo content */
	padding-left: 0.15em; /* optical centering of the triangle glyph */
}

/* Two-tone (Figma 127:9385): white hero over a muted synopsis band, with the
   hero video overlapping the seam. The overlap is a stacked-layout effect no
   block attribute can express (allowed CSS category 4). Desktop only — the
   columns stack on mobile, so the video sits above the band with no overlap. */
.nisa-webinar-synopsis-band {
	position: relative;
}

@media (min-width: 782px) {
	.nisa-webinar-hero__video {
		position: relative;
		z-index: 1;
	}
	.nisa-webinar-synopsis-band {
		margin-top: -4rem; /* overlap: pull the muted band up beneath the video's lower edge — layout not expressible via blocks */
	}
}

/* Phones: the "Q4 2026 · 56 Min Watch" line carries an 8rem bottom margin
   (block attribute, sized for the side-by-side desktop hero). Stacked, it left
   ~150px of white above the video (BugHerd #921); the row gap alone spaces it.
   Inline style, so only !important overrides it; desktop keeps the attribute. */
@media (max-width: 781px) {
	.nisa-webinar__meta {
		margin-bottom: 0 !important; /* lint-allow: beats the block's inline margin on phones only */
	}
}

/* ---------------------------------------------------------------------------
   NDT Report page — nisa-theme/ndt-hero + nisa-theme/ndt-survey-intro
   Figma: NDT (node 4971:10104)
   --------------------------------------------------------------------------- */

/* The cover shrink-wraps its own box so the download disc can be anchored to
   the IMAGE's corner rather than to the (wider) column it sits in. */
.nisa-ndt-hero__cover {
	position: relative;
	z-index: 1; /* paint over the cream band below so the hanging disc isn't covered — all widths (BugHerd #923: on phones the band hid the disc's lower half) */
	width: -moz-fit-content;
	width: fit-content;
}

/* Same two-tone seam trick as .nisa-webinar-hero__video: the cover overhangs
   the white hero and lands on the cream intro band below. A cross-section
   overlap, so no block attribute can express it (allowed CSS category 4).
   Desktop only — under 782px the columns stack and the overhang is dropped.
   Scoped through the column and written as margin-block-END because WP's own
   layout rule (`:where(.wp-block-column.is-layout-flow) > :last-child`) sets
   `margin-block-end: 0` at equal specificity and loads later — a plain
   `.nisa-ndt-hero__cover { margin-bottom }` silently loses to it. */
@media (min-width: 782px) {
	.nisa-ndt-hero__mediacol > .nisa-ndt-hero__cover {
		margin-block-end: clamp(-6.375rem, -7.1vw, -3rem); /* abspos: negative optical overhang onto the band below, not sibling spacing */
	}
}

/* Download disc, pinned to the cover's lower-left corner and hanging outside it
   on both axes (Figma: -35px x, -44px y against a 365x472 cover).
   Scoped through the cover so the margin reset outranks WP's flow blockGap
   (`:where(.is-layout-flow) > *`), which otherwise pushes the disc down by a
   full gap even though it is out of flow.
   Mobile keeps the disc flush with the cover's left edge — the cover goes
   full-bleed there, so the designed outward hang would run off the viewport. */
.nisa-ndt-hero__cover > .nisa-ndt-hero__disc {
	position: absolute;
	left: 0;
	bottom: -1.5rem;
	margin: 0; /* abspos: zero reset, not sibling spacing */
}

/* "2024 Survey" label is right-aligned by its block setting, which reads as
   a label for the column beside it on desktop. Stacked on phones it should sit
   flush left with the copy (BugHerd #924). Two classes outrank core's
   .has-text-align-right without !important; desktop keeps the block setting. */
@media (max-width: 781px) {
	.nisa-ndt-intro__label.has-text-align-right {
		text-align: left;
	}
}

@media (min-width: 782px) {
	.nisa-ndt-hero__cover > .nisa-ndt-hero__disc {
		left: -9.6%;
		bottom: -9.3%;
	}
}

/* Circular icon-only button. The label stays in the DOM as the accessible name
   and is collapsed to zero, so the glyph is sized independently below. */
.is-style-nisa-disc-download .wp-block-button__link {
	position: relative;
	display: inline-block;
	width: clamp(3.25rem, 7.15vw, 6.4375rem);
	aspect-ratio: 1;
	padding: 0;
	border: none;
	border-radius: 50%;
	font-size: 0; /* lint-allow: collapses the label text so it survives as the accessible name only; the glyph is the separately sized ::before */
	line-height: 0;
	box-shadow: 0 4px 4px rgb(0 0 0 / 0.25);
	transition: background-color 0.25s ease;
}

/* Glyph inherits the mask from the shared tool-download rule above; only the
   geometry is disc-specific (em sizing is unusable at font-size:0). */
.is-style-nisa-disc-download .wp-block-button__link::before {
	position: absolute;
	inset: 0;
	margin: auto; /* abspos centering inside the disc */
	width: 42%;
	height: 42%;
}

.is-style-nisa-disc-download .wp-block-button__link:hover,
.is-style-nisa-disc-download .wp-block-button__link:focus-visible {
	background-color: var(--wp--preset--color--accent);
}

/* Serif edition label sits on the intro's first baseline rather than the top of
   its column, matching the comp's optical alignment with the lead paragraph. */
@media (min-width: 782px) {
	.nisa-ndt-intro__label {
		padding-top: 0.15em;
	}
}

/* ---------------------------------------------------------------------------
   Legal / long-form policy pages — nisa-theme/legal-page
   Privacy Policy #2843; also intended for Legal #262 and Cookies #263.
   Heading sizes, colours and link styling all come from theme.json; the reading
   measure comes from the group's contentSize. The only thing neither can reach
   is the UA's own <ul> block margin, which sits outside WP's blockGap and left
   a 44px gap below every list against the 20px rhythm everywhere else.
   --------------------------------------------------------------------------- */
.nisa-legal .wp-block-list {
	margin-block-end: 0; /* UA reset — blockGap owns the rhythm below the list */
}

/* CCPA disclosure tables (California Notice). Four columns of bulleted cells
   can't compress to the 860px reading measure, so the table scrolls inside its
   own figure rather than pushing the page sideways. Kept in a wp:html block
   because core/table cannot hold the <ul> lists these cells need. */
.nisa-legal__table {
	margin: 0;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.nisa-legal__table table {
	width: 100%;
	min-width: 46rem;
	border-collapse: collapse;
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.5;
}

.nisa-legal__table :is(td, th) {
	padding: 0.75rem;
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 15%, transparent);
	vertical-align: top;
	text-align: left;
}

.nisa-legal__table ul {
	margin: 0;
	padding-left: 1.1rem;
}

/* ---------------------------------------------------------------------------
   Data chart figure — reusable treatment for designer-exported SVG charts
   (eyebrow + title + subtitle, the chart itself, a source line, a collapsible
   data table, and the standard note). Charts arrive as standalone HTML pages
   whose <style> block targets bare `body`, `h1`, `table`, `th`, `td`, `details`
   and generic classes like `.wrap`/`.sub`/`.ax`; every one of those is
   re-expressed here under .nisa-chart so nothing leaks into the page, and the
   colours/fonts come from the theme tokens rather than the export's literals.
   The chart markup itself lives in a wp:html block (inline SVG + <details>
   table, which no core block can hold).
   --------------------------------------------------------------------------- */
.nisa-chart {
	max-width: 57.5rem; /* 920px — the width the exported chart's type is sized for */
	margin-inline: auto;
	color: var(--wp--preset--color--body);
	font-family: var(--wp--preset--font-family--inter);
}

.nisa-chart__eyebrow {
	margin: 0 0 0.375rem; /* lint-allow: type rhythm inside the chart's own wp:html markup — one block, so no blockGap or block-attr margin can reach these */
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

.nisa-chart__title {
	margin: 0 0 0.125rem; /* lint-allow: type rhythm inside the chart's own wp:html markup — one block, so no blockGap or block-attr margin can reach these */
	color: var(--wp--preset--color--primary);
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-weight: 400;
	line-height: 1.1;
}

.nisa-chart__sub {
	margin: 0 0 1.125rem; /* lint-allow: type rhythm inside the chart's own wp:html markup — one block, so no blockGap or block-attr margin can reach these */
	font-size: var(--wp--preset--font-size--md);
}

.nisa-chart__figure {
	margin: 0; /* UA reset — defeats browser <figure> margins */
}

/* Below ~46rem the exported type stops being legible (its labels are sized in
   viewBox units, so they shrink with the chart), so the plot scrolls sideways
   at a readable floor instead — same treatment as the CCPA tables. The caption
   sits outside this wrapper so it still wraps to the reading width. */
.nisa-chart__plot {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.nisa-chart__svg {
	display: block;
	width: 100%;
	min-width: 46rem;
	height: auto;
}

/* SVG text layers — the export styles these by class from inside the chart. */
.nisa-chart__ax {
	font-family: var(--wp--preset--font-family--inter);
	font-size: 16px; /* lint-allow: SVG user units, not CSS px — scales with the viewBox */
	fill: var(--wp--preset--color--body);
}

.nisa-chart__pill,
.nisa-chart__ctlab {
	font-family: var(--wp--preset--font-family--inter);
	font-size: 15px; /* lint-allow: SVG user units, not CSS px — scales with the viewBox */
	font-weight: 600;
}

.nisa-chart__pill {
	fill: var(--wp--preset--color--primary);
}

.nisa-chart__ctlab {
	fill: var(--wp--preset--color--accent);
}

.nisa-chart__source {
	margin-top: 0.375rem; /* lint-allow: caption offset inside the chart's own <figure>, no block boundary exists here */
	font-size: var(--wp--preset--font-size--xs);
}

.nisa-chart__source a {
	color: var(--wp--preset--color--accent);
}

.nisa-chart__details {
	margin-top: 1.25rem; /* lint-allow: gap inside the chart's own wp:html markup (source line -> disclosure), no block boundary exists here */
}

.nisa-chart__summary {
	padding: 0.5rem 0.25rem;
	border-radius: 4px;
	color: var(--wp--preset--color--primary);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	cursor: pointer;
}

.nisa-chart__summary:focus-visible {
	outline: 3px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* The table is the chart's text alternative (72 releases), so it scrolls in
   place instead of running the page long. */
.nisa-chart__tablescroll {
	max-height: 22.5rem;
	margin-top: 0.75rem; /* lint-allow: gap inside the chart's own wp:html markup (summary -> table), no block boundary exists here */
	overflow: auto;
	border: 1px solid var(--wp--preset--color--light-blue);
}

.nisa-chart__table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--wp--preset--font-size--xs);
}

.nisa-chart__table caption {
	padding: 0.375rem 0;
	color: var(--wp--preset--color--primary);
	font-weight: 600;
	text-align: left;
}

.nisa-chart__table :is(th, td) {
	padding: 0.3125rem 0.5625rem;
	border: 1px solid var(--wp--preset--color--light-blue);
}

.nisa-chart__table thead th {
	position: sticky;
	top: 0;
	background-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--secondary);
	text-align: left;
}

.nisa-chart__table tbody th {
	background-color: var(--wp--preset--color--muted);
	text-align: left;
	white-space: nowrap;
}

.nisa-chart__table td {
	text-align: right;
	font-variant-numeric: tabular-nums;
}

.nisa-chart__table tbody tr:nth-child(even) :is(td, th) {
	background-color: var(--wp--preset--color--pale-blue);
}

.nisa-chart__standard {
	margin-top: 1.625rem; /* lint-allow: gap inside the chart's own wp:html markup, co-located with the rule above it */
	padding-top: 0.75rem;
	border-top: 1px solid var(--wp--preset--color--light-blue);
	color: var(--wp--preset--color--gray);
	font-size: var(--wp--preset--font-size--xxs);
}

/* ---------------------------------------------------------------------------
   In Our Community (#21) — Figma node 4971:10598
   --------------------------------------------------------------------------- */

/* Trailing space under each support column. The shared bottom rule that used to
   live here is gone; only In Our Community draws one (below). */
.nisa-ins-resgrid > .wp-block-column {
	padding-bottom: 1.5rem;
}

/* White rules on this page only — the band sits on light-blue here, whereas the
   /insights/ resources band shares these classes over a near-white wash where
   a white rule would vanish. The comp rules the three columns at ONE shared
   baseline: per-column separator blocks each sit under their own text, and the
   three bodies are different lengths, so equal-height flex columns plus a
   bottom border are what land the rules on a single line. */
.page-id-21 .nisa-ins-resgrid > .wp-block-column {
	border-bottom: 1px solid var(--wp--preset--color--secondary);
}

/* Band whitespace: 171px above the heading at the 1440 artboard, and 106px
   below the rules (trimmed from the comp's 202px in design review), scaling
   down fluidly. Block axis only — has-global-padding owns the inline axis. */
.page-id-21 .nisa-ins-resources {
	padding-block: clamp(3.5rem, 11.9vw, 10.6875rem) clamp(4rem, 14vw, 6.625rem);
}

/* Charitable Fund lockup — sized to the comp's 152x64 slot; the asset is 412px
   wide so it stays crisp on hi-dpi. */
.nisa-belief__logo img {
	width: 9.5rem;
	height: auto;
}

/* Band + card geometry. Moved off the block attributes at the client's request
   (2026-08-21), so it is set HERE and no longer in the editor's Dimensions
   panel — change these values in this file. custom.css is also fed to the
   editor canvas via add_editor_style(), so the editor preview still matches. */
.nisa-belief-band {
	/* Block axis ONLY. The inline axis is owned by has-global-padding
	   (16px mobile -> 57.6px at 1440); setting padding here would clobber it. */
	padding-block: 0 var(--wp--preset--spacing--60);
}

.nisa-belief {
	padding-block: clamp(2.5rem, 4.2vw, 3.75rem);
	padding-inline: clamp(1.5rem, 5.3vw, 4.75rem) clamp(1.5rem, 4.4vw, 4rem);
	border-radius: 4px;
}

/* Phones: the "$7.6m donated" figure uses the `stat` preset, which floors at
   48px — it read smaller than the 152px Charitable Fund logo above it (BugHerd
   #956). Retarget the preset's variable to 5rem, the same phone size as the
   Our Firm section totals (#949), so the editor's Stat setting stays truthful. */
@media (max-width: 781px) {
	.nisa-belief__statcol .nisa-stat__value {
		--wp--preset--font-size--stat: 5rem;
	}
}

/* ==========================================================================
   Subscribe modal — native <dialog> carrying the embedded Subscribe Gravity
   Form (see inc/subscribe-modal.php + assets/js/subscribe-modal.js). Chrome
   CSS: styles the injected modal shell and overrides Gravity Forms' orbital
   theme within the dialog only (Contact form elsewhere is untouched). Figma:
   NISA Dev node 1-938.
   ========================================================================== */

/* Explicit fixed + translate centering — matches .nisa-video-dialog; survives
   WP/theme margin resets that would otherwise strip the UA margin:auto. */
dialog.nisa-subscribe-dialog {
	position: fixed;
	top: 50%;
	left: 50%;
	right: auto;
	bottom: auto;
	translate: -50% -50%;
	margin: 0;
	width: min(29rem, 92vw);
	max-height: 90vh;
	padding: 0;
	border: none;
	border-radius: 16px;
	background: var(--wp--preset--color--secondary);
	overflow: visible;
}

.nisa-subscribe-dialog::backdrop {
	background: rgba(1, 46, 82, 0.55);
}

.nisa-subscribe-dialog__panel {
	max-height: 90vh;
	overflow-y: auto;
	padding: clamp(1.5rem, 4vw, 2rem) clamp(1.25rem, 3.5vw, 1.75rem);
}

.nisa-subscribe-dialog__close {
	position: absolute;
	top: 0.85rem;
	right: 0.85rem;
	z-index: 2;
	display: grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	padding: 0;
	border: none;
	border-radius: 50%;
	background: transparent;
	color: var(--wp--preset--color--gray);
	cursor: pointer;
	transition: color 0.15s ease;
}

.nisa-subscribe-dialog__close svg {
	width: 0.9rem;
	height: 0.9rem;
}

.nisa-subscribe-dialog__close:hover {
	color: var(--wp--preset--color--primary);
}

/* Shared focus ring for every modal's bespoke controls (subscribe close, topic
   checkbox, submit button; terms-gate accept/decline) and the Contact form's
   checkboxes / consent link / Submit — the email input keeps
   its own tighter offset. One rule rather than per-modal copies: identical
   declaration bodies are a linter failure (C5). */
.nisa-terms-gate__accept:focus-visible,
.nisa-terms-gate__decline:focus-visible,
.nisa-subscribe-dialog__close:focus-visible,
.nisa-subscribe-dialog .nisa-subscribe-topics .gfield-choice-input:focus-visible,
.nisa-subscribe-dialog .gform_wrapper.gform-theme .gform_footer button.gform_button.button:focus-visible,
.nisa-subscribe-page .nisa-subscribe-topics .gfield-choice-input:focus-visible,
.nisa-subscribe-page .gform_wrapper.gform-theme .gform_footer button.gform_button.button:focus-visible,
.nisa-contact .gform_wrapper .gfield-choice-input[type="checkbox"]:focus-visible,
.nisa-contact .gform_wrapper .gfield_html a:focus-visible,
.nisa-contact .gform_wrapper .gform_footer button.gform_button.button:focus-visible {
	outline: 2px solid var(--wp--preset--color--bright-blue-2);
	outline-offset: 2px;
}

.nisa-subscribe-dialog__title {
	/* lint-allow: modal chrome spacing — injected shell, not block-editable */
	margin: 0 0 0.5rem;
	padding-right: 1.5rem;
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-size: var(--wp--preset--font-size--xl);
	font-weight: 400;
	line-height: 1.15;
	color: var(--wp--preset--color--primary);
}

.nisa-subscribe-dialog__desc {
	/* lint-allow: modal chrome spacing — injected shell, not block-editable */
	margin: 0 0 1.25rem;
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.5;
	color: var(--wp--preset--color--primary);
}

.nisa-subscribe-dialog__fineprint {
	/* lint-allow: modal chrome spacing — injected shell, not block-editable */
	margin: 0.85rem 0 0;
	font-size: var(--wp--preset--font-size--xs);
	line-height: 1.4;
	text-align: center;
	color: var(--wp--preset--color--gray);
}

/* --- Gravity Forms overrides, scoped to the dialog only --------------------- */

/* Rebind the orbital theme's brand tokens to NISA colors (fixes focus rings,
   error accents, etc. without per-rule overrides). */
.nisa-subscribe-dialog .gform-theme {
	--gf-color-primary: var(--wp--preset--color--accent);
	--gf-color-primary-contrast: var(--wp--preset--color--secondary);
	--gf-ctrl-border-color: var(--wp--preset--color--mist);
	--gf-ctrl-label-color-req: var(--wp--preset--color--primary);
	--gf-radius: 8px;
}

.nisa-subscribe-dialog .gform_wrapper {
	margin: 0;
}

/* Field spacing between GF fields (plugin output — no blockGap to own it). */
.nisa-subscribe-dialog .gform_wrapper .gfield {
	/* lint-allow: spacing between Gravity Forms fields (plugin markup) */
	margin-top: 0.5rem;
}

.nisa-subscribe-dialog .gform_wrapper .gform-body .gfield:first-child {
	margin-top: 0;
}

/* Topics legend stays AT-only — the intro copy above the form already says
   "Select the topics…" and every checkbox has its own visible label. */
.nisa-subscribe-dialog .nisa-subscribe-topics .gfield_label,
.nisa-subscribe-page .nisa-subscribe-topics .gfield_label {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	border: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
}

/* Email label is visible (WCAG 3.3.2 — the placeholder prompt vanished once
   typing started). Same type as the Contact form labels; colour per context:
   navy on the white modal, white on the navy /subscribe/ band. "(Required)"
   matches the label colour via GF's own --gf-ctrl-label-color-req token (its
   default red fails on navy) at regular weight. */
.nisa-subscribe-dialog .nisa-subscribe-email .gfield_label,
.nisa-subscribe-page .nisa-subscribe-email .gfield_label {
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 500;
	letter-spacing: 0.01em;
	color: var(--wp--preset--color--primary);
}

.nisa-subscribe-page .nisa-subscribe-email .gfield_label {
	--gf-ctrl-label-color-req: var(--wp--preset--color--secondary);
	color: var(--wp--preset--color--secondary);
}

.nisa-subscribe-dialog .nisa-subscribe-email .gfield_required,
.nisa-subscribe-page .nisa-subscribe-email .gfield_required {
	font-size: inherit;
	font-weight: 400;
}

/* Topic checkboxes rendered as bordered selectable boxes (one per row). */
.nisa-subscribe-dialog .nisa-subscribe-topics .gfield_checkbox,
.nisa-subscribe-page .gform_wrapper.gform-theme .nisa-subscribe-topics .gfield_checkbox {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

/* .gform_wrapper.gform-theme raises these above the orbital stylesheet's own
   (0,5,1) choice/label rules — otherwise GF's layout wins on load order and the
   checkbox-to-label gap collapses and its native appearance leaks back in. */
.nisa-subscribe-dialog .gform_wrapper.gform-theme .nisa-subscribe-topics .gchoice {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	margin: 0;
	padding: 0.7rem 0.9rem;
	border: 1px solid var(--wp--preset--color--mist);
	border-radius: 8px;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}

.nisa-subscribe-dialog .gform_wrapper.gform-theme .nisa-subscribe-topics .gchoice:has(.gfield-choice-input:checked) {
	border-color: var(--wp--preset--color--accent);
	background-color: var(--wp--preset--color--pale-blue);
}

.nisa-subscribe-dialog .gform_wrapper.gform-theme .nisa-subscribe-topics .gchoice label {
	flex: 1;
	margin: 0;
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.3;
	color: var(--wp--preset--color--accent);
	cursor: pointer;
}

/* Square control: empty white box unchecked, solid navy box checked — no check
   glyph. State is NOT color-alone: the native checkbox still announces
   checked/unchecked to assistive tech, and the whole row gains an accent border
   + pale-blue wash when selected, so sighted users get a second cue too. */
.nisa-subscribe-dialog .gform_wrapper.gform-theme .nisa-subscribe-topics .gfield-choice-input {
	flex: 0 0 auto;
	width: 1.15rem;
	height: 1.15rem;
	margin: 0;
	padding: 0;
	appearance: none;
	-webkit-appearance: none;
	border: 1.5px solid var(--wp--preset--color--accent);
	border-radius: 4px;
	background-color: var(--wp--preset--color--secondary);
	background-image: none;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

.nisa-subscribe-dialog .gform_wrapper.gform-theme .nisa-subscribe-topics .gfield-choice-input:checked {
	background-color: var(--wp--preset--color--accent);
}

/* Gravity Forms orbital paints its own checkmark as `content: var(--gf-icon-ctrl-checkbox)`
   on .gfield-choice-input::before (in GF's blue, not ours). The design wants a plain
   filled box with no glyph, so suppress the pseudo entirely — this (0,5,1) selector
   beats GF's ~(0,3,2) ::before rule without !important. */
.nisa-subscribe-dialog .gform_wrapper.gform-theme .nisa-subscribe-topics .gfield-choice-input::before,
.nisa-subscribe-dialog .gform_wrapper.gform-theme .nisa-subscribe-topics .gfield-choice-input::after {
	content: none;
}

/* Email input (.gform_wrapper lifts specificity over the orbital stylesheet). */
.nisa-subscribe-dialog .gform_wrapper .ginput_container_email input {
	width: 100%;
	min-height: 3.5rem;
	padding: 0.95rem 1rem;
	border: 1px solid var(--wp--preset--color--mist);
	border-radius: 8px;
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--primary);
	background-color: var(--wp--preset--color--secondary);
}

.nisa-subscribe-dialog .gform_wrapper .ginput_container_email input:focus-visible {
	outline: 2px solid var(--wp--preset--color--bright-blue-2);
	outline-offset: 1px;
	border-color: var(--wp--preset--color--accent);
}

/* Submit button — full-width navy */
.nisa-subscribe-dialog .gform_footer {
	/* lint-allow: spacing above the submit button (plugin footer markup) */
	margin: 1rem 0 0;
	padding: 0;
}

/* The orbital stylesheet's button rule resolves to specificity (0,5,1) and
   loads after custom.css, so an equal (0,5,1) selector loses the tie. Chaining
   .gform-theme onto the wrapper here makes this (0,6,1) — one class above
   orbital's cap — so the NISA button styling wins without !important. */
.nisa-subscribe-dialog .gform_wrapper.gform-theme .gform_footer button.gform_button.button {
	justify-content: center;
	width: 100%;
	margin: 0;
	padding: 0.95rem 1rem;
	border: none;
	border-radius: 999px;
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--secondary);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	letter-spacing: 0.01em;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

.nisa-subscribe-dialog .gform_wrapper.gform-theme .gform_footer button.gform_button.button:hover {
	background-color: var(--wp--preset--color--bright-blue);
}

/* Validation copy stays legible on white. */
.nisa-subscribe-dialog .gfield_validation_message,
.nisa-subscribe-dialog .validation_message {
	/* lint-allow: gap between a field and its own error text (plugin markup) */
	margin-top: 0.35rem;
	padding: 0;
	border: none;
	background: none;
	font-size: var(--wp--preset--font-size--xs);
	color: #b3261e;
}

/* Inline AJAX confirmation (post-submit thank-you). */
.nisa-subscribe-dialog .gform_confirmation_message {
	/* lint-allow: client-requested gap above the plugin's confirmation markup */
	margin-top: 30px;
	font-size: var(--wp--preset--font-size--md);
	line-height: 1.5;
	color: var(--wp--preset--color--primary);
}

/* Once the AJAX confirmation replaces the form, the intro copy no longer
   applies — the thank-you sits directly under the title. */
.nisa-subscribe-dialog__panel:has(.gform_confirmation_message) .nisa-subscribe-dialog__desc {
	display: none;
}

/* ==========================================================================
   Subscribe PAGE section (/subscribe/) — the canonical, linkable version of the
   subscribe modal, rendered on a dark-navy band via the subscribe-form-section
   pattern + [nisa_subscribe_form] shortcode. Same Gravity Form, dark palette.
   Structure mirrors the modal's GF overrides; colours are inverted for navy.
   ========================================================================== */

.nisa-subscribe-page {
	text-align: center;
}

.nisa-subscribe-page__title {
	line-height: 1.1;
}

.nisa-subscribe-page__desc {
	max-width: 34rem;
	margin-inline: auto;
	line-height: 1.5;
	color: var(--wp--preset--color--sky-blue);
}

.nisa-subscribe-page__fineprint {
	color: color-mix(in srgb, var(--wp--preset--color--secondary) 70%, transparent);
}

/* Constrain + left-align the form within the centred column. */
.nisa-subscribe-page .gform_wrapper {
	margin-inline: auto;
	text-align: left;
}

.nisa-subscribe-page .gform_wrapper .gfield {
	/* lint-allow: spacing between Gravity Forms fields (plugin markup) */
	margin-top: 0.75rem;
}

.nisa-subscribe-page .gform_wrapper .gform-body .gfield:first-child {
	margin-top: 0;
}

/* Topic rows as bordered boxes on navy — translucent white border, white label.
   (The .gfield_checkbox flex column is shared with the modal rule above.) */
.nisa-subscribe-page .gform_wrapper.gform-theme .nisa-subscribe-topics .gchoice {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	margin: 0;
	padding: 0.8rem 1rem;
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--secondary) 32%, transparent);
	border-radius: 8px;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}

.nisa-subscribe-page .gform_wrapper.gform-theme .nisa-subscribe-topics .gchoice:has(.gfield-choice-input:checked) {
	border-color: var(--wp--preset--color--bright-blue-2);
	background-color: color-mix(in srgb, var(--wp--preset--color--secondary) 8%, transparent);
}

.nisa-subscribe-page .gform_wrapper.gform-theme .nisa-subscribe-topics .gchoice label {
	flex: 1;
	margin: 0;
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.3;
	color: var(--wp--preset--color--secondary);
	cursor: pointer;
}

/* Square control: empty (light-bordered) unchecked, solid bright-blue checked,
   no glyph. State also carries via the row border/wash + native AT semantics. */
.nisa-subscribe-page .gform_wrapper.gform-theme .nisa-subscribe-topics .gfield-choice-input {
	flex: 0 0 auto;
	width: 1.15rem;
	height: 1.15rem;
	margin: 0;
	padding: 0;
	appearance: none;
	-webkit-appearance: none;
	border: 1.5px solid color-mix(in srgb, var(--wp--preset--color--secondary) 55%, transparent);
	border-radius: 4px;
	background-color: transparent;
	cursor: pointer;
	transition: background-color 0.15s ease, border-color 0.15s ease;
}

.nisa-subscribe-page .gform_wrapper.gform-theme .nisa-subscribe-topics .gfield-choice-input:checked {
	background-color: var(--wp--preset--color--bright-blue-2);
	border-color: var(--wp--preset--color--bright-blue-2);
}

/* Suppress Gravity Forms' own ::before checkmark glyph (see modal note). */
.nisa-subscribe-page .gform_wrapper.gform-theme .nisa-subscribe-topics .gfield-choice-input::before,
.nisa-subscribe-page .gform_wrapper.gform-theme .nisa-subscribe-topics .gfield-choice-input::after {
	content: none;
}

/* Email input — white fill on navy (matches the contact-form treatment). */
.nisa-subscribe-page .gform_wrapper .ginput_container_email input {
	width: 100%;
	min-height: 3.5rem;
	padding: 0.95rem 1rem;
	border: 1px solid transparent;
	border-radius: 8px;
	font-size: var(--wp--preset--font-size--sm);
	color: var(--wp--preset--color--primary);
	background-color: var(--wp--preset--color--secondary);
}

.nisa-subscribe-page .gform_wrapper .ginput_container_email input:focus-visible {
	outline: 2px solid var(--wp--preset--color--bright-blue-2);
	outline-offset: 2px;
	border-color: transparent;
}

/* Submit — white pill with navy text (high contrast on navy; a mid-blue fill
   would fail AA against white text). */
.nisa-subscribe-page .gform_footer {
	/* lint-allow: spacing above the submit button (plugin footer markup) */
	margin: 1.25rem 0 0;
	padding: 0;
}

.nisa-subscribe-page .gform_wrapper.gform-theme .gform_footer button.gform_button.button {
	justify-content: center;
	width: 100%;
	margin: 0;
	padding: 0.95rem 1rem;
	border: none;
	border-radius: 999px;
	background-color: var(--wp--preset--color--secondary);
	color: var(--wp--preset--color--primary);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	letter-spacing: 0.01em;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

.nisa-subscribe-page .gform_wrapper.gform-theme .gform_footer button.gform_button.button:hover {
	background-color: var(--wp--preset--color--wash);
}

/* Inline AJAX confirmation on the dark band. Set in the theme.json h3 style
   (serif, xl, 300) — styled, not an <h3>, so the outline doesn't skip h2 —
   and set off from the heading/intro by a hairline + space, so the thank-you
   reads as the new state rather than a third line of the same intro. */
.nisa-subscribe-page .gform_confirmation_message {
	/* lint-allow: spacing around the plugin's confirmation markup */
	margin-top: 1rem;
	padding-top: 2rem;
	border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--secondary) 25%, transparent);
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-size: var(--wp--preset--font-size--xl);
	font-weight: 300;
	line-height: 1.15;
	letter-spacing: 0.01em;
	color: var(--wp--preset--color--secondary);
	text-align: center;
}

/* ==========================================================================
   Terms gate — the "Agree to Terms" interstitial on Perspectives (see
   inc/terms-gate.php + assets/js/terms-gate.js). Rebuild of the legacy
   Elementor popup 6832. Chrome CSS: this shell is PHP-rendered, not block
   markup, so there are no editor panels behind these properties.

   No z-index anywhere below — a native <dialog> opened with showModal() sits
   in the browser top layer, already above the z-index:1000 fixed header.
   ========================================================================== */

/* Explicit fixed + translate centering — matches .nisa-subscribe-dialog;
   survives WP/theme margin resets that would otherwise strip UA margin:auto. */
dialog.nisa-terms-gate {
	position: fixed;
	top: 50%;
	left: 50%;
	right: auto;
	bottom: auto;
	translate: -50% -50%;
	margin: 0;
	width: min(40rem, 92vw);
	max-height: 90vh;
	padding: 0;
	border: none;
	border-radius: 16px;
	background: var(--wp--preset--color--secondary);
	overflow: hidden;
}

.nisa-terms-gate::backdrop {
	background: rgba(1, 46, 82, 0.55);
}

/* Long legal copy on a short viewport scrolls inside the panel rather than
   overflowing the dialog — the page behind it is scroll-locked. */
.nisa-terms-gate__panel {
	max-height: 90vh;
	overflow-y: auto;
	padding: clamp(1.75rem, 4vw, 2.5rem);
}

.nisa-terms-gate__title {
	/* lint-allow: modal chrome spacing — injected shell, not block-editable */
	margin: 0 0 1rem;
	font-family: var(--wp--preset--font-family--ivypresto-headline);
	font-size: var(--wp--preset--font-size--xl);
	font-weight: 400;
	line-height: 1.15;
	color: var(--wp--preset--color--primary);
}

.nisa-terms-gate__body p {
	/* lint-allow: modal chrome spacing — injected shell, not block-editable */
	margin: 0 0 1rem;
	font-size: var(--wp--preset--font-size--xs);
	line-height: 1.6;
	color: var(--wp--preset--color--primary);
}

.nisa-terms-gate__body p:last-child {
	margin-bottom: 0;
}

.nisa-terms-gate__body a {
	color: var(--wp--preset--color--accent);
	text-decoration: underline;
}

.nisa-terms-gate__body a:hover,
.nisa-terms-gate__body a:focus-visible {
	text-decoration: none;
}

/* Bespoke flex container — owns its own gap (no blockGap behind it). */
.nisa-terms-gate__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	/* lint-allow: modal chrome spacing — injected shell, not block-editable */
	margin-top: 1.75rem;
}

.nisa-terms-gate__accept,
.nisa-terms-gate__decline {
	flex: 1 1 10rem;
	padding: 0.875rem 1.5rem;
	border: none;
	border-radius: 50rem;
	font-family: var(--wp--preset--font-family--inter);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 500;
	line-height: 1.2;
	letter-spacing: 0.04em;
	text-align: center;
	text-decoration: none;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease;
}

.nisa-terms-gate__accept {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--secondary);
}

.nisa-terms-gate__accept:hover {
	background: var(--wp--preset--color--bright-blue-2);
}

.nisa-terms-gate__decline {
	background: var(--wp--preset--color--mist);
	color: var(--wp--preset--color--primary);
}

.nisa-terms-gate__decline:hover {
	background: var(--wp--preset--color--wash);
}
