/*
 * Theme CSS.
 *
 * components.css carries the compiled component styles lifted from the Nuxt
 * build — semantic class names only, no framework. This file supplies what
 * used to be Tailwind utility classes sitting directly in the Vue markup
 * (layout of the header bar, responsive visibility) plus the base reset, so
 * no utility framework is needed in WordPress.
 */

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

*, *::before, *::after {
	margin: 0;
	padding: 0;
	box-sizing: border-box;

	/*
	 * The component CSS was authored against Tailwind's preflight, which sets a
	 * global `border-style: solid` and zero width. Without it every rule that
	 * only sets a border WIDTH — the locale selector's yellow box, for one —
	 * renders nothing at all, because the initial border-style is `none`.
	 *
	 * The colour is preflight's gray-200, not the CSS initial currentColor:
	 * production computes rgb(229, 231, 235) on every element. Nothing visible
	 * hangs on it today — every component that draws a border sets its own
	 * colour, and the only rule left relying on the default is the <hr> below —
	 * but currentColor would draw that divider near-black the first time a
	 * product with a nutrition table renders.
	 */
	border-width: 0;
	border-style: solid;
	border-color: #e5e7eb;
}

html { color-scheme: light; }

/* Preflight leftovers the component CSS also assumes. */
h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; }
/* The global `border-width: 0` above also blanks <hr>, which preflight restores
   with an explicit top border — the product detail's divider was invisible. */
hr { height: 0; color: inherit; border-top-width: 1px; }
button, input, textarea, select { font: inherit; color: inherit; }
button { background: none; }
table { border-collapse: collapse; }

body {
	font-family: Populaire, sans-serif;
	/* The Nuxt global.scss sets no page background — sections bring their own. */
	background: #fff;
	/* …and no text colour either: it leaves the browser default black, so every
	   component's own colour sits on black rather than on a tinted dark. The
	   palette's `dark-100` (#332a2a) is defined in tailwind.config.js but never
	   applied anywhere in the design — using it here tinted all inherited text. */
}

/*
 * Match Tailwind's preflight exactly. Note <picture> is NOT in the display:block
 * list — it stays inline, as it does in the Nuxt build. Making it a block
 * changes the layout around every NuxtPicture-equivalent wrapper.
 */
img, video, svg, canvas, audio, iframe, embed, object {
	display: block;
	vertical-align: middle;
}
img, video { max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
button { font: inherit; cursor: pointer; }

/* The block group wrapper must not interfere with .layout's flex column. */
.wp-block-group.layout { display: flex; min-height: 100vh; flex-direction: column; }
.layout > .wp-block-template-part { display: contents; }

/* --------------------------------------------------------------------------
   Accessibility
   --------------------------------------------------------------------------
   None of this came from the Nuxt build: the Vue app shipped no skip link, no
   screen-reader utility class and no focus styling of its own, so these are
   additions rather than ports. They are kept together here so the next person
   comparing the two implementations can see at a glance what is NOT a
   translation of something upstream.
   -------------------------------------------------------------------------- */

/*
 * The standard visually-hidden pattern. Needed in its own right for the labels
 * the design draws as pictograms, and needed regardless because WordPress core
 * emits `.screen-reader-text` markup of its own (pagination, comment forms) —
 * with no rule for the class, that text was rendering as visible page copy.
 *
 * clip-path rather than `display: none` or `width: 0`: both of the latter take
 * the element out of the accessibility tree, which is the opposite of the point.
 */
.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/*
 * No rules for the skip link itself: core ships its own
 * (wp-block-template-skip-link.css, inlined in the head) and the theme only
 * translates the label — see andros_skip_link_text() in functions.php. Anything
 * here would have to fight core's `.skip-link.screen-reader-text`, which is
 * enqueued first and is more specific.
 */

/*
 * A visible focus indicator everywhere (WCAG 2.4.7).
 *
 * `a { color: inherit }` in the reset leaves links with no colour of their own,
 * so the UA's default ring is the only thing that ever marked focus — and the
 * contact form removed even that (see the override below). Two rings, dark over
 * light, so the indicator survives both the white cards and the brand-coloured
 * header without knowing which it is on.
 */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
	outline: 3px solid #161615;
	outline-offset: 2px;
	box-shadow: 0 0 0 6px #fff;
	border-radius: 2px;
}

/*
 * `main` is the skip link's target and carries tabindex="-1" so the browser
 * actually moves focus there; that makes it focusable, and it must not then draw
 * a ring around the whole page.
 */
main:focus,
main:focus-visible,
.product-detail-slot:focus,
.product-detail-slot:focus-visible {
	outline: none;
	box-shadow: none;
}

/*
 * components.css blanks the focus ring on the contact fields
 * (`outline: 2px solid transparent`, Tailwind's `outline-none`) without putting
 * anything back — tabbing through the form was completely untracked. Higher
 * specificity because components.css is enqueued after this file.
 */
.s-contact .content .contact form fieldset input:focus-visible,
.s-contact .content .contact form fieldset textarea:focus-visible {
	outline: 3px solid #161615;
	outline-offset: 2px;
}

/* Per-field error text, referenced by each input's aria-describedby. #b91c1c is
   the colour the status banner already uses, and clears 4.5:1 on the white card. */
.contact-form .field-error {
	margin-top: 0.35rem;
	color: #b91c1c;
	font-size: 0.75rem;
	line-height: 1rem;
}

.contact-form [aria-invalid="true"] {
	border-color: #b91c1c !important;
}

/*
 * The nutrition table's label column is `<th scope="row">`, which is what ties
 * each value to its name. The component CSS styles `table th` for the single
 * headline cell in the <thead> — brand background, white text — so that rule is
 * pinned to the head here and the row headers are given the <td> treatment they
 * are rendered alongside. Purely defensive: nothing about the table's appearance
 * changes.
 */
.s-category .container .card table tbody th {
	width: 50%;
	padding: 0.5rem;
	background: transparent;
	color: inherit;
	font-weight: inherit;
	text-align: left;
}

@media (min-width: 768px) {
	.s-category .container .card table tbody th {
		padding: 0.5rem 1.5rem;
	}
}

.andros-nutrition th {
	font-weight: inherit;
	text-align: left;
}

/*
 * Pagination.vue put the 40px circle on the <li> and the click handler with it,
 * leaving the <a> inside as bare text. Ours is a real link, so it has to BE the
 * circle — otherwise the target is the ~10px glyph sitting in the middle of it
 * (WCAG 2.5.8), and the visible button and the clickable one are different
 * shapes. Nothing here changes what is drawn; the li's own rules still size and
 * round it.
 */
.s-recipes .pagination li a {
	display: flex;
	width: 100%;
	height: 100%;
	align-items: center;
	justify-content: center;
	border-radius: inherit;
}

/*
 * The language switcher gained a <nav> wrapper so it is a named landmark rather
 * than two loose links. Inside the mobile panel that wrapper is a second <nav>,
 * and the panel's rules are written at `.mobile-menu-root .mobile-menu nav [ul|li]`
 * — they would take the language row and lay it out as the vertical main menu:
 * column direction, 1.5rem type, 1.5rem of top padding. Everything below undoes
 * exactly that, nothing more; `.languages`' own rules then land as before.
 *
 * Specificity: three classes beats the components' two-classes-plus-element, and
 * components.css is enqueued after this file, so the class count is what decides.
 */
.mobile-menu-root .mobile-menu .locale-nav {
	padding-top: 0;
	font-size: inherit;
	line-height: inherit;
	text-align: inherit;
}

/* `.languages` centred itself with `margin-inline: auto` as a shrink-to-fit flex
   ITEM of the panel. The wrapper is that item now and stretches full width, so
   the centring moves onto the row itself. */
.mobile-menu-root .mobile-menu .locale-nav ul {
	flex-direction: row;
	justify-content: center;
}

.mobile-menu-root .mobile-menu .locale-nav li {
	font-size: inherit;
	line-height: inherit;
}

/* `.languages` carries `margin-top: auto` to sit at the foot of the flex column;
   with the wrapper in between, the wrapper is the flex item that needs it. */
.mobile-menu-root .mobile-menu .locale-nav {
	margin-top: auto;
}

/*
 * Target size (WCAG 2.2, 2.5.8). "DE" is 13px wide and 8px from "CZ", which is
 * neither a 24px target nor 24px of clearance around one — a small, imprecise
 * or shaky tap lands on the wrong language and reloads the site in it.
 *
 * The gap is widened rather than the links, because the links are what the
 * `.active` underline is drawn on: padding them out to 24px would stretch that
 * underline from the width of the word to nearly twice it. 1rem is the spacing
 * the mobile panel's own copy of this list already uses, and it is the smallest
 * step that clears the criterion — the bar grows by 16px in the corner it sits
 * in, and nothing else moves.
 *
 * The `.locale-nav` in the middle of the selector is doing real work: the
 * component rule is `.locale-selector .locales`, an exact specificity tie, and
 * components.css is enqueued after this file — so a matching selector here would
 * silently lose and the gap would stay at 8px.
 */
.locale-selector .locale-nav .locales {
	gap: 1rem;
}

/* --------------------------------------------------------------------------
   Locale bar — replaces `hidden md:block`
   -------------------------------------------------------------------------- */

.locales-bar { display: none; }

@media (min-width: 768px) {
	.locales-bar { display: block; }
}

/* --------------------------------------------------------------------------
   Brand nav — replaces `hidden md:flex justify-center items-end w-full mb-3`
   and the `w-1/2 md:w-1/3` side columns
   -------------------------------------------------------------------------- */

.brand-nav { display: none; }

@media (min-width: 768px) {
	.brand-nav {
		display: flex;
		width: 100%;
		align-items: flex-end;
		justify-content: center;
	}
	/* `mb-3` is ColorHeader's alone — HeroHeader's nav sits flush. */
	.brand-nav:not(.brand-nav--hero) { margin-bottom: 0.75rem; }
}

.brand-nav__side { display: flex; align-items: center; width: 50%; }
.brand-nav__side--left  { justify-content: flex-end; }
.brand-nav__side--right { justify-content: flex-start; }

.brand-nav .button.logo { width: 33.333%; }

@media (min-width: 768px) {
	.brand-nav__side { width: 33.333%; }
}

/*
 * `.button` means two different things in this design, and Vue's scoping kept
 * them apart. Button.vue is the brush-stroke pill — always
 * `<a class="button"><span class="label">…</span><svg/></a>` — and its box
 * styles (margin .75rem, display:flex, width:100%, min-width:max-content,
 * padding:1.25rem) belong only to it. Everywhere else — both header navs, the
 * mobile menu, the small-screen brand logo, the footer, product titles — the
 * class marks a plain text link that Vue styled from its own component.
 *
 * Unscoping the component CSS collapsed the distinction, so the pill's box
 * landed on every plain link. Rather than enumerate the places (four already,
 * and the footer was the fifth), this keys on what actually tells them apart:
 * the presence of a label span. Damage it caused, for the record —
 *
 *   padding 1.25rem  nav links 80px tall instead of the design's 40
 *   margin .75rem    "Andros Home" wrapped to two lines inside its 160px cell
 *   width 100%       footer links overflowed their flex row, scrolling the page
 *   min-width        resolved to 340px on the mobile brand logo and so beat the
 *                    design's own max-width: 250px, which min-width always does
 *
 * Every rule that legitimately sets one of these — ColorHeader's -7rem pull on
 * .button.home, the side-column spacing, .logo-mobile's margins — carries more
 * specificity than this and still wins.
 */
.button:not(:has(> .label)) {
	display: inline;
	width: auto;
	min-width: 0;
	margin: 0;
	padding: 0;
	text-align: inherit;
}

/*
 * Same leak one level down: `.button span` is the pill's label, but the only
 * span inside a plain link is the header nav's empty .arrow, and `width: 100%`
 * blew it up from 11px to a ~70px square (98px once rotated 45°). The .arrow
 * rules themselves are more specific, so its padding and border stay.
 */
.button:not(:has(> .label)) > span {
	width: auto;
	padding: 0;
	font-size: inherit;
	line-height: inherit;
	color: inherit;
}

/* `mr-2 md:mr-8 lg:mr-12` / `ml-2 md:ml-8 lg:ml-12` on the links themselves —
   ColorHeader has no .button-wrapper, its links are direct children. Scoped
   through `header nav` so they outrank the reset above. */
.color-header header nav .brand-nav__side--left  > .button { margin-right: 0.5rem; }
.color-header header nav .brand-nav__side--right > .button { margin-left: 0.5rem; }

@media (min-width: 768px) {
	.color-header header nav .brand-nav__side--left  > .button { margin-right: 2rem; }
	.color-header header nav .brand-nav__side--right > .button { margin-left: 2rem; }
}

@media (min-width: 1024px) {
	.color-header header nav .brand-nav__side--left  > .button { margin-right: 3rem; }
	.color-header header nav .brand-nav__side--right > .button { margin-left: 3rem; }
}

/* --------------------------------------------------------------------------
   Mobile menu — replaces MobileMenu.vue's `block md:hidden` and its props
   -------------------------------------------------------------------------- */

.mobile-menu-root { display: block; }

@media (min-width: 768px) {
	.mobile-menu-root { display: none; }
}

/*
 * The hamburger's offset, read by the component CSS as var(--menu-top). The
 * front page passes no `top` prop, so it takes MobileMenu.vue's own 1.5rem
 * default; the two branded headers pass `width < 640 ? '2rem' : '4rem'`, a
 * window-width watcher that is only a breakpoint.
 */
.mobile-menu-root { --menu-top: 1.5rem; }

.hero-header  .mobile-menu-root,
.color-header .mobile-menu-root { --menu-top: 2rem; }

@media (min-width: 640px) {
	.hero-header  .mobile-menu-root,
	.color-header .mobile-menu-root { --menu-top: 4rem; }
}

/*
 * The panel and scrim are toggled with the `hidden` attribute, whose UA rule is
 * a bare `display: none` — no match for the component's `display: flex`.
 *
 * Both class names have to be in the selector: `.mobile-menu-root [hidden]`
 * ties with `.mobile-menu-root .mobile-menu` on specificity, and components.css
 * is enqueued after this file, so the component's `display: flex` won and the
 * menu rendered permanently open.
 */
.mobile-menu-root .mobile-menu[hidden],
.mobile-menu-root .overlay[hidden] { display: none; }

/*
 * Every header passes menuButtonColor="#000000", but the extractor maps each
 * v-bind() colour onto --brand, which left the bars brand-on-brand and so
 * invisible against the colour header. Black, as the components ask for.
 *
 * The `button` element selector is load-bearing: without it this ties with
 * components.css's `.mobile-menu-root .hamburger span`, which is enqueued after
 * this file and would win.
 */
.mobile-menu-root button.hamburger span { background-color: #000; }

/*
 * The product detail's text column, `class="w-full"` in ProductDetails.vue.
 * .card centres its children, so without a width the column shrank to its
 * content: the ingredients line sat centred and the nutrition table came out
 * 358px instead of the 560px its own max-width allows.
 */
.s-category .container .card > .card__body { width: 100%; }

/*
 * The card's `p { font-size: .75rem }` is meant for the nutrition table's cells
 * only. In Vue it cannot reach the ingredients copy at all: those paragraphs
 * come from the markdown renderer, a child component, so they carry no
 * data-v- attribute and the scoped rule skips them — leaving them to inherit
 * .description's 14px. Unscoped it caught them and shrank them to 12px.
 */
.s-category .container .card .description p {
	font-size: inherit;
	line-height: inherit;
}

/* --------------------------------------------------------------------------
   Recipe tag filter

   Archive.vue builds this from HeadlessListbox with its styling as Tailwind
   utilities inline in the markup, so none of it survives in components.css.
   These are those utilities, written out: max-w-[300px] mx-auto, rounded-lg
   bg-white py-2 pl-3 pr-10 shadow-md on the button, and an absolutely
   positioned max-h-60 overflow-auto panel beneath it.
   -------------------------------------------------------------------------- */

.tag-filter {
	position: relative;
	margin: 0.25rem auto 0;
	width: 100%;
	max-width: 300px;
}

.tag-filter__button {
	position: relative;
	display: block;
	width: 100%;
	cursor: default;
	border-radius: 0.5rem;
	background: #fff;
	padding: 0.5rem 2.5rem 0.5rem 0.75rem;
	text-align: left;
	box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
}

.tag-filter__summary { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.tag-filter__chevron {
	position: absolute;
	inset: 0 0 0 auto;
	display: flex;
	align-items: center;
	padding-right: 0.5rem;
	pointer-events: none;
}

.tag-filter__chevron svg { width: 0.75rem; height: 0.75rem; }

/* Closed by default once the script has taken over; always open without it. */
.tag-filter--ready .tag-filter__options { display: none; }
.tag-filter--ready.tag-filter--open .tag-filter__options { display: block; }

.tag-filter--ready .tag-filter__options {
	position: absolute;
	z-index: 20;
	margin-top: 0.25rem;
	max-height: 15rem;
	width: 100%;
	overflow: auto;
	border-radius: 0.375rem;
	background: #fff;
	padding: 0.25rem 0;
	box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
}

.tag-filter__option label {
	position: relative;
	display: block;
	cursor: pointer;
	padding: 0.5rem 1rem 0.5rem 2.5rem;
	color: #111827; /* text-gray-900, not the body's brown */
}

.tag-filter__option:hover label { background: #fef3c7; color: #78350f; }

/* The native box is the state; the tick mirrors the design's check icon. */
.tag-filter__option input { position: absolute; opacity: 0; pointer-events: none; }

.tag-filter__check {
	position: absolute;
	inset: 0 auto 0 0;
	display: none;
	align-items: center;
	padding-left: 0.75rem;
}

.tag-filter__check svg { width: 0.75rem; height: 0.75rem; }
.tag-filter__option input:checked ~ .tag-filter__check { display: flex; }
.tag-filter__option input:checked ~ .tag-filter__name { font-weight: 500; }
.tag-filter__option input:focus-visible ~ .tag-filter__name { outline: 2px solid var(--brand); outline-offset: 2px; }

.tag-filter__submit {
	margin-top: 0.5rem;
	border-radius: 0.5rem;
	background: var(--brand);
	padding: 0.5rem 1rem;
	color: #fff;
}

.recipies__empty { margin: 2.5rem auto; text-align: center; font-size: 1.5rem; line-height: 2rem; }

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

/* The locale selector is position:absolute (LocaleSelector.vue), so the header
   root must establish the containing block, and sit above the hero image. */
.hero-header, .color-header { position: relative; }
.hero-header .locale-selector,
.color-header .locale-selector { z-index: 10; }

/* The hero variant stacks one layer higher: its <picture> is a positioned
   sibling in the same stacking context, so at an equal z-index the image — being
   later in the markup — paints over the selector. */
.hero-header .locale-selector { z-index: 11; }

/* --------------------------------------------------------------------------
   Fallbacks for sections with no component CSS of their own
   -------------------------------------------------------------------------- */

.contact__form { display: grid; gap: 1rem; max-width: 44rem; margin-inline: auto; }
.contact__form label { display: grid; gap: 0.35rem; }
.contact__form input,
.contact__form textarea {
	padding: 0.6rem;
	border: 1px solid #bebebe;
	border-radius: 0.5rem;
	font: inherit;
}
.contact__disabled { font-size: 0.85rem; color: #707070; }

/* The button brush-stroke SVG is inlined from assets/images/button.svg, whose
   paths carry no fill and so default to black. Button.vue's CSS sets
   `color: var(--brand)` on the svg, expecting the fill to inherit. */
.button svg path { fill: currentColor; }

/*
 * Button.vue takes a `padding` prop applied to its label below the md
 * breakpoint (`padding: v-bind(padding)`, reset to 0 at md), which the
 * extractor turned into var(--button-padding, 0). CategoryItem.vue is the only
 * caller that passes one — padding="20px" — and without it the category
 * buttons' brush stroke came out 76px tall on mobile instead of 116.
 */
.categoryButton { --button-padding: 20px; }

/*
 * WordPress adds width/height attributes to every image; NuxtPicture did not.
 * Where the component CSS imposes a height (.titleImage img, .hero-image img …)
 * the attribute width would otherwise win and squash the image. Kept at low
 * specificity so component rules that do set a width still override it.
 */
picture > img { width: auto; }

/* --------------------------------------------------------------------------
   Tailwind variable defaults
   --------------------------------------------------------------------------
   The component CSS composes transforms, filters and shadows out of --tw-*
   custom properties, e.g.

       .button:hover svg { --tw-brightness: brightness(.75);
                           filter: var(--tw-blur) var(--tw-brightness) … }

   Tailwind's base declares every one of those with an empty/neutral default.
   Without them the var() references are invalid at computed-value time, so the
   ENTIRE declaration is dropped — the button hover never darkened, the product
   tiles never scaled, and no box-shadow rendered. These are Tailwind's own
   defaults, which is all that was missing.
   -------------------------------------------------------------------------- */

*, ::before, ::after, ::backdrop {
	--tw-translate-x: 0;
	--tw-translate-y: 0;
	--tw-rotate: 0;
	--tw-skew-x: 0;
	--tw-skew-y: 0;
	--tw-scale-x: 1;
	--tw-scale-y: 1;

	--tw-blur: ;
	--tw-brightness: ;
	--tw-contrast: ;
	--tw-grayscale: ;
	--tw-hue-rotate: ;
	--tw-invert: ;
	--tw-saturate: ;
	--tw-sepia: ;
	--tw-drop-shadow: ;

	--tw-shadow: 0 0 #0000;
	--tw-shadow-colored: 0 0 #0000;
	--tw-shadow-color: initial;
	--tw-ring-shadow: 0 0 #0000;
	--tw-ring-offset-shadow: 0 0 #0000;
	--tw-ring-inset: ;
	--tw-ring-offset-width: 0px;
	--tw-ring-offset-color: #fff;
	--tw-ring-color: rgb(59 130 246 / 0.5);

	--tw-border-opacity: 1;
	--tw-bg-opacity: 1;
	--tw-text-opacity: 1;
}

/*
 * The chevron on the "Andros Home" link needs no rules of its own: the two
 * header components already style it (padding .25rem + a 3px bottom/right
 * border, rotated 135deg). It only ever misbehaved — stretching to 85px square —
 * because the leaked Button.vue rule made its parent a flex container, which
 * blockified and stretched it. With that reset above, the component rules land
 * as authored.
 */

/*
 * The nav layout has to outrank the component rules for `header nav`, which are
 * more specific than a bare `.brand-nav` and were leaving it as a block — so the
 * logo stacked above the links instead of sitting between the two side columns.
 */
.color-header header nav.brand-nav,
.hero-header header nav.brand-nav { display: none; }

@media (min-width: 768px) {
	.color-header header nav.brand-nav {
		display: flex;
		width: 100%;
		align-items: flex-end;
		justify-content: center;
		margin-bottom: 0.75rem;
	}
	.color-header header nav.brand-nav .brand-nav__side { width: 33.333%; }
	.color-header header nav.brand-nav .button.logo { width: 33.333%; }

	.hero-header header nav.brand-nav { display: flex; }
}

/*
 * `w-1/3` on the logo link. Its height is left to the component rules — a
 * max-width of 250px on the link and `w-full h-full object-contain` on the
 * image — exactly as in ColorHeader.vue, rather than a max-height picked to
 * make the numbers come out.
 */
.color-header header nav .button.logo { width: 33.333%; }

/* --------------------------------------------------------------------------
   Contact form
   -------------------------------------------------------------------------- */

/*
 * The submit result, standing in for the Vue's vue3-toastify overlay. That
 * toast is client-only and would never survive the redirect a no-JavaScript
 * form depends on, so the message is rendered into the card instead — above the
 * form, where it reads in document order rather than floating over a corner.
 */
.contact-status {
	margin-bottom: 1.5rem;
	border-radius: 0.5rem;
	padding: 0.75rem 1.25rem;
	font-family: ui-sans-serif, system-ui, sans-serif;
	font-size: 1rem;
	line-height: 1.5rem;
	background: #f3f4f6;
	color: var(--brand);
}

.contact-status--error {
	background: #fef2f2;
	color: #b91c1c;
}

/*
 * The honeypot. Off-screen rather than `display: none` or `visibility: hidden`,
 * both of which the bots worth stopping already know to skip, and sized to 1px
 * rather than 0 so it is not treated as an empty box and dropped.
 */
.contact-form__hp {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* --------------------------------------------------------------------------
   404
   --------------------------------------------------------------------------
   .error-container and its h1 come from error.vue and are already in
   components.css. Only two things are missing: the explanatory line, which the
   Vue never had (it showed a bare "404"), and room around the whole thing —
   error.vue inherited the layout's page padding from NuxtLayout, which the
   block template's <main> does not provide.
   -------------------------------------------------------------------------- */
.error-container {
	padding: 2rem 1.25rem 4rem;
}

.error-message {
	margin-top: 1rem;
	max-width: 32rem;
	text-align: center;
	font-size: 1.25rem;
	line-height: 1.75rem;
}

/*
 * Button.vue is `width: 100%`, sized by whatever grid cell or card holds it.
 * Nothing holds this one, so it stretched the brush stroke across the full
 * 1240px viewport. Capped near the width it takes on a phone, which is the one
 * place the original proportions were ever visible.
 */
.error-container .button {
	max-width: 22rem;
}

/*
 * core/post-content wraps the page's blocks in .entry-content.
 *
 * The page background lives on `.layout main` (components.css), but <main> only
 * holds the section block — anything the client adds to the page renders as a
 * SIBLING of it inside this wrapper, and landed on white. The h1's top margin
 * had the same problem from the other end: it sits above main's box, so the
 * background stopped short of it and left a white band.
 *
 * Both are the same mistake, so the background moves up one level to the
 * element that spans everything between the header and the footer. <main> then
 * carries none of its own, or it would paint a second copy over the first at a
 * different offset.
 */
.layout > .wp-block-post-content {
	position: relative;
	z-index: 0;
	display: flex;
	flex-grow: 1;
	flex-direction: column;
	background-image: url("../images/wooden.webp");
	background-size: cover;
}

.layout > .wp-block-post-content > main {
	flex-grow: 1;
	background-image: none;
}
