/* =============================================================================
   Bakery Combinations — homepage sections

   Every value below is transcribed from the Figma frames, not approximated.
   Mobile-first: the base rules are the 430px frame (node 51375:29330); the
   1200px media query carries the 1440px frame (node 51375:15852).

   Type that differs between the two frames uses a linear ramp that is exact at
   430px and 1440px:  min + (max - min) * (100vw - 430px) / 1010px
============================================================================= */

/* -----------------------------------------------------------------------------
   Hero — desktop 51375:15934 (1440×722) / mobile 51375:29332 (430×941)
-------------------------------------------------------------------------- */

.hero {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--hero-gap);
	/* In Figma the nav is the first child of the hero's flex column, so the
	   padding has to stand in for the nav's height *and* the column gap that
	   follows it. Mobile nav = 24 + 64 icon + 24 = 112. */
	padding-top: calc(112px + var(--hero-gap));
	padding-bottom: var(--hero-gap);
	isolation: isolate;
	overflow: hidden;
}

/* Background photograph + flat overlay.
   The overlay was measured off the Figma render: a uniform rgba(9,13,30,0.84)
   reproduces the frame to under 1/255 mean channel error. */
.hero__bg {
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url("../images/hero-background.webp");
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

/* The clip, when one is set, sits over the photograph and under the wash. */
.hero__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border: 0;
	pointer-events: none;
}

/* The wash is its own layer so it covers the clip as it did the photograph. */
.hero__bg::after {
	content: "";
	position: absolute;
	inset: 0;
	background-color: rgba(9, 13, 30, 0.84);
}

.hero__content {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: 40px;
	padding: 40px;
}

.hero__copy {
	display: flex;
	flex-direction: column;
	gap: 16px;
	align-items: flex-start;
}

.hero__title {
	/* 40px @430  →  64px @1440 */
	font-size: clamp(40px, 29.782px + 2.3762vw, 64px);
	line-height: 1;
	letter-spacing: -0.02em;
	color: var(--bca-white);
}

.hero__lede {
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-white);
}

.hero__actions {
	display: flex;
	align-items: center;
	gap: 16px;
}

/* Feature image — mobile: full width between the gutters at the drawn
   350 / 231 ratio (350 × 231 on the 430 frame). */
.hero__feature {
	position: relative;
	width: calc(100% - (var(--gutter) * 2));
	height: auto;
	aspect-ratio: 350 / 231;
	margin: 0;
	border: var(--bca-hairline) solid var(--bca-rule-cream);
}

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

/* Desktop only. */
.hero__scroll {
	display: none;
}

@media (min-width: 1200px) {

	.hero {
		/* Desktop nav height is driven by the 89px contact panel; adding the
		   88px gap puts the copy block at y=177, as drawn. 177+457+88 = 722. */
		padding-top: calc(89px + var(--hero-gap));
	}

	/* The copy block spans the full frame and gains its top/bottom rules.
	   The right padding reserves the absolutely placed feature image's zone
	   (345 wide + 120 offset + the 110 clearance drawn at 1440), so the copy
	   wraps short of the photograph on every viewport instead of running
	   under it — at 1440 it leaves exactly the 825px measure the frame
	   draws. */
	.hero__content {
		height: 457px;
		justify-content: flex-end;
		padding-right: 575px;
		/* The 1440 stage the frame draws, centred on anything wider. */
		max-width: 1440px;
		margin-inline: auto;
		border-top: var(--bca-hairline) solid var(--bca-rule-white);
		border-bottom: var(--bca-hairline) solid var(--bca-rule-white);
	}

	.hero__title {
		max-width: 825px;
	}

	/* Desktop lets the first clause wrap naturally inside the 825px measure. */
	.hero__br--mobile {
		display: none;
	}

	.hero__lede {
		max-width: 562px;
	}

	.hero__actions {
		align-items: flex-start;
		gap: 12px;
	}

	/* Feature image sits 120px in from the right edge, aligned to the copy
	   block's 457px band (left 975 / top 177 in the 1440 frame). */
	.hero__feature {
		position: absolute;
		top: 89px;
		/* 120px off the 1440 stage's right edge, wherever that stage sits. */
		right: max(120px, calc((100% - 1440px) / 2 + 120px));
		width: 345px;
		max-width: none;
		height: 457px;
		margin-top: var(--hero-gap);
		border: 0;
		border-top: var(--bca-hairline) solid var(--bca-rule-cream);
		border-bottom: var(--bca-hairline) solid var(--bca-rule-cream);
	}

	/* The two rules that frame the image run the full height of the hero,
	   from the underside of the nav to the bottom edge. */
	.hero__feature::before,
	.hero__feature::after {
		content: "";
		position: absolute;
		/* From the underside of the nav (y=89) to the bottom of the hero. */
		top: calc(var(--hero-gap) * -1);
		bottom: calc(var(--hero-gap) * -1);
		width: 0;
		border-left: var(--bca-hairline) solid var(--bca-rule-white);
		pointer-events: none;
	}

	.hero__feature::before {
		left: 0;
	}

	.hero__feature::after {
		right: 0;
	}

	.hero__scroll {
		display: block;
		position: absolute;
		/* On the 1440 stage's left gutter, wherever that stage sits — the
		   hero content centres past the frame's width and the label rides
		   with it. */
		left: max(var(--gutter), calc((100% - 1440px) / 2 + var(--gutter)));
		bottom: 40px;
		font-family: var(--font-body);
		font-weight: 400;
		font-size: 10px;
		line-height: 1;
		letter-spacing: 0.08em;
		text-transform: uppercase;
		color: var(--bca-powder);
		opacity: 0.9;
	}
}

/* -----------------------------------------------------------------------------
   Partner logo strip — desktop 51375:15949 (1440×166). No mobile counterpart.
-------------------------------------------------------------------------- */

/* No background of its own: the page's grid plate shows through this band. */
.partners {
	padding-block: 40px;
	overflow: hidden;
}

.partners__viewport {
	display: flex;
	width: 100%;
	overflow: hidden;
}

/* The row is designed to run off the edge of the frame. Each tile advances
   the set by 216px (200 tile + 16 gap), so translating by the tile count
   times that — one set plus one gap — lands the clone exactly where the
   original started. The count comes from the template (--tiles); the duration
   scales with it so the speed stays the 37.8px/s the seven-tile Figma frame
   drew (1512px over 40s). */
.partners__track {
	display: flex;
	align-items: center;
	gap: 16px;
	width: max-content;
	animation: partners-scroll calc(var(--tiles, 7) * 216s / 37.8) linear infinite;
}

@keyframes partners-scroll {
	from {
		transform: translateX(0);
	}

	to {
		transform: translateX(calc(var(--tiles, 7) * -216px));
	}
}

.partners__item {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 200px;
	height: 86px;
	padding: 10px;
	border-radius: 10px;
	overflow: hidden;
	flex: none;
}

/* The leaf keeps the exact box Figma drew; the fill is positioned inside it so
   the source bitmap ships untouched. */
.logo-crop {
	position: relative;
	display: block;
	width: var(--leaf-w);
	height: var(--leaf-h);
	flex: none;
	overflow: hidden;
}

.logo-crop img {
	position: absolute;
	left: var(--fill-x, 0);
	top: var(--fill-y, 0);
	width: var(--fill-w, 100%);
	height: var(--fill-h, 100%);
	max-width: none;
	object-fit: cover;
}

/* The dark marquee sets every mark in white. Most partners upload a prepared
   white cut, but any full-colour file dropped into the slot is flattened to
   the same white here, so one odd upload can never break the strip. The
   testimonial tiles sit on white cards and keep their logos as uploaded. */
.partners .logo-crop img {
	filter: brightness(0) invert(1);
}

/* Marquee logo fit (D6 feedback, HOME-3): a mark is contained in its box,
   never cover-cropped, so a box whose shape is off can only leave air round a
   logo, not cut it. Centred, as marks are — the top anchor every photograph
   takes is there to keep heads in frame, and a logo has none. */
.partners .logo-crop img {
	object-fit: contain;
	object-position: 50% 50%;
}

@media (prefers-reduced-motion: reduce) {

	.partners__track {
		animation: none;
	}

	.partners__viewport {
		overflow-x: auto;
	}
}

/* -----------------------------------------------------------------------------
   Media frame — the recurring corner bracket motif.
   Desktop brackets are 16px arms with the image inset 16.05 / 15; mobile drops
   to 8.6px arms and a 12.3 / 14 inset. Figma exports the bracket as a rotated
   two line vector; two 1px borders are the same picture.
-------------------------------------------------------------------------- */

.media-frame {
	--frame-arm: 8.606px;
	--frame-inset-x: 12.3px;
	--frame-inset-y: 14px;
	--frame-ratio: 329 / 219;

	position: relative;
	width: 100%;
	margin: 0;
	padding: var(--frame-inset-y) var(--frame-inset-x);
}

.media-frame__corner {
	position: absolute;
	width: var(--frame-arm);
	height: var(--frame-arm);
	pointer-events: none;
}

.media-frame__corner--tl {
	top: 0;
	left: 0;
	border-top: 1px solid var(--bca-powder);
	border-left: 1px solid var(--bca-powder);
}

.media-frame__corner--tr {
	top: 0;
	right: 0;
	border-top: 1px solid var(--bca-powder);
	border-right: 1px solid var(--bca-powder);
}

.media-frame__corner--bl {
	bottom: 0;
	left: 0;
	border-bottom: 1px solid var(--bca-powder);
	border-left: 1px solid var(--bca-powder);
}

.media-frame__corner--br {
	bottom: 0;
	right: 0;
	border-bottom: 1px solid var(--bca-powder);
	border-right: 1px solid var(--bca-powder);
}

/* The plate is a <video>, so it needs the block box an <img> already has. */
.video-plate {
	display: block;
}

.media-frame__img {
	width: 100%;
	height: auto;
	aspect-ratio: var(--frame-ratio);
	object-fit: cover;
}

@media (min-width: 1200px) {

	.media-frame {
		--frame-arm: 16px;
		--frame-inset-x: 16.05px;
		--frame-inset-y: 15px;
	}
}

/* The Industrial frame closes its process section on a wide plate — the photo
   is drawn 1328 × 562 inside the 1360 frame (53333:37863). */
.process__media {
	--frame-ratio: 1328 / 562;
}

/* -----------------------------------------------------------------------------
   About us statement — desktop 51375:16039 / mobile 51375:29349
-------------------------------------------------------------------------- */

.about-intro {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--section-64-88);
	padding: var(--section-64-88) var(--gutter);
}

/* Mobile treats the statement and the buttons as plain siblings of the media,
   so the wrapper's gap simply matches the section's. Desktop tightens it to 36
   and lets the section gap grow to 88. */
.about-intro__intro {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--section-64-88);
	width: 100%;
}

.about-intro__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 16px;
	width: 100%;
}

.about-intro__lede {
	max-width: 1128px;
	font-family: var(--font-display);
	font-weight: 400;
	/* 24px @430 → 40px @1440 */
	font-size: clamp(24px, 17.188px + 1.5842vw, 40px);
	line-height: 1.1;
	letter-spacing: -0.02em;
	text-align: center;
	color: var(--bca-cream);
}

.about-intro__lede-tail {
	color: var(--bca-cream-40);
}

/* Channels for the scroll lit statements — cream on the dark sections, and the
   same ramp in ink on the two cream ones, which cream would disappear into. */
.about-intro__lede,
.process__lede {
	--stmt-rgb: 255 246 239;
}

.values__statement,
.turnkey__statement {
	--stmt-rgb: 8 6 36;
}

.about-intro__actions {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 16px;
}

/* The photograph is cropped to a different shape in each frame — 329×219 on
   mobile, 1327.9×562 on desktop — so the ratio switches with the layout. */
.about-intro__media {
	--frame-ratio: 329 / 219;
}

@media (min-width: 1200px) {

	.about-intro__intro {
		gap: 36px;
	}

	.about-intro__lede {
		line-height: 1;
	}

	.about-intro__media {
		--frame-ratio: 1327.9 / 562;
	}
}

/* -----------------------------------------------------------------------------
   Shared light panel + hairline decorations

   The light sections all sit on #f7f7f7 under a soft light noise plate, and
   they mark their hairline grid with an 8px crosshair. Where a rule leaves the
   grid it becomes a 53px "ray" that fades from steel blue to white — Figma
   exports this as a vector, two CSS boxes draw the same thing.
-------------------------------------------------------------------------- */

.panel {
	position: relative;
	isolation: isolate;
	background-color: var(--bca-powder);
	color: var(--bca-midnight);
}

.panel::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url("../images/panel-texture.png");
	background-size: 1048.8546px 534.8267px;
	background-position: top left;
	mix-blend-mode: soft-light;
	opacity: 0.8;
	pointer-events: none;
}

/* Crosshair: two 1px strokes meeting at the centre of an 8px box, anchored so
   the centre lands exactly on the corner it marks.

   The box size and the length of the hairline that leaves it are custom
   properties because the Turnkey Solutions mobile frames draw the same mark
   smaller — a 4.566px crosshair with a 30.253px tail (51375:29999). */
.mark {
	position: absolute;
	z-index: 2;
	width: var(--mark-size, 8px);
	height: var(--mark-size, 8px);
	pointer-events: none;
}

.mark::before,
.mark::after {
	content: "";
	position: absolute;
	background-color: var(--bca-midnight);
}

.mark::before {
	left: 50%;
	top: 0;
	width: 1px;
	height: 100%;
	transform: translateX(-50%);
}

.mark::after {
	top: 50%;
	left: 0;
	width: 100%;
	height: 1px;
	transform: translateY(-50%);
}

.mark--tl {
	top: 0;
	left: 0;
	transform: translate(-50%, -50%);
}

.mark--tr {
	top: 0;
	right: 0;
	transform: translate(50%, -50%);
}

.mark--bl {
	bottom: 0;
	left: 0;
	transform: translate(-50%, 50%);
}

.mark--br {
	bottom: 0;
	right: 0;
	transform: translate(50%, 50%);
}

/* The 53px hairline the Accordion component runs outward from each corner,
   fading from steel blue at 60% to nothing (Figma: a 0.25px line with a linear
   gradient, #28357c/0.6 → transparent, rotated to vertical). The mark itself is
   8px, so the group reads 8 + 53 = 61 tall exactly as the frame draws it. */
.mark__tick {
	position: absolute;
	width: var(--bca-rule);
	height: var(--tick-h, 53px);
	pointer-events: none;
}

/* The mark is centred on the corner, so centring the tick inside it too would
   put a 1px line on a half pixel — it then straddles two columns at half
   strength, which measures 230 against the frame's 215. Aligning it to the side
   the box's own border paints keeps it on one pixel.

   The nudge is the border of the box the marks are hung on: an absolutely
   placed child resolves against the padding box, so on a bordered box the
   rule is painted a pixel outside the mark and the tail has to come back to
   meet it. Where the marks hang on an unbordered wrapper and the rule
   belongs to a child instead - the Contact page's frame around its card -
   that box sets the nudge to zero. */
.mark--tl .mark__tick,
.mark--bl .mark__tick {
	left: calc(50% - var(--mark-border, var(--bca-hairline)));
}

.mark--tr .mark__tick,
.mark--br .mark__tick {
	right: calc(50% - var(--mark-border, var(--bca-hairline)));
}

.mark--tl .mark__tick,
.mark--tr .mark__tick {
	bottom: 100%;
	background-image: linear-gradient(to top, rgba(40, 53, 124, 0.15), rgba(40, 53, 124, 0));
}

.mark--bl .mark__tick,
.mark--br .mark__tick {
	top: 100%;
	background-image: linear-gradient(to bottom, rgba(40, 53, 124, 0.15), rgba(40, 53, 124, 0));
}

.ray {
	position: absolute;
	z-index: 1;
	width: var(--bca-rule);
	height: var(--ray-h, 53px);
	pointer-events: none;
}

.ray--up {
	bottom: 100%;
	background-image: linear-gradient(to top, rgba(40, 53, 124, 0.15), #ffffff);
}

.ray--down {
	top: 100%;
	background-image: linear-gradient(to bottom, rgba(40, 53, 124, 0.15), #ffffff);
}

.ray--left {
	left: 0;
	transform: translateX(-50%);
}

.ray--right {
	right: 0;
	transform: translateX(50%);
}

/* The tag sits on the light panel in these sections. */
.tag--dark .tag__label {
	color: var(--bca-midnight);
}

/* -----------------------------------------------------------------------------
   About values (POETT) — desktop 51375:16069 / mobile 51375:29375
-------------------------------------------------------------------------- */

.values {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 64px;
	padding: 88px var(--gutter);
}

.values__intro {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 64px;
	width: 100%;
}

.values__copy {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 16px;
	width: 100%;
}

.values__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-end;
	gap: 16px;
	width: 100%;
}

.values__statement {
	width: 100%;
	font-family: var(--font-display);
	font-weight: 400;
	/* 24px @430 → 40px @1440 */
	font-size: clamp(24px, 17.188px + 1.5842vw, 40px);
	line-height: 1.1;
	letter-spacing: -0.02em;
	text-align: center;
	color: var(--bca-midnight);
}

.values__statement-tail {
	color: rgba(8, 6, 36, 0.4);
}

.values__detail {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 64px;
	width: 100%;
}

.values__body {
	width: 100%;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	text-align: center;
	color: var(--bca-midnight);
	opacity: 0.8;
}

/* Not drawn in the mobile frame. */
.values__figure {
	display: none;
}

.values__grid {
	position: relative;
	display: flex;
	flex-direction: column;
	width: 100%;
}

.values__cell {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 24px;
	padding: 36px;
	border: var(--bca-hairline) solid var(--rule);
	border-bottom: 0;
}

/* The grid's rays follow the cells as its last children, so the closing
   rule has to find the last cell by type — as :last-child it never matched
   and the phone frame's block stood open at the foot (QA, Sep 2026). */
.values__cell:last-of-type {
	border-bottom: var(--bca-hairline) solid var(--rule);
}

.values__initial {
	width: 100%;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 32px;
	line-height: 1.1;
	letter-spacing: -0.02em;
	color: var(--bca-steel-blue);
}

/* The tangerine is the hover state alone: the frame drew the accented cell's
   initial in it (53333:23431), but the client keeps every initial steel blue
   at rest (Sam, Aug 2026) — so the repeater's accent flag no longer pins it. */
.values__cell:hover .values__initial,
.values__cell:focus-within .values__initial {
	color: var(--bca-tangerine);
}

.values__initial {
	transition: color 0.2s ease;
}

.values__cell-copy {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 18px;
	width: 100%;
	color: var(--bca-midnight);
}

.values__title {
	width: 100%;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 18px;
	line-height: 1.1;
	letter-spacing: -0.03em;
}

.values__text {
	width: 100%;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
}

/* Rays only leave the grid on the desktop frame. */
.values__grid > .ray {
	display: none;
}

@media (min-width: 1200px) {

	.values {
		align-items: flex-start;
		gap: 88px;
	}

	/* Copy and photo become one bottom aligned row, held to the 1360 content
	   column past the frame's width — the cell grid below rides with it. */
	.values__intro {
		flex-direction: row;
		align-items: flex-end;
		justify-content: space-between;
		gap: 40px;
		max-width: 1360px;
		margin-inline: auto;
	}

	.values__grid {
		max-width: 1360px;
		margin-inline: auto;
	}

	/* Fixed at the drawn widths on the 1440 frame; both columns give way
	   proportionally on narrower desktops so the row never overflows. */
	.values__copy {
		align-items: flex-start;
		gap: 24px;
		width: auto;
		height: 511px;
		flex: 0 1 554px;
		min-width: 0;
	}

	.values__head {
		align-items: flex-start;
	}

	.values__statement {
		line-height: 1;
		text-align: left;
	}

	.values__detail {
		align-items: flex-start;
		gap: 24px;
	}

	.values__body {
		width: 100%;
		max-width: 540px;
		text-align: left;
	}

	/* 664 wide column; the framed plate is 660 × 402 with a 40px mount and the
	   photo filling the remaining 580 × 322. */
	/* Figma (51375:16082) hangs the plate 54.41px below the TOP of the intro
	   row — its top border runs level with the tag — leaving 54.59px of air
	   above the row's bottom edge. */
	.values__figure {
		position: relative;
		display: block;
		align-self: flex-start;
		width: auto;
		height: 402px;
		margin: 54.41px 0 0;
		padding: 40px;
		border: var(--bca-hairline) solid var(--bca-mount-rule);
		flex: 0 1 660px;
		min-width: 0;
	}

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

	/* Five equal cells sharing one hairline grid: every cell keeps its right
	   rule, the first also keeps its left. */
	/* The grid block reserves 54.41 above and 52.18 below so the rays that leave
	   its outer corners have room — Figma draws the block (51375:16104) 475 tall
	   around a 368.41 tall row of cells. */
	.values__grid {
		flex-direction: row;
		align-items: stretch;
		margin-block: 54.41px 52.18px;
	}

	.values__cell {
		flex: 1 1 0;
		min-width: 0;
		border: var(--bca-hairline) solid var(--rule);
		border-left: 0;
	}

	.values__cell:first-child {
		border-left: var(--bca-hairline) solid var(--rule);
	}

	.values__initial {
		font-size: 88px;
		line-height: 0.9;
	}

	.values__cell {
		gap: 48px;
	}

	.values__title {
		font-size: 28px;
	}

	.values__text {
		font-size: 16px;
	}

	.values__grid > .ray {
		display: block;
	}
}

/* -----------------------------------------------------------------------------
   Shared carousel + filter bar

   Both the equipment and insights carousels use the same scroll snap track and
   the same steel blue prev/next pair. Card widths are set per section through
   --card-w so the track geometry stays in one place.
-------------------------------------------------------------------------- */

.carousel {
	width: 100%;
	/* Every rail is boxed to the 1360 content column — past the frame's
	   width it centres rather than running to the screen's edges. */
	max-width: 1360px;
	margin-inline: auto;
	overflow: hidden;
}

.carousel__track {
	display: flex;
	gap: var(--card-gap, 16px);
	overflow-x: auto;
	/* Explicit: with overflow-y left at visible the browser computes it to
	   auto alongside overflow-x, which makes the rail a vertical scroller too
	   and swallows the wheel gesture meant for the page. */
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.carousel__track::-webkit-scrollbar {
	display: none;
}

.carousel__slide {
	flex: none;
	width: var(--card-w);
	scroll-snap-align: start;
}

/* A product rail is sized by script to the cards in view (initCarouselFit),
   so its slides stop stretching to the tallest card anywhere on the rail.
   Any card taller than the rail's current height is one scrolled out of
   view, and it is measured back in as it arrives. */
[data-carousel-fit] .carousel__track {
	align-items: flex-start;
	transition: height 0.25s ease;
}

/* Filtered out by the bar above the track. */
.carousel__slide[hidden] {
	display: none;
}

.carousel-nav {
	display: flex;
	align-items: center;
	gap: 8px;
	/* The arrows keep to the 1360 column their rail rides in — symmetric,
	   so a start-anchored pair indents to the column's leading edge and a
	   centred pair stays centred; inside anything narrower this resolves
	   to nothing. */
	margin-inline: max(0px, calc((100% - 1360px) / 2));
}

/* 8px of padding around the 32px glyph on the mobile frame, 4px on desktop. */
.carousel-nav__btn {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 8px;
	border-radius: 2px;
	background-color: var(--bca-steel-blue);
	color: var(--bca-powder);
	transition: background-color 0.2s ease, opacity 0.2s ease;
}

.carousel-nav__btn:hover {
	background-color: #1d2861;
}

.carousel-nav__btn[disabled] {
	opacity: 0.4;
	cursor: default;
}

/* One exported glyph, mirrored for the back state. */
.carousel-nav__btn--prev .arrow-icon {
	transform: rotate(180deg);
}

/* The card chips take the same glyph the other way up. Figma draws the icon
   with a 180° rotation on it (51375:16436) so the arrow leads away from the
   card — mapping its local tip through the node's absolute transform puts the
   head 15.43px to the *right* of the tail. */
.product-card__go .arrow-icon,
.insight-card__go .arrow-icon {
	transform: rotate(180deg);
}

.arrow-icon {
	width: 32px;
	height: 32px;
	flex: none;
}

/* Filter bar — the tabs sit on a steel hairline, the active one on a 2px
   tangerine rule. Figma's tab label carries an empty second line, which is what
   opens the gap between the word and the underline; ::after reproduces it. */
.filter-bar {
	display: flex;
	align-items: center;
	gap: 24px;
	width: 100%;
	/* Boxed to the 1360 content column with the rails it drives — the rule
	   under the tabs closes on the column, not the screen. */
	max-width: 1360px;
	margin-inline: auto;
	overflow-x: auto;
	border-bottom: var(--bca-hairline) solid rgba(40, 53, 124, 0.25);
	scrollbar-width: none;
}

.filter-bar::-webkit-scrollbar {
	display: none;
}

/* Mid-drag the row shows it is being pulled, and the tab text stays put. */
.filter-bar.is-dragging {
	cursor: grabbing;
	user-select: none;
}

.filter-bar__tab {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: none;
	/* Figma draws the 2px underline inside the 10px bottom padding, so the
	   border keeps the box at the drawn height: 10 + text + 8 + 2. */
	padding-block: 10px 8px;
	border-bottom: 2px solid transparent;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 18px;
	line-height: 1.1;
	letter-spacing: -0.03em;
	white-space: nowrap;
	color: var(--bca-midnight);
	opacity: 0.6;
}

.filter-bar__label::after {
	content: "\200B";
	display: block;
}

.filter-bar__tab .filter-bar__label {
	opacity: 0.4;
}

.filter-bar__tab.is-active {
	border-bottom-color: var(--bca-tangerine);
	opacity: 1;
}

.filter-bar__tab.is-active .filter-bar__label {
	opacity: 1;
}

/* -----------------------------------------------------------------------------
   Equipment carousel — desktop 51375:16200 / mobile 51375:29456
-------------------------------------------------------------------------- */

.equipment {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: center;
	gap: 64px;
	padding: 88px var(--gutter);
	/* Mobile card: (810 − 2 × 16) ÷ 3 from the 430 frame. */
	--card-w: 259.33px;
	--card-gap: 16px;
}

.band {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 64px;
	width: 100%;
}

.band__head {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: flex-end;
	gap: 16px;
	width: 100%;
}

.band__title {
	width: 100%;
	font-size: 32px;
	line-height: 1.1;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

/* Desktop hard breaks the heading into two lines; mobile lets it flow. */
.band__title br {
	display: none;
}

.band__lede {
	width: 100%;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
	opacity: 0.8;
}

.band__cta {
	display: flex;
	align-items: center;
}

/* Product card ------------------------------------------------------------ */

.product-card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 24px;
	width: 100%;
}

/* The plate is a plain white square — Figma stacks a photographic fill under a
   solid white layer, so white is all that survives. */
.product-card__plate {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 1;
	background-color: var(--bca-white);
	overflow: hidden;
	transition: background-color 0.25s ease;
}

/* The frame sets the still 4.38% in from the left and 2% from the right,
   which on a photograph that fills its box reads as a lopsided mount (QA,
   Sep 2026). It is centred now: the same 93.62% still, 3.19% clear all round. */
.product-card__plate img {
	position: absolute;
	left: 3.19%;
	top: 3.19%;
	width: 93.62%;
	height: 93.62%;
	object-fit: contain;
	object-position: center;
}

.product-card:hover .product-card__plate,
.product-card:focus-visible .product-card__plate {
	background-color: rgba(40, 53, 124, 0.1);
}

.product-card__meta {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 8px;
	width: 100%;
}

.product-card__eyebrow {
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 10px;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--bca-steel-blue);
	opacity: 0.9;
	white-space: nowrap;
}

/* The hover chip is 40px tall against a 31px name, and as a flex item it
   held the row open to its own height. It hangs off the row's top right
   instead, as the frame draws it overflowing the 24px row (51375:16220), so
   the row is only as tall as the name. */
.product-card__row {
	position: relative;
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 16px;
	width: 100%;
}

/* Room for the chip is only kept where a pointer can hover it up; a phone
   never shows it, and a 259px card has no name width to spare. */
@media (hover: hover) {

	.product-card__row {
		padding-right: 56px;
	}
}

.product-card__name {
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 24px;
	line-height: 1.1;
	letter-spacing: -0.03em;
	color: var(--bca-midnight);
}

/* Revealed on hover — the frame draws it at zero opacity. */
.product-card__go {
	position: absolute;
	top: 0;
	right: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	flex: none;
	padding: 4px;
	border-radius: 2px 2px 8px 2px;
	background-color: var(--bca-midnight);
	color: var(--bca-powder);
	opacity: 0;
	transition: opacity 0.25s ease;
}

.product-card:hover .product-card__go,
.product-card:focus-visible .product-card__go {
	opacity: 1;
}

/* Product card summary (D6 feedback, HOME-8 / EQUIP-4) --------------------
   A sentence on what the machine does, for names like "HolyCrab" that do
   not say. Where there is no hover it is a static two-line note under the
   name. Where there is, it is laid over the plate — the card's first box, so
   the same square from the same corner — and a midnight band carrying it
   rises over the plate's foot under the pointer or keyboard focus: cream on
   midnight reads the same over a white studio shot or a dark photograph, and
   the band never reaches the name, which sits below the plate. */
.product-card {
	position: relative;
}

/* "Mecatherm & MIWE | Industrial" — a long supplier line ends rather than
   pushing past a narrow card. */
.product-card__eyebrow {
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
}

.product-card__summary {
	display: block;
	width: 100%;
}

.product-card__summary-text {
	display: -webkit-box;
	overflow: hidden;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
	opacity: 0.8;
}

@media (hover: hover) {

	.product-card__summary {
		position: absolute;
		top: 0;
		left: 0;
		display: flex;
		align-items: flex-end;
		aspect-ratio: 1;
		overflow: hidden;
		pointer-events: none;
	}

	.product-card__summary-text {
		display: block;
		width: 100%;
		padding: 20px 24px;
		-webkit-line-clamp: unset;
		background-color: rgba(8, 6, 36, 0.92);
		color: var(--bca-cream);
		opacity: 1;
		transform: translateY(calc(100% + 1px));
		transition: transform 0.35s ease;
	}

	.product-card:hover .product-card__summary-text,
	.product-card:focus-visible .product-card__summary-text {
		transform: none;
	}
}

@media (hover: hover) and (prefers-reduced-motion: reduce) {

	.product-card__summary-text {
		opacity: 0;
		transform: none;
		transition: opacity 0.2s ease;
	}

	.product-card:hover .product-card__summary-text,
	.product-card:focus-visible .product-card__summary-text {
		opacity: 1;
	}
}

@media (min-width: 1200px) {

	.equipment {
		gap: 88px;
		/* Three across the 1360 content column with 24px gutters. */
		--card-w: calc((100% - 48px) / 3);
		--card-gap: 24px;
	}

	/* Figma fixes the name row at 24px (51375:16220) — the 40px hover chip and
	   the 31px name text overflow it — and gives the cards box 9.67px of slack
	   below (513 vs 503.33) so the overflow has room before the 88px gap. It is
	   a minimum rather than a fixed height: the frame only ever names a machine
	   in one word, and the real catalogue runs to names like "AF2P68-C Proving
	   Cabinet for Grids", which a fixed row would cut in half. */
	.equipment .product-card__row {
		min-height: 24px;
	}

	.equipment .carousel {
		padding-bottom: 9.67px;
	}

	/* The 40px hover chip and the 31px names overflow the drawn 24px row on
	   purpose — but the track clips its scroll content, so it is given that
	   room inside the clip and pulled straight back. The carousel box lets
	   the widened track through: with the pull-back it would otherwise crop
	   the chip at the slide's edge all over again. */
	.equipment .carousel,
	.related .carousel {
		overflow: visible;
	}

	.equipment .carousel__track,
	.related .carousel__track {
		padding-bottom: 20px;
		margin-bottom: -20px;
	}

	/* The band becomes one ruled row with the CTA bottom aligned beside it,
	   held to the 1360 content column past the frame's width. */
	.band {
		flex-direction: row;
		align-items: flex-end;
		justify-content: space-between;
		gap: 40px;
		max-width: 1360px;
		margin-inline: auto;
		padding-block: 40px;
		border-top: var(--bca-hairline) solid rgba(40, 53, 124, 0.15);
		border-bottom: var(--bca-hairline) solid rgba(40, 53, 124, 0.15);
	}

	.band__head {
		flex: 1 1 0;
		min-width: 0;
	}

	.band__title {
		font-size: 48px;
		line-height: 1;
		letter-spacing: 0;
	}

	.band__title br {
		display: inline;
	}

	/* Not drawn on the desktop frame. */
	.band__lede {
		display: none;
	}

	/* Except on the frames that do draw it there — the Industries benefits band
	   and the supplier list — which also set the heading a size down. */
	.band--lede .band__lede {
		display: block;
		/* The frames set the line in its own column beside the button rather
		   than running it the width of the band. */
		width: 379.877px;
		max-width: 100%;
	}

	/* The Equipment archive's opening band also draws its lede on desktop in
	   the client file (53314:30224), on a 664px measure under the statement. */
	.equipment-intro .band__lede {
		display: block;
		max-width: 664px;
	}

	.band--lede .band__title {
		font-size: 40px;
		line-height: 1;
		letter-spacing: -0.02em;
	}

	.band__cta {
		flex: none;
	}

	.filter-bar__tab {
		font-size: 24px;
	}

	.carousel-nav__btn {
		padding: 4px;
	}

	.product-card__name {
		font-size: 28px;
	}
}

/* -----------------------------------------------------------------------------
   Equipment search (D6 feedback, HOME-2)
   template-parts/components/equipment-search.php

   The enquiry form's field on the light panel — a hairline rule under Inter
   16px that turns steel blue under focus — with the tangerine glyph of the
   rail's Hide Filters toggle in front and the Buttons-text action of the
   product page's back link behind. 24px of content over 24px of air, so the
   rule lines up with the toggle's beside it on the catalogue. The
   suggestions drop under it on the white plate the cards use, each lit with
   the cards' own hover tint.
-------------------------------------------------------------------------- */

.equipment-search {
	position: relative;
	width: 100%;
	color: var(--bca-midnight);
}

.equipment-search__field {
	display: flex;
	align-items: center;
	gap: 16px;
	padding-bottom: 24px;
	border-bottom: var(--bca-hairline) solid var(--bca-mount-rule);
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

/* The rule doubles under focus without moving anything. */
.equipment-search__field:focus-within {
	border-bottom-color: var(--bca-steel-blue);
	box-shadow: 0 1px 0 var(--bca-steel-blue);
}

.equipment-search__icon {
	display: flex;
	flex: none;
	color: var(--bca-tangerine);
}

.equipment-search__input {
	flex: 1 1 auto;
	min-width: 0;
	height: 24px;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 16px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
	text-overflow: ellipsis;
	-webkit-appearance: none;
	appearance: none;
}

.equipment-search__input::placeholder {
	color: var(--bca-midnight);
	opacity: 0.6;
}

/* The rule carries the focus, as on the enquiry fields. */
.equipment-search__input:focus {
	outline: 0;
}

.equipment-search__input::-webkit-search-decoration,
.equipment-search__input::-webkit-search-cancel-button {
	-webkit-appearance: none;
	appearance: none;
}

.equipment-search__clear,
.equipment-search__submit {
	position: relative;
	display: inline-flex;
	align-items: center;
	flex: none;
	transition: color 0.2s ease, opacity 0.2s ease;
}

/* Both are drawn 24px tall; their tap targets reach 44. */
.equipment-search__clear::before,
.equipment-search__submit::before {
	content: "";
	position: absolute;
	inset: -10px -6px;
}

.equipment-search__clear {
	justify-content: center;
	width: 24px;
	height: 24px;
	color: var(--bca-midnight);
	opacity: 0.6;
}

.equipment-search__clear svg {
	width: 10px;
	height: 10px;
}

.equipment-search__clear:hover {
	color: var(--bca-tangerine);
	opacity: 1;
}

.equipment-search__submit {
	gap: 12px;
	height: 24px;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 14px;
	line-height: 1.1;
	text-transform: uppercase;
	color: var(--bca-steel-blue);
}

.equipment-search__submit:hover {
	color: var(--bca-tangerine);
}

.equipment-search__submit-icon {
	display: flex;
}

/* The card arrow points back; the action points on. */
.equipment-search__submit-icon .arrow-icon,
.equipment-search__option--all .arrow-icon {
	width: 15px;
	height: 13px;
	transform: rotate(180deg);
}

/* A phone keeps the arrow and lets the field have the width. */
@media (max-width: 767.98px) {

	.equipment-search__submit-label {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip: rect(0 0 0 0);
		white-space: nowrap;
	}
}

/* Suggestions. */
.equipment-search__panel {
	position: absolute;
	top: calc(100% + 8px);
	left: 0;
	z-index: 30;
	width: 100%;
	max-width: 664px;
	max-height: min(480px, 70vh);
	overflow-y: auto;
	overscroll-behavior: contain;
	border: var(--bca-hairline) solid var(--bca-mount-rule);
	background-color: var(--bca-white);
	box-shadow: 0 16px 40px rgba(8, 6, 36, 0.12);
}

.equipment-search__list {
	display: flex;
	flex-direction: column;
	transition: opacity 0.2s ease;
}

.equipment-search.is-busy .equipment-search__list {
	opacity: 0.6;
}

.equipment-search__option {
	display: grid;
	grid-template-columns: 56px minmax(0, 1fr);
	align-items: center;
	gap: 16px;
	padding: 12px 16px;
	color: var(--bca-midnight);
	transition: background-color 0.15s ease;
}

.equipment-search__option + .equipment-search__option {
	box-shadow: inset 0 1px 0 rgba(40, 53, 124, 0.1);
}

/* The cards' hover tint, with a steel bar so the keyboard's place is plain. */
.equipment-search__option.is-active {
	background-color: rgba(40, 53, 124, 0.1);
	box-shadow: inset 2px 0 0 var(--bca-steel-blue), inset 0 1px 0 rgba(40, 53, 124, 0.1);
}

.equipment-search__thumb {
	position: relative;
	display: block;
	width: 56px;
	aspect-ratio: 1;
	background-color: var(--bca-white);
	box-shadow: inset 0 0 0 1px rgba(40, 53, 124, 0.1);
}

.equipment-search__thumb img {
	position: absolute;
	top: 3px;
	left: 3px;
	width: calc(100% - 6px);
	height: calc(100% - 6px);
	object-fit: contain;
	object-position: center;
}

.equipment-search__text {
	display: flex;
	flex-direction: column;
	gap: 6px;
	min-width: 0;
}

.equipment-search__meta,
.equipment-search__summary {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.equipment-search__meta {
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 10px;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--bca-steel-blue);
	opacity: 0.9;
}

.equipment-search__name {
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 18px;
	line-height: 1.1;
	letter-spacing: -0.03em;
}

.equipment-search__summary {
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 13px;
	line-height: 1.4;
	letter-spacing: -0.02em;
	opacity: 0.8;
}

.equipment-search__option--all {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 16px;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 14px;
	line-height: 1.1;
	text-transform: uppercase;
	color: var(--bca-steel-blue);
}

.equipment-search__empty {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: 16px;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

.equipment-search__empty-links {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 24px;
}

.equipment-search__empty-links a {
	color: var(--bca-tangerine);
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* -----------------------------------------------------------------------------
   Homepage equipment controls (D6 feedback, HOME-2 / HOME-5 / HOME-7)
   template-parts/sections/equipment.php; initBarArrows() and
   initHomeEquipment() in main.js

   Nothing here is a new language. The search is the shared field, set beside
   the band's CTA. The category tabs' arrows are the carousel's steel squares,
   with the row fading out beneath them. The filters are the catalogue rail's
   groups, checkboxes and chips — redrawn here because equipment.css only
   loads on the equipment pages — opening under the tabs on desktop and as
   the catalogue's slide-in panel below it.
-------------------------------------------------------------------------- */

/* Search and CTA: stacked under the copy on a phone, the field full width. */
.equipment .band__cta {
	flex-direction: column;
	align-items: flex-start;
	gap: 32px;
	width: 100%;
}

/* In the band the field sits on its rule like an inline input, rather than
   lining up with the catalogue's toggle row. */
.equipment-search--band .equipment-search__field {
	padding-bottom: 12px;
}

.equipment__controls {
	display: flex;
	flex-direction: column;
	gap: 32px;
	width: 100%;
	max-width: 1360px;
	margin-inline: auto;
}

/* The tabs and the toggle share the bar's hairline. On a phone the toggle
   takes its own line under the tabs, so the rule stays with them. */
.equipment__tools {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: 24px 40px;
}

.equipment__tabs {
	position: relative;
	flex: 1 1 100%;
	min-width: 0;
	border-bottom: var(--bca-hairline) solid rgba(40, 53, 124, 0.25);
}

/* The fade is a mask, so the tabs thin out into the panel's own texture
   under each arrow rather than into a flat wash, and the padding keeps a
   focused or chosen tab clear of the squares (see initBarArrows()). */
.equipment__tabs .filter-bar {
	border-bottom: 0;
	scroll-padding-inline: 88px;
	-webkit-mask-image: linear-gradient(to right, transparent var(--bar-l0, 0px), #000 var(--bar-l1, 0px), #000 calc(100% - var(--bar-r1, 0px)), transparent calc(100% - var(--bar-r0, 0px)));
	mask-image: linear-gradient(to right, transparent var(--bar-l0, 0px), #000 var(--bar-l1, 0px), #000 calc(100% - var(--bar-r1, 0px)), transparent calc(100% - var(--bar-r0, 0px)));
}

.equipment__tabs.can-prev .filter-bar {
	--bar-l0: 40px;
	--bar-l1: 88px;
}

.equipment__tabs.can-next .filter-bar {
	--bar-r0: 40px;
	--bar-r1: 88px;
}

/* The carousel's 40px square, level with the tab names, shown only while
   the row runs on that way. */
.equipment__step {
	position: absolute;
	top: 0;
	z-index: 1;
	padding: 4px;
	opacity: 0;
	visibility: hidden;
	transition: background-color 0.2s ease, opacity 0.2s ease, visibility 0s linear 0.2s;
}

.equipment__step--prev {
	left: 0;
}

.equipment__step--next {
	right: 0;
}

.equipment__tabs.can-prev .equipment__step--prev,
.equipment__tabs.can-next .equipment__step--next {
	opacity: 1;
	visibility: visible;
	transition: background-color 0.2s ease, opacity 0.2s ease;
}

/* "Show Filters" — the catalogue rail's toggle: the tangerine sliders mark
   ahead of Clash at 18px. */
.equipment__toggle {
	display: flex;
	align-items: center;
	gap: 16px;
	flex: none;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 18px;
	line-height: 1.1;
	letter-spacing: -0.03em;
	white-space: nowrap;
	color: var(--bca-midnight);
	transition: color 0.2s ease;
}

.equipment__toggle:hover {
	color: var(--bca-tangerine);
}

.equipment__toggle-icon {
	display: flex;
	color: var(--bca-tangerine);
}

/* Both words share one cell, so the toggle keeps its width as it flips and
   the tabs beside it never shift. */
.equipment__toggle-label {
	display: grid;
}

.equipment__toggle-label > span {
	grid-area: 1 / 1;
}

.equipment__toggle[aria-expanded="true"] .equipment__toggle-show,
.equipment__toggle:not([aria-expanded="true"]) .equipment__toggle-hide {
	visibility: hidden;
}

/* The rail's groups and checkboxes (equipment.css), for the homepage. */
.equipment-filter .filter-group__title {
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 18px;
	line-height: 1.1;
	letter-spacing: -0.03em;
	color: var(--bca-midnight);
}

.equipment-filter .filter-group__body,
.equipment-filter .filter-group__list,
.equipment-filter .filter-sub__list {
	display: flex;
	flex-direction: column;
}

.equipment-filter .filter-group__list,
.equipment-filter .filter-sub__list {
	gap: 12px;
	padding-bottom: 12px;
}

.equipment-filter .filter-sub__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding-block: 12px;
}

.equipment-filter .filter-sub__row .filter-option {
	flex: 1 1 auto;
	min-width: 0;
}

/* A top-level category reads in the small caps of the rail's parents,
   whether or not it has children to open. */
.equipment-filter .filter-sub__row .filter-option__label,
.equipment-filter__group--category .filter-group__body > .filter-group__list .filter-option__label {
	font-weight: 400;
	font-size: 12px;
	line-height: 1.3;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.equipment-filter__group--category .filter-group__body > .filter-group__list {
	justify-content: center;
	min-height: 48px;
	padding-block: 12px;
}

.equipment-filter .filter-sub__head {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 24px;
	height: 24px;
	color: var(--bca-midnight);
}

.equipment-filter .filter-sub__chevron {
	width: 16px;
	height: 16px;
	flex: none;
	color: var(--bca-tangerine);
	transition: transform 0.2s ease;
}

.equipment-filter .filter-sub__head[aria-expanded="true"] .filter-sub__chevron {
	transform: rotate(180deg);
}

.equipment-filter .filter-option__link {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	color: var(--bca-midnight);
	transition: color 0.2s ease;
}

.equipment-filter .filter-option__link:hover {
	color: var(--bca-tangerine);
}

.equipment-filter .filter-option__box {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 16px;
	height: 16px;
	flex: none;
	margin-top: 1px;
	border: var(--bca-hairline) solid rgba(40, 53, 124, 0.15);
	color: var(--bca-white);
	transition: background-color 0.2s ease, border-color 0.2s ease;
}

.equipment-filter .filter-option.is-checked .filter-option__box {
	background-color: var(--bca-tangerine);
	border-color: var(--bca-tangerine);
}

.equipment-filter .filter-option__tick {
	opacity: 0;
	transform: scale(0.6);
	transition: opacity 0.15s ease, transform 0.15s ease;
}

.equipment-filter .filter-option.is-checked .filter-option__tick {
	opacity: 1;
	transform: none;
}

.equipment-filter .filter-option__label {
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 13px;
	line-height: 1.4;
	letter-spacing: -0.02em;
}

/* The picks, as the catalogue's chips (51375:27203), with the count. */
.equipment__summary {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 16px 40px;
}

.equipment__chips {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 16px;
}

.equipment__summary .chip-set {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	min-height: 48px;
	padding: 0 24px;
	border-radius: 200px;
	background-color: #f0f0f0;
}

.equipment__summary .chip-set__label,
.equipment__summary .chip {
	font-family: var(--font-body);
	font-size: 14px;
	line-height: 1.2;
	letter-spacing: 0;
	color: var(--bca-midnight);
}

.equipment__summary .chip-set__label {
	font-weight: 500;
}

.equipment__summary .chip {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-weight: 300;
	transition: color 0.2s ease;
}

.equipment__summary .chip:hover {
	color: var(--bca-tangerine);
}

.equipment__summary .chip__remove {
	display: flex;
	flex: none;
	color: #2c2c2c;
	transition: color 0.2s ease;
}

.equipment__summary .chip__remove svg {
	width: 10px;
	height: 10px;
}

.equipment__summary .chip:hover .chip__remove {
	color: var(--bca-tangerine);
}

.equipment__clear {
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 16px;
	line-height: 1.2;
	color: #000;
	text-decoration: underline;
	text-underline-offset: 3px;
	transition: color 0.2s ease;
}

.equipment__clear:hover {
	color: var(--bca-tangerine);
}

.equipment__count {
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	color: var(--bca-midnight);
	opacity: 0.8;
}

/* In place of the rail when nothing matches every pick. */
.equipment__empty {
	width: 100%;
	max-width: 1360px;
	margin-inline: auto;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	color: var(--bca-midnight);
}

.equipment__empty a,
.equipment__empty button {
	color: var(--bca-tangerine);
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Locked behind the phone's panel. */
body.home-filter-open {
	overflow: hidden;
}

@media (max-width: 767.98px) {

	/* The pills stack, as on the catalogue's phone frame, with the count
	   under them. */
	.equipment__summary,
	.equipment__chips {
		flex-direction: column;
		align-items: flex-start;
	}
}

@media (min-width: 768px) {

	.equipment .band__cta {
		flex-direction: row;
		align-items: center;
		gap: 24px;
	}

	.equipment .band__cta .equipment-search {
		flex: 1 1 auto;
		width: auto;
	}

	.equipment__tools {
		flex-wrap: nowrap;
		border-bottom: var(--bca-hairline) solid rgba(40, 53, 124, 0.25);
	}

	.equipment__tabs {
		flex: 1 1 auto;
		border-bottom: 0;
	}

	/* Level with the tab names: their 10px of padding, then half a line. */
	.equipment__toggle {
		margin-top: 8px;
	}
}

@media (min-width: 768px) and (max-width: 1199.98px) {

	/* The heading keeps the band's first line; the search and the CTA share
	   the next. */
	.equipment .band {
		flex-wrap: wrap;
	}

	.equipment .band__cta {
		flex: 1 1 100%;
	}
}

/* Below the desktop frame the filters are the catalogue's phone panel
   (51375:50134): 310px sliding in from the right over a scrim, "Filters"
   and the round close at its head, the actions held at its foot. */
@media (max-width: 1199.98px) {

	.equipment-filter {
		position: fixed;
		inset: 0 0 0 auto;
		z-index: 50;
		display: flex;
		flex-direction: column;
		width: 310px;
		max-width: calc(100% - 40px);
		background-color: var(--bca-powder);
		transform: translateX(100%);
		visibility: hidden;
		transition: transform 0.3s ease, visibility 0s linear 0.3s;
	}

	.equipment-filter.is-open {
		transform: translateX(0);
		visibility: visible;
		transition: transform 0.3s ease;
	}

	.equipment-filter__head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 16px;
		flex: none;
		padding: 20px;
	}

	.equipment-filter__heading {
		font-family: var(--font-display);
		font-weight: 400;
		font-size: 26px;
		line-height: 1;
		letter-spacing: -0.03em;
		color: var(--bca-midnight);
	}

	.equipment-filter__close {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
		flex: none;
		border: var(--bca-hairline) solid rgba(40, 53, 124, 0.1);
		border-radius: 50%;
		color: var(--bca-midnight);
	}

	.equipment-filter__groups {
		flex: 1 1 auto;
		overflow-y: auto;
		overscroll-behavior: contain;
		padding-inline: 20px;
	}

	.equipment-filter__group {
		border-top: var(--bca-hairline) solid rgba(40, 53, 124, 0.1);
	}

	.equipment-filter .filter-group__title {
		padding-block: 24px 12px;
	}

	.equipment-filter__actions {
		display: flex;
		flex-direction: column;
		gap: 16px;
		flex: none;
		padding: 20px;
		border-top: var(--bca-hairline) solid rgba(40, 53, 124, 0.1);
	}

	.equipment-filter__actions .btn {
		width: 100%;
		padding: 14px 16px;
	}

	.equipment-filter__scrim {
		position: fixed;
		inset: 0;
		z-index: 40;
		background-color: rgba(8, 6, 36, 0.4);
	}

	/* While the panel is open the section is lifted over the sections after
	   it, so neither the panel nor the scrim slides under them. */
	.equipment.has-filter-drawer {
		z-index: 45;
	}
}

@media (min-width: 1200px) {

	/* The search keeps the width its example needs, beside the CTA; where
	   that and the heading's two drawn lines no longer fit across the band
	   (below about 1330px), the pair drops under the heading instead of
	   either one being squeezed. */
	.equipment .band {
		flex-wrap: wrap;
		row-gap: 32px;
	}

	.equipment .band__head {
		flex: 1 0 auto;
		width: auto;
	}

	.equipment .band__cta {
		flex: none;
		width: auto;
	}

	.equipment .band__cta .equipment-search {
		flex: none;
		width: 400px;
	}

	.equipment__step {
		top: 3px;
	}

	.equipment__toggle {
		margin-top: 11px;
	}

	/* Open under the tabs: Industry, Category and Brand side by side, ruled
	   apart, the families and brands running down two columns each. */
	.equipment-filter {
		padding-bottom: 32px;
		border-bottom: var(--bca-hairline) solid rgba(40, 53, 124, 0.1);
	}

	.equipment-filter__head,
	.equipment-filter__actions,
	.equipment-filter__scrim {
		display: none;
	}

	.equipment-filter__groups {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(0, 3fr) minmax(0, 2fr);
		gap: 40px;
	}

	.equipment-filter__group + .equipment-filter__group {
		padding-left: 40px;
		border-left: var(--bca-hairline) solid rgba(40, 53, 124, 0.1);
	}

	.equipment-filter .filter-group__title {
		margin-bottom: 16px;
	}

	.equipment-filter__group--category .filter-group__body,
	.equipment-filter__group--brand .filter-group__list {
		display: grid;
		grid-template-rows: repeat(var(--rows, 5), auto);
		grid-auto-columns: minmax(0, 1fr);
		grid-auto-flow: column;
		column-gap: 32px;
	}
}

@media (prefers-reduced-motion: reduce) {

	.equipment-filter,
	.equipment-filter.is-open {
		transition: none;
	}
}

/* -----------------------------------------------------------------------------
   Our process — desktop 51375:16252 / mobile 51375:29494
-------------------------------------------------------------------------- */

.process {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--section-64-88);
	padding: var(--section-64-88) var(--gutter);
}

/* Five hairlines the depth of the whole section, on the desktop grid's column
   boundaries. Not drawn on the mobile frame. */
.process__rules {
	display: none;
}

.process__intro {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--section-64-88);
	width: 100%;
	max-width: 1356px;
}

.process__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 16px;
	width: 100%;
}

.tag--white .tag__label {
	color: var(--bca-white);
}

.process__lede {
	width: 100%;
	max-width: 672px;
	font-family: var(--font-display);
	font-weight: 400;
	/* 24px @430 → 40px @1440 */
	font-size: clamp(24px, 17.188px + 1.5842vw, 40px);
	line-height: 1.1;
	letter-spacing: -0.02em;
	text-align: center;
	color: var(--bca-cream);
}

.process__lede-tail {
	color: var(--bca-cream-40);
}

.process__actions {
	display: flex;
	align-items: flex-start;
}

/* Mobile: a filled 2 × 2 closed by a hairline on every side. */
.process__grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	width: 100%;
	border-right: var(--bca-hairline) solid var(--bca-rule-cream);
	border-bottom: var(--bca-hairline) solid var(--bca-rule-cream);
}

.process__cell {
	position: relative;
	display: grid;
	grid-template-columns: 1fr;
	grid-template-areas:
		"num"
		"title"
		"body";
	align-content: start;
	gap: 24px;
	padding: 24px;
	border-top: var(--bca-hairline) solid var(--bca-rule-cream);
	border-left: var(--bca-hairline) solid var(--bca-rule-cream);
}

/* The tangerine tick that sits on the leading edge of each populated cell. */
.process__cell:not(.process__cell--blank)::before {
	content: "";
	position: absolute;
	top: 0;
	left: calc(var(--bca-hairline) * -1);
	width: 1px;
	height: 98px;
	background-color: var(--bca-tangerine);
}

.process__cell--blank {
	display: none;
}

.process__num {
	grid-area: num;
	justify-self: end;
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 10px;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--bca-powder);
	opacity: 0.4;
	white-space: nowrap;
}

.process__step-title {
	grid-area: title;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 18px;
	line-height: 1.1;
	letter-spacing: -0.03em;
	color: var(--bca-powder);
}

.process__step-body {
	grid-area: body;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-powder);
	opacity: 0.8;
}

@media (min-width: 1200px) {

	.process__intro {
		gap: 36px;
	}

	.process__lede {
		line-height: 1;
	}

	.process__rules {
		display: block;
		position: absolute;
		top: 0;
		bottom: 0;
		left: 50%;
		width: min(1130px, calc(100% - (var(--gutter) * 2)));
		transform: translateX(-50%);
		pointer-events: none;
	}

	.process__rules span {
		position: absolute;
		top: 0;
		bottom: 0;
		width: var(--bca-rule);
		background-color: var(--bca-rule-cream);
	}

	.process__rules span:nth-child(1) { left: 0; }
	.process__rules span:nth-child(2) { left: 25%; }
	.process__rules span:nth-child(3) { left: 50%; }
	.process__rules span:nth-child(4) { left: 75%; }
	.process__rules span:nth-child(5) { left: 100%; }

	/* The staircase: four columns, two rows, cells placed explicitly so the
	   reading order of the markup stays 001 → 004. */
	.process__grid {
		grid-template-columns: repeat(4, 1fr);
		/* Two equal card rows: the cell's top rule, the title band and the
		   frame's five lines of copy under the step gap — Figma's 293px plus
		   the hairline. Longer copy grows both rows alike instead of spilling
		   out of them, so the clip that follows the climb can never cut a
		   step's text (D6 feedback, HOME-10). */
		grid-auto-rows: minmax(calc(var(--process-step-gap, 94px) + 200px), 1fr);
		width: 1130px;
		max-width: 100%;
		border-right: 0;
		border-bottom: 0;
	}

	.process__cell {
		grid-column: var(--col);
		grid-row: var(--row);
		grid-template-columns: 1fr auto;
		grid-template-areas:
			"title num"
			"body  body";
		gap: var(--process-step-gap, 94px) 16px;
		/* The copy runs to the row's foot, as drawn — no padding under it to
		   inflate the rows. */
		padding-bottom: 0;
		border-left: 0;
	}

	.process__cell--blank {
		display: block;
	}

	/* The rule that closes the grid — drawn on the grid rather than as the
	   bottom row's border so it can ride the clipped edge up with the climb;
	   a border would stay behind on the vacated row. */
	.process__grid::after {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		bottom: calc(0px - var(--process-drift, 0px));
		height: var(--bca-hairline);
		background-color: var(--bca-rule-cream);
	}

	/* The staircase's scroll drift (main.js writes --process-drift on the
	   section): from the frame's own staircase, the lower pair's cards climb
	   one row to finish level with the upper pair. The contents and the
	   tangerine tick carry the motion — never the cell, so the hairline grid
	   holds still and the tick travels along its column rule. */
	.process__cell--row2:not(.process__cell--blank) > *,
	.process__cell--row2:not(.process__cell--blank)::before {
		transform: translateY(var(--process-drift, 0px));
		will-change: transform;
	}

	/* The room the climb vacates is given back at the same rate: the drift
	   pulls the grid's bottom margin up and clips the emptied bottom away,
	   so the visible grid always ends at the riding rule and whatever
	   follows keeps the section's own padding — or its own gap — below that
	   edge at every point of the scroll. The climb never exceeds the row,
	   so neither does the clip, and the upper pair's copy is never cut. */
	.process__grid {
		position: relative;
		margin-bottom: var(--process-drift, 0px);
		clip-path: inset(0 0 calc(0px - var(--process-drift, 0px)) 0);
	}

	.process__cell:not(.process__cell--blank)::before {
		left: 0;
		height: 105px;
	}

	.process__num {
		grid-area: num;
		align-self: start;
	}

	/* Fixed at the frame's 55px row — two line titles overflow it, exactly as
	   drawn, so the body copy starts 173px into every cell. */
	.process__step-title {
		height: 55px;
		font-size: 28px;
	}

	.process__step-body {
		font-size: 16px;
	}
}

/* Our process fits the viewport when the steps land (D6 feedback, HOME-10).
   The climb lands as the section's top reaches the top of the viewport, and
   the reader should then have the heading block and all four steps, copy
   included, on screen. At the frame's spacing (88 / 88 / 36 and a 94px step
   gap) the landed section is 860px tall — at home on a 900px viewport, not on
   a laptop's — so on shorter desktop viewports the vertical spacing steps
   down with the viewport's height: exact at 880px tall and above, at its
   floor (32 / 32 / 16 and a 40px gap) by 640, linear between. That holds the
   whole section on screen down to about a 620px tall window. The type is
   left as it is. */
@media (min-width: 1200px) {

	.process {
		--process-step-gap: clamp(40px, 22.5vh - 104px, 94px);
		padding-block: min(var(--section-64-88), clamp(32px, 23.333vh - 117.333px, 88px));
		gap: min(var(--section-64-88), clamp(32px, 23.333vh - 117.333px, 88px));
	}

	.process__intro {
		gap: clamp(16px, 8.333vh - 37.333px, 36px);
	}
}

/* Without motion there is no climb to watch, so the steps simply sit level
   in a single row and the staircase's empty cells are set aside. */
@media (min-width: 1200px) and (prefers-reduced-motion: reduce) {

	.process__cell.process__cell--row2 {
		grid-row: 1;
	}

	.process__cell--blank {
		display: none;
	}
}

/* -----------------------------------------------------------------------------
   Turnkey solutions — desktop 51375:16311 / mobile 51375:29531
-------------------------------------------------------------------------- */

.turnkey {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 64px;
	padding: 88px var(--gutter);
}

.turnkey__intro {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 64px;
	width: 100%;
}

.turnkey__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-end;
	gap: 16px;
	width: 100%;
}

.turnkey__statement {
	width: 100%;
	font-family: var(--font-display);
	font-weight: 400;
	/* 24px @430 → 40px @1440 */
	font-size: clamp(24px, 17.188px + 1.5842vw, 40px);
	line-height: 1.1;
	letter-spacing: -0.02em;
	text-align: center;
	color: var(--bca-midnight);
}

.turnkey__statement-tail {
	color: rgba(8, 6, 36, 0.4);
}

.turnkey__actions {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 16px;
}

.turnkey__list {
	display: flex;
	flex-direction: column;
	gap: 64px;
	width: 100%;
	/* The rows' own 1360 column: past the frame's width the deck centres
	   rather than dealing edge to edge. */
	max-width: 1360px;
	margin-inline: auto;
}

/* Mobile stacks the row; the gaps are uneven (48 / 16 / 48) so they are set as
   margins rather than one flex gap. */
.turnkey__row {
	display: grid;
	grid-template-columns: 1fr;
	grid-template-areas:
		"media"
		"name"
		"text"
		"cta";
	width: 100%;
	padding-bottom: 48px;
}

.turnkey__list > .turnkey__row:not(:last-child) {
	border-bottom: var(--bca-hairline) solid rgba(40, 53, 124, 0.25);
}

.turnkey__media {
	grid-area: media;
	display: block;
	width: 259px;
	max-width: 100%;
}

.turnkey__media img {
	width: 100%;
	height: auto;
	aspect-ratio: 259 / 180;
	object-fit: cover;
	transition: transform 0.4s ease;
}

/* The photo and the name are links to the row's page (Sep 2026): the photo
   eases in under the pointer, the name lifts to tangerine like the arrow. */
.turnkey__media {
	overflow: hidden;
}

.turnkey__media:hover img {
	transform: scale(1.03);
}

.turnkey__name-link {
	color: inherit;
	text-decoration: none;
	transition: color 0.2s ease;
}

.turnkey__name-link:hover,
.turnkey__name-link:focus-visible {
	color: var(--bca-tangerine);
}

.turnkey__name {
	grid-area: name;
	margin-top: 48px;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 24px;
	line-height: 1.1;
	letter-spacing: -0.03em;
	color: var(--bca-midnight);
}

.turnkey__text {
	grid-area: text;
	margin-top: 16px;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

.turnkey__cta {
	grid-area: cta;
	display: flex;
	margin-top: 48px;
}

/* Not drawn on the mobile frame. A link since Sep 2026 — it carries the
   row's destination, and lifts to tangerine under the pointer to say so. */
.turnkey__arrow {
	display: none;
	color: var(--bca-steel-blue);
	transition: color 0.2s ease;
}

.turnkey__arrow:hover,
.turnkey__arrow:focus-visible {
	color: var(--bca-tangerine);
}

.arrow-icon--large {
	width: 64px;
	height: 64px;
}

@media (min-width: 1200px) {

	.turnkey {
		align-items: flex-start;
		gap: 124px;
	}

	/* Statement left, both CTAs bottom right on one row, held to the 1360
	   content column past the frame's width. */
	.turnkey__intro {
		flex-direction: row;
		align-items: flex-end;
		justify-content: space-between;
		gap: 40px;
		max-width: 1360px;
		margin-inline: auto;
	}

	/* The drawn 901px measure, giving way on narrower desktops so the CTA
	   pair never leaves the viewport. */
	.turnkey__head {
		align-items: flex-start;
		width: auto;
		flex: 0 1 901px;
		min-width: 0;
	}

	.turnkey__statement {
		line-height: 1;
		text-align: left;
	}

	.turnkey__actions {
		gap: 12px;
		flex: none;
	}

	.turnkey__list {
		gap: 0;
		border-top: var(--bca-hairline) solid rgba(40, 53, 124, 0.25);
	}

	/* One 214px band: image, name, body and arrow across the full width. The
	   track ratios reproduce the drawn 442 / 48 / 200 / 45 / 516 / 45 / 64
	   rhythm and stay proportional below 1440. */
	/* The rows pin and stack as the section is scrolled: each one sticks to the
	   top of the viewport and the next slides up over it, so they deal like a
	   deck of cards rather than scrolling past. Each row needs to be opaque to
	   cover the one beneath, and to sit a layer above it — hence the index the
	   template stamps on each row.

	   Desktop only: the row is one band here, but the phone frame stacks the
	   photograph, name, copy and button into something taller than the viewport,
	   which cannot pin without trapping the reader. */
	.turnkey__row {
		position: sticky;
		top: 0;
		z-index: var(--row-index, 1);
		background-color: var(--bca-powder);
	}

	/* The panel's own noise, repeated on the row so the opaque ground it needs
	   does not read as a flat patch over the textured section. */
	.turnkey__row::before {
		content: "";
		position: absolute;
		inset: 0;
		z-index: -1;
		background-image: url("../images/panel-texture.png");
		background-size: 1048.8546px 534.8267px;
		background-position: top left;
		mix-blend-mode: soft-light;
		opacity: 0.8;
		pointer-events: none;
	}

	.turnkey__row {
		grid-template-columns: 442fr 248fr 561fr 109px;
		grid-template-areas:
			"media name text  arrow"
			"media name cta   arrow";
		align-content: start;
		padding-block: 48px;
		border-bottom: var(--bca-hairline) solid rgba(40, 53, 124, 0.25);
	}

	.turnkey__media {
		width: 100%;
	}

	.turnkey__media img {
		aspect-ratio: 442 / 214;
	}

	.turnkey__name {
		margin-top: 0;
		padding-left: 48px;
		font-size: 36px;
		letter-spacing: -0.02em;
	}

	.turnkey__text {
		margin-top: 0;
		padding-left: 45px;
		font-size: 16px;
	}

	/* Figma pins the button's underside flush with the photo's bottom edge
	   (fixed 171px text box + 4px + 39px button = the 214px media height). */
	.turnkey__cta {
		margin-top: 4px;
		padding-left: 45px;
		align-items: flex-end;
	}

	.turnkey__arrow {
		grid-area: arrow;
		display: flex;
		align-items: flex-start;
		justify-content: flex-end;
	}
}

/* -----------------------------------------------------------------------------
   Photo banner — desktop 51375:16347 / mobile 51375:29553

   Same 722px band in both frames. The corner brackets reuse the media frame's
   marks, sitting on the 40px padding box.
-------------------------------------------------------------------------- */

.banner {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	height: 722px;
	padding: 40px;
}

/* The equipment inner frame's band (53333:27652): a bare 344px still, no
   brackets, tick, wash or selector. */
.banner--plain {
	height: 344px;
	padding: 0;
}

.banner {
	/* Photograph comes from the Homepage options screen. */
	background-image: var(--banner-image);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
	overflow: hidden;
}

/* The band's footage, laid over the poster the section paints as its
   background so there is never a gap while the file loads. Everything else in
   the section — brackets, tick, thumbnails — sits above it. */
/* The band's footage, laid over the poster the section paints as its
   background so there is never a gap while the file loads. */
.banner__video {
	position: absolute;
	inset: 0;
	z-index: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border: 0;
	pointer-events: none;
	transition: opacity 0.6s ease;
}

/* The outgoing still, under the footage and over the section's background.
   Choosing a thumbnail puts the incoming poster on the background, then fades
   this layer and the footage out to reveal it, so the band crossfades rather
   than cuts (client, Sep 2026). */
.banner__still {
	position: absolute;
	inset: 0;
	z-index: 0;
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
	pointer-events: none;
	transition: opacity 0.6s ease;
}

.banner.is-switching .banner__still,
.banner.is-switching .banner__video {
	opacity: 0;
}

/* The frame's third fill: black at 40% over the footage. It has to be its own
   layer rather than baked into the still, because the video has to take the
   same wash as the poster it replaces. */
.banner__wash {
	position: absolute;
	inset: 0;
	z-index: 1;
	background-color: rgba(0, 0, 0, 0.4);
	pointer-events: none;
}

/* Everything the design draws on top of the band. */
.banner .media-frame__corner,
.banner__tick,
.banner__thumbs {
	z-index: 2;
}

.banner .media-frame__corner {
	--frame-arm: 16px;

	top: 40px;
	bottom: 40px;
	left: 40px;
	right: 40px;
	width: var(--frame-arm);
	height: var(--frame-arm);
	border-color: var(--bca-powder);
}

.banner .media-frame__corner--tl { bottom: auto; right: auto; }
.banner .media-frame__corner--tr { bottom: auto; left: auto; }
.banner .media-frame__corner--bl { top: auto; right: auto; }
.banner .media-frame__corner--br { top: auto; left: auto; }

/* The 53px hairline off the content box's right edge — Figma (51375:16366)
   parks it at x 1360..1413, 27px shy of the frame edge. */
.banner__tick {
	position: absolute;
	top: 441px;
	right: 27px;
	width: 53px;
	height: var(--bca-rule);
	background-color: var(--bca-rule-white);
	pointer-events: none;
}

/* The row is centred on the frame and, where it is wider than the band, runs
   as a rail the reader slides — swipe, drag or a tap on a tile — with the
   chosen tile brought to the centre. The frame crops the outer tiles at 430
   by design; they were unreachable that way, so the rail scrolls (client,
   Sep 2026). The inset padding lets the first and last tiles centre too. */
.banner__thumbs {
	position: absolute;
	/* Anchored to the band's bottom edge on the page rhythm — 88px clear —
	   so the row sits right whatever the band's height. */
	bottom: 88px;
	left: 0;
	right: 0;
	display: flex;
	align-items: center;
	justify-content: safe center;
	gap: 21px;
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.banner__thumbs::-webkit-scrollbar {
	display: none;
}

/* Only a row wider than the band is a rail; the script marks it, and the
   inset then lets its first and last tiles reach the centre. A row that
   fits stays put, centred, as the desktop frame draws it. */
.banner__thumbs.is-rail {
	padding-inline: calc(50% - 106.5px);
}

.banner__thumbs.is-dragging {
	cursor: grabbing;
	user-select: none;
	scroll-snap-type: none;
	scroll-behavior: auto;
}

/* Every tile wears the translucent mount — a white wash filling the 24px
   ring around the still — with the current one lifted by its powder rule
   and full-strength image. */
.banner__thumb {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	width: 213px;
	height: 160px;
	padding: 24px;
	flex: none;
	scroll-snap-align: center;
	border: var(--bca-hairline) solid rgba(40, 53, 124, 0.15);
	background-color: rgba(255, 255, 255, 0.1);
}

/* The thumbnail is the control that selects its clip, so the whole tile is the
   target — the button fills the tile's content box and the still fills it. */
.banner__thumb-btn {
	display: block;
	width: 100%;
	height: 100%;
}

.banner__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0.6;
	transition: opacity 0.25s ease;
}

.banner__thumb-btn:hover img {
	opacity: 0.85;
}

/* The selected frame lifts: powder rule and a 10% white wash behind the image. */
.banner__thumb--current {
	border-color: var(--bca-powder);
	background-color: rgba(255, 255, 255, 0.1);
}

.banner__thumb--current img {
	opacity: 1;
}

/* -----------------------------------------------------------------------------
   FAQ — desktop 51375:16374 / mobile 51375:29580
-------------------------------------------------------------------------- */

.faq {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 88px var(--gutter);
}

.faq__inner {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 64px;
	width: 100%;
}

.faq__copy {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
	width: 100%;
}

.faq__title {
	font-size: 32px;
	line-height: 1.1;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

.faq__lede {
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
	opacity: 0.8;
}

/* Mobile pushes the CTA a full 64px clear of the lede; desktop keeps it on the
   16px rhythm of the rest of the column. */
.faq__cta {
	display: flex;
	margin-top: 48px;
}

/* Both frames draw the panel inside a taller box — 358 × 637 on mobile,
   794 × 534 on desktop — but that box only ever held five questions' worth of
   panel. Given the site's four it left a blank band above and below the panel
   (QA, Sep 2026), so the frame now hugs the panel and the panel sits at the
   top beside the copy. */
.faq__frame {
	position: relative;
	display: flex;
	align-items: flex-start;
	width: 100%;
}

/* The bordered rectangle the component draws, with the crosshairs centred on
   its own four corners rather than on the taller frame around it. Figma
   (Accordion Tabs/Accordion): 786 × 420, 0.25px steel blue on all four sides,
   40px of padding and 20px between the questions. */
.faq__panel {
	position: relative;
	width: 100%;
	padding: 24px;
	border: var(--bca-hairline) solid var(--bca-mount-rule);
}

.accordion {
	display: flex;
	flex-direction: column;
	gap: 20px;
	width: 100%;
}

.accordion__item {
	padding-bottom: 24px;
	border-bottom: var(--bca-hairline) solid rgba(40, 53, 124, 0.25);
}

.accordion__item:last-child {
	padding-bottom: 0;
	border-bottom: 0;
}

.accordion__head {
	display: flex;
	align-items: center;
	gap: 16px;
	width: 100%;
	text-align: left;
}

.accordion__num {
	width: 15px;
	flex: none;
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 10px;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--bca-tangerine);
	opacity: 0.9;
}

.accordion__question {
	flex: 1 1 0;
	min-width: 0;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 18px;
	line-height: 1.1;
	letter-spacing: -0.03em;
	color: var(--bca-midnight);
}

/* The exported glyph points right; a quarter turn gives the drawn down state,
   and the open state flips it and takes the tangerine. */
.accordion__toggle {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: none;
	padding: 4px;
	border-radius: 2px;
	color: var(--bca-steel-blue);
	transition: color 0.2s ease, transform 0.2s ease;
	transform: rotate(90deg);
}

.accordion__item.is-open .accordion__toggle {
	color: var(--bca-tangerine);
	transform: rotate(-90deg);
	/* Open, the icon also stops propping up the head's height. Closed, the
	   40px icon is what the row centres a one-line question against; left in
	   place while open, that same centring leaves ~9px of dead air under a
	   one-line question and none under a wrapped one, so the answer's mount
	   below would vary with the line count. */
	margin-block: -9px;
}

/* The answer keeps the number column's indent so it lines up with the question. */
.accordion__body {
	display: flex;
	align-items: flex-start;
	gap: 16px;
	margin-top: 24px;
}

.accordion__body[hidden] {
	display: none;
}

.accordion__num--ghost {
	opacity: 0;
}

.accordion__answer {
	flex: 1 1 0;
	min-width: 0;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

@media (min-width: 1200px) {

	.faq {
		padding-block: 88px;
	}

	/* Copy left, the 794px accordion pinned right, 20px apart — the pair
	   held to the 1360 content column past the frame's width. */
	.faq__inner {
		flex-direction: row;
		align-items: flex-start;
		gap: 20px;
		max-width: 1360px;
		margin-inline: auto;
	}

	.faq__copy {
		flex: 1 1 0;
		min-width: 0;
		align-items: flex-start;
	}

	.faq__title {
		font-size: 40px;
		line-height: 1;
	}

	.faq__cta {
		margin-top: 0;
	}

	.faq__panel {
		padding: 40px;
	}

	.faq__frame {
		width: 794px;
		max-width: 100%;
		flex: none;
	}

	.faq__panel {
		padding: 40px;
	}

	.accordion {
		gap: 20px;
	}

	.accordion__question {
		line-height: 1.2;
		letter-spacing: 0;
	}

	.accordion__body {
		/* Measured from the question text now the open head hugs it — this
		   reproduces the mount the desktop frame drew, which the old 0 only
		   faked for one-line questions via the icon's centring slack. */
		margin-top: 10px;
	}

	.accordion__answer {
		font-size: 16px;
		opacity: 0.9;
	}
}

/* -----------------------------------------------------------------------------
   Featured case studies — desktop 51375:16391 / mobile 51375:29645
-------------------------------------------------------------------------- */

/* Unlike the equipment band, this one keeps its rules on the mobile frame and
   sits the CTA 48px under the heading. */
.band--ruled {
	gap: 48px;
	padding-block: 40px;
	border-top: var(--bca-hairline) solid rgba(40, 53, 124, 0.15);
	border-bottom: var(--bca-hairline) solid rgba(40, 53, 124, 0.15);
}

.case-studies {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: center;
	gap: 64px;
	padding: 64px var(--gutter);
	--card-w: 100%;
	--card-gap: 24px;
}

/* The card anchors the button's stretched ::after below, which makes the
   whole tile the study's click target while the button stays the only anchor
   in the tab order and the accessibility tree. Hovering anywhere on the card
   is hovering the anchor, so the button's hover fill fires card-wide too. */
.case-card {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 24px;
	width: 100%;
	height: 100%;
	padding: 24px;
	background-color: var(--bca-white);
}

.case-card .btn::after {
	content: "";
	position: absolute;
	inset: 0;
	/* Above the pill (z-index 1), or clicks on it would fall through. */
	z-index: 2;
}

.case-card__media {
	position: relative;
	display: block;
	width: 100%;
	height: 159px;
	overflow: hidden;
}

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

/* Top down scrim so the pill stays legible on any photograph. */
.case-card__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.6), rgba(102, 102, 102, 0));
	pointer-events: none;
}

.case-card__pill {
	position: absolute;
	left: 26px;
	top: 28px;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 8px 12px;
	background-color: rgba(255, 255, 255, 0.2);
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 10px;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--bca-white);
	opacity: 0.9;
	white-space: nowrap;
}

.case-card__meta {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
	width: 100%;
}

.case-card__row {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 16px;
	width: 100%;
}

.case-card__title {
	width: 246px;
	max-width: 100%;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 24px;
	line-height: 1.1;
	letter-spacing: -0.03em;
	color: var(--bca-midnight);
}

.case-card__company {
	flex: 1 1 0;
	min-width: 0;
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 10px;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-align: right;
	color: var(--bca-steel-blue);
	opacity: 0.9;
}

/* The title's fixed 246px measure leaves a phone card's corner too narrow
   for the company, which broke it into a ragged stack — below the bridge
   the company reads under the title instead. */
@media (max-width: 767.98px) {

	.case-card__row {
		flex-direction: column;
		align-items: flex-start;
		gap: 8px;
	}

	.case-card__company {
		flex: none;
		line-height: 1.5;
		text-align: left;
	}
}

.case-card__body {
	width: 100%;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 16px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
	opacity: 0.8;
}

@media (min-width: 1200px) {

	.case-studies {
		gap: 88px;
		padding-block: 88px;
		/* Three tiles across the 1360 content column with 24px gutters. */
		--card-w: calc((100% - 48px) / 3);
	}

	.band--ruled {
		gap: 40px;
	}

	.case-card {
		min-height: 502px;
	}

	.case-card__media {
		height: 209px;
	}
}

/* -----------------------------------------------------------------------------
   Client feedback — desktop 51375:16405 / mobile 51375:29671
-------------------------------------------------------------------------- */

.testimonials {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 64px;
	padding: 88px var(--gutter);
	--card-w: 350px;
	--card-gap: 24px;
}

.testimonials .band__head {
	align-items: center;
}

.testimonials__title {
	text-align: center;
}

.testimonials__row {
	display: flex;
	flex-direction: column-reverse;
	align-items: center;
	gap: 64px;
	width: 100%;
}

.quote-card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 40px;
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 24px;
	background-color: var(--bca-white);
}

.quote-card__person {
	display: flex;
	align-items: center;
	gap: 16px;
	width: 100%;
}

/* 72px midnight tile holding the partner mark at its exact Figma crop — the
   same .logo-crop leaf the partner strip uses, offset half a pixel down as
   drawn. */
.quote-card__mark {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 72px;
	height: 72px;
	flex: none;
	background-color: var(--bca-midnight);
	overflow: hidden;
}

.quote-card__mark .logo-crop {
	transform: translateY(0.5px);
}

.quote-card__identity {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: center;
	gap: 8px;
	color: var(--bca-midnight);
}

.quote-card__name {
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 28px;
	line-height: 1.1;
	letter-spacing: -0.03em;
}

.quote-card__role {
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 10px;
	line-height: 1.2;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	opacity: 0.9;
}

.quote-card__quote {
	margin: 0;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 16px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

@media (min-width: 1200px) {

	.testimonials {
		gap: 40px;
		/* Two 438.5px cards inside the 901px carousel drawn in the frame. */
		--card-w: calc((100% - 24px) / 2);
	}

	/* The band ignores the section gutter and runs the full frame width —
	   including past the 1360 cap the boxed bands take, or its 900px title
	   box slides off the carousel's left edge it aligns with. */
	.band--bleed {
		width: calc(100% + (var(--gutter) * 2));
		max-width: none;
		margin-inline: calc(var(--gutter) * -1);
		padding: 40px;
	}

	.testimonials .band {
		flex-direction: row;
		align-items: flex-start;
		justify-content: space-between;
	}

	.testimonials .band__head {
		flex-direction: row;
		align-items: flex-start;
		justify-content: space-between;
		gap: 40px;
		/* The rules bleed but the tag and title hold to the content column past
		   1440, keeping the 900px title box on the carousel's left edge. */
		max-width: 1360px;
		margin-inline: auto;
	}

	.testimonials__title {
		width: 900px;
		flex: none;
		font-size: 36px;
		line-height: 1.1;
		letter-spacing: -0.02em;
		text-align: left;
	}

	/* Nav bottom left, the 901px carousel bottom right — the pair held to
	   the 1360 content column past the frame's width. */
	.testimonials__row {
		flex-direction: row;
		align-items: flex-end;
		justify-content: space-between;
		gap: 24px;
		max-width: 1360px;
		margin-inline: auto;
	}

	.testimonials__row .carousel {
		width: 901px;
		flex: none;
		/* The shared rail centring would pull it off the row's right edge —
		   space-between is what places it here. */
		margin-inline: 0;
	}

	.quote-card {
		min-height: 280px;
	}
}

/* -----------------------------------------------------------------------------
   Resource centre — desktop 51375:16417 / mobile 51375:29694

   The only carousel on the dark ground, so the band rules, CTA and nav pair
   all take the powder treatment.
-------------------------------------------------------------------------- */

.insights {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: center;
	gap: 64px;
	padding: 88px var(--gutter);
	/* No fill of its own: the section sits on the page's midnight ground so the
	   glow at (816, 9717) can bloom through its top right corner. */
	--card-w: 260px;
	--card-gap: 16px;
}

.band--dark {
	border-top-color: var(--bca-rule-cream);
	border-bottom-color: var(--bca-rule-cream);
}

.band--dark .band__title {
	color: var(--bca-powder);
}

.insights .carousel-nav__btn {
	background-color: var(--bca-powder);
	color: var(--bca-midnight);
}

.insights .carousel-nav__btn:hover {
	background-color: var(--bca-white);
}

.insight-card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 24px;
	width: 100%;
}

.insight-card__media {
	position: relative;
	display: block;
	width: 100%;
	height: 262px;
	overflow: hidden;
}

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

.insight-card__pill {
	position: absolute;
	left: 22px;
	top: 20px;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 8px 12px;
	background-color: rgba(255, 255, 255, 0.2);
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 10px;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--bca-white);
	opacity: 0.9;
	white-space: nowrap;
}

.insight-card__meta {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 8px;
	width: 100%;
}

.insight-card__date {
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 10px;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--bca-tangerine);
	opacity: 0.9;
	white-space: nowrap;
}

.insight-card__row {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 16px;
	width: 100%;
}

.insight-card__title {
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 24px;
	line-height: 1.1;
	letter-spacing: -0.03em;
	color: var(--bca-powder);
}

/* The Resource Centre and the Insights index draw the tile on the powder panel
   rather than the midnight band the homepage draws it on, so its type inverts
   with the ground. */
.insight-card--panel .insight-card__title {
	color: var(--bca-midnight);
}

.insight-card--panel .insight-card__date {
	color: var(--bca-steel-blue);
}

.insight-card--panel .insight-card__go {
	background-color: var(--bca-steel-blue);
	color: var(--bca-powder);
}

/* Drawn at zero opacity — a hover reveal, as with the product card. */
.insight-card__go {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: none;
	width: 40px;
	height: 40px;
	border-radius: 2px;
	background-color: var(--bca-powder);
	color: var(--bca-midnight);
	opacity: 0;
	transition: opacity 0.25s ease;
}

.insight-card:hover .insight-card__go,
.insight-card:focus-visible .insight-card__go {
	opacity: 1;
}

@media (min-width: 1200px) {

	.insights {
		gap: 88px;
		--card-w: calc((100% - 48px) / 3);
		--card-gap: 24px;
	}

	.insight-card__media {
		height: 421px;
	}

	.insight-card__meta {
		gap: 16px;
	}

	.insight-card__title {
		font-size: 28px;
	}

	/* Desktop closes each card with a hairline. */
	.insight-card {
		padding-bottom: 16px;
		border-bottom: var(--bca-hairline) solid var(--bca-rule-cream);
	}

	/* On the homepage the frame stretches every card to a fixed 578px row, so
	   the closing rule paints 45px under the title (16px gap + the 10px zero
	   opacity meta line + 19px of stretch). */
	.insights .insight-card {
		padding-bottom: 45px;
	}

}

/* -----------------------------------------------------------------------------
   Contact — desktop 51382:65278 / mobile 51375:29724
-------------------------------------------------------------------------- */

.contact {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: 88px var(--gutter);
	isolation: isolate;
	/* Photograph comes from the Homepage options screen. */
	background-image:
		linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)),
		var(--contact-image);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

.contact__inner {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 64px;
	width: 100%;
}

.contact__copy {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
	width: 100%;
}

.contact__head {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
	width: 100%;
}

.contact__title {
	font-size: 32px;
	line-height: 1.1;
	letter-spacing: -0.02em;
	color: var(--bca-powder);
}

.contact__lede {
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 16px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-powder);
}

.contact__frame {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-width: 0;
}

.contact__card {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 48px;
	width: 100%;
	padding: 24px;
	background-color: var(--bca-white);
	border: var(--bca-hairline) solid var(--bca-mount-rule);
}

/* The card's marks and their ticks are drawn light — they sit out on the
   photograph rather than on the card. */
.contact__card .mark::before,
.contact__card .mark::after {
	background-color: var(--bca-white);
}

.contact__card .mark--tl .mark__tick,
.contact__card .mark--tr .mark__tick {
	background-image: linear-gradient(to top, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0));
}

.contact__card .mark--bl .mark__tick,
.contact__card .mark--br .mark__tick {
	background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0));
}

/* The enquiry tabs sit 23px apart rather than the 24 used elsewhere. The
   mobile frame sets the bar on a single line; the desktop card (51382:65289)
   draws it with the same blank second line as the catalogue and stage bars —
   a 60px bar — so desktop restores the base treatment below. */
.filter-bar--tight {
	gap: 23px;
}

.filter-bar--tight .filter-bar__tab {
	padding-block: 15px;
}

.filter-bar--tight .filter-bar__label::after {
	content: none;
}

@media (min-width: 1200px) {

	/* The card keeps the 18px tab the component draws — only the catalogue and
	   stage bars step up to 24px on desktop. */
	.filter-bar--tight .filter-bar__tab {
		padding-block: 10px 8px;
		font-size: 18px;
	}

	.filter-bar--tight .filter-bar__label::after {
		content: "\200B";
	}
}

/* One panel per tab; only the chosen one is in the card at a time. */
.contact__panel {
	width: 100%;
}

.contact__panel[hidden] {
	display: none;
}

.enquiry {
	display: flex;
	flex-direction: column;
	gap: 48px;
	width: 100%;
}

/* Contact Form 7 nests the fields inside its own wrapper and <form>, so the
   48px the frame sets between the fields and the foot row has to live on the
   form itself — on .enquiry it only ever separates CF7's own wrapper from
   nothing. */
.enquiry .wpcf7,
.enquiry .wpcf7-form {
	width: 100%;
}

.enquiry .wpcf7-form {
	display: flex;
	flex-direction: column;
	gap: 48px;
}

/* After Service opens on a line of copy the general form does not have — the
   tangerine rule beside it is the same accent the active tab is underlined in,
   so the card reads as a different form the moment the tab is moved. */
.enquiry__note {
	padding-left: 16px;
	border-left: 2px solid var(--bca-tangerine);
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.01em;
	color: var(--bca-midnight);
	opacity: 0.8;
}

/* The note sits tight to the fields it introduces rather than a full 48 off. */
.enquiry .enquiry__note {
	margin-bottom: -24px;
}

.enquiry__grid {
	display: grid;
	/* minmax(0, …) rather than 1fr: Contact Form 7 emits cols="40" on the
	   message field, whose intrinsic width would otherwise set the column's
	   floor and push the card past its gutter. */
	grid-template-columns: minmax(0, 1fr);
	gap: 24px 16px;
	width: 100%;
}

.enquiry__field {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 10px;
	min-width: 0;
	border-bottom: 1px solid rgba(8, 6, 36, 0.6);
}

.enquiry__label {
	width: 100%;
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 10px;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--bca-midnight);
}

.enquiry__input {
	width: 100%;
	min-width: 0;
	padding: 0 0 16px;
	border: 0;
	background: none;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 16px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

.enquiry__input::placeholder {
	color: var(--bca-midnight);
	opacity: 0.6;
}

.enquiry__input:focus {
	outline: 0;
}

.enquiry__field:focus-within {
	border-bottom-color: var(--bca-steel-blue);
}

/* The frame draws the message field five lines deep (53333:23819). Contact
   Form 7 emits rows="10" on its textareas, which a min-height cannot pull
   back, so the height is set outright — the field stays draggable. */
.enquiry__input--area {
	resize: vertical;
	/* Five 24px lines plus the 16px padding above the rule (51382:65300). */
	height: 136px;
	min-height: 136px;
}

/* The service form's only control that is not a plain field. It is drawn as
   one — same rule, same type — with the browser's own arrow replaced by the
   chevron the rest of the theme uses. */
.enquiry__input--select {
	appearance: none;
	padding-right: 24px;
	background-image: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23080624' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E" );
	background-repeat: no-repeat;
	background-position: right 2px top 8px;
	border-radius: 0;
	cursor: pointer;
}

/* Nothing chosen yet — read as the placeholder the text fields set. */
.enquiry__input--select:invalid {
	color: rgba(8, 6, 36, 0.6);
}

/* After Service picks up the tangerine on focus and on its submit; General
   Enquiry stays steel blue throughout. */
.enquiry--service .enquiry__field:focus-within {
	border-bottom-color: var(--bca-tangerine);
}

.enquiry__submit--service {
	background-color: var(--bca-tangerine);
	color: var(--bca-white);
}

.enquiry__submit--service:hover {
	background-color: #cf4419;
}

.enquiry__foot {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: space-between;
	gap: 24px;
	width: 100%;
}

/* Google renders its own widget here; the slot only reserves the drawn box. */
/* Google's widget is a fixed 302px iframe. Clipping the slot keeps that
   intrinsic width out of the card's min-content, so a narrow card can never be
   pushed wider than its column; main.js scales the widget down to fit. */
.enquiry__captcha {
	width: 100%;
	max-width: 302px;
	min-width: 0;
	min-height: 76px;
	overflow: hidden;
}

.enquiry__submit {
	gap: 16px;
}

.enquiry__submit-icon svg {
	width: 15px;
	height: 13px;
}

@media (min-width: 1200px) {

	.contact {
		padding-block: 88px;
	}

	/* 670px copy column against the 672px card. The two columns and the 680px
	   box the card is centred in fill the 1360 content column exactly, so the
	   gap is what is left of it — a wider one pushes the card past the right
	   gutter, which is not where any frame draws it. */
	.contact__inner {
		flex-direction: row;
		align-items: flex-start;
		justify-content: space-between;
		gap: 10px;
		max-width: 1360px;
		margin-inline: auto;
	}

	/* Both columns are fixed at the drawn widths on the 1440 frame and give
	   way proportionally on narrower desktops so the card never leaves the
	   viewport. The lede reads straight off the heading (53333:31354), not
	   bottom-anchored to the column. */
	.contact__copy {
		width: auto;
		gap: 32px;
		flex: 0 1 670px;
		min-width: 0;
	}

	.contact__title {
		font-size: 48px;
		line-height: 1;
		letter-spacing: 0;
	}

	.contact__lede {
		width: 350px;
		max-width: 100%;
	}

	.contact__frame {
		width: auto;
		min-height: 834px;
		flex: 0 1 680px;
		min-width: 0;
	}

	/* 672 inside the 680 frame — the marks keep their 4px overhang at every
	   width. */
	.contact__card {
		width: calc(100% - 8px);
		padding: 40px;
	}

	.enquiry__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.enquiry__field--wide {
		grid-column: 1 / -1;
	}

	.enquiry__foot {
		flex-direction: row;
		align-items: flex-end;
	}
}

/* -----------------------------------------------------------------------------
   Ambient glows — page level ellipses on the desktop frame (51375:15852)

   Each bloom is a 20% steel blue radial that fades to transparent at 71.9% of
   its radius, blurred 24.75px — the exact terms of the exported vector. The
   layer sits behind every section, so the opaque light panels hide most of them
   and only the ones over the dark ground read, as drawn.

   The mobile frame positions its own smaller set; they land behind opaque
   panels at that width, so the layer is desktop only.
-------------------------------------------------------------------------- */

.site-main {
	position: relative;
}

.page-glow {
	display: none;
}

.section-glow {
	display: none;
}

@media (min-width: 1200px) {

	.page-glow {
		display: block;
		position: absolute;
		inset: 0;
		z-index: -1;
		overflow: hidden;
		pointer-events: none;
	}

	/* Figma's own export of the grid plate, at its drawn offset. Its ground is
	   #080624 — the same midnight the body uses — so the plate's edges are
	   seamless and it simply stops where the artwork does.

	   Each frame places its own plates: the homepage drops one at y=507, and the
	   pages that open on a dark hero carry a second one starting above the top of
	   the frame so the squares run behind the hero too. The offsets come in as
	   custom properties rather than being fixed here. */
	.page-glow__grid {
		position: absolute;
		left: calc(50% - (var(--frame-desktop) / 2) + var(--grid-x, 0px));
		top: var(--grid-y, 507px);
		width: var(--grid-w, var(--frame-desktop));
		height: var(--grid-h, 1646px);
		/* A page can swap in its own export — the About hero's plate is a
		   different drawing than the shared one. The shared plate is the
		   2x re-export (Figma draws it as vectors; the old 1x raster read
		   soft on retina glass). */
		background-image: var(--grid-img, url("../images/grid-layer-2x.png"));
		background-size: 100% 100%;
		background-repeat: no-repeat;
	}

	/* A page hero draws its split on the hero plate's own rule at x=929, and
	   holds it 510px in from the stage's right edge (.page-hero__split).
	   Narrower than the 1440 stage a centred plate drifts off it, leaving a
	   second rule a few px beside the split (D6 feedback, ALL-1), so on those
	   pages the plates ride the stage's right edge instead — the same place at
	   1440 and wider, and one line at every width. */
	.site-main:has(> .page-hero) .page-glow__grid {
		left: calc(min(50% - (var(--frame-desktop) / 2), 100% - var(--frame-desktop)) + var(--grid-x, 0px));
	}

	.page-glow span:not(.page-glow__grid) {
		position: absolute;
		/* x is measured from the left edge of the centred 1440 frame. */
		left: calc(50% - (var(--frame-desktop) / 2) + var(--glow-x));
		top: var(--glow-y);
		width: var(--glow-size);
		height: var(--glow-size);
		border-radius: 50%;
		background-image: radial-gradient(
			circle,
			rgba(40, 53, 124, 0.2) 0%,
			rgba(73, 97, 226, 0) 71.9%
		);
		filter: blur(24.75px);
	}

	/* Blooms some sections carry inside their own frame, painted OVER their
	   plate rather than behind it — the values frame draws two (51375:16070,
	   51375:16196) and the equipment frame one. Coordinates are the section's
	   frame coordinates; negative tops bleed over the sections above, which is
	   how Figma stacks them. */
	.section-glow {
		display: block;
		position: absolute;
		/* Above the panels that follow, so a bloom that runs past its
		   section's bottom edge continues instead of being cut off. */
		z-index: 2;
		left: calc(50% - (var(--frame-desktop) / 2) + var(--glow-x));
		top: var(--glow-y);
		width: var(--glow-size);
		height: var(--glow-size);
		border-radius: 50%;
		background-image: radial-gradient(
			circle,
			rgba(40, 53, 124, 0.2) 0%,
			rgba(73, 97, 226, 0) 71.9%
		);
		filter: blur(24.75px);
		pointer-events: none;
	}
}

/* Below the desktop breakpoint the grid plates scale with the viewport —
   tan(atan2()) turns 100vw / 1440px into the plain ratio the frame-coordinate
   custom properties need. The glow blooms stay desktop only: their y
   coordinates are desktop page positions and the small layouts reflow far
   past them. Browsers without atan2() simply keep the layer hidden. */
@supports (top: calc(1px * tan(atan2(1vw, 1px)))) {

	@media (max-width: 1199.98px) {

		.page-glow {
			display: block;
			position: absolute;
			inset: 0;
			z-index: -1;
			overflow: hidden;
			pointer-events: none;
		}

		.page-glow span:not(.page-glow__grid) {
			display: none;
		}

		.page-glow__grid {
			position: absolute;
			left: calc(50% - 50vw + (var(--grid-x, 0px) * tan(atan2(100vw, 1440px))));
			top: calc(var(--grid-y, 507px) * tan(atan2(100vw, 1440px)));
			width: calc(var(--grid-w, var(--frame-desktop)) * tan(atan2(100vw, 1440px)));
			height: calc(var(--grid-h, 1646px) * tan(atan2(100vw, 1440px)));
			background-image: var(--grid-img, url("../images/grid-layer.webp"));
			background-size: 100% 100%;
			background-repeat: no-repeat;
		}

		/* Where a page lays two plates the shared one takes over where it
		   begins. On the midnight pages its own ground covers the hero plate
		   from there down, but the Artisan pair are both exported clear, and
		   the taller phone hero showed both lattices at once — every rule
		   doubled a few px from its neighbour (D6 feedback, ALL-1). So the
		   hero plate stops at the shared plate's 507px. */
		.page-glow__grid:has(+ .page-glow__grid) {
			clip-path: inset(0 0 calc(100% - (507px * tan(atan2(100vw, 1440px)))) 0);
		}
	}
}

/* -----------------------------------------------------------------------------
   Homepage order (D6 feedback, HOME-4)

   Equipment moved up under the partner strip, above both About Us sections.
   The page lays its backdrop by page position, so two things are re-anchored
   to keep each section on the ground it had:
     - The about statement's lattice. It was the lower part of "Grid layers -
       v3" (51375:15860); front-page.php now hangs the same plate from the
       statement's top edge (.page-glow-anchor), at the offset it had from it
       under the strip: 507 − (hero 546 + 2 × hero gap + strip 166). Phones
       never saw it — the plate ended inside their taller hero — so it stays
       desktop only.
     - The values panel's first bloom (51375:16070), drawn far above its own
       frame, would now land on the equipment panel's foot, which the client
       asked to keep clean (Sep 2026). The panel is lifted over it.
-------------------------------------------------------------------------- */

.page-glow-anchor {
	display: none;
}

@media (min-width: 1200px) {

	.page-glow-anchor {
		display: block;
		position: relative;
		z-index: -1;
		height: 0;
	}

	.page-glow-anchor .page-glow__grid {
		--grid-y: calc(-205px - (var(--hero-gap) * 2));
	}

	.equipment {
		z-index: 1;
	}
}

/* -----------------------------------------------------------------------------
   Page level marks that Figma parents to the frame rather than to a section.
   Both are desktop only — the 430 frame does not draw them.
-------------------------------------------------------------------------- */

.testimonials__edge {
	display: none;
}

@media (min-width: 1200px) {


	/* 51375:16474 — 0.25px white 20% rule down the frame's left edge. */
	.testimonials__edge {
		display: block;
		position: absolute;
		left: 0;
		top: 502px;
		width: var(--bca-rule);
		height: 1173px;
		background-color: var(--bca-rule-cream);
		pointer-events: none;
	}
}

/* -----------------------------------------------------------------------------
   Between the frames — 768px to 1199px

   Figma draws this page at two widths, 430 and 1440, and everything above is
   one or the other: the base rules are the 430 frame, the 1200px query is the
   1440 frame. That leaves the tablet and small laptop range rendering the phone
   layout stretched to 1199px, where single column stacks go sparse and lines of
   body copy run to nearly 1100px.

   This block is the transition between the two drawn frames and nothing else.
   It is bounded on both sides, so neither design width can ever see it: the
   430 frame keeps the base rules, the 1440 frame keeps the desktop query. Each
   rule below moves one property toward the desktop frame's own answer — the
   layout the design already specifies at the next width up — rather than
   introducing a third treatment.
-------------------------------------------------------------------------- */

@media (min-width: 768px) and (max-width: 1199.98px) {

	/* Reading measure. The mobile frame sets body copy in a 350px column; at
	   this width the same text would run the full gutter, so it is capped near
	   the desktop frame's own measure. */
	.hero__lede,
	.band__lede,
	.faq__lede,
	.contact__lede,
	.values__body {
		max-width: 62ch;
	}

	/* Hero — the feature band grows with the gutter instead of staying at the
	   350px the phone frame draws, keeping its 350 × 231 crop. It is a child of
	   the section rather than of the padded copy column, so the gutter has to
	   stay in the cap. */
	.hero__feature {
		width: 100%;
		max-width: min(700px, calc(100% - (var(--gutter) * 2)));
		height: auto;
		aspect-ratio: 350 / 231;
	}

	/* Heading bands put the call to action back beside the heading, which is
	   where the 1440 frame has it. */
	.band {
		flex-direction: row;
		align-items: flex-end;
		justify-content: space-between;
		gap: 40px;
	}

	.band__head {
		width: auto;
		flex: 1 1 auto;
		min-width: 0;
	}

	.band__cta {
		flex: none;
	}

	/* Values — the phone frame stacks the cells, the desktop frame runs them
	   as one row. Two columns is the step between. An odd last cell spans the
	   pair so the grid still closes. */
	.values__grid {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.values__cell,
	.values__cell:last-of-type {
		border-bottom: var(--bca-hairline) solid var(--rule);
	}

	.values__cell:last-of-type:nth-child(odd) {
		grid-column: 1 / -1;
	}

	/* Turnkey — media beside the copy, as the desktop row does, rather than a
	   259px thumbnail alone above a full width paragraph. */
	.turnkey__row {
		grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
		grid-template-areas:
			"media name"
			"media text"
			"media cta";
		align-content: start;
		column-gap: 40px;
	}

	.turnkey__media {
		width: 100%;
		align-self: start;
	}

	.turnkey__name {
		margin-top: 0;
	}

	.turnkey__cta {
		margin-top: 24px;
	}

	/* Carousels — the desktop frame shows three across, the phone one. Two is
	   the step between; the arithmetic matches the desktop rule's own form. */
	.equipment,
	.case-studies,
	.insights,
	.testimonials {
		--card-w: calc((100% - 24px) / 2);
	}

	/* FAQ and contact — both are a full width card on the phone frame and a
	   fixed column on the desktop one. Held at the desktop width and centred
	   so the fields and questions do not stretch past it. */
	.faq__frame {
		justify-content: center;
	}

	.faq__panel {
		max-width: 794px;
		margin-inline: auto;
	}

	.contact__card {
		max-width: 672px;
		margin-inline: auto;
	}

	.contact__frame {
		min-height: 0;
	}

	/* Footer — the phone frame stacks the six link groups into two columns and
	   the desktop frame lays them out as three. Promoting the merged pair to
	   siblings, exactly as the desktop query does, gets the three columns here
	   too: 154 + 115 + 133 plus two 40px gaps is 482px, which clears the 688px
	   of content this range starts with. The address stays on its own row —
	   moving it alongside is what would overflow. */
	.site-footer__intro {
		max-width: 560px;
	}

	.site-footer__merge {
		display: contents;
	}

	.site-footer__merge .site-footer__group {
		width: var(--group-width, auto);
	}

	/* The single line vector lockup carries this range better than the phone
	   frame's two line type, and it is the desktop frame's own treatment. */
	.site-footer__wordmark-img {
		display: block;
		width: 100%;
		height: auto;
		aspect-ratio: 1359.680908203125 / 70.56000518798828;
	}

	.site-footer__wordmark-text {
		display: none;
	}
}


/* =============================================================================
   Shared page hero — see template-parts/components/page-hero.php
   Used by About Us (51425:12201) and the Equipment archive (51375:26886).
============================================================================= */

/* -----------------------------------------------------------------------------
   Page hero — About Us 51425:12201 (1440 × 562), Equipment archive
   (inside 51375:26886), mobile 51375:32669 (430 × 774)

   The navigation is the hero's first child in every frame, drawn on the same
   midnight ground the section sits on, so the existing absolutely positioned
   header simply overlays it and the section clears its height. Shared by both
   pages through template-parts/components/page-hero.php.
-------------------------------------------------------------------------- */

.page-hero {
	position: relative;
	display: flex;
	flex-direction: column;
	/* Mobile nav = 24 + 64 icon + 24 = 112, and the frames open the copy block
	   50 below the bar at both widths. */
	padding-top: 162px;
}

.page-hero__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 40px;
	/* 430 × 526: the frames set the block's height and spread the copy and the
	   call to action to its two ends. A minimum rather than a fixed height, so
	   a hero with more to say — Aftersales runs its contact lines here — grows
	   instead of spilling its buttons onto the marquee below. */
	min-height: 526px;
	padding: var(--gutter) var(--gutter) 72px;
	border-bottom: var(--bca-hairline) solid var(--bca-rule-white);
}

.page-hero__head {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
}

/* 64px @430 → 88px @1440, the frame's own two sizes. */
.page-hero__title {
	font-family: var(--font-display);
	font-weight: 400;
	font-size: clamp(64px, 53.78px + 2.3762vw, 88px);
	line-height: 0.9;
	letter-spacing: -0.02em;
	color: var(--bca-white);
}

.page-hero__lines {
	display: flex;
	flex-direction: column;
	gap: 20px;
	margin: 30px 0 0;
	padding: 0;
	list-style: none;
}

.page-hero__line {
	display: flex;
	align-items: center;
	gap: 16px;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-white);
}

/* The 16px on the line is the icon's spacing; the frame sets the bold prefix
   and the address a word apart, so the pair is its own box. */
.page-hero__line-copy {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 6px;
	min-width: 0;
}

.page-hero__line-label {
	flex: none;
	font-weight: 600;
	color: var(--bca-white);
}

.page-hero__line-icon {
	display: flex;
	flex: none;
	color: var(--bca-white);
}

.page-hero__line a:hover {
	text-decoration: underline;
}

/* The head is fixed at 139 where no lines are drawn; with them it grows. */
.page-hero__head:has(.page-hero__lines) {
	height: auto;
}

.page-hero__aside {
	display: flex;
	flex-direction: column;
	gap: 40px;
}

.page-hero__lede {
	font-family: var(--font-body);
	/* The frames set the line in the body face's light weight, as every other
	   paragraph on the site is set — at 400 the last word of the 430 frame's
	   second line no longer clears the gutter. */
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-white);
}

.page-hero__actions {
	display: flex;
	align-items: flex-start;
	gap: 16px;
	/* Narrower than the drawn frame the pair no longer clears one row, so it
	   wraps rather than running the second button past the gutter. */
	flex-wrap: wrap;
}

/* The rule between the two columns is desktop only. */
.page-hero__split {
	display: none;
}

/* The marquee is the homepage's, but the hero holds it to the frame's own
   rhythm: 48px clear of the copy block and flush to the bottom of the band,
   rather than the 40px it carries either side on the homepage. */
.page-hero .partners {
	padding-block: 0;
}


@media (min-width: 768px) and (max-width: 1199.98px) {
	.page-hero__inner {
		flex-direction: row;
		align-items: flex-start;
		justify-content: space-between;
		gap: 40px;
	}

	.page-hero__head { flex: 1 1 auto; min-width: 0; }
	.page-hero__aside { width: 340px; flex: none; }
}

@media (min-width: 1200px) {
	/* The bar is 89px on this breakpoint; the client file's Hero Banners opens
	   the copy block 48 below it (gap-[48px]), putting the tag on 177 and
	   closing the band on 562. */
	.page-hero {
		padding-top: 137px;
	}

	/* 1440 × 339, 40px padding, the two columns 40px apart. */
	.page-hero__inner {
		flex-direction: row;
		align-items: flex-start;
		gap: 40px;
		min-height: 339px;
		/* Full width up to the 1440 stage: the explicit width matters — the
		   inner is a flex child, and auto margins switch a widthless flex
		   item to shrink-to-fit, which floats the copy as a narrow island. */
		width: 100%;
		max-width: 1440px;
		margin-inline: auto;
		padding: var(--gutter);
	}

	/* The 1440 frame sets the line a weight up from the 430 one. */
	.page-hero__lede {
		font-weight: 400;
	}

	.page-hero__head {
		flex: 1 1 0;
		min-width: 0;
		height: 139px;
	}

	.page-hero__aside {
		width: 403px;
		height: 219px;
		flex: none;
		justify-content: space-between;
		gap: 0;
	}

	.page-hero__lede {
		width: 392px;
	}

	.page-hero__actions {
		gap: 12px;
	}

	/* The hairline the frame runs between the two columns, from the bar's
	   underline down to the rule that closes the copy block. The frame draws
	   it 68px left of the 403px aside — anchored from the right so the
	   relationship holds on viewports wider than 1440. 510px in puts the 1px
	   rule on x=929 at exactly 1440, the column the hero plate draws its own
	   rule on, so the two read as the one line the frame draws; the plates
	   keep that rule under it at other widths (D6 feedback, ALL-1). */
	.page-hero__split {
		display: block;
		position: absolute;
		right: 510px;
		top: -48px;
		bottom: 0;
		width: var(--bca-rule);
		background-color: var(--bca-rule-white);
	}

}


/* =============================================================================
   The light navigation

   Driven by the has-light-header body class, which any view can carry (see
   bakery_uses_light_header) — so these rules are global rather than living
   with one page's stylesheet.
============================================================================= */

/* -----------------------------------------------------------------------------
   The light navigation

   This is the only frame that opens on the powder panel, so the bar that
   overlays it inverts: the steel cut of the logo, midnight links, and the
   hairline in steel rather than powder. The contact panel keeps its steel fill
   and white label either way.
-------------------------------------------------------------------------- */

.has-light-header .site-header {
	/* 0.25px solid steel in the client file — 0.25 under the quarter rule. */
	border-bottom-color: rgba(40, 53, 124, 0.25);
}

.has-light-header .primary-nav__link,
.has-light-header .primary-nav__toggle {
	color: var(--bca-midnight);
}

.has-light-header .primary-nav__link:hover {
	color: var(--bca-tangerine);
}

.has-light-header .nav-toggle {
	color: var(--bca-steel-blue);
}

.has-light-header .nav-toggle path {
	stroke: var(--bca-steel-blue);
}

/* The powder logo would vanish on this ground, so the steel cut is swapped in
   with the same two files the mobile menu already uses. */
.has-light-header .site-header .site-logo__mark {
	content: url("../images/logo-mark-steel.svg");
}

.has-light-header .site-header .site-logo__word {
	content: url("../images/logo-word-steel.svg");
}



/* =============================================================================
   Panel hero — a supplier 51375:20183, Insights 51375:18145,
   mobile 51375:32373 / 51375:34307

   The hero drawn on the powder panel rather than the midnight ground the rest
   of the site's heroes use, so the header inverts with it. The copy runs down
   the left with its buttons closing the column, and a plate hangs in a hairline
   frame on the right that runs off the frame's edge — a supplier's mark on one
   page, a photograph on the other. Rendered from
   template-parts/components/panel-hero.php.
============================================================================= */

/* The one hero drawn on the powder panel rather than a dark ground, so the
   header inverts with it. The phone frame stacks the plate under the copy. */

.panel-hero {
	display: flex;
	flex-direction: column;
	/* 519 → 640 between the buttons and the plate's frame on the 430 frame. */
	gap: 120px;
	/* Clears the 112px the nav occupies at this width; the frame opens 88
	   below it. */
	padding: 200px var(--gutter) 97px;
	background-color: var(--bca-powder);
}

/* "Grid layers - v3" (53333:27731) — the lattice the frame lays behind the top
   of the page: 20 verticals and 20 horizontals on an 80.687px module, drawn in
   steel blue. The dark pages get the same idea from grid-layer.webp, but that
   plate is a midnight ground with light lines, so it cannot sit on the powder;
   this is the frame's own layer exported as it composites — lines together
   with the "grid blocker" shapes above them, which are what fade the lattice
   out through the middle of the hero and back in below it.

   The plate runs on past the hero, but the frame stops it dead at the hero's
   bottom edge — sampling the render finds the lattice at full strength through
   y730 and nothing below it. That is the next section's own opaque ground
   covering the overhang, so the hero is deliberately not lifted here. */
@media (min-width: 1200px) {

	.panel-hero::after {
		content: "";
		position: absolute;
		z-index: -1;
		/* The layer is exported clipped to the frame, so it lands 1:1 on the
		   page: no offset, the frame's own width, and the 1395 the plate runs
		   to before it stops. Its rules hold the plate frame's left edge where
		   the 1440 frame has it, 56px past one and 25px short of the next, at
		   every width (D6 feedback, ALL-1): flush left below 1440, where the
		   frame stays at x=743, and past it as near centred as whole 80.685px
		   modules allow, since the frame rides the screen's right edge there.
		   Centred outright, a rule ran a few px beside the frame's edge at
		   common laptop widths. The plain value is the fallback where round()
		   is not supported. */
		left: max(0px, 50% - (var(--frame-desktop) / 2));
		left: max(0px, 100% - var(--frame-desktop) - round(50% - (var(--frame-desktop) / 2), 80.685px));
		top: 0;
		width: var(--frame-desktop);
		height: 1395px;
		background-image: url("../images/hero-grid.webp");
		background-size: 100% 100%;
		background-repeat: no-repeat;
		pointer-events: none;
	}
}

/* The small frames carry the same lattice, scaled with the viewport — the
   ratio trick that scales the dark plates below 1200px. Browsers without
   atan2() keep the plain ground. */
@supports (top: calc(1px * tan(atan2(1vw, 1px)))) {

	@media (max-width: 1199.98px) {

		.panel-hero::after {
			content: "";
			position: absolute;
			z-index: -1;
			left: calc(50% - 50vw);
			top: 0;
			width: 100vw;
			height: calc(1395px * tan(atan2(100vw, 1440px)));
			background-image: url("../images/hero-grid.webp");
			background-size: 100% 100%;
			background-repeat: no-repeat;
			pointer-events: none;
		}
	}
}

.panel-hero__copy {
	display: flex;
	flex-direction: column;
	gap: 40px;
	width: 100%;
}

.panel-hero__head {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 14px;
	width: 100%;
}

.panel-hero__title {
	width: 100%;
	font-family: var(--font-display);
	font-weight: 400;
	/* 40px @430 → 72px @1440 */
	font-size: clamp(40px, 26.38px + 3.1683vw, 72px);
	line-height: 1.1;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

/* The frames open more air under the title than the 16px the head sets between
   the tag and it — 47px of ink on the 430 frame. */
.panel-hero__lede {
	width: 100%;
	margin-top: 24px;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
	opacity: 0.8;
}

/* The plate hangs in the same hairline box with a crosshair on each corner the
   rest of the site hangs its plates in — 24px clear of the plate here, 48 on
   the 1440 frame. */
.panel-hero__frame {
	position: relative;
	width: 100%;
	padding: 24px;
	border: var(--bca-hairline) solid var(--bca-mount-rule);
}

/* The mark sits on a white plate rather than the panel's powder. */
.panel-hero__plate {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 217px;
	padding: 24px;
	background-color: var(--bca-white);
}

/* The mark fills the plate's padded box — scaled up to it, not just capped
   by it, so a small logo file still draws at the size the frame sets
   (53333:29448 runs Hengel's mark the width of the box). */
.panel-hero__plate--contain .panel-hero__mark {
	width: 100%;
	height: 100%;
	object-fit: contain;
	object-position: center;
}

/* The Insights frame fills the plate with its photograph rather than centring a
   mark inside it, so that plate spends no padding. */
.panel-hero__plate--cover {
	padding: 0;
}

.panel-hero__plate--cover .panel-hero__mark {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* A clip laid over the still (Case Studies and Insights heroes, Sep 2026):
   it fills the plate edge to edge, and the still underneath is its poster
   until the first frame arrives. */
.panel-hero__plate {
	position: relative;
	overflow: hidden;
}

.panel-hero__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border: 0;
	pointer-events: none;
}



	/* The 1440 frame runs the copy and the plate side by side. The plate's
	   frame runs off the right edge, so the section closes its right gutter. */

@media (min-width: 1200px) {

	.panel-hero {
		flex-direction: row;
		align-items: flex-start;
		justify-content: space-between;
		gap: 33px;
		/* The frame runs the plate off the screen's right edge, and it stays
		   pressed against it at every width (client, Sep 2026) — only the
		   copy rides the centred 1440 stage. */
		padding: 177px 0 54px max(var(--gutter), calc((100% - 1440px) / 2 + var(--gutter)));
	}

	.panel-hero__copy {
		width: 670px;
		flex: none;
		justify-content: space-between;
		/* The frame closes the copy 488 below its tag, which is what puts the
		   buttons where it draws them. */
		min-height: 488px;
	}

	/* The frame sets the tag 11 clear of the title and the title 7 clear of the
	   paragraph, so the head runs on the closer of the two and the title takes
	   the difference. */
	.panel-hero__head {
		gap: 7px;
	}

	.panel-hero__title {
		margin-top: 4px;
	}

	.panel-hero__lede {
		width: 390px;
		max-width: 100%;
		margin-top: 0;
	}

	.panel-hero__frame {
		width: 697px;
		/* Fixed at the drawn width on the 1440 frame and shrinking with the
		   gutter below it, so the plate never runs past the viewport. */
		flex: 0 1 auto;
		min-width: 0;
		/* 48px clear of the plate on three sides, less the hairline each edge
		   already spends; the fourth runs off frame. */
		padding: 49px 0 48px 47px;
		border-right: 0;
		margin-top: 2px;
		--mark-size: 8px;
	}

	.panel-hero__plate {
		width: 100%;
		height: 396px;
		padding: 56px;
	}

	.panel-hero__plate--cover {
		padding: 0;
	}
}

/* Between the frames — the plate keeps the 430 frame's proportions as the
   gutter opens. */

@media (min-width: 768px) and (max-width: 1199.98px) {

	.panel-hero__plate {
		height: auto;
		aspect-ratio: 302 / 217;
	}
}


/* =============================================================================
   Back link — an insight 51375:18790, a case study 51375:24954

   The small uppercase link back to the index an article opens on, with the
   shared arrow glyph turned back on itself.
============================================================================= */

.article-head__back {
	display: flex;
	align-items: center;
	gap: 12px;
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 11px;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--bca-steel-blue);
}

.article-head__back-icon {
	display: flex;
	/* One exported glyph, turned back on itself for the return. */
	transform: rotate(180deg);
}

.article-head__back-icon svg {
	width: 24px;
	height: 24px;
}

.article-head__back:hover {
	text-decoration: underline;
}



/* =============================================================================
   Legal pages — 51439:11221 / 51439:12155, mobile 51439:11689 / 51439:12506

   The headline over the page's own content. The content itself is the
   editor's, dressed by the article rules — see assets/css/article.css, which
   these pages load with them.
============================================================================= */

.legal-page {
	background-color: var(--bca-powder);
	color: var(--bca-midnight);
}

.legal-head {
	/* Clears the 112px the nav occupies at this width. */
	padding: 152px var(--gutter) 0;
}

.legal-head__title {
	font-family: var(--font-display);
	font-weight: 400;
	/* 40px @430 → 72px @1440 */
	font-size: clamp(40px, 26.38px + 3.1683vw, 72px);
	line-height: 1.1;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

.legal-copy {
	padding: var(--section-64-88) var(--gutter);
}

@media (min-width: 1200px) {

	.legal-head {
		padding-top: 176px;
		max-width: 1440px;
		margin-inline: auto;
	}

	.legal-copy {
		padding: 165px var(--gutter) 120px;
		max-width: 1440px;
		margin-inline: auto;
	}

	/* The frame runs the copy the full width of the content column rather
	   than the 970 the article sets beside its share rail — and that column
	   rides the centred 1440 stage past the frame's width, like every other
	   section. */
	.legal-copy.article-copy {
		width: auto;
		max-width: 1440px;
	}
}


/* =============================================================================
   404 — 51439:12758 / 51439:13109

   One centred block on the powder panel, closing straight onto the footer.
============================================================================= */

.error-page {
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: var(--bca-powder);
	color: var(--bca-midnight);
	padding: 152px var(--gutter) var(--section-64-88);
}

.error-page__inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 24px;
	width: 100%;
	text-align: center;
}

.error-page__code {
	font-family: var(--font-display);
	font-weight: 400;
	/* 56px @430 → 124px @1440 */
	font-size: clamp(56px, 27.05px + 6.7327vw, 124px);
	line-height: 1;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

.error-page__text {
	width: 520px;
	max-width: 100%;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 16px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
	opacity: 0.8;
}

.error-page__actions {
	justify-content: center;
}

@media (min-width: 1200px) {

	.error-page {
		padding: 172px var(--gutter) 100px;
	}

	.error-page__inner {
		gap: 37px;
	}

	.error-page__actions {
		margin-top: 6px;
	}
}


/* =============================================================================
   Contact Us — 51375:25460 (1440 × 2149), mobile 51375:32207

   The copy and the contact details down the left, the site's own tabbed
   enquiry card in a corner marked frame on the right. The card itself is the
   contact band's — see template-parts/components/enquiry-card.php — so only
   the frame and the details column are written here.
============================================================================= */

.contact-page {
	background-color: var(--bca-powder);
	color: var(--bca-midnight);
}

.contact-page__inner {
	display: flex;
	flex-direction: column;
	gap: 48px;
	/* Clears the 112px the nav occupies at this width. */
	padding: 152px var(--gutter) var(--section-64-88);
}

.contact-page__copy {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 24px;
}

.contact-page__title {
	font-family: var(--font-display);
	font-weight: 400;
	/* 32px @430 → 40px @1440 */
	font-size: clamp(32px, 28.6px + 0.7921vw, 40px);
	line-height: 1.1;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

.contact-page__details {
	display: flex;
	flex-direction: column;
	gap: 16px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.contact-page__detail {
	display: flex;
	align-items: flex-start;
	gap: 16px;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 16px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

.contact-page__icon {
	display: flex;
	flex: none;
	color: var(--bca-steel-blue);
}

.contact-page__detail a:hover {
	text-decoration: underline;
}

.contact-page__social {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 8px 0 0;
	padding: 0;
	list-style: none;
}

.contact-page__social-link {
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--bca-steel-blue);
	transition: color 0.2s ease;
}

.contact-page__social-link:hover,
.contact-page__social-link:focus-visible {
	color: var(--bca-tangerine);
}

/* The card hangs in the hairline frame the rest of the site hangs its plates
   in, rather than on the photograph the contact band sets it on. */
.contact-page__frame {
	position: relative;
	--mark-size: 4.566px;
	/* The rule these marks sit on is the card's border, not this frame's. */
	--mark-border: 0px;
}

/* The contact band centres its card inside a wider frame and hangs the marks
   on the card itself, so it insets the card by 8px. Here the marks are on the
   frame and the frame is not a centring flex box, so that inset would leave the
   card 8px short on the right and the two right hand marks off its corner. */
.contact-page__frame .contact__card {
	width: 100%;
	border: var(--bca-hairline) solid var(--bca-mount-rule);
}

@media (min-width: 1200px) {

	.contact-page__inner {
		flex-direction: row;
		align-items: flex-start;
		justify-content: space-between;
		gap: 40px;
		max-width: 1440px;
		margin-inline: auto;
		padding: 176px var(--gutter) 120px;
	}

	.contact-page__copy {
		width: 610px;
		flex: none;
		gap: 32px;
	}

	.contact-page__title {
		width: 520px;
		max-width: 100%;
	}

	.contact-page__frame {
		width: 672px;
		flex: 0 1 auto;
		min-width: 0;
		--mark-size: 8px;
	}
}


/* =============================================================================
   The stepped After Service form — 51382:62315 / 62347 / 62408 / 62434,
   51395:24776 / 25552 / 25630

   The After Service tab is not one form but four groups opened one at a time:
   the personal details, the product, an upload and the message. Each head
   carries a mark that fills in once its fields are answered, and Next Step
   moves to the one below.
============================================================================= */

.enquiry-steps {
	display: flex;
	flex-direction: column;
	width: 100%;
}

.enquiry-step {
	border-bottom: var(--bca-hairline) solid rgba(40, 53, 124, 0.1);
}

.enquiry-step__head {
	display: flex;
	align-items: center;
	gap: 16px;
	width: 100%;
	padding-block: 20px;
	text-align: left;
	color: var(--bca-midnight);
}

/* Dotted while the group is unanswered, a filled tick once it is. */
.enquiry-step__mark {
	position: relative;
	display: block;
	width: 20px;
	height: 20px;
	flex: none;
	border: 1.5px dashed var(--bca-tangerine);
	border-radius: 50%;
}

.enquiry-step.is-done .enquiry-step__mark {
	border-style: solid;
	border-color: var(--bca-steel-blue);
}

.enquiry-step.is-done .enquiry-step__mark::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: 6px;
	height: 10px;
	border: solid var(--bca-steel-blue);
	border-width: 0 1.5px 1.5px 0;
	/* Once rotated, the tick's strokes all sit below its box's centre, so
	   centring it in the circle takes more lift than -50%. */
	transform: translate(-50%, -68%) rotate(45deg);
}

.enquiry-step__title {
	flex: 1 1 auto;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 18px;
	line-height: 1.1;
	letter-spacing: -0.02em;
}

.enquiry-step__chevron {
	display: flex;
	flex: none;
	color: var(--bca-tangerine);
	transition: transform 0.2s ease;
}

.enquiry-step.is-open .enquiry-step__chevron {
	transform: rotate(180deg);
}

.enquiry-step__body {
	padding-bottom: 24px;
}

.enquiry-step__body[hidden] {
	display: none;
}

.enquiry__hint {
	grid-column: 1 / -1;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
	opacity: 0.7;
}

.enquiry__input--file {
	padding-block: 12px;
}

.enquiry__foot--steps {
	display: flex;
	align-items: center;
	gap: 16px;
}

.enquiry__next {
	display: flex;
	align-items: center;
	gap: 12px;
}

.enquiry__next-icon {
	display: flex;
}

/* Only the last group closes on the real submit; the ones before it advance.
   The script stamps is-last on the foot itself. */
.enquiry__foot--steps:not(.is-last) .enquiry__submit,
.enquiry__foot--steps.is-last .enquiry__next {
	display: none;
}


/* =============================================================================
   Contact carousel — 51375:25895 / 25956 / 26017

   A midnight band with the enquiry card's tab bar over a row of white contact
   cards. Measured from the Industrial Sales frame: the band opens on 88, the
   bar closes on its rule at 194, the cards open 89 under it and the band
   closes on 89 — three 437 cards, 25 apart.
============================================================================= */

.contact-people {
	background-color: var(--bca-midnight);
	color: var(--bca-cream);
	padding: var(--section-64-88) var(--gutter);
}

.contact-people__inner {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	width: 100%;
	/* Boxed to the 1360 content column past the frame's width, tag, tabs
	   and cards together. */
	max-width: 1360px;
	margin-inline: auto;
}

.contact-people .filter-bar--people {
	margin-top: 25px;
	gap: 24px;
	border-bottom-color: var(--bca-rule-cream);
}

.contact-people .filter-bar__tab {
	padding-block: 6px 40px;
	color: var(--bca-cream);
}

.contact-people .filter-bar__label::after {
	content: none;
}

.contact-people .filter-bar__tab.is-active {
	border-bottom-color: var(--bca-tangerine);
}

.contact-people__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 25px;
	width: 100%;
	margin: 88px 0 0;
	padding: 0;
	list-style: none;
}

.contact-people__grid[hidden] {
	display: none;
}

.person-card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	padding: 24px;
	background-color: var(--bca-white);
	color: var(--bca-midnight);
}

.person-card__name {
	font-family: var(--font-display);
	font-weight: 400;
	font-size: 24px;
	line-height: 1.1;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

.person-card__role {
	margin-top: 8px;
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 10px;
	line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--bca-steel-blue);
	opacity: 0.9;
}

.person-card__line {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-top: 22px;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 16px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
}

/* The frame opens the first line 39 under the role rather than the 22 it sets
   between the two lines. */
.person-card__role + .person-card__line,
.person-card__name + .person-card__line {
	margin-top: 39px;
}

.person-card__icon {
	display: flex;
	flex: none;
	color: var(--bca-steel-blue);
}

.person-card__line a:hover {
	text-decoration: underline;
}

@media (min-width: 768px) {

	.contact-people__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 1200px) {

	.contact-people {
		padding: 88px var(--gutter);
	}

	/* Three across the 1360 column, 25 apart, and never wider than the 437 the
	   frame draws even when a tab holds fewer. A fourth card wraps to its own
	   row, which keeps the first row's height even when it has a line fewer
	   (a contact given no email, D6 feedback CONTACT-2). */
	.contact-people__grid {
		grid-template-columns: repeat(3, minmax(0, 437px));
		grid-auto-rows: 1fr;
	}
}


/* The File Upload step's dropzone — 51382:62408 ------------------------------ */

.dropzone {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 12px;
	width: 100%;
	min-height: 145px;
	padding: 32px 24px;
	border: 1px dashed rgba(40, 53, 124, 0.5);
	border-radius: 4px;
	text-align: center;
	transition: border-color 0.2s ease, background-color 0.2s ease;
}

.dropzone.is-over {
	border-color: var(--bca-tangerine);
	background-color: rgba(235, 81, 38, 0.04);
}

.dropzone__icon {
	color: var(--bca-steel-blue);
}

.dropzone__lead {
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 16px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
	opacity: 0.8;
}

.dropzone__browse {
	font-weight: 500;
	color: var(--bca-steel-blue);
	text-decoration: underline;
	opacity: 1;
}

.dropzone__limit {
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	color: var(--bca-midnight);
	opacity: 0.6;
}

.dropzone__file {
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 14px;
	line-height: 1.5;
	color: var(--bca-steel-blue);
}

.dropzone__file[hidden] {
	display: none;
}

/* The real input covers the zone so the whole box is the control. */
.dropzone .wpcf7-form-control-wrap {
	position: absolute;
	inset: 0;
}

.dropzone__input {
	width: 100%;
	height: 100%;
	opacity: 0;
	cursor: pointer;
}

.dropzone__types {
	margin-top: 16px;
	font-family: var(--font-body);
	font-weight: 300;
	font-size: 14px;
	line-height: 1.5;
	letter-spacing: -0.02em;
	text-align: center;
	color: var(--bca-midnight);
	opacity: 0.6;
}


/* The icon card's glyph follows the values grid: steel blue at rest, tangerine
   as the card is pointed at, wherever the card is drawn. */
.icon-card__icon {
	transition: background-color 0.2s ease;
}

.icon-card:hover .icon-card__icon,
.icon-card:focus-within .icon-card__icon {
	background-color: var(--bca-tangerine);
}


/* =============================================================================
   The pointer — 51375:25670

   A 34px ring with a 6px square at its centre, following the cursor across the
   site. It is drawn white and composited with difference blending, so it comes
   out white over the dark grounds and midnight over the light ones without
   having to know which section it is over — including over photographs, where
   a fixed colour would disappear into the image.

   Drawn only where the device actually has a pointer, and dropped entirely
   when the visitor has asked for reduced motion; the native cursor stays over
   anything you type into so the caret is never lost.
============================================================================= */

.pointer {
	position: fixed;
	left: 0;
	top: 0;
	/* A cursor sits above everything, dialogs included: with the native one
	   hidden, anything stacked over the ring leaves the visitor with no
	   pointer at all. */
	z-index: 2147483000;
	display: none;
	width: 34px;
	height: 34px;
	border: 1px solid #ffffff;
	border-radius: 50%;
	pointer-events: none;
	mix-blend-mode: difference;
	will-change: transform;
	transition: transform 0.08s linear;
}

.pointer::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: 6px;
	height: 6px;
	background-color: #ffffff;
	transform: translate(-50%, -50%);
}

/* Without difference blending there is nothing to invert against, so the ring
   falls back to the midnight the frame draws it in. */
@supports not (mix-blend-mode: difference) {

	.pointer {
		border-color: var(--bca-midnight);
	}

	.pointer::after {
		background-color: var(--bca-midnight);
	}
}

@media (pointer: fine) {

	.has-pointer .pointer {
		display: block;
	}

	.has-pointer,
	.has-pointer a,
	.has-pointer button,
	.has-pointer [role="tab"] {
		cursor: none;
	}

	/* Anything with a caret keeps the native cursor. */
	.has-pointer input,
	.has-pointer textarea,
	.has-pointer select,
	.has-pointer [contenteditable] {
		cursor: auto;
	}

	/* The WordPress admin bar sits above the ring (z-index 99999 to its 999),
	   so cursor: none would leave no pointer there at all. It is not part of
	   the design — give it and everything in it the native cursors back. */
	.has-pointer #wpadminbar,
	.has-pointer #wpadminbar a,
	.has-pointer #wpadminbar button,
	.has-pointer #wpadminbar input {
		cursor: auto;
	}
}

@media (prefers-reduced-motion: reduce) {

	.pointer {
		display: none !important;
	}
}

/* -----------------------------------------------------------------------------
   Video lightbox — the supplier and turnkey stage clips open here rather
   than inside their card (client, Sep 2026). Built by the script on first
   use; one per page.
-------------------------------------------------------------------------- */

.lightbox {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 64px 24px 24px;
}

.lightbox__backdrop {
	position: absolute;
	inset: 0;
	background-color: rgba(8, 6, 36, 0.86);
}

.lightbox__dialog {
	position: relative;
	width: 100%;
	max-width: 1120px;
	outline: 0;
	animation: lightbox-rise 0.3s ease both;
}

@keyframes lightbox-rise {
	from { opacity: 0; transform: translateY(16px); }
	to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
	.lightbox__dialog { animation: none; }
}

/* The player fills a 16:9 plate; a file clip letterboxes on black. */
.lightbox__frame {
	position: relative;
	width: 100%;
	aspect-ratio: 16 / 9;
	background-color: #000;
}

.lightbox__frame iframe,
.lightbox__frame video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}

.lightbox__close {
	position: absolute;
	right: 0;
	bottom: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	margin-bottom: 8px;
	padding: 0;
	color: var(--bca-powder);
	background: none;
	border: 0;
	cursor: pointer;
	transition: color 0.2s ease;
}

.lightbox__close:hover,
.lightbox__close:focus-visible {
	color: var(--bca-tangerine);
}

.has-lightbox-open {
	overflow: hidden;
}
