/* unifeyed-base — archetype behaviours that theme.json cannot express.
 *
 * SCOPE RULE: this file carries only behaviour core blocks have no mechanism for. Anything
 * expressible in theme.json belongs there instead. Every rule here is a recorded Criterion 1
 * datapoint — a place where the blocks track needs custom CSS and the Elementor track does not.
 *
 * All values are TOKEN REFERENCES. No resolved pixels, no hard-coded colour.
 */

/* ---------------------------------------------------------------------------
 * [hidden] MUST WIN
 *
 * The user-agent stylesheet's `[hidden] { display: none }` carries NO class, so any rule of ours
 * that sets an explicit display — `.u-record { display: flex }`, `.u-registry { display: flex }` —
 * outranks it and the hidden attribute stops hiding anything.
 *
 * This is why the registry rendered its full list in a browser while every test reported them
 * hidden: the tests read `element.hidden`, the PROPERTY, which was correctly true, while the
 * element carried on rendering. Attribute state and rendered state had silently diverged.
 *
 * Declared once, globally, so no component can reintroduce it by giving itself a display.
 * --------------------------------------------------------------------------- */
[hidden] { display: none !important; }

/* ---------------------------------------------------------------------------
 * hero-centered-cta — absolutely positioned decorative overlay
 *
 * The design (S-3) places World_map_(blue_dots) at layoutPositioning: ABSOLUTE, opacity 0.2,
 * offset X 805 / Y 53 over the gradient, 1054x659 at the 1920 desktop canvas.
 *
 * Core blocks have NO native absolute positioning for a decorative child. theme.json's position
 * support covers sticky headers only. So the choice is between:
 *   (a) core/cover with the map as background   — fills the section, no offset, wrong
 *   (b) CSS background-image on the section     — breaks the attachment-id rule (Phase 4)
 *   (c) a real image block + theme CSS          — CHOSEN
 *
 * (c) keeps the map a genuine media-library attachment referenced by id, keeps the markup
 * semantic, and puts the positioning in the theme where it applies to every instance of the
 * archetype rather than being re-specified per section.
 *
 * Offsets are expressed as percentages of the hero, not the design's raw px, so the overlay
 * holds its relative position at every viewport instead of only at 1920.
 *   left: 805/1920 = 41.93%   top: 53/696 = 7.61%   width: 1054/1920 = 54.9%
 * --------------------------------------------------------------------------- */
.u-hero {
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

/* SPECIFICITY CONVENTION — adopted after the third collision in this file (A1).
 *
 * Every rule here is written at exactly ONE class of specificity: a single class selector,
 * (0,1,0). No child combinators, no descendant chains, no :not(). Modifiers therefore always
 * override their base by source order alone, which is what a reader expects.
 *
 * The three collisions this prevents, all the same shape — a base rule written with a combinator
 * silently out-ranking its own modifier:
 *   Home c3  .u-hero > *:not(.u-hero__overlay)  (0,2,0) beat .u-hero__title      (0,1,0)
 *   About c1 .u-hero > .u-hero__overlay         (0,2,0) beat .u-hero__overlay--photo (0,1,0)
 *   (and the same trap was latent in every other base/modifier pair here)
 *
 * Where a rule genuinely must scope to children, it uses a dedicated class on the child rather
 * than a combinator. Elementor pays none of this cost: it sets these properties per element, so
 * there is no cascade to lose to. Criterion 3. */
.u-hero__overlay {
	position: absolute;
	/* The hero uses layout: constrained, so core caps its children at contentSize (1200px).
	 * The overlay is decorative and sized as a percentage of the full-bleed section, so it must
	 * opt out or it renders 1200px wide regardless of its own width. */
	max-width: none;
	left: 41.93%;
	top: 7.61%;
	width: 54.9%;
	margin: 0;
	opacity: 0.2;
	pointer-events: none;
	z-index: 0;
}

.u-hero__overlay img {
	display: block;
	width: 100%;
	height: auto;
}

/* Hero content must sit above the overlay. Dedicated class, not :not(), per the convention. */
.u-hero__content {
	position: relative;
	z-index: 1;
	/* ONE LEFT EDGE for every child of the hero column (eyebrow, title, body, actions).
	 *
	 * `!important` is deliberate and is the only place in this file that uses it. Core's
	 * constrained layout emits
	 *   :where(.is-layout-constrained) > :where(:not(.alignleft)...) { margin-left: auto !important }
	 * so it cannot be out-ranked by specificity at all - the (0,1,0) convention is powerless
	 * against it. This is what defeated D9 twice: `margin-inline: 0` was applied, measured as
	 * applied, and still lost. Matching !important is the fix, not more specificity. */
	margin-left: var(--u-content-inset) !important;
	margin-right: auto !important;
}

/* ---------------------------------------------------------------------------
 * icon-card-row — one-dimensional flex row, stacking below md
 *
 * AR-3 keeps this DISTINCT from card-grid: this archetype is a flex row, About's PILLARS is a
 * real two-dimensional grid. Emitting both as grids would collapse the one measurement most
 * likely to separate the two tracks.
 *
 * Core's flex layout does not stack at a breakpoint on its own, so the responsive half is here.
 * Mobile-first: stacked by default, row from md up.
 * --------------------------------------------------------------------------- */
.u-icon-card-row {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--s-24);
}

@media (min-width: 768px) {
	.u-icon-card-row {
		flex-direction: row;
		flex-wrap: nowrap;
		align-items: flex-start;
		gap: var(--wp--preset--spacing--s-24);
	}

	.u-icon-card-row > * {
		flex: 1 1 0;
		min-width: 0; /* without this a flex item refuses to shrink below its content width */
	}
}

/* ---------------------------------------------------------------------------
 * Constrained title width — hero-title-max (Q-1: 900 / 600 / 900, non-monotonic as designed)
 * --------------------------------------------------------------------------- */
.u-hero__title {
	max-width: var(--wp--custom--size--hero-title-max);
	/* Left edge, not centred - every hero archetype is align: start in the spec (corrected
	 * 2026-09-09; `center` was never extracted from Figma). Same !important reason as above. */
	margin-left: var(--u-content-inset) !important;
	margin-right: auto !important;
}

/* ---------------------------------------------------------------------------
 * SURFACES — a section's background decides the colour of the text on it (D5)
 *
 * Extracted from the Figma frame, not assumed: on dark sections headings are white, body is
 * athens-gray and eyebrows are casper; on light and accent sections headings are mirage, body is
 * fiord and eyebrows are bermuda-gray. It is not a single colour per surface.
 *
 * This lives in CSS rather than theme.json because theme.json styles elements globally, and the
 * same h2 must be white on a dark section and mirage on a light one. Contextual styling is a
 * blocks-track gap: Elementor sets colour per element in the UI. Criterion 1 / Criterion 3.
 * --------------------------------------------------------------------------- */
.u-surface--dark { color: var(--wp--preset--color--grey-athens-gray); }
.u-surface--dark h1,
.u-surface--dark h2,
.u-surface--dark h3,
.u-surface--dark h4 { color: var(--wp--preset--color--white-solid); }
.u-surface--dark h6,
.u-surface--dark .u-eyebrow { color: var(--wp--preset--color--blue-casper); }
.u-surface--dark p { color: var(--wp--preset--color--grey-athens-gray); }

.u-surface--light,
.u-surface--accent { color: var(--wp--preset--color--grey-fiord); }
.u-surface--light h1, .u-surface--light h2, .u-surface--light h3, .u-surface--light h4,
.u-surface--accent h1, .u-surface--accent h2, .u-surface--accent h3, .u-surface--accent h4 {
	color: var(--wp--preset--color--blue-mirage);
}
.u-surface--light h6, .u-surface--light .u-eyebrow,
.u-surface--accent h6, .u-surface--accent .u-eyebrow {
	color: var(--wp--preset--color--blue-bermuda-gray);
}
.u-surface--light p, .u-surface--accent p { color: var(--wp--preset--color--grey-fiord); }

.u-surface--accent { background-color: var(--wp--preset--color--grey-athens-gray); }
.u-surface--light  { background-color: var(--wp--preset--color--white-solid); }

/* Eyebrow labels are H6 semantics rendered as a paragraph in some sections; give them the same
 * small-caps treatment the token carries (D13). */
.u-eyebrow {
	letter-spacing: 2px;
	text-transform: uppercase;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 600;
}

/* Secondary button — transparent with a white border (D10). Core has no second button style,
 * so the variant is a class the emitter applies. */
.u-btn--secondary .wp-block-button__link,
.wp-block-button.u-btn--secondary > .wp-block-button__link {
	background-color: transparent !important;
	border-color: var(--wp--preset--color--white-solid) !important;
	color: var(--wp--preset--color--white-solid) !important;
}

/* ---------------------------------------------------------------------------
 * hero-centered-cta — the hero is a TWO-COLUMN structure, not centred (D9)
 *
 * Content occupies a left column; the map occupies the right. The build previously centred
 * everything and stretched the map full width, which is a structural difference rather than an
 * alignment one.
 * --------------------------------------------------------------------------- */
@media (min-width: 768px) {
	/* The 52% column belongs to hero-centered-cta (Home): content left, map right.
	 * hero-image (About) places content at the full content width with the photo overlapping it,
	 * so the modifier is scoped rather than applied to every hero. */
	.u-hero--column .u-hero__actions { justify-content: flex-start; }
}

/* ---------------------------------------------------------------------------
 * site-header — full nav bar (D6). ABSOLUTE overlay on the hero per S-1.
 * --------------------------------------------------------------------------- */
.u-nav {
	position: absolute;
	inset-inline: 0;
	top: 0;
	z-index: 10;
	/* The nav link colour must be set HERE, on the container, not on the links.
	 * Core wins the link rule outright with a doubled-class selector:
	 *   .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content
	 * at (0,3,0), and it declares `color: inherit`. No rule on the anchor can beat that without
	 * escalating past it, but because it inherits, setting the colour on the ancestor works and
	 * needs no specificity fight at all. Design value: Primary/Athens Gray. */
	color: var(--wp--preset--color--grey-athens-gray);
}

/* The nav bar sits inside the CONTENT COLUMN, not across the viewport. In Figma the nav
   div.wrap is x=360 w=1200 on desktop - the logo shares the content edge with the hero text.
   Previously .u-nav spanned the viewport with only the outside-margin padding, so the logo
   landed at x=48 and overhung the photograph. */
.u-nav__bar {
	align-items: center;
	max-width: var(--wp--style--global--content-size, 1200px);
	margin-inline: auto;
}
.u-nav__logo { margin: 0; max-width: 255px; }
.u-nav__logo img { display: block; width: 100%; height: auto; }
/* Nav links are ATHENS GRAY in the design (Primary/Athens Gray, rgb(238,241,245)) - measured
 * from the Figma Nav frame, not assumed. The previous rule asked for white-solid and lost the
 * cascade entirely: core's navigation block sets its own link colour at higher specificity, so
 * the links rendered mirage rgb(26,39,51) - near-black on a dark hero, which is the legibility
 * problem reported. Targeting core's own generated class is one of this file's declared
 * exceptions to the single-class convention. */
.u-nav .wp-block-navigation-item__content {
	color: var(--wp--preset--color--grey-athens-gray);
	text-decoration: none;
}

.u-nav a { color: var(--wp--preset--color--grey-athens-gray); text-decoration: none; }

/* "Verify a Source" — the last link renders as a filled light button (D6). */
.u-nav .wp-block-navigation-item:last-child a {
	background-color: var(--wp--preset--color--grey-athens-gray);
	color: var(--wp--preset--color--blue-daintree);
	padding: 12px 20px;
	border-radius: var(--wp--custom--radius--r-4);
}

/* The header overlays the hero, so the page must not reserve space for it. */
.wp-site-blocks > header { position: relative; height: 0; }

/* The hero runs to the TOP EDGE of the frame in every design - hero dy=0 and nav dy=0 on all
   seven Figma frames, with the nav overlaying the hero rather than sitting above it.
   Core's block-gap rule gives every child of .wp-site-blocks a margin-block-start of 24px. It
   lands on <main> (the header is already height 0) and put a 24px white band above the hero on
   every page. Same declared exception as the rule above: this targets a core-generated element,
   not one of ours. */
/* EVERY direct child, not just main. Zeroing only `main` left the same 24px gap at the next
   boundary along — a full-width white band between the last content section and the footer.
   Header, main and footer are all flush in the design. Fourth instance of core's block-gap
   default adding space the design never asked for (above the hero, between sections, and now at
   the footer join); generalised so the next boundary cannot repeat it. */
.wp-site-blocks > * { margin-block-start: 0; }

/* ---------------------------------------------------------------------------
 * hero-image (About) — photographic overlay, offset right at 80%
 * Figma: ABSOLUTE, 1428x691 within a 1920x691 hero, x=597, opacity 0.8.
 *   left 597/1920 = 31.1%   width 1428/1920 = 74.4%
 * --------------------------------------------------------------------------- */
.u-hero__overlay--photo {
	/* GEOMETRY COMES FROM THE SPEC, per breakpoint, via custom properties emitted onto this
	 * element (--u-ov-*). It is different on every page - the photo is 74.4% wide on About and
	 * 58.5% on How We Work - so a single hand-written rule was wrong by construction and could
	 * not have been detected: the value existed only here.
	 *
	 * The image asset carries its OWN feathered alpha on every edge (0 at the left, ~0.8 across
	 * the middle, 0 at the right) and the design's 0.8 layer opacity is baked into the export.
	 * That is what makes the hero read as ONE CONTINUOUS SURFACE rather than a navy block butted
	 * against a photograph: there is no edge to see. Verified from the exported PNG's alpha
	 * channel, not from the render (DF-1 - a gradient reads ambiguously on screen).
	 * Emitting opacity 0.8 here as well would double-fade it. */
	top: 0;
	height: 100%;
	left: var(--u-ov-x-base);
	width: var(--u-ov-w-base);
	opacity: var(--u-ov-opacity, 1);
	object-fit: cover;
}

.u-hero__overlay--photo img { width: 100%; height: 100%; object-fit: cover; }

@media (min-width: 768px) {
	.u-hero__overlay--photo { left: var(--u-ov-x-md); width: var(--u-ov-w-md); }
}

@media (min-width: 1200px) {
	.u-hero__overlay--photo { left: var(--u-ov-x-lg); width: var(--u-ov-w-lg); }
}

.u-hero__overlay--photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* ---------------------------------------------------------------------------
 * checklist — shared marker plus one line of text per item
 * --------------------------------------------------------------------------- */
/* gap 0: each row carries its own 16/16 padding and a top rule, so the rule separates them.
   See the note on .u-statement — same treatment, same token, three sections. */
.u-checklist { gap: 0; }

.u-checklist__item {
	display: flex;
	flex-wrap: nowrap;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--s-12);
	padding-top: var(--wp--preset--spacing--s-16, 16px);
	padding-bottom: var(--wp--preset--spacing--s-16, 16px);
	border-top: 1px solid var(--wp--preset--color--grey-light-gray);
}

.u-checklist__marker {
	flex: 0 0 20px;
	margin: 0;
	margin-block-start: 0.35em;   /* optically align the tick with the first text line */
}

.u-checklist__item p { margin: 0; }

/* ---------------------------------------------------------------------------
 * card-grid — AR-3's CSS Grid case.
 *
 * Deliberately NO grid CSS here: core's grid layout (columnCount 3) handles the two-dimensional
 * arrangement natively, including the short last row. That is the point of the AR-3 measurement —
 * if this needed hand-written grid CSS, the blocks track would have failed the case rather than
 * passed it. Only card appearance is styled.
 * --------------------------------------------------------------------------- */
.u-card {
	background-color: var(--wp--preset--color--white-solid);
	padding: var(--wp--preset--spacing--s-32);
	border-radius: var(--wp--custom--radius--r-4);
}

.u-card h4 { margin-block-start: 0; }

/* ---------------------------------------------------------------------------
 * card-grid — responsive column count (A2)
 *
 * REFINES the cycle-1 AR-3 finding. Core's grid layout takes a SINGLE columnCount, so it renders
 * the design's desktop grid natively but has no mechanism for the design's 3 -> 2 -> 1 sequence.
 * The two-dimensional arrangement is native; the RESPONSIVENESS is not.
 *
 * Spec: card-grid.items_layout.columns = { base: 1, md: 2, lg: 3 } — matching Figma exactly
 * (Desktop GRID cols=3, Tablet GRID cols=2, Mobile VERTICAL).
 * Mobile-first: base overrides core's emitted 3, then md, then lg restores it.
 * --------------------------------------------------------------------------- */
.u-card-grid { grid-template-columns: repeat(1, minmax(0, 1fr)); }

@media (min-width: 768px) {
	.u-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1200px) {
	.u-card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* =========================================================================
   Added 2026-09-09 — the five remaining pages.
   Convention unchanged: every selector at a single class of specificity,
   (0,1,0). No child combinators, no descendant chains, no :not().
   ========================================================================= */

/* ---- resource-list ---- */
.u-res-list { display: flex; flex-direction: column; gap: 0; width: 100%; }
.u-res { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--s-8, 8px);
	width: 100%; padding-top: var(--wp--preset--spacing--s-24, 24px);
	padding-bottom: var(--wp--preset--spacing--s-24, 24px);
	border-bottom: 1px solid rgba(0, 56, 81, 0.12); }
.u-res__tag { margin: 0; opacity: 0.7; text-transform: uppercase; letter-spacing: 0.08em; }
.u-res__arrow { margin: 0; align-self: flex-start; }

/* ---- card-columns ---- */
.u-card-columns { display: grid; grid-template-columns: minmax(0, 1fr);
	gap: var(--wp--preset--spacing--s-24, 24px); width: 100%; align-items: start; }
.u-card__media { margin: 0 0 var(--wp--preset--spacing--s-16, 16px) 0; }
.u-card__tag { margin: 0 0 var(--wp--preset--spacing--s-8, 8px) 0; opacity: 0.7;
	text-transform: uppercase; letter-spacing: 0.08em; }

/* ---- process-steps ---- */
.u-steps { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--s-24, 24px);
	width: 100%; align-items: stretch; }
.u-step { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--s-8, 8px);
	flex: 1 1 0; min-width: 0; }
.u-step__num { margin: 0; opacity: 0.7; text-transform: uppercase; letter-spacing: 0.08em; }

/* ---- stat-band ---- */
.u-stats { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--s-24, 24px);
	width: 100%; align-items: stretch; }
.u-stat { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--s-8, 8px);
	flex: 1 1 0; min-width: 0; }
.u-stat__figure { margin: 0; }

/* ---- people-grid ---- */
.u-people { display: grid; grid-template-columns: minmax(0, 1fr);
	gap: var(--wp--preset--spacing--s-32, 32px); width: 100%; }
.u-person { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--s-8, 8px); }
.u-person__portrait { margin: 0 0 var(--wp--preset--spacing--s-8, 8px) 0; }
.u-person__role { margin: 0; opacity: 0.7; }

/* ---- profile-header ---- */
.u-profile__portrait { margin: 0 0 var(--wp--preset--spacing--s-16, 16px) 0; }
.u-profile__name { margin: 0; }
.u-profile__role { margin: 0; opacity: 0.85; }

/* two-col-body-list column heading — 480px measure, from the design.
 *
 * Measured on How We Work | Desktop: "Applying for certification." is 480 wide and 88 tall at
 * fs 40 / lh 44 — two lines. The build rendered it 588 wide (the full column) and 44 tall, so it
 * set on ONE line and ran up against the body column beside it. Capping the measure at the
 * design's 480 restores the two-line wrap and the breathing space. */
.u-colhead { max-width: 480px; }

/* ---- two-col-body-list ---- */
.u-statements { display: flex; flex-direction: column;
	gap: var(--wp--preset--spacing--s-8, 8px); width: 100%; }
.u-statement { width: 100%; }

/* ---- functionally inert controls (lookup-form, registry-listing) ----
   These render as static markup. They carry no handler, endpoint or validation, because the
   design has no runtime to extract one from. Styled to look correct; they do nothing. */
/* NOTE: the lookup controls are styled with the real lookup card further down this file.
   The inert-era rules that used to sit here were removed rather than overridden - they were
   still supplying a margin-top on the button and a content-inset margin that broke the
   button's alignment inside the field row. */

/* ---- registry-listing ---- */
.u-registry { display: flex; flex-direction: column;
	gap: var(--wp--preset--spacing--s-16, 16px); width: 100%; }
@media (min-width: 768px) {
	/* resource-row: TAG | (title over description) | ARROW.
	 *
	 * This was a single flex row, which put the description BESIDE its title. The design stacks
	 * them: measured on Resources | Desktop, the tag sits at x=16298 while the title (y=12064) and
	 * the description (y=12089) share x=16478 — same left edge, 25px apart. A 180px offset between
	 * the two columns, which is the 156px tag column plus the 24px gap.
	 *
	 * Grid rather than nested flex because the emitted children are FLAT (tag, h5, p, arrow) and
	 * adding a wrapper would mean changing the archetype's markup. Only the tag and the arrow are
	 * placed explicitly; the title and description then auto-flow into column 2, rows 1 and 2,
	 * which is exactly the design's arrangement without needing classes they do not carry. */
	/* DOUBLED CLASS, deliberately — (0,2,0), the documented exception to the (0,1,0) convention.
	 * The row also carries core's `wp-block-group-is-layout-flex`, whose `display: flex` is also
	 * (0,1,0) but is printed to the document AFTER this stylesheet, so at equal specificity core
	 * wins on source order. Measured: grid-template-columns and the gaps applied while `display`
	 * stayed `flex`, which is the signature of exactly this collision — our rule was live, and one
	 * property of it was being overridden. Same family as the `.is-layout-grid` and
	 * `margin-left: auto !important` traps already recorded in this file. */
	.u-res.u-res { display: grid; grid-template-columns: 156px minmax(0, 1fr) auto;
		align-items: baseline;
		column-gap: var(--wp--preset--spacing--s-24, 24px);
		row-gap: var(--wp--preset--spacing--s-8, 8px); }
	.u-res__tag { grid-column: 1; grid-row: 1 / span 2; }
	.u-res__arrow { grid-column: 3; grid-row: 1 / span 2; }
	.u-card-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.u-people { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.u-steps { flex-direction: row; }
	.u-stats { flex-direction: row; }
}

@media (min-width: 1200px) {
	.u-card-columns { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.u-people { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---------------------------------------------------------------------------
 * CONTENT-EDGE ALIGNMENT (--u-content-inset)
 *
 * Core's constrained layout centres every child of a section and does it with
 *   margin-left: auto !important
 * which no specificity can beat. For a block narrower than the content width that means the
 * block is centred, so a 600px paragraph under a 1200px heading starts 300px to its right —
 * a ragged left edge on every start-aligned section.
 *
 * This computes the distance from the section's padding box to the content edge, so a narrow
 * block starts exactly where a full-width one does. `max()` keeps it at 0 when the viewport is
 * narrower than the content width, so mobile is unaffected.
 *
 * !important here matches core's !important. It is not a specificity escalation and is confined
 * to this one declaration pair.
 * --------------------------------------------------------------------------- */
:root { --u-content-inset: max(0px, calc((100% - var(--wp--style--global--content-size, 1200px)) / 2)); }

.u-maxw {
	margin-left: var(--u-content-inset) !important;
	margin-right: auto !important;
}

/* ---------------------------------------------------------------------------
 * CARD OUTLINE (fidelity item 5)
 *
 * EXTRACTION GAP, not an emitter drop. The Figma pillar card carries
 *   stroke SOLID rgb(213,215,221), strokeWeight 1, cornerRadius 4, padding 24
 * and the site spec never captured a border construct at all - so there was nothing for the
 * emitter to drop. The value lives here for now; folding `border` into the spec's archetype
 * schema is queued, because as it stands the outline is CSS-owned and can drift from the design
 * without any check noticing (the same shape as overlay geometry and responsive columns).
 * --------------------------------------------------------------------------- */
.u-icon-card {
	padding: var(--wp--preset--spacing--s-24, 24px);
	border: 1px solid var(--wp--preset--color--grey-light-gray);
	border-radius: var(--wp--custom--radius--r-4);
}

.u-card { border: 1px solid var(--wp--preset--color--grey-light-gray); }

/* ---------------------------------------------------------------------------
 * card-columns — COLUMN-MAJOR, not row-major (fidelity item 1)
 *
 * The design is three independent columns of unequal-height cards read top-to-bottom. A CSS grid
 * fills row-major, which put card 2 beside card 1 instead of beneath it and destroyed the
 * staggered arrangement. Multi-column layout fills column-major and lets each card keep its own
 * height, which is what the design does.
 * --------------------------------------------------------------------------- */
.u-card-columns {
	display: block;
	column-count: 1;
	column-gap: var(--wp--preset--spacing--s-24, 24px);
}

/* Only cards inside the multi-column flow need to avoid breaking and to carry their own bottom
   gap. Applying either to every .u-card put a stray 24px under cards in real grids (About's
   card-grid), which is what made the newsroom look ragged. */
.u-card--flow {
	break-inside: avoid;
	margin-bottom: var(--wp--preset--spacing--s-24, 24px);
}

@media (min-width: 768px) {
	.u-card-columns { column-count: 2; }
}

@media (min-width: 1200px) {
	.u-card-columns { column-count: 3; }
}

/* ---------------------------------------------------------------------------
 * HOVER STATES
 *
 * The Figma file has a dedicated "Hover States" canvas which had never been extracted. It
 * specifies hovers for resource rows, cards, buttons, the lookup field and registry cards.
 *
 * IT CONTAINS NO NAV FRAMES. The nav hover below is therefore INFERRED, not extracted, and is
 * flagged as a client query alongside Q-1..Q-4: white plus underline, the conventional treatment,
 * chosen because the design gives no answer. Everything else here is from the Hover States canvas.
 * --------------------------------------------------------------------------- */
.u-nav .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--white-solid);      /* INFERRED - see above */
	text-decoration: underline;
}

.u-nav .wp-block-navigation-item:last-child a:hover {
	background-color: var(--wp--preset--color--white-solid);
	text-decoration: none;
}

.u-res:hover { background-color: var(--wp--preset--color--grey-athens-gray); }

.u-card:hover { border-color: var(--wp--preset--color--blue-bermuda-gray); }

.u-icon-card:hover { border-color: var(--wp--preset--color--blue-bermuda-gray); }

.u-record:hover { border-color: var(--wp--preset--color--blue-bermuda-gray); }

.wp-block-button__link:hover { opacity: 0.88; }

.u-field__input:focus { outline: 2px solid var(--wp--preset--color--blue-bermuda-gray); outline-offset: 2px; }

/* Every interactive surface gets a visible transition, so hover reads as a state change rather
   than a repaint. Kept short; reduced-motion users are covered by the capture harness and by
   the browser's own preference, which core honours. */
.u-res, .u-card, .u-icon-card, .u-record, .wp-block-navigation-item__content, .wp-block-button__link {
	transition: color .15s ease, background-color .15s ease, border-color .15s ease, opacity .15s ease;
}

/* ---------------------------------------------------------------------------
 * site-footer — was an EMPTY STUB (`<div class="wp-block-group"></div>`) for the whole build.
 * The spec carried a full definition; the template part was never written, and because the
 * emitter correctly skips `use:` sections as template parts, nothing rendered a footer at all.
 * Figma: full-bleed daintree, content column 1200 at x=360, brand half 600 / links half 600,
 * legal row split left/right.
 * --------------------------------------------------------------------------- */
.u-foot__grid { gap: var(--wp--preset--spacing--s-32, 32px); align-items: flex-start; }
.u-foot__brand { flex: 1 1 480px; max-width: 600px; }
.u-foot__logo { margin: 0 0 var(--wp--preset--spacing--s-24, 24px) 0; max-width: 255px; }
.u-foot__logo img { display: block; width: 100%; height: auto; }
.u-foot__about { max-width: 480px; margin: 0; }
/* Footer link-column gap is 24 at mobile and tablet, 60 at desktop — measured from the Figma
   footer row (itemSpacing 24 / 24 / 60). It was a flat 48 everywhere, which is wrong at every
   breakpoint and, at mobile, left about ONE PIXEL of headroom before the two columns wrapped:
   162 + 144 design column widths + 48 gap = 354 against a 354 container.

   That is not a cosmetic discrepancy. Correcting the footer email from .org to .com made the
   Connect column 3.8px wider (m is wider than g), which tipped the row into wrapping and grew
   every page by 147px at mobile. A three-character, entirely correct content edit broke the
   layout on seven pages because the spacing token disagreed with the design.

   At the design's 24px the same content leaves ~23px of slack, so a longer address or a
   differently formatted phone number no longer reflows the footer. */
.u-foot__cols { gap: var(--wp--preset--spacing--s-24, 24px); flex: 0 1 auto; align-items: flex-start; }
.u-foot__col { min-width: 144px; }
/* Scoped to (0,1,1) to match `.u-foot p` above — a bare .u-foot__title (0,1,0) lost to it,
   which is the same specificity trap one level down. */
.u-foot .u-foot__title {
	margin: 0 0 var(--wp--preset--spacing--s-16, 16px) 0;
	color: var(--wp--preset--color--blue-casper);   /* design rgb(174,186,210) */
}
.u-foot__link { margin: 0 0 var(--wp--preset--spacing--s-8, 8px) 0; }
.u-foot__bottom { margin-top: var(--wp--preset--spacing--s-48, 48px); gap: var(--wp--preset--spacing--s-16, 16px); }
.u-foot__legal { margin: 0; }
/* The footer defines its own palette rather than using u-surface--dark. The generic dark surface
   sets body text to athens-gray, but the design's footer description and copyright are WHITE and
   only the column headers are muted (casper). Carrying the surface class here meant
   `.u-surface--dark p` (0,1,1) overrode every footer colour rule. */
.u-foot { color: var(--wp--preset--color--white-solid); }
.u-foot p { color: var(--wp--preset--color--white-solid); }

/* ---------------------------------------------------------------------------
 * TEXT TRANSFORM, DRIVEN BY THE TOKEN (not per component)
 *
 * The spec records text_transform: uppercase on h6, tag and tag-medication - and deliberately
 * NOT on h4 or quote, which are ORIGINAL in the Figma text styles. It was being applied by a
 * scattered set of per-component rules, so any slot whose class nobody remembered to add stayed
 * lower case. Binding it to the token class applies it wherever the token is used, once.
 * --------------------------------------------------------------------------- */
/* Text transform, family, weight and tracking are now generated per token into
   assets/css/type-tokens.css. The hand-written rules that used to sit here applied a
   guessed 0.08em tracking to three tokens; the spec's real values are 2px, 1px and
   0.5px and differ per token. */


/* ---------------------------------------------------------------------------
 * Sections are CONTIGUOUS in every Figma frame - measured inter-section gaps are 0 on all seven
 * desktop frames. Core's block-gap rule was adding 24px between every section, the same default
 * that put a band above the hero. Same declared exception: a core-generated element.
 * --------------------------------------------------------------------------- */
.entry-content > * { margin-block-start: 0; }

/* Process steps carry a 2px rule ABOVE each step: Figma div.step has
   individualStrokeWeights {top: 2} with stroke rgb(0,56,81) = prussian blue. */
.u-step {
	border-top: 2px solid var(--wp--preset--color--blue-prussian-blue);
	padding-top: var(--wp--preset--spacing--s-16, 16px);
}

/* Statement rows: repeated 13x9 tick plus one line of copy. */
/* two-col-body-list marker — sized from the design, not nudged.
 *
 * Reported as "the checkmarks sit lower than their text". They were top-aligned correctly; the
 * marker was simply the wrong SIZE. Measured on How We Work | Desktop: the row is a 12px-gap
 * horizontal with a 20x20 marker frame and the text at fs 16 / lh 24, both starting at the same y.
 * The build rendered a 30px marker with an 8px gap, so it overhung the 24px line box by 6px and
 * read as sitting low — and a `padding-top: 6px` had been added on top of that, pushing it lower
 * still. Two compensations for a size that was wrong to begin with.
 *
 * At 20x20 against a 24px line the marker occupies the line box cleanly and needs no padding
 * nudge, which is why the padding is removed rather than retuned. */
/* ROW SEPARATORS — extracted, and the same rule in three places.
 *
 * About's "Five Commitments", How We Work's "For suppliers" and Verify a Source's "Reading a
 * result" all draw each row as an `li` with a TOP stroke of rgba(213,215,221) at 1px and 16px of
 * padding above and below. That colour is exactly the palette's grey-light-gray (#d5d7dd), so it
 * stays inside the token system rather than being hardcoded — which is what the two pre-existing
 * FAQ border rules below get wrong and are corrected to match.
 *
 * Row heights corroborate the padding: About 80 = 16 + 48 (two 24px lines) + 16, Verify a Source
 * 56 = 16 + 24 + 16. The container gap therefore goes to 0 — the rows butt together and the rule
 * is what separates them, so any gap would double-space them away from the design. */
.u-statements { gap: 0; }
.u-statement { gap: 12px; align-items: flex-start;
	padding-top: var(--wp--preset--spacing--s-16, 16px);
	padding-bottom: var(--wp--preset--spacing--s-16, 16px);
	border-top: 1px solid var(--wp--preset--color--grey-light-gray); }
.u-statement__marker { margin: 0; flex: 0 0 20px; width: 20px; height: 20px; }
.u-statement__marker img { display: block; width: 100%; height: 100%; }

/* ---------------------------------------------------------------------------
 * HERO PHOTO BLEND MODE — the reason the hero read grey instead of blue.
 *
 * The Figma hero image node is blendMode: SOFT_LIGHT at 0.8 opacity, on all five photo heroes.
 * Soft-light over the navy gradient keeps the navy hue and lets the photograph modulate
 * luminosity only; NORMAL compositing shows the photograph's own grey tones instead. Measured
 * against a Figma render of the same frame: photo core figma=(1,61,85) vs web=(135,144,148).
 *
 * This was missed on the first pass because the earlier node dump printed blendMode for fills
 * but not for the NODE - the property that carried it. The lesson is the A-0 one again: read the
 * property that governs the behaviour, not the one that is convenient to print.
 *
 * `isolation: isolate` on the hero confines the blend to the hero's own gradient; without it the
 * overlay would composite against whatever the page happens to paint beneath.
 * --------------------------------------------------------------------------- */
.u-hero { isolation: isolate; }
.u-hero__overlay--photo { mix-blend-mode: soft-light; }

/* ---------------------------------------------------------------------------
 * VERIFY A SOURCE — lookup card and registry listing
 *
 * Extracted geometry: div.lookup is an athens-gray card, 1px white stroke, radius 4, padding 32
 * (20 on mobile), gap 16. It holds a white row of radius 4 and height 56, containing the input
 * (padding 20/16, placeholder in fiord) and the Verify button (fill rgb(3,62,89), radius 4,
 * padding 24/16, white label).
 *
 * FOCUS STATE: the Hover States canvas shows the field only with a typed caret - it specifies NO
 * colour change on focus. A visible focus ring is added anyway because a keyboard user needs one
 * and the design does not answer the question; flagged as inferred, like the nav hover.
 *
 * Status colours are extracted per value and are CSS-owned for now - they should become tokens.
 * --------------------------------------------------------------------------- */
:root {
	--u-status-active:  rgb(47, 168, 25);
	--u-status-pending: rgb(245, 166, 35);
	--u-status-expired: rgb(208, 2, 27);
	--u-status-revoked: rgb(128, 128, 128);
}

.u-lookup {
	background-color: var(--wp--preset--color--grey-athens-gray);
	border: 1px solid var(--wp--preset--color--white-solid);
	border-radius: var(--wp--custom--radius--r-4);
	padding: var(--wp--preset--spacing--s-20, 20px);
	max-width: 584px;
}

.u-field__label { display: block; margin: 0 0 var(--wp--preset--spacing--s-16, 16px) 0; color: var(--wp--preset--color--blue-mirage); }

.u-field__row {
	display: flex;
	align-items: stretch;
	background-color: var(--wp--preset--color--white-solid);
	border-radius: var(--wp--custom--radius--r-4);
	overflow: hidden;
}

.u-field__input {
	box-sizing: border-box;
	flex: 1 1 auto;
	min-width: 0;
	border: 0;
	background: transparent;
	padding: var(--wp--preset--spacing--s-16, 16px) var(--wp--preset--spacing--s-20, 20px);
	font: inherit;
	color: var(--wp--preset--color--blue-mirage);
}

.u-field__input::placeholder { color: var(--wp--preset--color--blue-fiord); opacity: 1; }
.u-field__input:focus-visible { outline: 2px solid var(--wp--preset--color--blue-bermuda-gray); outline-offset: -2px; }

.u-field__submit {
	flex: 0 0 auto;
	border: 0;
	border-radius: var(--wp--custom--radius--r-4);
	background-color: rgb(3, 62, 89);
	color: var(--wp--preset--color--white-solid);
	padding: var(--wp--preset--spacing--s-16, 16px) var(--wp--preset--spacing--s-24, 24px);
	font: inherit;
	cursor: pointer;
}

.u-field__submit:hover { opacity: 0.88; }

/* Chips and a result count were removed: this page is a lookup, not a browsable list.
   Their styling is deleted rather than left orphaned. */

.u-registry__empty { margin: var(--wp--preset--spacing--s-24, 24px) 0 0 0; }

/* ---- records ---- */
.u-record {
	/* Design registry-card: 1px stroke rgb(213,215,221), radius 4, padding 32, white ground.
	   The border and background were lost when the stale inert-era .u-record rule was removed —
	   the replacement carried the padding but not the card treatment. */
	border: 1px solid rgb(213, 215, 221);
	border-radius: var(--wp--custom--radius--r-4);
	background-color: var(--wp--preset--color--white-solid);
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--s-32, 32px);
	align-items: center;
	justify-content: space-between;
	/* Design: registry-card is 149px tall on desktop with 32px padding and a 32px internal gap.
	   The build was inflating it because the row had no height discipline and the content was
	   centred in whatever height the flex column produced. */
	padding: var(--wp--preset--spacing--s-32, 32px);
}

.u-record__main { flex: 1 1 320px; min-width: 0; }
.u-record__med { margin: 4px 0; }
.u-record__tags { display: flex; flex-wrap: wrap; gap: var(--wp--preset--spacing--s-8, 8px); align-items: center; }

.u-record__meta {
	display: inline-block;
	padding: 4px 12px;
	border: 1px solid var(--wp--preset--color--blue-casper);
	border-radius: 9999px;
	background: transparent;
}

.u-record__status {
	display: inline-block;
	padding: 4px 12px;
	border-radius: 9999px;
	color: var(--wp--preset--color--white-solid);
}

.u-status--active  { background-color: var(--u-status-active); }
.u-status--pending { background-color: var(--u-status-pending); }
.u-status--expired { background-color: var(--u-status-expired); }
.u-status--revoked { background-color: var(--u-status-revoked); }

@media (min-width: 768px) {
	.u-lookup { padding: var(--wp--preset--spacing--s-32, 32px); }
}

/* Cards that carry their own padding and border must be border-box, or the padding is added to a
   100%-width content box and the row overflows the viewport on mobile. Same defect class as the
   lookup input earlier in this build. */
.u-record { box-sizing: border-box; }
.u-card { box-sizing: border-box; }
.u-icon-card { box-sizing: border-box; }
.u-lookup { box-sizing: border-box; }

/* ---------------------------------------------------------------------------
 * Verify a Source — section head beside the search card (design layout)
 *
 * Figma desktop: div.wrap is HORIZONTAL, 1200 wide, two 584 columns with a 32 gap — head left,
 * card right. Tablet and mobile stack them (div.wrap is VERTICAL there), gap 32.
 * Section padding is 120 top/bottom on desktop, 100 on tablet and mobile.
 * --------------------------------------------------------------------------- */
.u-lookup-row { gap: var(--wp--preset--spacing--s-32, 32px); align-items: flex-start; }
.u-lookup__head { flex: 1 1 100%; min-width: 0; }
.u-lookup { flex: 1 1 100%; max-width: 584px; }

.u-record__main { flex: 1 1 320px; min-width: 0; }
.u-record__id { margin: 0; }
.u-record__med { margin: 4px 0 0 0; }
.u-record__supplier { margin: 2px 0 0 0; }
.u-record__tags { flex: 0 1 auto; }

/* The registry list and its controls sit directly under the card — the large empty band was the
   chips' own top margin stacking with the section gap. */

@media (min-width: 1200px) {
	.u-lookup__head { flex: 0 0 584px; max-width: 584px; }
	.u-lookup { flex: 0 0 584px; max-width: 584px; }
}

/* Core's vertical flex layout sets align-items: flex-start, so each row shrank to its own content
   width (669px instead of 1200) and the two columns then wrapped onto separate lines - which is
   what made every record ~197px tall instead of 149. Rows are full width; the list stretches. */
.u-registry { align-items: stretch; }
.u-record { width: 100%; }

/* Flex items default to min-width: auto, so a flex child cannot shrink below its content's
   min-content width and pushes the page wider than the viewport. The lookup card was 397px inside
   a 354px column at 402. Standard guard, applied to both columns of the lookup row. */
.u-lookup, .u-lookup__head { min-width: 0; max-width: 100%; }

@media (min-width: 1200px) {
	.u-lookup, .u-lookup__head { max-width: 584px; }
}

/* ---------------------------------------------------------------------------
 * FOOTER LINK COLOUR
 *
 * The link columns were never missing — they were invisible. Anchors inherited theme.json's
 * elements.link colour, prussian blue rgb(0,56,81), on the footer's daintree rgb(0,38,54): a
 * contrast ratio close to 1. Design has footer text and links in white.
 *
 * Same failure as the nav, and the same root: a global link colour applied over a dark surface
 * that nothing scoped it out of. `.u-foot a` at (0,1,1) beats theme.json's
 * `a:where(:not(.wp-element-button))` at (0,1,0), so no escalation is needed here.
 * --------------------------------------------------------------------------- */
.u-foot a {
	color: var(--wp--preset--color--white-solid);
	text-decoration: none;
}

.u-foot a:hover { text-decoration: underline; }

/* The no-JS notice. Sits above the revealed records and explains why they are all listed. */
.u-registry__noscript {
	margin: var(--wp--preset--spacing--s-24, 24px) 0;
	padding: var(--wp--preset--spacing--s-16, 16px);
	border-left: 3px solid var(--wp--preset--color--blue-bermuda-gray);
	background-color: var(--wp--preset--color--grey-athens-gray);
}

/* ---------------------------------------------------------------------------
 * HERO CONTENT GAPS — the design's, not core's default
 *
 * Element heights and line-heights already matched the design exactly (19 / 120 / 81 on Resources
 * desktop). The heroes were uniformly 48px too tall because core gives every block a 24px
 * margin-block-start, while the Figma hero uses:
 *
 *     eyebrow -> title   8px      title -> subtitle  16px      subtitle -> actions  0
 *
 * 24 (before the eyebrow) + 16 + 8 = the 48px constant seen on all five photo heroes.
 * Fifth instance of core's block-gap default adding space the design never asked for.
 * --------------------------------------------------------------------------- */
.u-hero__content { margin-block-start: 0; }
.u-hero__title { margin-block-start: 8px; }
.u-hero__sub { margin-block-start: 16px; }
.u-hero__actions { margin-block-start: 40px; gap: 16px; }   /* design div.hero-cta pad-top 40, gap 16 */

/* profile-header (Member Bio) has its OWN vertical padding in the design, not the shared
   block-vertical-padding: 120/80 desktop, 120/40 tablet, 100/60 mobile. Exposed as custom
   properties so the section override in the spec can reference them per breakpoint. */
:root { --u-profile-pt: 100px; --u-profile-pb: 60px; }

@media (min-width: 768px) {
	:root { --u-profile-pt: 120px; --u-profile-pb: 40px; }
}

@media (min-width: 1200px) {
	:root { --u-profile-pt: 120px; --u-profile-pb: 80px; }
}

/* The hero's 52% column is DESKTOP ONLY. Figma's tablet frame gives the hero wrap the full
   content width; applying the column from 768 squeezed the headline to 349px, wrapped it to four
   lines and stacked the buttons — 813px against a design 647. */
@media (min-width: 1200px) {
	.u-hero--column .u-hero__content {
		max-width: 52%;
		text-align: left;
	}

	.u-hero--column .u-hero__title {
		max-width: min(52%, var(--wp--custom--size--hero-title-max));
	}
}

/* ---------------------------------------------------------------------------
 * profile-header (Member Bio) — portrait beside the name, not above it
 *
 * Figma: div.wrap is HORIZONTAL with a 32 gap on desktop and tablet, VERTICAL on mobile, and the
 * portrait is 300 / 200 / 354 across the three breakpoints. The build stacked at every width and
 * used a fixed 200, which is why the hero measured 496 against a design 367.
 * --------------------------------------------------------------------------- */
/* Mobile stacks portrait over text with the design's 32px gap (Figma div.wrap VERTICAL,
   gap 32). Without it the stack collapsed onto block margins and ran 39px short. */
.u-profile { display: flex; flex-direction: column; gap: 32px; }

/* THE OVERHANG MUST PAINT ABOVE THE NEXT SECTION.
 *
 * Reported as "the member photo is cut off at the bottom", and the natural reading is that
 * something clips it. It does not: measured on /heath-shuler/ the figure has overflow visible, no
 * clipping ancestor, and the rendered box keeps the source aspect ratio (0.997 against a natural
 * 1.000), so nothing is cropping or squashing the image.
 *
 * What happens is OCCLUSION. The negative margin makes the portrait overhang 53px past its
 * section, and the following section — u-surface--accent, an opaque rgb(238,241,245) — begins at
 * exactly that boundary and, being later in the document with no stacking context between them,
 * paints over the overhang. `elementFromPoint` down the middle of the photo returns the IMG at
 * 25/50/75% and the next section at 90/97%: the bottom sixth of the portrait is behind it.
 *
 * Distinguishing the two mattered: a clipping fix (overflow, height, object-fit) would have
 * changed nothing here, because the pixels are drawn and then covered. */
.u-profile__portrait { margin: 0; max-width: 354px; position: relative; z-index: 1; }
.u-profile__portrait img { display: block; width: 100%; height: auto; }

/* ---------------------------------------------------------------------------
 * profile-header (Member Bio) — measured against the Figma frame
 *
 *   desktop  wrap x=360 w=1200 HORIZONTAL gap 32 | avatar 300x300 at x=360 | text x=692 w=868
 *   tablet   wrap x=48  w=672  HORIZONTAL gap 32 | avatar 200x200 at x=48  | text x=280 w=440
 *   mobile   wrap x=24  w=354  VERTICAL   gap 32 | avatar 354x354 at x=24  | text below at x=24
 *
 * Two structural corrections:
 *
 * 1. `.u-profile` IS the section element, and giving it `display: flex` removed core's constrained
 *    layout — which is what centres children at the content width. The portrait was therefore
 *    laid out from the section's padding edge (x=48) rather than the content margin (x=360).
 *    Capping the grid at the content size and centring it restores the design's x=360 without
 *    fighting core.
 *
 * 2. Name and role were siblings in a flex ROW, so they sat side by side — name adrift mid-hero,
 *    role pushed to the far edge. The design stacks them as one block right of the portrait.
 *    Done with grid placement: portrait spans both rows in column 1, name and role take column 2.
 *
 * The portrait still overhangs below the hero (300px tall inside a 167px text row), so its height
 * must stay out of the section's height calculation — hence the negative bottom margin.
 * --------------------------------------------------------------------------- */
.u-profile__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 32px;
	/* A grid is shrink-to-fit, so without this the whole block sized to its content and drifted
	   horizontally with the length of each member's name — six pages, six different positions.
	   width:100% plus core's max-width:contentSize and auto margins puts it at the content edge. */
	width: 100%;
}

.u-profile__portrait { margin: 0; width: 100%; max-width: 354px; }
.u-profile__portrait img { display: block; width: 100%; height: auto; }
.u-profile__grid .u-profile__name { margin: 0; }
.u-profile__grid .u-profile__role { margin: 0; }

@media (min-width: 768px) {
	.u-profile__grid {
		grid-template-columns: auto 1fr;
		grid-template-rows: auto auto;
		align-content: start;
		column-gap: 32px;
		row-gap: 4px;
	}

	.u-profile__portrait {
		grid-column: 1;
		grid-row: 1 / span 2;
		flex: none;
		width: 200px;
		max-width: 200px;
		margin-bottom: -72px;   /* 200 portrait - 128 text row */
		align-self: start;
	}

	.u-profile__grid .u-profile__name { grid-column: 2; grid-row: 1; align-self: end; }
	.u-profile__grid .u-profile__role { grid-column: 2; grid-row: 2; align-self: start; }
}

@media (min-width: 1200px) {
	.u-profile__portrait {
		width: 300px;
		max-width: 300px;
		margin-bottom: -133px;  /* 300 portrait - 167 text row */
	}
}

/* prose-block: the design runs the body to 900px on desktop and to the full content width below,
   with its left edge on the portrait's — the content margin, which .u-maxw supplies. */
.u-prose { max-width: 100%; }

@media (min-width: 1200px) {
	.u-prose { max-width: 900px; }
}


/* ---------------------------------------------------------------------------
 * HEADER RULE — extracted, not guessed
 *
 * It is not a node in the Nav frame: it is a BOTTOM STROKE on the Nav instance itself,
 * rgb(255,255,255) at alpha 0.160 with individualStrokeWeights {bottom: 1}. Alpha 0.160 resolves
 * exactly to the palette's white-16, so it stays inside the token system.
 * --------------------------------------------------------------------------- */
.u-nav { border-bottom: 1px solid var(--wp--preset--color--white-16); }

/* FOOTER RULE — the same treatment, same token, extracted the same way.
 *
 * The Footer instance carries a TOP stroke: rgba(255,255,255,0.160), individualStrokeWeights
 * {top: 1}, strokeAlign INSIDE — identical to the Nav's bottom stroke. Confirmed on both the
 * Homepage and About IMAI desktop frames, and it is present on every page's Footer instance, so
 * it belongs to the template part rather than to any one page.
 *
 * Reported missing by the tester on every page. The nav half of the pair was already implemented
 * and was ALSO not rendering — see the note below on why. */
.u-foot { border-top: 1px solid var(--wp--preset--color--white-16); }

/* WHY THE NAV RULE WAS NOT RENDERING, though it had been correct in this file since it was
 * extracted: a stray `}` sat at what was line 981, left behind by the Member Bio grid rework. It
 * unbalanced the file and the CSS parser consumed the very next rule — this one. Removing it took
 * the parsed selector count from 204 to 205 and restored `.u-nav`.
 *
 * The damage was exactly one rule, not wholesale truncation, which is what made it survive: the
 * page looked fine, every other rule applied, and nothing failed. A missing border is invisible
 * unless someone compares against the design. `toolkit/check-css.mjs` now fails on brace
 * imbalance so this cannot recur silently. */

/* ---------------------------------------------------------------------------
 * ACTIVE NAV ITEM — INFERRED, not extracted.
 *
 * The design does NOT indicate the current page: all five links are fontWeight 500 on every one
 * of the seven frames, including the link matching the frame being viewed. Added anyway because
 * it is a real usability gain and WordPress supplies the class for free, but flagged as inferred
 * alongside the nav hover and the lookup focus ring. Remove if the client wants strict fidelity.
 * --------------------------------------------------------------------------- */
.u-nav .current-menu-item > a { font-weight: 700; }

/* ---------------------------------------------------------------------------
 * DARK SURFACES MUST PAINT A BACKGROUND
 *
 * u-surface--dark set text colours but never a background: the dark ground came only from a
 * gradient fill. A section declaring surface: dark with a SOLID fill therefore rendered
 * near-white text on the page's white default — measured at 1.95:1 on How We Work's band.
 * This fallback means a dark surface can never again render light; an explicit gradient or
 * colour class from the emitter still wins, since both come later in the cascade.
 * --------------------------------------------------------------------------- */
.u-surface--dark { background-color: var(--wp--preset--color--blue-daintree); }

/* stat-band: head centred, stats left (Figma band-navy) */
.u-stats { text-align: left; }

/* ---------------------------------------------------------------------------
 * FAQ — D8 closed
 *
 * Design: div.faq-list carries a 1px TOP rule and each details a 1px BOTTOM rule, both
 * rgb(213,215,221). The summary is a full-width row, Cinzel at the h4 scale (24px), with the
 * toggle pushed to the far right: a 16x16 + when closed, a 23x23 x when open. Both SVGs were
 * extracted and imported in Phase 2 and had never been placed - the disclosure archetype had no
 * marker slot, which is what left D8 open. It now has two.
 *
 * No script: [open] selects which glyph shows. Core's default triangle is suppressed on both the
 * standard and the WebKit pseudo-element.
 * --------------------------------------------------------------------------- */
.u-faq-accordion { border-top: 1px solid var(--wp--preset--color--grey-light-gray); }
.u-faq__item { border-bottom: 1px solid var(--wp--preset--color--grey-light-gray); }

.u-faq__q {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--s-16, 16px);
	padding: var(--wp--preset--spacing--s-24, 24px) 0;
	cursor: pointer;
	list-style: none;
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--h-4);
	line-height: 1.1;
}

.u-faq__q::-webkit-details-marker { display: none; }
.u-faq__q::marker { content: ''; }

.u-faq__toggle { flex: 0 0 auto; display: inline-flex; align-items: center; }
.u-faq__plus { display: block; }
.u-faq__cross { display: none; }
.u-faq__item[open] .u-faq__plus { display: none; }
.u-faq__item[open] .u-faq__cross { display: block; }

.u-faq__item p { margin-block-start: 0; padding-bottom: var(--wp--preset--spacing--s-24, 24px); max-width: 600px; }

/* Footer: design padding is 60/24 with the logo at the top of the content and 24px beneath it. */
.u-foot {
	padding-top: 60px !important;
	padding-bottom: 24px !important;
}

.u-foot__logo { margin: 0 0 var(--wp--preset--spacing--s-24, 24px) 0; }

/* Desktop widens the footer link-column gap to the design's 60. Mobile and tablet keep the 24
   set on .u-foot__cols above. See the note there for why the flat 48 was a latent break. */
@media (min-width: 1200px) {
	.u-foot__cols { gap: 60px; }
}

/* ---------------------------------------------------------------------------
 * people-grid card — matched to the Figma div.person
 *
 * White ground, radius 4, portrait full-bleed across the top, then a padded block holding the
 * name and role on the left with the arrow on the right (div.role: padding 32, gap 16).
 * Name is Cinzel 20 in prussian blue, role Cinzel 13 in bermuda gray.
 *
 * The children are flat, so the block is assembled with grid placement rather than extra markup.
 * --------------------------------------------------------------------------- */
.u-person {
	position: relative;
	display: grid;
	grid-template-columns: 1fr auto;
	background-color: var(--wp--preset--color--white-solid);
	border-radius: var(--wp--custom--radius--r-4);
	overflow: hidden;
}

.u-person__portrait { grid-column: 1 / -1; margin: 0; }
.u-person__portrait img { display: block; width: 100%; height: auto; }

.u-person__name {
	grid-column: 1; grid-row: 2;
	margin: var(--wp--preset--spacing--s-32, 32px) 0 0 var(--wp--preset--spacing--s-32, 32px);
	color: var(--wp--preset--color--blue-prussian-blue);
}

/* Scoped to (0,2,0): `.u-surface--accent p` (0,1,1) sets fiord and out-ranked a bare
   .u-person__role, so the role rendered rgb(74,90,106) against the design's bermuda gray. */
.u-person .u-person__role {
	grid-column: 1; grid-row: 3;
	margin: 4px 0 var(--wp--preset--spacing--s-32, 32px) var(--wp--preset--spacing--s-32, 32px);
	color: var(--wp--preset--color--blue-bermuda-gray);
}

.u-person__arrow {
	grid-column: 2; grid-row: 2 / span 2;
	align-self: center;
	margin: 0 var(--wp--preset--spacing--s-32, 32px) 0 var(--wp--preset--spacing--s-16, 16px);
}

/* One anchor covering the whole card. Keeps the accessible name on a single link instead of
   three competing ones, and leaves the visible arrow purely decorative. */
.u-stretch { position: absolute; inset: 0; z-index: 1; }
/* A PLACEHOLDER MEMBER CARD IS NOT A LINK AND MUST NOT BEHAVE LIKE ONE.
 *
 * Client confirmed 2026-09-25 that only one advisory board member is real. The other five carry no
 * `href`, so the emitter writes no anchor — but the hover treatment is attached to `.u-person`
 * itself, so a card with nothing to click would still respond to the pointer. That is the one part
 * of placeholder rendering that cannot be expressed by omitting a field, which is why `status`
 * reaches the output as a class here and nowhere else.
 *
 * SCOPED, not overridden. The first version kept `.u-person:hover` and undid it with a doubled
 * `.u-person--placeholder.u-person--placeholder:hover { box-shadow: none }`. Scoping the base rule
 * so it never matches a placeholder is better for a reason that outlives this case: "applies, then
 * is reverted" leaves a live rule and a counter-rule, and the next hover property added to the base
 * needs its own counter-rule or it leaks. "Never matches" needs nothing.
 *
 * DOCUMENTED EXCEPTION to the (0,1,0) convention at the top of this file, which says no `:not()`.
 * Taken deliberately: the alternative was the doubled-class override the convention was written to
 * avoid, and the risk the convention guards against — a base rule silently outranking its own
 * modifier — is exactly what scoping removes rather than creates. */
.u-person:not(.u-person--placeholder):hover { box-shadow: 0 0 0 1px var(--wp--preset--color--blue-bermuda-gray); }
.u-person--placeholder { cursor: default; }

/* newsroom corner arrow — design places it on the three short cards (h=209) */
.u-card__arrow { margin: var(--wp--preset--spacing--s-16, 16px) 0 0 0; }

/* Become a Member: the call-to-action line under the H2, beside the form. Same 16px step below a
   title as .u-hero__sub; color comes from .u-surface--light p. */
.u-cta-note { margin-block-start: 16px; }

/* ---------------------------------------------------------------------------
 * Gravity Forms inside a .u-lookup card (Become a Member)
 *
 * No Figma frame exists for this form. Every value is taken from the Verify a Source lookup
 * (.u-field__*), so the two forms on the site share one input treatment: white field on the
 * athens-gray card, r-4 radius, 16/20 padding, mirage text, bermuda-gray focus ring. The submit
 * button gets .wp-element-button from functions.php and takes its styles from theme.json.
 *
 * DOCUMENTED EXCEPTION to the (0,1,0) convention at the top of this file. The markup is Gravity
 * Forms', not ours, and its legacy theme styles inputs at up to (0,6,1)
 * (`.gform_wrapper.gravity-theme input:not(...)x4`). A single class cannot win, and these rules
 * have no modifiers of their own for a combinator to out-rank, which is the risk the convention
 * exists to prevent. Every rule is scoped under .u-gform so nothing leaks to other forms.
 * --------------------------------------------------------------------------- */
.u-gform .gform_wrapper.gravity-theme .gform_fields { row-gap: var(--wp--preset--spacing--s-24, 24px); }

.u-gform .gform_wrapper.gravity-theme .gfield_label,
.u-gform .gform_wrapper.gravity-theme .gfield_label.gform-field-label {
	font: inherit;
	font-weight: 500;
	color: var(--wp--preset--color--blue-mirage);
	margin: 0 0 var(--wp--preset--spacing--s-8, 8px) 0;
}

.u-gform .gform_wrapper.gravity-theme .gform-field-label--type-sub {
	font-size: 0.875em;
	color: var(--wp--preset--color--grey-fiord);
}

.u-gform .gform_wrapper.gravity-theme .gfield_required { color: var(--u-status-expired); }

.u-gform .gform_wrapper.gravity-theme .gfield input[type="text"],
.u-gform .gform_wrapper.gravity-theme .gfield input[type="email"] {
	box-sizing: border-box;
	width: 100%;
	min-height: 0;
	border: 0;
	border-radius: var(--wp--custom--radius--r-4);
	background-color: var(--wp--preset--color--white-solid);
	padding: var(--wp--preset--spacing--s-16, 16px) var(--wp--preset--spacing--s-20, 20px);
	font: inherit;
	line-height: 1.5;
	color: var(--wp--preset--color--blue-mirage);
}

.u-gform .gform_wrapper.gravity-theme .gfield input[type="text"]:focus-visible,
.u-gform .gform_wrapper.gravity-theme .gfield input[type="email"]:focus-visible {
	outline: 2px solid var(--wp--preset--color--blue-bermuda-gray);
	outline-offset: -2px;
}

/* The consent checkbox was removed from the form 2026-10-30 (operator); its rules went with it.
   The opt-in line is now page text beside the form, .u-cta-note. */

/* Below 641px Gravity Forms sets `line-height: 2; min-height: 2rem` through
   `.gform_wrapper.gravity-theme input:not([type=radio]):not([type=checkbox]):not([type=image]):not([type=file])`
   at (0,6,1), which beat the rule above and grew mobile inputs from 56px to 64px (measured
   2026-10-29). Same selector shape, prefixed with .u-gform, so it wins by exactly one class. */
.u-gform .gform_wrapper.gravity-theme input:not([type=radio]):not([type=checkbox]):not([type=image]):not([type=file]) {
	line-height: 1.5;
	min-height: 0;
}

.u-gform .gform_wrapper.gravity-theme .gform_footer { margin: var(--wp--preset--spacing--s-8, 8px) 0 0 0; padding: 0; }

/* The site's buttons compute to an 18px line box at the 15px button size (52px tall); the form
   button inherited 1.5 from the form and measured 57px. */
.u-gform .gform_wrapper.gravity-theme .gform_footer .gform_button { line-height: 1.2; }

/* Validation: the site's own error red, not Gravity Forms' default. */
.u-gform .gform_wrapper.gravity-theme .gfield_error input[type="text"],
.u-gform .gform_wrapper.gravity-theme .gfield_error input[type="email"] { box-shadow: inset 0 0 0 1px var(--u-status-expired); }
.u-gform .gform_wrapper.gravity-theme .validation_message,
.u-gform .gform_wrapper.gravity-theme .gform_validation_errors > h2 { color: var(--u-status-expired); font: inherit; }

/* Field messages as plain text under the field, not Gravity Forms' tinted box: the summary banner
   above the form already carries the visual alarm, and a box per field doubled it. */
.u-gform .gform_wrapper.gravity-theme .gfield_validation_message.validation_message {
	background: none;
	border: 0;
	padding: 0;
	margin: var(--wp--preset--spacing--s-8, 8px) 0 0 0;
	font-size: 0.875em;
}
.u-gform .gform_wrapper.gravity-theme .gform_validation_errors {
	border-color: var(--u-status-expired);
	border-radius: var(--wp--custom--radius--r-4);
	box-shadow: none;
}
.u-gform .gform_wrapper.gravity-theme .gform_validation_errors .gform_submission_error,
.u-gform .gform_wrapper.gravity-theme .gform_validation_error_link { color: var(--u-status-expired); }

.u-gform .gform_confirmation_message { color: var(--wp--preset--color--blue-mirage); }
