/**
 * Edible layouts — the homepage, and every interior page on an Edible template.
 *
 * Depends on tokens.css (scale) and colors.css (schemes). Everything is scoped to
 * .edible-theme, the class the Edible templates add to <body>. That scoping is a leftover
 * from when this was an Avada child theme and had to keep out of the parent's way; it is
 * kept because it still marks exactly which pages get the section layout system.
 *
 * Mobile-first: the base rules describe the phone layout, and min-width queries at the
 * end of each section step up to tablet and desktop. Breakpoints are in em so they
 * respect the reader's text size:
 *
 *     48em = 768px   tablet — two-column grids
 *     64em = 1024px  desktop — sticky hero, absolutely placed hero meta
 *     90em = 1440px  wide — larger type, set in tokens.css
 *
 * Contents
 *     1  Base and utilities
 *     2  Layout primitives
 *     3  Header and fullscreen menu
 *     4  Hero
 *     5  Media
 *     6  Spotlight slider
 *     7  News
 *     8  Programme strands
 *     9  Newsletter
 *    10  About
 *   10b  Interior pages — Discover and Contact
 *   10c  Programme
 *    11  Footer
 *    12  Block editor content
 *    13  Motion preferences
 *
 * @package Edible
 */

/* -----------------------------------------------------------------------------
   1  Base and utilities
   -------------------------------------------------------------------------- */

/* .screen-reader-text is the name core uses in the search form, comment form and
   pagination; .visually-hidden is ours. Same treatment. */
.edible-theme .visually-hidden,
.edible-theme .screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.edible-theme .skip-link {
	position: absolute;
	top: -100%;
	left: var(--space-md);
	z-index: 1001;
	padding: var(--space-sm) var(--space-md);
	background: var(--color-black);
	color: var(--color-white);
	font-size: var(--text-sm);
	text-transform: uppercase;
}

.edible-theme .skip-link:focus {
	top: calc(var(--admin-bar-height) + var(--space-sm));
}

.edible-theme .spacer {
	height: var(--space-4xl);
}

/* Pointer devices only — a tap on a phone shouldn't leave the link faded. */
@media (hover: hover) {

	.edible-theme a:hover {
		opacity: var(--text-opacity-highlight);
	}
}

@media (min-width: 64em) {

	.edible-theme .spacer {
		height: 200px;
	}
}

/* -----------------------------------------------------------------------------
   2  Layout primitives
   -------------------------------------------------------------------------- */

.edible-theme .site-main {
	position: relative;
	z-index: 1;
}

.edible-theme .section {
	position: relative;
}

.edible-theme .section-wrapper {
	width: 100%;
	padding-inline: var(--gutter);
}

.edible-theme .section-container {
	width: 100%;
	padding-top: var(--space-sm);
	padding-bottom: var(--space-xl);
	border-bottom: 1px solid var(--scheme-text);

	/* Revealed by the IntersectionObserver in home.js. The .is-revealed class is
	   added immediately when the observer is unavailable, so this never traps
	   content behind a script that failed to load. */
	opacity: 0;
	transition: opacity 1000ms ease;
}

.edible-theme .section-container.is-revealed {
	opacity: 1;
}

/* Sections that own their background edge-to-edge shouldn't draw a rule as well. */
.edible-theme .section--bleed .section-container,
.edible-theme .section--image .section-container,
.edible-theme .section--spotlight .section-container,
.edible-theme .section--space .section-container,
.edible-theme .section--hero .section-container,
.edible-theme .section--footer-partners .section-container {
	border-bottom: 0;
}

.edible-theme .section--news,
.edible-theme .section--newsletter,
.edible-theme .section--history,
.edible-theme .section--partners,
.edible-theme .section--footer-partners .section-wrapper {
	padding-block: var(--space-xl);
}

.edible-theme .grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-lg);
}

@media (min-width: 48em) {

	.edible-theme .grid--2,
	.edible-theme .grid--3,
	.edible-theme .grid--4 {
		grid-template-columns: repeat(2, 1fr);
	}

	.edible-theme .section--news,
	.edible-theme .section--newsletter,
	.edible-theme .section--history,
	.edible-theme .section--partners,
	.edible-theme .section--footer-partners .section-wrapper {
		padding-block: var(--space-2xl);
	}
}

@media (min-width: 64em) {

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

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

	.edible-theme .grid--9 {
		grid-template-columns: repeat(9, 1fr);
	}
}

/* -----------------------------------------------------------------------------
   3  Header and fullscreen menu
   -------------------------------------------------------------------------- */

.edible-theme .header {
	position: fixed;
	inset: var(--admin-bar-height) 0 auto;
	z-index: 999;
	font-size: var(--text-xs);
	text-transform: uppercase;
	transition: background-color 0.3s ease, color 0.3s ease;
}

/*
 * No z-index here, and that is load-bearing.
 *
 * The fullscreen panel is core Navigation's overlay, which means it is a descendant of this
 * bar rather than a sibling of it — the trigger and the panel are one block, and the trigger
 * belongs in the bar. .header's own z-index makes it a stacking context, and inside that
 * context the panel (z-index 998) has to paint *under* the bar's own contents so the title
 * stays visible and clickable while the menu is down.
 *
 * Giving this element a z-index would make it a stacking context too, and the panel would
 * then paint above the title inside it — the title vanishing instead of inverting, which is
 * the exact bug the old sibling markup had to be arranged around. So the bar's items are
 * lifted individually below, and this stays a plain flex row.
 */
.edible-theme .header-container {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-sm);
	min-height: var(--header-height);
	padding-inline: var(--gutter);
}

/* Core's Group blocks bring flow spacing with them; the chrome does its own spacing. */
.edible-theme .header-wrapper > *,
.edible-theme .header-container > *,
.edible-theme .nav--primary > *,
.edible-theme .nav__languages > * {
	margin-block: 0;
}

/*
 * The bar's text is uppercase, and its contents are Paragraph blocks now — which base.css
 * resets text-transform on, so that a tag never decides case. Uppercase has to be asked for
 * again here, on the children rather than the bar. Asked for at the reset instead it would
 * change every component that sets uppercase on a container, which is not this change.
 */
.edible-theme .header p {
	text-transform: uppercase;
}

/*
 * Fixed to the foot of the window, inverted against whatever is behind it. Kept above
 * the panel for the same reason as the bar above, so the dates stay legible with the
 * menu open — difference blending turns them white against the black panel.
 *
 * It belongs to the menu, not to the page: hidden until the panel is down. Fixed and
 * blended, it would otherwise sit across the foot of every page and invert whatever
 * scrolled under it — which is what it did.
 *
 * .has-menu-open is set on the bar by home.js § 3, on the same timing as the scheme
 * swap: immediately on open, held back until the panel has finished sliding up on close.
 * Gating on core's own state class instead — which goes the moment the close starts —
 * would take the dates away while the black panel is still covering the screen.
 */
.edible-theme .header-container--bottom {
	position: fixed;
	inset: auto 0 0;
	z-index: 999;
	gap: var(--space-md);
	padding-block: var(--space-sm);
	color: var(--color-white);
	mix-blend-mode: difference;
	pointer-events: none;
	visibility: hidden;
	opacity: 0;
}

/* The transition is declared here rather than above on purpose: it fades in with the panel
   and is gone the instant the class is, so nothing lingers over the page underneath. */
.edible-theme .header.has-menu-open .header-container--bottom {
	visibility: visible;
	opacity: 1;
	transition: opacity 0.3s ease;
}

/* Site Title renders a <p>, so the ellipsis and the weight go on the block, not a link. */
.edible-theme .header-logo {
	position: relative;
	z-index: 1000;
	font-weight: 600;
	letter-spacing: var(--tracking-tight);

	/* On a narrow phone the full lockup name would wrap the bar onto two lines. */
	max-width: 55vw;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

/*
 * No z-index, for the reason given on .header-container: the panel lives inside this group,
 * and a stacking context here would trap it above the bar's own text.
 */
.edible-theme .nav--primary {
	display: flex;
	align-items: center;
	gap: var(--space-md);
}

.edible-theme .nav__languages {
	position: relative;
	z-index: 1000;
	display: flex;
	gap: var(--space-xs);
}

/* Two Paragraph blocks, so the separator between them is drawn rather than typed —
   otherwise it is a third block an editor has to know not to delete. */
.edible-theme .nav__languages > * + *::before {
	content: "/";
	margin-inline-end: var(--space-xs);
}

.edible-theme .nav__languages .is-active {
	font-weight: 700;
}

/* -----------------------------------------------------------------------------
   3b  The fullscreen menu — a core Navigation block with its overlay set to
       "always". WordPress owns the open/close, the focus trap and the scroll
       lock; what follows is the look, the slide-down and the one thing core
       cannot do — see home.js § 3 for the header inversion.
   -------------------------------------------------------------------------- */

/* The trigger, styled as the bar's own text rather than a button. Lifted above the panel
   so it stays the thing you click, exactly as the old .burger-button was. */
.edible-theme .nav--fullscreen .wp-block-navigation__responsive-container-open {
	all: unset;

	/* all:unset resets position to static, where z-index does nothing. */
	position: relative;
	z-index: 1000;
	min-height: 44px;			/* Comfortable tap target. */
	display: inline-flex;
	align-items: center;
	cursor: pointer;
	font-size: inherit;
	text-transform: uppercase;
}

/*
 * Core ships two buttons — open in the bar, close in the panel — where the design has one
 * control that changes its label. So each is shown only in the state it belongs to and the
 * close button is put where the trigger was, which reads as the label swapping.
 *
 * .is-open is mirrored onto the <nav> by home.js. Core's own state class sits on the panel,
 * and no sibling selector reaches backwards from there to the trigger.
 */
.edible-theme .nav--fullscreen.is-open .wp-block-navigation__responsive-container-open {
	visibility: hidden;
}

/* Fixed to the same band as the bar and centred in it, rather than offset by a guess, so it
   lands on the title's own line whatever --header-height is set to. */
.edible-theme .nav--fullscreen .wp-block-navigation__responsive-container-close {
	all: unset;
	position: fixed;
	top: var(--admin-bar-height);
	right: var(--gutter);
	z-index: 1000;
	display: inline-flex;
	align-items: center;
	height: var(--header-height);
	cursor: pointer;
	font-size: var(--text-xs);
	text-transform: uppercase;
}

.edible-theme .nav--fullscreen .wp-block-navigation__responsive-container-open:focus-visible,
.edible-theme .nav--fullscreen .wp-block-navigation__responsive-container-close:focus-visible {
	outline: 2px solid currentcolor;
	outline-offset: 3px;
}

/*
 * The panel. Slides down from above; items shear in on a stagger.
 *
 * Core hides it with `display: none` on .hidden-by-default, which no transform can animate
 * out of — so it is laid out at all times and moved out of the viewport instead. visibility
 * is what keeps it off the tab order while it is up there, which display:none was doing.
 *
 * Why !important, which the rest of this file manages without:
 *
 * This is not the theme's element. Core styles the open overlay as a full-screen modal —
 * white, top-aligned, z-index 100000 — and it is entitled to: that is a sensible modal, just
 * not this design. Ordinary specificity lost to it on a real install even at (0,3,0), which
 * means core wins from somewhere this file cannot outrank by counting classes: an inline
 * style, a stronger selector, or the next release. The symptoms were exact — a white panel,
 * the items in the top-left, and the header title buried under a z-index of 100000.
 *
 * So the handful of properties the design cannot negotiate are marked, and only those. The
 * panel's colours are not among them: they are handed to core as the block's own
 * customOverlay* attributes, so the inline style core writes is already black on white.
 * preview/core-navigation.css reproduces core at its most stubborn, so this stays testable.
 */
.edible-theme .nav--fullscreen .wp-block-navigation__responsive-container {
	position: fixed;
	inset: var(--admin-bar-height) 0 0 !important;

	/* Under the bar, so the title stays readable and clickable over the panel. Core's
	   100000 is what buries it. */
	z-index: 998 !important;

	/* A column, centred on both axes: one <ul> in the middle of the viewport. Core stacks
	   it against the top-left corner instead. */
	display: flex !important;
	flex-direction: column !important;
	align-items: center !important;
	justify-content: center !important;
	width: auto;
	padding: var(--gutter) !important;
	overflow-y: auto;
	visibility: hidden;
	transform: translateY(-100%);
	transition: transform 1s cubic-bezier(0.76, 0, 0.24, 1), visibility 1s;
}

.edible-theme .nav--fullscreen .wp-block-navigation__responsive-container.is-menu-open {
	visibility: visible;
	transform: translateY(0);
}

/*
 * Core's own dialog scaffolding inside the panel: three nested divs between it and the list,
 * each a full-width flex column. They are structure, not layout, so they get out of the way —
 * otherwise the centring above has three boxes to fight through before it reaches the list,
 * and the list ends up in the top-left corner of the first one.
 *
 * `.header` is in the chain for the third, and only the third, because core styles that one
 * from a selector of exactly this file's weight *and* marks it. Equal specificity and both
 * marked means load order decides, and core's block styles are printed after the theme's — so
 * matching core's weight is a coin toss that this file loses. One step up settles it.
 */
.edible-theme .nav--fullscreen .wp-block-navigation__responsive-close,
.edible-theme .nav--fullscreen .wp-block-navigation__responsive-dialog,
.edible-theme .header .nav--fullscreen .wp-block-navigation__responsive-container-content {
	display: contents !important;
}

/*
 * Zero, so the generic menu-link hover further down adds nothing here. The fullscreen
 * items carry their own lean on the <li> and reverse it on hover — see below — and a
 * second shear on the <a> inside would compose with it and land at some third angle.
 */
.edible-theme .header .nav--fullscreen .wp-block-navigation__container {
	--menu-hover-skew: 0deg;

	display: flex;
	flex-direction: column;
	gap: var(--space-md);

	/* stretch, so each item fills the list and text-align can centre the label inside it.
	   Core ranges the items against the left edge, which leaves every line starting at a
	   different x — and with type this size, the first one hanging off the viewport. */
	align-items: stretch !important;
	font-family: var(--font-display);
	font-size: clamp(2.25rem, 13vw, 8rem);
	font-style: italic;
	line-height: var(--leading-tighter);
	text-align: center;
}

/*
 * The lean is the resting state, not just the way the items arrive: every item is
 * sheared, and the direction alternates down the list.
 *
 * --lean carries the sign so one expression covers all four states — entry, resting and
 * hover, in both directions. The alternation is :nth-child(even) now that the items are
 * core's: the old --reverse class came from menu_order in edible_nav_menu_css_class(),
 * which was only ever emulating this.
 */
.edible-theme .nav--fullscreen .wp-block-navigation-item {
	--lean: 1;

	opacity: 0;
	transform: translateY(-20svh) skewX(calc(var(--menu-skew) * var(--lean)));
	transition: transform 1s cubic-bezier(0.76, 0, 0.24, 1), opacity 0.35s ease;
}

.edible-theme .nav--fullscreen .wp-block-navigation-item:nth-child(even) {
	--lean: -1;
}

/* Open: they drop into place, keeping the lean they arrived with. */
.edible-theme .nav--fullscreen .is-menu-open .wp-block-navigation-item {
	opacity: 1;
	transform: translateY(0) skewX(calc(var(--menu-skew) * var(--lean)));
}

/*
 * Hover reverses that one item, so it breaks out of the zig-zag rather than joining it.
 * Same expression, sign flipped — which is the whole reason the direction lives in a
 * custom property instead of being written out four times.
 */
@media (hover: hover) {

	.edible-theme .nav--fullscreen .is-menu-open .wp-block-navigation-item:hover {
		transform: translateY(0) skewX(calc(var(--menu-skew) * var(--lean) * -1));
	}
}

/* :focus-within, not :focus — the focusable element is the <a> inside the item. */
.edible-theme .nav--fullscreen .is-menu-open .wp-block-navigation-item:focus-within {
	transform: translateY(0) skewX(calc(var(--menu-skew) * var(--lean) * -1));
}

/* Stagger, so the items arrive as a cascade rather than a block. */
.edible-theme .nav--fullscreen .is-menu-open .wp-block-navigation-item:nth-child(1) {
	transition-delay: 0.1s;
}

.edible-theme .nav--fullscreen .is-menu-open .wp-block-navigation-item:nth-child(2) {
	transition-delay: 0.16s;
}

.edible-theme .nav--fullscreen .is-menu-open .wp-block-navigation-item:nth-child(3) {
	transition-delay: 0.22s;
}

.edible-theme .nav--fullscreen .is-menu-open .wp-block-navigation-item:nth-child(4) {
	transition-delay: 0.28s;
}

.edible-theme .nav--fullscreen .is-menu-open .wp-block-navigation-item:nth-child(5) {
	transition-delay: 0.34s;
}

/*
 * Menu link hover: the link goes italic and shears to a left lean.
 *
 * The transform is on the <a>, not the <li>. The fullscreen items animate in on the
 * <li>'s own transform, and a hover rule there would fight the open/close transition.
 *
 * inline-block because a transform does nothing to an inline box.
 */
.edible-theme .menu a {
	--menu-hover-dir: 1;

	display: inline-block;
	transition: transform 0.35s cubic-bezier(0.76, 0, 0.24, 1);
}

/*
 * Alternate the lean down the list, so hovering your way down a menu rocks left, right,
 * left. Keyed off the item's position, the same way the fullscreen menu's own shear is —
 * which keeps the two effects leaning the same way as each other.
 *
 * :where() so the nth-child adds no specificity: this only sets a custom property, and
 * without it the rule would outweigh every plain link rule further down the file.
 */
.edible-theme .menu :where(li:nth-child(even)) a {
	--menu-hover-dir: -1;
}

/* Pointer devices only, so a tap on a phone doesn't leave a link stuck mid-shear. */
@media (hover: hover) {

	.edible-theme .menu a:hover {
		font-style: italic;
		transform: skewX(calc(var(--menu-hover-skew) * var(--menu-hover-dir)));
	}
}

/*
 * Keyboard users get the same signal, on every device.
 *
 * :where() so the pseudo-class contributes nothing to specificity. Without it this rule
 * outweighs every plain link rule further down the file — .newsletter__intro a and the
 * rest — purely by being a focus style, which is the sort of thing that later gets
 * "fixed" with !important somewhere unrelated.
 */
.edible-theme .menu a:where(:focus-visible) {
	font-style: italic;
	transform: skewX(calc(var(--menu-hover-skew) * var(--menu-hover-dir)));
}

@media (min-width: 48em) {

	.edible-theme .header {
		font-size: var(--text-sm);
	}

	.edible-theme .header-logo {
		max-width: none;
	}

	.edible-theme .nav--primary {
		gap: var(--space-lg);
	}

	.edible-theme .nav--fullscreen .wp-block-navigation__responsive-container-close {
		font-size: var(--text-sm);
	}

	.edible-theme .nav--fullscreen .wp-block-navigation__container {
		gap: calc(var(--space-lg) + var(--space-xs));
	}
}

/* -----------------------------------------------------------------------------
   4  Hero
   -------------------------------------------------------------------------- */

/* Phone: an ordinary block. Sticky positioning with a negative z-index is
   unreliable in mobile Safari, and on a small screen there isn't the height for the
   effect to read anyway. */
.edible-theme .section--hero {
	display: flex;
	align-items: center;
	padding-block: calc(var(--header-height) + var(--space-xl)) var(--space-xl);
}

.edible-theme .section--hero .section-wrapper {
	width: 100%;
}

.edible-theme .section--hero .section-container {
	padding-bottom: 0;
}

.edible-theme .title {

	/* One step up from the --text-sm the meta used to be set in, and the single place to
	   change it: both meta blocks and both breakpoints read this. */
	--hero-meta-size: var(--text-base);

	position: relative;
	display: flex;
	flex-direction: column;
	margin: 0;
}

.edible-theme .wordmark {
	width: 100%;
	height: auto;
	fill: currentcolor;
}

.edible-theme .wordmark path,
.edible-theme .wordmark polygon {
	fill: currentcolor;
}

/* Each line lands on its own beat. */
.edible-theme .section--hero .wordmark > g {
	opacity: 0;
	animation: edible-fade-in 0.6s ease-out forwards;
}

.edible-theme .section--hero .wordmark > g:nth-child(1) {
	animation-delay: 0.2s;
}

.edible-theme .section--hero .wordmark > g:nth-child(2) {
	animation-delay: 0.4s;
}

@keyframes edible-fade-in {

	to {
		opacity: 1;
	}
}

.edible-theme .hero-spacer {
	display: none;
}

/* Phone: the meta reads as a normal stacked block under the mark. */
.edible-theme .title__meta {
	display: none;
}

.edible-theme .title__meta--mobile {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-xs);
	margin-top: var(--space-lg);
	font-size: var(--hero-meta-size);
}

.edible-theme .title__meta-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
}

/* Bullet separator between meta items. */
.edible-theme .title__meta-row li + li::before {
	content: "";
	display: inline-block;
	width: var(--space-xs);
	height: var(--space-xs);
	margin-inline: 0.4em;
	transform: translateY(-0.1em);
	border-radius: 999px;
	background: currentcolor;
}

/* The editions read as a small table, not as three sentences: the bullets stand on one
   vertical axis with the cities ranged right against it and the dates ranged left off it,
   so the eye can run down either column. That means the rows share their two columns —
   hence one grid on the wrapper and `subgrid` on each row, which is the only way rows in
   separate lists can measure their columns together.

   Gated on @supports because the fallback for an unsupported `subgrid` is not the flex row
   it replaces — it is a one-column grid with the city and the date stacked. Where subgrid
   is missing the rows simply stay as they were, aligned left. */
@supports (grid-template-columns: subgrid) {

	.edible-theme .title__editions {
		display: grid;
		grid-template-columns: auto auto;
	}

	.edible-theme .title__meta-row--date {
		display: grid;
		grid-column: 1 / -1;
		grid-template-columns: subgrid;
	}

	/* City hard against the axis; the date's leading bullet sits just past it. */
	.edible-theme .title__meta-row--date li + li {
		justify-self: start;
	}

	.edible-theme .title__meta-row--date li:first-child {
		justify-self: end;
	}
}

@media (min-width: 64em) {

	/* Desktop: the page scrolls over the wordmark instead of pushing it up.
	   .hero-spacer supplies the scroll distance that makes that read. */
	.edible-theme .section--hero {
		position: sticky;
		top: var(--admin-bar-height);
		z-index: -1;
		min-height: calc(100svh - var(--admin-bar-height));
		padding-block: calc(var(--header-height) + var(--space-2xl)) var(--space-3xl);
	}

	.edible-theme .wordmark {
		max-height: calc(100svh - var(--admin-bar-height) - var(--header-height) - var(--space-4xl));
	}

	.edible-theme .hero-spacer {
		display: block;
		height: var(--hero-spacer-height);
		pointer-events: none;
	}

	/* The lockup leaves a void at its bottom right — "Edible" stops well short of
	   where the CONFLUENCE line ends. Both meta blocks sit in that void, at
	   coordinates positionHeroMeta() in home.js derives from the measured ink. */
	.edible-theme .title__meta {
		position: absolute;
		z-index: 1;
		display: flex;
		flex-direction: column;
		width: fit-content;
		font-size: var(--hero-meta-size);
		text-transform: none;
	}

	/* Pinned left, so the block grows rightward — and at a larger size it can grow past
	   the lockup. Capping it at the distance to the container's edge makes a long row wrap
	   instead of bleeding out of the section. */
	.edible-theme .title__meta--hero {
		top: var(--hero-meta-y);
		left: var(--hero-meta-x);
		max-width: calc(100% - var(--hero-meta-x));
	}

	.edible-theme .title__meta--date {
		top: var(--date-meta-y);
		right: var(--date-meta-x);
		transform: translateY(-100%);
	}

	.edible-theme .title__meta--mobile {
		display: none;
	}
}

/* -----------------------------------------------------------------------------
   5  Media
   -------------------------------------------------------------------------- */

.edible-theme .section--image .section-wrapper {
	padding-inline: 0;
}

.edible-theme .media img,
.edible-theme .media video {
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
}

@media (min-width: 48em) {

	.edible-theme .media img,
	.edible-theme .media video {
		aspect-ratio: 16 / 9;
	}
}

/* -----------------------------------------------------------------------------
   6  Spotlight slider
   -------------------------------------------------------------------------- */

.edible-theme .spotlight-slider {
	width: 100%;
}

.edible-theme .spotlight {
	position: relative;
	display: flex;
	flex-direction: column;
	aspect-ratio: 4 / 3;
	padding: var(--space-md);
	overflow: hidden;
	background-position: center;
	background-size: cover;
	color: var(--scheme-solid-text);
	text-decoration: none;
}

/* Scrim, so the title holds up over any photograph. */
.edible-theme .spotlight::after {
	content: "";
	position: absolute;
	inset: 0;

	/* Black at 40% / 15% / 50% — darker top and bottom, clear through the middle. */
	background: linear-gradient(180deg, #0006 0%, #00000026 45%, #00000080 100%);
}

.edible-theme .spotlight > * {
	position: relative;
	z-index: 1;
}

.edible-theme .spotlight:hover {
	opacity: 1;
}

.edible-theme .spotlight__top,
.edible-theme .spotlight__bottom {
	display: flex;
	flex-direction: column;
	gap: var(--space-sm);
	font-size: var(--text-xs);
}

.edible-theme .spotlight__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-sm);
}

.edible-theme .spotlight__title {
	margin: auto 0;
	padding-block: var(--space-lg);
	font-family: var(--font-display);
	font-size: clamp(1.75rem, 8vw, 4.5rem);
	font-style: italic;
	line-height: var(--leading-tighter);
	text-align: center;
	text-wrap: balance;
}

.edible-theme .spotlight__cta {
	text-decoration: underline;
	text-underline-offset: 0.25em;
}

.edible-theme .pill {
	display: inline-block;
	padding: var(--space-xs) var(--space-md);
	border: 1px solid;
	border-radius: 999px;
	font-size: var(--text-xs);
	letter-spacing: var(--tracking-tight);
	text-transform: uppercase;
	white-space: nowrap;
}

.edible-theme .pill--category {
	border: none;
	background-color: var(--scheme-bg);
	color: var(--scheme-text);
}

.edible-theme .swiper-button-prev,
.edible-theme .swiper-button-next,
.edible-theme .swiper-pagination-bullet-active {
	--swiper-theme-color: var(--color-white);

	color: var(--color-white);
}

/* Arrows are a poor fit for touch; the slider is swipeable there. */
.edible-theme .swiper-button-prev,
.edible-theme .swiper-button-next {
	display: none;
}

@media (min-width: 48em) {

	.edible-theme .spotlight {
		aspect-ratio: 21 / 9;
		padding: calc(var(--space-lg) + var(--space-xs));
	}

	.edible-theme .spotlight__top,
	.edible-theme .spotlight__bottom {
		flex-direction: row;
		align-items: flex-start;
		justify-content: space-between;
		gap: var(--space-md);
		font-size: var(--text-sm);
	}

	.edible-theme .swiper-button-prev,
	.edible-theme .swiper-button-next {
		display: flex;
	}
}

/* -----------------------------------------------------------------------------
   7  News
   -------------------------------------------------------------------------- */

.edible-theme .news-block {
	display: flex;
	flex-direction: column;
}

.edible-theme .news-block__heading {
	margin-bottom: var(--space-lg);
	font-size: var(--text-lg);
	text-transform: uppercase;
}

.edible-theme .news-card {
	display: flex;
	flex-direction: column;
	gap: calc(var(--space-xs) * 3);
}

.edible-theme .news-card:hover {
	opacity: 1;
}

.edible-theme .news-card__image {
	aspect-ratio: 3 / 2;
	overflow: hidden;
}

.edible-theme .news-card__image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

.edible-theme .news-card__title {
	font-size: var(--text-base);
	line-height: var(--leading-snug);
	text-wrap: balance;
}

.edible-theme .news-card__excerpt-wrap {
	position: relative;
	font-size: var(--text-sm);
	line-height: var(--leading-normal);
	color: var(--scheme-accent);
}

/* Clamped until the + is pressed. */
.edible-theme .news-card__excerpt {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	overflow: hidden;
}

.edible-theme .news-card__excerpt-wrap.is-expanded .news-card__excerpt {
	display: block;
	overflow: visible;
}

.edible-theme .news-card__expand {
	all: unset;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	margin-left: -0.5rem;			/* Optically align the glyph with the text. */
	cursor: pointer;
	color: var(--scheme-text);
	font-size: var(--text-base);
	line-height: 1;
}

.edible-theme .news-card__expand:focus-visible {
	outline: 2px solid currentcolor;
	outline-offset: 3px;
}

.edible-theme .news-block__more {
	all: unset;
	align-self: flex-start;
	min-height: 44px;
	display: inline-flex;
	align-items: center;
	margin-top: var(--space-xl);
	padding: var(--space-sm) var(--space-lg);
	border: 1px solid var(--scheme-text);
	border-radius: 999px;
	cursor: pointer;
	font-size: var(--text-sm);
	text-transform: uppercase;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.edible-theme .news-block__more:hover,
.edible-theme .news-block__more:focus-visible {
	background-color: var(--scheme-solid-bg);
	color: var(--scheme-solid-text);
}

.edible-theme .news-block__more[disabled] {
	opacity: var(--text-opacity-inactive);
	cursor: default;
}

@media (hover: hover) {

	.edible-theme .news-card:hover .news-card__image img {
		transform: scale(1.03);
	}
}

@media (min-width: 64em) {

	.edible-theme .news-block__heading {
		font-size: var(--text-xl);
	}

	.edible-theme .news-card__title {
		font-size: var(--text-lg);
	}
}

/* -----------------------------------------------------------------------------
   8  Programme strands
   -------------------------------------------------------------------------- */

.edible-theme .grid--strands {
	row-gap: var(--space-xl);
}

.edible-theme .strand {
	display: flex;
	flex-direction: column;
	gap: var(--space-sm);
}

.edible-theme .strand__figure img {
	width: 100%;
}

.edible-theme .strand__figure figcaption {
	margin-top: var(--space-xs);
	font-size: var(--text-xs);
}

.edible-theme .strand__title {
	font-family: var(--font-display);
	font-size: var(--text-lg);
	font-style: italic;
	line-height: var(--leading-snug);
}

.edible-theme .strand__body {
	max-width: var(--width-md);
	font-size: var(--text-sm);
	line-height: var(--leading-relaxed);
}

@media (min-width: 64em) {

	.edible-theme .grid--strands {
		row-gap: var(--space-2xl);
	}

	.edible-theme .strand__title {
		font-size: var(--text-xl);
	}
}

/* -----------------------------------------------------------------------------
   9  Newsletter
   -------------------------------------------------------------------------- */

.edible-theme .newsletter {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-xl);
	align-items: start;
}

.edible-theme .newsletter__intro h2 {
	font-family: var(--font-display);
	font-size: var(--text-lg);
	font-style: italic;
	line-height: var(--leading-snug);
	text-wrap: balance;
}

.edible-theme .newsletter__intro a {
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.edible-theme .newsletter__form {
	gap: var(--space-md);
	font-size: var(--text-sm);
}

.edible-theme .field {
	display: flex;
	flex-direction: column;
	gap: var(--space-xs);
}

.edible-theme .field--wide {
	grid-column: 1 / -1;
}

/* Left-aligned rather than stretched across the column. */
.edible-theme .field--actions {
	align-items: flex-start;
}

.edible-theme .field--honeypot {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.edible-theme .newsletter input[type="text"],
.edible-theme .newsletter input[type="email"] {
	min-height: 44px;
	padding: var(--space-sm) 0;
	border: 0;
	border-bottom: 1px solid var(--scheme-text);
	background: transparent;

	/* iOS zooms the viewport when a focused field is under 16px. */
	font-size: max(16px, var(--text-sm));
}

.edible-theme .newsletter input::placeholder {
	color: var(--scheme-opacity);
}

/* The native controls the custom widgets drive. Hidden only once home.js has taken
   over, so the plain form still works with JavaScript off. */
.edible-theme .newsletter__form.js-widgets-ready select,
.edible-theme .newsletter__form.js-widgets-ready .field--consent > input[type="checkbox"],
.edible-theme .newsletter__form.js-widgets-ready .field--consent > label {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
}

.edible-theme .binary-choice,
.edible-theme .custom-checkbox {
	display: none;
}

.edible-theme .newsletter__form.js-widgets-ready .binary-choice,
.edible-theme .newsletter__form.js-widgets-ready .custom-checkbox {
	display: block;
}

.edible-theme .binary-choice__options {
	display: flex;
	gap: var(--space-lg);
}

.edible-theme .binary-choice button,
.edible-theme .custom-checkbox button {
	all: unset;
	display: flex;
	align-items: center;
	gap: var(--space-sm);
	min-height: 44px;
	cursor: pointer;
	text-align: left;
}

.edible-theme .binary-choice button:focus-visible,
.edible-theme .custom-checkbox button:focus-visible {
	outline: 2px solid currentcolor;
	outline-offset: 3px;
}

.edible-theme .binary-choice .box,
.edible-theme .custom-checkbox .box {
	flex: 0 0 auto;
	width: 1em;
	height: 1em;
	border: 1px solid var(--scheme-text);
}

/* Declared before the checked state so the two never race on specificity. */
.edible-theme .field.has-error input,
.edible-theme .field.has-error .box {
	border-color: var(--color-orange);
}

.edible-theme .binary-choice button[aria-pressed="true"] .box,
.edible-theme .custom-checkbox button[aria-pressed="true"] .box {
	background: var(--scheme-text);
}

.edible-theme .newsletter .button {
	all: unset;
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: var(--space-sm) var(--space-xl);
	border: 1px solid var(--scheme-text);
	border-radius: 999px;
	cursor: pointer;
	text-transform: uppercase;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.edible-theme .newsletter .button:hover,
.edible-theme .newsletter .button:focus-visible {
	background-color: var(--scheme-solid-bg);
	color: var(--scheme-solid-text);
}

.edible-theme .form-success {
	grid-column: 1 / -1;
}

@media (min-width: 48em) {

	.edible-theme .newsletter {
		grid-template-columns: 1fr 1fr;
		gap: var(--space-2xl);
	}

	.edible-theme .newsletter__intro h2 {
		font-size: var(--text-xl);
	}
}

/* -----------------------------------------------------------------------------
   10  About
   -------------------------------------------------------------------------- */

.edible-theme .about {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-lg);
}

/* Bleeds past the section padding so the photograph meets the panel edge. */
.edible-theme .about__media {
	margin-inline: calc(var(--gutter) * -1);
	margin-top: calc(var(--space-xl) * -1);
}

.edible-theme .about__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.edible-theme .about__media figcaption {
	margin-top: var(--space-xs);
	padding-inline: var(--gutter);
	font-size: var(--text-xs);
}

.edible-theme .about__body {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-md);
}

.edible-theme .about__heading h2 {
	font-family: var(--font-display);
	font-size: var(--text-xl);
	font-style: italic;
}

.edible-theme .about__text {
	display: flex;
	flex-direction: column;
	gap: var(--space-md);
	font-size: var(--text-sm);
	line-height: var(--leading-relaxed);
}

@media (min-width: 48em) {

	.edible-theme .about {
		grid-template-columns: 1fr 1fr;
		gap: var(--space-xl);
	}

	.edible-theme .about__media {
		margin-inline: calc(var(--gutter) * -1) 0;
		margin-top: calc(var(--space-2xl) * -1);
		margin-bottom: calc(var(--space-2xl) * -1);
	}

	.edible-theme .about__body {
		grid-template-columns: 30% 1fr;
		gap: var(--space-xl);
		padding: var(--space-xl) var(--space-xl) calc(var(--space-2xl) + var(--space-sm));
	}

	.edible-theme .about__heading h2 {
		font-size: var(--text-2xl);
	}
}

/* -----------------------------------------------------------------------------
   10b  Interior pages — Discover and Contact

   Interior pages have no hero, so the first section has to clear the fixed header
   itself.
   -------------------------------------------------------------------------- */

.edible-theme .site-main--page > .section-flow > :first-child,
.edible-theme .site-main--page .section--first {
	padding-top: calc(var(--header-height) + var(--space-2xl));
}

/* The About image bleeds upward past the section padding. In the first section that
   would take it under the fixed header, so hold it at the padding edge instead. */
.edible-theme .site-main--page .section--first .about__media {
	margin-top: 0;
}

/* Discover — a statement and a link, both at heading scale. */
.edible-theme .discover {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-lg);
}

.edible-theme .discover h2 {
	font-family: var(--font-display);
	font-size: var(--text-lg);
	font-style: italic;
	line-height: var(--leading-snug);
	text-wrap: balance;
}

.edible-theme .discover__cta a {
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

/* Contact. */
.edible-theme .contact {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-xl);
}

.edible-theme .contact__details {
	display: flex;
	flex-direction: column;
	gap: var(--space-lg);
}

.edible-theme .wordmark--contact {
	width: 100%;
	max-height: none;
	margin-bottom: var(--space-md);
}

/* Label and value stay side by side at every width — together they read as one line. */
.edible-theme .contact__row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--space-md);
	padding-bottom: var(--space-md);
	border-bottom: 1px solid var(--scheme-opacity);
	font-size: var(--text-sm);
}

.edible-theme .contact__value {
	display: flex;
	flex-direction: column;
}

.edible-theme .contact__value a {
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

/* The image fills its column rather than setting the row's height — otherwise a tall
   map would push past the black panel and leave it floating on the page background.
   The details column is what the section's height follows. */
.edible-theme .contact__media {
	position: relative;
	min-height: 240px;
}

.edible-theme .contact__media figure {
	position: absolute;
	inset: 0;
}

.edible-theme .contact__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

@media (min-width: 48em) {

	.edible-theme .discover,
	.edible-theme .contact {
		grid-template-columns: 1fr 1fr;
	}

	.edible-theme .discover {
		gap: var(--space-2xl);
	}

	.edible-theme .discover h2 {
		font-size: var(--text-xl);
	}

	/* Bleeds to the right edge of the tinted panel, mirroring the About image.
	   Because the figure is absolutely placed, this grows the bleed without
	   growing the section. */
	.edible-theme .contact__media figure {
		right: calc(var(--gutter) * -1);
		top: calc(var(--space-2xl) * -1);
		bottom: calc(var(--space-2xl) * -1);
	}
}

/* -----------------------------------------------------------------------------
   10c  Programme

   The page title, the filter bar, the by-venue list beside the map, and the card grid.

   The filter bar is one row of triggers whose lists open over the page rather than
   pushing it down, with the view switch opposite them and the search underneath. It
   is the same at every width — the row wraps on a phone rather than rearranging —
   because a sticky bar that changes shape as it is used is disorienting.
   -------------------------------------------------------------------------- */

/* The interior-page answer to the hero wordmark: the page's name, same italic, same
   shear. Live text rather than an SVG per page.

   fit-content, because the shear is applied to the box and not to the letters. Left as a
   full-width block, a five-letter title still skews a 1400px box, and the top-right corner
   of that box lands well past the viewport — giving the page a horizontal scrollbar with
   nothing visible in it. Hugging the text keeps the overhang proportional to the word. */
.edible-theme .page-title {
	width: fit-content;
	max-width: 100%;
	font-family: var(--font-display);
	font-size: clamp(2.5rem, 14vw, 9rem);
	font-style: italic;
	line-height: var(--leading-tighter);
	transform: skewX(var(--title-skew));
	transform-origin: bottom left;
}

.edible-theme .page-title__lede {
	max-width: 46ch;
	margin-top: var(--space-lg);
	font-size: var(--text-lg);
}

/*
 * The full-bleed variant: the title is the page's opening image, so it runs the whole
 * width whatever it says.
 *
 * The size comes from the character count rather than a type scale, because a scale sizes
 * to the viewport and not to the word — "Programme" and "News" would fill very different
 * fractions of the same line. page-title.php counts the characters into --title-chars and
 * this divides the viewport by them. The + 1 is a budget for the shear, which pushes the
 * top of the line to the right past where the glyphs end.
 *
 * 1.33 was measured rather than derived. It puts the glyphs at 95% of the line and the
 * shear carries the top of the last letter the rest of the way, so the title lands on both
 * edges with nothing clipped. The ratio holds at every width — the size is linear in the
 * viewport — so one number covers the range. The section clips regardless, which is what
 * keeps an unusually wide title from growing the page sideways.
 */
.edible-theme .page-title--bleed {
	font-size: calc(100vw / (var(--title-chars, 9) + 1) * 1.33);
	line-height: 0.82;
	text-transform: uppercase;
	white-space: nowrap;
}

.edible-theme .section--page-title-bleed .section-wrapper {
	padding-inline: 0;
	overflow: hidden;
}

.edible-theme .section--page-title-bleed .section-container {
	padding-bottom: var(--space-lg);
}

.edible-theme .section--page-title-bleed .page-title__lede {
	padding-inline: var(--gutter);
}

/* --- Hero --- */

/*
 * The programme's hero is the homepage spotlight run edge to edge and desaturated, so the
 * only colour on the page is the programme itself.
 *
 * The grey is on the scrim's backdrop-filter rather than on the card, so it reaches the
 * photograph without touching the pills stacked above it — the category colour is a
 * wayfinding cue and greying it out would cost the reader the one thing the hero shares
 * with the cards below.
 */
.edible-theme .programme-hero .section-wrapper {
	padding-inline: 0;
}

.edible-theme .programme-hero .spotlight::after {
	backdrop-filter: grayscale(1);
}

.edible-theme .programme-hero .spotlight__title {
	font-size: clamp(2rem, 10vw, 6rem);
	color: var(--color-off-white);
}

/* Only one of the two views is on screen at a time. */
.edible-theme .programme[data-view="grid"] .section--map,
.edible-theme .programme[data-view="map"] .section--programs {
	display: none;
}


/* Filtered out, in both the grid and the venue list. */
.edible-theme .programme .is-hidden {
	display: none;
}

/* --- Filter bar --- */

.edible-theme .section--filters {
	position: sticky;
	top: calc(var(--admin-bar-height) + var(--header-height));
	z-index: 900;
	background-color: var(--color-white);
	border-bottom: 1px solid var(--color-light-grey);
}

.edible-theme .filters {
	display: flex;
	flex-direction: column;
	gap: var(--space-md);
	padding-block: var(--space-sm);
}

/*
 * The bar: the three groups on one side, the view switch and the whole-bar toggle on the
 * other. On a phone it wraps to two rows rather than shrinking the tap targets.
 */
.edible-theme .filters__bar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-sm) var(--space-lg);
}

/* Three columns, closed or open: closed they hold the three titles, open the titles with
   their lists under them. One grid rather than a wrapping row, so the columns line up with
   each other instead of with however long the last label happened to be. */
.edible-theme .filters__groups {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--space-sm) var(--space-lg);
	align-items: start;
	flex: 1 1 100%;
}

/* Open, the bar can outgrow the window on a phone, and it is sticky — so past a point the
   lists scroll inside it rather than pushing the programme off the bottom of the screen. */
.edible-theme .filters:not(.is-closed) .filters__groups {
	max-height: 60vh;
	overflow-y: auto;
}

.edible-theme .filters__actions {
	display: flex;
	align-items: center;
	gap: var(--space-lg);
	margin-left: auto;
}

.edible-theme .filters__mode {
	display: inline-flex;
	align-items: center;
	gap: var(--space-xs);
	min-height: 44px;
	font-size: var(--text-xs);
	letter-spacing: var(--tracking-tight);
	text-transform: uppercase;
	text-decoration: underline;
	text-underline-offset: 0.25em;
	white-space: nowrap;
}

.edible-theme .filters__mode-icon {
	text-decoration: none;
}

.edible-theme .filters__toggle {
	all: unset;
	display: inline-flex;
	align-items: center;
	gap: var(--space-sm);
	min-height: 44px;
	padding-inline: var(--space-md);
	border: 1px solid currentcolor;
	border-radius: 999px;
	font-size: var(--text-xs);
	letter-spacing: var(--tracking-tight);
	text-transform: uppercase;
	white-space: nowrap;
	cursor: pointer;
}

.edible-theme .filters__toggle:focus-visible,
.edible-theme .filters__mode:focus-visible {
	outline: 2px solid currentcolor;
	outline-offset: 3px;
}

.edible-theme .filters__sign::after {
	content: "+";
}

.edible-theme .filters__toggle[aria-expanded="true"] .filters__sign::after {
	content: "–";
}

/* No map, no switch to offer; and only ever show the way out of the view you
   are not already in. */
.edible-theme .programme[data-has-map="false"] .filters__mode,
.edible-theme .programme[data-view="grid"] .filters__mode--grid,
.edible-theme .programme[data-view="map"] .filters__mode--map {
	display: none;
}

/*
 * A group is its title with its list under it, in flow — three columns of them, which is the
 * whole bar. The lists were absolutely positioned panels, one per group, each with its own
 * trigger; they are neither now. One state opens all three at once, so there is no stack of
 * overlapping layers to keep out of each other's way, and no group that is a different height
 * from its neighbours because of which trigger was last pressed.
 *
 * In flow means the sticky bar grows when it opens. That is the trade: a bar that overlapped
 * the programme hid the thing being filtered behind the filter.
 */
.edible-theme .filter__type {
	margin: 0;
	font-size: var(--text-xs);
	font-weight: 700;
}

.edible-theme .filter__list {
	display: flex;
	flex-direction: column;
	gap: var(--space-xs);
	margin: var(--space-sm) 0 0;
	padding: 0;
	list-style: none;
}

/* Closed is the three titles and nothing else. On .filters, not on each group, because that
   is the one thing this bar will not do any more: open half of itself. */
.edible-theme .filters.is-closed .filter__list {
	display: none;
}

/*
 * A real checkbox, moved out of sight rather than display:none — a hidden input is not
 * focusable, and the whole control is keyboard-operable because the input is still
 * there. .filter-checkbox is the box you actually see.
 */
.edible-theme .filter-option {
	display: flex;
	align-items: center;
	gap: var(--space-sm);
	min-height: 32px;
	cursor: pointer;
}

/* An option reads larger than the title above it, and quieter. The title is a label for the
   column — it is read once — where these are the things being chosen between. */
.edible-theme .filter-label {
	font-size: var(--text-sm);
	color: var(--scheme-accent);
}

.edible-theme .filter-option:hover .filter-label,
.edible-theme .filter-option__input:checked ~ .filter-label {
	color: var(--scheme-text);
}

.edible-theme .filter-option__input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
}

.edible-theme .filter-checkbox {
	flex: 0 0 auto;
	width: 0.9em;
	height: 0.9em;
	border: 1px solid currentcolor;
	border-radius: 50%;
}

.edible-theme .filter-option__input:checked ~ .filter-checkbox {
	background-color: currentcolor;
}

.edible-theme .filter-option__input:focus-visible ~ .filter-checkbox {
	outline: 2px solid currentcolor;
	outline-offset: 2px;
}

.edible-theme .filter-tooltip {
	cursor: help;
}

/* Search runs the full width under the bar — it is the one control that takes an
   answer rather than offering a list, so it gets the line to itself. */
.edible-theme .search__input {
	width: 100%;
	padding: var(--space-sm) 0;
	border: none;
	border-bottom: 1px solid currentcolor;
	background: none;
	color: inherit;

	/* 16px minimum, or iOS zooms the page on focus. */
	font-size: max(1rem, var(--text-base));
}

.edible-theme .filters__status {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-md);
}

.edible-theme .filters__count {
	margin: 0;
	font-size: var(--text-xs);
	text-transform: uppercase;
	opacity: var(--text-opacity-highlight);
}

.edible-theme .filters__reset {
	all: unset;
	min-height: 44px;
	display: inline-flex;
	align-items: center;
	font-size: var(--text-xs);
	text-transform: uppercase;
	text-decoration: underline;
	text-underline-offset: 0.25em;
	cursor: pointer;
}

/* --- By-venue list --- */

.edible-theme .events__heading {
	margin-bottom: var(--space-lg);
	font-size: var(--text-sm);
	letter-spacing: var(--tracking-tight);
	text-transform: uppercase;
}

.edible-theme .events__group {
	padding-block: var(--space-md);
	border-top: 1px solid var(--color-light-grey);
}

.edible-theme .events__group-title {
	margin-bottom: var(--space-sm);
	font-size: var(--text-base);
}

.edible-theme .events__group-list {
	display: flex;
	flex-direction: column;
	gap: var(--space-md);
	margin: 0;
	padding: 0;
	list-style: none;
}

.edible-theme .events__item {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--space-sm);
}

.edible-theme .events__item-title {
	font-family: var(--font-display);
	font-size: var(--text-lg);
	font-style: italic;
}

.edible-theme .events__item-date,
.edible-theme .events__item-cta {
	font-size: var(--text-xs);
	text-transform: uppercase;
}

.edible-theme .events__item-cta {
	opacity: var(--text-opacity-highlight);
}

.edible-theme .events__empty {
	padding-block: var(--space-xl);
	font-size: var(--text-lg);
	font-style: italic;
}

/* --- Map panel --- */

.edible-theme .map-container__inner {
	position: relative;
	aspect-ratio: 3 / 4;
	overflow: hidden;
	background-color: var(--color-off-white);
}

.edible-theme .map-container__placeholder {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.edible-theme .map-container__note {
	position: absolute;
	inset: auto var(--space-md) var(--space-md);
	margin: 0;
	padding: var(--space-sm) var(--space-md);
	background-color: var(--color-white);
	font-size: var(--text-xs);
}

/* --- Card grid --- */

.edible-theme .program {
	display: flex;
	flex-direction: column;
	gap: var(--space-sm);
}

.edible-theme .program__image {
	position: relative;
	margin: 0;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background-color: var(--color-off-white);
}

.edible-theme .program__image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.edible-theme .program__pills {
	position: absolute;
	inset: var(--space-sm) var(--space-sm) auto;
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-xs);
}

.edible-theme .pill--entrance {
	background-color: var(--color-white);
	color: var(--color-black);
}

/*
 * The whole card is one link, so anything that underlines links draws a rule under the title
 * and under both meta lines — three of them per card, twelve in a row of four.
 *
 * Stated here rather than left to the single `a` rule in base.css: WordPress generates link
 * element styles of its own from core's theme.json, and a card is the one place where losing
 * that argument is visible on every line of text in the tile rather than on one word in a
 * sentence. Cheaper to say it where it matters than to work out who won.
 */
.edible-theme .program,
.edible-theme .program:hover,
.edible-theme .program:focus-visible,
.edible-theme .program__title,
.edible-theme .program__meta,
.edible-theme .program__meta span {
	text-decoration: none;
}

.edible-theme .program__title {
	font-size: var(--text-base);
	font-weight: 700;
}

/* Sentence case, not caps: these are a date and an address, and the card already has two
   pills shouting at the top of it. */
.edible-theme .program__meta {
	display: flex;
	flex-direction: column;
	font-size: var(--text-xs);
	opacity: var(--text-opacity-highlight);
}

/* A centred text link rather than a button: it continues the list it sits under
   instead of competing with the cards for weight. */
.edible-theme .load-more--events {
	all: unset;
	display: flex;
	align-items: center;
	justify-content: center;
	width: fit-content;
	min-height: 44px;
	margin: var(--space-xl) auto 0;
	font-size: var(--text-xs);
	letter-spacing: var(--tracking-tight);
	text-transform: uppercase;
	text-decoration: underline;
	text-underline-offset: 0.35em;
	cursor: pointer;
}

.edible-theme .load-more--events:focus-visible {
	outline: 2px solid currentcolor;
	outline-offset: 3px;
}

@media (min-width: 48em) {

	.edible-theme .events__item {
		flex-wrap: nowrap;
		justify-content: space-between;
	}

	.edible-theme .filters__status {
		flex-wrap: nowrap;
	}
}

@media (min-width: 64em) {

	/* The map is worth pinning: the list scrolls past it rather than with it. */
	.edible-theme .map-container {
		position: sticky;
		top: calc(var(--admin-bar-height) + var(--header-height) + var(--space-4xl));
	}

	.edible-theme .map-container__inner {
		aspect-ratio: 4 / 5;
	}
}

/* -----------------------------------------------------------------------------
   11  Footer
   -------------------------------------------------------------------------- */

/* Core's Group and Paragraph blocks bring flow spacing with them; the footer does its own
   spacing, in the grids below. */
.edible-theme .footer > *,
.edible-theme .footer-body > *,
.edible-theme .footer-top > *,
.edible-theme .footer-bottom > *,
.edible-theme .footer-partners-text > *,
.edible-theme .footer-instagram > *,
.edible-theme .footer-legal > *,
.edible-theme .partner-logos > * {
	margin-block: 0;
}

/* The logo box, the gap between logos and whether the artwork is grey are all set on the
   arrangement's root element as custom properties, from the block's own settings — see
   edible_partner_display(). The values below are the defaults repeated as fallbacks, so the
   markup renders correctly even where those properties never arrive. */
.edible-theme .partner-logos {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;

	/* Rows sit closer than columns, at three quarters of the gap that is being set. */
	gap: calc(var(--partner-gap, 32px) * 0.75) var(--partner-gap, 32px);
	padding: 0;
	list-style: none;
}

/* An Image block is a <figure>, which arrives with margins of its own. */
.edible-theme .partner-logo {
	display: flex;
	margin: 0;
}

/* The logo is fitted inside the box rather than sized to it: both are maximums and the image
   keeps its aspect ratio, so a wordmark and a roundel come out on the same optical line. The
   box is smaller on a phone — 70% of the width, 80% of the height — because the strip has a
   screen a fifth as wide to spend. */
.edible-theme .partner-logo img {
	width: auto;
	max-width: calc(var(--partner-logo-w, 256px) * 0.7); /* 160px */
	max-height: calc(var(--partner-logo-h, 96px) * 0.8); /* 56px */
	object-fit: contain;
	filter: grayscale(var(--partner-grayscale, 1));
}

/* The scrolling strip.

   The partner list printed an even number of times in a row, moved left by half the track and
   looped, so the second half is under the window at the moment the first half leaves it and
   the seam never shows. The maths only holds while the gap *between* two sets matches the gap
   *inside* one, which is why the trailing gap is padding on each set rather than a gap on the
   track: a track gap falls outside the 50% and the strip jumps by half of it every lap.

   Nothing here is measured in JavaScript, so the strip runs with scripts off. The duration is
   set per instance from the number of logos — see template-parts/home/partners.php. */
.edible-theme .partner-marquee {
	overflow: hidden;

	/* Fade both ends into the band so logos enter and leave rather than being cut off. */
	mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}

.edible-theme .partner-marquee__track {
	display: flex;
	width: max-content;
	animation: edible-marquee var(--marquee-duration, 40s) linear infinite;
}

/* Half the track is at least a screen wide, whatever it holds.

   This is what stops the strip running out. The animation moves the track by half of itself, so
   that half has to be at least as wide as the window — otherwise the row scrolls off to the left
   and drags bare background behind it, which is what the footer did with nine narrow logos on a
   wide screen. The number of logos cannot answer that question, because a logo is fitted inside
   its box rather than filling it, so a count says nothing about pixels.

   A screen split between however many sets make up that half does answer it, and the split is
   worked out in PHP because CSS cannot count them. It is an over-estimate on purpose: 100vw
   against a strip that sits inside the section's gutters.

   The leftover goes into the logos rather than to the end of the row: each one grows by the same
   amount and centres its image, so a short list comes out evenly spread across the strip with
   every gap — the one at the seam included — still exactly --partner-gap. Distributing it with
   justify-content instead would spread the gaps and leave the seam the odd one out. */
.edible-theme .partner-marquee__set {
	flex-wrap: nowrap;
	min-width: var(--marquee-set-min, 100vw);
	gap: var(--partner-gap, 32px);

	/* The trailing gap is padding on the set rather than a gap on the track: a track gap falls
	   outside the 50% the animation moves by, and the strip would jump by half of it every lap. */
	padding-inline-end: var(--partner-gap, 32px);
}

.edible-theme .partner-marquee__set > .partner-logo {
	flex: 1 0 auto;
	justify-content: center;
}

/* The strip with Scroll continuously switched off: the wall the marquee replaced, centred and
   wrapping. Only one set is printed in that case — the copies exist to hide a seam that is no
   longer moving past — so there is nothing here to hide, only the strip's own machinery to undo.

   prefers-reduced-motion arrives at the same place by a different route, further down: it cannot
   be known on the server, so there the copies are printed and hidden. Keep the two in step.

   Ahead of the pause-on-hover rule below only to keep the stylesheet's specificity ascending;
   nothing here and nothing there sets the same property. */
.edible-theme .partner-marquee--static {
	overflow: visible;
	mask-image: none;
}

/* justify-content, not the set's own: a set standing still shrink-wraps its logos, so what has
   to be centred is the set inside the track. Without this the wall sits against the left edge. */
.edible-theme .partner-marquee--static .partner-marquee__track {
	justify-content: center;
	width: auto;
	animation: none;
	transform: none;
}

.edible-theme .partner-marquee--static .partner-marquee__set {
	flex-wrap: wrap;
	min-width: 0;
	padding-inline-end: 0;
}

/* Standing still, a stretched logo is just a gap in a centred row. */
.edible-theme .partner-marquee--static .partner-marquee__set > .partner-logo {
	flex: 0 0 auto;
}

/* Let someone stop the strip to read a name, or to reach a logo's link. */
.edible-theme .partner-marquee:hover .partner-marquee__track,
.edible-theme .partner-marquee:focus-within .partner-marquee__track {
	animation-play-state: paused;
}

@keyframes edible-marquee {

	to {
		transform: translateX(-50%);
	}
}

/* Colour on hover: one logo at a time comes up in its own colours. Set on the item rather than
   on the image so the whole cell is the target, and paired with :focus-within so it is reachable
   by keyboard on the logos that are links. */
.edible-theme .partners--hover-colour .partner-logo:hover,
.edible-theme .partners--hover-colour .partner-logo:focus-within,
.edible-theme .partners--hover-colour a.partner-grid__card:hover,
.edible-theme .partners--hover-colour a.partner-grid__card:focus-visible {
	--partner-grayscale: 0;
}

/* The Partners page grid — the same partners as the strip, listed rather than glanced at.

   auto-fill with a minimum rather than a column count, so the grid answers the width it is
   given instead of the breakpoint it is at: three across on a phone at the smallest, as many as
   fit on a wide screen, and no media query to keep in step with the rest of the layout.

   The logo box has a fixed height and the name sits under it, which is what keeps a row of
   cards on one baseline whatever shape the artwork is. */
.edible-theme .partner-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));

	/* The gap the block is set to, between the columns; rows get half again, because a card is a
	   logo with a name under it and needs the name kept clear of the row below. */
	gap: var(--partner-gap, 32px) calc(var(--partner-gap, 32px) * 0.75);
	padding: 0;
	list-style: none;
}

.edible-theme .partner-grid__item {
	margin: 0;
}

.edible-theme .partner-grid__card {
	display: flex;
	flex-direction: column;
	gap: var(--space-sm);
	align-items: center;
	height: 100%;
	text-align: center;
	text-decoration: none;
}

/* The box every card reserves for its artwork, so a row of cards keeps its names on one line
   whatever shape the logos are. It follows the logo size the block is set to — a card wants more
   room around the mark than the strip does, so it is the logo height and a bit over half again. */
.edible-theme .partner-grid__logo {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: calc(var(--partner-logo-h, 56px) * 1.28);
}

.edible-theme .partner-grid__logo img {
	width: auto;
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
	filter: grayscale(var(--partner-grayscale, 1));
}

/* The logo is what the eye goes to, so the name is set small and quiet under it — until the
   card is a link and is hovered, where it is the only part that can acknowledge the pointer.

   The width is load-bearing: the card centres its children, which shrink-wraps them, so
   without it a long name sizes to its own text and runs out past the column rather than
   wrapping inside it. */
.edible-theme .partner-grid__name {
	width: 100%;
	font-size: var(--text-xs);
	line-height: 1.3;
	color: var(--scheme-accent);
}

/* A partner with no artwork: the name is the card, so it is set at the size the logo would
   have occupied rather than as a caption under an empty box. */
.edible-theme .partner-grid__card > .partner-grid__name:only-child {
	display: flex;
	align-items: center;
	justify-content: center;
	height: calc(var(--partner-logo-h, 56px) * 1.28);
	font-size: var(--text-sm);
	color: var(--scheme-text);
}

.edible-theme a.partner-grid__card:hover .partner-grid__name,
.edible-theme a.partner-grid__card:focus-visible .partner-grid__name {
	color: var(--scheme-text);
	text-decoration: underline;
}

@media (min-width: 48em) {

	.edible-theme .partner-grid {
		grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
		gap: calc(var(--partner-gap, 32px) * 1.5) var(--partner-gap, 32px);
	}

	.edible-theme .partner-grid__logo,
	.edible-theme .partner-grid__card > .partner-grid__name:only-child {
		height: calc(var(--partner-logo-h, 56px) * 1.6);
	}
}

.edible-theme .footer-body {
	padding: var(--space-2xl) var(--gutter) calc(var(--space-3xl) + var(--space-lg));
}

.edible-theme .footer-top {
	gap: var(--space-xl);
	align-items: start;
	font-size: var(--text-sm);
}

.edible-theme .footer-instagram a {
	display: inline-flex;
	align-items: center;
	gap: var(--space-xs);
	min-height: 44px;
}

.edible-theme .footer-container {
	gap: var(--space-lg);
}

/* Three Navigation blocks, one per column. Core lays its list out as a wrapping row; these
   are columns of links, so the direction is overridden rather than the block restyled. */
.edible-theme .footer-container ul {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-xs);
}

.edible-theme .footer-container .wp-block-navigation {
	align-items: flex-start;
}

.edible-theme .footer-bottom {
	margin-top: var(--space-2xl);
}

.edible-theme .footer-logo {
	grid-column: 1 / -1;
}

.edible-theme .wordmark--footer {
	width: 100%;
	max-height: none;
}

.edible-theme .footer-legal {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-sm) var(--space-md);
	justify-content: space-between;
	margin-top: var(--space-lg);
	font-size: var(--text-xs);
	color: var(--scheme-accent);
}

@media (min-width: 48em) {

	.edible-theme .partner-logo img {
		max-width: var(--partner-logo-w, 256px); /* 160px */
		max-height: var(--partner-logo-h, 96px); /* 56px */
	}
}

@media (min-width: 64em) {

	.edible-theme .footer-partners-text {
		grid-column: span 4;
	}

	.edible-theme .footer-instagram {
		grid-column: span 2;
	}

	.edible-theme .footer-container {
		grid-column: span 3;
		grid-template-columns: repeat(3, 1fr);
	}

	.edible-theme .footer-bottom {
		margin-top: var(--space-3xl);
	}
}

/* -----------------------------------------------------------------------------
   12  Block editor content

   The homepage body is composed in Gutenberg from the patterns in inc/patterns.php.
   Those patterns wear the same classes as the PHP sections — .section, .about,
   .newsletter, .strand — so almost everything above applies unchanged. These rules
   cover the wrappers core adds on top.
   -------------------------------------------------------------------------- */

.edible-theme .section-flow > * {
	margin-block: 0;
}

/* Sections run edge to edge; .section-wrapper supplies the gutter. */
.edible-theme .section-flow .alignfull {
	width: 100%;
	max-width: none;
	margin-inline: 0;
}

/*
 * Core's constrained layout caps and centres a group's children against
 * --wp--style--global--content-size, and its block-gap adds vertical margins between
 * them. Both fight a full-bleed section, so they are neutralised here.
 *
 * Note what this does NOT do: it must not zero padding on the section wrappers. They
 * carry the gutter and the vertical rhythm, set by the .section-* rules further up —
 * and those selectors are less specific than anything targeting .wp-block-group, so a
 * blanket reset here would silently win and flatten the whole page.
 */
.edible-theme .section-flow .wp-block-group.section > *,
.edible-theme .section-flow .wp-block-group.section-wrapper > *,
.edible-theme .section-flow .wp-block-group.section-container > * {
	max-width: none;
	margin-block: 0;
	margin-inline: 0;
}

/* Belt and braces: the gutter, restated at a specificity that beats any core rule
   reaching the same element. */
.edible-theme .section-flow .wp-block-group.section-wrapper {
	padding-inline: var(--gutter);
}

/* Core columns stack below 782px on their own; above that, match the gutter used by
   the rest of the page. */
.edible-theme .section-flow .wp-block-columns {
	gap: var(--space-lg);
	margin-bottom: 0;
}

.edible-theme .section-flow .wp-block-image {
	margin: 0;
}

.edible-theme .section-flow .wp-element-caption {
	margin-top: var(--space-xs);
	font-size: var(--text-xs);
	color: var(--scheme-accent);
}

@media (min-width: 64em) {

	.edible-theme .section-flow .grid--strands {
		gap: var(--space-lg);
		margin-bottom: var(--space-2xl);
	}
}

/* -----------------------------------------------------------------------------
   13  Motion preferences
   -------------------------------------------------------------------------- */

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

	.edible-theme *,
	.edible-theme *::before,
	.edible-theme *::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}

	.edible-theme .section-container,
	.edible-theme .section--hero .wordmark > g {
		opacity: 1;
	}

	/* The partner strip becomes the wall it replaced: centred, wrapping, standing still — the
	   same place Scroll continuously off arrives at, and the rules have to match it. Every repeat
	   after the first exists only to cover the seam of a scroll that is no longer happening, so
	   they all go — otherwise the same logos would be drawn several times over for no reason at
	   all. What is left is one set of partners, once. */
	.edible-theme .partner-marquee {
		overflow: visible;
		mask-image: none;
	}

	.edible-theme .partner-marquee__track {
		justify-content: center;
		width: auto;
		animation: none;
		transform: none;
	}

	/* min-width goes with the scroll: a set stretched to the width of the window would push a
	   wrapping row out past the page rather than filling a strip that is moving through it. */
	.edible-theme .partner-marquee__set {
		flex-wrap: wrap;
		min-width: 0;
		padding-inline-end: 0;
	}

	.edible-theme .partner-marquee__set > .partner-logo {
		flex: 0 0 auto;
	}

	.edible-theme .partner-marquee__set[aria-hidden="true"] {
		display: none;
	}

	/* Drop the travel, keep the lean — the shear is the design, not the motion. */
	.edible-theme .nav--fullscreen .wp-block-navigation-item {
		opacity: 1;
		transform: skewX(calc(var(--menu-skew) * var(--lean)));
	}
}
