/*
 * Only rules theme.json cannot express belong in this file.
 * Design tokens, colours, type and spacing are all declared in theme.json so
 * they reach the editor as well as the front end.
 */

/* ---------- Accessibility ---------- */

.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 999;
	padding: 0.75rem 1.25rem;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--white);
	text-decoration: none;
}

.skip-link:focus {
	left: 0;
}

:where(a, button, input, select, textarea, summary):focus-visible {
	outline: 2px solid var(--wp--preset--color--aim-red);
	outline-offset: 2px;
}

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

.aim-hero {
	position: relative;
	isolation: isolate;
	overflow: hidden;
}

.aim-hero__media,
.aim-hero__media video,
.aim-hero__media img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.aim-hero__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(
		100deg,
		rgba(21, 24, 27, 0.82) 0%,
		rgba(21, 24, 27, 0.62) 45%,
		rgba(21, 24, 27, 0.28) 100%
	);
}

.aim-hero__content {
	position: relative;
}

/*
 * Hero text column. Left-aligned and vertically centred over the video, the
 * heading and subtitle are constrained so they read as a tight, deliberate
 * block rather than stretching the full banner width. `text-wrap: balance`
 * keeps the headline's two lines evenly weighted at any viewport.
 */
/*
 * Note: `.aim-hero .wp-block-cover__inner-container > *` resets max-width:none
 * (specificity 0,2,1) so hero content isn't clamped to the global content size.
 * These overrides therefore target the heading's own `.wp-block-heading` class
 * (0,3,0) and the subtitle's colour class so they out-specify that reset.
 */
.aim-hero .wp-block-cover__inner-container > .wp-block-heading {
	max-width: 20ch;
	text-wrap: balance;
	line-height: 1.08;
	margin-block-end: 1.1rem;
}

/*
 * The post-content measure rule (`.wp-block-post-content .alignfull p:not(...)`,
 * specificity 0,5,1 → 68ch) bleeds into the hero and out-specifies the theme's
 * own intended hero-paragraph width. `!important` is the clean way to hold the
 * subtitle to a tidy column under the headline rather than escalate specificity.
 */
.aim-hero .wp-block-cover__inner-container > p.has-silver-color.has-text-color {
	max-width: 40rem !important;
}

/* A little more air below the subtitle before the call-to-action buttons. */
.aim-hero .wp-block-cover__inner-container > .wp-block-buttons {
	margin-block-start: var(--wp--preset--spacing--40);
}

/*
 * Users who ask for reduced motion get the poster frame instead of the loop.
 * The <video> is also rendered with no autoplay attribute in that case; this
 * is the belt-and-braces half.
 */
@media (prefers-reduced-motion: reduce) {
	.aim-hero__media video {
		display: none;
	}
}

/* ---------- Specification tables ---------- */

.aim-spec {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--wp--preset--font-size--small);
}

.aim-spec th,
.aim-spec td {
	padding: 0.7rem 0.9rem;
	text-align: left;
	border-bottom: 1px solid var(--wp--preset--color--mist);
	vertical-align: top;
}

.aim-spec th {
	font-weight: 500;
	color: var(--wp--preset--color--ink);
	width: 42%;
}

.aim-spec td {
	font-family: var(--wp--preset--font-family--mono);
	color: var(--wp--preset--color--ink-soft);
	font-variant-numeric: tabular-nums;
}

.aim-spec caption {
	caption-side: bottom;
	padding-top: 0.85rem;
	color: var(--wp--preset--color--steel);
	font-size: var(--wp--preset--font-size--x-small);
	text-align: left;
}

/* Wide content must scroll in its own box, never the page body. */
.aim-scroll-x {
	overflow-x: auto;
	max-width: 100%;
}

/* ---------- Eyebrow / technical label ---------- */

.aim-eyebrow {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 500;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: var(--wp--preset--color--aim-red);
	display: block;
	margin-bottom: 0.6rem;
}

/*
 * AIM Red is specified against white. On the near-black hero it measures
 * 3.5:1, under the 4.5:1 WCAG AA floor for small text — and the eyebrow is
 * 13px. The lightened brand tint restores it to 5.4:1.
 */
.aim-hero .aim-eyebrow,
.has-ink-background-color .aim-eyebrow {
	color: var(--wp--preset--color--aim-red-light);
}

/* ---------- Rule accent ---------- */

.aim-rule-accent {
	border: 0;
	border-top: 3px solid var(--wp--preset--color--aim-red);
	width: 48px;
	margin: 0 0 var(--wp--preset--spacing--40);
}

/* ---------- Header / footer chrome ---------- */

.aim-header .wp-block-navigation a {
	text-decoration: none;
	color: #D6DBE0;
}

.aim-header .wp-block-navigation a:hover {
	color: var(--wp--preset--color--white);
}

/*
 * The header needs its own stacking context. Without one the dropdown (z-index
 * 2, scoped to the nav) can be painted over by the hero cover that follows it
 * in document order.
 */
.aim-header {
	position: relative;
	z-index: 20;
}

/* ---------- Desktop dropdown ---------- */

@media (min-width: 782px) {

	/*
	 * The nav is right-justified, so core anchors submenus to the parent's
	 * RIGHT edge (`left:auto; right:0`). With a 200px min-width against a 76px
	 * "Capabilities" item that pushes the panel 112px to the left of its
	 * parent, so it reads as detached. Re-anchor to the left edge.
	 *
	 * Specificity has to clear core's
	 * `.wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child …`
	 * which is (0,5,0).
	 */
	.aim-header .wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child > .wp-block-navigation__submenu-container,
	.aim-header .wp-block-navigation .has-child > .wp-block-navigation__submenu-container {
		left: 0;
		right: auto;
		min-width: 240px;
		padding-block: 0.5rem;
		/* Core's default is rgba(0,0,0,.15) — invisible on a dark panel. */
		border: 1px solid rgba(255, 255, 255, 0.14);
		border-radius: 2px;
		box-shadow: 0 14px 34px rgba(0, 0, 0, 0.4);
		z-index: 30;
	}

	.aim-header .wp-block-navigation__submenu-container li > a {
		padding: 0.62rem 1.15rem;
		font-size: 0.875rem;
		width: 100%;
	}

	.aim-header .wp-block-navigation__submenu-container li > a:hover,
	.aim-header .wp-block-navigation__submenu-container li > a:focus-visible {
		background-color: rgba(255, 255, 255, 0.07);
		color: var(--wp--preset--color--white);
	}
}

/* ---------- Navigation collapse breakpoint ----------
 *
 * Core only swaps the inline nav for the burger below 600px. This nav carries
 * eight items plus the portal link and the quote button; measured at 1200px it
 * still wrapped to a 174px two-line header. So the collapse point is the
 * 1280px content rail — above it the row fits, below it the burger takes over.
 *
 * Undoing core's own `min-width: 600px` rules across that range is all this
 * takes; the overlay itself already works at every width.
 */
@media (min-width: 600px) and (max-width: 1359px) {
	.aim-header .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}

	.aim-header .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}

	.aim-header .wp-block-navigation__responsive-container-close {
		display: flex;
	}
}

/* ---------- Overlay ----------
 * Styled up to the collapse point, not just phone widths, because the burger
 * now appears as high as 1279px.
 */

@media (max-width: 1359px) {

	/*
	 * Overlay items were right-ragged. The cause is core's own custom property
	 * --navigation-layout-justification-setting, which the right-justified nav
	 * sets to flex-end; inside the overlay the layout flips to a column, so
	 * that property now governs the HORIZONTAL axis. Overriding the variable
	 * works with core's rules instead of fighting their specificity.
	 */
	.wp-block-navigation__responsive-container.is-menu-open {
		--navigation-layout-justification-setting: flex-start;
		--navigation-layout-align: flex-start;
		--navigation-layout-justify: flex-start;
	}

	/*
	 * Core reads that variable back at (0,3,0):
	 *   .wp-block-navigation__responsive-container.is-menu-open:where(…) .wp-block-navigation__container
	 *     { align-items: var(--navigation-layout-justification-setting) }
	 * and resolves it against the value set on the outer nav, not the overlay —
	 * so the variable override alone left items at flex-end. Setting the
	 * property directly at (0,4,0) settles it.
	 */
	.aim-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container,
	.aim-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
		align-items: flex-start;
		flex-wrap: nowrap;
		width: 100%;
	}

	/* Tighten the top-level vertical rhythm. Core's 1.4rem blockGap stacked on
	   the 44px tap targets gave a ~66px stride that overflowed the screen and
	   read as loose; 0.35rem brings it to a ~50px stride that still taps well. */
	.aim-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
		gap: 0.35rem;
	}

	.aim-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item {
		width: 100%;
	}

	/* A parent item is a flex ROW by default, so core lays its submenu out to
	   the RIGHT of the label — on a phone that threw the child links into the
	   middle of the screen. Stack the label above its submenu instead. This is
	   the fix for the "layout and spacing" problem in the overlay. */
	.aim-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item.has-child {
		flex-direction: column;
		align-items: flex-start;
	}

	/*
	 * Core pads the overlay with clamp(1rem, var(--wp--style--root--padding-*), 20rem).
	 * Those root-padding variables are empty on this theme, so the clamp is
	 * invalid and the padding computes to 0 — items ran to the screen edge.
	 * Specificity must clear core's `:not(.disable-default-overlay)` at (0,3,0).
	 * Top padding is small — just a margin from the screen edge; the logo-bar
	 * clearance is reserved on the content wrapper below, not here, so the logo
	 * sits at the true top of the overlay instead of floating in a tall void.
	 */
	.aim-header .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
		padding: 1.5rem 1.75rem 2.5rem;
	}

	/* Reserve room at the top of the scrolling content for the absolutely
	   positioned logo + close bar, so the first menu item clears the logo. */
	.aim-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
		padding-top: 4.5rem;
	}

	/* 14px type with 23px rows is neither readable nor tappable. */
	.aim-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item > a,
	.aim-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item > .wp-block-navigation-item__content {
		font-size: 1.125rem;
		min-height: 44px;
		display: flex;
		align-items: center;
		width: 100%;
	}

	/*
	 * Submenu list. Core's block-library CSS loads after the theme and matches
	 * the plain selector at equal specificity, so the theme lost every tie
	 * (measured 32px pad, no guide line). The extra
	 * `.wp-block-navigation__container` qualifier plus !important is what
	 * actually reaches these nodes: a modest indent with a hairline guide, full
	 * width so the drop sits under its parent label, and no inter-item gap.
	 */
	.aim-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container .wp-block-navigation__submenu-container {
		width: 100% !important;
		gap: 0 !important;
		padding: 0.1rem 0 0.35rem 0.95rem !important;
		margin: 0.1rem 0 0.45rem 0.1rem !important;
		border-inline-start: 1px solid rgba(255, 255, 255, 0.22) !important;
		align-items: flex-start;
		text-align: start;
	}

	.aim-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container .wp-block-navigation__submenu-container .wp-block-navigation-item > a {
		font-size: 0.95rem;
		min-height: 38px !important;
		color: var(--wp--preset--color--silver);
		padding: 0.35rem 0.6rem !important;
	}

	/* Vertically centred on the 40px logo (both are positioned against the
	   shared .wp-block-navigation__responsive-dialog context). */
	.aim-header .wp-block-navigation__responsive-container-close {
		top: 1.4rem;
		right: 1.25rem;
	}

	/* ---------- Overlay logo ----------
	 * The site-logo block sits outside the Navigation block, so the open
	 * overlay covers it. inc/setup.php injects the custom-logo <img> as the
	 * first child of the overlay content; here it is pinned top-left to mirror
	 * the close button top-right. `left: 0` aligns it with the menu items (the
	 * overlay's side padding already provides the inset — a non-zero left would
	 * double it and push the logo off-alignment). The base `display:none` lives
	 * OUTSIDE this media query (below the closing brace) so the injected logo is
	 * hidden at every width — desktop included; this rule only re-shows it once
	 * core adds .is-menu-open on the overlay. */
	.aim-header .wp-block-navigation__responsive-container.is-menu-open .aim-overlay-logo {
		display: block;
		position: absolute;
		top: 1rem;
		left: 0;
		margin: 0;
		line-height: 0;
	}

	.aim-header .wp-block-navigation__responsive-container.is-menu-open .aim-overlay-logo a,
	.aim-header .wp-block-navigation__responsive-container.is-menu-open .aim-overlay-logo img {
		display: block;
	}

	.aim-header .wp-block-navigation__responsive-container.is-menu-open .aim-overlay-logo img {
		height: 40px;
		width: auto;
		max-width: none;
	}

	/* Stop the page scrolling behind the open overlay. WordPress puts
	   has-modal-open on <html>, not <body> — targeting body silently did
	   nothing. Both are covered here in case that changes. */
	html.has-modal-open,
	html.has-modal-open body {
		overflow: hidden;
	}
}

/* Overlay logo is injected into every nav render (see inc/setup.php) but must
   only ever appear inside the open burger overlay. Hide it globally here — the
   max-width media query above re-shows it under .is-menu-open. Without this the
   full-size logo renders inline in the desktop nav. */
.aim-header .aim-overlay-logo {
	display: none;
}

.aim-header .wp-block-site-logo img {
	height: 60px;
	width: auto;
}

/* ---------- Customer portal link ----------
 *
 * A utility link, not a nav item and not a second CTA. The hairline separates
 * it from the navigation so it reads as a different kind of destination, and
 * the padlink glyph signals "sign in" without needing an icon font.
 */
.aim-portal-link {
	margin: 0;
	font-size: 0.875rem;
	font-weight: 500;
	white-space: nowrap;
	padding-inline-start: 1.4rem;
	border-inline-start: 1px solid rgba(255, 255, 255, 0.18);
}

.aim-portal-link a {
	color: var(--wp--preset--color--silver);
	text-decoration: none;
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	transition: color 160ms cubic-bezier(.2, .6, .3, 1);
}

.aim-portal-link a::before {
	content: "";
	width: 11px;
	height: 13px;
	flex: none;
	background-color: currentColor;
	/* Padlock, inlined as a mask so it inherits the link colour on hover. */
	-webkit-mask: var(--aim-lock) center / contain no-repeat;
	mask: var(--aim-lock) center / contain no-repeat;
}

:root {
	--aim-lock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 13'%3E%3Cpath d='M2 5V3.5a3.5 3.5 0 1 1 7 0V5h.5A1.5 1.5 0 0 1 11 6.5v5A1.5 1.5 0 0 1 9.5 13h-8A1.5 1.5 0 0 1 0 11.5v-5A1.5 1.5 0 0 1 1.5 5H2Zm1.5 0h4V3.5a2 2 0 1 0-4 0V5Z'/%3E%3C/svg%3E");
}

.aim-portal-link a:hover,
.aim-portal-link a:focus-visible {
	color: var(--wp--preset--color--white);
}

/* ---------- Mobile header bar ----------
 *
 * Placed after the logo and portal rules above so it overrides them; equal
 * specificity means source order decides.
 *
 * At 375px the logo (151px), burger and CTA (168px) exceeded the 335px of
 * usable width and wrapped the bar onto three rows — 174px tall. Trimming the
 * logo and tightening the CTA keeps it to one row while preserving the quote
 * button, which is the header's whole job.
 */
@media (max-width: 781px) {
	.aim-header .wp-block-site-logo img {
		height: 44px;
	}

	/*
	 * The default 28px block-gap between logo / nav / portal / CTA was itself
	 * enough to force the wrap once the elements fit. Tightening it buys the
	 * ~30px needed to hold one row at 375px.
	 */
	.aim-header .wp-block-group {
		gap: 0.75rem;
	}

	.aim-header .wp-block-button__link {
		padding: 0.65rem 0.8rem;
		font-size: 0.75rem;
	}

	/* Portal collapses to its padlock; the label is kept for screen readers
	   rather than dropped, so the link stays reachable on mobile. */
	.aim-header .aim-portal-link {
		display: block;
		padding-inline-start: 0.85rem;
		border-inline-start-color: rgba(255, 255, 255, 0.14);
	}

	.aim-header .aim-portal-link a {
		font-size: 0;
		gap: 0;
	}

	.aim-header .aim-portal-link a::before {
		width: 14px;
		height: 16px;
	}
}

/*
 * Small phones (320px and similar). Even compacted, logo + portal + burger +
 * CTA came to 297px against 280px of usable width and wrapped to 129px. The
 * portal padlock is the one element that can go: it remains in the overlay's
 * reach via the footer, whereas the quote CTA is the header's whole purpose.
 */
@media (max-width: 389px) {
	.aim-header .aim-portal-link {
		display: none;
	}

	.aim-header .wp-block-site-logo img {
		height: 38px;
	}

	.aim-header .wp-block-button__link {
		padding: 0.6rem 0.7rem;
		font-size: 0.6875rem;
	}

	.aim-header .wp-block-group {
		gap: 0.5rem;
	}
}

/*
 * The footer's own container sits on the 1280px rail, but the groups inside it
 * are constrained too — so core centred the legal paragraph at contentSize
 * while the logo above it stayed on the rail. Align footer content left, same
 * as the body.
 */
/* Footer sits on the same 1280px rail as the header and body bands. */
.aim-footer {
	padding-inline: max(var(--aim-gutter), calc((100% - var(--aim-rail)) / 2));
}

.aim-footer .wp-block-group > *,
.aim-footer .wp-block-column > * {
	margin-inline: 0 !important;
	max-width: none;
}

.aim-footer .aim-legal {
	max-width: 90ch;
}

.aim-footer__heading {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 500;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: var(--wp--preset--color--white);
}

.aim-footer .wp-block-navigation a {
	text-decoration: none;
}

/* Header is 60px. 48px reads as a deliberate step down rather than a shrunken
   copy — 38px looked like an afterthought. */
.aim-footer .wp-block-site-logo img {
	height: 54px;
	width: auto;
}

.aim-contact-block {
	font-style: normal;
	line-height: 1.75;
	font-size: var(--wp--preset--font-size--small);
}

.aim-legal {
	font-size: var(--wp--preset--font-size--x-small);
	line-height: 1.75;
	color: var(--wp--preset--color--steel);
}

/* ---------- Vacancies (aim-careers plugin) ---------- */

/*
 * Rendered by [aim_vacancies]. Styled here rather than in the plugin so the
 * listing inherits the theme's tokens and looks native, while the Job content
 * type and its data stay in the plugin where they outlive the theme.
 */
.aim-vacancies {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--wp--preset--spacing--40, 1.5rem);
}

.aim-vacancy {
	padding: var(--wp--preset--spacing--40, 1.5rem);
	border: 1px solid var(--wp--preset--color--mist);
	border-top: 3px solid var(--wp--preset--color--aim-red);
	background: var(--wp--preset--color--white);
}

.aim-vacancy__title {
	margin: 0 0 0.25rem;
}

.aim-vacancy__title a {
	text-decoration: none;
}

.aim-vacancy__meta {
	margin: 0 0 0.5rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--x-small);
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--steel);
}

.aim-vacancy__summary {
	margin: 0 0 0.75rem;
	color: var(--wp--preset--color--ink-soft);
}

.aim-vacancy__closing {
	margin: 0 0 0.75rem;
	font-size: var(--wp--preset--font-size--x-small);
	color: var(--wp--preset--color--steel);
}

.aim-vacancy__closing--ongoing {
	color: var(--wp--preset--color--aim-red);
}

.aim-vacancy__actions {
	margin: 0;
}

.aim-vacancy__apply {
	display: inline-flex;
	align-items: center;
	gap: 0.55rem;
	padding: 0.8rem 1.6rem;
	background: var(--wp--preset--color--aim-red);
	color: var(--wp--preset--color--white);
	text-decoration: none;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 500;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	border-radius: 2px;
	box-shadow: 0 6px 18px rgba(218, 0, 36, 0.24);
	transition: background-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

/* Arrow reinforces the call to action and nudges forward on hover. */
.aim-vacancy__apply::after {
	content: "\2192";
	font-size: 1.05em;
	line-height: 1;
	transition: transform 0.15s ease;
}

.aim-vacancy__apply:hover,
.aim-vacancy__apply:focus-visible {
	background: var(--wp--preset--color--aim-red-dark);
	transform: translateY(-1px);
	box-shadow: 0 10px 26px rgba(218, 0, 36, 0.32);
}

.aim-vacancy__apply:hover::after,
.aim-vacancy__apply:focus-visible::after {
	transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {
	.aim-vacancy__apply,
	.aim-vacancy__apply::after {
		transition: none;
	}
}

.aim-vacancies-empty {
	color: var(--wp--preset--color--ink-soft);
}

/* ---------- Accessible-only text ---------- */

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ---------- Section rhythm ---------- */

/*
 * Full-bleed bands are what give the page its sectioned feel. Without them
 * every section sits in the 760px content column and the page reads as one
 * long undifferentiated document.
 *
 * WordPress applies a negative left margin to cancel the container's gutter,
 * but the element's width does not expand to match, leaving the band short by
 * the gutter on each side. Setting margin-inline and letting width resolve to
 * auto fixes it, and stays correct as the clamp() gutter changes with viewport.
 */
:root {
	--aim-gutter: clamp(1.25rem, 4vw, 2.5rem);
}

/*
 * Scoped to post-content deliberately. Bands placed directly in <main> by a
 * template are already full width — <main> uses flow layout with no gutter —
 * so applying the negative margin there pushes them past the viewport and
 * causes sideways scroll on mobile.
 */
.wp-block-post-content > .alignfull {
	margin-inline: calc(-1 * var(--aim-gutter));
	width: auto;
	max-width: none;
}

main > .alignfull {
	margin-inline: 0;
	width: auto;
	max-width: none;
}

/*
 * Bands placed by a template (the capability spec table, its CTA, the Insights
 * archive) sit directly in <main> rather than inside post-content, and core
 * centres their children at contentSize. Two problems came from that: their
 * left edge (340px) differed from content bands (80px), AND — because the band
 * children were centred on the rail — any child NARROWER than the rail (a
 * measure-capped paragraph, capped to 72ch) floated to the centre instead of
 * sitting on the left edge with the heading and button beside it.
 *
 * Pad the band to the rail and left-align every child, exactly as the page
 * header does. A capped paragraph then stays on the left edge; full-width
 * children (heading, buttons) fill the rail. One left edge, no floating.
 */
main > .alignfull:not(.aim-page-header) {
	padding-inline: max(var(--aim-gutter), calc((100% - var(--aim-rail)) / 2));
}

main > .alignfull:not(.aim-page-header) > * {
	margin-inline: 0 !important;
}

/*
 * Two consecutive light bands (spec table then CTA) would otherwise read as
 * one block. A hairline keeps them legible as separate sections without
 * resorting to a third background colour, which would only reintroduce the
 * Surface-vs-Mist "too similar to notice" problem.
 */
main > .alignfull + .alignfull:not(.has-ink-background-color) {
	border-top: 1px solid var(--wp--preset--color--mist);
}

.wp-block-group.alignfull > .wp-block-group__inner-container {
	width: 100%;
}

/* ---------- Vertical rhythm ----------
 *
 * WordPress emits `.is-layout-flow > * + * { margin-block-start: <blockGap> }`
 * at specificity (0,1,0). A bare `main h2` selector is (0,0,2) and loses, which
 * is why every gap on the page measured an identical 16px regardless of what
 * sat either side of it. Scoping each rule to a class lifts it to (0,1,1) so it
 * wins, and lets the relationships actually differ:
 *
 *   eyebrow → heading   tight   — they are one unit
 *   heading → body      close
 *   body    → grid      medium
 *   section → new h3    wide    — a genuine break
 */

/*
 * Header, main and footer each supply their own padding, so the block-gap
 * WordPress inserts between them renders as a stray white strip — most
 * obviously between the header and a full-bleed hero, which should meet it
 * flush.
 */
.wp-site-blocks > * {
	margin-block-start: 0;
	margin-block-end: 0;
}

/*
 * Every full-bleed band already sets its own top/bottom padding as the sole
 * source of vertical spacing. Core's flow-layout gap rule
 * (`.is-layout-flow > * + *`) additionally puts a 28px margin-top on each one
 * regardless — measured as a real, visible seam of the WRONG band's colour at
 * every single section boundary on every page, not a rounding artefact.
 */
main .alignfull,
.aim-page-header.alignfull,
main > .wp-block-post-content {
	margin-block: 0 !important;
}

.aim-section > :first-child,
.wp-block-group__inner-container > :first-child,
.wp-block-cover__inner-container > :first-child,
.alignfull > :first-child {
	margin-block-start: 0;
}

.alignfull > :last-child,
.wp-block-group__inner-container > :last-child {
	margin-block-end: 0;
}

/* An eyebrow labels the heading below it — keep them visually bound. */
.alignfull .aim-eyebrow,
.wp-block-cover .aim-eyebrow {
	margin-block: 0 var(--wp--preset--spacing--20);
}

/*
 * An H2 that OPENS a band needs no top margin (the band padding does that job),
 * but a second H2 within the same band — e.g. "Production Volumes" following
 * the Materials paragraph — is a new subsection and must be clearly separated
 * from the content above it, or the two run together.
 */
.alignfull h2 {
	margin-block: var(--wp--preset--spacing--60) var(--wp--preset--spacing--30);
}

.alignfull > h2:first-child,
.alignfull > .aim-eyebrow:first-child + h2 {
	margin-block-start: 0;
}

/* A subsection heading needs real separation from the block above it. */
.alignfull h3 {
	margin-block: var(--wp--preset--spacing--50) var(--wp--preset--spacing--20);
}

.alignfull > h3:first-child {
	margin-block-start: 0;
}

/* Lists and grids sit slightly further from the text that introduces them. */
.alignfull :is(ul, ol, .wp-block-columns, .aim-scroll-x) {
	margin-block-start: var(--wp--preset--spacing--40);
}

/* Cards carry their own internal rhythm — the section rules must not leak in. */
.alignfull .aim-card :is(h2, h3) {
	margin-block: 0 var(--wp--preset--spacing--20);
}

.alignfull .aim-card :is(p, ul) {
	margin-block-start: 0;
}

/*
 * Deliberately NOT setting margin-block-start here. The card is a flex column
 * and the link uses `margin-top: auto` to sit against the bottom edge, so a row
 * of cards aligns on its links regardless of how long each body runs. A rhythm
 * rule at this specificity would override that and break the alignment.
 */

/* ---------- One left edge ----------
 *
 * A constrained layout centres EVERY child at contentSize independently. So a
 * heading lands at 760px wide (left edge 332px), a card grid at 1280px (left
 * edge 72px) and the hero at 880px (left edge 272px) — three different indents
 * running down the same page, which is what makes a layout look accidental.
 *
 * Instead: centre one wide container per band, then align all its children to
 * that container's left edge. Running text is then limited by max-width rather
 * than by centring, so every element shares a left rail while the right edge
 * varies naturally with content.
 *
 * The !important is required because core sets margin-inline: auto !important
 * on constrained children — specificity alone cannot override it.
 */
/*
 * Modern WordPress renders group children directly — there is no
 * .wp-block-group__inner-container — so the band itself has to establish the
 * rail. Padding it to a centred wide box means every child starts at the same
 * left edge without any of them being centred individually.
 */
/* Literal rather than --wp--style--global--wide-size: that custom property is
   not reliably resolvable inside calc() in this scope, and silently collapsed
   the rail to the gutter width. */
:root {
	--aim-rail: 1280px;
}

/*
 * Percentage padding resolves against the CONTAINING BLOCK, not the element's
 * own box — and the band is wider than its container by one gutter each side
 * (the negative margin that makes it full-bleed). Adding the gutter back gives
 * the true centred rail, which is the same 1280px rail the header and footer
 * template parts use, so the logo and the hero headline line up.
 */
.wp-block-post-content > .alignfull {
	padding-inline: max(
		var(--aim-gutter),
		calc((100% - var(--aim-rail)) / 2 + var(--aim-gutter))
	);
}

.aim-hero .wp-block-cover__inner-container {
	max-width: var(--aim-rail);
	margin-inline: auto;
	width: 100%;
}

.wp-block-post-content > .alignfull > *,
.aim-hero .wp-block-cover__inner-container > * {
	margin-inline: 0 !important;
	max-width: none;
}

/*
 * A card is itself a constrained group, so core centres its children too —
 * which left the numeral and the card heading centred above left-aligned body
 * copy. Everything in a card aligns left.
 */
.aim-card > * {
	margin-inline: 0 !important;
	max-width: none;
}

/*
 * Measures, re-applied above the reset. Specificity must exceed
 * `.wp-block-post-content > .alignfull > *` (0,2,0), hence the extra class.
 * Long single-line headings at 42px read as sprawling.
 */
.wp-block-post-content .alignfull h2 {
	max-width: 22ch;
}

.wp-block-post-content .alignfull h3 {
	max-width: 30ch;
}

.wp-block-post-content .alignfull .aim-list-2col,
.wp-block-post-content .alignfull .aim-chips,
.wp-block-post-content .alignfull .aim-steps--row {
	max-width: 62rem;
}

/* ---------- Measure ----------
 *
 * Running text was setting at 89 characters per line. The comfortable range is
 * 60–75; past that the eye struggles to find the start of the next line. The
 * content column stays 760px so headings, grids and spec tables keep their
 * width — only running copy is measured.
 *
 * ch scales with font-size, so the larger lead gets a deliberately tighter
 * character count than body copy rather than a wider one.
 */
.wp-block-post-content .alignfull p:not(.aim-eyebrow):not(.aim-trustline):not(.aim-card__link),
.aim-hero p:not(.aim-eyebrow):not(.aim-trustline) {
	max-width: 68ch;
}

/* Lead paragraph (1.3125rem) — larger type wants fewer characters. */
.wp-block-post-content .alignfull p[style*="font-size:1.3125rem"] {
	max-width: 52ch;
}

/* Lists inside a band still need their own measure once the reset clears it.
   Grid and chip lists are full-width layouts, not running text — exclude them. */
.wp-block-post-content .alignfull > ul:not(.aim-list-2col):not(.aim-chips):not(.aim-steps--row) {
	max-width: 68ch;
}

/*
 * Intro copy under an H2 reads as a deck, not body text — but only on light
 * grounds. Ink Soft on any dark band is unreadable: it measured 2.0:1 on the
 * red CTA. Every coloured ground must be excluded explicitly, so new ones are
 * an obvious edit rather than a silent contrast failure.
 */
.alignfull:not(.has-ink-background-color):not(.has-aim-red-background-color):not(.has-aim-red-dark-background-color) h2 + p {
	color: var(--wp--preset--color--ink-soft);
}

/* ---------- Page header ---------- */

/*
 * Pad the band to the rail and left-align its children, rather than letting
 * the constrained layout centre them. Centring is what pushed the 792px H1 to
 * 317px while the full-width breadcrumbs sat at 73px — the two elements of the
 * same header on different left edges.
 */
.aim-page-header.alignfull {
	padding-inline: max(var(--aim-gutter), calc((100% - var(--aim-rail)) / 2));
}

/*
 * !important is required, not laziness: core ships
 *   .is-layout-constrained > :where(…) { margin-left: auto !important }
 * so no specificity can win. Scoped to this band only, exactly as done for the
 * hero — constrained centring still applies everywhere else.
 */
.aim-page-header.alignfull > * {
	margin-inline: 0 !important;
	max-width: none;
	width: auto;
}

.aim-page-header h1,
.aim-page-header .wp-block-post-title {
	margin-block: var(--wp--preset--spacing--30) 0;
	max-width: 22ch;
	letter-spacing: -0.025em;
}

.aim-breadcrumbs ol {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--x-small);
	letter-spacing: 0.04em;
}

.aim-breadcrumbs li {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.aim-breadcrumbs li + li::before {
	content: "\203A";
	opacity: 0.5;
}

.aim-breadcrumbs a {
	color: var(--wp--preset--color--silver);
	text-decoration: none;
}

.aim-breadcrumbs a:hover,
.aim-breadcrumbs a:focus-visible {
	color: var(--wp--preset--color--white);
	text-decoration: underline;
}

.aim-breadcrumbs [aria-current="page"] {
	color: var(--wp--preset--color--white);
}

/* ---------- Measure ----------
 *
 * Band paragraphs ran the full 1280px rail — 82ch on the Capabilities intro,
 * well past the ~75ch where the eye starts losing its place returning to the
 * next line. Cards and grids set their own width so are left alone.
 */
.alignfull > p,
.alignfull > .wp-block-group > p {
	max-width: 72ch;
}

/* ---------- Feature image (in a content column) ---------- */

.aim-feature-img {
	margin: 0;
}

.aim-feature-img img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 2px;
	box-shadow: 0 2px 4px rgba(21, 24, 27, .08), 0 12px 32px rgba(21, 24, 27, .10);
}

/* ---------- Cards ---------- */

.aim-card {
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--mist);
	border-radius: 2px;
	/* Slightly more than the 28px step: a card needs its content held away
	   from the rule, and 28px reads cramped at this type size. */
	padding: 2rem 1.75rem;
	height: 100%;
	display: flex;
	flex-direction: column;
	transition: box-shadow 160ms cubic-bezier(.2, .6, .3, 1), border-color 160ms;
}

/* Push the card's link to the bottom so a row of cards aligns on its links
   even when the body copy runs to different lengths. */
.alignfull .aim-card .aim-card__link,
.aim-card .aim-card__link {
	margin-block-start: auto;
	padding-block-start: var(--wp--preset--spacing--30);
}

.aim-card:hover {
	border-color: var(--wp--preset--color--silver);
	box-shadow: 0 2px 4px rgba(21, 24, 27, .08), 0 12px 32px rgba(21, 24, 27, .10);
}

.aim-card > :first-child { margin-block-start: 0; }
.aim-card > :last-child  { margin-block-end: 0; }

.aim-card h3 {
	font-size: 1.1875rem;
	line-height: 1.3;
	margin-block: 0 0.6rem;
}

/*
 * Card copy is set smaller than body text: a card column is ~240px, and 17px
 * type only fits ~28 characters there, which reads choppy. 15px lifts it to a
 * more even rag. Declared here rather than per-block because the generator
 * writes block attributes without the matching classes.
 */
.aim-card p:not(.aim-eyebrow):not(.aim-card__link) {
	font-size: 0.9375rem;
	line-height: 1.6;
	color: var(--wp--preset--color--steel);
	max-width: none;
}

/* The numeral eyebrow is an index, not a label — keep it quiet. */
.aim-card .aim-eyebrow {
	font-size: 0.75rem;
	letter-spacing: 0.12em;
}

.aim-card .aim-eyebrow {
	color: var(--wp--preset--color--aim-red);
	margin-bottom: 0.75rem;
}

.aim-card__link a {
	font-size: 0.875rem;
	font-weight: 600;
	text-decoration: none;
}

.aim-card__link a:hover { text-decoration: underline; }

/* Columns must stack, not squash, on narrow screens. */
@media (max-width: 781px) {
	.wp-block-columns:not(.is-not-stacked-on-mobile) > .wp-block-column {
		flex-basis: 100% !important;
	}
}

/* ---------- Long specification lists ---------- */

/*
 * Short scannable lists laid out as an even GRID, not CSS `columns`.
 *
 * `columns` flowed items into uneven stacks — 7 items became 3/3/1, leaving a
 * lone item marooned beside empty space, which read as broken rather than
 * designed. A grid fills row by row: every column is the same width, items
 * align both horizontally and vertically, and a trailing item sits under its
 * neighbours instead of alone in a half-empty column.
 *
 * auto-fill with a min track means the column COUNT follows the available
 * width — no manual breakpoints, and it can never produce a widow column.
 */
.aim-list-2col {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
	gap: 0.55rem var(--wp--preset--spacing--50);
	padding-left: 0;
}

.aim-list-2col li {
	margin: 0;
	padding-left: 1.5rem;
	position: relative;
	list-style: none;
}

/* Consistent square-dash marker so the removed list bullet still reads as a
   list, aligned with the text baseline. */
.aim-list-2col li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.62em;
	width: 0.5rem;
	height: 1px;
	background: var(--wp--preset--color--aim-red);
}

/* ---------- Chip lists ---------- */

/*
 * A compact alternative to `.aim-list-2col` for scannable, non-sequential sets
 * (materials, operations, applications). Rendered as a real <ul> so it still
 * reads as a list; each item becomes a pill. Halves the vertical space a long
 * dashed list takes and reads as distinct from running copy.
 */
.aim-chips {
	list-style: none;
	padding-left: 0;
	margin: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.aim-chips li {
	margin: 0;
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.44rem 0.8rem;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.25;
	color: var(--wp--preset--color--ink-soft);
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--mist);
	border-radius: 100px;
	transition: border-color 150ms, color 150ms;
}

.aim-chips li::before {
	content: "";
	width: 0.4rem;
	height: 0.4rem;
	border-radius: 100px;
	background: var(--wp--preset--color--aim-red);
	flex: 0 0 auto;
}

.aim-chips li:hover {
	border-color: var(--wp--preset--color--aim-red);
	color: var(--wp--preset--color--ink);
}

/* A surface band already sits on #F4F6F7, so chips there use white to lift. */
.has-surface-background-color .aim-chips li {
	background: var(--wp--preset--color--white);
}

/* ---------- Stat callouts ---------- */

/*
 * Headline figures pulled out of card copy so the key envelope reads at a
 * glance. Sits at the foot of an `.aim-card`, above nothing else, divided from
 * the body copy by a hairline.
 */
.aim-stat-row {
	display: flex;
	flex-wrap: wrap;
	gap: 1.1rem 1.6rem;
	margin-block-start: auto;
	padding-block-start: 1rem;
	border-block-start: 1px solid var(--wp--preset--color--mist);
}

.aim-stat__n {
	display: block;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 1.3rem;
	line-height: 1;
	font-weight: 600;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
	font-variant-numeric: tabular-nums;
}

.aim-stat__l {
	display: block;
	margin-block-start: 0.34rem;
	font-size: 0.68rem;
	text-transform: uppercase;
	letter-spacing: 0.11em;
	color: var(--wp--preset--color--steel);
}

/*
 * Hero variant: a stand-alone stat strip (single-machine capability pages),
 * not a card footer — so it needs no auto top margin, a wider gap, and slightly
 * larger figures to carry a section on its own.
 */
.aim-stat-row--strip {
	margin-block-start: 0;
	gap: 1.3rem 2.6rem;
}

.aim-stat-row--strip .aim-stat__n {
	font-size: 1.6rem;
}

/* ---------- Grouped specification cards ---------- */

/*
 * When spec rows carry a "Group :: Label" prefix, [aim_spec_table] renders one
 * card per group instead of a single flat table — each machine's figures held
 * together. Ungrouped pages keep the `.aim-spec` table above.
 */
.aim-spec-cards {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
	gap: var(--wp--preset--spacing--40, 1.1rem);
}

.aim-spec-card {
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--mist);
	border-radius: 2px;
	padding: 1.4rem 1.4rem 0.6rem;
}

.aim-spec-card__title {
	margin: 0 0 0.5rem;
	padding-block-end: 0.6rem;
	border-block-end: 1px solid var(--wp--preset--color--mist);
	font-size: 1rem;
	font-weight: 600;
	color: var(--wp--preset--color--ink);
}

.aim-spec-card__list {
	margin: 0;
}

.aim-spec-card__row {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 1rem;
	padding-block: 0.62rem;
	border-block-end: 1px solid var(--wp--preset--color--mist);
}

.aim-spec-card__row:last-child {
	border-block-end: 0;
}

.aim-spec-card__row dt {
	margin: 0;
	color: var(--wp--preset--color--steel);
	font-size: var(--wp--preset--font-size--small);
}

.aim-spec-card__row dd {
	margin: 0;
	text-align: right;
	white-space: nowrap;
	font-family: var(--wp--preset--font-family--mono);
	color: var(--wp--preset--color--ink-soft);
	font-variant-numeric: tabular-nums;
}

.aim-spec__note {
	margin-block-start: 1rem;
	color: var(--wp--preset--color--steel);
	font-size: var(--wp--preset--font-size--x-small);
}

/* ---------- Numbered process steps ---------- */

/*
 * A responsive flow of numbered tiles for a genuine sequence (the manufacturing
 * route). The number is generated with a CSS counter, so markup carries only the
 * copy. Tiles are white — put the band on `surface` so they lift.
 */
.aim-steps {
	list-style: none;
	padding-left: 0;
	margin: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 13.5rem), 1fr));
	gap: 1rem;
	counter-reset: aim-step;
}

.aim-steps > li {
	margin: 0;
	display: flex;
	flex-direction: column;
	padding: 1.25rem 1.3rem 1.4rem;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--mist);
	border-radius: 2px;
}

.aim-steps > li::before {
	counter-increment: aim-step;
	content: counter(aim-step, decimal-leading-zero);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 1.5rem;
	line-height: 1;
	font-weight: 600;
	color: var(--wp--preset--color--aim-red);
	font-variant-numeric: tabular-nums;
	margin-bottom: 0.7rem;
}

.aim-steps__t {
	font-weight: 600;
	margin-bottom: 0.25rem;
}

.aim-steps__d {
	color: var(--wp--preset--color--steel);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.5;
}

/*
 * Row variant: keep a short flow (e.g. a 4-step "how we work") on a single line
 * on desktop, stepping down to 2-up then 1-up on narrower screens. Widened to
 * 62rem above so four tiles fit comfortably.
 */
.aim-steps--row {
	grid-template-columns: repeat(4, 1fr);
}

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

@media (max-width: 520px) {
	.aim-steps--row {
		grid-template-columns: 1fr;
	}
}

/* ---------- Traceability chain ---------- */

/*
 * A linked thread of nodes joined by accent arrows — reads as the traceability
 * chain itself. Mono type gives it a "data" feel. Designed to sit on the dark
 * ink band, where the arrow switches to the on-dark red.
 */
.aim-chain {
	list-style: none;
	padding-left: 0;
	margin: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.45rem 0.7rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.9rem;
}

.aim-chain > li {
	margin: 0;
	display: inline-flex;
	align-items: center;
	gap: 0.7rem;
}

.aim-chain > li:not(:last-child)::after {
	content: "\2192";
	color: var(--wp--preset--color--aim-red);
	font-weight: 600;
}

.has-ink-background-color .aim-chain > li:not(:last-child)::after {
	color: var(--wp--preset--color--aim-red-light);
}

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

/*
 * The Cover block writes its min-height inline (min-height:88vh on the element),
 * and an inline style beats a class selector — so this rule must be !important
 * to remain the single source of truth for hero height. Keep this value and the
 * block's minHeight in bin/restyle-content.php (aimb_hero) in step.
 */
.aim-hero {
	min-height: 88vh !important;
}

.aim-hero .wp-block-cover__video-background {
	object-fit: cover;
}

/*
 * The constrained layout centres EACH child independently, so an eyebrow, an
 * H1 and a lead paragraph with different max-widths all end up with different
 * left edges — the block reads as misaligned rather than as one unit. Centre
 * the container once, then left-align everything inside it against a shared
 * edge.
 */
.aim-hero .aim-eyebrow {
	color: var(--wp--preset--color--aim-red-light);
}

.aim-hero h1 {
	max-width: 15ch;
	letter-spacing: -0.025em;
}

/* Measure applies to running copy only — never to the single-line eyebrow or
   the trust line, which were being clamped to 406px and wrapping badly. */
.aim-hero p:not(.aim-eyebrow):not(.aim-trustline) {
	max-width: 46ch;
}

.aim-trustline {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--x-small);
	letter-spacing: 0.04em;
	color: var(--wp--preset--color--silver);
	border-top: 1px solid rgba(255, 255, 255, .16);
	padding-top: var(--wp--preset--spacing--30);
	margin-top: var(--wp--preset--spacing--50);
	max-width: none;
}

/* Outline button needs to read on a dark ground. */
.aim-btn-ghost .wp-block-button__link {
	color: var(--wp--preset--color--white);
	border-color: rgba(255, 255, 255, .45);
}

.aim-btn-ghost .wp-block-button__link:hover {
	background: rgba(255, 255, 255, .1);
	border-color: var(--wp--preset--color--white);
}

@media (prefers-reduced-motion: reduce) {
	.aim-hero .wp-block-cover__video-background { display: none; }
}

/* ---------- Dark bands ---------- */

/*
 * Headings default to Ink, which on an Ink band renders invisible. Anything
 * sitting on a dark ground has to be forced light — this is a safety net so a
 * missing colour class can never produce unreadable text.
 */
.has-ink-background-color :is(h1, h2, h3, h4, h5),
.wp-block-cover :is(h1, h2, h3, h4, h5) {
	color: var(--wp--preset--color--white);
}

.has-ink-background-color :is(li, p) {
	color: var(--wp--preset--color--silver);
}

.has-ink-background-color strong,
.has-ink-background-color a {
	color: var(--wp--preset--color--white);
}

.has-ink-background-color h6 {
	color: var(--wp--preset--color--silver);
}

/* ---------- Red CTA band ----------
 *
 * White on AIM Red measures 5.2:1 — comfortably AA. Silver would be only
 * 3.1:1, so everything on this ground is white, not the Silver used on Ink.
 */
.has-aim-red-background-color :is(h1, h2, h3, h4, h5, p, li, strong) {
	color: var(--wp--preset--color--white);
}

.has-aim-red-background-color .aim-eyebrow {
	color: var(--wp--preset--color--white);
	opacity: 0.75;
}

/* A red button on a red ground would vanish — invert it. */
.has-aim-red-background-color .wp-block-button__link {
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
}

.has-aim-red-background-color .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--white);
}

.has-aim-red-background-color .wp-block-button__link:focus-visible {
	outline: 2px solid var(--wp--preset--color--white);
	outline-offset: 2px;
}

/* ---------- Request-a-Quote form ----------
 *
 * The form is a self-contained card, constrained to a readable width and left
 * aligned on the rail. At full 1280px the fields stretched edge to edge, which
 * read as sparse and unscannable; a form wants ~46rem and a defined boundary.
 */
.aim-rfq {
	/* !important on both: the rail-reset rule
	   `.wp-block-post-content > .alignfull > * { max-width:none }` (0,2,0) and
	   core's constrained centring both outrank a plain .aim-rfq (0,1,0). */
	max-width: 46rem !important;
	margin: var(--wp--preset--spacing--40) 0 0;
	margin-inline: 0 !important;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--mist);
	border-radius: 3px;
	box-shadow: 0 1px 2px rgba(21, 24, 27, .04), 0 10px 30px rgba(21, 24, 27, .05);
	padding: clamp(1.5rem, 3vw, 2.75rem);
}

/* Honeypot — visually and programmatically gone, but present in the DOM. */
.aim-rfq-hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.aim-rfq-section {
	margin: 0;
	padding: 0;
	min-width: 0;
}

/* Generous space before each new section; the heading's own rule provides the
   visual separation, so no extra divider line is needed. */
.aim-rfq-section + .aim-rfq-section {
	margin-top: var(--wp--preset--spacing--50);
}

/*
 * Section heading. A div + <p> heading (not <legend>) so spacing is
 * predictable — the legend's fieldset-padding quirk was throwing a 76px gap
 * between the heading and its fields. A trailing hairline rule gives the small
 * mono label real presence and doubles as the section separator; the fields sit
 * tight beneath it so heading and group read as one unit.
 */
.aim-rfq-legend {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	margin: 0 0 var(--wp--preset--spacing--30);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--aim-red);
}

.aim-rfq-legend::after {
	content: "";
	flex: 1;
	height: 1px;
	background: var(--wp--preset--color--mist);
}

.aim-rfq-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--40) var(--wp--preset--spacing--40);
}

.aim-rfq-field--wide {
	grid-column: 1 / -1;
}

@media (max-width: 620px) {
	.aim-rfq-grid { grid-template-columns: 1fr; }
}

/* Field label — scoped so it does NOT hit the checkbox row label below. */
.aim-rfq-field > label:not(.aim-rfq-check) {
	display: block;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
	margin-bottom: 0.45rem;
}

.aim-rfq-req {
	color: var(--wp--preset--color--aim-red);
	font-weight: 400;
}

.aim-rfq-field :is(input, select, textarea) {
	box-sizing: border-box;
	width: 100%;
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink);
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--silver);
	border-radius: 2px;
	transition: border-color 160ms cubic-bezier(.2, .6, .3, 1), box-shadow 160ms;
}

/* Single-line controls share one exact height so a select never sits 4px
   short of the text input beside it. */
.aim-rfq-field :is(input, select) {
	height: 3rem;
	padding: 0 0.85rem;
}

/* Native select chevron, so it doesn't look like a text box. */
.aim-rfq-field select {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 2.25rem;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%233A4046' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 0.9rem center;
}

.aim-rfq-field textarea {
	padding: 0.7rem 0.85rem;
	resize: vertical;
	min-height: 8rem;
	line-height: 1.55;
}

.aim-rfq-field :is(input, select, textarea):focus {
	outline: none;
	border-color: var(--wp--preset--color--aim-red);
	box-shadow: 0 0 0 3px rgba(218, 0, 36, 0.12);
}

.aim-rfq-field--error :is(input, select, textarea) {
	border-color: var(--wp--preset--color--danger);
	background: #fdf5f5;
}

/* Consent / NDA checkbox row. */
.aim-rfq-field .aim-rfq-check {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 0.75rem;
	align-items: start;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 400;
	line-height: 1.5;
	color: var(--wp--preset--color--ink-soft);
	cursor: pointer;
	margin: 0;
}

.aim-rfq-check input {
	width: 1.2rem;
	height: 1.2rem;
	margin: 0.1rem 0 0;
	accent-color: var(--wp--preset--color--aim-red);
	flex: none;
}

.aim-rfq-check a {
	color: var(--wp--preset--color--aim-red);
	text-decoration: underline;
}

/* Slightly tighter gap between the two consent rows than between fields. */
.aim-rfq-field.aim-rfq-field--wide + .aim-rfq-field--wide .aim-rfq-check {
	margin-top: 0;
}

.aim-rfq-error {
	background: #fdf5f5;
	border: 1px solid var(--wp--preset--color--danger);
	border-radius: 2px;
	padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40);
	margin-bottom: var(--wp--preset--spacing--40);
	color: var(--wp--preset--color--danger);
	font-size: var(--wp--preset--font-size--small);
}

.aim-rfq-error p {
	margin: 0.4rem 0 0;
}

.aim-rfq-submit {
	margin-top: var(--wp--preset--spacing--50);
	padding-top: var(--wp--preset--spacing--50);
	border-top: 1px solid var(--wp--preset--color--mist);
}

.aim-rfq-button {
	background: var(--wp--preset--color--aim-red);
	color: var(--wp--preset--color--white);
	border: 0;
	border-radius: 2px;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.01em;
	padding: 0.95rem 2.25rem;
	cursor: pointer;
	transition: background 160ms cubic-bezier(.2, .6, .3, 1);
}

.aim-rfq-button:hover {
	background: var(--wp--preset--color--aim-red-dark);
}

.aim-rfq-button:focus-visible {
	outline: 2px solid var(--wp--preset--color--ink);
	outline-offset: 2px;
}

.aim-rfq-note {
	font-size: var(--wp--preset--font-size--x-small);
	color: var(--wp--preset--color--steel);
	line-height: 1.6;
	margin: var(--wp--preset--spacing--30) 0 0;
}

/* ---------- Reassurance aside (beside the form on desktop) ----------
 *
 * A dark panel that fills the space to the right of the form card. Sticky on
 * desktop so it stays in view down the long form; the flow stacks it below the
 * form on narrow screens, where sticky simply has no room to act.
 */
.aim-rfq-aside {
	position: sticky;
	top: 2rem;
	background: var(--wp--preset--color--ink);
	border-radius: 3px;
	padding: clamp(1.75rem, 2.5vw, 2.5rem);
}

.aim-rfq-aside::before {
	content: "";
	display: block;
	width: 30px;
	height: 34px;
	background-color: var(--wp--preset--color--aim-red-light);
	-webkit-mask: var(--aim-lock) center / contain no-repeat;
	mask: var(--aim-lock) center / contain no-repeat;
	margin-bottom: var(--wp--preset--spacing--40);
}

.aim-rfq-aside__label {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--aim-red-light);
	margin: 0 0 var(--wp--preset--spacing--30);
}

.aim-rfq-aside p:not(.aim-rfq-aside__label) {
	color: var(--wp--preset--color--silver);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.7;
	margin: 0;
}

.aim-rfq-aside strong {
	color: var(--wp--preset--color--white);
	font-weight: 600;
}

/* On mobile the aside follows the form; give it clear separation. */
@media (max-width: 781px) {
	.aim-rfq-aside {
		position: static;
		margin-top: var(--wp--preset--spacing--40);
	}
}

/* Success state after submission. */
.aim-rfq-success {
	max-width: 46rem;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--mist);
	border-left: 3px solid var(--wp--preset--color--success);
	border-radius: 3px;
	padding: clamp(1.5rem, 3vw, 2.75rem);
}

.aim-rfq-success h2 {
	margin-block: var(--wp--preset--spacing--20) var(--wp--preset--spacing--30) !important;
}

.aim-rfq-success p {
	max-width: 62ch;
}

.aim-rfq-success p:last-child {
	margin-bottom: 0;
}

/* ---------- Contact page ----------
 *
 * Two columns on the rail: the message form (a self-contained card) beside a
 * quieter details column — address, hours and a location map. The form carries
 * the visual weight; the details column stays airy so the address and phone are
 * the first things the eye lands on.
 */
/* The template's post-content carries no vertical padding — pages that open and
   close with full-bleed bands supply their own. This page's content is plain, so
   the wrapper gives it breathing room: clear of the dark header band above and
   well clear of the footer below (otherwise the form card's border touches it). */
.aim-contact-intro {
	padding-block: var(--wp--preset--spacing--60) var(--wp--preset--spacing--70);
}

.aim-contact-cols {
	align-items: start;
}

/* Intro sits in the same wide group as the columns; cap its measure for a
   comfortable line length but keep its left edge on the rail, aligned with the
   form column beneath it. Without this it renders at content-width (760px) and
   floats ~260px in from the form's left edge — the misalignment reads as sloppy. */
.aim-contact-lead {
	max-width: 60ch;
	margin-inline: 0 !important;
}

/* The form card already sets its own top margin; the h2 above it supplies the
   label, so pull the card up tight under that heading. */
.aim-contact-cols .aim-rfq {
	margin-top: var(--wp--preset--spacing--30);
}

.aim-contact-aside > :first-child {
	margin-top: 0 !important;
}

/* Address reads larger here than in the compact footer, and the phone/email
   are the primary actions, so give them weight. */
.aim-contact-aside .aim-contact-block {
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.95;
}

.aim-contact-aside .aim-contact-block a {
	font-weight: 500;
}

/* Opening hours: a scannable day/time list, days left and times right. */
.aim-hours {
	margin-top: var(--wp--preset--spacing--40);
}

.aim-hours__label {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
	margin: 0 0 0.5rem;
}

.aim-hours__list {
	margin: 0;
	display: grid;
	gap: 0.4rem;
	max-width: 22rem;
}

.aim-hours__row {
	display: flex;
	justify-content: space-between;
	gap: 1.5rem;
	font-size: var(--wp--preset--font-size--small);
}

.aim-hours__row dt {
	margin: 0;
	color: var(--wp--preset--color--ink-soft);
}

.aim-hours__row dd {
	margin: 0;
	color: var(--wp--preset--color--ink);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.aim-hours__row--closed dd {
	color: var(--wp--preset--color--steel);
}

/* ---------- Location map ---------- */

.aim-map {
	margin: var(--wp--preset--spacing--40) 0 0;
}

.aim-map__frame {
	display: block;
	width: 100%;
	height: 340px;
	border: 1px solid var(--wp--preset--color--mist);
	border-radius: 3px;
	background: var(--wp--preset--color--surface);
	/* An OSM embed sets its own light background; the border defines the edge. */
}

.aim-map__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40);
	margin-top: var(--wp--preset--spacing--30);
	font-size: var(--wp--preset--font-size--small);
}

.aim-map__link {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	font-weight: 500;
	text-decoration: none;
	color: var(--wp--preset--color--aim-red);
}

.aim-map__link:hover {
	text-decoration: underline;
}

.aim-map__link:not(.aim-map__link--muted)::after {
	content: "\2192"; /* → */
	transition: transform var(--wp--custom--transition--base, 160ms);
}

.aim-map__link:not(.aim-map__link--muted):hover::after {
	transform: translateX(2px);
}

.aim-map__link--muted {
	color: var(--wp--preset--color--steel);
	font-weight: 400;
}

@media (max-width: 781px) {
	.aim-map__frame {
		height: 280px;
	}
}

/* ---------- FAQ accordion ---------- */

/*
 * A plain <details>/<summary> accordion for aim-core's [aim_faq] shortcode —
 * works with no JavaScript. Deliberately mirrors the careers FAQ so the two
 * read as one system, but is styled from theme tokens because the careers
 * stylesheet is only loaded on careers pages. The default disclosure triangle
 * is replaced with a brand chevron that flips open.
 */
.aim-faq__list {
	margin-top: var(--wp--preset--spacing--40);
	border-top: 1px solid var(--wp--preset--color--mist);
}

.aim-faq__item {
	border-bottom: 1px solid var(--wp--preset--color--mist);
}

.aim-faq__q {
	position: relative;
	list-style: none;
	cursor: pointer;
	padding: 1.15rem 2.5rem 1.15rem 0;
	font-weight: 600;
	font-size: var(--wp--preset--font-size--medium, 1.125rem);
	line-height: 1.4;
	color: var(--wp--preset--color--ink);
	transition: color 160ms ease;
}

.aim-faq__q::-webkit-details-marker {
	display: none;
}

.aim-faq__q:hover,
.aim-faq__item[open] .aim-faq__q {
	color: var(--wp--preset--color--aim-red);
}

/* Chevron built from two borders; rotates from pointing-down to pointing-up. */
.aim-faq__q::after {
	content: "";
	position: absolute;
	right: 0.35rem;
	top: 1.5rem;
	width: 0.65rem;
	height: 0.65rem;
	border-right: 2px solid var(--wp--preset--color--aim-red);
	border-bottom: 2px solid var(--wp--preset--color--aim-red);
	transform: rotate(45deg);
	transition: transform 200ms ease;
}

.aim-faq__item[open] .aim-faq__q::after {
	transform: rotate(-135deg);
}

.aim-faq__a {
	padding: 0 2.5rem 1.3rem 0;
}

.aim-faq__a p {
	margin: 0;
	max-width: 70ch;
	color: var(--wp--preset--color--ink-soft);
	line-height: 1.7;
}

@media (prefers-reduced-motion: reduce) {
	.aim-faq__q::after {
		transition: none;
	}
}

/* ---------- Print ---------- */

@media print {
	.aim-hero__media,
	.aim-hero__scrim,
	nav,
	.skip-link {
		display: none !important;
	}

	body {
		color: #000;
		background: #fff;
	}

	a[href]::after {
		content: " (" attr(href) ")";
		font-size: 0.85em;
		word-break: break-all;
	}
}
