/* ==========================================================================
   EU DROPS & BITES
   --------------------------------------------------------------------------
   The campaign is named after two things: a drop of olive oil and a bite of
   dried fruit. The design says so before the copy does.

   THE IDENTITY IN ONE PARAGRAPH. Two harvests, one standard. The palette is
   taken from the campaign's own logo — the deep olive of the leaf, the gold-
   green of the fruit, the burgundy of the raisin — on warm linen rather than
   white, because neither of these products has ever looked good on white. Each
   product owns a colourway, so a reader always knows which of the two they are
   reading about, and a section that covers both carries both. Type does the
   heavy lifting: a display serif with real personality set very large against a
   quiet geometric sans, with photography full-bleed and uncropped by cards.

   WHAT IS DELIBERATELY ABSENT. No card shadows, no rounded boxes, no
   gradients-as-decoration, no glass, no animated counters. Section separation
   is done with space, colour and one hairline rule; everything else is
   photography and words.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Fonts
   Both are variable fonts served from this theme. `swap` because a campaign
   headline that is invisible for 3s is worse than one that reflows once.
   -------------------------------------------------------------------------- */

@font-face {
	font-family: 'Platypi';
	src: url('../fonts/platypi-variable.woff2') format('woff2-variations');
	font-weight: 300 800;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'Manrope';
	src: url('../fonts/manrope-variable.woff2') format('woff2-variations');
	font-weight: 200 800;
	font-style: normal;
	font-display: swap;
}

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

:root {
	/* Palette, sampled from the approved logo and roll-up. */
	--ink: #1e2b16;
	--ink-soft: #4a5544;
	--olive: #2d4421;
	--olive-deep: #1b2913;
	--grove: #61672a;
	/* THREE AMBERS, BECAUSE ONE CANNOT DO THREE JOBS.
	   `--amber` is the decorative one: rules, borders, the drop in the section
	   mark. It is never used for text — at 3.53:1 on linen it is legible as a
	   shape and not as a word.
	   `--amber-deep` is the TEXT amber. It was #8a5f10 and measured 4.48:1 on
	   linen-deep, which axe correctly failed by two hundredths; #7f570e clears
	   4.5:1 on all four light surfaces with room to spare.
	   `--amber-bright` exists for the one place amber is a BACKGROUND with dark
	   text on it — the hero's primary button — where the deep amber would be
	   too dark to read ink against. */
	--amber: #a8761a;
	--amber-deep: #7f570e;
	--amber-bright: #c68f27;
	--raisin: #7b2033;
	--raisin-deep: #5f1727;
	--linen: #f5f1e7;
	--linen-deep: #ebe5d6;
	--paper: #fffdf8;
	--stone: #ddd5c2;
	--stone-soft: #e8e1d1;

	/* The accent is what a colourway swaps. Everything tinted reads it. */
	--accent: var(--grove);
	--accent-deep: var(--olive);
	--accent-wash: #eef0e2;

	--font-display: 'Platypi', Georgia, 'Times New Roman', serif;
	--font-body: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

	/* A fluid scale with real floors and ceilings. clamp() without a sensible
	   minimum is how a 320px screen ends up with 11px body copy. */
	--t-xs: 0.8125rem;
	--t-sm: 0.9375rem;
	--t-base: clamp(1.0625rem, 0.99rem + 0.3vw, 1.1875rem);
	--t-lead: clamp(1.1875rem, 1.08rem + 0.55vw, 1.4375rem);
	--t-h4: clamp(1.1875rem, 1.09rem + 0.45vw, 1.375rem);
	--t-h3: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
	--t-h2: clamp(1.75rem, 1.42rem + 1.5vw, 2.75rem);
	--t-h1: clamp(2.125rem, 1.6rem + 2.5vw, 3.875rem);
	--t-display: clamp(2.125rem, 1.45rem + 2.9vw, 4rem);

	--space-1: 0.375rem;
	--space-2: 0.75rem;
	--space-3: 1.25rem;
	--space-4: 2rem;
	--space-5: 3rem;
	--space-6: 4.5rem;
	--space-7: 6.5rem;

	--shell: 74rem;
	--shell-narrow: 44rem;
	/* The floor is min()'d against the viewport on purpose. A rem floor grows
	   with the root font size while the viewport does not, so at 320 CSS px
	   with 200 % text a 1.25rem gutter became 40 px a side and ate a quarter
	   of the screen. Above that stress point this evaluates exactly as before. */
	--gutter: clamp(min(1.25rem, 5vw), 4vw, 3rem);

	--rule: 1px solid var(--stone);
	--focus: 3px solid var(--amber-deep);
}

.eudb-tone-oil {
	--accent: var(--amber);
	--accent-deep: var(--amber-deep);
	--accent-wash: #f7eedc;
}

.eudb-tone-raisin {
	--accent: var(--raisin);
	--accent-deep: var(--raisin-deep);
	--accent-wash: #f6e8e9;
}

.eudb-tone-both {
	--accent: var(--grove);
	--accent-deep: var(--olive);
	--accent-wash: #eef0e2;
}

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

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

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

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

body.eudb {
	margin: 0;
	background: var(--linen);
	color: var(--ink);
	font-family: var(--font-body);
	font-size: var(--t-base);
	font-weight: 400;
	line-height: 1.62;
	/* Nordic text sets long words; let them break rather than overflow. */
	overflow-wrap: break-word;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

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

h1, h2, h3, h4 {
	font-family: var(--font-display);
	font-weight: 600;
	line-height: 1.12;
	letter-spacing: -0.015em;
	margin: 0 0 var(--space-3);
	color: var(--olive-deep);
	/* Finnish and Swedish compounds are long and will break a narrow column, so
	   hyphenation is allowed — but only where the column really is narrow. At
	   desktop widths `hyphens: auto` produced "A handful of rais-ins." in a 64px
	   display headline, which looks like a rendering fault rather than
	   typesetting. `overflow-wrap` below is the safety net at any width. */
	hyphens: manual;
	overflow-wrap: break-word;
}

@media (max-width: 48rem) {
	h1, h2, h3, h4 {
		hyphens: auto;
	}

	/* Except the hero headline, which is the one piece of type on the site big
	   enough that a hyphen in it is the first thing you see. */
	.eudb-hero__title {
		hyphens: manual;
	}
}

h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); }
h4 { font-size: var(--t-h4); font-family: var(--font-body); font-weight: 700; letter-spacing: 0; }

p { margin: 0 0 var(--space-3); }

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

a:hover {
	color: var(--accent-deep);
}

:focus-visible {
	outline: var(--focus);
	outline-offset: 3px;
	border-radius: 2px;
}

::selection {
	background: var(--amber);
	color: #fff;
}

strong { font-weight: 700; }

hr {
	border: 0;
	border-top: var(--rule);
	margin: var(--space-5) 0;
}

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

.eudb-skip {
	position: absolute;
	left: var(--space-3);
	top: -100px;
	z-index: 200;
	background: var(--olive);
	color: #fff;
	padding: 0.75rem 1.25rem;
	font-weight: 700;
	text-decoration: none;
	transition: top 0.15s ease;
}

.eudb-skip:focus {
	top: var(--space-3);
	color: #fff;
}

/* --------------------------------------------------------------------------
   4. Layout primitives
   -------------------------------------------------------------------------- */

.eudb-shell {
	width: calc(100% - var(--eudb-shell-l) - max(var(--eudb-shell-l), var(--eudb-lane, 0px)));
	margin-inline: var(--eudb-shell-l) auto;
}

.eudb-shell--narrow {
	width: calc(100% - var(--eudb-narrow-l) - max(var(--eudb-narrow-l), var(--eudb-lane, 0px)));
	margin-inline: var(--eudb-narrow-l) auto;
}

.eudb-main {
	display: block;
}

.eudb-main:focus {
	outline: none;
}

.eudb-section {
	padding-block: var(--space-6);
}

.eudb-section--tint {
	background: var(--linen-deep);
	border-top: var(--rule);
}

.eudb-section__title {
	font-size: var(--t-h2);
	margin-bottom: var(--space-4);
}

.eudb-section__lead {
	font-size: var(--t-lead);
	max-width: 46ch;
	color: var(--ink-soft);
	margin-bottom: var(--space-4);
}

/* --------------------------------------------------------------------------
   5. The drop-and-bite rule, and eyebrows
   The campaign's two marks, reduced to 12 pixels. It is the one ornament the
   design allows itself, so it appears everywhere a section begins.
   -------------------------------------------------------------------------- */

.eudb-rule {
	display: flex;
	align-items: center;
	gap: 7px;
	margin: 0 0 var(--space-3);
}

.eudb-rule__line {
	display: block;
	width: 3rem;
	height: 1px;
	background: currentColor;
	opacity: 0.45;
}

.eudb-rule__drop {
	display: block;
	width: 7px;
	height: 10px;
	background: var(--amber);
	/* A teardrop: round at the base, pointed at the top. */
	border-radius: 50% 50% 50% 50% / 65% 65% 35% 35%;
	transform: rotate(180deg);
}

.eudb-rule__bite {
	display: block;
	width: 11px;
	height: 8px;
	background: var(--raisin);
	border-radius: 50%;
	transform: rotate(-18deg);
}

.eudb-rule--light {
	color: rgba(255, 255, 255, 0.85);
}

.eudb-rule--dark {
	color: var(--olive);
}

.eudb-eyebrow {
	font-family: var(--font-body);
	font-size: var(--t-xs);
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--accent-deep);
	margin: 0 0 var(--space-2);
}

.eudb-hero .eudb-eyebrow {
	color: #e8e0c8;
}

.eudb-hero--quiet .eudb-eyebrow {
	color: var(--accent-deep);
}

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

.eudb-btn[hidden] {
	/* `display: inline-flex` below beats the user-agent `[hidden]{display:none}`
	   on specificity, so the consent banner's "Save preferences" button — which
	   is `hidden` until the granular panel is opened — rendered permanently.
	   Three buttons where the design has two, on the one component a visitor
	   must understand at a glance. */
	display: none;
}

.eudb-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* 48px minimum height and 24px of horizontal padding: WCAG 2.2 target size
	   with room for a Finnish label, which is always the longest one. */
	min-height: 48px;
	padding: 0.7rem 1.5rem;
	font-family: var(--font-body);
	font-size: var(--t-sm);
	font-weight: 700;
	letter-spacing: 0.03em;
	line-height: 1.25;
	text-align: center;
	text-decoration: none;
	border: 2px solid transparent;
	background: none;
	cursor: pointer;
	transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

.eudb-btn--solid {
	background: var(--olive);
	border-color: var(--olive);
	color: #fff;
}

.eudb-btn--solid:hover {
	background: var(--olive-deep);
	border-color: var(--olive-deep);
	color: #fff;
}

.eudb-btn--ghost {
	border-color: var(--olive);
	color: var(--olive);
}

.eudb-btn--ghost:hover {
	background: var(--olive);
	color: #fff;
}

.eudb-btn--quiet {
	color: var(--ink);
	border-color: transparent;
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.eudb-btn--quiet:hover {
	color: var(--olive-deep);
	background: rgba(45, 68, 33, 0.07);
}

.eudb-btn--lg {
	min-height: 54px;
	padding-inline: 2rem;
	font-size: var(--t-base);
}

.eudb-actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	margin: var(--space-4) 0 0;
}

.eudb-hero .eudb-btn--ghost {
	border-color: rgba(255, 255, 255, 0.7);
	color: #fff;
}

.eudb-hero .eudb-btn--ghost:hover {
	background: #fff;
	color: var(--olive-deep);
}

.eudb-hero .eudb-btn--solid {
	/* --amber behind ink measured 3.84:1. --amber-bright is the same hue lifted
	   until the label clears 4.5:1 against it. */
	background: var(--amber-bright);
	border-color: var(--amber-bright);
	color: var(--olive-deep);
}

.eudb-hero .eudb-btn--solid:hover {
	background: #d9a441;
	border-color: #d9a441;
}

.eudb-hero--quiet .eudb-btn--ghost {
	border-color: var(--olive);
	color: var(--olive);
}

.eudb-hero--quiet .eudb-btn--solid {
	background: var(--olive);
	border-color: var(--olive);
	color: #fff;
}

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

/* THE MASTHEAD IS ONE TIER; ITS GEOMETRY AND THE EU MARKS' LIVE HERE, ON :root.
   The masthead is the campaign logo, the navigation, the language switcher and
   the burger, and nothing else.

   2026-10-12, ΥΠΑΑΤ's second layout review (owner-relayed): the "Enjoy, it's
   from Europe!" stamp at the bottom right and the EU emblem at the bottom left;
   the stamp recommended to stay fixed on the right while the page scrolls;
   therefore no EU strip at the top of the site; and the footer stamp enlarged
   in proportion to the EU flag. So the white EU tier that sat under the logo
   row from 2026-09-30 is gone from the markup (not hidden), and the marks are:

     - the footer compliance band (section 18): the emblem bottom left, the
       stamp bottom right — the one emblem on every page;
     - one floating stamp, `.eudb-float`, the last child of <main>: sticky to
       the bottom-right of the viewport while <main> scrolls past, at rest at
       the end of <main>, never over the header or the footer.

   The tokens sit on :root because the hero, the consent banner, the header
   logo and every content container read them.

   PROMINENCE IS MEASURED ON PAINTED INK, NOT ON IMAGE BOXES. Both lockups have
   transparent clear space inside the file and the campaign logo has none (it
   was trimmed), so comparing boxes flatters the emblem. Measured from each
   file's alpha channel, as fractions of the rendered width W:

       vertical lockup    420 x 442   ink 0.919 W x 0.857 W   flag 0.545 W
       campaign logo      940 x 639   ink = box, L x 0.680 L
       ENJOY stamp        140 x 205   box 1.464 W tall, ink 1.261 W tall;
                                      0.107 W clear at each side, 0.100 W below

   THE HEADER LOGO MAY BE NO LARGER THAN THE EMBLEM (Article 17.2; the emblem
   guide's "at least the same size as the biggest of the other logos"). The
   emblem is now the footer band's, so the logo's cap is derived from it: the
   logo may be no taller than the emblem's ink and may cover no more area —
   area binds for the vertical lockup, L <= sqrt(0.919 x 0.857 / 0.680) W =
   1.0765 W. Every logo target below is far under that cap (120 px against
   215 px); the cap is there so that editing a target cannot make it false. */
:root {
	--eudb-logo-hk: 0.6798;
	--eudb-enjoy-box-k: 1.4643;
	--eudb-enjoy-hk: 1.2607;
	--eudb-enjoy-side-k: 0.1071;
	--eudb-enjoy-foot-k: 0.1;

	--eudb-v-ink-hk: 0.8571;
	--eudb-v-logo-k: 1.0765;

	/* The footer band's emblem: 200 px, 176 px below 40rem. */
	--eudb-band-eu-w: 200px;

	/* Targets for the narrowest band, to 22rem (320 px). */
	--eudb-brand-target: 88px;
	--eudb-tier1-min: 68px;

	--eudb-brand-w: min(var(--eudb-brand-target), calc(var(--eudb-band-eu-w) * var(--eudb-v-logo-k)));

	/* The row is the logo's ink plus 1rem above and below it: the brand link's
	   0.5rem padding and the row's. The header's height is that row and the
	   rule under it — derived, not measured: the hero subtracts it, and a
	   JavaScript measurement would arrive after the hero had been laid out. */
	--eudb-tier1-h: max(var(--eudb-tier1-min), calc(var(--eudb-brand-w) * var(--eudb-logo-hk) + 2rem));
	--eudb-header-h: calc(var(--eudb-tier1-h) + 1px);

	/* THE LEFT EDGE OF A CONTENT CONTAINER, as the centred shell has always
	   had it. `100%` is left unresolved here on purpose: a custom property is
	   substituted as tokens, so it resolves against each container's own
	   containing block where it is used. */
	--eudb-shell-l: max(var(--gutter), (100% - var(--shell)) / 2);
	--eudb-narrow-l: max(var(--gutter), (100% - var(--shell-narrow)) / 2);

	/* THE FLOATING STAMP AND ITS LANE. The stamp is never allowed to cover
	   copy, a control, a form or a navigation item, so it does not float over
	   the content at all: every content container in <main> keeps its right
	   edge at least --eudb-lane from the viewport's right edge (the container
	   rules use `max(left edge, lane)` for their right margin), and the stamp
	   lives in that lane. Where the shell's own side margin is already wider
	   than the lane — 1440 px and up — nothing moves; below that only the
	   RIGHT edge of the content pulls in, and the left edge stays aligned with
	   the masthead and the footer. Full-bleed photographs and band tints still
	   run under the stamp: the stamp is an opaque orange field carrying its
	   own lettering, so it needs no plate, and gets none.

	   Sizes, box width (lettering ~0.22 W): 48 px to 40rem — the smallest the
	   2026-09-30 review accepted was 49.2 px — 56 px to 64rem, 64 px to
	   1366 px, 72 px from there. The lane is the box, its distance from the
	   viewport edge (never inside the safe area) and a clearance to content,
	   which the stamp's own transparent side margin (0.107 W) adds to. */
	--eudb-float-w: 48px;
	--eudb-float-edge: 4px;
	--eudb-float-clear: 4px;
	--eudb-float-gap: 8px;
	--eudb-float-right: max(var(--eudb-float-edge), env(safe-area-inset-right, 0px));
	--eudb-float-bottom: max(var(--eudb-float-gap), env(safe-area-inset-bottom, 0px));
	--eudb-lane: calc(var(--eudb-float-w) + var(--eudb-float-right) + var(--eudb-float-clear));
}

/* THE BANDS. Range syntax, so each band is closed at both ends and no two can
   match the same width — the cascade order of these blocks does not matter.
   Header logo: 88 / 104 / 112 / 120 px. */
@media (22rem < width < 40rem) {
	:root {
		--eudb-brand-target: 104px;
	}
}

@media (width <= 40rem) {
	:root {
		--eudb-band-eu-w: 176px;
	}
}

@media (40rem <= width <= 48rem) {
	:root {
		--eudb-brand-target: 112px;
	}
}

@media (width > 48rem) {
	:root {
		--eudb-brand-target: 120px;
	}
}

@media (40rem <= width < 64rem) {
	:root {
		--eudb-float-w: 56px;
		--eudb-float-edge: 8px;
		--eudb-float-clear: 8px;
		--eudb-float-gap: 12px;
	}
}

@media (64rem <= width < 85.375rem) {
	:root {
		--eudb-float-w: 64px;
		--eudb-float-edge: 12px;
		--eudb-float-clear: 12px;
		--eudb-float-gap: 16px;
	}
}

@media (width >= 85.375rem) {
	:root {
		--eudb-float-w: 72px;
		--eudb-float-edge: 16px;
		--eudb-float-clear: 16px;
		--eudb-float-gap: 16px;
	}
}

@media (width > 75rem) {
	:root {
		--eudb-tier1-min: 78px;
	}
}

/* NOT STICKY, AT ANY WIDTH. The masthead scrolls away; the only thing that
   follows the reader is the floating stamp, in its own lane. Relative, not
   static: the burger panel and the skip link are positioned against it, and
   the z-index keeps the panel above the hero that follows — and above the
   floating stamp (50), so an open menu or submenu is never under it. */
.eudb-masthead {
	background: var(--paper);
	border-bottom: var(--rule);
	position: relative;
	z-index: 60;
}

.eudb-masthead__inner {
	width: min(100% - (var(--gutter) * 2), var(--shell));
	margin-inline: auto;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	min-height: var(--eudb-tier1-min);
	padding-block: 0.5rem;
}

.eudb-brand {
	display: inline-flex;
	align-items: center;
	flex: 0 0 auto;
	padding-block: 0.5rem;
}

.eudb-brand__img {
	width: var(--eudb-brand-w);
	height: auto;
}

/* The masthead-row switcher: present from 48rem up, gone below it. */
.eudb-lang--masthead {
	display: none;
	flex: 0 0 auto;
	margin-left: auto;
}

@media (min-width: 48.001rem) {
	.eudb-lang--masthead {
		display: block;
	}
}

/* The floating stamp ----------------------------------------------------------
   A zero-height sticky rail, last in <main>: in flow, so margins collapse
   through it and it takes no space; sticky to the viewport's bottom while
   <main> is on screen, and at rest at the end of <main> — so it can never
   travel over the footer, and never rise above <main> into the header. The
   stamp hangs from the rail's right end, in the lane every content container
   leaves free. It is lifted above the consent banner while that is open
   (`--eudb-consent-h`, set by site.js), and the banner is capped (section 19)
   so that there is always room for it between the header and the banner.

   ONE STAMP AT THE BOTTOM RIGHT AT A TIME. When the footer band's own stamp
   is in view, site.js marks the root and this copy steps aside — visibility,
   not display, and not by leaving the markup — so the reader never sees two
   stamps in one corner. Without JavaScript both show, which is acceptable. */
.eudb-float {
	position: sticky;
	bottom: calc(var(--eudb-float-bottom) + var(--eudb-consent-h, 0px));
	z-index: 50;
	height: 0;
	margin: 0;
	pointer-events: none;
}

.eudb-float .eudb-enjoy {
	position: absolute;
	right: var(--eudb-float-right);
	bottom: 0;
	width: var(--eudb-float-w);
	max-width: none;
	height: auto;
	transition: opacity 0.15s ease, visibility 0.15s;
}

.eudb-band-enjoy-in-view .eudb-float .eudb-enjoy,
.eudb-float-no-room .eudb-float .eudb-enjoy {
	opacity: 0;
	visibility: hidden;
}

@media (prefers-reduced-motion: reduce) {
	.eudb-float .eudb-enjoy {
		transition: none;
	}
}

@media print {
	.eudb-float {
		display: none;
	}

	/* No stamp on paper, so no lane either. */
	:root {
		--eudb-lane: 0px;
	}
}

.eudb-masthead__nav {
	display: flex;
	align-items: center;
	gap: var(--space-4);
}

.eudb-nav__list,
.eudb-nav__sub {
	list-style: none;
	margin: 0;
	padding: 0;
}

.eudb-nav__list {
	display: flex;
	align-items: center;
	gap: var(--space-1);
}

.eudb-nav__item {
	position: relative;
	display: flex;
	align-items: center;
}

.eudb-nav__link {
	display: inline-flex;
	align-items: center;
	min-height: 48px;
	padding: 0 0.7rem;
	font-size: var(--t-sm);
	font-weight: 600;
	color: var(--ink);
	text-decoration: none;
	letter-spacing: 0.01em;
}

.eudb-nav__link:hover {
	color: var(--olive);
	text-decoration: underline;
	text-underline-offset: 0.35em;
}

.eudb-nav__item.is-current > .eudb-nav__link {
	color: var(--olive);
	box-shadow: inset 0 -3px 0 var(--amber);
}

.eudb-nav__toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	min-height: 48px;
	margin-left: -0.5rem;
	border: 0;
	background: none;
	cursor: pointer;
	color: var(--ink);
}

.eudb-nav__chev {
	width: 8px;
	height: 8px;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg) translate(-2px, -2px);
	transition: transform 0.18s ease;
}

.eudb-nav__toggle[aria-expanded='true'] .eudb-nav__chev {
	transform: rotate(-135deg) translate(-3px, -3px);
}

.eudb-nav__sub {
	position: absolute;
	top: 100%;
	left: 0;
	min-width: 16rem;
	background: var(--paper);
	border: var(--rule);
	border-top: 3px solid var(--amber);
	padding: var(--space-1) 0;
	display: none;
	box-shadow: 0 14px 34px rgba(30, 43, 22, 0.14);
}

.eudb-nav__item.is-open > .eudb-nav__sub {
	display: block;
}

.eudb-nav__sub .eudb-nav__link {
	display: flex;
	padding: 0.55rem 1.1rem;
	min-height: 44px;
	width: 100%;
}

/* Language switcher ------------------------------------------------------- */

.eudb-lang ul {
	list-style: none;
	display: flex;
	align-items: center;
	gap: 2px;
	margin: 0;
	padding: 0;
}

.eudb-lang__item {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	padding: 0 0.4rem;
	font-size: var(--t-xs);
	font-weight: 700;
	letter-spacing: 0.08em;
	color: var(--ink-soft);
	text-decoration: none;
}

.eudb-lang__item abbr {
	text-decoration: none;
	border: 0;
}

.eudb-lang__item:hover {
	color: var(--olive);
	background: var(--linen-deep);
}

.eudb-lang__item.is-current {
	color: var(--olive-deep);
	background: var(--linen-deep);
	box-shadow: inset 0 -3px 0 var(--olive);
}

/* A language whose translation is missing is shown, but not as a link — see
   eudb_language_switcher(). The cursor says "unavailable", not "broken".

   NOT `opacity`. Fading the item to 45% took it to 2.14:1 against the masthead
   and 3.19:1 against the footer, which axe flagged on the 404 page — the one
   route where BOTH other languages are unavailable, so the whole switcher was
   below the contrast floor at once. "Unavailable" still has to be readable, or
   the reader cannot tell which language they are being denied. A dedicated
   colour and a strike-through carry the same meaning without the fade. */
.eudb-lang__item.is-missing {
	color: var(--ink-soft);
	cursor: not-allowed;
}

.eudb-lang__item.is-missing abbr {
	text-decoration: line-through;
	text-decoration-thickness: 1px;
}

.eudb-lang--footer .eudb-lang__item.is-missing {
	color: #c3c9b6;
}

.eudb-lang--footer ul {
	gap: var(--space-1);
}

.eudb-lang--footer .eudb-lang__item {
	background: rgba(255, 255, 255, 0.08);
	color: #e7e2d4;
}

.eudb-lang--footer .eudb-lang__item.is-current {
	background: rgba(255, 255, 255, 0.2);
	color: #fff;
	box-shadow: inset 0 -3px 0 var(--amber);
}

/* Burger ------------------------------------------------------------------ */

.eudb-burger {
	display: none;
	align-items: center;
	gap: 0.6rem;
	min-height: 48px;
	padding: 0 0.75rem;
	border: 2px solid var(--stone);
	background: none;
	cursor: pointer;
	font-family: var(--font-body);
	font-size: var(--t-xs);
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ink);
}

.eudb-burger__bars {
	display: grid;
	gap: 3px;
	width: 18px;
}

.eudb-burger__bars i {
	display: block;
	height: 2px;
	background: currentColor;
	transition: transform 0.2s ease, opacity 0.2s ease;
}

.eudb-burger[aria-expanded='true'] .eudb-burger__bars i:nth-child(1) {
	transform: translateY(5px) rotate(45deg);
}

.eudb-burger[aria-expanded='true'] .eudb-burger__bars i:nth-child(2) {
	opacity: 0;
}

.eudb-burger[aria-expanded='true'] .eudb-burger__bars i:nth-child(3) {
	transform: translateY(-5px) rotate(-45deg);
}

/* THE BAND WHERE THE DESKTOP NAV IS SHOWN BUT FINNISH DOES NOT FIT.
   Between the burger breakpoint (62rem) and 75rem the full horizontal nav is
   displayed. In English it fits comfortably; in Finnish — "Ekstra-neitsyt-
   oliiviöljy", "Eurooppalainen tuotanto", "Uutiset ja tapahtumat" — it ran 14px
   past the viewport at 1024px and put a horizontal scrollbar on the whole
   document. Measured, not guessed: `documentElement.scrollWidth` was 1038
   against a 1024 viewport.
   Tightening the masthead through this band reclaims about 55px, which leaves
   headroom for the longest language rather than only just clearing it. The
   language buttons stay 38x44, comfortably above the 24x24 target-size floor. */
/* Below 22rem the row is the logo and a burger labelled "VALIKKO", and the two
   of them plus their gap have to fit 320px minus the gutters. The EU mark is
   no longer in this row (since 2026-10-12 it is in the footer band only), so the
   logo's width here is its band target, capped by the emblem's (section 7). */
/* THE NARROWEST SUPPORTED WIDTH, IN THE LONGEST LANGUAGE.
   At 320px the Finnish masthead — the full logo plus a burger labelled
   "VALIKKO" rather than "MENU" — ran 5px past the viewport and scrolled the
   document sideways. Five pixels, on every Finnish page, invisible at 390px
   where the screenshots are taken. WCAG 2.2 §1.4.10 asks for 320px, so 320px
   is what this has to fit in. */
@media (max-width: 26rem) {
	.eudb-burger {
		padding: 0 0.5rem;
		gap: 0.4rem;
	}

	/* THE WORD GOES, THE NAME STAYS. Below 26rem the row was built to carry
	   three things — the campaign logo, the EU funding mark and this button —
	   and in Finnish the word on the button is "VALIKKO", which is 103 px of a
	   320 px screen. The funding mark has since left the masthead; the word stays
	   hidden, because the row is still the logo plus a 44 px target.
	   The button keeps its accessible name through `aria-label` (header.php),
	   so a screen reader still announces "Menu"; only the printed word is
	   dropped, and the target stays well over the 44 px minimum. */
	.eudb-burger__label {
		position: absolute;
		width: 1px;
		height: 1px;
		margin: -1px;
		padding: 0;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
		border: 0;
	}

	.eudb-burger {
		min-width: 52px;
		justify-content: center;
	}
}


/* THE PANEL STARTS AT 75rem, AND THE MASTHEAD IS WHY.
   Between 62rem and 75rem the row used to be logo + inline nav + switcher, and
   it fitted. It did not fit with the EU funding mark in it as well: at 1024 px
   the Swedish, Finnish and Greek navigations ran 20, 54 and 29 px past the
   viewport and scrolled the document sideways, so the breakpoint moved rather
   than the emblem shrinking. The mark has since left the masthead; the breakpoint
   is kept at 75rem by decision, and moving it back needs the Finnish and Greek
   navigation re-measured first.

   IN THIS BAND THE BURGER AND THE SWITCHER SIT TOGETHER AT THE RIGHT, in
   document order. The burger takes the free space; the switcher gives up the
   auto margin it needs above 75rem, where it leads the inline navigation. */
@media (min-width: 48.001rem) {
	.eudb-lang--header {
		display: none;
	}
}

@media (max-width: 75rem) {
	.eudb-burger {
		display: inline-flex;
		margin-left: auto;
	}

	.eudb-lang--masthead {
		margin-left: 0;
	}

	.eudb-masthead__nav {
		display: none;
		position: absolute;
		left: 0;
		right: 0;
		top: 100%;
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		background: var(--paper);
		border-bottom: 3px solid var(--amber);
		box-shadow: 0 18px 34px rgba(30, 43, 22, 0.16);
		padding: var(--space-2) var(--gutter) var(--space-4);
		/* The panel opens below the masthead — it is positioned against the
		   whole header — and over the floating stamp (the masthead's z-index is
		   above it). It is not height-capped any more: the header no longer sticks,
		   so a panel taller than the screen in Finnish simply extends the page,
		   and the page's own scroll reaches its last item. */
	}

	.eudb-masthead__nav.is-open {
		display: flex;
	}

	.eudb-nav {
		width: 100%;
	}

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

	.eudb-nav__item {
		flex-wrap: wrap;
		border-bottom: var(--rule);
	}

	.eudb-nav__link {
		flex: 1;
		padding: 0.9rem 0;
		font-size: var(--t-base);
		min-height: 52px;
	}

	.eudb-nav__item.is-current > .eudb-nav__link {
		box-shadow: none;
		color: var(--olive);
	}

	.eudb-nav__item.is-current > .eudb-nav__link::before {
		content: '';
		width: 4px;
		align-self: stretch;
		background: var(--amber);
		margin-right: 0.75rem;
	}

	.eudb-nav__toggle {
		width: 52px;
		margin: 0;
	}

	.eudb-nav__sub {
		position: static;
		width: 100%;
		border: 0;
		border-top: var(--rule);
		box-shadow: none;
		background: var(--linen);
		padding: 0;
		margin-bottom: var(--space-2);
	}

	.eudb-nav__sub .eudb-nav__link {
		padding-left: 1.25rem;
	}

	.eudb-lang {
		margin-top: var(--space-3);
	}
}

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

.eudb-hero {
	position: relative;
	isolation: isolate;
	background: var(--olive-deep);
	color: #fff;
	display: flex;
	align-items: flex-end;
}

.eudb-hero--standard {
	min-height: clamp(20rem, 42vw, 30rem);
}

/* THE TALL OPENING FILLS WHAT THE HEADER LEAVES OF THE FIRST SCREEN. The
   header is static (one tier since 2026-10-12), so a height taken from the viewport
   alone would push the hero's bottom-aligned headline and buttons below the
   fold on a laptop. --eudb-header-h is the header's height as the stylesheet
   builds it (section 7), not a measurement, so this is right on first layout. */
.eudb-hero--tall {
	min-height: clamp(24rem, calc(100svh - var(--eudb-header-h)), 36rem);
}

.eudb-hero__media {
	position: absolute;
	inset: 0;
	z-index: -2;
	overflow: hidden;
}

.eudb-hero__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center 45%;
}

/* THE SCRIM IS NOT DECORATION. The headline sits on a photograph, and a
   photograph's brightness is not something CSS can know. Two overlapping
   gradients — one from the bottom, one from the left — guarantee the contrast
   ratio under the text without flattening the whole image into mud. */
.eudb-hero--standard::before,
.eudb-hero--tall::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: -1;
	background:
		linear-gradient(to top, rgba(20, 31, 14, 0.86) 0%, rgba(20, 31, 14, 0.6) 42%, rgba(20, 31, 14, 0.16) 78%, rgba(20, 31, 14, 0.06) 100%),
		linear-gradient(to right, rgba(20, 31, 14, 0.62) 0%, rgba(20, 31, 14, 0.2) 52%, rgba(20, 31, 14, 0) 82%);
}

.eudb-hero__inner {
	width: calc(100% - var(--eudb-shell-l) - max(var(--eudb-shell-l), var(--eudb-lane, 0px)));
	margin-inline: var(--eudb-shell-l) auto;
	padding-block: var(--space-6) var(--space-5);
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--space-4);
}

.eudb-hero__copy {
	max-width: 42rem;
}

.eudb-hero__title {
	font-size: var(--t-display);
	color: #fff;
	margin-bottom: var(--space-3);
	/* A measure, not a width. The campaign line is a full sentence; capping it
	   at roughly fifteen characters per line is what turns it into three
	   deliberate lines instead of four accidental ones. */
	max-width: 15ch;
	text-wrap: balance;
	text-shadow: 0 1px 18px rgba(16, 25, 11, 0.35);
}

.eudb-hero--standard .eudb-hero__title {
	font-size: var(--t-h1);
}

.eudb-hero__lead {
	font-size: var(--t-lead);
	color: #ece7d8;
	margin-bottom: 0;
	max-width: 46ch;
}

.eudb-hero--quiet {
	background: var(--accent-wash);
	color: var(--ink);
	border-bottom: var(--rule);
	min-height: 0;
}

.eudb-hero--quiet::before {
	display: none;
}

.eudb-hero--quiet .eudb-hero__inner {
	padding-block: var(--space-6) var(--space-5);
}

.eudb-hero--quiet .eudb-hero__title {
	color: var(--olive-deep);
	font-size: var(--t-h1);
	text-shadow: none;
}

.eudb-hero--quiet .eudb-hero__lead {
	color: var(--ink-soft);
}

@media (max-width: 48rem) {
	.eudb-hero__inner {
		flex-direction: column;
		align-items: flex-start;
		padding-block: var(--space-5) var(--space-4);
	}

	.eudb-hero__copy {
		max-width: none;
	}
}

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

.eudb-crumbs {
	padding-block: var(--space-3) 0;
}

.eudb-crumbs ol {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.4rem;
	margin: 0;
	padding: 0;
	font-size: var(--t-xs);
	color: var(--ink-soft);
}

.eudb-crumbs li + li::before {
	content: '/';
	margin-right: 0.4rem;
	opacity: 0.5;
}

/* SC 2.5.8 again, and the same reasoning: a breadcrumb reads as a line of
   text, so the inline exception probably covers it — but the separators are
   generated content rather than real text between the links, which makes
   "probably" the operative word. Giving the links the criterion's own 24 px
   costs nothing and settles it. */
.eudb-crumbs a {
	display: inline-flex;
	align-items: center;
	min-height: 24px;
	color: var(--ink-soft);
}

.eudb-crumbs [aria-current='page'] {
	color: var(--ink);
	font-weight: 600;
}

/* --------------------------------------------------------------------------
   10. Block content flow
   The editor writes in Gutenberg; this is where that output is given the
   campaign's measure, rhythm and alignment behaviour.
   -------------------------------------------------------------------------- */

.eudb-flow {
	padding-block: var(--space-5) var(--space-6);
}

.eudb-flow > * {
	width: calc(100% - var(--eudb-narrow-l) - max(var(--eudb-narrow-l), var(--eudb-lane, 0px)));
	margin-inline: var(--eudb-narrow-l) auto;
	margin-block: 0 var(--space-3);
}

.eudb-flow > .alignwide {
	width: calc(100% - var(--eudb-shell-l) - max(var(--eudb-shell-l), var(--eudb-lane, 0px)));
	margin-inline: var(--eudb-shell-l) auto;
}

/* The questionnaire panel (mu-plugin, invitation.css) centres itself with
   `margin: … auto`; held to the content's left edge here so that its right
   edge keeps out of the floating stamp's lane like every other child. */
.eudb-flow > .eudb-qpanel {
	margin-inline: var(--eudb-narrow-l) auto;
}

.eudb-flow > .alignfull {
	width: 100%;
	max-width: none;
	margin-inline: 0;
	margin-block: var(--space-6);
}

.eudb-flow > h2 {
	margin-top: var(--space-5);
}

.eudb-flow > h3 {
	margin-top: var(--space-4);
}

.eudb-flow > h2:first-child,
.eudb-flow > h3:first-child {
	margin-top: 0;
}

.eudb-flow > ul,
.eudb-flow > ol {
	padding-left: 1.35rem;
}

.eudb-flow li {
	margin-bottom: 0.4rem;
}

.eudb-flow > figure {
	margin-block: var(--space-4);
}

.eudb-flow figcaption {
	font-size: var(--t-sm);
	color: var(--ink-soft);
	margin-top: var(--space-2);
	padding-left: 0.9rem;
	border-left: 3px solid var(--accent);
}

.eudb-flow .has-lead-font-size {
	font-size: var(--t-lead);
	line-height: 1.5;
	color: var(--ink-soft);
}

/* A table that can scroll sideways is a tab stop (see inc/setup.php). It has to
   look like one when it is focused, and it has to be obvious that it scrolls. */
.eudb-flow figure.wp-block-table {
	overflow-x: auto;
}

.eudb-flow figure.wp-block-table:focus-visible {
	outline: var(--focus);
	outline-offset: 2px;
}

.eudb-flow .wp-block-table table {
	border-collapse: collapse;
	width: 100%;
	font-size: var(--t-sm);
}

.eudb-flow .wp-block-table th,
.eudb-flow .wp-block-table td {
	border: 1px solid var(--stone);
	padding: 0.55rem 0.7rem;
	text-align: left;
	vertical-align: top;
}

.eudb-flow .wp-block-table thead th {
	background: var(--linen-deep);
	font-size: var(--t-xs);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.eudb-flow .wp-block-table code {
	font-size: 0.9em;
	word-break: break-word;
}

.eudb-flow blockquote {
	margin: var(--space-5) auto;
	padding: 0 0 0 var(--space-3);
	border-left: 4px solid var(--accent);
	font-family: var(--font-display);
	font-size: var(--t-h3);
	line-height: 1.32;
	color: var(--olive-deep);
}

.eudb-flow blockquote p:last-child {
	margin-bottom: 0;
}

.eudb-flow--front {
	padding-top: 0;
}

/* Core group blocks used as full-bleed campaign sections. */
.eudb-flow .wp-block-group.alignfull {
	padding-block: var(--space-6);
}

.eudb-flow .wp-block-group.alignfull > * {
	width: calc(100% - var(--eudb-shell-l) - max(var(--eudb-shell-l), var(--eudb-lane, 0px)));
	margin-inline: var(--eudb-shell-l) auto;
}

.eudb-flow .wp-block-group.alignfull > .eudb-grid,
.eudb-flow .wp-block-group.alignfull > .eudb-diptych,
.eudb-flow .wp-block-group.alignfull > .eudb-pillars {
	width: calc(100% - var(--eudb-shell-l) - max(var(--eudb-shell-l), var(--eudb-lane, 0px)));
}

/* A BAND CARRIES ITS OWN RHYTHM; SPACERS MUST NOT STACK ON IT. Each band
   already pads 4.5rem top and bottom, so the generic .alignfull margin above
   put a further 4.5rem of paper between two bands, and the last child's own
   margin (a grid's 2rem) sat inside the padding: 190px of nothing above the
   home page's questionnaire panel and up to 334px above the footer, measured
   2026-09-30. Bands therefore take no margin against each other; a TINTED band
   keeps its 4.5rem against ordinary content so the colour change still has air;
   a PLAIN band, whose padding is indistinguishable from margin, takes none. */
.eudb-flow > .wp-block-group.alignfull {
	margin-block: 0;
}

.eudb-flow > :not(.wp-block-group.alignfull) + .wp-block-group.alignfull.has-background,
.eudb-flow > .wp-block-group.alignfull.has-background + :not(.wp-block-group.alignfull) {
	margin-top: var(--space-6);
}

.eudb-flow .wp-block-group.alignfull > * > :first-child {
	margin-top: 0;
}

.eudb-flow .wp-block-group.alignfull > * > :last-child {
	margin-bottom: 0;
}

/* A plain band that ends the flow hands its bottom spacing to whatever
   follows — the footer's margin, or the flow's padding. */
.eudb-flow > .wp-block-group.alignfull:not(.has-background):last-child {
	padding-bottom: 0;
}

/* A flow that ends the page hands its bottom spacing to the footer's margin,
   which every template already has; padding here stacked with it (167px under
   the last paragraph of every page and post). Without the padding, the last
   child's margin collapses into the footer's 4.5rem, the same spacing the
   archives end with. */
/* "Ends <main>" ignores the floating stamp's rail (section 7), which is always
   the last child of <main> (footer.php prints it on every page) and, at zero
   height, lets the margin collapse through it into the footer's. Two rules,
   not one list: an engine without `:nth-last-child(… of S)` would drop the
   whole list, and the plain second-to-last form is right whenever the rail is
   there. */
.eudb-main > .eudb-flow:nth-last-child(2),
.eudb-main > article:nth-last-child(2) > .eudb-flow:last-child {
	padding-bottom: 0;
}

.eudb-main > .eudb-flow:nth-last-child(1 of :not(.eudb-float)),
.eudb-main > article:nth-last-child(1 of :not(.eudb-float)) > .eudb-flow:last-child {
	padding-bottom: 0;
}

/* Palette utilities for the block editor's colour controls.
   Hand-written because inc/assets.php removes core's global-styles output —
   see the note there. Every slug offered in eudb_editor_palette() must appear
   here in both forms, or an editor's colour choice silently does nothing. */

.has-ink-color { color: var(--ink); }
.has-olive-color { color: var(--olive); }
.has-grove-color { color: var(--grove); }
.has-amber-color { color: var(--amber-deep); }
.has-raisin-color { color: var(--raisin); }
.has-linen-color { color: var(--linen); }
.has-paper-color { color: var(--paper); }

.has-ink-background-color { background-color: var(--ink); color: #fff; }
.has-olive-background-color { background-color: var(--olive); color: #fff; }
.has-grove-background-color { background-color: var(--grove); color: #fff; }
.has-amber-background-color { background-color: var(--amber); color: #fff; }
.has-raisin-background-color { background-color: var(--raisin); color: #fff; }
.has-linen-background-color { background-color: var(--linen); }
.has-linen-deep-background-color { background-color: var(--linen-deep); }
.has-paper-background-color { background-color: var(--paper); }

.has-ink-background-color h2, .has-ink-background-color h3,
.has-olive-background-color h2, .has-olive-background-color h3,
.has-grove-background-color h2, .has-grove-background-color h3,
.has-amber-background-color h2, .has-amber-background-color h3,
.has-raisin-background-color h2, .has-raisin-background-color h3 { color: #fff; }

.has-ink-background-color a, .has-olive-background-color a,
.has-grove-background-color a, .has-amber-background-color a,
.has-raisin-background-color a { color: #fff; }

/* Font sizes offered in the editor. */
.has-small-font-size { font-size: var(--t-sm); }
.has-normal-font-size { font-size: var(--t-base); }
.has-large-font-size { font-size: var(--t-h3); }


/* --------------------------------------------------------------------------
   11. Cards and grids
   No shadows and no rounded boxes: a hairline above the body, a large picture,
   and type doing the separating.
   -------------------------------------------------------------------------- */

.eudb-grid {
	display: grid;
	gap: var(--space-4) var(--space-3);
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
	margin-block: var(--space-4);
}

.eudb-card {
	position: relative;
	display: flex;
	flex-direction: column;
	background: none;
}

.eudb-card__media {
	overflow: hidden;
	background: var(--stone-soft);
	aspect-ratio: 3 / 2;
	margin-bottom: var(--space-3);
}

.eudb-card__media .eudb-thumb {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.eudb-card:hover .eudb-card__media .eudb-thumb {
	transform: scale(1.035);
}

@media (prefers-reduced-motion: reduce) {
	.eudb-card__media .eudb-thumb,
	.eudb-card:hover .eudb-card__media .eudb-thumb {
		transition: none;
		transform: none;
	}
}

.eudb-card__body {
	border-top: 2px solid var(--accent);
	padding-top: var(--space-2);
	flex: 1;
	display: flex;
	flex-direction: column;
}

.eudb-card__kicker {
	font-size: var(--t-xs);
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--accent-deep);
	margin: 0 0 var(--space-1);
}

.eudb-card__title {
	font-size: var(--t-h3);
	margin: 0 0 var(--space-2);
	letter-spacing: -0.01em;
}

.eudb-card__title a {
	color: var(--olive-deep);
	text-decoration: none;
}

.eudb-card__title a:hover {
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

/* The whole card is clickable but only the heading is a link: one link in the
   accessibility tree, one target for everyone else. */
.eudb-card__title a::after {
	content: '';
	position: absolute;
	inset: 0;
}

.eudb-card__excerpt {
	font-size: var(--t-sm);
	color: var(--ink-soft);
	margin: 0 0 var(--space-2);
	flex: 1;
}

.eudb-card__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	font-size: var(--t-xs);
	font-weight: 600;
	letter-spacing: 0.04em;
	color: var(--ink-soft);
	margin: 0;
}

.eudb-card__metaitem + .eudb-card__metaitem::before {
	content: '·';
	margin-right: var(--space-2);
	opacity: 0.6;
}

.eudb-empty {
	padding: var(--space-5) 0;
	font-size: var(--t-lead);
	color: var(--ink-soft);
	border-top: var(--rule);
}

/* --------------------------------------------------------------------------
   12. Product diptych
   The two promoted products, side by side and colour-coded, so the structure
   of the campaign is legible before a word is read.
   -------------------------------------------------------------------------- */

.eudb-diptych {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-4);
	margin-block: var(--space-4);
}

.eudb-diptych__panel {
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--paper);
	border-top: 5px solid var(--accent);
}

.eudb-diptych__media {
	aspect-ratio: 4 / 5;
	overflow: hidden;
	background: var(--stone-soft);
}

.eudb-diptych__media .eudb-thumb {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.eudb-diptych__panel:hover .eudb-thumb {
	transform: scale(1.03);
}

@media (prefers-reduced-motion: reduce) {
	.eudb-diptych__media .eudb-thumb,
	.eudb-diptych__panel:hover .eudb-thumb {
		transition: none;
		transform: none;
	}
}

.eudb-diptych__body {
	padding: var(--space-3) var(--space-3) var(--space-4);
}

.eudb-diptych__title {
	font-size: var(--t-h2);
	margin-bottom: var(--space-2);
}

.eudb-diptych__title a {
	color: var(--olive-deep);
	text-decoration: none;
}

.eudb-diptych__title a::after {
	content: '';
	position: absolute;
	inset: 0;
}

.eudb-diptych__panel:hover .eudb-diptych__title a {
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.eudb-diptych__text {
	color: var(--ink-soft);
	margin-bottom: var(--space-3);
}

.eudb-diptych__more {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-size: var(--t-sm);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--accent-deep);
}

.eudb-diptych__more::after {
	content: '';
	width: 1.4rem;
	height: 1px;
	background: currentColor;
	transition: width 0.25s ease;
}

.eudb-diptych__panel:hover .eudb-diptych__more::after {
	width: 2.4rem;
}

@media (max-width: 53rem) {
	.eudb-diptych {
		grid-template-columns: minmax(0, 1fr);
	}

	.eudb-diptych__media {
		aspect-ratio: 3 / 2;
	}
}

/* --------------------------------------------------------------------------
   13. Pillars
   The four pillars of the European production model, as a numbered list with
   hairlines. Not four cards.
   -------------------------------------------------------------------------- */

.eudb-pillars {
	list-style: none;
	counter-reset: none;
	margin: var(--space-4) 0 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0;
	border-top: var(--rule);
}

.eudb-pillars__item {
	position: relative;
	padding: var(--space-4) var(--space-4) var(--space-4) 0;
	border-bottom: var(--rule);
	display: grid;
	grid-template-columns: 3.4rem minmax(0, 1fr);
	column-gap: var(--space-2);
	align-items: start;
}

.eudb-pillars__item:nth-child(odd) {
	border-right: var(--rule);
	padding-right: var(--space-5);
}

.eudb-pillars__item:nth-child(even) {
	padding-left: var(--space-4);
}

.eudb-pillars__num {
	grid-row: 1 / span 2;
	font-family: var(--font-display);
	font-size: 2rem;
	font-weight: 400;
	line-height: 1;
	/* Not --amber at 85%: that measured 2.85:1 on linen, below the 3:1 that
	   large text needs, and the numbers are part of the reading order even
	   though they are aria-hidden from it. */
	color: var(--amber-deep);
}

.eudb-pillars__name {
	font-size: var(--t-h3);
	margin: 0 0 var(--space-2);
	align-self: center;
}

.eudb-pillars__text {
	grid-column: 2;
	font-size: var(--t-sm);
	color: var(--ink-soft);
	margin: 0;
}

@media (max-width: 53rem) {
	.eudb-pillars {
		grid-template-columns: minmax(0, 1fr);
	}

	.eudb-pillars__item,
	.eudb-pillars__item:nth-child(odd),
	.eudb-pillars__item:nth-child(even) {
		padding: var(--space-3) 0;
		border-right: 0;
		padding-left: 0;
	}
}

/* --------------------------------------------------------------------------
   14. Archive heads, filters, pagination
   -------------------------------------------------------------------------- */

.eudb-archive-head {
	background: var(--accent-wash);
	border-bottom: var(--rule);
	padding-bottom: var(--space-5);
}

.eudb-archive-head .eudb-crumbs {
	padding-top: var(--space-3);
	margin-bottom: var(--space-4);
}

.eudb-archive-head__title {
	font-size: var(--t-h1);
	margin-bottom: var(--space-3);
	max-width: 22ch;
}

.eudb-archive-head__lead {
	font-size: var(--t-lead);
	color: var(--ink-soft);
	max-width: 52ch;
	margin: 0;
}

.eudb-filters {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--space-3) var(--space-5);
	padding-block: var(--space-4) var(--space-3);
	border-bottom: var(--rule);
}

.eudb-filters__set {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--space-2);
}

.eudb-filters__label {
	font-family: var(--font-body);
	font-size: var(--t-xs);
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--ink-soft);
	margin: 0;
}

.eudb-filters__list {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-1);
	margin: 0;
	padding: 0;
}

.eudb-filters__clear {
	margin: 0;
}

.eudb-chip {
	display: inline-flex;
	align-items: center;
	min-height: 40px;
	padding: 0 0.9rem;
	border: 1px solid var(--stone);
	background: var(--paper);
	font-size: var(--t-sm);
	font-weight: 600;
	color: var(--ink);
	text-decoration: none;
}

.eudb-chip:hover {
	border-color: var(--olive);
	color: var(--olive);
}

.eudb-chip.is-current {
	background: var(--olive);
	border-color: var(--olive);
	color: #fff;
}

.eudb-chip--clear {
	border-style: dashed;
}

.eudb-pagination {
	padding-block: var(--space-4) var(--space-6);
	border-top: var(--rule);
	margin-top: var(--space-4);
}

.eudb-pagination ul {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-1);
	margin: 0;
	padding: 0;
}

.eudb-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	padding: 0 0.7rem;
	border: 1px solid var(--stone);
	background: var(--paper);
	color: var(--ink);
	text-decoration: none;
	font-weight: 600;
}

.eudb-pagination .page-numbers.current {
	background: var(--olive);
	border-color: var(--olive);
	color: #fff;
}

/* --------------------------------------------------------------------------
   15. Articles
   -------------------------------------------------------------------------- */

.eudb-article__head {
	padding-block: var(--space-4) var(--space-4);
	max-width: 48rem;
}

.eudb-article__title {
	font-size: var(--t-h1);
	text-wrap: balance;
}

.eudb-article__meta {
	font-size: var(--t-sm);
	color: var(--ink-soft);
	margin-bottom: var(--space-3);
}

.eudb-article__lead {
	font-size: var(--t-lead);
	color: var(--ink-soft);
	margin: 0;
}

.eudb-article__figure {
	margin: 0;
	width: calc(100% - var(--eudb-shell-l) - max(var(--eudb-shell-l), var(--eudb-lane, 0px)));
	margin-inline: var(--eudb-shell-l) auto;
}

.eudb-article__figure .eudb-thumb {
	width: 100%;
	aspect-ratio: 16 / 7;
	object-fit: cover;
}

.eudb-article__figure figcaption {
	font-size: var(--t-sm);
	color: var(--ink-soft);
	margin-top: var(--space-2);
	padding-left: 0.9rem;
	border-left: 3px solid var(--accent);
}

.eudb-flow--article {
	padding-top: var(--space-5);
}

.eudb-results {
	list-style: none;
	margin: var(--space-4) 0 0;
	padding: 0;
	border-top: var(--rule);
}

.eudb-results__item {
	padding-block: var(--space-3);
	border-bottom: var(--rule);
}

.eudb-results__type {
	font-size: var(--t-xs);
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--accent-deep);
	margin: 0 0 var(--space-1);
}

.eudb-results__title {
	font-size: var(--t-h3);
	margin: 0 0 var(--space-1);
}

.eudb-results__title a {
	color: var(--olive-deep);
	text-decoration: none;
}

.eudb-results__title a:hover {
	text-decoration: underline;
}

.eudb-results__excerpt {
	color: var(--ink-soft);
	font-size: var(--t-sm);
	margin: 0;
}

.eudb-searchform {
	padding-block: var(--space-4);
	max-width: 34rem;
}

.eudb-search__label {
	display: block;
	font-size: var(--t-sm);
	font-weight: 700;
	margin-bottom: var(--space-1);
}

.eudb-search__row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-1);
}

.eudb-search__input {
	flex: 1 1 11rem;
	/* `min-width: 0` is load-bearing. A flex item defaults to `min-width: auto`,
	   which refuses to shrink below its intrinsic content width — so at 320px
	   the input held its ground and pushed the Search button 27px past the
	   viewport, putting a horizontal scrollbar on the 404 and search pages.
	   WCAG 2.2 §1.4.10 Reflow. Measured, not guessed. */
	min-width: 0;
	min-height: 48px;
	padding: 0 0.85rem;
	border: 2px solid var(--stone);
	background: var(--paper);
	font: inherit;
	font-size: var(--t-sm);
	color: var(--ink);
}

.eudb-search__input:focus {
	border-color: var(--olive);
}

/* --------------------------------------------------------------------------
   16. Recipes
   -------------------------------------------------------------------------- */

.eudb-recipe__head {
	width: calc(100% - var(--eudb-shell-l) - max(var(--eudb-shell-l), var(--eudb-lane, 0px)));
	margin-inline: var(--eudb-shell-l) auto;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr);
	gap: var(--space-5);
	align-items: start;
	padding-block: var(--space-4) var(--space-6);
}

.eudb-recipe__title {
	font-size: var(--t-h1);
	text-wrap: balance;
}

.eudb-recipe__lead {
	font-size: var(--t-lead);
	color: var(--ink-soft);
	margin-bottom: var(--space-4);
}

.eudb-recipe__figure {
	margin: 0;
}

.eudb-recipe__figure .eudb-thumb {
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
}

/* The honest caption about library photography. Small, present, not hidden. */
.eudb-recipe__figure figcaption {
	font-size: var(--t-xs);
	line-height: 1.5;
	color: var(--ink-soft);
	margin-top: var(--space-2);
	padding-left: 0.8rem;
	border-left: 3px solid var(--accent);
}

.eudb-facts {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 7.5rem), 1fr));
	gap: 0;
	margin: 0;
	border-top: 2px solid var(--accent);
	border-bottom: var(--rule);
}

.eudb-facts__item {
	padding: var(--space-2) var(--space-2) var(--space-2) 0;
}

.eudb-facts dt {
	font-size: var(--t-xs);
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ink-soft);
	margin-bottom: 0.2rem;
}

.eudb-facts dd {
	margin: 0;
	font-family: var(--font-display);
	font-size: var(--t-h4);
	color: var(--olive-deep);
}

.eudb-facts__item--total dd {
	color: var(--accent-deep);
}

.eudb-recipe__body {
	width: calc(100% - var(--eudb-shell-l) - max(var(--eudb-shell-l), var(--eudb-lane, 0px)));
	margin-inline: var(--eudb-shell-l) auto;
	display: grid;
	grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
	gap: var(--space-5);
	align-items: start;
	padding-bottom: var(--space-7);
}

.eudb-recipe__ingredients {
	background: var(--accent-wash);
	padding: var(--space-3) var(--space-3) var(--space-4);
	position: sticky;
	/* Was 96px, to clear the sticky masthead. The masthead no longer sticks. */
	top: var(--space-3);
}

.eudb-recipe__ingredients h2,
.eudb-recipe__method h2 {
	font-size: var(--t-h3);
	margin-bottom: var(--space-3);
}

.eudb-recipe__group {
	font-family: var(--font-body);
	font-size: var(--t-xs);
	font-weight: 700;
	letter-spacing: 0.11em;
	text-transform: uppercase;
	color: var(--accent-deep);
	margin: var(--space-3) 0 var(--space-2);
}

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

.eudb-recipe__list li {
	padding: 0.5rem 0 0.5rem 1.3rem;
	border-bottom: 1px solid rgba(30, 43, 22, 0.12);
	font-size: var(--t-sm);
	position: relative;
}

.eudb-recipe__list li::before {
	content: '';
	position: absolute;
	left: 0;
	top: 1.05em;
	width: 6px;
	height: 9px;
	background: var(--accent);
	border-radius: 50% 50% 50% 50% / 65% 65% 35% 35%;
	transform: rotate(180deg);
}

.eudb-recipe__list li:last-child {
	border-bottom: 0;
}

.eudb-recipe__steps {
	list-style: none;
	counter-reset: eudb-step;
	margin: 0;
	padding: 0;
}

.eudb-recipe__steps li {
	counter-increment: eudb-step;
	position: relative;
	padding: 0 0 var(--space-3) 3.2rem;
	margin-bottom: var(--space-3);
	border-bottom: var(--rule);
}

.eudb-recipe__steps li:last-child {
	border-bottom: 0;
}

.eudb-recipe__steps li::before {
	content: counter(eudb-step, decimal-leading-zero);
	position: absolute;
	left: 0;
	top: -0.15rem;
	font-family: var(--font-display);
	font-size: 1.6rem;
	line-height: 1;
	color: var(--accent-deep);
}

.eudb-note {
	background: var(--paper);
	border-left: 4px solid var(--accent);
	padding: var(--space-3);
	margin-top: var(--space-4);
}

.eudb-note h3 {
	font-family: var(--font-body);
	font-size: var(--t-sm);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	margin-bottom: var(--space-1);
	color: var(--accent-deep);
}

.eudb-note p:last-child {
	margin-bottom: 0;
}

.eudb-recipe__prose {
	margin-top: var(--space-4);
}

@media (max-width: 60rem) {
	.eudb-recipe__head,
	.eudb-recipe__body {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--space-4);
	}

	.eudb-recipe__figure {
		order: -1;
	}

	.eudb-recipe__figure .eudb-thumb {
		aspect-ratio: 3 / 2;
	}

	.eudb-recipe__ingredients {
		position: static;
	}
}

/* --------------------------------------------------------------------------
   17. Forms
   -------------------------------------------------------------------------- */

.eudb-form {
	margin-top: var(--space-4);
}

.eudb-form__row {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-3);
}

@media (max-width: 44rem) {
	.eudb-form__row {
		grid-template-columns: minmax(0, 1fr);
	}
}

.eudb-field {
	margin-bottom: var(--space-3);
}

.eudb-field label {
	display: block;
	font-size: var(--t-sm);
	font-weight: 700;
	margin-bottom: var(--space-1);
}

.eudb-field input[type='text'],
.eudb-field input[type='email'],
.eudb-field select,
.eudb-field textarea {
	width: 100%;
	min-height: 48px;
	padding: 0.6rem 0.8rem;
	border: 2px solid var(--stone);
	background: var(--paper);
	font: inherit;
	font-size: var(--t-sm);
	color: var(--ink);
}

.eudb-field textarea {
	line-height: 1.55;
	resize: vertical;
}

.eudb-field input:focus,
.eudb-field select:focus,
.eudb-field textarea:focus {
	border-color: var(--olive);
}

.eudb-field.is-invalid input,
.eudb-field.is-invalid select,
.eudb-field.is-invalid textarea {
	border-color: var(--raisin);
	background: #fdf7f7;
}

.eudb-field__hint {
	font-size: var(--t-xs);
	color: var(--ink-soft);
	margin: var(--space-1) 0 0;
}

/* The error is red AND prefixed, because colour alone is not an indicator. */
.eudb-field__error {
	font-size: var(--t-sm);
	font-weight: 600;
	color: var(--raisin-deep);
	margin: var(--space-1) 0 0;
}

.eudb-field__error::before {
	content: '⚠ ';
}

.eudb-field--check {
	display: grid;
	grid-template-columns: 1.5rem minmax(0, 1fr);
	gap: var(--space-2);
	align-items: start;
}

.eudb-field--check input[type='checkbox'] {
	/* 24 CSS px exactly — WCAG 2.2 SC 2.5.8 (AA). See the note on the consent
	   banner's box; the same 2.4 px argument is not worth having twice. */
	width: 1.5rem;
	height: 1.5rem;
	margin-top: 0.15rem;
	accent-color: var(--olive);
}

.eudb-field--check label {
	font-weight: 400;
	font-size: var(--t-sm);
	margin: 0;
}

.eudb-field--check .eudb-field__error {
	grid-column: 1 / -1;
}

.eudb-req {
	color: var(--raisin);
	font-weight: 700;
}

.eudb-form__required {
	font-size: var(--t-xs);
	color: var(--ink-soft);
}

/* The honeypot. Off-screen rather than display:none, because some bots skip
   fields that are display:none and fill the ones that are not. */
.eudb-hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.eudb-form-note {
	padding: var(--space-3) var(--space-4);
	margin-bottom: var(--space-4);
	border-left: 5px solid var(--olive);
	background: var(--paper);
}

.eudb-form-note:focus {
	outline: var(--focus);
	outline-offset: 2px;
}

.eudb-form-note h2 {
	font-size: var(--t-h3);
	margin-bottom: var(--space-2);
}

.eudb-form-note--error {
	border-left-color: var(--raisin);
	background: #fdf6f6;
}

.eudb-form-note--error h2 {
	color: var(--raisin-deep);
}

.eudb-form-note--ok {
	border-left-color: var(--grove);
	background: #f2f5e8;
}

.eudb-form-note p:last-child,
.eudb-form-note ul:last-child {
	margin-bottom: 0;
}

.eudb-contact-details {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
	gap: var(--space-4);
	margin-block: var(--space-4);
	padding-top: var(--space-4);
	border-top: var(--rule);
}

.eudb-contact-details h2,
.eudb-contact-details h3 {
	font-family: var(--font-body);
	font-size: var(--t-sm);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--accent-deep);
	margin-bottom: var(--space-2);
}

.eudb-contact-details p {
	margin-bottom: var(--space-1);
}

.eudb-contact-details__note {
	font-size: var(--t-sm);
	color: var(--ink-soft);
}

/* --------------------------------------------------------------------------
   18. Footer and the compliance band
   -------------------------------------------------------------------------- */

.eudb-footer {
	background: var(--olive-deep);
	color: #ded9ca;
	margin-top: var(--space-6);
}

.eudb-footer a {
	color: #ece7d8;
}

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

.eudb-footer__top {
	width: min(100% - (var(--gutter) * 2), var(--shell));
	margin-inline: auto;
	display: grid;
	grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1fr);
	gap: var(--space-5) var(--space-4);
	padding-block: var(--space-6) var(--space-5);
}

/* 150px against the band's 200px emblem. The campaign's own mark is not being
   hidden — it is the first thing in the footer and it carries the strapline —
   but it may not be the more prominent of the two, and at 190px it was. */
.eudb-footer__logo {
	width: 150px;
	height: auto;
	/* The logo is dark-on-transparent artwork. On the dark footer it is placed
	   on its own light plate rather than inverted — inverting an approved mark
	   is modifying it. */
	background: var(--linen);
	padding: 0.75rem 1rem;
}

.eudb-footer__strap {
	overflow-wrap: break-word;
	font-family: var(--font-display);
	font-size: var(--t-h4);
	color: #e7e1d0;
	margin-top: var(--space-3);
	max-width: 22ch;
}

.eudb-footer__heading {
	font-family: var(--font-body);
	font-size: var(--t-xs);
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: #b9c0a8;
	margin: 0 0 var(--space-2);
}

.eudb-footer__heading + .eudb-footer__heading,
.eudb-footer__list + .eudb-footer__heading,
.eudb-lang + .eudb-footer__heading {
	margin-top: var(--space-4);
}

.eudb-footer__list {
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: var(--t-sm);
}

.eudb-footer__list li {
	margin-bottom: var(--space-2);
}

.eudb-footer__list a {
	display: inline-block;
	min-height: 28px;
	padding-block: 0.15rem;
}

.eudb-footer__label {
	display: block;
	font-size: var(--t-xs);
	color: #a9b199;
	margin-bottom: 0.1rem;
}

.eudb-footer__social {
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: var(--t-sm);
}

/*
 * WCAG 2.2 SC 2.5.8, Target Size (Minimum), which is AA. At the footer's small
 * type these links were 21px tall, and the alternative "undersized target"
 * spacing exception was being met by exactly 24px centre-to-centre — passing on
 * the boundary, where a font swap or a rounding difference would quietly drop it
 * below. Every other link in the footer is already 29px or more; these are made
 * to clear the rule outright rather than rely on the exception.
 */
.eudb-footer__social a {
	display: inline-flex;
	align-items: center;
	min-height: 24px;
	padding-block: 0.15rem;
}

.eudb-footer__social li + li {
	margin-top: 0.2rem;
}

.eudb-footer__note {
	font-size: var(--t-sm);
	color: #b9c0a8;
	margin-bottom: var(--space-2);
}

.eudb-consent-reopen {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 0 1rem;
	border: 1px solid rgba(255, 255, 255, 0.35);
	background: none;
	color: #ece7d8;
	font: inherit;
	font-size: var(--t-sm);
	font-weight: 600;
	cursor: pointer;
}

.eudb-consent-reopen:hover {
	background: rgba(255, 255, 255, 0.1);
	color: #fff;
}

/* The compliance band -------------------------------------------------------
   White, full bleed, and three items in document order: the emblem, the
   disclaimer with the owner line, then the theme statement with the ENJOY
   stamp. `order` is never used: what the eye reads and what a screen reader
   reads are the same sequence. Since 2026-10-12 (ΥΠΑΑΤ's second review) this
   band carries the page's only EU emblem, at the BOTTOM LEFT, and its stamp
   at the BOTTOM RIGHT:

     from 75rem    three columns; emblem and stamp both sit on the band's
                   bottom line, the text between them
     40 – 75rem    emblem | text, then the theme statement and the stamp on
                   their own row, right-aligned — at 62–75rem a third column
                   squeezed the disclaimer to ~250 px once the stamp grew
     below 40rem   stacked in the same order, the pair right-aligned last

   The emblem is the vertical lockup at 200px (176px on phones, the
   --eudb-band-eu-w token in section 7), against the footer logo's 118 x 80
   px of ink above it (96 x 65 on phones): its 184 x 171 px of painted ink is
   taller and larger on both surrogates. The flag is 0.545 x 200 = 109 px =
   2.88 cm.

   THE STAMP IS SIZED TO THE EMBLEM, "IN PROPORTION TO THE EU FLAG". Its
   painted height is the emblem's painted height less 1 px of margin, so it
   can never round into being the taller of the two (Article 17.2): 135 px
   wide on 200, 118.7 on 176. It was capped at 92 px until 2026-10-12. Its
   area stays well under the emblem's (about 107 x 170 against 184 x 171). */

.eudb-compliance {
	--eudb-band-enjoy-w: calc(var(--eudb-band-eu-w) * var(--eudb-v-ink-hk) / var(--eudb-enjoy-hk) - 1px);

	background: #fff;
	color: var(--ink);
	border-top: 4px solid var(--amber);
}

.eudb-compliance__inner {
	width: min(100% - (var(--gutter) * 2), var(--shell));
	margin-inline: auto;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--space-4) var(--space-5);
	padding-block: var(--space-5);
	align-items: start;
}

@media (40rem <= width < 75rem) {
	.eudb-compliance__inner {
		grid-template-columns: auto minmax(0, 1fr);
	}

	.eudb-compliance__enjoy {
		grid-column: 1 / -1;
	}
}

@media (width >= 75rem) {
	.eudb-compliance__inner {
		grid-template-columns: auto minmax(0, 1fr) auto;
	}

	.eudb-compliance__eu,
	.eudb-compliance__enjoy {
		align-self: end;
	}
}

.eudb-compliance .eudb-emblem {
	width: var(--eudb-band-eu-w);
	max-width: none;
	height: auto;
}

/* The local-language funding statement, on Swedish, Finnish and Greek pages
   only (inc/compliance.php). Reflex Blue, the flag's own colour, and no case
   or spacing effects: the Graphic Charter allows reflex blue, black or white
   beside the emblem, and no font effects. */
.eudb-compliance__statement {
	font-size: var(--t-xs);
	font-weight: 700;
	line-height: 1.45;
	color: #003399;
	margin: var(--space-2) 0 0;
	max-width: var(--eudb-band-eu-w);
}

/* The pair. The statement stands to the LEFT of the stamp and bottom-aligned
   with its ink; when the two no longer fit side by side (a phone with doubled
   text) the statement wraps to the line above, still right-aligned, and the
   stamp stays last and rightmost. */
.eudb-compliance__enjoy {
	justify-self: end;
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-end;
	align-items: flex-end;
	gap: var(--space-1) max(0px, calc(14px - var(--eudb-band-enjoy-w) * var(--eudb-enjoy-side-k)));
	min-width: 0;
	max-width: 100%;
}

.eudb-compliance .eudb-enjoy {
	flex: 0 0 auto;
	width: var(--eudb-band-enjoy-w);
	max-width: none;
	height: auto;
}

.eudb-compliance__theme {
	flex: 0 1 auto;
	min-width: min(9rem, 100%);
	max-width: 26ch;
	margin: 0;
	padding-bottom: calc(var(--eudb-band-enjoy-w) * var(--eudb-enjoy-foot-k));
	font-size: var(--t-xs);
	line-height: 1.45;
	color: var(--ink-soft);
	text-align: right;
	/* A MANDATORY TEXT IS NEVER HYPHENATED. `hyphens: auto` once split the Greek
	   Annex 5 line as «εκστρα-τείες» and «στη-ρίζει». Words wrap whole. */
	hyphens: manual;
	overflow-wrap: break-word;
}

.eudb-compliance__disclaimer,
.eudb-compliance__owner {
	font-size: var(--t-xs);
	line-height: 1.6;
	color: var(--ink-soft);
	margin: 0 0 var(--space-2);
	max-width: 78ch;
}

.eudb-compliance__owner {
	margin-bottom: 0;
}

.eudb-compliance__owner strong {
	color: var(--ink);
}

.eudb-footer__base {
	background: var(--olive-deep);
	border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.eudb-footer__base p {
	width: min(100% - (var(--gutter) * 2), var(--shell));
	margin-inline: auto;
	padding-block: var(--space-3);
	font-size: var(--t-xs);
	color: #a9b199;
	margin-bottom: 0;
}

@media (max-width: 62rem) {
	.eudb-footer__top {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 40rem) {
	.eudb-footer__top {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--space-4);
	}

	.eudb-footer__logo {
		width: 128px;
	}

	/* The band's emblem is 176px here (section 7): ink 162 x 151 px against
	   the footer logo's 96 x 65, and a flag of 96 px = 2.54 cm. */
}

/* --------------------------------------------------------------------------
   19. Consent banner
   -------------------------------------------------------------------------- */

.eudb-consent {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 120;
	background: var(--paper);
	border-top: 4px solid var(--amber);
	box-shadow: 0 -12px 40px rgba(20, 31, 14, 0.22);
	/* THE BANNER NEVER COVERS THE MASTHEAD OR THE FLOATING STAMP ON LANDING.
	   Measured 2026-09-30: at 320x568 and 360x640 an uncapped banner rose over
	   the EU marks then under the logo row (Greek from 8px below the top).
	   Since 2026-10-12 the stamp floats above the banner (section 7), so the
	   cap is the viewport less the header, the stamp's box and its two gaps:
	   the stamp always fits between the header and the banner, and the banner
	   scrolls internally instead. The 16rem floor keeps it usable on a very
	   short screen; site.js hides the stamp if the floor ever leaves it no
	   room, rather than letting it ride up into the header. */
	--eudb-float-room: calc(var(--eudb-float-w) * var(--eudb-enjoy-box-k) + var(--eudb-float-bottom) * 2);
	max-height: max(16rem, calc(100dvh - var(--eudb-header-h, 0px) - var(--eudb-float-room)));
	overflow-y: auto;
}

/* Landscape phones (short viewports): a 16rem floor would leave no room for
   the stamp (the EU tier, before 2026-10-12, measured at 844x390, 740x360,
   667x375, 568x320). There the floor drops to 6rem; the banner scrolls, and
   Tab brings each button into view. */
@media (max-height: 32rem) {
	.eudb-consent {
		max-height: max(6rem, calc(100dvh - var(--eudb-header-h, 0px) - var(--eudb-float-room)));
	}
}

.eudb-consent[hidden] {
	display: none;
}

.eudb-consent__inner {
	width: min(100% - (var(--gutter) * 2), var(--shell));
	margin-inline: auto;
	padding-block: var(--space-3);
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 19rem);
	gap: var(--space-3) var(--space-4);
	align-items: start;
}

.eudb-consent__title {
	font-size: var(--t-h4);
	font-family: var(--font-display);
	margin-bottom: var(--space-1);
}

.eudb-consent__text {
	font-size: var(--t-sm);
	color: var(--ink-soft);
	margin-bottom: 0;
	max-width: 72ch;
}

.eudb-consent__detail {
	margin-top: var(--space-3);
}

.eudb-consent__detail[hidden] {
	display: none;
}

.eudb-consent__fieldset {
	border: 0;
	border-top: var(--rule);
	margin: 0;
	padding: var(--space-2) 0 0;
}

.eudb-consent__option {
	display: grid;
	grid-template-columns: 1.5rem minmax(0, 1fr);
	gap: var(--space-2);
	align-items: start;
	padding-block: var(--space-2);
	border-bottom: 1px solid rgba(30, 43, 22, 0.1);
}

/* 1.5rem = 24 CSS px, which is WCAG 2.2 SC 2.5.8 (AA) exactly. At 1.35rem the
   box painted 21.6 px. The associated label means a pointer can hit a much
   larger area, and a labelled checkbox is arguably not what 2.5.8 measures —
   but arguing that is more expensive than 2.4 px, so the box is simply the
   size the criterion asks for. */
.eudb-consent__option input {
	width: 1.5rem;
	height: 1.5rem;
	margin-top: 0.1rem;
	accent-color: var(--olive);
}

.eudb-consent__option label {
	font-size: var(--t-sm);
}

.eudb-consent__option-name {
	display: block;
	font-weight: 700;
}

.eudb-consent__option-desc {
	display: block;
	color: var(--ink-soft);
	font-size: var(--t-xs);
	line-height: 1.5;
}

.eudb-consent__actions {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	align-items: stretch;
}

/* EQUAL WEIGHT FOR REJECT AND ACCEPT, AND THE FIRST ATTEMPT WAS NOT EQUAL.
   Reject was given the outline treatment and Accept the filled one. They were
   the same size and in the same column, which was the intention — but a filled
   green button next to an outlined one reads as "this is the one you want",
   and a consent choice must not nudge. Verified in a screenshot at 1280px,
   where the difference was obvious.
   Both are now `eudb-btn--solid` and therefore pixel-identical apart from the
   word on them. "Manage preferences" stays quieter because it opens a panel
   rather than answering the question. */

.eudb-consent__actions .eudb-btn--ghost {
	order: 3;
	border-color: transparent;
	text-decoration: underline;
	text-underline-offset: 0.2em;
	min-height: 44px;
}

.eudb-consent-status {
	position: fixed;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

@media (max-width: 53rem) {
	.eudb-consent__inner {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* --------------------------------------------------------------------------
   20. Motion
   One effect, on section entry, 260ms, and nothing at all for a visitor who
   has asked for less. The hero never animates: it is the LCP element.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
	.eudb-reveal {
		opacity: 0;
		transform: translateY(10px);
		transition: opacity 0.45s ease, transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1);
	}

	.eudb-reveal.is-in {
		opacity: 1;
		transform: none;
	}
}

/* --------------------------------------------------------------------------
   21. Print
   -------------------------------------------------------------------------- */

@media print {
	.eudb-masthead,
	.eudb-consent,
	.eudb-filters,
	.eudb-pagination,
	.eudb-lang,
	.eudb-consent-reopen,
	.eudb-section--tint {
		display: none !important;
	}

	body.eudb {
		background: #fff;
		font-size: 11pt;
	}

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

	.eudb-compliance {
		border-top: 2px solid #000;
	}

	a[href^='http']::after {
		content: ' (' attr(href) ')';
		font-size: 9pt;
		word-break: break-all;
	}
}

/* --------------------------------------------------------------------------
   21. Leaflet preview
   A document thumbnail that shows the document. The leaflet is a text PDF and
   its first page looks like a text PDF; a prettier stand-in would be a picture
   of something the reader is not about to download.
   -------------------------------------------------------------------------- */

.eudb-leaflet {
	margin: var(--space-4) 0 0;
	max-width: 232px;
}

.eudb-leaflet__link {
	display: block;
	border: var(--rule);
	background: #fff;
	box-shadow: 0 8px 24px rgba(30, 43, 22, 0.1);
}

.eudb-leaflet__link:hover,
.eudb-leaflet__link:focus-visible {
	border-color: var(--olive);
}

.eudb-leaflet__img {
	display: block;
	width: 100%;
	height: auto;
}

.eudb-leaflet__caption {
	font-size: var(--t-xs);
	color: var(--ink-soft);
	margin-top: var(--space-2);
	line-height: 1.4;
}

/* The contact page's two mailbox links painted 23.0 px tall — one pixel under
   SC 2.5.8's 24. They are inline links inside a paragraph and very likely
   exempt; they are also one pixel from not needing the exemption. */
.eudb-contact-details a[href^='mailto:'],
.eudb-footer__list a[href^='mailto:'] {
	display: inline-flex;
	align-items: center;
	min-height: 24px;
}

/* The questionnaire's Next / Submit / Back keep an 11rem minimum width
   (mu-plugins/eu1144-dropsandbites-questionnaire, questionnaire.css) so they
   do not change size between steps. At a 200 % default font that is 352 px,
   wider than the column the floating stamp's lane leaves on a phone, and the
   buttons ran into the lane at 374–420 px (measured 2026-10-12). Never wider
   than their column. */
.eudb-main .eudb-q__nav .eudb-btn {
	min-width: min(11rem, 100%);
}

/* Two more things the 200 % default-font sweep found in the questionnaire,
   both older than the lane but made visible by it: a <fieldset> takes
   `min-width: min-content` from the UA stylesheet, so one long Finnish
   compound in an option label pushed the whole step 59 px past a 320 px
   screen; and the preview-only test-submission box is an `auto 1fr` grid whose
   text column could not shrink below its longest word. Both now give way. */
.eudb-main .eudb-q__step {
	min-width: 0;
}

.eudb-main .eudb-q__option label,
.eudb-main .eudb-q__q-label,
.eudb-main .eudb-q__test label,
.eudb-main .eudb-q__test-hint {
	overflow-wrap: anywhere;
}

.eudb-main .eudb-q__test {
	grid-template-columns: auto minmax(0, 1fr);
}

/* At 320 px the floating stamp's lane (section 7) leaves the contact column
   248 px, and "marketing@eudropsandbites.eu" is 253 px of one unbreakable
   word: it ran 5 px into the lane (measured 2026-10-12). A mailbox address
   may break anywhere rather than run under the stamp. */
.eudb-contact-details a[href^='mailto:'] {
	max-width: 100%;
	overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------------------
   Narrow-width reflow. A flex or grid child takes min-content as its automatic
   minimum, so a single long word — a headline, a mailto address — can make the
   track, the row and finally the page wider than the viewport. Measured at
   320 CSS px with 200 % text, that is what the hero copy, the masthead row and
   the two footer mail addresses did. Giving those children an explicit zero
   minimum lets them wrap instead of pushing.
   --------------------------------------------------------------------------- */
.eudb-hero__inner > *,
.eudb-masthead__inner > *,
.eudb-hero__copy,
.eudb-crumbs,
.eudb-recipe__intro {
	min-width: 0;
}

.eudb-footer__list a,
.eudb-footer__note,
.eudb-compliance__owner {
	overflow-wrap: anywhere;
}

/* The skip link is absolutely positioned off the top of the page, but an
   absolutely positioned box still counts towards the document's scrollable
   width. With 200 % text the Swedish and Finnish labels ran 71 px past a
   320 px viewport and produced a horizontal scrollbar on every route. */
.eudb-skip {
	max-width: calc(100% - (var(--space-3) * 2));
}

/* Buttons and headlines are the last things in the hero that can set a
   min-content width larger than the column they sit in. */
.eudb-actions {
	flex-wrap: wrap;
}

.eudb-btn,
.eudb-hero__title,
.eudb-hero__lead {
	overflow-wrap: anywhere;
	max-width: 100%;
}

/* `overflow-wrap: anywhere` — unlike `break-word` — also lowers the element's
   min-content width, which is the number a flex or grid parent uses when it
   decides how wide the row has to be. These are the elements whose single
   longest word is longer than a 320 px column once text is doubled:
   Greek and Finnish compounds in the hero eyebrow, the headline, the two hero
   buttons, the diptych call to action and the consent re-open control. */
.eudb-hero__copy,
.eudb-eyebrow,
.eudb-diptych__more,
.eudb-consent-reopen {
	overflow-wrap: anywhere;
	max-width: 100%;
}

/* Recipe filter chips carry Greek course and product names that are longer
   than a doubled-text 320 px row; the set already wraps between chips, the
   chips now wrap inside themselves too. */
.eudb-chip,
.eudb-filters__label,
.eudb-filters__clear {
	max-width: 100%;
	overflow-wrap: anywhere;
}
