/**
 * Structural styles: focus, skip link, tap targets.
 *
 * Motion belongs in animation.css. Nothing here animates, so nothing here
 * needs a reduced-motion guard — and keeping the two files separate is what
 * makes that guard auditable.
 */

/* ---------------------------------------------------------------------------
   Mobile text-size adjustment
   --------------------------------------------------------------------------- */

/*
 * Root cause of the 375px horizontal-overflow bug: real mobile Chrome and
 * Safari run a "font boosting" / text-autosizing heuristic that inflates the
 * computed font-size of text blocks it judges to be paragraph-like on narrow
 * viewports, independent of any width set in this stylesheet. It is a
 * rendering-time behaviour on the device itself, not something any element
 * here declares — which is exactly why walking the DOM for an element whose
 * layout box is wider than the viewport (the technique used to investigate
 * this bug) finds nothing: nothing IS wider until boosting inflates the text
 * inside it past its fixed-width container at paint time, and desktop/
 * headless Chrome driven through the DevTools protocol never triggers that
 * heuristic even with mobile + touch emulation and a realistic device pixel
 * ratio, which is why this could not be reproduced with any of those tools
 * here. It explains every observed detail: unrelated text blocks (hero,
 * body copy, the donate heading, the button label) clip at the same right
 * edge because the same global multiplier is applied to all of them, it
 * disappears once a viewport is wide enough that the heuristic no longer
 * considers the text column narrow, and the header survives because "elpis"
 * is a single short word, never flagged as a paragraph-like cluster to
 * boost.
 *
 * This turns the behaviour off rather than papering over its symptom with
 * `overflow-x: hidden`, which would keep the boosted (and now-too-wide) text
 * on the page, just silently clipped with no way to reach the hidden part.
 */
html {
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
}

/* ---------------------------------------------------------------------------
   Focus
   --------------------------------------------------------------------------- */

/*
 * One rule, everything focusable. :focus-visible is the modern behaviour;
 * the :focus fallback below catches browsers without it.
 *
 * No focus outline is ever suppressed in this codebase. CLAUDE.md:108-109.
 */
:where( a, button, input, select, textarea, summary, [tabindex] ):focus-visible {
	outline: var( --wp--custom--focus--width ) solid var( --wp--preset--color--primary-deep );
	outline-offset: var( --wp--custom--focus--offset );
	/* Cosmetic geometry on the outline itself, not a spacing value. Literal. */
	border-radius: 2px;
}

@supports not selector( :focus-visible ) {
	:where( a, button, input, select, textarea, summary, [tabindex] ):focus {
		outline: var( --wp--custom--focus--width ) solid var( --wp--preset--color--primary-deep );
		outline-offset: var( --wp--custom--focus--offset );
	}
}

/*
 * On teal surfaces the deep teal ring disappears. Invert it there.
 * teal-deep is the utility bar's background (CLAUDE.md's revised visual
 * direction) -- same problem as primary, so it gets the same fix.
 */
.has-primary-background-color :where( a, button ):focus-visible,
.has-teal-deep-background-color :where( a, button ):focus-visible {
	outline-color: var( --wp--preset--color--base );
}

/*
 * The hero's photo/scrim background is dark enough that the default
 * primary-deep ring all but disappears on it — measured at 1.2:1 to 1.4:1
 * against the composited scrim, nowhere near the 3:1 a focus indicator needs.
 * Scoped to .elpis-hero-content specifically, not the whole .elpis-hero
 * section: the ETAP card (.elpis-hero-card) sits on its own white surface as
 * a sibling of .elpis-hero-content, where an inverted white ring would
 * itself disappear.
 */
.elpis-hero-content :where( a, button ):focus-visible {
	outline-color: var( --wp--preset--color--base );
}

/* ---------------------------------------------------------------------------
   Skip link
   --------------------------------------------------------------------------- */

.elpis-skip-link {
	position: absolute;
	top: var( --wp--custom--skip-link--offset );
	left: var( --wp--preset--spacing--30 );
	z-index: 99;
	padding: var( --wp--preset--spacing--30 ) var( --wp--preset--spacing--40 );
	background-color: var( --wp--preset--color--base );
	color: var( --wp--preset--color--primary-deep );
	font-family: var( --wp--preset--font-family--body );
	font-size: var( --wp--preset--font-size--small );
	font-weight: 700;
	text-decoration: underline;
}

.elpis-skip-link:focus {
	top: var( --wp--preset--spacing--30 );
}

/* ---------------------------------------------------------------------------
   Tap targets
   --------------------------------------------------------------------------- */

/*
 * 44x44 minimum. CLAUDE.md:113 — many users are parents on phones, one-handed.
 * Buttons already clear this via theme.json padding; navigation does not.
 *
 * Left as a literal, not a token: this is the WCAG 2.2 target-size minimum, a
 * standard rather than a house design choice. Tokenizing it would obscure
 * where the number comes from.
 */
.wp-block-navigation .wp-block-navigation-item__content,
.wp-block-navigation-link a,
.wp-block-social-link a {
	display: flex;
	align-items: center;
	min-height: 44px;
	min-width: 44px;
	padding-inline: var( --wp--preset--spacing--20 );
}

/*
 * The overlay-menu hamburger and its close button are icon-only buttons.
 * WP core's navigation/style.css (`.wp-block-navigation__responsive-container-open,
 * -close`) sets no padding and no width/height, so they render at exactly
 * their SVG's intrinsic 24x24 size — well under the minimum above. Centre
 * the icon in a properly sized box rather than reusing the inline-padding
 * approach above, which assumes text content.
 */
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	min-width: 44px;
}

/*
 * The header's primary nav (parts/header.html, className elpis-primary-nav)
 * needs every spare pixel to keep eight items on one line beside the logo
 * and button at 1280 -- see the header rebuild brief. Tightening padding-inline
 * only reduces the breathing room beyond each label; min-height/min-width:44px
 * above still apply unchanged, so the tap target floor is untouched.
 */
.elpis-primary-nav .wp-block-navigation-item__content {
	padding-inline: var( --wp--preset--spacing--10 );
}

/* ---------------------------------------------------------------------------
   Logo emblem, wordmark, and the gold arc
   --------------------------------------------------------------------------- */

/*
 * The header now uses the full 3D emblem (logo-emblem.png), not the flat
 * logo-mark.svg dove -- the client's approved comp uses the emblem, and
 * CLAUDE.md's header rebuild brief is explicit that the flat mark is no
 * longer the header's logo. logo-mark.svg itself is left in place (nothing
 * else in the theme references it removing it is out of scope here).
 */
.elpis-logo-link {
	display: flex;
	align-items: center;
	gap: var( --wp--preset--spacing--20 );
	min-height: 44px;
	color: inherit;
	text-decoration: none;
}

/* Sizing only, same reasoning as the old .elpis-logo-mark rule: an
   <img>-referenced PNG cannot read anything declared here. Taller than the
   old 44px flat mark on purpose -- the emblem's circular badge needs more
   room to read clearly than the flat dove did, and 56px still comfortably
   clears the 44px tap-target minimum. */
.elpis-logo-emblem {
	display: block;
	width: auto;
	height: 56px;
	flex: 0 0 auto;
}

.elpis-wordmark {
	display: flex;
	flex-direction: column;
	line-height: 1.15;
}

.elpis-wordmark-primary {
	font-family: var( --wp--preset--font-family--heading );
	font-size: var( --wp--preset--font-size--large );
	font-weight: 600;
	letter-spacing: -0.01em;
	color: var( --wp--preset--color--primary-deep );
}

.elpis-wordmark-secondary {
	font-family: var( --wp--preset--font-family--body );
	font-size: var( --wp--preset--font-size--x-small );
	font-weight: 700;
	letter-spacing: 0.08em;
	color: var( --wp--preset--color--muted );
}

/*
 * The gold arc: the one memorable device, echoing the emblem's rim.
 * One per screen, maximum. CLAUDE.md:85-90.
 *
 * As a separator it replaces the default rule entirely.
 */
.wp-block-separator.is-style-elpis-arc {
	border: 0;
	height: auto;
	max-width: var( --wp--custom--arc--max-width );
	width: 100%;
	margin-inline: auto;
	color: var( --wp--preset--color--accent );
	opacity: 1;
}

.wp-block-separator.is-style-elpis-arc svg {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}

/*
 * The active nav item takes the same gesture, stretched to the item width.
 * Positioned rather than inline so it sits under the label without becoming
 * a flex sibling of the link text.
 */
.wp-block-navigation-item.current-menu-item {
	position: relative;
}

.elpis-nav-arc {
	position: absolute;
	left: var( --wp--preset--spacing--20 );
	right: var( --wp--preset--spacing--20 );
	bottom: var( --wp--custom--arc--underline-offset );
	height: var( --wp--custom--arc--underline-height );
	color: var( --wp--preset--color--accent );
	pointer-events: none;
}

.elpis-nav-arc svg {
	display: block;
	width: 100%;
	height: 100%;
}

/* ---------------------------------------------------------------------------
   Measure
   --------------------------------------------------------------------------- */

/*
 * CLAUDE.md:83 caps the measure at 68 characters. contentSize is 720px for
 * that reason, but long words in headings can still overrun on narrow screens.
 */
h1, h2, h3, h4 {
	overflow-wrap: break-word;
}

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

/*
 * Rebuilt photographic, per the client's approved comp
 * (client-references/homepage-reference.jpg — see "Visual direction —
 * revised" in CLAUDE.md). Previously a flat primary-tint band; now a
 * full-bleed media layer plus a mandatory scrim, with the content and the
 * floating ETAP card sitting above both. Mobile-first padding/min-height
 * survive unchanged from the earlier build — only the background and the
 * content layout changed.
 */
.elpis-hero {
	position: relative;
	overflow: hidden;
	display: flex;
	align-items: center;
	padding-top: var( --wp--preset--spacing--50 );
	padding-bottom: var( --wp--preset--spacing--50 );
}

@media (min-width: 600px) {
	.elpis-hero {
		padding-top: var( --wp--preset--spacing--70 );
		padding-bottom: var( --wp--preset--spacing--70 );
		min-height: var( --wp--custom--hero--min-height );
	}
}

/*
 * The photograph layer. No stock photography of children ships here
 * (CLAUDE.md) — this gradient of two already-dark tokens is the marked
 * placeholder. Both ends are pre-validated in CLAUDE.md's contrast table
 * (10.34:1 and 8.14:1 for white text), so even before the scrim below is
 * added, white text over either end already clears both thresholds this
 * hero needs to hit; the scrim exists for when a real, possibly much
 * brighter, photograph replaces it.
 */
.elpis-hero-media {
	position: absolute;
	inset: 0;
	z-index: 0;
	/* Defeats the constrained layout's child cap -- see patterns/hero.php's
	   comment on why "alignfull" is the wrong tool here. */
	max-width: none;
	margin: 0;
	background: linear-gradient(
		135deg,
		var( --wp--preset--color--teal-deep ),
		var( --wp--preset--color--teal-mid )
	);
}

.elpis-hero-photo {
	display: block;
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/*
 * The mandatory scrim. teal-deep at 55% opacity over the gradient above.
 * Measured against the gradient's lightest corner (teal-mid, the worst
 * case), the composite is rgb(0,79,87); white text on that measures 9.31:1 —
 * clears the tagline's 3:1 and the supporting line's 4.5:1 with real margin,
 * not by the hair's-breadth CLAUDE.md warns against elsewhere (its `primary`
 * text-contrast note). Deepen this opacity if a future real photograph
 * measures lighter than the placeholder does.
 */
.elpis-hero-scrim {
	position: absolute;
	inset: 0;
	z-index: 1;
	max-width: none;
	margin: 0;
	background-color: var( --wp--preset--color--teal-deep );
	opacity: 0.55;
}

/*
 * Content and the ETAP card share one flex row, wrapping to stack the card
 * below the content on narrow screens per the brief — no separate mobile
 * layout is needed beyond the max-width removal in the card's own
 * small-screen rule further down.
 */
.elpis-hero-inner {
	position: relative;
	z-index: 2;
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	justify-content: space-between;
	gap: var( --wp--preset--spacing--60 );
	width: 100%;
	max-width: var( --wp--style--global--wide-size );
	margin-inline: auto;
}

.elpis-hero-content {
	flex: 1 1 420px;
	/* Caps the measure at contentSize (720px), same 68-character reasoning
	   CLAUDE.md applies everywhere else — a hero is not exempt. */
	max-width: var( --wp--style--global--content-size );
}

/* ---------------------------------------------------------------------------
   The h1/tagline resolution
   --------------------------------------------------------------------------- */

/*
 * The h1 stays the accessible, plain-language heading (see the long comment
 * in patterns/hero.php) but is styled as a quiet uppercase kicker line so the
 * tagline lockup beneath it — not this — reads as the dominant element,
 * matching the comp.
 */
.elpis-hero-eyebrow {
	font-family: var( --wp--preset--font-family--body );
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	opacity: 0.85;
}

/*
 * The tagline lockup: a sky heart, the tagline, an amber puzzle piece, as one
 * fixed unit — now the hero's visually dominant element, styled at display
 * size to carry that weight (previously a small italic line for the earlier
 * light-background hero). Both marks stay aria-hidden in the markup
 * (patterns/hero.php); the tagline text is what a screen reader announces.
 *
 * Deliberately NOT flex. flex-wrap line-breaking decides whether an item fits
 * on the current line using that item's un-shrunk hypothetical (max-content)
 * width, not its post-shrink rendered width. The tagline text's hypothetical
 * width (one line, no wrap, at display size) is far wider than the hero
 * column, so under flex it never "fit" beside either icon and always landed
 * on its own line — heart alone on line one, the (now internally-wrapped)
 * text alone on line two, puzzle alone on line three. Plain inline flow does
 * not have this problem: SVG is an inline-replaced element by default, so it
 * sits in the text run exactly like an inline image and wraps with the words
 * around it, which is also exactly the comp's "heart leads the first line,
 * puzzle follows the last word" reading, including at 375px where the
 * tagline text itself wraps to two lines.
 */
.elpis-tagline-lockup {
	margin-top: var( --wp--preset--spacing--20 );
	font-family: var( --wp--preset--font-family--heading );
	font-weight: 600;
	font-size: var( --wp--preset--font-size--display );
	line-height: 1.1;
	letter-spacing: -0.01em;
	color: var( --wp--preset--color--base );
}

.elpis-tagline-lockup svg {
	width: var( --wp--preset--spacing--50 );
	height: var( --wp--preset--spacing--50 );
	vertical-align: -0.1em;
}

/*
 * sky and amber are brand marks, never UI colour (CLAUDE.md:96-100) — this is
 * the one place either is drawn, and each mark's colour lives only here.
 * The margins here are the lockup's only spacing between mark and text now
 * that inline flow has replaced the flex gap above.
 */
.elpis-icon-heart {
	color: var( --wp--preset--color--sky );
	margin-right: var( --wp--preset--spacing--20 );
}

.elpis-icon-puzzle {
	color: var( --wp--preset--color--amber );
	margin-left: var( --wp--preset--spacing--20 );
}

/* ---------------------------------------------------------------------------
   Hero ETAP card
   --------------------------------------------------------------------------- */

/*
 * The "Need therapy assistance?" card floats beside the hero content on wide
 * screens and stacks full-width below it on narrow ones (patterns/hero.php).
 * It sits on its own white surface, not on the photo/scrim, so its internal
 * text is checked against white, not the hero's dark background.
 */
.elpis-hero-card {
	flex: 0 1 var( --wp--custom--hero--card-width );
	width: 100%;
	max-width: var( --wp--custom--hero--card-width );
	background-color: var( --wp--preset--color--base );
	border-radius: 4px;
	box-shadow: var( --wp--preset--shadow--lift );
	overflow: hidden;
}

@media ( max-width: 699px ) {
	.elpis-hero-card {
		flex-basis: 100%;
		max-width: none;
	}
}

.elpis-hero-card-head {
	background-color: var( --wp--preset--color--teal-deep );
	padding: var( --wp--preset--spacing--30 ) var( --wp--preset--spacing--40 );
}

.elpis-hero-card-head h2 {
	margin: 0;
}

.elpis-hero-card-body {
	padding: var( --wp--preset--spacing--40 );
	color: var( --wp--preset--color--contrast );
}

.elpis-hero-card-list {
	list-style: none;
	margin: var( --wp--preset--spacing--30 ) 0 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var( --wp--preset--spacing--20 );
}

.elpis-hero-card-list li {
	display: flex;
	align-items: center;
	gap: var( --wp--preset--spacing--20 );
	font-size: var( --wp--preset--font-size--small );
}

.elpis-hero-card-list svg {
	flex: 0 0 auto;
	width: var( --wp--preset--spacing--30 );
	height: var( --wp--preset--spacing--30 );
	color: var( --wp--preset--color--primary-deep );
}

/*
 * A hand-built button rather than a real wp:button — this whole card is one
 * wp:html widget (see patterns/hero.php's comment on that choice) — styled to
 * the same radius/weight/tap-target conventions the rest of the theme's real
 * buttons use.
 */
.elpis-hero-card-apply {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var( --wp--preset--spacing--20 );
	min-height: 44px;
	margin-top: var( --wp--preset--spacing--40 );
	padding: 0.9rem 1.75rem;
	border-radius: 4px;
	background-color: var( --wp--preset--color--teal-deep );
	color: var( --wp--preset--color--base );
	font-family: var( --wp--preset--font-family--body );
	font-size: var( --wp--preset--font-size--small );
	font-weight: 700;
	text-decoration: none;
}

.elpis-hero-card-apply:hover,
.elpis-hero-card-apply:focus {
	background-color: var( --wp--preset--color--primary-deep );
	color: var( --wp--preset--color--base );
}

.elpis-hero-card-apply svg {
	flex: 0 0 auto;
	width: var( --wp--preset--spacing--30 );
	height: var( --wp--preset--spacing--30 );
}

/* ---------------------------------------------------------------------------
   ETAP path
   --------------------------------------------------------------------------- */

/*
 * patterns/etap-path.php: a numbered walk from "what ETAP is" to "apply".
 * The number is plain text, not a pseudo-element, so it is announced by a
 * screen reader as real sequence information rather than hidden decoration.
 */
.elpis-etap-steps {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var( --wp--preset--spacing--50 );
	margin-top: var( --wp--preset--spacing--50 );
}

.elpis-etap-step {
	display: flex;
	align-items: flex-start;
	gap: var( --wp--preset--spacing--40 );
}

.elpis-etap-num {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: var( --wp--preset--spacing--50 );
	height: var( --wp--preset--spacing--50 );
	border-radius: 50%;
	background-color: var( --wp--preset--color--primary-tint );
	color: var( --wp--preset--color--primary-deep );
	font-family: var( --wp--preset--font-family--heading );
	font-size: var( --wp--preset--font-size--large );
	font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Trust signals stat row
   --------------------------------------------------------------------------- */

/*
 * patterns/trust-signals.php. A definition list is the correct element for
 * a set of figure/label pairs — dt holds the count, dd holds what it counts.
 */
.elpis-stat-row {
	display: flex;
	flex-wrap: wrap;
	gap: var( --wp--preset--spacing--50 );
	margin: var( --wp--preset--spacing--50 ) 0 0;
}

.elpis-stat dt {
	font-family: var( --wp--preset--font-family--heading );
	font-size: var( --wp--preset--font-size--xx-large );
	font-weight: 600;
	color: var( --wp--preset--color--primary-deep );
}

.elpis-stat dd {
	margin: 0;
	font-size: var( --wp--preset--font-size--small );
	color: var( --wp--preset--color--muted );
}

/* ---------------------------------------------------------------------------
   Utility bar
   --------------------------------------------------------------------------- */

/*
 * parts/header.html. Every link here is small in the comp -- exactly why
 * CLAUDE.md's 44px tap-target rule matters most here, per the header rebuild
 * brief. Same technique as the nav tap targets above: a flex box tall enough
 * to hit the minimum, centred around the visually small label.
 *
 * color is set explicitly rather than left to inherit: these are raw <a>
 * tags (wp:html, not a block WordPress themes it), and theme.json's global
 * `link` element style targets the bare `a` selector, which beats inherited
 * colour from the ancestor group's has-base-color. A class selector already
 * out-specifies a bare element selector, so no !important is needed here --
 * but :hover/:focus need their own rule below because `a:hover`/`a:focus`
 * (element + pseudo-class) would otherwise still out-specify a plain class.
 */
.elpis-utility-link {
	display: inline-flex;
	align-items: center;
	gap: var( --wp--preset--spacing--20 );
	min-height: 44px;
	padding-inline: var( --wp--preset--spacing--20 );
	color: var( --wp--preset--color--base );
	text-decoration: none;
	font-size: var( --wp--preset--font-size--x-small );
}

.elpis-utility-link:hover,
.elpis-utility-link:focus {
	color: var( --wp--preset--color--base );
	text-decoration: underline;
}

.elpis-utility-link svg {
	width: 16px;
	height: 16px;
	flex: 0 0 auto;
}

.elpis-utility-divider {
	color: var( --wp--preset--color--base );
	opacity: 0.6;
}

/*
 * SEC number and non-profit status collapse below 600px (the same
 * mobile/wider line base.css already draws for the hero) rather than
 * wrapping onto the utility bar's own crowded row or forcing the bar to
 * overflow. The contact details beside this block -- the ones a parent on a
 * phone will actually tap -- stay, and are left free to wrap onto their own
 * lines instead: CLAUDE.md ranks "let a parent find out ... and how to ask"
 * above the SEC/non-profit trust signal, and both survive elsewhere anyway
 * (the footer already carries the SEC number).
 */
/*
 * "body" in the selector is load-bearing, not decorative: this group also
 * carries core's own `.is-layout-flex`, and global-styles-inline-css defines
 * `body .is-layout-flex{display:flex}` -- one class plus one element, which
 * out-specifies a plain `.elpis-utility-secondary{display:none}` regardless
 * of source order. Matching that same shape (element + class) ties the
 * specificity instead, and this rule wins the tie because base.css is
 * enqueued after global-styles-inline-css.
 */
body .elpis-utility-secondary {
	display: none;
}

@media ( min-width: 600px ) {
	body .elpis-utility-secondary {
		display: flex;
	}
}

/* ---------------------------------------------------------------------------
   Header CTA button
   --------------------------------------------------------------------------- */

/*
 * CLAUDE.md's gold button rule: ink text on gold-cta, never white -- white
 * measures 2.73:1 on gold-cta and fails AA, ink measures 7.55:1. The block's
 * own backgroundColor/textColor attributes already render this correctly at
 * rest, but theme.json's global button element also defines its own
 * :hover/:focus colours (primary-deep background, base text) at the same
 * selector weight core gives its colour-attribute classes, and relying on
 * that implementation detail to keep resolving in this button's favour is
 * exactly the kind of thing that quietly breaks on a core update. Pinning
 * all three states here explicitly makes the contrast guarantee independently
 * verifiable rather than incidental.
 */
.elpis-cta-gold .wp-block-button__link,
.elpis-cta-gold .wp-block-button__link:hover,
.elpis-cta-gold .wp-block-button__link:focus {
	background-color: var( --wp--preset--color--gold-cta );
	color: var( --wp--preset--color--contrast );
}

/* ---------------------------------------------------------------------------
   "How can we help you today?" card row
   --------------------------------------------------------------------------- */

/*
 * patterns/help-cards.php. Four routes, one card each, on the shell band.
 * Four columns down to one as the viewport narrows -- no separate stacked
 * layout is needed beyond the grid-template-columns changes below.
 */
.elpis-help-cards {
	display: grid;
	grid-template-columns: repeat( 4, 1fr );
	gap: var( --wp--preset--spacing--40 );
	margin-top: var( --wp--preset--spacing--50 );
}

@media ( max-width: 900px ) {
	.elpis-help-cards {
		grid-template-columns: repeat( 2, 1fr );
	}
}

@media ( max-width: 560px ) {
	.elpis-help-cards {
		grid-template-columns: 1fr;
	}
}

.elpis-help-card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	/* Grid stretches every card to the row's tallest height; copy length
	   varies card to card (some headings wrap, some don't), so pin the
	   arrow-link to the bottom of that shared height rather than letting it
	   drift to wherever its own card's text happens to end. */
	height: 100%;
	background-color: var( --wp--preset--color--base );
	border-radius: 4px;
	box-shadow: var( --wp--preset--shadow--lift );
	padding: var( --wp--preset--spacing--40 );
}

.elpis-help-card h3 {
	margin: var( --wp--preset--spacing--30 ) 0 0;
}

.elpis-help-card p {
	margin: var( --wp--preset--spacing--20 ) 0 0;
	color: var( --wp--preset--color--muted );
}

/*
 * The icon circle carries each route's colour; the heading text does not
 * (see patterns/help-cards.php's comment -- coral, leaf, and gold-cta all
 * fail the 4.5:1 text threshold). A circle-plus-white-glyph is a graphic,
 * needing only 3:1, which every one of these four fills clears.
 */
.elpis-help-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: var( --wp--preset--spacing--60 );
	height: var( --wp--preset--spacing--60 );
	border-radius: 50%;
	color: var( --wp--preset--color--base );
}

.elpis-help-icon svg {
	width: var( --wp--preset--spacing--30 );
	height: var( --wp--preset--spacing--30 );
}

.elpis-help-icon--teal-mid {
	background-color: var( --wp--preset--color--teal-mid );
}

.elpis-help-icon--gold-cta {
	background-color: var( --wp--preset--color--gold-cta );
}

.elpis-help-icon--leaf {
	background-color: var( --wp--preset--color--leaf );
}

.elpis-help-icon--coral {
	background-color: var( --wp--preset--color--coral );
}

/*
 * The arrow link at the foot of each card. Plain primary-deep, same as any
 * other link (theme.json's global link element already sets this colour) --
 * styled here only to line up the arrow glyph and to remove the underline
 * theme.json's link element otherwise adds, matching the comp's plain-text
 * link treatment.
 */
.elpis-help-card-link {
	display: inline-flex;
	align-items: center;
	gap: var( --wp--preset--spacing--20 );
	margin-top: auto;
	padding-top: var( --wp--preset--spacing--30 );
	min-height: 44px;
	font-weight: 700;
	text-decoration: none;
}

.elpis-help-card-link:hover,
.elpis-help-card-link:focus {
	text-decoration: underline;
}

.elpis-help-card-link svg {
	flex: 0 0 auto;
	width: var( --wp--preset--spacing--30 );
	height: var( --wp--preset--spacing--30 );
}

/* ---------------------------------------------------------------------------
   Split layout: a query/grid on the left, a side panel on the right
   --------------------------------------------------------------------------- */

/*
 * Shared by patterns/news-get-involved.php ("Recent news and stories" beside
 * "Get involved") and patterns/upcoming-events.php ("Upcoming events" beside
 * "Stay connected") -- one grid definition rather than two near-identical
 * ones, since both sections are the same "content column plus one panel"
 * shape from the approved comp.
 */
.elpis-split-layout {
	display: grid;
	grid-template-columns: 2fr 1fr;
	gap: var( --wp--preset--spacing--60 );
	align-items: start;
}

@media ( max-width: 900px ) {
	.elpis-split-layout {
		grid-template-columns: 1fr;
	}
}

/* ---------------------------------------------------------------------------
   Recent news and stories
   --------------------------------------------------------------------------- */

/*
 * patterns/news-get-involved.php. No "layout" attribute is set on the
 * wp:post-template block on purpose -- see that pattern's own comment: core
 * would otherwise emit an inline grid-template-columns style that a class
 * selector here could not out-specify without !important. This rule is the
 * only thing turning the post template into a grid.
 *
 * auto-fit rather than a fixed repeat(3, 1fr): this query's container
 * (.elpis-split-layout) is now "align":"wide" (patterns/news-get-involved.php
 * -- part of the layout-width fix that also widened patterns/help-cards.php's
 * four-card row and every other grid/card section on the homepage), so its
 * query column has real room for three ~230px cards side by side. But the
 * grid's own width still isn't fixed -- .elpis-split-layout is 2fr of a
 * responsive row that also collapses to one column under 900px (base.css's
 * own .elpis-split-layout rule), and this pattern deliberately still renders
 * only one demo post (see this pattern's own comment: seeding fake posts to
 * fill a grid is not allowed). A fixed repeat(3, 1fr) would leave two empty
 * tracks whenever there are fewer than three posts, or however narrow the
 * column gets; auto-fit collapses unused tracks instead, so one post fills
 * whatever width is available and three posts still lay out three-across
 * once they exist.
 */
.elpis-news-query .wp-block-post-template {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 220px, 1fr ) );
	gap: var( --wp--preset--spacing--40 );
}

.elpis-news-card {
	display: flex;
	flex-direction: column;
	background-color: var( --wp--preset--color--base );
	border-radius: 4px;
	box-shadow: var( --wp--preset--shadow--lift );
	overflow: hidden;
}

.elpis-news-card > * {
	padding-inline: var( --wp--preset--spacing--40 );
}

.elpis-news-card > *:last-child {
	padding-bottom: var( --wp--preset--spacing--40 );
}

/*
 * The neutral fallback fill behind each card's featured image -- shows
 * through as-is when a post has no thumbnail (true of the demo post; see
 * this pattern's own comment on why the image block is wrapped rather than
 * styled directly), and sits behind a real photo once one is uploaded.
 */
.elpis-news-card-media {
	aspect-ratio: 4 / 3;
	background-color: var( --wp--preset--color--primary-tint );
	margin: 0 0 var( --wp--preset--spacing--30 );
}

.elpis-news-card-media .wp-block-post-featured-image,
.elpis-news-card-media img {
	display: block;
	width: 100%;
	height: 100%;
	margin: 0;
	object-fit: cover;
}

.elpis-news-card .wp-block-post-title {
	margin-top: var( --wp--preset--spacing--20 );
}

/* ---------------------------------------------------------------------------
   Side panels: "Get involved" and "Stay connected"
   --------------------------------------------------------------------------- */

.elpis-side-panel {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	height: 100%;
	background-color: var( --wp--preset--color--base );
	border-radius: 4px;
	box-shadow: var( --wp--preset--shadow--lift );
	padding: var( --wp--preset--spacing--40 );
}

.elpis-side-panel-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: var( --wp--preset--spacing--60 );
	height: var( --wp--preset--spacing--60 );
	border-radius: 50%;
	background-color: var( --wp--preset--color--teal-deep );
	color: var( --wp--preset--color--base );
}

.elpis-side-panel-icon svg {
	width: var( --wp--preset--spacing--30 );
	height: var( --wp--preset--spacing--30 );
}

.elpis-side-panel h3 {
	margin: var( --wp--preset--spacing--30 ) 0 0;
}

.elpis-side-panel > p {
	margin: var( --wp--preset--spacing--20 ) 0 0;
	color: var( --wp--preset--color--muted );
}

.elpis-side-list {
	list-style: none;
	margin: var( --wp--preset--spacing--30 ) 0 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var( --wp--preset--spacing--20 );
	font-size: var( --wp--preset--font-size--small );
}

.elpis-side-list li {
	padding-left: var( --wp--preset--spacing--30 );
	position: relative;
}

/* A plain bullet, drawn with the accent hairline colour rather than an icon
   -- CLAUDE.md reserves route-coloured icon circles for the four cards in
   patterns/help-cards.php; a fifth colour scheme here would blur that. */
.elpis-side-list li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.6em;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background-color: var( --wp--preset--color--accent );
}

/*
 * Same visual convention as .elpis-hero-card-apply (teal-deep fill, base
 * text, 44px minimum) -- a new class rather than reusing that one, since
 * these two panels are not the hero and coupling their styling to a
 * hero-specific class name would make a future hero-only change silently
 * affect this section too.
 */
.elpis-side-panel-cta {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var( --wp--preset--spacing--20 );
	min-height: 44px;
	margin-top: var( --wp--preset--spacing--40 );
	padding: 0.9rem 1.75rem;
	border-radius: 4px;
	background-color: var( --wp--preset--color--teal-deep );
	color: var( --wp--preset--color--base );
	font-family: var( --wp--preset--font-family--body );
	font-size: var( --wp--preset--font-size--small );
	font-weight: 700;
	text-decoration: none;
}

.elpis-side-panel-cta:hover,
.elpis-side-panel-cta:focus {
	background-color: var( --wp--preset--color--primary-deep );
	color: var( --wp--preset--color--base );
}

.elpis-side-panel-cta svg {
	flex: 0 0 auto;
	width: var( --wp--preset--spacing--30 );
	height: var( --wp--preset--spacing--30 );
}

/* ---------------------------------------------------------------------------
   Impact band
   --------------------------------------------------------------------------- */

/*
 * patterns/impact-band.php. Reuses .elpis-stat-row/.elpis-stat (defined
 * above for the retired patterns/trust-signals.php) rather than a second set
 * of classes -- this modifier only recolours the figures for a dark band and
 * centres them under the heading, matching the comp.
 */
.elpis-stat-row--dark {
	justify-content: center;
}

.elpis-stat-row--dark .elpis-stat {
	text-align: center;
}

.elpis-stat-row--dark .elpis-stat dt,
.elpis-stat-row--dark .elpis-stat dd {
	color: var( --wp--preset--color--base );
}

/* ---------------------------------------------------------------------------
   Upcoming events
   --------------------------------------------------------------------------- */

.elpis-events-grid {
	display: grid;
	grid-template-columns: repeat( 3, 1fr );
	gap: var( --wp--preset--spacing--40 );
}

@media ( max-width: 900px ) {
	.elpis-events-grid {
		grid-template-columns: 1fr;
	}
}

.elpis-event-card {
	background-color: var( --wp--preset--color--base );
	border-radius: 4px;
	box-shadow: var( --wp--preset--shadow--lift );
	padding: var( --wp--preset--spacing--40 );
}

.elpis-event-card h3 {
	margin: var( --wp--preset--spacing--30 ) 0 0;
}

.elpis-event-card p {
	margin: var( --wp--preset--spacing--20 ) 0 0;
	color: var( --wp--preset--color--muted );
}

.elpis-event-date {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	width: var( --wp--preset--spacing--60 );
	height: var( --wp--preset--spacing--60 );
	border-radius: 4px;
	background-color: var( --wp--preset--color--teal-deep );
	color: var( --wp--preset--color--base );
	line-height: 1.1;
}

.elpis-event-day {
	font-family: var( --wp--preset--font-family--heading );
	font-size: var( --wp--preset--font-size--large );
	font-weight: 600;
}

.elpis-event-month {
	font-size: var( --wp--preset--font-size--x-small );
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

/* ---------------------------------------------------------------------------
   Partners
   --------------------------------------------------------------------------- */

.elpis-partners-row {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var( --wp--preset--spacing--50 );
	margin-top: var( --wp--preset--spacing--50 );
}

/*
 * A labelled neutral slot, not an invented logo -- CLAUDE.md's photography
 * section, applied to a partner mark rather than a photograph. The dashed
 * border on the icon inside (not this box) is what reads as "placeholder,"
 * so the box itself can still look intentional rather than broken.
 */
.elpis-partner-slot {
	display: flex;
	align-items: center;
	gap: var( --wp--preset--spacing--30 );
	min-width: 260px;
	background-color: var( --wp--preset--color--base );
	border-radius: 4px;
	padding: var( --wp--preset--spacing--30 ) var( --wp--preset--spacing--40 );
}

.elpis-partner-slot-mark {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: var( --wp--preset--spacing--60 );
	height: var( --wp--preset--spacing--60 );
	color: var( --wp--preset--color--muted );
}

.elpis-partner-slot-mark svg {
	width: 100%;
	height: 100%;
}

.elpis-partner-slot-name {
	font-size: var( --wp--preset--font-size--small );
	font-weight: 700;
	color: var( --wp--preset--color--contrast );
}

/* ---------------------------------------------------------------------------
   Footer
   --------------------------------------------------------------------------- */

/*
 * parts/footer.html. Five columns collapsing in two steps rather than one,
 * since five-across is already tight at wideSize and jumping straight to a
 * single column wastes the width a tablet-sized screen still has.
 */
.elpis-footer-grid {
	display: grid;
	grid-template-columns: repeat( 5, 1fr );
	gap: var( --wp--preset--spacing--50 );
	margin-top: var( --wp--preset--spacing--60 );
}

@media ( max-width: 900px ) {
	.elpis-footer-grid {
		grid-template-columns: repeat( 2, 1fr );
	}
}

@media ( max-width: 480px ) {
	.elpis-footer-grid {
		grid-template-columns: 1fr;
	}
}

.elpis-footer-col-title {
	margin: 0 0 var( --wp--preset--spacing--30 );
	font-family: var( --wp--preset--font-family--body );
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

.elpis-footer-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var( --wp--preset--spacing--20 );
}

/*
 * Explicit colour, not inherited -- theme.json's global link element sets
 * primary-deep, which is close to invisible on this footer's teal-deep
 * background. Same fix, same reasoning, as .elpis-utility-link above.
 */
.elpis-footer-link {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var( --wp--preset--color--base );
	font-size: var( --wp--preset--font-size--small );
	text-decoration: none;
}

.elpis-footer-link:hover,
.elpis-footer-link:focus {
	color: var( --wp--preset--color--base );
	text-decoration: underline;
}

.elpis-footer-note {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var( --wp--preset--color--primary-tint );
	font-size: var( --wp--preset--font-size--small );
}
