/*
 * Olimpmir — front-end styles.
 *
 * Every value here resolves to a theme.json token (--wp--preset--* or
 * --wp--custom--*). No literal colours, type sizes or spacing (HANDOFF §2).
 * Sections are full-bleed and own their horizontal gutter.
 */

/* ---------------------------------------------------------------- base --- */

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

body {
	margin: 0;
}

html {
	scroll-behavior: smooth;
	scroll-padding-block-start: var(--wp--custom--nav--height);
}

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

img,
picture,
svg {
	max-width: 100%;
}

/* ------------------------------------------------------- accessibility --- */

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

:where(a, button, input, textarea, summary, [tabindex]):focus-visible {
	outline: var(--wp--custom--focus--ring);
	outline-offset: var(--wp--custom--focus--offset);
}

/* ------------------------------------------------------------- buttons --- */

/* theme.json styles the primary button; these add the shared box so the nav
   anchor and the button block agree, and define the secondary variant. */

.o-btn,
.wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--wp--custom--button--height);
	border-radius: var(--wp--custom--radius);
	text-decoration: none;
	transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out;
}

.o-btn--primary {
	padding: 0 var(--wp--preset--spacing--m);
	background-color: var(--wp--preset--color--blue-500);
	color: var(--wp--preset--color--white);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1;
}

.o-btn--primary:hover,
.o-btn--primary:focus {
	background-color: var(--wp--preset--color--blue-600);
	color: var(--wp--preset--color--white);
}

/* Secondary: outlined on light, no fill (Figma 9:21). */
.o-btn--secondary > .wp-block-button__link {
	background-color: transparent;
	color: var(--wp--preset--color--navy-900);
	box-shadow: inset 0 0 0 var(--wp--custom--button--border) var(--wp--preset--color--navy-900);
}

.o-btn--secondary > .wp-block-button__link:hover,
.o-btn--secondary > .wp-block-button__link:focus {
	background-color: var(--wp--preset--color--navy-900);
	color: var(--wp--preset--color--white);
}

/* ----------------------------------------------------------------- nav --- */

.o-nav {
	position: fixed;
	inset-block-start: 0;
	inset-inline: 0;
	z-index: 100;
	display: flex;
	align-items: center;
	justify-content: space-between;
	height: var(--wp--custom--nav--height);
	padding-inline: var(--wp--custom--gutter--fluid);
	background-color: transparent;
	border-block-end: 1px solid transparent;
	transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
}

.o-nav.is-solid {
	background-color: var(--wp--preset--color--white);
	border-block-end-color: var(--wp--preset--color--grey-300);
}

.o-nav__brand {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--xs);
	color: var(--wp--preset--color--navy-900);
	text-decoration: none;
}

.o-nav__mark {
	display: block;
	width: auto;
	height: var(--wp--custom--logo--mark-height);
}

.o-nav__word {
	display: block;
	width: auto;
	height: var(--wp--custom--logo--word-height);
}

.o-nav__fallback {
	font-weight: 700;
	font-size: var(--wp--preset--font-size--h-3);
	letter-spacing: 0.02em;
}

.o-nav__toggle {
	display: none;
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
}

.o-nav__bars {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--menu--gap);
	align-items: center;
	justify-content: center;
	width: var(--wp--preset--spacing--m);
	padding-block: var(--wp--custom--menu--gap);
}

.o-nav__bars i {
	width: var(--wp--custom--menu--bar);
	height: var(--wp--custom--menu--bar-weight);
	border-radius: calc(var(--wp--custom--menu--bar-weight) / 2);
	background-color: var(--wp--preset--color--navy-900);
}

/* ----------------------------------------------------------- menu panel --- */

/* Below 768 only: above it the toggle is hidden and this never displays
   (HANDOFF §8). No Figma frame exists for it — the Nav component set has just
   Overlay and Solid — so it is built from the tokens. */
.o-menu {
	display: none;
}

/* ---------------------------------------------------------------- hero --- */

.o-hero {
	position: relative;
	isolation: isolate;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: center;
	min-height: var(--wp--custom--hero--min-height);
	padding-block-start: var(--wp--custom--hero--pad-top);
	padding-inline: var(--wp--custom--gutter--fluid);
	background-color: var(--wp--preset--color--grey-050);
}

.o-hero__media {
	position: absolute;
	inset: 0;
	z-index: -1;
	overflow: hidden;
	-webkit-mask-image: var(--wp--custom--hero--mask-desktop);
	mask-image: var(--wp--custom--hero--mask-desktop);
}

.o-hero__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: left center;
}

.o-hero__content {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--ml);
	width: 737px;
	max-width: 100%;
}

.o-hero__title {
	max-width: 720px;
	margin: 0;
}

.o-hero__lede {
	max-width: 600px;
	margin: 0;
	line-height: 1.6;
}

/* The headline breaks on purpose at desktop (HANDOFF §6); below 768 it wraps
   to the column instead, as the 390 frame does. */
.o-hero__title br {
	display: initial;
}

.o-hero__cta,
.o-404__cta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--s);
	margin: 0;
}

.o-hero__trust {
	margin: 0;
	padding-block-start: var(--wp--preset--spacing--s);
	font-weight: 500;
	line-height: 1.43;
}

/* ------------------------------------------------------------ sections --- */

.o-section {
	padding-block: var(--wp--preset--spacing--section);
	padding-inline: var(--wp--custom--gutter--fluid);
}

.o-eyebrow {
	margin: 0;
	color: var(--wp--preset--color--grey-500);
	font-weight: var(--wp--custom--eyebrow--weight);
	line-height: 1.2;
	letter-spacing: var(--wp--custom--eyebrow--tracking);
	text-transform: uppercase;
}

.o-section--navy .o-eyebrow {
	color: var(--wp--custom--on-dark--muted);
}

/* Section backgrounds, per the HANDOFF §4 table. */
.o-section--white {
	background-color: var(--wp--preset--color--white);
}

.o-section--grey {
	background-color: var(--wp--preset--color--grey-100);
}

/* Two grey sections meet now. Moving §5 above §2 on the client's 21 Sep 2026
   note left §4 handing straight over to §6 with no colour change to mark the
   join — 256px of unbroken grey at 1440. §8 already answers exactly this case,
   white against white with a 1px grey-300 rule (HANDOFF §4), so it is that rule
   again rather than a new idea. The selector is the adjacency itself, so the
   line appears only while the two are neighbours and goes away by itself if the
   order is changed back. */
.o-section--grey + .o-section--grey {
	border-block-start: 1px solid var(--wp--preset--color--grey-300);
}

/* Body copy. Figma separates paragraphs with one blank line. */
.o-prose p {
	margin: 0;
	line-height: 1.6;
}

.o-prose p + p {
	margin-block-start: 1.6em;
	margin-block-start: 1lh;
}

/* The one place orange is allowed besides the step numbers (HANDOFF §3). */
.o-date {
	color: var(--wp--preset--color--orange-500);
	font-weight: 700;
}

/* ------------------------------------------------------------- problem --- */

.o-problem {
	display: flex;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--m);
}

.o-problem__lead {
	display: flex;
	flex: 1 1 733px;
	flex-direction: column;
	gap: var(--wp--preset--spacing--ml);
	min-width: 0;
}

.o-problem__title {
	margin: 0;
	color: var(--wp--custom--on-dark--heading);
}

.o-problem__body {
	flex: 1 1 523px;
	min-width: 0;
	padding-block-start: var(--wp--custom--problem--body-offset);
}

/* ------------------------------------------------------------- greener --- */

/* Section 3 is the recycling argument, so section 3 carries the mark — as a
   watermark rather than a badge on a card, which is where the client sent it
   on 21 Sep 2026. It costs no layout: a background paints inside the box the
   section already had, so nothing here can change the section's height.

   It is big enough now to run behind the copy rather than beside it — 600px
   against a section 820px tall at 1440 — which is only safe because the tint
   went to grey-100 in the same breath. navy-900 over it is 11.94:1 and
   grey-500 over it is 4.72:1, so every word still passes AA.

   A background-image, deliberately, and not a masked pseudo-element: a
   background paints above its own element's background-colour and below every
   descendant by definition, with no stacking context to reason about and
   nothing that can put it over a word. The price is that the tint is baked
   into the file rather than read from a custom property at runtime — which is
   why tools/build-recycle-mark.py takes the colour out of theme.json instead
   of anyone typing it. Change the token there, rerun, and the asset follows. */
.o-greener {
	background-image: url("../img/icon-recycle.svg?v=bbc6aa8494");
	background-repeat: no-repeat;
	background-position: right var(--wp--custom--gutter--fluid) center;
	background-size: var(--wp--custom--greener--mark);
}
.o-greener__inner {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--ml);
	width: 845px;
	max-width: 100%;
}

.o-greener__title {
	margin: 0;
}

/* Figma adds 16px above the button on top of the 32px stack gap. */
.o-greener__action {
	padding-block-start: var(--wp--preset--spacing--s);
	margin: 0;
}

/* --------------------------------------------------------- what changes --- */

.o-changes {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--l);
}

.o-changes__header {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--gap--header);
}

.o-changes__header h2 {
	margin: 0;
}

.o-changes__grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	align-items: start;
	gap: var(--wp--custom--gap--grid);
}

.o-change {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--s);
}

.o-change h3 {
	margin: 0;
}

.o-change__body {
	margin: 0;
	color: var(--wp--preset--color--grey-500);
	font-size: var(--wp--preset--font-size--body);
}

/* --------------------------------------------------------- what we make --- */

.o-make {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--gap--stack);
}

.o-make__header {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--gap--header);
}

.o-make__header h2 {
	margin: 0;
}

.o-make__grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	align-items: start;
	gap: var(--wp--preset--spacing--m);
}

.o-product {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--s);
}

.o-product h3 {
	margin: 0;
}

.o-product__media {
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border: 1px solid var(--wp--preset--color--grey-300);
	border-radius: var(--wp--custom--radius);
}

.o-product__media img,
.o-band__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.o-product__body,
.o-band__body {
	margin: 0;
	color: var(--wp--preset--color--grey-500);
	font-size: var(--wp--preset--font-size--body);
}

/* Plain-sheet band: image and copy split 737/543 of the content width, the
   proportion held at any width rather than pinned to 1440 (9:124). */
.o-band {
	display: grid;
	grid-template-columns: minmax(0, 737fr) minmax(0, 543fr);
	overflow: hidden;
	border: 1px solid var(--wp--preset--color--grey-300);
	border-radius: var(--wp--custom--radius);
}

.o-band__media {
	aspect-ratio: 3 / 2;
}

.o-band__info {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: var(--wp--preset--spacing--s);
	padding: var(--wp--preset--spacing--l);
}

.o-band__info h3 {
	margin: 0;
}

/* ------------------------------------------------------- specification --- */

.o-specs {
	display: flex;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--m);
}

.o-specs__left {
	display: flex;
	flex: 1 1 519px;
	flex-direction: column;
	gap: var(--wp--preset--spacing--ml);
	min-width: 0;
}

.o-specs__right {
	display: flex;
	flex: 1 1 737px;
	flex-direction: column;
	gap: var(--wp--preset--spacing--ml);
	min-width: 0;
}

.o-specs__header {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--gap--header);
}

.o-specs__header h2 {
	margin: 0;
}

.o-specs__photo {
	aspect-ratio: 4 / 5;
	overflow: hidden;
	border-radius: var(--wp--custom--radius);
}

.o-specs__photo img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.o-specs__about {
	margin: 0;
	line-height: 1.65;
}

.o-specs__grade {
	margin: 0;
	color: var(--wp--preset--color--grey-500);
	font-weight: 500;
	line-height: 1.43;
}

.o-specs__table {
	margin: 0;
}

.o-spec {
	display: flex;
	align-items: flex-start;

	/* The old labels were one short word, so the 200px column left its own
	   space. "Development with the partner" fills it exactly and ran into
	   the text, so the gap is explicit now. */
	gap: var(--wp--preset--spacing--m);
	padding-block: var(--wp--custom--spec--row-pad);
	border-block-end: 1px solid var(--wp--preset--color--grey-300);
}

.o-spec dt {
	flex: 0 1 auto;
	width: var(--wp--custom--spec--label-width);
	min-width: 0;
	margin: 0;
	color: var(--wp--preset--color--grey-500);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1.43;
}

/* Spec values are the only mono on the page besides the step numbers. */
/* Prose, not figures, since the table became a categorisation on
   19 Sep 2026 — so no JetBrains Mono here any more. Mono is now the step
   numbers 01–04 and nothing else. */
.o-spec dd {
	flex: 1 1 0;
	min-width: 0;
	margin: 0;
	color: var(--wp--preset--color--navy-900);
	font-size: 1rem;
	line-height: 1.5;
}

/* --------------------------------------------------------- how it works --- */

.o-steps {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--gap--stack);
}

.o-steps__header {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--gap--header);
}

.o-steps__header h2 {
	margin: 0;
}

/* The connector spans the whole row, one pixel straddling the centre line of
   the bubbles (9:174). Each number is painted over it. */
.o-steps__row {
	position: relative;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	align-items: start;
	gap: var(--wp--custom--gap--grid);
}

.o-steps__row::before {
	content: "";
	position: absolute;
	inset-inline: 0;
	top: calc(var(--wp--custom--step--size) / 2 - 0.5px);
	height: 1px;
	background-color: var(--wp--custom--step--line);
}

.o-step {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--s);
}

.o-step__content {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--s);
}

/* The second and last place orange appears, and the second use of the mono
   face (HANDOFF §3). At 1440 the bubble is a plain white box whose only job is
   to mask the connector behind it (9:177); the ring belongs to 390. */
.o-step__num {
	position: relative;
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--wp--custom--step--size);
	margin: 0;
	padding-block: var(--wp--custom--step--pad-y);
	padding-inline: var(--wp--custom--step--pad-x);
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--orange-500);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1.143;
	letter-spacing: var(--wp--custom--step--tracking);
}

.o-step h3 {
	margin: 0;
}

.o-step__body {
	margin: 0;
	color: var(--wp--preset--color--grey-500);
	font-size: var(--wp--preset--font-size--body);
}

/* ----------------------------------------------------------- questions --- */

/* Four items, no accordion, everything visible (HANDOFF §4). The rule above
   the section is the only thing separating it from section 7, which is also
   white (9:196); each item then carries the rule below it (9:200). */
.o-faq {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--faq--stack);
	border-block-start: 1px solid var(--wp--preset--color--grey-300);
}

.o-faq__list {
	display: flex;
	flex-direction: column;
	width: 845px;
	max-width: 100%;
}

.o-faq__item {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--faq--item-gap);
	padding-block: var(--wp--custom--faq--row-pad);
	border-block-end: 1px solid var(--wp--preset--color--grey-300);
}

.o-faq__q {
	margin: 0;
}

/* Answers keep the 17/28 body style at 390 — unlike sections 4 and 7, the
   390 frame does not shrink them (18:137). */
.o-faq__a {
	margin: 0;
	color: var(--wp--preset--color--grey-500);
}

/* -------------------------------------------------------- get a quote --- */

/* Navy without the rib — that belongs to sections 2 and 10 (HANDOFF §5).
   The footer will reuse this. */
.o-section--navy {
	background-color: var(--wp--preset--color--navy-900);
	color: var(--wp--custom--on-dark--body);
}

/* Neither column grows: at 1440 they sit at their Figma widths and leave the
   slack on the right, exactly as 9:213 and 9:223 do. Below that they shrink
   together rather than one crushing the other. */

/* The recycling loop again, asked for here on 21 Sep 2026, in the white file
   rather than the grey one — grey-100 on navy would be a light shape sitting
   on the section, not a shade of it.

   **The two layouts leave their empty space in opposite corners**, so the
   position has to move with them. Side by side, the left column runs out at
   524px in a 980px section and leaves 519x456 of bare navy under it, so the
   mark is bottom-left. Stacked, that corner is underneath the white form
   panel, which is opaque and would swallow it whole — there the space is
   beside the short lines at the top, so it goes top-right. This is the one
   section with its own breakpoint already, for the form's sake, so there is
   no new one here.

   Both offsets are the section's own padding, not a number, so the mark keeps
   to the same margin the copy does. */
.o-quote {
	display: flex;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--m);
	background-image: url("../img/icon-recycle-white.svg?v=3304696fee");
	background-repeat: no-repeat;
	background-position: left var(--wp--custom--gutter--fluid) bottom var(--wp--preset--spacing--section);
	background-size: var(--wp--custom--quote--mark);
}

.o-quote__left {
	display: flex;
	flex: 0 1 519px;
	flex-direction: column;
	gap: var(--wp--custom--quote--left-gap);
	min-width: 0;
}

.o-quote__header {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--m);
}

.o-quote__header h2 {
	margin: 0;
	color: var(--wp--custom--on-dark--heading);
}

.o-quote__contact {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--quote--contact-gap);
}

.o-quote__prefer {
	margin: 0;
}

/* Blue on navy is 3.04:1, so links in this section stay white (HANDOFF §9).
   The phone reads as a link from its size and weight; the address is
   underlined, since at 14px nothing else would mark it. */
.o-quote__phone {
	color: var(--wp--custom--on-dark--heading);
	font-size: var(--wp--custom--quote--phone);
	font-weight: 600;
	line-height: 1.4;
	text-decoration: none;
}

.o-quote__details {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--quote--detail-gap);
}

.o-quote__details p {
	margin: 0;
	color: var(--wp--custom--on-dark--heading);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1.43;
}

.o-quote__details a {
	color: inherit;
}

/* Client, 21 Sep 2026: "зелен бутон предпочитам". WhatsApp leaves the run
   of details and becomes a button — the one green on the site, and the
   answer to "бяга симетрията" in the same message, since the glyph is no
   longer indenting the first line of a text block against the phone and
   the hours above and below it.

   The label is navy, not white: white on #25D366 is 1.98:1 and fails AA
   outright, navy-900 on it is 7.20:1. It takes the shared .o-btn box, so
   the height and the 4px radius stay the site's and it drops to 48px at
   390 with every other button. align-self keeps it hugging its label in
   a column that would otherwise stretch it to the gutter. */
.o-quote__wa {
	align-self: flex-start;
	gap: 0.5em;
	padding: 0 var(--wp--preset--spacing--m);
	background-color: var(--wp--custom--whatsapp--green);
	color: var(--wp--custom--whatsapp--ink);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1;
}

.o-quote__wa:hover,
.o-quote__wa:focus {
	background-color: var(--wp--custom--whatsapp--green-hover);
	color: var(--wp--custom--whatsapp--ink);
}

/* Sized from the line, not in px, so it tracks the label. */
.o-quote__wa-icon {
	width: 1.4em;
	height: 1.4em;
	flex: none;
}

/* ------------------------------------------------------------ the form --- */

.o-form {
	display: flex;
	flex: 0 1 628px;
	flex-direction: column;
	gap: var(--wp--custom--quote--panel-gap);
	min-width: 0;
	padding: var(--wp--custom--quote--panel-pad);
	border-radius: var(--wp--custom--radius);
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--navy-900);
}

.o-field {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--quote--field-gap);
}

.o-field__label {
	color: var(--wp--preset--color--grey-500);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1.43;
}

.o-field__input {
	width: 100%;
	min-height: var(--wp--custom--quote--field-height);
	padding: 0 var(--wp--custom--quote--field-pad);
	border: 1px solid var(--wp--preset--color--grey-300);
	border-radius: var(--wp--custom--radius);
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--navy-900);
	font-family: inherit;
	font-size: var(--wp--custom--quote--field-text);
	line-height: 1.65;
}

.o-field__area {
	padding: var(--wp--custom--quote--area-pad);
	min-height: var(--wp--custom--quote--area-height);
	resize: vertical;
}

/* Figma tints the placeholder navy at 60%, which is 4.07:1 on white and fails
   AA. grey-500 is the approved muted colour and reads the same at 5.64:1. */
.o-field__input::placeholder {
	color: var(--wp--preset--color--grey-500);
	opacity: 1;
}

/* The group gap is the label-to-field one, so the note under the textarea
   takes back the difference. */
.o-field--area {
	gap: var(--wp--custom--quote--help-gap);
}

.o-field--area .o-field__area {
	margin-block-start: calc(var(--wp--custom--quote--field-gap) - var(--wp--custom--quote--help-gap));
}

.o-field__help {
	margin: 0;
	color: var(--wp--preset--color--grey-500);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1.43;
}

.o-form__submit {
	width: 100%;
	border: 0;
	font-family: inherit;
	cursor: pointer;
}

.o-form__submit[disabled] {
	cursor: progress;
}

/* The honeypot. Off-screen rather than display:none, and out of the tab order
   so taking it out of the accessibility tree leaves nothing focusable behind. */
.o-form__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* No error colour exists in the palette, and none is needed: the message says
   what happened, which is what WCAG 1.4.1 asks for anyway. */
.o-form__status {
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	line-height: 1.43;
}

.o-form__status:empty {
	display: none;
}

/* -------------------------------------------------------- <= 1023px --- */

/* The form panel is the one thing on the page that cannot take a squeeze:
   side by side at 768 it lands near 350px, narrower than the 390 frame. It
   stacks a breakpoint earlier than everything else for that reason. */
@media (max-width: 1023px) {

	/* Stacked, the bottom-left corner is behind the form panel — see above. */
	.o-quote {
		flex-direction: column;
		gap: var(--wp--custom--quote--stack);
		background-position: right var(--wp--custom--gutter--fluid) top var(--wp--preset--spacing--section);
	}

	.o-quote__left,
	.o-form {
		flex: 0 0 auto;
		width: 100%;
	}
}

/* ------------------------------------------------------------- footer --- */

/* The footer sets its own padding rather than the section clamp: 64/80 at the
   top, 48/80 at the bottom (18:179, 9:248). */
.o-foot {
	background-color: var(--wp--preset--color--navy-900);
	color: var(--wp--custom--on-dark--body);
	padding-block: var(--wp--custom--footer--pad-top) var(--wp--custom--footer--pad-bottom);
	padding-inline: var(--wp--custom--gutter--fluid);
}

.o-foot__grid {
	display: flex;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--m);
	padding-block-start: var(--wp--custom--footer--grid-pad);
	border-block-start: 1px solid var(--wp--custom--on-dark--rule);
}

.o-foot__col,
.o-foot__links {
	flex: 0 1 411px;
	min-width: 0;
}

.o-foot__col {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--gap--header);
}

.o-foot__brand {
	display: flex;
	align-self: flex-start;
	align-items: center;
	gap: var(--wp--custom--footer--lockup-gap);
	color: var(--wp--preset--color--white);
	text-decoration: none;
}

/* The mark ships as a white file; the wordmark is currentColor, so the white
   on .o-foot__brand carries it. */
.o-foot__mark {
	display: block;
	width: auto;
	height: var(--wp--custom--logo--footer-mark);
}

.o-foot__word {
	display: block;
	width: auto;
	height: var(--wp--custom--logo--footer-word);
}

.o-foot__fallback {
	font-size: var(--wp--preset--font-size--h-3);
	font-weight: 700;
	letter-spacing: 0.02em;
}

.o-foot__address p,
.o-foot__about {
	margin: 0;
	color: var(--wp--custom--on-dark--detail);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1.43;
}

/* The parent's mark, reversed to white by tools/build-bibg-logo.py. It sits
   in the run of text, so the line-height has to absorb it: 24px of image on
   a 20px line would otherwise push this row taller than the two above it. */
.o-foot__parent {
	display: flex;
	align-items: center;
	gap: 0.5ch;
}

.o-foot__parent-mark {
	display: block;
	width: auto;
	height: var(--wp--custom--logo--parent-height);
}

/* No underline: the mark is the affordance, and a rule under a logo reads
   as damage. Keyboard users still get the global focus ring. */
.o-foot__parent-link:hover .o-foot__parent-mark {
	opacity: 0.8;
}
/* The type goes on the list, not the anchors: an <li> left at the 17px body
   leading makes each row 28px and the column 108px against Figma's 84. */
/* White, not the 70% the rest of the footer details use: the client could
   not pick the LinkedIn link out of the column on 21 Sep 2026 and asked for
   blue or bright white. Blue is not available — blue-500 on navy-900 is
   3.04:1 and fails AA, the same measurement that keeps §9's phone white.
   White is 14.27:1, and it is the colour these links already went to on
   hover, so nothing new enters the palette. All three move together: they
   are one list of links, and brightening one would just move the question. */
.o-foot__links {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--footer--link-gap);
	margin: 0;
	padding: 0;
	list-style: none;
	color: var(--wp--custom--on-dark--heading);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1.43;
}

/* Blue is 3.04:1 on navy, so footer links are white at 70% and earn their
   underline on hover and focus instead (HANDOFF §9). */
/* inline-flex and a gap so the LinkedIn mark sits on the line beside its
   word rather than on the text baseline. The other two links have no icon,
   and a gap with one child costs them nothing.

   The li has to be a flex container as well. An inline-flex box still sits on
   the text baseline, so its descent was adding 4px and the LinkedIn row came
   out 24px against the other two at 20 — the gaps in the list stopped being
   equal. As a flex item it is measured by its own box instead. */
.o-foot__links li {
	display: flex;
}

.o-foot__links a {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	color: inherit;
	text-decoration: none;
}

/* Sized from the line, not in px, so it tracks the 14px detail type. 1.25em
   is 17.5px inside a 20px line box — §9's glyph is 1.4em, but that line is
   a button with room around it and this one is a list. */
.o-foot__link-icon {
	width: 1.25em;
	height: 1.25em;
	flex: none;
}

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

.o-foot__bottom {
	margin-block-start: var(--wp--custom--footer--bottom-gap);
	padding-block-start: var(--wp--custom--footer--bottom-pad);
	border-block-start: 1px solid var(--wp--custom--on-dark--rule-faint);
}

.o-foot__bottom p {
	margin: 0;
	color: var(--wp--custom--on-dark--muted);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1.43;
}

/* ------------------------------------------------------------ <= 767px --- */

/* --------------------------------------------------------------- legal --- */

/* The privacy page. No Figma frame, so it is built from the tokens: one column
   at a reading measure rather than the full bleed the sections use, because it
   is a page of prose and nothing else. The section itself stays edge to edge so
   its white background does, and the column is centred inside it. */
/* Neither of these pages has a hero to absorb the fixed nav, so each clears
   it itself. */
:is(.o-legal, .o-404) {
	padding-block-start: calc(var(--wp--custom--nav--height) + var(--wp--preset--spacing--section));
}

.o-legal {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--wp--custom--legal--stack);
}

.o-legal > * {
	width: 100%;
	max-width: var(--wp--custom--legal--measure);
	margin-block: 0;
}

.o-legal__title {
	font-size: var(--wp--preset--font-size--h-2);
}

.o-legal__lead {
	color: var(--wp--preset--color--grey-500);
	line-height: 1.5;
}

.o-legal__block {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--legal--block-gap);
}

.o-legal__block > * {
	margin-block: 0;
}

.o-legal__block p,
.o-legal__list {
	line-height: 1.6;
}

.o-legal__list {
	display: flex;
	flex-direction: column;
	gap: var(--wp--custom--legal--list-gap);
	padding-inline-start: var(--wp--preset--spacing--s);
}

/* ----------------------------------------------------------------- 404 --- */

/* No Figma frame. Left-aligned like the hero, and given a minimum height so a
   two-line message does not leave the footer riding up under the nav. */
.o-404 {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: center;
	min-height: var(--wp--custom--not-found--min-height);
	gap: var(--wp--custom--not-found--stack);
}

.o-404 > * {
	max-width: var(--wp--custom--not-found--measure);
	margin-block: 0;
}

.o-404__title {
	font-size: var(--wp--preset--font-size--h-2);
}

.o-404__body {
	color: var(--wp--preset--color--grey-500);
	line-height: 1.5;
}

@media (max-width: 767px) {

	.o-nav {
		height: var(--wp--custom--nav--height-mobile);
	}

	.o-nav__mark {
		height: var(--wp--custom--logo--mark-height-mobile);
	}

	/* Figma's mobile nav (52:271) is the mark alone; the owner asked for the
	   full lockup on 19 Sep 2026. The word is derived from the mobile mark so
	   the 28:18 lockup ratio holds at the smaller size. */
	.o-nav__word {
		height: var(--wp--custom--logo--word-height-mobile);
	}

	.o-nav__cta {
		display: none;
	}

	.o-nav__toggle {
		display: block;
	}

	.o-hero {
		min-height: var(--wp--custom--hero--min-height-mobile);
		padding-block: var(--wp--custom--hero--pad-top-mobile) var(--wp--preset--spacing--xl);
	}

	/* Mobile drops the gradient mask for a flat veil over the left-half crop
	   (Figma 18:12), which keeps the ribs readable behind full-width text. */
	.o-hero__media {
		-webkit-mask-image: none;
		mask-image: none;
	}

	.o-hero__media::after {
		content: "";
		position: absolute;
		inset: 0;
		background-color: var(--wp--preset--color--white);
		opacity: var(--wp--custom--veil--mobile);
	}

	.o-hero__content {
		gap: var(--wp--preset--spacing--m);
		width: 100%;
	}

	.o-hero__title,
	.o-hero__lede {
		max-width: none;
	}

	.o-hero__title br {
		display: none;
	}

	.o-hero__cta,
	.o-404__cta {
		flex-direction: column;
		gap: 0.75rem;
		width: 100%;
	}

	.o-hero__cta .wp-block-button,
	.o-hero__cta .wp-block-button__link,
	.o-404__cta .wp-block-button,
	.o-404__cta .wp-block-button__link {
		width: 100%;
	}

	.o-btn,
	.wp-block-button__link {
		min-height: var(--wp--custom--button--height-mobile);
	}

	/* theme.json's vertical padding would make the box 52px; the 390 frame
	   uses 48px, so the flex centring carries the label instead. */
	.wp-block-button__link {
		padding-block: 0;
	}

	.o-problem {
		flex-direction: column;
		gap: var(--wp--preset--spacing--m);
	}

	/* The desktop basis is a width only while this is a row. In a column it
	   is a HEIGHT, and it padded the two blocks out to 733px and 523px
	   around 218px and 307px of copy — 730px of navy nothing. Reset the
	   same way .o-quote and .o-foot__grid do. */
	.o-problem__lead,
	.o-problem__body {
		flex: 0 0 auto;
		width: 100%;
	}

	.o-problem__lead {
		gap: var(--wp--preset--spacing--m);
	}

	.o-problem__body {
		padding-block-start: 0;
	}

	.o-greener__inner {
		width: auto;
		gap: var(--wp--preset--spacing--m);
	}

	.o-greener__action {
		padding-block-start: 0;
		width: 100%;
	}

	.o-greener__action .wp-block-button,
	.o-greener__action .wp-block-button__link {
		width: 100%;
	}

	.o-changes {
		gap: var(--wp--preset--spacing--ml);
	}

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

	.o-change {
		gap: var(--wp--preset--spacing--xs);
	}

	/* Figma switches these bodies to the Small/Medium style at 390 (18:39). */
	.o-changes .o-change__body {
		font-size: var(--wp--preset--font-size--small);
		font-weight: 500;
		line-height: 1.43;
	}

	/* 390 stacks the cards and the band, with a 4:3 crop on the card photos
	   (18:53). */
	.o-make__grid {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--wp--preset--spacing--ml);
	}

	.o-product__media {
		aspect-ratio: 4 / 3;
	}

	.o-band {
		grid-template-columns: minmax(0, 1fr);
	}

	.o-band__info {
		padding: var(--wp--custom--gutter--mobile);
	}

	/* 390 reorders to photo, heading, table, about, then the grade note
	   (18:75). display:contents promotes the column children so a single
	   `order` can arrange them across both wrappers. */
	/* stretch, not the desktop flex-start: display:contents promotes these
	   blocks into this flex line, where flex-start shrink-wraps them. The
	   photo has no intrinsic width — its img is width:100% — so it came out
	   0 wide and aspect-ratio turned that into 0 tall: the picture never
	   rendered or even loaded on a phone, and the table sat 24px narrow. */
	.o-specs {
		flex-direction: column;
		align-items: stretch;
		gap: var(--wp--preset--spacing--ml);
	}

	.o-specs__left,
	.o-specs__right {
		display: contents;
	}

	.o-specs__photo  { order: 1; aspect-ratio: 3 / 2; }
	.o-specs__header { order: 2; }
	.o-specs__table  { order: 3; }
	.o-specs__about  { order: 4; }
	.o-specs__grade  { order: 5; }

	/* Label above value, one row each (HANDOFF §8). */
	.o-spec {
		flex-direction: column;
		align-items: stretch;
		gap: var(--wp--custom--spec--stack-gap);
	}

	.o-spec dt {
		width: auto;
	}

	/* 390 stacks the steps and turns the connector vertical. It is drawn per
	   step rather than as one line so it always stops at the last number,
	   whatever the copy length (18:106). */
	.o-steps__row {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--wp--preset--spacing--ml);
	}

	.o-steps__row::before {
		content: none;
	}

	.o-step {
		position: relative;
		flex-direction: row;
		align-items: flex-start;
	}

	.o-step:not(:last-child)::before {
		content: "";
		position: absolute;
		top: calc(var(--wp--custom--step--size) / 2);
		bottom: calc(-1 * var(--wp--preset--spacing--ml));
		left: calc(var(--wp--custom--step--size) / 2 - 0.5px);
		width: 1px;
		background-color: var(--wp--custom--step--line-mobile);
	}

	/* The bubble becomes a ring on the connector (18:109). Padding goes and
	   min-height does the centring, so the border stays inside 32px. */
	.o-step__num {
		flex: 0 0 auto;
		width: var(--wp--custom--step--size);
		height: var(--wp--custom--step--size);
		padding: 0;
		border: 1px solid var(--wp--preset--color--orange-500);
		border-radius: 50%;
	}

	.o-step__content {
		flex: 1 1 0;
		min-width: 0;
		gap: var(--wp--custom--step--content-gap);
	}

	/* Figma switches the step bodies to the Small/Medium style at 390
	   (18:113). */
	.o-steps .o-step__body {
		font-size: var(--wp--preset--font-size--small);
		font-weight: 500;
		line-height: 1.43;
	}

	/* 390 stacks the three columns and drops both the rule above them and the
	   48px under it (18:180). */
	/* The rule and its 48px are 1440-only in Figma (18:180), which left no
	   divider at all between §9 and the footer once the rib went. Owner asked
	   for it on mobile too, 19 Sep 2026 — see CLAUDE.md. */
	.o-foot__grid {
		flex-direction: column;
		gap: var(--wp--preset--spacing--ml);
	}

	.o-foot__col,
	.o-foot__links {
		flex: 0 0 auto;
		width: 100%;
	}

	/* Anchors land clear of the fixed nav. */
	html {
		scroll-padding-block-start: var(--wp--custom--nav--height-mobile);
	}

	.has-menu-open,
	.has-menu-open body {
		overflow: hidden;
	}

	/* Under the nav's z-index, so the toggle stays on top and doubles as the
	   close button. */
	.has-menu-open .o-menu {
		position: fixed;
		inset: 0;
		z-index: 90;
		display: flex;
		flex-direction: column;
		justify-content: space-between;
		gap: var(--wp--preset--spacing--l);
		padding-block: calc(var(--wp--custom--nav--height-mobile) + var(--wp--preset--spacing--l)) var(--wp--preset--spacing--xl);
		padding-inline: var(--wp--custom--gutter--fluid);
		overflow-y: auto;
		background-color: var(--wp--preset--color--white);
	}

	.o-menu__list {
		display: flex;
		flex-direction: column;
		gap: var(--wp--preset--spacing--m);
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.o-menu__list a {
		display: inline-block;
		color: var(--wp--preset--color--navy-900);
		font-size: var(--wp--preset--font-size--h-3);
		font-weight: 600;
		line-height: 1.25;
		text-decoration: none;
	}

	.o-menu__list a:hover,
	.o-menu__list a:focus-visible {
		color: var(--wp--preset--color--blue-500);
	}

	.o-menu__call {
		width: 100%;
	}

	/* The bars become a cross. No transition: section 11 allows the nav state
	   change and button hover, nothing else. */
	.o-nav__toggle[aria-expanded="true"] .o-nav__bars i:nth-child(1) {
		transform: translateY(calc(var(--wp--custom--menu--bar-weight) + var(--wp--custom--menu--gap))) rotate(45deg);
	}

	.o-nav__toggle[aria-expanded="true"] .o-nav__bars i:nth-child(2) {
		opacity: 0;
	}

	.o-nav__toggle[aria-expanded="true"] .o-nav__bars i:nth-child(3) {
		transform: translateY(calc(-1 * (var(--wp--custom--menu--bar-weight) + var(--wp--custom--menu--gap)))) rotate(-45deg);
	}

	:is(.o-legal, .o-404) {
		padding-block-start: calc(var(--wp--custom--nav--height-mobile) + var(--wp--preset--spacing--section));
	}
}
