/**
 * Supplementary styles for the 3ducation theme.
 *
 * Design system lives in theme.json. This file holds the structural and
 * motion details theme.json can't express: the category bento grid,
 * brand color-coding, the kinetic partner marquee, and hover micro-physics.
 * Design dials: variance 8, motion 6, density 4.
 */

/* ------------------------------------------------------------------ *
 * Buttons: tactile push + outline variant on light backgrounds
 * ------------------------------------------------------------------ */
.wp-block-button__link {
	transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.18s ease;
}
.wp-block-button__link:active {
	transform: translateY(1px);
}
.wp-block-button.is-style-outline .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--ink);
	border: 1.5px solid var(--wp--preset--color--ink);
}
.wp-block-button.is-style-outline .wp-block-button__link:hover {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--surface);
}

/* Focus ring for keyboard users */
.wp-block-button__link:focus-visible,
.wc-block-components-button:focus-visible,
a:focus-visible {
	outline: 2px solid var(--wp--preset--color--magenta);
	outline-offset: 2px;
}

/* ------------------------------------------------------------------ *
 * Homepage hero: a wp:cover block (patterns/hero.php) — full-bleed photo the
 * client can swap in the Site Editor, with a left→right dark gradient overlay
 * as the legibility scrim. This CSS only pins the height and lays out the
 * content band; the photo + scrim live on the Cover block itself.
 * ------------------------------------------------------------------ */
.home-hero {
	/* The wp:cover block now provides the photo (editable in the Site Editor)
	   and the left→right gradient scrim overlay that keeps the light text
	   legible; here we only pin the height and keep content off the edge. */
	min-height: clamp(440px, 60vh, 640px);
	padding-inline: var(--wp--preset--spacing--40);
}
/* .home-hero__content is a 1240 band centred like the rest of the page (both
   groups use plain flow layout, so WP's constrained auto-margins don't fight
   us); its children cap at 640 and sit flush-left, lining up with the pillars. */
.home-hero__content {
	width: 100%;
	max-width: 1240px;
	margin-inline: auto;
}
.home-hero__content > * {
	max-width: 640px;
}
.home-hero__tag {
	position: absolute;
	top: var(--wp--preset--spacing--30);
	right: var(--wp--preset--spacing--30);
	margin: 0;
	z-index: 1;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: var(--wp--preset--color--mist-soft);
}
@media (max-width: 781px) {
	.home-hero { min-height: clamp(380px, 70vh, 520px); }
	/* Vertical scrim on narrow screens where the text spans full width — override
	   the Cover overlay's inline gradient (hence !important). */
	.home-hero .wp-block-cover__background {
		background: linear-gradient(
			180deg,
			rgba(15, 16, 22, 0.55) 0%,
			rgba(15, 16, 22, 0.85) 100%
		) !important;
	}
}

/* ------------------------------------------------------------------ *
 * Category bento: asymmetric, color-coded (no 3-equal-card row)
 * ------------------------------------------------------------------ */
.cat-bento {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--wp--preset--spacing--30);
}
.cat-card {
	position: relative;
	padding: var(--wp--preset--spacing--45);
	border-radius: 18px;
	border: 1px solid var(--wp--preset--color--border);
	background: var(--wp--preset--color--surface);
	overflow: hidden;
	transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s ease;
}
.cat-card::before {
	content: "";
	position: absolute;
	inset: 0 auto 0 0;
	width: 5px;
	background: var(--cat-accent, var(--wp--preset--color--ink));
}
.cat-card:hover {
	transform: translateY(-3px);
	box-shadow: 0 24px 40px -24px rgba(20, 21, 26, 0.22);
}
.cat-card--printers  { grid-column: span 2; --cat-accent: var(--wp--preset--color--amber); }
.cat-card--workshops { grid-row: span 2; background: var(--wp--preset--color--ink); --cat-accent: var(--wp--preset--color--cyan); }
.cat-card--filament  { --cat-accent: var(--wp--preset--color--cyan); }
.cat-card--resin     { --cat-accent: var(--wp--preset--color--magenta); }

/* Workshops card sits on dark: invert text */
.cat-card--workshops .wp-block-heading,
.cat-card--workshops .cat-link a { color: var(--wp--preset--color--surface); }
.cat-card--workshops p { color: var(--wp--preset--color--mist) !important; }
.cat-card--workshops .cat-tag { color: var(--wp--preset--color--cyan); }

.cat-tag {
	text-transform: uppercase;
	letter-spacing: 2px;
	font-weight: 500;
	color: var(--cat-accent);
	margin: 0 0 0.5rem;
}
.cat-link a {
	text-decoration: none;
	font-weight: 500;
	color: var(--wp--preset--color--ink);
}
/* Stretch the link across the whole card so the card is clickable */
.cat-card .stretched::after {
	content: "";
	position: absolute;
	inset: 0;
}

@media (max-width: 781px) {
	.cat-bento { grid-template-columns: 1fr; }
	.cat-card--printers { grid-column: auto; }
	.cat-card--workshops { grid-row: auto; }
}

/* ------------------------------------------------------------------ *
 * Audience split: B2B (scholen) / B2C (thuis) two-up, color-coded.
 * Shares the bento/pillars card language — accent bar + hover-lift.
 * ------------------------------------------------------------------ */
.audience-split {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--wp--preset--spacing--30);
	align-items: stretch;
}
/* Zero WordPress' flow-layout top margin so both cards top-align; the
 * grid `gap` owns the spacing. Same reset as .pillars. */
.audience-split > * { margin-block-start: 0; }
.audience-card {
	position: relative;
	display: flex;
	flex-direction: column;
	padding: var(--wp--preset--spacing--45);
	border-radius: 18px;
	border: 1px solid var(--wp--preset--color--border);
	background: var(--wp--preset--color--surface);
	overflow: hidden;
	transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s ease;
}
.audience-card::before {
	content: "";
	position: absolute;
	inset: 0 0 auto 0;
	height: 5px;
	background: var(--audience-accent, var(--wp--preset--color--ink));
}
.audience-card:hover {
	transform: translateY(-3px);
	box-shadow: 0 24px 40px -24px rgba(20, 21, 26, 0.22);
}
.audience-card--scholen { --audience-accent: var(--wp--preset--color--cyan); }
.audience-card--thuis   { --audience-accent: var(--wp--preset--color--magenta); }
.audience-tag {
	text-transform: uppercase;
	letter-spacing: 2px;
	font-weight: 500;
	color: var(--audience-accent);
	margin: 0.4rem 0 0.5rem;
}
.audience-list {
	margin: 1rem 0 0;
	padding-left: 1.2rem;
	color: var(--wp--preset--color--ink-soft);
}
.audience-list li { margin-block: 0.35rem; }
/* Pin the CTA to the bottom so both cards' buttons bottom-align
 * regardless of copy length. */
.audience-cta { margin-top: auto; padding-top: 1.5rem; }
@media (max-width: 781px) {
	.audience-split { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------------ *
 * Social-proof placeholder (homepage) — reserved slot for real photos
 * of teachers and smiling kids at the workshops. Striped fill + label
 * signal where imagery drops in, matching the About gallery language.
 * ------------------------------------------------------------------ */
.social-proof-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 240px;
	padding: var(--wp--preset--spacing--45);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 18px;
	background-color: var(--wp--preset--color--base);
	background-image: repeating-linear-gradient(
		-45deg,
		var(--wp--preset--color--border) 0,
		var(--wp--preset--color--border) 1px,
		transparent 1px,
		transparent 11px
	);
}
.social-proof-placeholder__label {
	margin: 0;
	text-align: center;
	text-transform: uppercase;
	letter-spacing: 2px;
	color: var(--wp--preset--color--muted);
}

/* ------------------------------------------------------------------ *
 * Kinetic partner marquee
 * ------------------------------------------------------------------ */
.marquee {
	overflow: hidden;
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
	        mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee__track {
	display: inline-flex;
	gap: 3.5rem;
	white-space: nowrap;
	width: max-content;
	animation: marquee 34s linear infinite;
}
.marquee__track span {
	font-family: var(--wp--preset--font-family--display), sans-serif;
	font-weight: 700;
	font-size: 1.35rem;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--muted);
	transition: color 0.2s ease;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__track span:hover { color: var(--wp--preset--color--ink); }
@keyframes marquee {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
	.marquee__track { animation: none; }
}

/* ------------------------------------------------------------------ *
 * Product cards: image ratio + hover lift in shop grids
 * ------------------------------------------------------------------ */
.wp-block-woocommerce-product-template li {
	transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
}
.wp-block-woocommerce-product-template li:hover {
	transform: translateY(-3px);
}
.wc-block-components-product-image img,
.wp-block-woocommerce-product-image img {
	aspect-ratio: 1 / 1;
	object-fit: cover;
	width: 100%;
	background: var(--wp--preset--color--base-soft);
	border-radius: 10px;
}

/* Mini-cart trigger spacing */
.wc-block-mini-cart__button { padding-inline: 0.4rem; }

/* Sale badge ("Aanbieding!"): a square amber box with white Space Grotesk
 * text, replacing WooCommerce's default rounded green pill/circle. Covers the
 * legacy gallery flash and the block-based sale badge (shop grid + product
 * detail page). */
.onsale,
.wc-block-components-sale-badge,
.wc-block-components-product-sale-badge {
	background-color: var(--wp--preset--color--amber) !important;
	color: var(--wp--preset--color--surface) !important;
	border: 0 !important;
	border-radius: 0 !important;
	font-family: var(--wp--preset--font-family--display) !important;
	font-weight: 700 !important;
	letter-spacing: 0.01em;
	padding: 0.4em 0.7em !important;
	min-height: 0 !important;
	min-width: 0 !important;
	line-height: 1.2 !important;
}

/* ------------------------------------------------------------------ *
 * Site notice bar: dismissible announcement at the top of every page
 * ------------------------------------------------------------------ */
.site-notice-bar {
	position: relative;
	display: none;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--surface);
}
/* Revealed by the inline script only when the notice is not yet dismissed,
 * so dismissed visitors never see a flash of the bar. */
.site-notice-bar.is-visible {
	display: block;
	animation: notice-drop 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
}
/* Thin brand accent line along the bottom edge */
.site-notice-bar::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 2px;
	background: var(--wp--preset--gradient--cube, linear-gradient(90deg, #e6186c 0%, #f2562f 26%, #f7941e 50%, #2fb58f 72%, #14b1bb 88%, #0fb1bf 100%));
}
.site-notice-bar__inner {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.5rem 1.4rem;
	max-width: 1240px;
	margin: 0 auto;
	padding: 0.7rem 3rem;
}
.site-notice-bar__text {
	margin: 0;
	font-size: 0.95rem;
	line-height: 1.45;
	text-align: center;
}
.site-notice-bar__cta {
	flex-shrink: 0;
	padding: 0.32em 1em;
	border: 1px solid rgba(255, 255, 255, 0.35);
	border-radius: 999px;
	color: var(--wp--preset--color--surface);
	font-size: 0.9rem;
	font-weight: 500;
	text-decoration: none;
	white-space: nowrap;
	transition: background 0.15s ease, border-color 0.15s ease;
}
.site-notice-bar__cta:hover {
	background: rgba(255, 255, 255, 0.12);
	border-color: var(--wp--preset--color--surface);
}
.site-notice-bar__close {
	position: absolute;
	top: 50%;
	right: 0.6rem;
	transform: translateY(-50%);
	display: grid;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	padding: 0;
	border: 0;
	border-radius: 6px;
	background: transparent;
	color: var(--wp--preset--color--mist);
	cursor: pointer;
	transition: background 0.15s ease, color 0.15s ease;
}
.site-notice-bar__close:hover {
	background: rgba(255, 255, 255, 0.12);
	color: var(--wp--preset--color--surface);
}
@keyframes notice-drop {
	from { opacity: 0; transform: translateY(-100%); }
	to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
	.site-notice-bar { animation: none; }
}

/* ------------------------------------------------------------------ *
 * Site pop-up: centred <dialog> (Instellingen -> Pop-up)
 *
 * Native <dialog> gives us Escape, the focus trap and the backdrop.
 * The card is a white surface with the cube gradient along its top edge
 * (same signature as the notice bar) and the theme's magenta button.
 * ------------------------------------------------------------------ */
.site-popup {
	/* Reset the UA dialog box; the card carries the visuals. */
	width: min(100% - 2rem, 34rem);
	max-height: min(100% - 2rem, 90dvh);
	margin: auto;
	padding: 0;
	border: 0;
	border-radius: 18px;
	background: transparent;
	color: var(--wp--preset--color--ink);
	overflow: visible;
}
.site-popup::backdrop {
	background: rgba(20, 21, 26, 0.6);
	background: color-mix(in srgb, var(--wp--preset--color--ink) 62%, transparent);
	backdrop-filter: blur(3px);
	-webkit-backdrop-filter: blur(3px);
}
.site-popup[open] {
	animation: popup-rise 0.35s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.site-popup[open]::backdrop {
	animation: popup-fade 0.25s ease both;
}
.site-popup__card {
	position: relative;
	max-height: min(100vh - 2rem, 90dvh);
	overflow: auto;
	padding: var(--wp--preset--spacing--45) var(--wp--preset--spacing--45) var(--wp--preset--spacing--40);
	border-radius: 18px;
	/* Cube-gradient edge along the top, layered over the surface. A background
	 * on a scroll container stays put while its content scrolls, so the edge
	 * survives long pop-up text. */
	background:
		var(--wp--preset--gradient--cube, linear-gradient(90deg, #e6186c 0%, #f2562f 26%, #f7941e 50%, #2fb58f 72%, #14b1bb 88%, #0fb1bf 100%)) top / 100% 3px no-repeat,
		var(--wp--preset--color--surface);
	box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.45);
}
.site-popup__title {
	margin: 0 0 var(--wp--preset--spacing--30);
	padding-right: 2.2rem;
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--x-large);
	font-weight: 700;
	line-height: 1.1;
	letter-spacing: -0.01em;
}
.site-popup__body {
	color: var(--wp--preset--color--ink-soft);
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.6;
}
.site-popup__body p {
	margin: 0 0 0.85em;
}
.site-popup__body p:last-child {
	margin-bottom: 0;
}
.site-popup__actions {
	margin-top: var(--wp--preset--spacing--40);
}
/* Matches theme.json's button element (magenta, 8px, display 500) but
 * compacter: two classes so it beats the global-styles padding and the
 * 48px touch-target rule further down; 44px keeps the tap target sane. */
.site-popup__actions .site-popup__cta {
	display: inline-flex;
	align-items: center;
	box-sizing: border-box;
	min-height: 44px;
	padding: 0.55em 1.4em;
	line-height: 1.2;
	border-radius: 8px;
	background: var(--wp--preset--color--magenta);
	color: var(--wp--preset--color--surface);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 500;
	text-decoration: none;
	transition: background 0.15s ease, transform 0.15s ease;
}
.site-popup__cta:hover,
.site-popup__cta:focus-visible {
	background: var(--wp--preset--color--magenta-dark);
	color: var(--wp--preset--color--surface);
	transform: translateY(-1px);
}
.site-popup__close {
	position: absolute;
	top: 0.9rem;
	right: 0.9rem;
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	border: 0;
	border-radius: 8px;
	background: transparent;
	color: var(--wp--preset--color--muted);
	cursor: pointer;
	transition: background 0.15s ease, color 0.15s ease;
}
.site-popup__close:hover,
.site-popup__close:focus-visible {
	background: var(--wp--preset--color--base-soft);
	color: var(--wp--preset--color--ink);
}
@media (max-width: 600px) {
	.site-popup {
		width: min(100% - 1.5rem, 34rem);
	}
	.site-popup__card {
		padding: var(--wp--preset--spacing--40);
	}
	/* Two classes: the touch-target rule further down sets .wp-element-button
	 * to inline-flex and would otherwise win on source order. */
	.site-popup__actions .site-popup__cta {
		display: flex;
	}
}
/* Bottom-left pill: reopens the pop-up after it was closed */
.site-popup-pill {
	position: fixed;
	left: 1rem;
	bottom: 1rem;
	z-index: 90;
	display: inline-flex;
	align-items: center;
	gap: 0.55rem;
	max-width: min(20rem, calc(100vw - 2rem));
	padding: 0.45rem 1rem 0.45rem 0.5rem;
	border: 0;
	border-radius: 999px;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--surface);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1.2;
	text-align: left;
	box-shadow: 0 12px 30px -10px rgba(0, 0, 0, 0.45);
	cursor: pointer;
	animation: pill-rise 0.35s cubic-bezier(0.16, 1, 0.3, 1) both;
	transition: background 0.15s ease, transform 0.15s ease;
}
.site-popup-pill[hidden] {
	display: none;
}
.site-popup-pill:hover,
.site-popup-pill:focus-visible {
	background: var(--wp--preset--color--surface-dark);
	transform: translateY(-1px);
}
.site-popup-pill__icon {
	flex-shrink: 0;
	display: grid;
	place-items: center;
	width: 1.6rem;
	height: 1.6rem;
	border-radius: 50%;
	background: var(--wp--preset--gradient--cube, linear-gradient(120deg, #e6186c 0%, #f2562f 26%, #f7941e 50%, #2fb58f 72%, #14b1bb 88%, #0fb1bf 100%));
	color: var(--wp--preset--color--surface);
}
.site-popup-pill__label {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}
@media (max-width: 600px) {
	.site-popup-pill {
		left: 0.75rem;
		bottom: 0.75rem;
		max-width: calc(100vw - 1.5rem);
	}
}
@keyframes pill-rise {
	from { opacity: 0; transform: translateY(8px); }
	to   { opacity: 1; transform: none; }
}
@keyframes popup-rise {
	from { opacity: 0; transform: translateY(12px) scale(0.97); }
	to   { opacity: 1; transform: none; }
}
@keyframes popup-fade {
	from { opacity: 0; }
	to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
	.site-popup[open],
	.site-popup[open]::backdrop { animation: none; }
}

/* ------------------------------------------------------------------ *
 * Product banners: flagship hero + category chips
 *
 * The storefront leads with big, image-led product banners that reuse
 * the brand's color-coding: a color accent per shop section and a
 * gentle hover lift, matching the category bento.
 * ------------------------------------------------------------------ */

/* Section eyebrow, color-coded per shop section (reuses brand accents) */
.print-eyebrow {
	text-transform: uppercase;
	letter-spacing: 2px;
	font-weight: 500;
	margin: 0 0 0.5rem;
}
.print-eyebrow--amber   { color: var(--wp--preset--color--amber); }
.print-eyebrow--magenta { color: var(--wp--preset--color--magenta); }
.print-eyebrow--cyan    { color: var(--wp--preset--color--cyan); }

/* Outline button tuned for dark banner grounds */
.wp-block-button.is-style-outline--light .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--surface);
	border: 1.5px solid rgba(255, 255, 255, 0.5);
}
.wp-block-button.is-style-outline--light .wp-block-button__link:hover {
	background: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--surface);
}

/* --- Product spotlights (shop) ---
 * Three hand-picked products at the top of the shop (admin-selectable), so the
 * storefront leads with a light three-up row instead of one heavy banner. Each
 * card carries a tricolor accent and is fully clickable. */
.spotlights-wrap { margin-block: 0; }
.spotlights {
	display: grid;
	/* Vaste drie kolommen, geen auto-fit. Met auto-fit rekte één uitgelicht
	 * product zich over de volle breedte uit -- een kaart van 1240px met een
	 * kleine productfoto erin. Nu houdt één kaart een derde van de rij, alsof
	 * er nog twee naast konden staan, en blijft het beeld rustig ongeacht
	 * hoeveel producten er per categorie gekozen zijn. */
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--30);
	align-items: stretch;
}
/* In de smalle tabletband zijn drie kolommen te krap voor een leesbare
 * kaart; twee derde-breedtes lezen daar beter. */
@media (max-width: 1023px) {
	.spotlights { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.spotlight-card {
	--spot-accent: var(--wp--preset--color--magenta);
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 16px;
	background: var(--wp--preset--color--surface);
	text-decoration: none;
	color: var(--wp--preset--color--ink);
	transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.18s ease, border-color 0.18s ease;
}
.spotlight-card:hover {
	transform: translateY(-3px);
	border-color: var(--spot-accent);
	box-shadow: 0 14px 34px rgba(20, 21, 26, 0.09);
}
.spotlight-card--magenta { --spot-accent: var(--wp--preset--color--magenta); }
.spotlight-card--cyan    { --spot-accent: var(--wp--preset--color--cyan); }
.spotlight-card--amber   { --spot-accent: var(--wp--preset--color--amber); }
.spotlight-card__media { display: block; background: var(--wp--preset--color--base-soft); }
.spotlight-card__media img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
}
.spotlight-card__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: 0.35rem;
	padding: 1rem 1.15rem 1.15rem;
}
.spotlight-card__eyebrow {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	font-size: 0.72rem;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: var(--spot-accent);
}
.spotlight-card__title {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 1.05rem;
	line-height: 1.2;
	letter-spacing: -0.01em;
}
.spotlight-card__price {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	color: var(--wp--preset--color--ink);
}
.spotlight-card__price del { color: var(--wp--preset--color--muted); font-weight: 500; margin-right: 0.4em; }
.spotlight-card__price ins { text-decoration: none; }
.spotlight-card__cta {
	margin-top: auto;
	padding-top: 0.4rem;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	font-size: 0.85rem;
	color: var(--spot-accent);
}
@media (max-width: 781px) {
	/* Op mobiel niet drie volle kaarten onder elkaar (dat duwt het
	 * productraster ver onder de vouw): toon ze als een horizontale swipe-rij
	 * met scroll-snap, zodat één kaart mooi vult en de volgende zichtbaar
	 * "gluurt" — de bezoeker ziet zo sneller producten en de sorteerbalk. */
	.spotlights {
		grid-template-columns: none;
		display: flex;
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
	}
	.spotlights::-webkit-scrollbar { display: none; }
	.spotlights .spotlight-card {
		flex: 0 0 80%;
		scroll-snap-align: start;
	}
}

/* --- Category chips (shop) ---
 * A slim, wrapping row of category links, so the product grid leads the
 * page instead of a tall bank of image cards. One tricolor accent per chip;
 * hover fills the pill for a punchy, on-brand state. */
.cat-chips-wrap { margin-block: 0; }
/* .category-chips-container is an alias class the pattern also prints on this
 * same <nav>, so the flex row can be targeted by either name. Gap is a
 * standardized design token, not a raw px value. */
.cat-chips,
.category-chips-container {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--wp--preset--spacing--30);
}
.cat-chip {
	--chip-accent: var(--wp--preset--color--ink);
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.7rem 1.25rem;
	border: 1.5px solid var(--wp--preset--color--border);
	border-radius: 999px;
	background: var(--wp--preset--color--surface);
	font-family: var(--wp--preset--font-family--display);
	font-size: 1.05rem;
	line-height: 1;
	text-decoration: none;
	color: var(--wp--preset--color--ink);
	transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
/* Accent dot */
.cat-chip::before {
	content: "";
	width: 11px;
	height: 11px;
	border-radius: 50%;
	background: var(--chip-accent);
	flex: 0 0 auto;
	transition: background-color 0.15s ease;
}
.cat-chip__name { font-weight: 600; }
.cat-chip__count {
	color: var(--wp--preset--color--muted);
	font-weight: 500;
	font-size: 0.9rem;
}
.cat-chip--magenta { --chip-accent: var(--wp--preset--color--magenta); }
.cat-chip--cyan    { --chip-accent: var(--wp--preset--color--cyan); }
.cat-chip--amber   { --chip-accent: var(--wp--preset--color--amber); }
.cat-chip:hover {
	background: var(--chip-accent);
	border-color: var(--chip-accent);
	transform: translateY(-1px);
}
.cat-chip:hover,
.cat-chip:hover .cat-chip__name,
.cat-chip:hover .cat-chip__count { color: var(--wp--preset--color--surface); }
.cat-chip:hover::before { background: var(--wp--preset--color--surface); }

/* Active state — the chip for the category currently being viewed stays filled
 * with its accent (the hover fill, made persistent) so shoppers can see where
 * they are. Set via .is-active + aria-current="page" in the pattern. */
.cat-chip.is-active,
.cat-chip[aria-current="page"] {
	background: var(--chip-accent);
	border-color: var(--chip-accent);
}
.cat-chip.is-active,
.cat-chip.is-active .cat-chip__name,
.cat-chip.is-active .cat-chip__count,
.cat-chip[aria-current="page"],
.cat-chip[aria-current="page"] .cat-chip__name,
.cat-chip[aria-current="page"] .cat-chip__count { color: var(--wp--preset--color--surface); }
.cat-chip.is-active::before,
.cat-chip[aria-current="page"]::before { background: var(--wp--preset--color--surface); }

/* On phones, shrink the chips so at least two fit on every line. Desktop keeps
 * the larger, roomier chips above. A tight column-gap keeps two per line, while
 * a roomier row-gap gives vertical breathing room between the wrapped lines. */
@media (max-width: 781px) {
	.cat-chips,
	.category-chips-container {
		column-gap: var(--wp--preset--spacing--20);
		row-gap: var(--wp--preset--spacing--30);
	}
	/* Taller chips (more vertical padding); width is unchanged so two still fit. */
	.cat-chip {
		gap: 0.45rem;
		padding: 0.65rem 0.85rem;
		font-size: 0.9rem;
	}
	.cat-chip::before { width: 9px; height: 9px; }
	.cat-chip__count { font-size: 0.8rem; }
}

/* ------------------------------------------------------------------ *
 * Pillars: three-way split value proposition (homepage)
 *
 * Equal, color-coded cards — webshop / workshops / service — reusing the
 * bento's accent-bar + hover-lift language so the split reads as one family.
 * ------------------------------------------------------------------ */
.pillars {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--wp--preset--spacing--30);
	align-items: stretch;
}
/* WordPress' flow layout adds margin-block-start to every child after the
 * first; in a grid row that shoves cards 2+ down and leaves the first sitting
 * higher. Zero it here — the grid `gap` owns the spacing. */
.pillars > * { margin-block-start: 0; }
.pillar {
	position: relative;
	display: flex;
	flex-direction: column;
	padding: var(--wp--preset--spacing--45);
	border-radius: 18px;
	border: 1px solid var(--wp--preset--color--border);
	background: var(--wp--preset--color--surface);
	overflow: hidden;
	transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s ease;
}
.pillar::before {
	content: "";
	position: absolute;
	inset: 0 0 auto 0;
	height: 5px;
	background: var(--pillar-accent, var(--wp--preset--color--ink));
}
.pillar:hover {
	transform: translateY(-3px);
	box-shadow: 0 24px 40px -24px rgba(20, 21, 26, 0.22);
}
.pillar--webshop   { --pillar-accent: var(--wp--preset--color--magenta); }
.pillar--workshops { --pillar-accent: var(--wp--preset--color--cyan); }
.pillar--service   { --pillar-accent: var(--wp--preset--color--amber); }
.pillar-tag {
	text-transform: uppercase;
	letter-spacing: 2px;
	font-weight: 500;
	color: var(--pillar-accent);
	margin: 0.4rem 0 0.5rem;
}
/* Pin the CTA to the bottom so all three cards grow downward and their
 * links bottom-align regardless of copy length. */
.pillar-link { margin-top: auto; }
.pillar-link a {
	text-decoration: none;
	font-weight: 500;
	color: var(--wp--preset--color--ink);
}
/* Stretch the link across the whole card so the card is clickable */
.pillar .stretched::after {
	content: "";
	position: absolute;
	inset: 0;
}
@media (max-width: 781px) {
	.pillars { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------------ *
 * Product trust badges (single product, near add-to-cart)
 *
 * A compact reassurance strip under the buy button: local support,
 * optional pre-assembly, official partner — color-coded in the tricolor.
 * ------------------------------------------------------------------ */
.product-trust {
	margin-top: var(--wp--preset--spacing--30);
	/* lucht tot de productmeta eronder (Merk: ...) */
	margin-bottom: var(--wp--preset--spacing--45);
}
.trust-badges {
	list-style: none;
	margin: 0;
	padding: var(--wp--preset--spacing--30);
	display: grid;
	gap: 0.9rem;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 14px;
	background: var(--wp--preset--color--surface);
}
.trust-badge {
	display: flex;
	align-items: flex-start;
	gap: 0.75rem;
}
.trust-badge__icon {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 10px;
	background: color-mix(in srgb, var(--badge-accent, var(--wp--preset--color--ink)) 12%, var(--wp--preset--color--surface));
	color: var(--badge-accent, var(--wp--preset--color--ink));
}
.trust-badge__text {
	display: flex;
	flex-direction: column;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.35;
	color: var(--wp--preset--color--ink-soft);
}
.trust-badge__text strong {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
}
.trust-badge--magenta { --badge-accent: var(--wp--preset--color--magenta); }
.trust-badge--cyan    { --badge-accent: var(--wp--preset--color--cyan); }
.trust-badge--amber   { --badge-accent: var(--wp--preset--color--amber); }

/* ------------------------------------------------------------------ *
 * Pre-order states — "Pre-Orders for WooCommerce" (XootiX) plugin
 *
 * Styles verified against the plugin's ACTUAL frontend output (its own class
 * names — not invented ones):
 *   .onsale.on-preorder   — the pre-order flag. The plugin REUSES WooCommerce's
 *                           .onsale class, which this theme already paints amber
 *                           for sales, so without the override below a pre-order
 *                           product looks discounted. Repaint it magenta.
 *   .preorder-availability-notice — OUR wrapper around the single-product
 *                           "Available on {date}" line. The plugin echoes that
 *                           text bare on woocommerce_before_add_to_cart_form; a
 *                           small filter in functions.php wraps it in this class
 *                           (enable it under Pre-Orders → available-date position
 *                           = single product for it to render at all).
 *   .preoder-span-block    — the plugin's shop-loop available-date text
 *                           (sic: the plugin misspells "preoder" — matched as-is).
 *   .preorder-cart-notice  — the per-item cart notice; see the cart section for
 *                           its block-cart caveat.
 * ------------------------------------------------------------------ */

/* Repaint the pre-order flag magenta so it reads as an action, not a discount.
 * The .onsale co-selector + !important are needed to beat the amber sale-badge
 * rule (which itself uses !important). White-on-magenta clears AA. Positioning,
 * size and shape are inherited from .onsale, so on the single product page (where
 * functions.php injects it into the image gallery) it overlays the same corner
 * as the Aanbieding badge with an identical layout. */
.onsale.on-preorder {
	background-color: var(--wp--preset--color--magenta) !important;
	color: var(--wp--preset--color--surface) !important;
	text-transform: uppercase;
}
/* Both flags at once (a discounted pre-order): the pre-order span is injected
 * before the sale span, so stack it just below the amber badge instead of
 * overlapping in the shared top-left corner. */
.wp-block-woocommerce-product-image-gallery .onsale.on-preorder:has(~ .onsale:not(.on-preorder)) {
	top: 2.2em;
}

/* Related products: a product with no related items renders the block as an
 * empty <div> (present but childless), which strands the "Gerelateerde
 * producten" heading and its spacer above blank space before the footer. Hide
 * the block, its heading, and the preceding spacer when there is no product
 * card to show. (Confirmed against the plugin's actual empty output.) */
.wp-block-woocommerce-related-products:empty {
	display: none;
}
.wp-block-heading:has(+ .wp-block-woocommerce-related-products:empty) {
	display: none;
}
.wp-block-spacer:has(+ .wp-block-heading + .wp-block-woocommerce-related-products:empty) {
	display: none;
}

/* Single-product availability panel (wrapped via functions.php): a soft
 * magenta-tinted card under the price announcing the dispatch date. Reuses the
 * trust-strip tint recipe + a magenta accent bar so it joins the buy-area family. */
.preorder-availability-notice {
	display: block;
	margin-block: var(--wp--preset--spacing--30);
	padding: var(--wp--preset--spacing--20);
	border: 1px solid var(--wp--preset--color--border);
	border-left: 4px solid var(--wp--preset--color--magenta);
	border-radius: 10px;
	background: color-mix(in srgb, var(--wp--preset--color--magenta) 8%, var(--wp--preset--color--surface));
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.45;
	color: var(--wp--preset--color--ink-soft);
}
/* The date itself (or any lead-in the plugin bolds) reads in brand ink. */
.preorder-availability-notice strong,
.preorder-availability-notice time {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
}

/* Shop-loop available-date line (plugin class, sic "preoder"): a quiet muted
 * caption under the loop price so it doesn't fight the product title. */
.preoder-span-block {
	display: block;
	margin-top: 0.25rem;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--muted);
}

/* ------------------------------------------------------------------ *
 * Product options (PPOM) — boxed like the site's info-panels
 *
 * For products with options, PPOM renders its fields inside the add-to-cart
 * form as a .ppom-wrapper. Give that wrapper the same bordered, rounded,
 * padded card chrome as the .info-panel asides used across the pillar pages,
 * and theme the option checkboxes/radios in brand cyan at a slightly larger,
 * easier-to-hit size.
 * ------------------------------------------------------------------ */
.ppom-wrapper {
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 14px;
	padding: clamp(1.25rem, 3vw, 1.75rem);
	background: var(--wp--preset--color--base);
	margin-block: var(--wp--preset--spacing--30);
}
/* Field title (e.g. "Kies je kleur") reads as the panel heading. */
.ppom-wrapper .form-control-label {
	display: block;
	margin-bottom: 0.6rem;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
}
/* One option per line with a comfortable target and gentle vertical rhythm. */
.ppom-wrapper .form-check-inline,
.ppom-wrapper .form-check {
	display: block;
	margin: 0.35rem 0;
}
.ppom-wrapper .form-check-label {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	cursor: pointer;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-soft);
}
/* Brand-blue (cyan), slightly larger option controls, drawn as sharp-cornered
 * squares with a cyan fill and white tick — echoing the brand's square sale
 * badge — for both checkbox (multi-select) and radio (single-select) fields. */
.ppom-wrapper input[type="checkbox"],
.ppom-wrapper input[type="radio"] {
	appearance: none;
	-webkit-appearance: none;
	width: 1.2em;
	height: 1.2em;
	margin: 0;
	flex: 0 0 auto;
	cursor: pointer;
	display: inline-grid;
	place-content: center;
	border: 1.5px solid var(--wp--preset--color--border);
	border-radius: 0;
	background: var(--wp--preset--color--surface);
	transition: background-color 0.12s ease, border-color 0.12s ease;
}
.ppom-wrapper input[type="checkbox"]::before,
.ppom-wrapper input[type="radio"]::before {
	content: "";
	width: 0.68em;
	height: 0.68em;
	transform: scale(0);
	transition: transform 0.12s ease;
	background-color: var(--wp--preset--color--surface);
	clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
}
.ppom-wrapper input[type="checkbox"]:checked,
.ppom-wrapper input[type="radio"]:checked {
	background: var(--wp--preset--color--cyan);
	border-color: var(--wp--preset--color--cyan);
}
.ppom-wrapper input[type="checkbox"]:checked::before,
.ppom-wrapper input[type="radio"]:checked::before {
	transform: scale(1);
}
.ppom-wrapper input[type="checkbox"]:focus-visible,
.ppom-wrapper input[type="radio"]:focus-visible {
	outline: 2px solid var(--wp--preset--color--cyan);
	outline-offset: 2px;
}

/* ------------------------------------------------------------------ *
 * Single product: scannable specifications table
 *
 * The product-details "Additional information" block ships a dense
 * bordered table. Strip the clutter to a clean two-column, zebra-striped
 * spec sheet that stays legible for high-end printers with many attributes.
 * ------------------------------------------------------------------ */
.wc-block-components-product-details .woocommerce-product-attributes,
.woocommerce-product-attributes {
	width: 100%;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 14px;
	border-collapse: separate;
	border-spacing: 0;
	overflow: hidden;
}
.woocommerce-product-attributes th,
.woocommerce-product-attributes td {
	padding: 0.7rem 1rem;
	border: 0;
	border-bottom: 1px solid var(--wp--preset--color--border);
	text-align: left;
	vertical-align: top;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.5;
}
.woocommerce-product-attributes tr:last-child th,
.woocommerce-product-attributes tr:last-child td {
	border-bottom: 0;
}
.woocommerce-product-attributes th {
	width: 38%;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
	background: var(--wp--preset--color--base);
}
.woocommerce-product-attributes td { color: var(--wp--preset--color--ink-soft); }
.woocommerce-product-attributes td p { margin: 0; }

/* ------------------------------------------------------------------ *
 * Workshops page: audience grid + intake form
 * ------------------------------------------------------------------ */
/* Audience cards — schools / businesses / hobbyists, color-coded */
.wsaud {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--wp--preset--spacing--30);
	align-items: stretch;
}
/* Same flow-margin reset as .pillars — keep the row top-aligned. */
.wsaud > * { margin-block-start: 0; }
.wsaud-card {
	position: relative;
	display: flex;
	flex-direction: column;
	padding: var(--wp--preset--spacing--45);
	border-radius: 18px;
	border: 1px solid var(--wp--preset--color--border);
	background: var(--wp--preset--color--surface);
	overflow: hidden;
	transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s ease;
}
.wsaud-card::before {
	content: "";
	position: absolute;
	inset: 0 auto 0 0;
	width: 5px;
	background: var(--wsaud-accent, var(--wp--preset--color--ink));
}
.wsaud-card:hover {
	transform: translateY(-3px);
	box-shadow: 0 24px 40px -24px rgba(20, 21, 26, 0.22);
}
.wsaud-card--magenta { --wsaud-accent: var(--wp--preset--color--magenta); }
.wsaud-card--cyan    { --wsaud-accent: var(--wp--preset--color--cyan); }
.wsaud-card--amber   { --wsaud-accent: var(--wp--preset--color--amber); }
.wsaud-tag {
	text-transform: uppercase;
	letter-spacing: 2px;
	font-weight: 500;
	color: var(--wsaud-accent);
	margin: 0.4rem 0 0.5rem;
}
.wsaud-list {
	list-style: none;
	margin: 0.75rem 0 1.25rem;
	padding: 0;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-soft);
}
.wsaud-list li {
	position: relative;
	padding: 0.35rem 0 0.35rem 1.4rem;
	border-top: 1px solid var(--wp--preset--color--border);
}
.wsaud-list li:first-child { border-top: 0; }
.wsaud-list li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.85em;
	width: 0.55rem;
	height: 0.55rem;
	border-radius: 2px;
	background: var(--wsaud-accent);
	transform: rotate(45deg);
}
.wsaud-link {
	margin-top: auto;
	padding-top: var(--wp--preset--spacing--30);
}
.wsaud-link a {
	text-decoration: none;
	font-weight: 500;
	/* Pick up the card's pillar accent (magenta/cyan/amber); ink fallback. */
	color: var(--wsaud-accent, var(--wp--preset--color--ink));
}
.wsaud-card .stretched::after {
	content: "";
	position: absolute;
	inset: 0;
}
@media (max-width: 781px) {
	.wsaud { grid-template-columns: 1fr; }
}

/* Hero wayfinding link — sits opposite the eyebrow, points to the bookable
 * product-category workshops now that the header "Workshops" item leads here. */
.ws-hero-top { width: 100%; }
.ws-hero-nav { margin: 0; }
.ws-hero-nav a {
	text-decoration: none;
	font-weight: 500;
	color: var(--wp--preset--color--cyan);
	transition: filter 0.15s ease;
}
.ws-hero-nav a:hover { filter: brightness(0.9); }

/* Intake form — clean two-up field layout on the dark band.
 * The form width is owned by the pattern's constrained group (contentSize),
 * so the fields line up with the heading; don't cap max-width here or it
 * overrides that constraint and the form goes full-bleed. */
.intake-form__row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 1rem;
	margin-bottom: 1rem;
}
.intake-field {
	display: flex;
	flex-direction: column;
	margin-bottom: 1rem;
}
.intake-form__row .intake-field { margin-bottom: 0; }
.intake-field label {
	margin-bottom: 0.4rem;
	font-family: var(--wp--preset--font-family--display);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: var(--wp--preset--color--mist);
}
.intake-field input,
.intake-field select,
.intake-field textarea {
	box-sizing: border-box;
	width: 100%;
	padding: 0.7em 0.9em;
	border: 1.5px solid var(--wp--preset--color--ink-line);
	border-radius: 8px;
	background: var(--wp--preset--color--surface-dark);
	color: var(--wp--preset--color--surface);
	font-family: inherit;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.5; /* shared line-height so <select> and inputs render the same height */
	transition: border-color 0.15s ease;
}
.intake-field textarea { resize: vertical; }
/* Strip the native <select> chrome so it matches the text inputs exactly, then
 * draw our own chevron. With the same box-sizing, padding, border, font-size
 * and line-height, the select is now the same height as the inputs. */
.intake-field select {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 2.4em;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23b9bac2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 0.9em center;
	background-size: 1em;
}
.intake-field input::placeholder,
.intake-field textarea::placeholder { color: var(--wp--preset--color--mist-soft); }
.intake-field input:focus,
.intake-field select:focus,
.intake-field textarea:focus {
	outline: none;
	border-color: var(--wp--preset--color--cyan);
}
.intake-form__submit {
	margin-top: 0.5rem;
	padding: 0.85em 1.7em;
	border: 0;
	border-radius: 8px;
	background: var(--wp--preset--color--magenta);
	color: var(--wp--preset--color--surface);
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	font-size: var(--wp--preset--font-size--medium);
	cursor: pointer;
	transition: background-color 0.18s ease, transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
}
.intake-form__submit:hover { background: var(--wp--preset--color--magenta-dark); }
.intake-form__submit:active { transform: translateY(1px); }
/* Honeypot: kept in the DOM for bots but off-screen for people (display:none
 * would be skipped by bots). A real submission leaves this empty. */
.intake-hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}
/* Success / error banner after a submit. Solid light fill + dark text so it
 * reads on both the dark intake panels and the light service form. */
.intake-form__status {
	margin: 0 0 1.1rem;
	padding: 0.75em 1em;
	border-radius: 8px;
	font-weight: 500;
	font-size: 0.95rem;
}
.intake-form__status--ok {
	background: #e7f8f0;
	color: #0a7a5e;
	border: 1px solid #b7e6d3;
}
.intake-form__status--err {
	background: #fdeaf1;
	color: #b31f5e;
	border: 1px solid #f5c4da;
}
/* Prose links inside the dark intake panels — the global link color is
 * ink (dark), which is invisible on the ink background. Surface + magenta
 * hover keeps them legible and on-brand. */
.workshops-intake p a {
	color: var(--wp--preset--color--surface);
	text-decoration: underline;
}
.workshops-intake p a:hover { color: var(--wp--preset--color--magenta); }
@media (max-width: 600px) {
	.intake-form__row { grid-template-columns: 1fr; gap: 0; }
	.intake-form__row .intake-field { margin-bottom: 1rem; }
}

/* ------------------------------------------------------------------ *
 * Educatieve pakketten — package cards
 *
 * The cards reuse the workshops audience-card system (.wsaud-card / .wsaud-tag
 * / .wsaud-list / .wsaud-link); only the grid, a bottom-pinned footer, and the
 * price label are page-specific.
 * ------------------------------------------------------------------ */
.edu-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--wp--preset--spacing--30);
	align-items: stretch;
}
/* WordPress' flow layout adds margin-block-start to children after the first;
 * zero it so the grid row stays top-aligned (the grid `gap` owns spacing). */
.edu-grid > * { margin-block-start: 0; }
/* Keep the price + CTA pinned to the bottom of each card so they line up
 * across cards no matter how long the inclusions list runs. */
.edu-foot { margin-top: auto; }
.edu-price {
	margin: 0 0 0.7rem;
	color: var(--wp--preset--color--ink-soft);
}
.edu-price strong {
	display: block;
	margin-bottom: 0.15rem;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	font-size: 0.72rem;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}
/* Offerte-CTA — a solid cyan pill button, mirroring the site button (8px
 * radius, display font) but in the educatie pillar's cyan. The anchor keeps
 * .stretched so the whole card stays clickable; the pill is the affordance. */
.edu-cta { margin: 0; text-align: center; }
.edu-cta a {
	display: inline-block;
	padding: 0.85em 1.7em;
	background: var(--wp--preset--color--cyan);
	color: var(--wp--preset--color--surface);
	border-radius: 8px;
	font-weight: 500;
	text-decoration: none;
	transition: filter 0.15s ease;
}
.edu-cta a:hover,
.edu-cta a:focus-visible { filter: brightness(0.92); }
/* Package-inclusion illustration — a framed thumbnail on the card's base tint
 * so the (white-background) product image reads as a panel rather than blending
 * into the white card. */
.edu-thumb {
	margin: 0.25rem 0 1.1rem;
	border-radius: 12px;
	overflow: hidden;
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
}
.edu-thumb img {
	display: block;
	width: 100%;
	height: auto;
}
/* Hero photo alongside a pillar-page intro (educatie / oplossingen / workshops)
 * — a tall rounded panel that balances the text column; object-fit cover keeps
 * it filled at any source ratio. */
.hero-photo { margin: 0; }
.hero-photo img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	border-radius: 18px;
	box-shadow: 0 30px 50px -30px rgba(20, 21, 26, 0.35);
}
/* Landscape variant — the contact hero uses a wide showroom shot, which a 4/5
 * portrait crop would gut. Same rounding and shadow, 3/2 proportions. */
.hero-photo--wide img { aspect-ratio: 3 / 2; }

/* Striped "Foto volgt" placeholder standing in for a hero photo (Service &
 * montage) — reuses .social-proof-placeholder but takes the same 4/5 panel
 * proportions as a real .hero-photo so the layout matches the other pillars. */
.hero-photo-placeholder {
	aspect-ratio: 4 / 5;
	min-height: 0;
}
@media (max-width: 781px) {
	.edu-grid { grid-template-columns: 1fr; }
	/* Stacked under the text on mobile — relax to a landscape crop so it isn't
	 * an over-tall column. */
	.hero-photo img,
	.hero-photo-placeholder { aspect-ratio: 3 / 2; }
}

/* ------------------------------------------------------------------ *
 * 404 — "failed print" page
 *
 * A giant brand-gradient 404 with a subtle layer-shift on the middle digit,
 * sitting on a faint print-bed grid, plus playful printer-diagnostic chips.
 * ------------------------------------------------------------------ */
.error-404 { text-align: center; }

/* Print-bed stage: a faint grid that fades out toward the edges, behind
 * the giant numerals. */
.error-404__stage {
	position: relative;
	display: inline-block;
	padding: 1.5rem 2.5rem;
	margin-bottom: 0.5rem;
}
.error-404__stage::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background-image:
		linear-gradient(var(--wp--preset--color--border) 1px, transparent 1px),
		linear-gradient(90deg, var(--wp--preset--color--border) 1px, transparent 1px);
	background-size: 30px 30px;
	background-position: center;
	-webkit-mask-image: radial-gradient(ellipse at center, #000 25%, transparent 72%);
	        mask-image: radial-gradient(ellipse at center, #000 25%, transparent 72%);
}

/* The numerals themselves: big display font in the brand tricolor. Solid
 * per-digit colors (not a clipped gradient) so the layer-shift transform on
 * the middle digit can't detach it from a background-clip and vanish. */
.error-404__code {
	position: relative;
	z-index: 1;
	font-family: var(--wp--preset--font-family--display), sans-serif;
	font-weight: 700;
	line-height: 0.9;
	letter-spacing: -0.04em;
	font-size: clamp(6rem, 22vw, 14rem);
}
.error-404__digit { display: inline-block; }
.error-404__digit--magenta { color: var(--wp--preset--color--magenta); }
.error-404__digit--amber   { color: var(--wp--preset--color--amber); }
.error-404__digit--cyan    { color: var(--wp--preset--color--cyan); }
/* The mis-registered layer: nudge and tilt the middle digit like a print
 * that shifted mid-job. */
.error-404__shift {
	transform: translate(0.04em, -0.05em) rotate(-4deg);
}

/* The layer-shift is a static nudge, but honour reduced-motion intent by
 * settling the digit straight for those users. */
@media (prefers-reduced-motion: reduce) {
	.error-404__shift { transform: none; }
}

/* ------------------------------------------------------------------ *
 * Header — compact mobile navbar
 *
 * The full "3DUCATION" wordmark logo is wide; on phones it crowds the row and
 * squeezes the Webshop button until its text breaks one letter per line. On
 * mobile we swap the wordmark for the compact cube mark (freeing space) and
 * keep the button text on a single line. The cube lives in the theme assets and
 * is referenced relative to this file (assets/images/logo-cube.png).
 * ------------------------------------------------------------------ */
@media (max-width: 781px) {
	.site-header .wp-block-site-logo { width: auto; margin: 0; }
	/* Hide the wide wordmark image, draw the square cube mark on its home link. */
	.site-header .custom-logo { display: none; }
	.site-header .custom-logo-link {
		display: block;
		width: 38px;
		height: 46px; /* 4:5, matches the 160×200 cube mark */
		background: url("images/logo-cube.png") left center / contain no-repeat;
	}
	/* Never let the Webshop button wrap or stack characters vertically. */
	.site-header .wp-block-button__link { white-space: nowrap; }
}

/* ------------------------------------------------------------------ *
 * Hamburger vertical centering
 *
 * The overlay-open button is a plain <button>; core gives it no height, so
 * inside the center-aligned header row it hugs the top of the tallest
 * neighbour (the cube logo / Webshop button) instead of sitting on the row's
 * mid-line. Make the button a full-height flex box that centers its icon so
 * the hamburger lines up with the logo and Webshop button. Applies wherever
 * the overlay is active (phone <600px and the 600–1199px tablet band). */
.site-header .wp-block-navigation__responsive-container-open:not(.always-shown) {
	align-self: stretch;
	align-items: center;
	justify-content: center;
}

/* ------------------------------------------------------------------ *
 * Tablet & small-laptop navigation
 *
 * The nav labels "Workshops & Educatie" and "Service & Montage" are too long
 * to sit inline next to the logo, Webshop button and icons below ~1200px: the
 * row wrapped to two lines and stacked the button's characters vertically.
 * WordPress' "mobile" overlay only collapses the nav below 600px, so the whole
 * tablet band was left broken. Extend the hamburger overlay up through 1199px
 * (higher-specificity overrides beat core's min-width:600px inline rule); the
 * inline nav returns at >=1200px, where it fits on one line.
 * ------------------------------------------------------------------ */
@media (min-width: 600px) and (max-width: 1199px) {
	.site-header .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
		min-width: 44px;
		min-height: 44px;
	}
	.site-header .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}
}
/* Belt-and-braces: the header Webshop button never wraps at any width. */
.site-header .wp-block-button__link { white-space: nowrap; }

/* ------------------------------------------------------------------ *
 * Footer flush with preceding section
 * ------------------------------------------------------------------ */
/* The site footer is ink-dark, like the homepage workshops CTA that
 * precedes it. WordPress puts a block-gap margin above the footer
 * template part, which shows as a thin light strip between the two
 * dark blocks. Remove it so the footer butts flush against the content. */
.wp-site-blocks > footer.wp-block-template-part {
	margin-block-start: 0;
}

/* Same block-gap strip appears between the header and the first section.
 * On the homepage that first section is the dark full-bleed hero, so the
 * light gap is visible — drop it so the hero butts flush under the nav. */
.wp-site-blocks > main {
	margin-block-start: 0;
}

/* The footer sits on the ink-dark background, but the Webshop / Klantenservice
 * link lists inherit the theme's dark ink link colour — dark on dark, so they
 * read as invisible. Force footer body links white; keep the brand magenta on
 * hover (which the theme link :hover already provides). */
.site-footer p a {
	color: var(--wp--preset--color--surface);
	text-decoration: none;
}
.site-footer p a:hover {
	color: var(--wp--preset--color--magenta);
	text-decoration: underline;
}
/* A phone number must never break across digits. */
.site-footer a[href^="tel:"] { white-space: nowrap; }
/* Tablet band (782–900px): core columns only stack below 782px, so the 4-up
 * footer stays side-by-side here and squeezes the narrow Contact column —
 * wrapping the address and phone number mid-token. Wrap the columns two-up into
 * a tidy 2×2 grid. The !important overrides the brand column's inline 38% basis;
 * the calc keeps the existing spacing|50 gutter between the two columns. */
@media (min-width: 782px) and (max-width: 900px) {
	/* Core pins columns to `flex-wrap: nowrap !important` above 782px, so this
	 * must be !important too to let the footer wrap into a 2×2 grid. */
	.site-footer .wp-block-columns { flex-wrap: wrap !important; }
	.site-footer .wp-block-columns > .wp-block-column {
		flex-basis: calc(50% - var(--wp--preset--spacing--50) / 2) !important;
		min-width: 0;
	}
}

/* ------------------------------------------------------------------ *
 * Shop product search (archive-product header row)
 * ------------------------------------------------------------------ */
/* WooCommerce's product-search block ships unstyled; dress it as a joined
 * input + button pill in the brand palette so it sits with the storefront. */
.shop-search .wc-block-product-search__label {
	display: block;
	margin-bottom: 0.35rem;
	font-family: var(--wp--preset--font-family--display);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}
/* Span the full content width above the product grid; the input flexes to
 * fill the row and the button stays its natural size on the right. */
.shop-search { width: 100%; }
.shop-search .wc-block-product-search__fields {
	display: flex;
	align-items: stretch;
	width: 100%;
}
.shop-search .wc-block-product-search__field {
	flex: 1 1 auto;
	min-width: 0;
	padding: 0.65em 0.9em;
	background: var(--wp--preset--color--surface);
	border: 1.5px solid var(--wp--preset--color--border);
	border-right: 0;
	border-radius: 8px 0 0 8px;
	font-size: var(--wp--preset--font-size--small);
}
.shop-search .wc-block-product-search__field:focus {
	outline: none;
	border-color: var(--wp--preset--color--magenta);
}
.shop-search .wc-block-product-search__button {
	display: flex;
	align-items: center;
	padding: 0 1em;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--surface);
	border: 0;
	border-radius: 0 8px 8px 0;
	cursor: pointer;
	transition: background-color 0.18s ease;
}
.shop-search .wc-block-product-search__button:hover,
.shop-search .wc-block-product-search__button:focus-visible {
	background: var(--wp--preset--color--magenta);
}

/* ------------------------------------------------------------------ *
 * Shop filter sidebar
 * ------------------------------------------------------------------ */
/* Separate each filter group and give headings the display-font treatment
 * consistent with the rest of the storefront. */
.shop-filters .wp-block-woocommerce-product-filter-taxonomy,
.shop-filters .wp-block-woocommerce-product-filter-price,
.shop-filters .wp-block-woocommerce-product-filter-status {
	margin-bottom: var(--wp--preset--spacing--50);
}
.shop-filters h3 {
	margin-bottom: var(--wp--preset--spacing--20);
	font-family: var(--wp--preset--font-family--display);
}
/* Keep the category list (many terms) from dominating the column. */
.shop-filters .wc-block-product-filter-checkbox-list {
	max-height: 260px;
	overflow-y: auto;
}
/* Magenta accent throughout the sidebar. */
.shop-filters input[type="checkbox"],
.shop-filters input[type="range"],
.shop-filters .wc-block-product-filter-price-slider__range {
	accent-color: var(--wp--preset--color--magenta);
}
.shop-filters .wc-block-product-filter-price-slider__range {
	--range-color: var(--wp--preset--color--magenta);
	background: var(--wp--preset--color--magenta);
}
/* Keep the price filter inside the sidebar column: the dual-range track and
 * the two amount inputs otherwise carry a fixed width that spills past the
 * column's right edge. Force everything to share the available width. */
.shop-filters .wp-block-woocommerce-product-filter-price-slider,
.shop-filters .wp-block-woocommerce-product-filter-price-slider * {
	box-sizing: border-box;
}
.shop-filters .wc-block-product-filter-price-slider__content,
.shop-filters .wc-block-product-filter-price-slider__range {
	width: 100%;
	max-width: 100%;
}
.shop-filters .wc-block-product-filter-price-slider__left,
.shop-filters .wc-block-product-filter-price-slider__right {
	flex: 1 1 0;
	min-width: 0;
}
.shop-filters .wc-block-product-filter-price-slider__left input,
.shop-filters .wc-block-product-filter-price-slider__right input {
	width: 100%;
	min-width: 0;
}
.shop-filters .wc-block-product-filter-checkbox-list__label:hover,
.shop-filters li:has(input:checked) .wc-block-product-filter-checkbox-list__text {
	color: var(--wp--preset--color--magenta);
}
.shop-filters .wc-block-product-filter-clear-button {
	color: var(--wp--preset--color--magenta);
	text-decoration-color: var(--wp--preset--color--magenta);
}
/* Tint the category scroll list's scrollbar to match. */
.shop-filters .wc-block-product-filter-checkbox-list {
	scrollbar-color: var(--wp--preset--color--magenta) transparent;
}

/* ------------------------------------------------------------------ *
 * Mobile filter overlay — WooCommerce breakpoint-overlap fix
 * ------------------------------------------------------------------ */
/* WooCommerce's Product Filters ship the "Filter producten" overlay trigger up
 * to 782px, but reset the overlay to position:relative (inline filters) from
 * 601px up. Those ranges OVERLAP: at 601–782px the overlay opens in mobile mode
 * yet is positioned relative, so it renders inline and lands on top of the
 * product grid instead of covering it (a full-screen dialog). It looks fine
 * below 601px (phones) and above 782px (inline desktop filters), so only the
 * tablet / narrow-window band is broken. Re-assert the fixed full-screen dialog
 * for that band when the overlay is open. Real class specificity (0,3,0) beats
 * WooCommerce's :where()-wrapped rules, so this wins regardless of load order. */
@media (min-width: 601px) and (max-width: 782px) {
	.wc-block-product-filters.is-overlay-opened .wc-block-product-filters__overlay {
		position: fixed;
		top: var(--top-padding, 0px);
		right: 0;
		bottom: 0;
		left: 0;
		z-index: 9999;
		background-color: rgba(95, 95, 95, 0.35);
	}
	.wc-block-product-filters.is-overlay-opened .wc-block-product-filters__overlay-wrapper {
		position: relative;
		width: 100%;
		height: 100%;
	}
	.wc-block-product-filters.is-overlay-opened .wc-block-product-filters__overlay-dialog {
		position: absolute;
		inset: 0;
		max-height: 100%;
		display: flex;
		flex-direction: column;
		transform: none;
		background-color: var(--wp--preset--color--surface);
		color: var(--wp--preset--color--ink);
	}
	.wc-block-product-filters.is-overlay-opened .wc-block-product-filters__overlay-content {
		flex-grow: 1;
		overflow-y: auto;
	}
	/* The desktop reset hides the dialog's header (Sluiten) and footer
	 * (Toepassen); bring them back so the open dialog is operable. */
	.wc-block-product-filters.is-overlay-opened .wc-block-product-filters__overlay-header {
		display: flex;
	}
	.wc-block-product-filters.is-overlay-opened .wc-block-product-filters__overlay-footer {
		display: block;
	}
}

/* ------------------------------------------------------------------ *
 * Shop product grid — four per row, uniform card height
 * ------------------------------------------------------------------ */
/* Stretch every card in a row to the tallest card's height, then make each
 * card a full-height flex column so the add-to-cart button bottom-aligns no
 * matter how tall the title or price above it is. */
.shop-grid .wp-block-woocommerce-product-template {
	align-items: stretch;
}
.shop-grid .wc-block-product {
	display: flex;
	flex-direction: column;
	height: 100%;
}
/* Two per row on mobile. WooCommerce's flex template ships 1 column below
 * 600px (each li 100%) and jumps straight to 4 above it; force 2-up across the
 * whole ≤781px range so phones show a pair and small tablets don't cram four.
 * (calc mirrors WC's own .columns-2 formula for the 1.25em flex gap.)
 * !important is required because WC pins the width with a specificity hack —
 * `.is-flex-container.is-flex-container.columns-4 > li` (0,4,1), a duplicated
 * class — which otherwise outranks a normal theme selector from 600px up. */
@media (max-width: 781px) {
	.shop-grid .wc-block-product-template.is-flex-container > li {
		width: calc(50% - 0.625em) !important;
	}
}
/* Tablet band (782–1023px): WooCommerce keeps its 4-up desktop layout here,
 * cramming cards to ~150px so product titles clamp and truncate mid-word — worse
 * on the shop archive where the filter sidebar narrows the grid column further.
 * Force 3-up so titles have room to breathe. (calc mirrors WC's .columns-3
 * formula for the 1.25em flex gap: (N-1)*gap/N = 2*1.25em/3 ≈ 0.834em.)
 * !important for the same reason as the ≤781px rule above — beat WC's
 * duplicated-class specificity hack on .columns-4. */
@media (min-width: 782px) and (max-width: 1023px) {
	.shop-grid .wc-block-product-template.is-flex-container > li {
		width: calc(33.333% - 0.834em) !important;
	}
}
/* Fixed square media box gives every card the same image height;
 * contain keeps the whole product visible on its white background. */
.shop-grid .wc-block-components-product-image {
	margin-bottom: var(--wp--preset--spacing--20);
}
.shop-grid .wc-block-components-product-image img {
	aspect-ratio: 1 / 1;
	width: 100%;
	object-fit: contain;
	background: var(--wp--preset--color--surface);
	border-radius: 8px;
}
/* Pre-order loop badge: the plugin outputs it as an absolutely-positioned
 * .onsale span, but the block product card is not a positioning context, so it
 * escapes to the page corner. Make the card the anchor and sit the badge over
 * the image's top-RIGHT corner, mirroring the amber AANBIEDING sale badge. */
.shop-grid .wc-block-product { position: relative; }
.shop-grid .onsale.on-preorder {
	position: absolute;
	inset: 8px 8px auto auto;
	margin: 0;
	z-index: 3;
}
/* Both at once (a discounted pre-order): the amber sale badge owns the top-right
 * corner, so drop the pre-order flag just below it instead of overlapping. */
.shop-grid .wc-block-product:has(.wc-block-components-product-sale-badge) .onsale.on-preorder {
	top: 2.6em;
}
/* Price reads as a soft-grey secondary detail so the product title and the
 * add-to-cart button lead the card. Shop grid only — the single-product page,
 * cart and related products keep the price in strong display ink (theme.json). */
.shop-grid .wp-block-woocommerce-product-price,
.shop-grid .wp-block-woocommerce-product-price .wc-block-components-product-price__value {
	color: var(--wp--preset--color--ink-soft);
}

/* Reserve exactly two lines for the title so one-, two- or three-line
 * product names all occupy the same height — long titles are clamped
 * instead of stretching the card. */
.shop-grid .wp-block-post-title {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	line-height: 1.3;
	height: 2.6em; /* exactly two lines — one-, two- or three-line names all match */
}
/* The title's inner link must inherit the clamp so long names truncate
 * instead of pushing the card taller. */
.shop-grid .wp-block-post-title a {
	display: inline;
	overflow: hidden;
}
/* Push the button to the bottom edge of the card and make it span the
 * full card width, compact (less vertical padding, single line). The flex
 * column lets the appended "Bekijk winkelwagen" link stack full-width
 * beneath the button once a product is added. */
.shop-grid .wp-block-woocommerce-product-button {
	margin-top: auto;
	width: 100%;
	display: flex;
	flex-direction: column;
}
.shop-grid .wp-block-woocommerce-product-button .wc-block-components-product-button__button {
	display: block;
	width: 100%;
	padding-top: 0.5rem;
	padding-bottom: 0.5rem;
	font-size: 0.8rem;
	line-height: 1.2;
	white-space: nowrap;
	text-align: center;
}
/* Button colour by state, keyed off WooCommerce's own button classes:
 *   – ajax add-to-cart  (.add_to_cart_button.ajax_add_to_cart) → solid magenta
 *     (the theme.json button default) — the primary buy action.
 *   – needs options     (.add_to_cart_button, no ajax) → cyan; the product
 *     links to its page to pick a variation or fill PPOM options, whether it's
 *     a variable product or a simple one with options ("Selecteer opties").
 *   – read more          (no .add_to_cart_button) → grey OUTLINE ("Lees meer").
 *     A secondary button (transparent fill, muted-grey border + text) that
 *     fills grey on hover — quieter than the magenta/cyan buy actions, but
 *     still clearly a live button rather than a dead greyed-out one. */
.shop-grid .wc-block-components-product-button__button.add_to_cart_button:not(.ajax_add_to_cart) {
	background-color: var(--wp--preset--color--cyan);
	border-color: var(--wp--preset--color--cyan);
	color: var(--wp--preset--color--surface);
}
.shop-grid .wc-block-components-product-button__button:not(.add_to_cart_button) {
	background-color: transparent;
	/* Inset ring rather than a real border, so this outline button keeps the
	 * exact same box size as the solid magenta/cyan buttons beside it (a real
	 * 1.5px border would make "Lees meer" taller/wider than its neighbours). */
	box-shadow: inset 0 0 0 1.5px var(--wp--preset--color--muted);
	color: var(--wp--preset--color--muted);
}
.shop-grid .wc-block-components-product-button__button:not(.add_to_cart_button):hover,
.shop-grid .wc-block-components-product-button__button:not(.add_to_cart_button):focus-visible {
	background-color: var(--wp--preset--color--muted);
	box-shadow: none;
	color: var(--wp--preset--color--surface);
}

/* Added-to-cart state — for any product already in the cart, WooCommerce
 * appends a bare "Bekijk winkelwagen" link under the add-to-cart button.
 * Turn that stray underlined link into a full-width cyan-outline secondary
 * action tucked beneath the button, so the card stays tidy instead of
 * leaking an unstyled link into the grid gap. */
.shop-grid .added_to_cart.wc_forward {
	display: block;
	width: 100%;
	margin-top: 0.4rem;
	padding: 0.5rem 0.75rem;
	/* Inset ring (see the "Lees meer" button above): keeps this secondary link
	 * the same box size as the primary button it sits beneath. */
	box-shadow: inset 0 0 0 1.5px var(--wp--preset--color--cyan);
	border-radius: 8px;
	background: transparent;
	color: var(--wp--preset--color--cyan);
	font-family: var(--wp--preset--font-family--display);
	font-size: 0.8rem;
	line-height: 1.2;
	text-align: center;
	text-decoration: none;
	white-space: nowrap;
	transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease, transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
}
.shop-grid .added_to_cart.wc_forward::after {
	content: " →";
}
.shop-grid .added_to_cart.wc_forward:hover,
.shop-grid .added_to_cart.wc_forward:focus-visible {
	background: var(--wp--preset--color--cyan);
	color: var(--wp--preset--color--surface);
}
.shop-grid .added_to_cart.wc_forward:active {
	transform: translateY(1px);
}

/* Pagination — cyan buttons with white text and roomy 44px tap targets. */
.shop-grid .wp-block-query-pagination {
	gap: 0.5rem;
	margin-top: var(--wp--preset--spacing--50);
}
.shop-grid .wp-block-query-pagination-numbers {
	display: flex;
	gap: 0.5rem;
	align-items: center;
}
.shop-grid .wp-block-query-pagination .page-numbers,
.shop-grid .wp-block-query-pagination-previous,
.shop-grid .wp-block-query-pagination-next {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.25rem;
	min-height: 2.25rem;
	padding: 0.4rem 0.75rem;
	border-radius: 8px;
	background-color: var(--wp--preset--color--cyan);
	color: var(--wp--preset--color--surface);
	font-family: var(--wp--preset--font-family--display);
	line-height: 1;
	text-decoration: none;
	transition: filter 0.15s ease;
}
.shop-grid .wp-block-query-pagination a.page-numbers:hover,
.shop-grid a.wp-block-query-pagination-previous:hover,
.shop-grid a.wp-block-query-pagination-next:hover {
	filter: brightness(0.92);
}
/* Current page reads as selected in brand ink. */
.shop-grid .wp-block-query-pagination .page-numbers.current {
	background-color: var(--wp--preset--color--ink);
}
/* The "…" gap is not a button. */
.shop-grid .wp-block-query-pagination .page-numbers.dots {
	min-width: 0;
	padding: 0.5rem 0.25rem;
	background: transparent;
	color: var(--wp--preset--color--ink-soft);
}

/* ------------------------------------------------------------------ *
 * Pillar pages — shared helpers
 *
 * Used across the Webshop & oplossingen, Workshops and Service & montage
 * pillar pages. .info-panel is a light bordered aside that reuses the
 * .wsaud-list bullet system (set its accent via a --magenta/--cyan/--amber
 * modifier); .price-tag is the big display price; .field-hint / file input
 * extend the dark intake form for the service request.
 * ------------------------------------------------------------------ */
/* Two consecutive full-width surface (white) bands — e.g. verjaardagsfeestjes →
 * voor scholen on the workshops page — should read as one continuous white area.
 * Collapse the blockGap between them so the page's base background no longer
 * shows through as a thin grey line. Scoped to surface→surface pairs so the
 * intentional white→base transitions (e.g. scholen → thuis on /oplossingen)
 * keep their separation. */
.solutions-section.has-surface-background-color + .solutions-section.has-surface-background-color {
	margin-block-start: 0;
}
.info-panel {
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 14px;
	padding: clamp(1.25rem, 3vw, 1.75rem);
	background: var(--wp--preset--color--base);
}
.info-panel > * { margin-block-start: 0; }
.info-panel--magenta { --wsaud-accent: var(--wp--preset--color--magenta); }
.info-panel--cyan    { --wsaud-accent: var(--wp--preset--color--cyan); }
.info-panel--amber   { --wsaud-accent: var(--wp--preset--color--amber); }
.info-panel__title {
	margin: 0 0 0.4rem;
	font-weight: 500;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: var(--wsaud-accent, var(--wp--preset--color--ink-soft));
}
/* The .wsaud-list inside a panel needs no top border on its first row. */
.info-panel .wsaud-list { margin: 0; }

/* ------------------------------------------------------------------ *
 * Contact map — keyless Google Maps embed on the /contact page.
 * Rounded, bordered frame that fills its column; the iframe grows to
 * the full column height so it stays flush with the detail panels
 * beside it, with a sensible minimum on narrow/stacked layouts.
 * ------------------------------------------------------------------ */
.contact-map {
	height: 100%;
	min-height: 420px;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 14px;
	overflow: hidden;
}
.contact-map iframe {
	display: block;
	width: 100%;
	height: 100%;
	min-height: 420px;
}

/* ------------------------------------------------------------------ *
 * Shop help panel — customer-service aside beside the archive H1
 *
 * The panel floats to the RIGHT of the title + search bar, so those stack
 * together on the left with no gap between the H1 and the search bar (instead of
 * the search being pushed below a tall side column). The intro wrapper contains
 * the float; the header and search boxes establish their own formatting context
 * so they sit beside the panel rather than running underneath it. Amber-tinted
 * card + accent bar; the CTA is a secondary outline button so it never competes
 * with the primary, solid-magenta Add-to-Cart action.
 * ------------------------------------------------------------------ */
.shop-intro { display: flow-root; }
.shop-intro .shop-header,
.shop-intro .shop-search-row { display: flow-root; }
.shop-intro .shop-search-row { margin-top: var(--wp--preset--spacing--40); }

/* --- Category intro (product-category archive) ---
 * Category "Thumbnail" image + SEO description (markdown via Parsedown).
 * Long copy clamps to ~3 lines with a soft fade and a CSS-only "Lees meer"
 * chevron toggle (a visually-hidden checkbox drives the expanded state). */
.category-intro { margin-block: 0; }
.category-intro__inner.has-image {
	display: grid;
	grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
	gap: var(--wp--preset--spacing--50);
	align-items: start;
}
.category-intro__img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border-radius: 16px;
	border: 1px solid var(--wp--preset--color--border);
}
.cat-desc { position: relative; }
/* Off-screen but focusable, so the toggle stays keyboard-operable without JS. */
.cat-desc__cb { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.cat-desc__body { color: var(--wp--preset--color--ink-soft); }
.cat-desc__body > :first-child { margin-top: 0; }
.cat-desc__body > :last-child { margin-bottom: 0; }
.cat-desc__body h2,
.cat-desc__body h3,
.cat-desc__body h4 {
	font-family: var(--wp--preset--font-family--display);
	color: var(--wp--preset--color--ink);
	line-height: 1.25;
	margin-block: 1em 0.35em;
}
/* Keep in-description headings as subheadings — they must not rival the page H1. */
.cat-desc__body h2 { font-size: 1.2rem; }
.cat-desc__body h3 { font-size: 1.05rem; }
.cat-desc__body h4 { font-size: 0.95rem; }
.cat-desc__body ul,
.cat-desc__body ol { padding-left: 1.2em; }
.cat-desc__body li { margin-block: 0.2em; }
.cat-desc__body a {
	color: var(--wp--preset--color--magenta);
	text-underline-offset: 2px;
}
/* Collapsed: ~3 lines with a fade-out mask, until the checkbox is checked. */
.cat-desc.is-clamped .cat-desc__body {
	max-height: 4.9em;
	overflow: hidden;
	-webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent);
	        mask-image: linear-gradient(to bottom, #000 55%, transparent);
}
.cat-desc.is-clamped .cat-desc__cb:checked ~ .cat-desc__body {
	max-height: none;
	-webkit-mask-image: none;
	        mask-image: none;
}
.cat-desc__toggle {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	margin-top: 0.55rem;
	font-family: var(--wp--preset--font-family--display);
	font-size: 0.85rem;
	font-weight: 500;
	color: var(--wp--preset--color--magenta);
	cursor: pointer;
	user-select: none;
}
.cat-desc__toggle-less { display: none; }
.cat-desc__cb:checked ~ .cat-desc__toggle .cat-desc__toggle-more { display: none; }
.cat-desc__cb:checked ~ .cat-desc__toggle .cat-desc__toggle-less { display: inline; }
.cat-desc__chev { transition: transform 0.2s ease; }
.cat-desc__cb:checked ~ .cat-desc__toggle .cat-desc__chev { transform: rotate(180deg); }
.cat-desc__cb:focus-visible ~ .cat-desc__toggle {
	outline: 2px solid var(--wp--preset--color--magenta);
	outline-offset: 3px;
	border-radius: 4px;
}
@media (max-width: 781px) {
	.category-intro__inner.has-image { grid-template-columns: 1fr; }
	.category-intro__img { max-width: 320px; }
}
/* Full-width "can't find it?" band at the foot of the shop/category archive:
 * copy on the left, secondary CTA on the right; wraps on narrow screens. */
.shop-help {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--50);
	border-left: 4px solid var(--wp--preset--color--amber);
	background: color-mix(in srgb, var(--wp--preset--color--amber) 8%, var(--wp--preset--color--surface));
}
.shop-help__body { flex: 1 1 460px; }
.shop-help__body > :last-child { margin-bottom: 0; }
.shop-help .wp-block-buttons { flex: 0 0 auto; margin-block: 0; }
.shop-help__title {
	margin: 0 0 0.5rem;
	font-size: 1.05rem;
	line-height: 1.25;
	color: var(--wp--preset--color--ink);
}
.shop-help__text {
	margin: 0 0 1.1rem;
	color: var(--wp--preset--color--ink-soft);
	line-height: 1.5;
}
/* Secondary CTA: amber outline that fills on hover — never a solid primary.
 * Label stays in ink (amber-on-light text would fail contrast). */
.shop-help .wp-block-button__link {
	background: transparent;
	border: 1.5px solid var(--wp--preset--color--amber);
	color: var(--wp--preset--color--ink);
}
.shop-help .wp-block-button__link:hover,
.shop-help .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--amber);
	border-color: var(--wp--preset--color--amber);
	color: var(--wp--preset--color--ink);
}
/* Phones/tablets: single column, panel last (below title + search). */
@media (max-width: 781px) {
	.shop-intro {
		display: flex;
		flex-direction: column;
		gap: var(--wp--preset--spacing--40);
	}
	.shop-intro .shop-search-row { margin-top: 0; }
}

/* Big display price used on the workshop / party offers. */
.price-tag {
	margin: 0.25rem 0 1.25rem;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: clamp(1.75rem, 4vw, 2.25rem);
	line-height: 1;
	letter-spacing: -0.02em;
	color: var(--wp--preset--color--ink);
}
.price-tag span {
	display: inline-block;
	margin-left: 0.4rem;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	letter-spacing: 0;
	color: var(--wp--preset--color--muted);
}

/* Service intake extras: helper text under a field, and a dark-themed file
 * input so it matches the other fields on the ink band. */
.intake-field .field-hint {
	margin-top: 0.35rem;
	font-size: 0.75rem;
	color: var(--wp--preset--color--muted);
}
.intake-field input[type="file"] {
	padding: 0.55em 0.9em;
	cursor: pointer;
}
.intake-field input[type="file"]::file-selector-button {
	margin-right: 0.8em;
	padding: 0.4em 0.9em;
	border: 0;
	border-radius: 6px;
	background: var(--wp--preset--color--ink-line);
	color: var(--wp--preset--color--surface);
	font-family: var(--wp--preset--font-family--display);
	font-size: 0.8rem;
	cursor: pointer;
	transition: background-color 0.15s ease;
}
.intake-field input[type="file"]::file-selector-button:hover {
	background: var(--wp--preset--color--magenta);
}

/* ------------------------------------------------------------------ *
 * Shop toolbar — result count + catalog sorting dropdown
 *
 * The category H1 + description now lead the page in .shop-header; this bar
 * sits above the grid with the "x resultaten" count on the left and the
 * sorting <select> on the right.
 * ------------------------------------------------------------------ */
.shop-toolbar { margin-bottom: var(--wp--preset--spacing--40); }
/* Result-count line reads as a quiet caption next to the sorting control. */
.shop-toolbar .wc-block-product-results-count,
.shop-toolbar .woocommerce-result-count {
	margin: 0;
	color: var(--wp--preset--color--ink-soft);
	font-size: var(--wp--preset--font-size--small);
}
/* Style WooCommerce's catalog-sorting <select> to match the shop search /
 * filters: a bordered pill with our own chevron, brand-cyan focus ring. */
.shop-toolbar .wc-block-catalog-sorting,
.shop-toolbar .wp-block-woocommerce-catalog-sorting { margin: 0; }
/* WooCommerce ships `.woocommerce-ordering { margin: 0 0 1em }` on the form that
 * wraps the <select>, plus its own select sizing. Both outrank the rules below,
 * which left the dropdown a few pixels higher AND shorter than the search pill
 * next to it. Hence the !important — see the note on WooCommerce specificity. */
.shop-toolbar .woocommerce-ordering,
.shop-sorting .woocommerce-ordering { margin: 0 !important; }
.shop-toolbar select,
.shop-sorting select {
	appearance: none;
	-webkit-appearance: none;
	box-sizing: border-box;
	max-width: 100%;
	height: 2.75rem !important;
	padding: 0 2.4em 0 0.9em;
	border: 1.5px solid var(--wp--preset--color--border);
	border-radius: 8px;
	background-color: var(--wp--preset--color--surface);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238a8d99' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 0.8em center;
	background-size: 1em;
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--small);
	cursor: pointer;
	transition: border-color 0.15s ease;
}
.shop-toolbar select:focus,
.shop-sorting select:focus {
	outline: none;
	border-color: var(--wp--preset--color--cyan);
}
/* Actions cluster: an inline product search sitting to the LEFT of the sort
 * dropdown, both pushed to the right of the toolbar. */
.shop-toolbar__actions {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	justify-content: flex-end;
	gap: var(--wp--preset--spacing--30);
}
/* Compact search pill (label hidden — the field placeholder + icon are enough
 * inline); mirrors the sort-select height and the .shop-search pill styling. */
.shop-toolbar-search { width: auto; margin: 0; }
.shop-toolbar-search .wc-block-product-search__label {
	position: absolute !important;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden; clip: rect(0, 0, 0, 0);
	white-space: nowrap; border: 0;
}
.shop-toolbar-search .wc-block-product-search__fields {
	display: flex;
	align-items: stretch;
	margin: 0;
}
.shop-toolbar-search .wc-block-product-search__field {
	/* Wide enough for the full placeholder — at 200px it clipped mid-word
	 * ("Zoek naar printers, filame…"), which read as a broken field. */
	width: 20rem;
	max-width: 100%;
	min-width: 0;
	/* Fixed height + border-box so the input matches the sort <select> exactly. */
	height: 2.75rem;
	box-sizing: border-box;
	padding: 0 0.9em;
	background: var(--wp--preset--color--surface);
	border: 1.5px solid var(--wp--preset--color--border);
	border-right: 0;
	border-radius: 8px 0 0 8px;
	font-size: var(--wp--preset--font-size--small);
}
.shop-toolbar-search .wc-block-product-search__fields { height: 2.75rem; }
.shop-toolbar-search .wc-block-product-search__field:focus {
	outline: none;
	border-color: var(--wp--preset--color--cyan);
}
.shop-toolbar-search .wc-block-product-search__button {
	display: flex;
	align-items: center;
	padding: 0 0.9em;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--surface);
	border: 0;
	border-radius: 0 8px 8px 0;
	cursor: pointer;
	transition: background-color 0.18s ease;
}
.shop-toolbar-search .wc-block-product-search__button:hover,
.shop-toolbar-search .wc-block-product-search__button:focus-visible {
	background: var(--wp--preset--color--magenta);
}
/* On mobile the sort control spans the full row (same width as the product
 * grid below), instead of hugging its content on the right. */
@media (max-width: 781px) {
	.shop-toolbar .shop-sorting { flex: 1 1 100%; }
	.shop-toolbar .shop-sorting .woocommerce-ordering { width: 100%; }
	.shop-toolbar .shop-sorting select,
	.shop-toolbar select { width: 100%; }
	/* Search + sort each take their own full-width row, aligned with the grid. */
	.shop-toolbar__actions { flex: 1 1 100%; justify-content: stretch; }
	.shop-toolbar__actions > * { flex: 1 1 100%; }
	.shop-toolbar-search .wc-block-product-search__field { width: 100%; flex: 1 1 auto; }
}

/* ------------------------------------------------------------------ *
 * About page — social-proof gallery placeholder
 *
 * A four-up row of placeholder tiles between the "Voor scholen" and
 * "Voor thuis" sections. The striped fill + "Foto" label signal where real
 * workshop / classroom photos should be dropped in.
 * ------------------------------------------------------------------ */
.about-gallery {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 14px;
}
/* Homepage social-proof: a row of three photos (audience-split). */
.proof-row {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 14px;
}
/* The photos are now wp:image blocks (editable in the Site Editor). Zero WP's
   injected flow-margin on grid children and the figure's default margin so the
   three cells stay aligned; the img keeps the 4:3 rounded-card look. */
.proof-row > * { margin-block-start: 0; }
.proof-row .wp-block-image { margin: 0; width: 100%; }
.proof-row img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border-radius: 14px;
	border: 1px solid var(--wp--preset--color--border);
}
@media (max-width: 781px) {
	.proof-row { grid-template-columns: 1fr; }
}
.about-gallery__item {
	margin: 0;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 14px;
	background: var(--wp--preset--color--surface);
}
/* Gallery/team cards are now wp:group + wp:image blocks (editable in the Site
   Editor). Zero WP's injected flow-margins on the grids and inside each card,
   and drop the wp:image figure's margin, so the image stays flush above its
   caption and the tiles align. */
.about-gallery > *,
.about-team > *,
.about-gallery__item > * { margin-block-start: 0; }
.about-gallery__item .wp-block-image { margin: 0; width: 100%; }
.about-gallery__item img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
}
.about-gallery__ph {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 4 / 5;
	background-color: var(--wp--preset--color--base);
	background-image: repeating-linear-gradient(
		-45deg,
		var(--wp--preset--color--border) 0,
		var(--wp--preset--color--border) 1px,
		transparent 1px,
		transparent 11px
	);
	color: var(--wp--preset--color--muted);
	font-family: var(--wp--preset--font-family--display);
	font-size: 0.72rem;
	font-weight: 500;
	letter-spacing: 2px;
	text-transform: uppercase;
}
.about-gallery__cap {
	margin: 0;
	padding: 0.7rem 0.85rem 0.85rem;
	font-size: 0.8rem;
	line-height: 1.35;
	color: var(--wp--preset--color--ink-soft);
}
@media (max-width: 781px) {
	.about-gallery { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 460px) {
	.about-gallery { grid-template-columns: 1fr; }
	/* Full-width 4/5 portrait tiles get ~490px tall when stacked one-up, making a
	 * long striped scroll. Relax to a landscape crop (mirrors the hero-photo
	 * placeholder's 3/2 mobile treatment). */
	.about-gallery .about-gallery__ph { aspect-ratio: 3 / 2; }
}

/* Team row — reuses the .about-gallery__item tile with a name + role caption.
 * A centred wrapping flex row rather than a grid: with five members that gives
 * three on the first row and the remaining two centred underneath (a 3-column
 * grid would left-align that orphan pair). Any member count stays balanced. */
.about-team {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 14px;
}
/* Three per row at the 1240px content width; the basis subtracts the two gaps
 * so the cards match the old grid's column width exactly. */
.about-team__item { flex: 0 1 calc((100% - 2 * 14px) / 3); }
.about-team__photo { margin: 0; width: 100%; }
.about-team__photo img {
	display: block;
	width: 100%;
	aspect-ratio: 3 / 4;
	object-fit: cover;
}
.about-team__cap {
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	padding: 0.85rem 0.95rem 1rem;
}
.about-team__cap > * { margin-block-start: 0; }
.about-team__name {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
}
.about-team__role {
	font-size: 0.82rem;
	color: var(--wp--preset--color--ink-soft);
}
@media (max-width: 600px) {
	.about-team__item { flex-basis: calc((100% - 14px) / 2); }
}
@media (max-width: 400px) {
	.about-team__item { flex-basis: 100%; }
}

/* ------------------------------------------------------------------ *
 * Cart & checkout — long item meta + pre-order dispatch notice
 *
 * IMPORTANT (verified): the Pre-Orders plugin prints its per-item cart notice
 * (.preorder-cart-notice) via the CLASSIC hook woocommerce_after_cart_item_name,
 * which does NOT fire in this theme's block-based cart (wp:woocommerce/cart) —
 * so the delivery-date line will NOT show in the block cart out of the box. It
 * DOES appear in the classic shortcode cart and the legacy widget mini-cart.
 * To surface it in the block cart you must integrate via the Store API
 * (woocommerce_store_api_product_query / a checkout block integration) — out of
 * scope for a pure theme. The rule below brands the notice wherever it renders.
 *
 * Separately, the wrapping rules keep any long line-item meta (PPOM options,
 * variations, a dispatch date) from overflowing the product column and shoving
 * the price/quantity out of line — useful regardless of the pre-order plugin. */

/* Brand the plugin's cart notice, overriding its inline style="color:red" with
 * a calmer brand magenta (needs !important to beat the inline style). */
.preorder-cart-notice {
	display: inline-block;
	margin-top: 0.3rem;
	color: var(--wp--preset--color--magenta) !important;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.4;
}

/* Block cart/checkout: allow the product name + metadata to wrap instead of
 * forcing the column wider. */
.wc-block-cart-item__product,
.wc-block-components-product-metadata,
.wc-block-components-product-details {
	min-width: 0;
	overflow-wrap: anywhere;
	word-break: break-word;
}
/* Each injected meta line (e.g. "Verwachte levering: 15 sept. 2026") reads as
 * a soft secondary detail under the title, with comfortable line spacing. */
.wc-block-components-product-details__item {
	margin-block: 0.2rem;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.4;
	color: var(--wp--preset--color--ink-soft);
}
.wc-block-components-product-details__name {
	font-weight: 500;
	color: var(--wp--preset--color--ink);
}

/* Classic .woocommerce-cart table fallback: same graceful wrapping so a long
 * pre-order date never widens the row or clips. */
.woocommerce-cart table.cart td.product-name {
	min-width: 0;
	overflow-wrap: anywhere;
	word-break: break-word;
}
.woocommerce-cart table.cart td.product-name .variation,
.woocommerce-cart table.cart td.product-name dl.variation {
	margin-block: 0.3rem 0;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.4;
	color: var(--wp--preset--color--ink-soft);
}

/* ------------------------------------------------------------------ *
 * Mobiele sweep — overflow-guard, responsieve media & tik-doelen
 *
 * Sluitstuk van de volledige mobiele designsweep. Twee grote lagen zitten
 * al goed en hoefden hier niets extra:
 *   • Vloeiende ruimte: de grote sectie-paddings (spacing-tokens 60/70/80)
 *     gebruiken nu clamp() in theme.json, dus élke sectie krimpt netjes mee
 *     op smalle schermen en blijft identiek op desktop.
 *   • Responsief stapelen: de kaartrasters (.pillars, .audience-split,
 *     .wsaud, .edu-grid, .cat-bento, .spotlights) en de core-kolommen
 *     klappen al naar één kolom onder 782px.
 * Hieronder vangen we de laatste drie mobiele risico's af die theme.json
 * niet kan uitdrukken: horizontaal scrollen, te brede media en te kleine
 * tik-doelen op knoppen.
 * ------------------------------------------------------------------ */

/* 1. Overflow-guard — de pagina scrollt nooit horizontaal op mobiel.
 * `clip` i.p.v. `hidden`: het snijdt overloop af zonder een scroll-context
 * te maken, dus het breekt geen position:sticky/fixed en laat de bewuste
 * swipe-rij van .spotlights (met z'n eigen scroll-container) intact. De
 * verticale as blijft `visible`, zodat niets verticaal wordt afgekapt. */
.wp-site-blocks {
	overflow-x: clip;
}

/* 2. Responsieve media — beeld, video en embeds blijven altijd binnen hun
 * kolom en veroorzaken zo nooit overloop op een smal scherm. */
img,
video {
	max-width: 100%;
	height: auto;
}
iframe,
embed,
object {
	max-width: 100%;
}

/* 3. Tik-doelen — elke primaire CTA is minstens 48px hoog, zodat hij op
 * touch comfortabel en foutloos aan te tikken is (WCAG 2.5.5 / Apple HIG,
 * 44–48px). inline-flex + centreren houdt het label mooi gecentreerd nu de
 * knop een minimumhoogte krijgt. De compacte knoppen in het productraster
 * zijn hier bewust uitgesloten en krijgen hun eigen mobiele maat verderop. */
.wp-block-button__link,
.wp-element-button,
.intake-form__submit,
.single_add_to_cart_button,
.wc-block-components-button {
	min-height: 48px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

@media (max-width: 781px) {
	/* Ruimere onderlinge afstand tussen gestapelde knoppen, zodat twee
	 * CTA's onder elkaar niet per ongeluk samen worden aangetikt. */
	.wp-block-buttons {
		gap: 0.75rem;
	}

	/* Hamburger-menu en het sluitkruis van de mobiele navigatie: een royaal
	 * vierkant tik-doel i.p.v. enkel het kleine icoon. */
	.wp-block-navigation__responsive-container-open,
	.wp-block-navigation__responsive-container-close {
		min-width: 44px;
		min-height: 44px;
	}

	/* Winkelwagen- en accountknop in de header krijgen hetzelfde comfortabele
	 * tik-oppervlak. */
	.wc-block-mini-cart__button,
	.wc-block-customer-account {
		min-height: 44px;
	}

	/* Productraster: de bewust compacte knop (In winkelwagen / Selecteer
	 * opties / Lees meer) groeit op mobiel mee naar een volwaardig 48px
	 * tik-doel — de kaart is dan tweekoloms, dus daar is ruimte voor. */
	.shop-grid .wp-block-woocommerce-product-button .wc-block-components-product-button__button,
	.shop-grid .added_to_cart.wc_forward {
		min-height: 48px;
		padding-top: 0.7rem;
		padding-bottom: 0.7rem;
	}
}
