/**
 * JV engineering — single stylesheet.
 *
 * Colours, fonts and spacing come from theme.json as --wp--preset--* custom
 * properties; they are aliased once below so the rest of the file stays short.
 * Change a colour in theme.json and it changes here, in the editor and in the
 * customiser at the same time.
 *
 * Contents
 *   1. Tokens & reset          6. Cards, steps, specs, figures
 *   2. Layout helpers          7. Tabs
 *   3. Buttons                 8. Team
 *   4. Header & navigation     9. Forms & notices
 *   5. Hero slider            10. Footer, editor, print
 */

/* ------------------------------------------------------------------ 1. */

:root {
	--c-base: var(--wp--preset--color--base, #fff);
	--c-surface: var(--wp--preset--color--surface, #f4f6f4);
	--c-surface-alt: var(--wp--preset--color--surface-alt, #e7ebe8);
	--c-line: var(--wp--preset--color--line, #d5dbd7);
	--c-muted: var(--wp--preset--color--text-muted, #5c6663);
	--c-text: var(--wp--preset--color--text, #1d2220);
	--c-dark: var(--wp--preset--color--dark, #262b29);
	--c-primary: var(--wp--preset--color--primary, #3f6b52);
	--c-primary-dark: var(--wp--preset--color--primary-dark, #2c4c3a);
	--c-primary-light: var(--wp--preset--color--primary-light, #dce7de);
	--c-accent: var(--wp--preset--color--accent, #8fb59b);

	/* Square by default. Photographs of real plant, simulation renders and
	   drawings are the content; rounding their corners frames them as
	   interface tiles instead of as pictures. Only controls keep a hairline
	   radius, so a focus ring does not look like a rendering fault. */
	--radius-sm: 2px;
	--radius: 2px;
	--radius-lg: 0px;
	/* A hairline, not a float. Nothing on this site hovers above the page. */
	--shadow-sm: 0 1px 0 rgb(29 34 32 / 10%);
	--shadow-md: 0 1px 0 rgb(29 34 32 / 14%);
	--header-h: 76px;
	--gutter: clamp(1.25rem, 4vw, 2.5rem);
	--section-y: clamp(2rem, 4vw, 3.5rem);
	--ring: 0 0 0 2px rgb(63 107 82 / 45%);
	--ease: cubic-bezier(0.4, 0, 0.2, 1);
}

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	scroll-behavior: smooth;
	scroll-padding-top: calc(var(--header-h) + 1rem);
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--c-base);
	color: var(--c-text);
	font-family: var(--wp--preset--font-family--system, system-ui, sans-serif);
	font-size: 1.0625rem;
	line-height: 1.65;
	-webkit-font-smoothing: antialiased;
}

img,
svg,
video {
	max-width: 100%;
	height: auto;
	display: block;
}

a {
	color: var(--c-primary);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
}

a:hover {
	color: var(--c-primary-dark);
}

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
	outline: 2px solid var(--c-primary);
	outline-offset: 2px;
	border-radius: 4px;
}

h1, h2, h3, h4 {
	margin: 0 0 0.6em;
	line-height: 1.22;
	font-weight: 700;
}

p, ul, ol, dl {
	margin: 0 0 1.1em;
}

p:last-child,
ul:last-child,
ol:last-child {
	margin-bottom: 0;
}

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

.skip-link {
	position: absolute;
	top: -100px;
	left: 1rem;
	z-index: 200;
	padding: 0.75rem 1.25rem;
	background: var(--c-primary);
	color: #fff;
	text-decoration: none;
	transition: top 0.15s var(--ease);
}

.skip-link:focus {
	top: 0;
	color: #fff;
}

/* ------------------------------------------------------------------ 2. */

.wrap {
	width: 100%;
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.wrap--wide {
	max-width: 1220px;
}

.wrap--narrow {
	max-width: 800px;
}

.site-main {
	display: block;
	min-height: 40vh;
}

.section {
	padding-block: var(--section-y);
}

.section--surface {
	background: var(--c-surface);
}

.section--dark {
	background: var(--c-dark);
	color: #e9edea;
}

.section--dark h2,
.section--dark h3 {
	color: #fff;
}

.section--green {
	background: var(--c-primary-light);
}

.section__head {
	max-width: 46rem;
	margin-bottom: clamp(1.25rem, 2.5vw, 2rem);
}

/* Body copy sitting directly in a wide band still gets a readable measure. */
.section .wrap > p,
.section .wrap > ul,
.section .wrap > ol {
	max-width: 68ch;
}

/* No rule, bar or eyebrow above the heading: a section is announced by its
   own words and by the band it sits in. The decorative accent dash that used
   to sit here repeated on every heading of every page, which is precisely
   what made the page read as a template rather than as a document. */
.section__title {
	font-size: clamp(1.45rem, 2.2vw, 1.9rem);
	margin-bottom: 0.4em;
}

.section__lead {
	color: var(--c-muted);
	font-size: 1.0625rem;
	margin: 0;
	text-wrap: pretty;
}

.section--dark .section__lead {
	color: #b9c4bd;
}

.page-head {
	background: var(--c-surface);
	border-bottom: 1px solid var(--c-line);
	padding-block: clamp(2.25rem, 4.5vw, 3.5rem);
}

.page-head__title {
	font-size: clamp(1.75rem, 3.2vw, 2.35rem);
	margin-bottom: 0.35em;
	max-width: 24ch;
}

.page-head__sub {
	color: var(--c-muted);
	font-size: 1.0625rem;
	max-width: 52ch;
	margin: 0;
	text-wrap: pretty;
}

.entry__content > * + * {
	margin-top: 1.15em;
}

.entry__content--full > * {
	margin-top: 0;
}

.wrap.entry__content,
.entry__content.wrap--narrow {
	padding-block: var(--section-y);
}

.entry__content :where(h2) {
	margin-top: 1.8em;
}

.entry__content :where(h3) {
	margin-top: 1.4em;
}

.entry__content :where(ul, ol) {
	padding-left: 1.3em;
}

.entry__content :where(li) + :where(li) {
	margin-top: 0.4em;
}

/* ------------------------------------------------------------------ 3. */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 0.8rem 1.5rem;
	border: 1px solid transparent;
	border-radius: var(--radius-sm);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.2;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 0.16s var(--ease), color 0.16s var(--ease),
		border-color 0.16s var(--ease);
}

.btn--sm {
	padding: 0.55rem 1.05rem;
	font-size: 0.9375rem;
}

.btn--primary {
	background: var(--c-primary);
	color: #fff;
}

.btn--primary:hover {
	background: var(--c-primary-dark);
	color: #fff;
}

.btn--ghost {
	border-color: var(--c-line);
	color: var(--c-text);
	background: transparent;
}

.btn--ghost:hover {
	border-color: var(--c-primary);
	color: var(--c-primary);
	background: var(--c-primary-light);
}

.btn--light {
	background: #fff;
	color: var(--c-primary-dark);
}

.btn--light:hover {
	background: var(--c-primary-light);
	color: var(--c-primary-dark);
}

/* ------------------------------------------------------------------ 4. */

.site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--c-base);
	border-bottom: 1px solid var(--c-line);
	transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
}

.site-header__inner {
	display: flex;
	align-items: center;
	gap: 1.5rem;
	min-height: var(--header-h);
}

/* Transparent over the hero, solid once the page scrolls. */
.has-hero-slider .site-header {
	position: fixed;
	inset-inline: 0;
	background: transparent;
	border-bottom-color: transparent;
}

.has-hero-slider .site-header:not(.is-stuck) {
	color: #fff;
}

.has-hero-slider .site-header:not(.is-stuck) .brand,
.has-hero-slider .site-header:not(.is-stuck) .site-nav__list > li > a {
	color: #fff;
}

.has-hero-slider .site-header:not(.is-stuck) .brand__tagline {
	color: rgb(255 255 255 / 78%);
}

/* Solid, not frosted: the header either is over the hero or it is not. */
.has-hero-slider .site-header.is-stuck {
	background: var(--c-base);
	border-bottom-color: var(--c-line);
}

.brand {
	display: inline-flex;
	align-items: center;
	gap: 0.7rem;
	color: var(--c-text);
	text-decoration: none;
	margin-right: auto;
}

.brand__mark {
	color: var(--c-primary);
	flex: none;
}

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

.brand__name {
	font-weight: 700;
	font-size: 1.0625rem;
	letter-spacing: -0.01em;
}

.brand__tagline {
	font-size: 0.75rem;
	color: var(--c-muted);
	letter-spacing: 0.02em;
}

.custom-logo-link {
	margin-right: auto;
}

.site-nav {
	display: flex;
	align-items: center;
	gap: 1.6rem;
}

/* Six top-level items, so the spacing is a little tighter than the theme's
   default rhythm. Tighten further before adding a seventh. */
.site-nav__list {
	display: flex;
	align-items: center;
	gap: 1.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-nav__list a {
	color: var(--c-text);
	text-decoration: none;
	font-weight: 550;
	font-size: 0.9625rem;
	white-space: nowrap;
	padding-block: 0.4rem;
	position: relative;
}

.site-nav__list a::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 2px;
	border-radius: 2px;
	background: currentcolor;
	opacity: 0;
	transform: scaleX(0.4);
	transition: opacity 0.16s var(--ease), transform 0.16s var(--ease);
}

.site-nav__list a:hover::after,
.site-nav__list .current-menu-item > a::after,
.site-nav__list .current_page_item > a::after,
.site-nav__list .current-menu-ancestor > a::after,
.site-nav__list .current_page_ancestor > a::after {
	opacity: 1;
	transform: scaleX(1);
}

/* Sub-menus. One level deep — header.php asks wp_nav_menu for depth 2.
   Opened on hover and on :focus-within, so it needs no JavaScript and still
   works from the keyboard. Inside the mobile panel it is simply always open. */

.site-nav__list li {
	position: relative;
}

.site-nav__list .menu-item-has-children > a::before {
	content: "";
	position: absolute;
	right: -0.8rem;
	top: 50%;
	width: 0.34rem;
	height: 0.34rem;
	border-right: 2px solid currentcolor;
	border-bottom: 2px solid currentcolor;
	transform: translateY(-75%) rotate(45deg);
	opacity: 0.5;
}

.site-nav__list .sub-menu {
	position: absolute;
	top: 100%;
	left: -1rem;
	z-index: 20;
	min-width: 15rem;
	margin: 0;
	padding: 0.4rem 0;
	list-style: none;
	background: var(--c-base);
	border: 1px solid var(--c-line);
	border-radius: var(--radius);
	box-shadow: var(--shadow-md);
	opacity: 0;
	visibility: hidden;
	transform: translateY(-4px);
	transition: opacity 0.16s var(--ease), transform 0.16s var(--ease), visibility 0.16s;
}

.site-nav__list li:hover > .sub-menu,
.site-nav__list li:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.site-nav__list .sub-menu a {
	display: block;
	padding: 0.55rem 1rem;
	color: var(--c-text);
	font-weight: 500;
	line-height: 1.35;
}

.site-nav__list .sub-menu a::after {
	display: none;
}

/* Items that belong to the entry above them. wp_nav_menu is capped at depth 2,
   so a third level cannot be rendered; these carry the nav-subitem class from
   seed.sh and are indented to show what they hang off. */
.site-nav__list .sub-menu .nav-subitem > a {
	padding-left: 2rem;
	font-size: 0.9125rem;
	color: var(--c-muted);
}

.site-nav__list .sub-menu .nav-subitem > a::before {
	content: "";
	position: absolute;
	left: 1rem;
	top: 50%;
	transform: translateY(-50%);
	width: 0.5rem;
	height: 1px;
	background: currentcolor;
	opacity: 0.45;
}

.site-nav__list .sub-menu a:hover,
.site-nav__list .sub-menu a:focus-visible,
.site-nav__list .sub-menu .current-menu-item > a {
	background: var(--c-surface);
	color: var(--c-primary-dark);
}

.nav-toggle {
	display: none;
	margin-left: auto;
	width: 44px;
	height: 44px;
	padding: 0;
	background: transparent;
	border: 1px solid var(--c-line);
	border-radius: var(--radius);
	color: inherit;
	cursor: pointer;
}

.nav-toggle__bars {
	display: grid;
	gap: 4px;
	justify-items: center;
}

.nav-toggle__bars span {
	display: block;
	width: 18px;
	height: 2px;
	background: currentcolor;
	border-radius: 2px;
	transition: transform 0.2s var(--ease), opacity 0.2s var(--ease);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1) {
	transform: translateY(6px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2) {
	opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3) {
	transform: translateY(-6px) rotate(-45deg);
}

/* Six top-level items plus the CTA button need roughly 1170px before they stop
   wrapping onto two lines, so the panel takes over earlier than the width of a
   phone would suggest. */

@media (max-width: 1160px) {
	.nav-toggle {
		display: grid;
		place-items: center;
	}

	.site-nav {
		position: absolute;
		inset-inline: 0;
		top: 100%;
		display: none;
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		padding: 0.5rem var(--gutter) 1.5rem;
		background: var(--c-base);
		border-bottom: 1px solid var(--c-line);
		box-shadow: var(--shadow-md);
	}

	.site-nav.is-open {
		display: flex;
	}

	.site-nav__list {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
	}

	.site-nav__list li + li {
		border-top: 1px solid var(--c-line);
	}

	.site-nav__list a,
	.has-hero-slider .site-header:not(.is-stuck) .site-nav__list > li > a {
		display: block;
		padding: 0.9rem 0;
		color: var(--c-text);
		font-size: 1.0625rem;
	}

	.site-nav__list .menu-item-has-children > a::before {
		display: none;
	}

	.site-nav__list .sub-menu {
		position: static;
		min-width: 0;
		padding: 0 0 0.5rem;
		background: transparent;
		border: 0;
		border-radius: 0;
		box-shadow: none;
		opacity: 1;
		visibility: visible;
		transform: none;
	}

	.site-nav__list .sub-menu li + li {
		border-top: 0;
	}

	.site-nav__list .sub-menu a {
		padding: 0.5rem 0 0.5rem 1rem;
		font-size: 1rem;
		color: var(--c-muted);
	}

	.site-nav__list .sub-menu .nav-subitem > a {
		padding-left: 2.25rem;
		font-size: 0.9375rem;
	}

	.site-nav__cta {
		margin-top: 1rem;
	}
}

/* ------------------------------------------------------------------ 5. */

.hero {
	position: relative;
	background: var(--c-dark);
}

.hero__viewport {
	overflow: hidden;
}

.hero__track {
	display: block;
}

.hero__slide {
	position: relative;
	display: grid;
	align-items: end;
	min-height: clamp(380px, 58vh, 540px);
	isolation: isolate;
}

.hero__image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	z-index: -2;
}

.hero__scrim {
	position: absolute;
	inset: 0;
	z-index: -1;
	/* Two neutral darkening passes, both grey: one down the frame so the
	   transparent header and the headline hold contrast, one in from the
	   leading edge so the text column does. The green diagonal wash that used
	   to sit here tinted the photograph towards the brand colour, which is a
	   poster treatment, not a photograph of a machine. */
	background:
		linear-gradient(180deg, rgb(29 34 32 / 62%) 0%, rgb(29 34 32 / 18%) 34%, rgb(29 34 32 / 78%) 100%),
		linear-gradient(90deg, rgb(29 34 32 / 55%) 0%, rgb(29 34 32 / 0%) 58%);
}

.hero__content {
	position: relative;
	padding-block: clamp(3rem, 8vh, 5.5rem);
	padding-inline-start: clamp(1.5rem, 3vw, 2.5rem);
	color: #fff;
	max-width: 1220px;
}

/* A viewfinder corner, not a decoration borrowed from a generic template —
   it reads as camera framing, which is what the company actually does. */
.hero__content::before {
	content: "";
	position: absolute;
	top: 0.35em;
	left: 0;
	width: 22px;
	height: 38px;
	border-left: 1.5px solid rgb(255 255 255 / 55%);
	border-top: 1.5px solid rgb(255 255 255 / 55%);
}

.hero__title {
	font-size: clamp(1.75rem, 3.4vw, 2.5rem);
	color: #fff;
	margin-bottom: 0.4em;
	max-width: 22ch;
}

.hero__sub {
	font-size: clamp(1rem, 1.2vw, 1.125rem);
	max-width: 56ch;
	color: rgb(255 255 255 / 92%);
	margin-bottom: 1.5rem;
	text-wrap: pretty;
}

.hero__actions {
	margin: 0;
}

/* Slideshow state, added by site.js. Without JS all slides simply stack.
   The track becomes a one-cell grid so every slide overlaps in the same place
   and the hero keeps the height of its tallest slide. */
.hero.is-live .hero__track {
	display: grid;
}

.hero.is-live .hero__slide {
	grid-area: 1 / 1;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.35s var(--ease), visibility 0.35s var(--ease);
}

.hero.is-live .hero__slide.is-active {
	opacity: 1;
	visibility: visible;
	z-index: 1;
}

/* A slide change is a cross-fade. The staggered rise-and-fade that used to
   run on the headline, lead and button of every incoming slide is the motion
   signature of a generated landing page, and it says nothing about the work.
   `is-entering` is still set by site.js; nothing is bound to it. */

.hero__controls {
	position: absolute;
	z-index: 2;
	right: var(--gutter);
	bottom: clamp(1.25rem, 4vh, 2.25rem);
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.hero__arrow {
	width: 40px;
	height: 40px;
	display: grid;
	place-items: center;
	border: 1px solid rgb(255 255 255 / 40%);
	background: rgb(29 34 32 / 45%);
	color: #fff;
	cursor: pointer;
	transition: background-color 0.16s var(--ease), border-color 0.16s var(--ease);
}

.hero__arrow:hover {
	background: var(--c-primary);
	border-color: var(--c-primary);
}

.hero__dots {
	display: flex;
	gap: 0.4rem;
	padding-inline: 0.35rem;
}

.hero__dot {
	width: 9px;
	height: 9px;
	padding: 0;
	border: 0;
	background: rgb(255 255 255 / 40%);
	cursor: pointer;
	transition: background-color 0.16s var(--ease);
}

.hero__dot[aria-selected="true"] {
	background: #fff;
}

@media (max-width: 600px) {
	.hero__arrow {
		display: none;
	}

	.hero__controls {
		left: var(--gutter);
		right: auto;
	}
}

/* ------------------------------------------------------------------ 6. */

.cards {
	display: grid;
	gap: clamp(1rem, 2vw, 1.5rem);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

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

	.cards--cols-3 {
		grid-template-columns: repeat(3, 1fr);
	}

	.cards--cols-4 {
		grid-template-columns: repeat(4, 1fr);
	}
}

.card {
	--card-pad: clamp(1.35rem, 2.4vw, 1.9rem);
	position: relative;
	background: var(--c-base);
	border: 1px solid var(--c-line);
	border-radius: var(--radius-lg);
	padding: var(--card-pad);
	transition: border-color 0.16s var(--ease);
}

/* Hover marks the border, nothing more. A card that lifts off the page and
   casts a shadow is a UI tile; these are catalogue entries. */
.card:hover {
	border-color: var(--c-primary);
}

.section--surface .card {
	background: var(--c-base);
}

.section--dark .card {
	background: rgb(255 255 255 / 5%);
	border-color: rgb(255 255 255 / 14%);
	color: #dfe6e2;
}

/* A card is a fixed-width grid cell, so — unlike a figure — its picture fills
   the cell and is cropped to one ratio: a small source must not set the card's
   height, and a row of cards has to line up. Every source is wider than a card
   even at four columns, so filling the width never upscales. The media bleeds
   past the card padding to the top and side edges, clipped by the card radius
   (less its 1px border), for a plain catalogue look. */

.card__media {
	margin: calc(var(--card-pad) * -1) calc(var(--card-pad) * -1) var(--card-pad);
	overflow: hidden;
	background: var(--c-surface);
}

.card__media-img {
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
}

.section--dark .card__media {
	background: rgb(255 255 255 / 5%);
}

/* The icon is a small mark set in the copy, not a badge. The tinted rounded
   tile it used to sit in is the app-icon motif every generated page reaches
   for, and it gave a decorative glyph more weight than the card's title. */
.card__icon {
	display: block;
	width: 22px;
	height: 22px;
	margin-bottom: 0.9rem;
	color: var(--c-muted);
}

.card__icon svg {
	width: 22px;
	height: 22px;
}

.section--dark .card__icon {
	color: var(--c-accent);
}

/* Sentence case. A letterspaced all-caps eyebrow over every card title is
   marketing furniture; this is a label, and it reads as one. */
.card__meta {
	font-size: 0.8125rem;
	font-weight: 600;
	color: var(--c-muted);
	margin-bottom: 0.35rem;
}

.card__title {
	font-size: 1.1875rem;
	margin-bottom: 0.5rem;
}

.card__title a {
	text-decoration: none;
	color: inherit;
}

.card__title a::after {
	content: "";
	position: absolute;
	inset: 0;
}

.card__title a:hover {
	color: var(--c-primary);
}

.card__body {
	color: var(--c-muted);
	font-size: 1rem;
	text-wrap: pretty;
}

.section--dark .card__body {
	color: #b9c4bd;
}

.steps {
	list-style: none;
	counter-reset: step;
	margin: 0;
	padding: 0;
	display: grid;
	gap: clamp(1rem, 2vw, 1.5rem);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

/* A numbered list, set as one. The circled figure joined to the next by a
   rail is the "our process" timeline every template ships with, and it does
   not survive a column count of two, three or four without lying about which
   step follows which. */
.steps__item {
	counter-increment: step;
	padding-top: 1rem;
	border-top: 1px solid var(--c-line);
}

.steps__item::before {
	content: counter(step) ".";
	display: block;
	margin-bottom: 0.4rem;
	font-size: 0.9375rem;
	font-weight: 700;
	color: var(--c-primary);
}

.steps__title {
	font-size: 1.125rem;
	margin-bottom: 0.4rem;
}

.steps__body {
	color: var(--c-muted);
	font-size: 1rem;
}

.specs {
	margin: 0;
	border-top: 1px solid var(--c-line);
}

.specs__row {
	display: grid;
	gap: 0.25rem 2rem;
	padding-block: 1rem;
	border-bottom: 1px solid var(--c-line);
}

@media (min-width: 720px) {
	.specs__row {
		grid-template-columns: 15rem 1fr;
	}
}

.specs__label {
	font-weight: 700;
	margin: 0;
}

.specs__value {
	margin: 0;
	color: var(--c-muted);
}

.figures {
	display: grid;
	gap: clamp(1rem, 2vw, 1.5rem);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
	margin-block: clamp(1.5rem, 3vw, 2.25rem);
}

@media (min-width: 900px) {
	.figures--3 {
		grid-template-columns: repeat(3, 1fr);
	}
}

/* A cell in the row does not have to be a picture. Copy on one side and a
   figure on the other is the same grid — same gap, same columns, same stack
   on a narrow screen — so the two line up instead of the text sitting above
   a picture that is only half the band wide. The prose centres against the
   image rather than hanging from the top of a much taller cell.

   A cell is one child, so several paragraphs need a group around them or the
   row grows a third column. */

.figures > p,
.figures > ul,
.figures > ol,
.figures > h2,
.figures > h3,
.figures > .wp-block-group {
	align-self: center;
	margin: 0;
	/* The same 46rem a figure is capped at, so a text cell and a picture cell
	   are the same measure. */
	max-width: 46rem;
}

.figures > .wp-block-group > :first-child {
	margin-top: 0;
}

.figures > .wp-block-group > :last-child {
	margin-bottom: 0;
}

/* Beside a text cell the picture is the only thing in its column, so it sits
   in the middle of it: the theme never upscales, and an image narrower than
   its track would otherwise hug the start of the row while the copy beside it
   is centred. Centred on both axes, the two cells share a centre line. Rows
   of pictures only are untouched — there the images fill their tracks and the
   captions line up along the top. */

.figures:has(> p, > ul, > ol, > h2, > h3, > .wp-block-group) .figure {
	align-self: center;
}

.figures:has(> p, > ul, > ol, > h2, > h3, > .wp-block-group) .figure__img {
	margin-inline: auto;
}

.figures:has(> p, > ul, > ol, > h2, > h3, > .wp-block-group) .figure__caption {
	text-align: center;
}

/* A figure sits inside a full-width band but is not obliged to fill it: past
   about 46rem an image stops adding information and starts adding scrolling.
   `full` releases the cap for the images that genuinely need the width. */

.figure {
	margin: clamp(1.5rem, 3vw, 2.25rem) 0;
	max-width: 46rem;
	/* Shrink to the image so the caption sits under it rather than running on
	   past its edge — portrait renders are much narrower than the band. */
	width: fit-content;
}

.figures .figure,
.figure--full {
	max-width: none;
}

/* In a row, the images do fill their column so the captions line up. */
.figures .figure__img {
	width: 100%;
}

.figures .figure {
	margin: 0;
	width: auto; /* Fill the grid track, so captions in a row line up. */
}

.figure--narrow {
	max-width: 34rem;
}

.figure__img {
	display: block;
	/* Never upscale: a simulation render is only as wide as it was rendered. */
	width: auto;
	max-width: 100%;
	height: auto;
	border: 1px solid var(--c-line);
	border-radius: var(--radius-lg);
	background: var(--c-surface);
}

/* Map: a self-hosted still with the interactive embed loaded only on request.
   Both states occupy the same block, so pressing the button does not jump the
   page around. */

.map {
	margin: clamp(1.5rem, 3vw, 2.25rem) 0 0;
	max-width: 48rem;
}

.map__frame {
	position: relative;
	overflow: hidden;
	border: 1px solid var(--c-line);
	border-radius: var(--radius-lg);
	background: var(--c-surface);
	aspect-ratio: 3 / 2;
}

.map__still,
.map__embed {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
	object-fit: cover;
}

.map__load {
	position: absolute;
	left: 50%;
	bottom: 1rem;
	transform: translateX(-50%);
}

.map__caption {
	margin-top: 0.7rem;
	font-size: 0.8125rem;
	line-height: 1.5;
	color: var(--c-muted);
	text-wrap: pretty;
}

.figure__link {
	display: block;
}

.figure__link:focus-visible {
	outline: none;
	box-shadow: var(--ring);
}

.figure__caption {
	margin-top: 0.7rem;
	font-size: 0.875rem;
	line-height: 1.5;
	color: var(--c-muted);
	text-wrap: pretty;
}

.figure__caption p {
	margin: 0;
}

.figure__caption p + p {
	margin-top: 0.4rem;
}

.section--dark .figure__img {
	border-color: rgb(255 255 255 / 14%);
	background: rgb(255 255 255 / 5%);
}

.section--dark .figure__caption {
	color: #c6d0cb;
}

/* Image placeholders. Page copy marks a photograph that has not been taken yet
   with one of these; the box says which picture belongs there. It is a slot,
   not an error, so it stays quiet: a dashed outline on the surface tone and
   muted centred text. Delete these rules once no .jve-placeholder is left in
   the content. */

.jve-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	max-width: 46rem;
	min-height: 180px;
	margin-block: clamp(1.5rem, 3vw, 2.25rem);
	padding: 1.5rem;
	border: 1px dashed var(--c-line);
	border-radius: var(--radius-lg);
	background: var(--c-surface);
	color: var(--c-muted);
	font-size: 0.875rem;
	line-height: 1.5;
	text-align: center;
	text-wrap: pretty;
}

/* The full width of the band, for the photographs that will want it. */
.jve-placeholder--wide {
	max-width: none;
	min-height: 280px;
}

.section--dark .jve-placeholder {
	border-color: rgb(255 255 255 / 14%);
	background: rgb(255 255 255 / 5%);
	color: #c6d0cb;
}

.cta {
	background: var(--c-primary);
	color: #fff;
	padding-block: clamp(2.75rem, 5vw, 4rem);
}

.cta__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem 2.5rem;
}

.cta__text {
	max-width: 46rem;
}

.cta__title {
	color: #fff;
	font-size: clamp(1.5rem, 3vw, 2.1rem);
	margin-bottom: 0.4em;
}

.cta__text p {
	color: rgb(255 255 255 / 88%);
	margin: 0;
	text-wrap: pretty;
}

.cta__action {
	margin: 0;
}

/* ------------------------------------------------------------------ 7. */

.tabs {
	padding-block: clamp(1.5rem, 3vw, 2.25rem) var(--section-y);
}

.tabs__list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem;
	border-bottom: 1px solid var(--c-line);
	margin-bottom: clamp(2rem, 4vw, 3rem);
}

.tabs__tab {
	appearance: none;
	background: transparent;
	border: 0;
	border-bottom: 3px solid transparent;
	padding: 0.85rem 1.1rem;
	margin-bottom: -1px;
	font: inherit;
	font-size: 1rem;
	font-weight: 600;
	color: var(--c-muted);
	cursor: pointer;
	transition: color 0.16s var(--ease), border-color 0.16s var(--ease), background-color 0.16s var(--ease);
}

.tabs__tab:hover {
	color: var(--c-text);
	background: var(--c-surface);
}

.tabs__tab[aria-selected="true"] {
	color: var(--c-primary-dark);
	border-bottom-color: var(--c-primary);
}

.tabs__panel[hidden] {
	display: none;
}

.tabs__panel > * + * {
	margin-top: 1.15em;
}

.tabs__panel > .section:first-child {
	margin-top: 0;
}

/* Inside tabs the section bands lose their outer padding — the tab strip
   already provides the separation. */
.tabs .section {
	padding-block: clamp(1.5rem, 3vw, 2.5rem);
}

.tabs .section .wrap {
	padding-inline: 0;
	max-width: none;
}

.tabs .section--surface,
.tabs .section--green,
.tabs .section--dark {
	padding-inline: clamp(1.25rem, 3vw, 2.5rem);
}

/* ------------------------------------------------------------------ 8. */

.team {
	display: grid;
	gap: clamp(1.25rem, 3vw, 2rem);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
}

.member {
	display: flex;
	gap: 1.25rem;
	align-items: flex-start;
	background: var(--c-base);
	border: 1px solid var(--c-line);
	border-radius: var(--radius-lg);
	padding: clamp(1.25rem, 2.4vw, 1.75rem);
}

/* A photograph, cropped square and bordered like every other picture on the
   site. The tinted circle it used to sit in read as an avatar slot waiting to
   be filled — which is exactly what it was, since a member without an image
   fell back to initials. That fallback is gone; see inc/shortcodes.php. */
.member__portrait {
	flex: none;
	width: 96px;
	height: 96px;
	overflow: hidden;
	border: 1px solid var(--c-line);
	background: var(--c-surface);
}

.member__portrait img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.member__name {
	font-size: 1.1875rem;
	margin-bottom: 0.15rem;
}

.member__role {
	color: var(--c-muted);
	font-weight: 600;
	font-size: 0.9375rem;
	margin-bottom: 0.7rem;
}

.member__bio {
	color: var(--c-muted);
	font-size: 1rem;
}

.member__contact {
	margin: 0.75rem 0 0;
	font-size: 0.9375rem;
}

.member__contact a {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	text-decoration: none;
}

.member__contact a:hover {
	text-decoration: underline;
}

.member__contact .icon {
	width: 18px;
	height: 18px;
}

/* ------------------------------------------------------------------ 9. */

.form {
	background: var(--c-base);
	border: 1px solid var(--c-line);
	border-radius: var(--radius-lg);
	padding: clamp(1.5rem, 3vw, 2.25rem);
}

.form__grid {
	display: grid;
	gap: 1.1rem;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}

.form__field {
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
}

.form__field--full {
	grid-column: 1 / -1;
}

.form__field label {
	font-weight: 600;
	font-size: 0.9375rem;
}

.req {
	color: var(--c-primary);
}

.form input[type="text"],
.form input[type="email"],
.form input[type="tel"],
.form select,
.form textarea {
	width: 100%;
	padding: 0.7rem 0.85rem;
	font: inherit;
	font-size: 1rem;
	color: var(--c-text);
	background: var(--c-base);
	border: 1px solid var(--c-line);
	border-radius: var(--radius);
	transition: border-color 0.16s var(--ease), box-shadow 0.16s var(--ease);
}

.form input:focus,
.form select:focus,
.form textarea:focus {
	border-color: var(--c-primary);
	box-shadow: var(--ring);
	outline: none;
}

.form textarea {
	resize: vertical;
	min-height: 9rem;
}

.form__hint {
	font-size: 0.875rem;
	color: var(--c-muted);
}

.form__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.form__submit {
	margin: 1.5rem 0 0;
}

.notice {
	display: flex;
	gap: 0.75rem;
	align-items: flex-start;
	padding: 1rem 1.25rem;
	border-radius: var(--radius);
	margin-bottom: 1.5rem;
	border: 1px solid;
}

.notice p {
	margin: 0;
}

.notice--ok {
	background: var(--c-primary-light);
	border-color: var(--c-accent);
	color: var(--c-primary-dark);
}

.notice--error {
	background: #fdf1ef;
	border-color: #e4b4ab;
	color: #8a3524;
}

.search-form {
	display: flex;
	gap: 0.5rem;
	margin-bottom: 2rem;
}

.search-form input[type="search"] {
	flex: 1;
	padding: 0.7rem 0.85rem;
	font: inherit;
	border: 1px solid var(--c-line);
	border-radius: var(--radius);
}

.result-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.result {
	padding-block: 1.25rem;
	border-bottom: 1px solid var(--c-line);
}

.result__title {
	font-size: 1.1875rem;
	margin-bottom: 0.25rem;
}

.result__title a {
	text-decoration: none;
}

.result__excerpt {
	color: var(--c-muted);
	margin: 0;
}

/* ----------------------------------------------------------------- 10. */

.site-footer {
	background: var(--c-dark);
	color: #c3ccc7;
	padding-top: clamp(3rem, 6vw, 4.5rem);
	font-size: 0.9375rem;
}

.site-footer a {
	color: #dfe6e2;
}

.site-footer a:hover {
	color: #fff;
}

.site-footer__grid {
	display: grid;
	gap: 2.25rem;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
	padding-bottom: 2.75rem;
}

.site-footer__col--brand .brand__mark {
	color: var(--c-primary);
	margin-bottom: 1rem;
}

.site-footer__blurb {
	max-width: 26ch;
	color: #a9b4ae;
}

.site-footer__title {
	font-size: 0.9375rem;
	font-weight: 700;
	color: #fff;
	margin-bottom: 0.8rem;
}

.site-footer__address {
	display: flex;
	gap: 0.6rem;
	font-style: normal;
	line-height: 1.7;
}

.site-footer__address a {
	color: inherit;
	text-decoration: none;
}

.site-footer__address a:hover,
.site-footer__address a:focus-visible {
	color: var(--c-accent);
	text-decoration: underline;
}

.site-footer__address .icon,
.site-footer__contact .icon {
	flex: none;
	width: 20px;
	height: 20px;
	color: var(--c-accent);
	margin-top: 0.15rem;
}

.site-footer__contact {
	margin-bottom: 0.85rem;
}

.site-footer__contact a {
	display: inline-flex;
	gap: 0.5rem;
	align-items: center;
	text-decoration: none;
	word-break: break-word;
}

.site-footer__contact a:hover {
	text-decoration: underline;
}

.site-footer__contact .btn--ghost {
	border-color: rgb(255 255 255 / 24%);
	color: #dfe6e2;
}

.site-footer__contact .btn--ghost:hover {
	background: rgb(255 255 255 / 8%);
	border-color: var(--c-accent);
	color: #fff;
	text-decoration: none;
}

.site-footer__nav {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 0.55rem;
}

.site-footer__nav a {
	text-decoration: none;
}

.site-footer__nav a:hover {
	text-decoration: underline;
}

.site-footer__bar {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 2rem;
	justify-content: space-between;
	padding-block: 1.35rem;
	border-top: 1px solid rgb(255 255 255 / 12%);
	color: #8d9995;
	font-size: 0.8125rem;
}

.site-footer__bar p {
	margin: 0;
}

/* Block editor: make the backend column match the front end. */
.editor-styles-wrapper {
	background: var(--c-base);
	font-family: var(--wp--preset--font-family--system, system-ui, sans-serif);
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
	}
}

@media print {
	.site-header,
	.site-footer,
	.hero__controls,
	.nav-toggle,
	.form {
		display: none !important;
	}

	body {
		color: #000;
	}
}
